@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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prs.js","sourceRoot":"","sources":["../../src/commands/prs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Retry command — Move a completed PRD back to pending for re-execution.
3
+ */
4
+ import { Command } from "commander";
5
+ /**
6
+ * Register the retry command with the program
7
+ */
8
+ export declare function retryCommand(program: Command): void;
9
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/commands/retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+BpC;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+CnD"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Retry command — Move a completed PRD back to pending for re-execution.
3
+ */
4
+ import * as fs from "fs";
5
+ import * as path from "path";
6
+ import { loadConfig } from "../config.js";
7
+ import { dim, info, success, error as uiError, } from "../utils/ui.js";
8
+ /**
9
+ * Normalize the PRD name to ensure it has .md extension
10
+ */
11
+ function normalizePrdName(name) {
12
+ if (!name.endsWith(".md")) {
13
+ return `${name}.md`;
14
+ }
15
+ return name;
16
+ }
17
+ /**
18
+ * Get list of PRD files in the done directory
19
+ */
20
+ function getDonePrds(doneDir) {
21
+ if (!fs.existsSync(doneDir)) {
22
+ return [];
23
+ }
24
+ return fs.readdirSync(doneDir).filter((f) => f.endsWith(".md"));
25
+ }
26
+ /**
27
+ * Register the retry command with the program
28
+ */
29
+ export function retryCommand(program) {
30
+ program
31
+ .command("retry <prdName>")
32
+ .description("Move a completed PRD from done/ back to pending")
33
+ .action((prdName) => {
34
+ const projectDir = process.cwd();
35
+ const config = loadConfig(projectDir);
36
+ const prdDir = path.join(projectDir, config.prdDir);
37
+ const doneDir = path.join(prdDir, "done");
38
+ // Normalize the PRD name
39
+ const normalizedPrdName = normalizePrdName(prdName);
40
+ // Check if PRD is already pending (exists in prdDir root)
41
+ const pendingPath = path.join(prdDir, normalizedPrdName);
42
+ if (fs.existsSync(pendingPath)) {
43
+ info(`"${normalizedPrdName}" is already pending, nothing to retry.`);
44
+ return;
45
+ }
46
+ // Check if PRD exists in done directory
47
+ const donePath = path.join(doneDir, normalizedPrdName);
48
+ if (fs.existsSync(donePath)) {
49
+ // Move from done to pending
50
+ fs.renameSync(donePath, pendingPath);
51
+ success(`Moved "${normalizedPrdName}" back to pending.`);
52
+ dim(`From: ${donePath}`);
53
+ dim(`To: ${pendingPath}`);
54
+ return;
55
+ }
56
+ // PRD not found anywhere
57
+ uiError(`PRD "${normalizedPrdName}" not found.`);
58
+ // List available PRDs in done directory
59
+ const donePrds = getDonePrds(doneDir);
60
+ if (donePrds.length > 0) {
61
+ info(`Available PRDs in done/:`);
62
+ for (const prd of donePrds) {
63
+ dim(` - ${prd}`);
64
+ }
65
+ }
66
+ else {
67
+ info("No PRDs found in done/ directory.");
68
+ }
69
+ process.exit(1);
70
+ });
71
+ }
72
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/commands/retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACL,GAAG,EACH,IAAI,EACJ,OAAO,EACP,KAAK,IAAI,OAAO,GACjB,MAAM,gBAAgB,CAAC;AAExB;;GAEG;AACH,SAAS,gBAAgB,CAAC,IAAY;IACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,GAAG,IAAI,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,OAAe;IAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,iBAAiB,CAAC;SAC1B,WAAW,CAAC,iDAAiD,CAAC;SAC9D,MAAM,CAAC,CAAC,OAAe,EAAE,EAAE;QAC1B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE1C,yBAAyB;QACzB,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEpD,0DAA0D;QAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QACzD,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,IAAI,iBAAiB,yCAAyC,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QAED,wCAAwC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;QACvD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,4BAA4B;YAC5B,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YACrC,OAAO,CAAC,UAAU,iBAAiB,oBAAoB,CAAC,CAAC;YACzD,GAAG,CAAC,SAAS,QAAQ,EAAE,CAAC,CAAC;YACzB,GAAG,CAAC,SAAS,WAAW,EAAE,CAAC,CAAC;YAC5B,OAAO;QACT,CAAC;QAED,yBAAyB;QACzB,OAAO,CAAC,QAAQ,iBAAiB,cAAc,CAAC,CAAC;QAEjD,wCAAwC;QACxC,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,0BAA0B,CAAC,CAAC;YACjC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,mCAAmC,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAgBhD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAyBvG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,cAAc,GAAG,iBAAiB,CAevG;AA+BD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+GpD"}
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAgBhD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA8BvG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,cAAc,GAAG,iBAAiB,CAevG;AA+BD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+GpD"}
@@ -16,6 +16,10 @@ export function buildEnvVars(config, options) {
16
16
  const env = {};
17
17
  // Provider command - the actual CLI binary to call
18
18
  env.NW_PROVIDER_CMD = PROVIDER_COMMANDS[config.provider];
19
+ // Default branch (empty = auto-detect in bash script)
20
+ if (config.defaultBranch) {
21
+ env.NW_DEFAULT_BRANCH = config.defaultBranch;
22
+ }
19
23
  // Runtime for reviewer (uses NW_REVIEWER_* variables)
20
24
  env.NW_REVIEWER_MAX_RUNTIME = String(config.reviewerMaxRuntime);
21
25
  env.NW_MIN_REVIEW_SCORE = String(config.minReviewScore);
@@ -1 +1 @@
1
- {"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Update command for Night Watch CLI
3
+ * Reinstalls global CLI and refreshes cron entries for one or more projects.
4
+ */
5
+ import { Command } from "commander";
6
+ export declare const DEFAULT_GLOBAL_SPEC = "@jonit-dev/night-watch-cli@latest";
7
+ export interface IUpdateOptions {
8
+ projects?: string;
9
+ globalSpec: string;
10
+ noGlobal?: boolean;
11
+ }
12
+ /**
13
+ * Parse project directories from a comma-separated CLI option.
14
+ * Defaults to current working directory when option is omitted.
15
+ */
16
+ export declare function parseProjectDirs(projects: string | undefined, cwd: string): string[];
17
+ /**
18
+ * Register update command.
19
+ */
20
+ export declare function updateCommand(program: Command): void;
21
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,mBAAmB,sCAAsC,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAYpF;AAgCD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6CpD"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Update command for Night Watch CLI
3
+ * Reinstalls global CLI and refreshes cron entries for one or more projects.
4
+ */
5
+ import { spawnSync } from "child_process";
6
+ import * as fs from "fs";
7
+ import * as path from "path";
8
+ import { dim, success, error as uiError, warn } from "../utils/ui.js";
9
+ export const DEFAULT_GLOBAL_SPEC = "@jonit-dev/night-watch-cli@latest";
10
+ /**
11
+ * Parse project directories from a comma-separated CLI option.
12
+ * Defaults to current working directory when option is omitted.
13
+ */
14
+ export function parseProjectDirs(projects, cwd) {
15
+ if (!projects || projects.trim().length === 0) {
16
+ return [cwd];
17
+ }
18
+ const dirs = projects
19
+ .split(",")
20
+ .map((entry) => entry.trim())
21
+ .filter((entry) => entry.length > 0)
22
+ .map((entry) => path.resolve(cwd, entry));
23
+ return Array.from(new Set(dirs));
24
+ }
25
+ function runCommand(command, args, cwd) {
26
+ const result = spawnSync(command, args, {
27
+ cwd,
28
+ env: process.env,
29
+ stdio: "inherit",
30
+ });
31
+ if (result.error) {
32
+ throw result.error;
33
+ }
34
+ if ((result.status ?? 1) !== 0) {
35
+ const location = cwd ? ` in ${cwd}` : "";
36
+ throw new Error(`Command failed${location}: ${command} ${args.join(" ")}`);
37
+ }
38
+ }
39
+ function resolveNightWatchBin() {
40
+ const result = spawnSync("which", ["night-watch"], {
41
+ encoding: "utf-8",
42
+ env: process.env,
43
+ });
44
+ if (result.status === 0 && typeof result.stdout === "string" && result.stdout.trim().length > 0) {
45
+ return result.stdout.trim();
46
+ }
47
+ return "night-watch";
48
+ }
49
+ /**
50
+ * Register update command.
51
+ */
52
+ export function updateCommand(program) {
53
+ program
54
+ .command("update")
55
+ .description("Update global CLI and refresh cron for project(s)")
56
+ .option("--projects <dirs>", "Comma-separated project directories (default: current directory)")
57
+ .option("--global-spec <spec>", "npm package spec used for global install", DEFAULT_GLOBAL_SPEC)
58
+ .option("--no-global", "Skip global npm install and only refresh project cron")
59
+ .action(async (options) => {
60
+ try {
61
+ const cwd = process.cwd();
62
+ const projectDirs = parseProjectDirs(options.projects, cwd);
63
+ if (!options.noGlobal) {
64
+ dim(`Updating global install: npm install -g ${options.globalSpec}`);
65
+ runCommand("npm", ["install", "-g", options.globalSpec]);
66
+ success("Global CLI update completed.");
67
+ }
68
+ const nightWatchBin = resolveNightWatchBin();
69
+ for (const projectDir of projectDirs) {
70
+ if (!fs.existsSync(projectDir) || !fs.statSync(projectDir).isDirectory()) {
71
+ warn(`Skipping invalid project directory: ${projectDir}`);
72
+ continue;
73
+ }
74
+ dim(`Refreshing cron in ${projectDir}`);
75
+ runCommand(nightWatchBin, ["uninstall"], projectDir);
76
+ runCommand(nightWatchBin, ["install"], projectDir);
77
+ success(`Refreshed project: ${projectDir}`);
78
+ }
79
+ success("Update completed.");
80
+ }
81
+ catch (err) {
82
+ uiError(`Update failed: ${err instanceof Error ? err.message : String(err)}`);
83
+ process.exit(1);
84
+ }
85
+ });
86
+ }
87
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jonit-dev/night-watch-cli",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "description": "Autonomous PRD execution using AI Provider CLIs + cron",
5
5
  "type": "module",
6
6
  "bin": {
@@ -15,17 +15,17 @@ set -euo pipefail
15
15
  PROJECT_DIR="${1:?Usage: $0 /path/to/project}"
16
16
  PROJECT_NAME=$(basename "${PROJECT_DIR}")
17
17
  PRD_DIR_REL="${NW_PRD_DIR:-docs/PRDs/night-watch}"
18
- if [[ "${PRD_DIR_REL}" = /* ]]; then
19
- PRD_DIR="${PRD_DIR_REL}"
20
- else
21
- PRD_DIR="${PROJECT_DIR}/${PRD_DIR_REL}"
22
- fi
23
18
  LOG_DIR="${PROJECT_DIR}/logs"
24
19
  LOG_FILE="${LOG_DIR}/night-watch.log"
25
- LOCK_FILE="/tmp/night-watch-${PROJECT_NAME}.lock"
20
+ LOCK_FILE=""
26
21
  MAX_RUNTIME="${NW_MAX_RUNTIME:-7200}" # 2 hours
27
22
  MAX_LOG_SIZE="524288" # 512 KB
28
23
  PROVIDER_CMD="${NW_PROVIDER_CMD:-claude}"
24
+ RUNTIME_MIRROR_DIR=""
25
+ RUNTIME_PROJECT_DIR=""
26
+ PRD_DIR=""
27
+ ELIGIBLE_PRD=""
28
+ CLAIMED=0
29
29
 
30
30
  # Ensure NVM / Node / Claude are on PATH
31
31
  export NVM_DIR="${HOME}/.nvm"
@@ -40,6 +40,8 @@ mkdir -p "${LOG_DIR}"
40
40
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
41
41
  # shellcheck source=night-watch-helpers.sh
42
42
  source "${SCRIPT_DIR}/night-watch-helpers.sh"
43
+ PROJECT_RUNTIME_KEY=$(project_runtime_key "${PROJECT_DIR}")
44
+ LOCK_FILE="/tmp/night-watch-${PROJECT_RUNTIME_KEY}.lock"
43
45
 
44
46
  # Validate provider
45
47
  if ! validate_provider "${PROVIDER_CMD}"; then
@@ -53,7 +55,45 @@ if ! acquire_lock "${LOCK_FILE}"; then
53
55
  exit 0
54
56
  fi
55
57
 
56
- cleanup_worktrees "${PROJECT_DIR}"
58
+ cleanup_on_exit() {
59
+ rm -f "${LOCK_FILE}"
60
+
61
+ if [ "${CLAIMED}" = "1" ] && [ -n "${ELIGIBLE_PRD}" ] && [ -n "${PRD_DIR}" ]; then
62
+ release_claim "${PRD_DIR}" "${ELIGIBLE_PRD}" || true
63
+ fi
64
+
65
+ if [ -n "${RUNTIME_MIRROR_DIR}" ] && [ -n "${RUNTIME_PROJECT_DIR}" ]; then
66
+ cleanup_runtime_workspace "${RUNTIME_MIRROR_DIR}" "${RUNTIME_PROJECT_DIR}" || true
67
+ fi
68
+ }
69
+
70
+ trap cleanup_on_exit EXIT
71
+
72
+ if [ -n "${NW_DEFAULT_BRANCH:-}" ]; then
73
+ DEFAULT_BRANCH="${NW_DEFAULT_BRANCH}"
74
+ else
75
+ DEFAULT_BRANCH=$(detect_default_branch "${PROJECT_DIR}")
76
+ fi
77
+
78
+ runtime_info=()
79
+ if mapfile -t runtime_info < <(prepare_runtime_workspace "${PROJECT_DIR}" "${DEFAULT_BRANCH}" "${LOG_FILE}"); then
80
+ RUNTIME_MIRROR_DIR="${runtime_info[0]:-}"
81
+ RUNTIME_PROJECT_DIR="${runtime_info[1]:-}"
82
+ else
83
+ log "FAIL: Could not prepare runtime workspace for ${PROJECT_DIR}"
84
+ exit 1
85
+ fi
86
+
87
+ if [ -z "${RUNTIME_MIRROR_DIR}" ] || [ -z "${RUNTIME_PROJECT_DIR}" ]; then
88
+ log "FAIL: Runtime workspace paths are missing"
89
+ exit 1
90
+ fi
91
+
92
+ if [[ "${PRD_DIR_REL}" = /* ]]; then
93
+ PRD_DIR="${PRD_DIR_REL}"
94
+ else
95
+ PRD_DIR="${RUNTIME_PROJECT_DIR}/${PRD_DIR_REL}"
96
+ fi
57
97
 
58
98
  ELIGIBLE_PRD=$(find_eligible_prd "${PRD_DIR}" "${MAX_RUNTIME}" "${PROJECT_DIR}")
59
99
 
@@ -64,29 +104,26 @@ fi
64
104
 
65
105
  # Claim the PRD to prevent other runs from selecting it
66
106
  claim_prd "${PRD_DIR}" "${ELIGIBLE_PRD}"
67
-
68
- # Update EXIT trap to also release claim
69
- trap "rm -f '${LOCK_FILE}'; release_claim '${PRD_DIR}' '${ELIGIBLE_PRD}'" EXIT
107
+ CLAIMED=1
70
108
 
71
109
  PRD_NAME="${ELIGIBLE_PRD%.md}"
72
110
  BRANCH_NAME="night-watch/${PRD_NAME}"
73
- if [ -n "${NW_DEFAULT_BRANCH:-}" ]; then
74
- DEFAULT_BRANCH="${NW_DEFAULT_BRANCH}"
75
- else
76
- DEFAULT_BRANCH=$(detect_default_branch "${PROJECT_DIR}")
77
- fi
78
111
 
79
- log "START: Processing ${ELIGIBLE_PRD} on branch ${BRANCH_NAME}"
112
+ log "START: Processing ${ELIGIBLE_PRD} on branch ${BRANCH_NAME} in runtime workspace ${RUNTIME_PROJECT_DIR}"
80
113
 
81
- cd "${PROJECT_DIR}"
114
+ if ! prepare_branch_checkout "${RUNTIME_PROJECT_DIR}" "${BRANCH_NAME}" "${DEFAULT_BRANCH}" "${LOG_FILE}"; then
115
+ log "FAIL: Could not prepare branch ${BRANCH_NAME} in runtime workspace"
116
+ night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" failure --exit-code 1 2>/dev/null || true
117
+ exit 1
118
+ fi
82
119
 
83
120
  PROMPT="Implement the PRD at docs/PRDs/night-watch/${ELIGIBLE_PRD}
84
121
 
85
122
  ## Setup
86
- - Branch name MUST be exactly: ${BRANCH_NAME}
87
- - Create the branch from ${DEFAULT_BRANCH}: git checkout ${DEFAULT_BRANCH} && git pull origin ${DEFAULT_BRANCH} && git checkout -b ${BRANCH_NAME}
88
- - Use a git worktree: git worktree add ../${PROJECT_NAME}-nw-${PRD_NAME} ${BRANCH_NAME}
89
- - cd into the worktree, install dependencies
123
+ - You are already inside an isolated runtime workspace: ${RUNTIME_PROJECT_DIR}
124
+ - Current branch is already prepared: ${BRANCH_NAME}
125
+ - Do not run git checkout/switch in ${PROJECT_DIR}
126
+ - Do not create or remove worktrees; the runtime controller handles isolation and cleanup
90
127
 
91
128
  ## Implementation — PRD Executor Workflow
92
129
  Read .claude/commands/prd-executor.md and follow its FULL execution pipeline:
@@ -102,7 +139,6 @@ Follow all CLAUDE.md conventions (if present).
102
139
  - Commit all changes, push, and open a PR:
103
140
  git push -u origin ${BRANCH_NAME}
104
141
  gh pr create --title \"feat: <short title>\" --body \"<summary referencing PRD>\"
105
- - After PR is created, clean up: git worktree remove ../${PROJECT_NAME}-nw-${PRD_NAME}
106
142
  - Do NOT move the PRD to done/ — the cron script handles that
107
143
  - Do NOT process any other PRDs — only ${ELIGIBLE_PRD}"
108
144
 
@@ -115,6 +151,7 @@ if [ "${NW_DRY_RUN:-0}" = "1" ]; then
115
151
  echo "Provider: ${PROVIDER_CMD}"
116
152
  echo "Eligible PRD: ${ELIGIBLE_PRD}"
117
153
  echo "Branch: ${BRANCH_NAME}"
154
+ echo "Runtime Dir: ${RUNTIME_PROJECT_DIR}"
118
155
  echo "Timeout: ${MAX_RUNTIME}s"
119
156
  exit 0
120
157
  fi
@@ -135,21 +172,25 @@ while [ "${ATTEMPT}" -lt "${MAX_RETRIES}" ]; do
135
172
 
136
173
  case "${PROVIDER_CMD}" in
137
174
  claude)
138
- if timeout "${MAX_RUNTIME}" \
139
- claude -p "${PROMPT}" \
140
- --dangerously-skip-permissions \
141
- >> "${LOG_FILE}" 2>&1; then
175
+ if (
176
+ cd "${RUNTIME_PROJECT_DIR}" && timeout "${MAX_RUNTIME}" \
177
+ claude -p "${PROMPT}" \
178
+ --dangerously-skip-permissions \
179
+ >> "${LOG_FILE}" 2>&1
180
+ ); then
142
181
  EXIT_CODE=0
143
182
  else
144
183
  EXIT_CODE=$?
145
184
  fi
146
185
  ;;
147
186
  codex)
148
- if timeout "${MAX_RUNTIME}" \
149
- codex --quiet \
150
- --yolo \
151
- --prompt "${PROMPT}" \
152
- >> "${LOG_FILE}" 2>&1; then
187
+ if (
188
+ cd "${RUNTIME_PROJECT_DIR}" && timeout "${MAX_RUNTIME}" \
189
+ codex --quiet \
190
+ --yolo \
191
+ --prompt "${PROMPT}" \
192
+ >> "${LOG_FILE}" 2>&1
193
+ ); then
153
194
  EXIT_CODE=0
154
195
  else
155
196
  EXIT_CODE=$?
@@ -185,16 +226,26 @@ while [ "${ATTEMPT}" -lt "${MAX_RETRIES}" ]; do
185
226
  done
186
227
 
187
228
  if [ ${EXIT_CODE} -eq 0 ]; then
188
- PR_EXISTS=$(gh pr list --state open --json headRefName --jq '.[].headRefName' 2>/dev/null | grep -cF "${BRANCH_NAME}" || echo "0")
229
+ PR_EXISTS=$(cd "${RUNTIME_PROJECT_DIR}" && gh pr list --state open --json headRefName --jq '.[].headRefName' 2>/dev/null | grep -cF "${BRANCH_NAME}" || echo "0")
189
230
  if [ "${PR_EXISTS}" -gt 0 ]; then
190
231
  release_claim "${PRD_DIR}" "${ELIGIBLE_PRD}"
232
+ CLAIMED=0
233
+ if ! checkout_default_branch "${RUNTIME_PROJECT_DIR}" "${DEFAULT_BRANCH}" "${LOG_FILE}"; then
234
+ log "WARN: Could not switch runtime workspace to ${DEFAULT_BRANCH}; PRD not moved to done/"
235
+ exit 0
236
+ fi
237
+
191
238
  mark_prd_done "${PRD_DIR}" "${ELIGIBLE_PRD}"
192
239
  night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" success --exit-code 0 2>/dev/null || true
193
- git -C "${PROJECT_DIR}" add -A docs/PRDs/night-watch/
194
- git -C "${PROJECT_DIR}" commit -m "chore: mark ${ELIGIBLE_PRD} as done (PR opened on ${BRANCH_NAME})
240
+ if [[ "${PRD_DIR_REL}" = /* ]]; then
241
+ log "WARN: PRD directory is absolute; skipping auto-commit of done/ move"
242
+ else
243
+ git -C "${RUNTIME_PROJECT_DIR}" add -A "${PRD_DIR_REL}/" || true
244
+ git -C "${RUNTIME_PROJECT_DIR}" commit -m "chore: mark ${ELIGIBLE_PRD} as done (PR opened on ${BRANCH_NAME})
195
245
 
196
246
  Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>" || true
197
- git -C "${PROJECT_DIR}" push origin "${DEFAULT_BRANCH}" || true
247
+ git -C "${RUNTIME_PROJECT_DIR}" push origin "${DEFAULT_BRANCH}" || true
248
+ fi
198
249
  log "DONE: ${ELIGIBLE_PRD} implemented, PR opened, PRD moved to done/"
199
250
  else
200
251
  log "WARN: ${PROVIDER_CMD} exited 0 but no PR found on ${BRANCH_NAME} — PRD NOT moved to done"
@@ -202,9 +253,7 @@ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>" || true
202
253
  elif [ ${EXIT_CODE} -eq 124 ]; then
203
254
  log "TIMEOUT: Night watch killed after ${MAX_RUNTIME}s while processing ${ELIGIBLE_PRD}"
204
255
  night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" timeout --exit-code 124 2>/dev/null || true
205
- cleanup_worktrees "${PROJECT_DIR}"
206
256
  else
207
257
  log "FAIL: Night watch exited with code ${EXIT_CODE} while processing ${ELIGIBLE_PRD}"
208
258
  night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" failure --exit-code "${EXIT_CODE}" 2>/dev/null || true
209
- cleanup_worktrees "${PROJECT_DIR}"
210
259
  fi
@@ -292,17 +292,151 @@ cleanup_worktrees() {
292
292
  local project_dir="${1:?project_dir required}"
293
293
  local project_name
294
294
  project_name=$(basename "${project_dir}")
295
+ local marker="${2:-${project_name}-nw}"
295
296
 
296
297
  git -C "${project_dir}" worktree list --porcelain 2>/dev/null \
297
298
  | grep '^worktree ' \
298
299
  | awk '{print $2}' \
299
- | grep "${project_name}-nw" \
300
+ | grep "${marker}" \
300
301
  | while read -r wt; do
301
302
  log "CLEANUP: Removing leftover worktree ${wt}"
302
303
  git -C "${project_dir}" worktree remove --force "${wt}" 2>/dev/null || true
303
304
  done || true
304
305
  }
305
306
 
307
+ # ── Runtime workspace isolation ───────────────────────────────────────────────
308
+
309
+ project_runtime_key() {
310
+ local project_dir="${1:?project_dir required}"
311
+ local project_name
312
+ local hash
313
+ project_name=$(basename "${project_dir}")
314
+
315
+ if command -v sha1sum >/dev/null 2>&1; then
316
+ hash=$(printf "%s" "${project_dir}" | sha1sum | awk '{print $1}')
317
+ elif command -v shasum >/dev/null 2>&1; then
318
+ hash=$(printf "%s" "${project_dir}" | shasum | awk '{print $1}')
319
+ else
320
+ hash=$(printf "%s" "${project_dir}" | cksum | awk '{print $1}')
321
+ fi
322
+
323
+ printf "%s-%s" "${project_name}" "${hash:0:12}"
324
+ }
325
+
326
+ resolve_runtime_base_ref() {
327
+ local git_dir="${1:?git_dir required}"
328
+ local default_branch="${2:?default_branch required}"
329
+
330
+ if git -C "${git_dir}" rev-parse --verify --quiet "refs/remotes/origin/${default_branch}" >/dev/null; then
331
+ printf "%s" "refs/remotes/origin/${default_branch}"
332
+ return 0
333
+ fi
334
+
335
+ if git -C "${git_dir}" rev-parse --verify --quiet "refs/heads/${default_branch}" >/dev/null; then
336
+ printf "%s" "refs/heads/${default_branch}"
337
+ return 0
338
+ fi
339
+
340
+ if git -C "${git_dir}" rev-parse --verify --quiet "refs/remotes/origin/HEAD" >/dev/null; then
341
+ printf "%s" "refs/remotes/origin/HEAD"
342
+ return 0
343
+ fi
344
+
345
+ return 1
346
+ }
347
+
348
+ prepare_runtime_workspace() {
349
+ local project_dir="${1:?project_dir required}"
350
+ local default_branch="${2:?default_branch required}"
351
+ local log_file="${3:-${LOG_FILE:-/dev/null}}"
352
+ local runtime_root="${NW_RUNTIME_ROOT:-${HOME}/.night-watch/runtime}"
353
+ local runtime_key
354
+ local runtime_base
355
+ local mirror_dir
356
+ local runs_dir
357
+ local worktree_dir
358
+ local clone_source=""
359
+ local base_ref=""
360
+
361
+ runtime_key=$(project_runtime_key "${project_dir}")
362
+ runtime_base="${runtime_root}/${runtime_key}"
363
+ mirror_dir="${runtime_base}/mirror.git"
364
+ runs_dir="${runtime_base}/runs"
365
+ worktree_dir="${runs_dir}/run-$(date +%Y%m%d-%H%M%S)-$$"
366
+
367
+ mkdir -p "${runs_dir}"
368
+
369
+ if [ ! -d "${mirror_dir}" ]; then
370
+ clone_source=$(git -C "${project_dir}" config --get remote.origin.url 2>/dev/null || echo "")
371
+
372
+ if [ -n "${clone_source}" ]; then
373
+ if ! git clone --mirror "${clone_source}" "${mirror_dir}" >> "${log_file}" 2>&1; then
374
+ git clone --mirror "${project_dir}" "${mirror_dir}" >> "${log_file}" 2>&1
375
+ fi
376
+ else
377
+ git clone --mirror "${project_dir}" "${mirror_dir}" >> "${log_file}" 2>&1
378
+ fi
379
+ fi
380
+
381
+ git -C "${mirror_dir}" remote update --prune >> "${log_file}" 2>&1 || true
382
+
383
+ base_ref=$(resolve_runtime_base_ref "${mirror_dir}" "${default_branch}") || return 1
384
+ git -C "${mirror_dir}" worktree add --detach "${worktree_dir}" "${base_ref}" >> "${log_file}" 2>&1
385
+
386
+ printf "%s\n%s\n" "${mirror_dir}" "${worktree_dir}"
387
+ }
388
+
389
+ cleanup_runtime_workspace() {
390
+ local mirror_dir="${1:?mirror_dir required}"
391
+ local worktree_dir="${2:?worktree_dir required}"
392
+
393
+ git -C "${mirror_dir}" worktree remove --force "${worktree_dir}" 2>/dev/null || true
394
+ git -C "${mirror_dir}" worktree prune 2>/dev/null || true
395
+ }
396
+
397
+ prepare_branch_checkout() {
398
+ local repo_dir="${1:?repo_dir required}"
399
+ local branch_name="${2:?branch_name required}"
400
+ local default_branch="${3:?default_branch required}"
401
+ local log_file="${4:-${LOG_FILE:-/dev/null}}"
402
+ local base_ref=""
403
+
404
+ git -C "${repo_dir}" fetch origin "${default_branch}" "${branch_name}" >> "${log_file}" 2>&1 || true
405
+
406
+ if git -C "${repo_dir}" rev-parse --verify --quiet "refs/heads/${branch_name}" >/dev/null; then
407
+ git -C "${repo_dir}" checkout "${branch_name}" >> "${log_file}" 2>&1
408
+ return $?
409
+ fi
410
+
411
+ if git -C "${repo_dir}" rev-parse --verify --quiet "refs/remotes/origin/${branch_name}" >/dev/null; then
412
+ git -C "${repo_dir}" checkout -b "${branch_name}" "origin/${branch_name}" >> "${log_file}" 2>&1
413
+ return $?
414
+ fi
415
+
416
+ base_ref=$(resolve_runtime_base_ref "${repo_dir}" "${default_branch}") || return 1
417
+ git -C "${repo_dir}" checkout -b "${branch_name}" "${base_ref}" >> "${log_file}" 2>&1
418
+ }
419
+
420
+ checkout_default_branch() {
421
+ local repo_dir="${1:?repo_dir required}"
422
+ local default_branch="${2:?default_branch required}"
423
+ local log_file="${3:-${LOG_FILE:-/dev/null}}"
424
+
425
+ git -C "${repo_dir}" fetch origin "${default_branch}" >> "${log_file}" 2>&1 || true
426
+
427
+ if git -C "${repo_dir}" rev-parse --verify --quiet "refs/remotes/origin/${default_branch}" >/dev/null; then
428
+ git -C "${repo_dir}" checkout -B "${default_branch}" "origin/${default_branch}" >> "${log_file}" 2>&1
429
+ return $?
430
+ fi
431
+
432
+ if git -C "${repo_dir}" rev-parse --verify --quiet "refs/heads/${default_branch}" >/dev/null; then
433
+ git -C "${repo_dir}" checkout "${default_branch}" >> "${log_file}" 2>&1
434
+ return $?
435
+ fi
436
+
437
+ git -C "${repo_dir}" checkout -B "${default_branch}" HEAD >> "${log_file}" 2>&1
438
+ }
439
+
306
440
  # ── Mark PRD as done ─────────────────────────────────────────────────────────
307
441
 
308
442
  mark_prd_done() {