@jonit-dev/night-watch-cli 1.5.0 → 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.
Files changed (65) hide show
  1. package/dist/cli.js +6 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/cancel.d.ts +46 -0
  4. package/dist/commands/cancel.d.ts.map +1 -0
  5. package/dist/commands/cancel.js +239 -0
  6. package/dist/commands/cancel.js.map +1 -0
  7. package/dist/commands/doctor.d.ts +1 -1
  8. package/dist/commands/doctor.d.ts.map +1 -1
  9. package/dist/commands/doctor.js +101 -58
  10. package/dist/commands/doctor.js.map +1 -1
  11. package/dist/commands/history.d.ts +7 -0
  12. package/dist/commands/history.d.ts.map +1 -0
  13. package/dist/commands/history.js +56 -0
  14. package/dist/commands/history.js.map +1 -0
  15. package/dist/commands/init.d.ts.map +1 -1
  16. package/dist/commands/init.js +11 -73
  17. package/dist/commands/init.js.map +1 -1
  18. package/dist/commands/install.d.ts +11 -0
  19. package/dist/commands/install.d.ts.map +1 -1
  20. package/dist/commands/install.js +47 -11
  21. package/dist/commands/install.js.map +1 -1
  22. package/dist/commands/prds.d.ts +13 -0
  23. package/dist/commands/prds.d.ts.map +1 -0
  24. package/dist/commands/prds.js +192 -0
  25. package/dist/commands/prds.js.map +1 -0
  26. package/dist/commands/prs.d.ts +13 -0
  27. package/dist/commands/prs.d.ts.map +1 -0
  28. package/dist/commands/prs.js +101 -0
  29. package/dist/commands/prs.js.map +1 -0
  30. package/dist/commands/retry.d.ts +9 -0
  31. package/dist/commands/retry.d.ts.map +1 -0
  32. package/dist/commands/retry.js +72 -0
  33. package/dist/commands/retry.js.map +1 -0
  34. package/dist/commands/review.d.ts.map +1 -1
  35. package/dist/commands/review.js +6 -0
  36. package/dist/commands/review.js.map +1 -1
  37. package/dist/commands/run.d.ts.map +1 -1
  38. package/dist/commands/run.js +11 -0
  39. package/dist/commands/run.js.map +1 -1
  40. package/dist/commands/update.d.ts +21 -0
  41. package/dist/commands/update.d.ts.map +1 -0
  42. package/dist/commands/update.js +87 -0
  43. package/dist/commands/update.js.map +1 -0
  44. package/dist/config.d.ts.map +1 -1
  45. package/dist/config.js +36 -1
  46. package/dist/config.js.map +1 -1
  47. package/dist/constants.d.ts +4 -0
  48. package/dist/constants.d.ts.map +1 -1
  49. package/dist/constants.js +7 -0
  50. package/dist/constants.js.map +1 -1
  51. package/dist/types.d.ts +4 -0
  52. package/dist/types.d.ts.map +1 -1
  53. package/dist/utils/crontab.d.ts.map +1 -1
  54. package/dist/utils/crontab.js +4 -0
  55. package/dist/utils/crontab.js.map +1 -1
  56. package/dist/utils/execution-history.d.ts +48 -0
  57. package/dist/utils/execution-history.d.ts.map +1 -0
  58. package/dist/utils/execution-history.js +183 -0
  59. package/dist/utils/execution-history.js.map +1 -0
  60. package/package.json +1 -1
  61. package/scripts/night-watch-cron.sh +142 -55
  62. package/scripts/night-watch-helpers.sh +189 -1
  63. package/scripts/night-watch-pr-reviewer-cron.sh +64 -15
  64. package/templates/night-watch-pr-reviewer.md +7 -11
  65. package/templates/night-watch.md +9 -20
package/dist/cli.js CHANGED
@@ -14,6 +14,8 @@ import { prdCommand } from './commands/prd.js';
14
14
  import { dashboardCommand } from './commands/dashboard.js';
15
15
  import { doctorCommand } from './commands/doctor.js';
16
16
  import { serveCommand } from './commands/serve.js';
17
+ import { historyCommand } from './commands/history.js';
18
+ import { updateCommand } from './commands/update.js';
17
19
  // Get package.json version
18
20
  const __filename = fileURLToPath(import.meta.url);
19
21
  const __dirname = dirname(__filename);
@@ -43,5 +45,9 @@ doctorCommand(program);
43
45
  dashboardCommand(program);
44
46
  // Register serve command
45
47
  serveCommand(program);
48
+ // Register history command (used by bash scripts for cooldown tracking)
49
+ historyCommand(program);
50
+ // Register update command
51
+ updateCommand(program);
46
52
  program.parse();
47
53
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,2BAA2B;AAC3B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;AAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;AAEvE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,kDAAkD,CAAC;KAC/D,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAEhC,wBAAwB;AACxB,WAAW,CAAC,OAAO,CAAC,CAAC;AAErB,uBAAuB;AACvB,UAAU,CAAC,OAAO,CAAC,CAAC;AAEpB,0BAA0B;AAC1B,aAAa,CAAC,OAAO,CAAC,CAAC;AAEvB,4BAA4B;AAC5B,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,WAAW,CAAC,OAAO,CAAC,CAAC;AAErB,uBAAuB;AACvB,UAAU,CAAC,OAAO,CAAC,CAAC;AAEpB,0BAA0B;AAC1B,aAAa,CAAC,OAAO,CAAC,CAAC;AAEvB,6BAA6B;AAC7B,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAE1B,yBAAyB;AACzB,YAAY,CAAC,OAAO,CAAC,CAAC;AAEtB,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,2BAA2B;AAC3B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;AAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;AAEvE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,kDAAkD,CAAC;KAC/D,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAEhC,wBAAwB;AACxB,WAAW,CAAC,OAAO,CAAC,CAAC;AAErB,uBAAuB;AACvB,UAAU,CAAC,OAAO,CAAC,CAAC;AAEpB,0BAA0B;AAC1B,aAAa,CAAC,OAAO,CAAC,CAAC;AAEvB,4BAA4B;AAC5B,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,WAAW,CAAC,OAAO,CAAC,CAAC;AAErB,uBAAuB;AACvB,UAAU,CAAC,OAAO,CAAC,CAAC;AAEpB,0BAA0B;AAC1B,aAAa,CAAC,OAAO,CAAC,CAAC;AAEvB,6BAA6B;AAC7B,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAE1B,yBAAyB;AACzB,YAAY,CAAC,OAAO,CAAC,CAAC;AAEtB,wEAAwE;AACxE,cAAc,CAAC,OAAO,CAAC,CAAC;AAExB,0BAA0B;AAC1B,aAAa,CAAC,OAAO,CAAC,CAAC;AAEvB,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Cancel command for Night Watch CLI
3
+ * Gracefully stops a running executor or reviewer process
4
+ */
5
+ import { Command } from "commander";
6
+ export interface ICancelOptions {
7
+ type: "run" | "review" | "all";
8
+ force?: boolean;
9
+ }
10
+ /**
11
+ * Get lock file paths for a project
12
+ */
13
+ export declare function getLockFilePaths(projectName: string): {
14
+ executor: string;
15
+ reviewer: string;
16
+ };
17
+ /**
18
+ * Prompt user for confirmation
19
+ */
20
+ export declare function promptConfirmation(prompt: string): Promise<boolean>;
21
+ /**
22
+ * Wait for specified milliseconds
23
+ */
24
+ export declare function sleep(ms: number): Promise<void>;
25
+ /**
26
+ * Check if a process is still running
27
+ */
28
+ export declare function isProcessRunning(pid: number): boolean;
29
+ export interface ICancelResult {
30
+ success: boolean;
31
+ message: string;
32
+ cleanedUp?: boolean;
33
+ }
34
+ /**
35
+ * Attempt to cancel a single process
36
+ */
37
+ export declare function cancelProcess(processType: "executor" | "reviewer", lockPath: string, force?: boolean): Promise<ICancelResult>;
38
+ /**
39
+ * Cancel running execution
40
+ */
41
+ export declare function performCancel(projectDir: string, options: ICancelOptions): Promise<ICancelResult[]>;
42
+ /**
43
+ * Cancel command implementation
44
+ */
45
+ export declare function cancelCommand(program: Command): void;
46
+ //# sourceMappingURL=cancel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancel.d.ts","sourceRoot":"","sources":["../../src/commands/cancel.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAKA;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAazE;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOrD;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,UAAU,GAAG,UAAU,EACpC,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,aAAa,CAAC,CA+HxB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,EAAE,CAAC,CAiB1B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkDpD"}
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Cancel command for Night Watch CLI
3
+ * Gracefully stops a running executor or reviewer process
4
+ */
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import * as readline from "readline";
8
+ import { LOCK_FILE_PREFIX } from "../constants.js";
9
+ import { checkLockFile } from "../utils/status-data.js";
10
+ import { dim, info, success, error as uiError, warn, } from "../utils/ui.js";
11
+ /**
12
+ * Get lock file paths for a project
13
+ */
14
+ export function getLockFilePaths(projectName) {
15
+ return {
16
+ executor: `${LOCK_FILE_PREFIX}${projectName}.lock`,
17
+ reviewer: `${LOCK_FILE_PREFIX}pr-reviewer-${projectName}.lock`,
18
+ };
19
+ }
20
+ /**
21
+ * Prompt user for confirmation
22
+ */
23
+ export async function promptConfirmation(prompt) {
24
+ const rl = readline.createInterface({
25
+ input: process.stdin,
26
+ output: process.stdout,
27
+ });
28
+ return new Promise((resolve) => {
29
+ rl.question(`${prompt} `, (answer) => {
30
+ rl.close();
31
+ const normalized = answer.toLowerCase().trim();
32
+ resolve(normalized === "y" || normalized === "yes");
33
+ });
34
+ });
35
+ }
36
+ /**
37
+ * Wait for specified milliseconds
38
+ */
39
+ export function sleep(ms) {
40
+ return new Promise((resolve) => setTimeout(resolve, ms));
41
+ }
42
+ /**
43
+ * Check if a process is still running
44
+ */
45
+ export function isProcessRunning(pid) {
46
+ try {
47
+ process.kill(pid, 0);
48
+ return true;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ /**
55
+ * Attempt to cancel a single process
56
+ */
57
+ export async function cancelProcess(processType, lockPath, force = false) {
58
+ const lockStatus = checkLockFile(lockPath);
59
+ // No lock file exists
60
+ if (!lockStatus.pid) {
61
+ return {
62
+ success: true,
63
+ message: `${processType} is not running (no lock file)`,
64
+ };
65
+ }
66
+ const pid = lockStatus.pid;
67
+ // Lock file exists but process is not running (stale)
68
+ if (!lockStatus.running) {
69
+ // Clean up stale lock file
70
+ try {
71
+ fs.unlinkSync(lockPath);
72
+ return {
73
+ success: true,
74
+ message: `${processType} is not running (cleaned up stale lock file for PID ${pid})`,
75
+ cleanedUp: true,
76
+ };
77
+ }
78
+ catch {
79
+ return {
80
+ success: true,
81
+ message: `${processType} is not running (stale lock file exists but could not be removed)`,
82
+ };
83
+ }
84
+ }
85
+ // Process is running - prompt for confirmation
86
+ const confirmPrompt = `Kill ${processType} (PID ${pid})? [y/N]`;
87
+ if (!force) {
88
+ const confirmed = await promptConfirmation(confirmPrompt);
89
+ if (!confirmed) {
90
+ return {
91
+ success: false,
92
+ message: `Cancelled - ${processType} (PID ${pid}) left running`,
93
+ };
94
+ }
95
+ }
96
+ else {
97
+ dim(confirmPrompt + " y (forced)");
98
+ }
99
+ // Send SIGTERM
100
+ try {
101
+ process.kill(pid, "SIGTERM");
102
+ }
103
+ catch (err) {
104
+ const errorMessage = err instanceof Error ? err.message : String(err);
105
+ return {
106
+ success: false,
107
+ message: `Failed to send SIGTERM to ${processType} (PID ${pid}): ${errorMessage}`,
108
+ };
109
+ }
110
+ info(`Sent SIGTERM to ${processType} (PID ${pid}), waiting 3 seconds...`);
111
+ // Wait 3 seconds
112
+ await sleep(3000);
113
+ // Check if process is still running
114
+ if (!isProcessRunning(pid)) {
115
+ // Clean up lock file
116
+ try {
117
+ fs.unlinkSync(lockPath);
118
+ }
119
+ catch {
120
+ // Ignore cleanup errors
121
+ }
122
+ return {
123
+ success: true,
124
+ message: `${processType} (PID ${pid}) terminated successfully`,
125
+ };
126
+ }
127
+ // Process still running after SIGTERM
128
+ warn(`${processType} (PID ${pid}) is still running after SIGTERM`);
129
+ // Offer to send SIGKILL
130
+ const killPrompt = `Send SIGKILL to ${processType} (PID ${pid})? [y/N]`;
131
+ let shouldKill;
132
+ if (!force) {
133
+ shouldKill = await promptConfirmation(killPrompt);
134
+ }
135
+ else {
136
+ dim(killPrompt + " y (forced)");
137
+ shouldKill = true;
138
+ }
139
+ if (!shouldKill) {
140
+ return {
141
+ success: false,
142
+ message: `${processType} (PID ${pid}) still running - SIGTERM sent but process did not terminate`,
143
+ };
144
+ }
145
+ // Send SIGKILL
146
+ try {
147
+ process.kill(pid, "SIGKILL");
148
+ }
149
+ catch (err) {
150
+ const errorMessage = err instanceof Error ? err.message : String(err);
151
+ return {
152
+ success: false,
153
+ message: `Failed to send SIGKILL to ${processType} (PID ${pid}): ${errorMessage}`,
154
+ };
155
+ }
156
+ // Wait briefly for SIGKILL to take effect
157
+ await sleep(500);
158
+ // Final check
159
+ if (!isProcessRunning(pid)) {
160
+ // Clean up lock file
161
+ try {
162
+ fs.unlinkSync(lockPath);
163
+ }
164
+ catch {
165
+ // Ignore cleanup errors
166
+ }
167
+ return {
168
+ success: true,
169
+ message: `${processType} (PID ${pid}) killed successfully`,
170
+ };
171
+ }
172
+ return {
173
+ success: false,
174
+ message: `${processType} (PID ${pid}) could not be terminated even with SIGKILL`,
175
+ };
176
+ }
177
+ /**
178
+ * Cancel running execution
179
+ */
180
+ export async function performCancel(projectDir, options) {
181
+ const projectName = path.basename(projectDir);
182
+ const lockPaths = getLockFilePaths(projectName);
183
+ const results = [];
184
+ const force = options.force ?? false;
185
+ if (options.type === "run" || options.type === "all") {
186
+ const result = await cancelProcess("executor", lockPaths.executor, force);
187
+ results.push(result);
188
+ }
189
+ if (options.type === "review" || options.type === "all") {
190
+ const result = await cancelProcess("reviewer", lockPaths.reviewer, force);
191
+ results.push(result);
192
+ }
193
+ return results;
194
+ }
195
+ /**
196
+ * Cancel command implementation
197
+ */
198
+ export function cancelCommand(program) {
199
+ program
200
+ .command("cancel")
201
+ .description("Cancel running executor or reviewer processes")
202
+ .option("-t, --type <type>", "Process type to cancel: 'run', 'review', or 'all'", "all")
203
+ .option("-f, --force", "Skip confirmation prompts")
204
+ .action(async (options) => {
205
+ try {
206
+ // Validate type option
207
+ const validTypes = ["run", "review", "all"];
208
+ if (!validTypes.includes(options.type)) {
209
+ uiError(`Invalid type '${options.type}'. Must be one of: ${validTypes.join(", ")}`);
210
+ process.exit(1);
211
+ }
212
+ const cancelOptions = {
213
+ type: options.type,
214
+ force: options.force,
215
+ };
216
+ const projectDir = process.cwd();
217
+ const results = await performCancel(projectDir, cancelOptions);
218
+ // Output results
219
+ for (const result of results) {
220
+ if (result.success) {
221
+ success(result.message);
222
+ }
223
+ else {
224
+ uiError(result.message);
225
+ }
226
+ }
227
+ // Exit with error code if any cancel failed
228
+ const hasFailure = results.some((r) => !r.success);
229
+ if (hasFailure) {
230
+ process.exit(1);
231
+ }
232
+ }
233
+ catch (err) {
234
+ uiError(`Error cancelling processes: ${err instanceof Error ? err.message : String(err)}`);
235
+ process.exit(1);
236
+ }
237
+ });
238
+ }
239
+ //# sourceMappingURL=cancel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancel.js","sourceRoot":"","sources":["../../src/commands/cancel.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Doctor command for Night Watch CLI
3
- * Validates webhook configuration and checks system health
3
+ * Validates environment setup and system health
4
4
  */
5
5
  import { Command } from "commander";
6
6
  import { IWebhookConfig } from "../types.js";
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAU7C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,EAAE,CAmDjE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiGpD"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAsB7C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,EAAE,CAmDjE;AAiDD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+IpD"}
@@ -1,12 +1,10 @@
1
1
  /**
2
2
  * Doctor command for Night Watch CLI
3
- * Validates webhook configuration and checks system health
3
+ * Validates environment setup and system health
4
4
  */
5
- import * as fs from "fs";
6
- import * as path from "path";
7
- import { execSync } from "child_process";
8
5
  import { loadConfig } from "../config.js";
9
- import { header, info, step, success, error as uiError, warn, } from "../utils/ui.js";
6
+ import { header, info, label, step, success, error as uiError, warn, } from "../utils/ui.js";
7
+ import { checkConfigFile, checkCrontabAccess, checkGhCli, checkGitRepo, checkLogsDirectory, checkNodeVersion, checkPrdDirectory, checkProviderCli, } from "../utils/checks.js";
10
8
  /**
11
9
  * Validate a single webhook configuration and return a list of issues.
12
10
  * Returns an empty array if the webhook is valid.
@@ -61,6 +59,38 @@ export function validateWebhook(webhook) {
61
59
  }
62
60
  return issues;
63
61
  }
62
+ /**
63
+ * Run a single check and print the result
64
+ */
65
+ function runCheck(checkNum, total, checkName, checkFn, options) {
66
+ step(checkNum, total, `Checking ${checkName}...`);
67
+ const result = checkFn();
68
+ if (result.passed) {
69
+ success(result.message);
70
+ return { passed: true, fixed: false };
71
+ }
72
+ // Check failed
73
+ if (options.fix && result.fixable && result.fix) {
74
+ result.fix();
75
+ // Re-run check after fix
76
+ const recheckResult = checkFn();
77
+ if (recheckResult.passed) {
78
+ success(`Fixed: ${checkName}`);
79
+ return { passed: true, fixed: true };
80
+ }
81
+ else {
82
+ uiError(`Failed to fix: ${checkName}`);
83
+ return { passed: false, fixed: false };
84
+ }
85
+ }
86
+ if (result.fixable) {
87
+ warn(`${result.message} (run with --fix to auto-fix)`);
88
+ }
89
+ else {
90
+ uiError(result.message);
91
+ }
92
+ return { passed: false, fixed: false };
93
+ }
64
94
  /**
65
95
  * Register the doctor command on the program
66
96
  */
@@ -68,60 +98,63 @@ export function doctorCommand(program) {
68
98
  program
69
99
  .command("doctor")
70
100
  .description("Check Night Watch configuration and system health")
71
- .action(async () => {
101
+ .option("--fix", "Automatically fix fixable issues")
102
+ .action(async (options) => {
72
103
  const projectDir = process.cwd();
73
- let hasErrors = false;
74
- header("Night Watch Doctor");
75
- // Check 1: Git repository
76
- step(1, 5, "Checking git repository...");
77
- try {
78
- execSync("git rev-parse --is-inside-work-tree", {
79
- cwd: projectDir,
80
- stdio: "pipe",
81
- });
82
- success("Git repository detected");
83
- }
84
- catch {
85
- uiError("Not a git repository");
86
- hasErrors = true;
87
- }
88
- // Check 2: GitHub CLI
89
- step(2, 5, "Checking GitHub CLI...");
90
- try {
91
- execSync("gh auth status", { stdio: "pipe" });
92
- success("GitHub CLI authenticated");
93
- }
94
- catch {
95
- warn("GitHub CLI not authenticated (run: gh auth login)");
96
- }
97
- // Check 3: Provider CLI
98
- step(3, 5, "Checking provider CLI...");
99
104
  const config = loadConfig(projectDir);
100
- try {
101
- execSync(`which ${config.provider}`, { stdio: "pipe" });
102
- success(`Provider CLI found: ${config.provider}`);
103
- }
104
- catch {
105
- uiError(`Provider CLI not found: ${config.provider}`);
106
- hasErrors = true;
107
- }
108
- // Check 4: PRD directory
109
- step(4, 5, "Checking PRD directory...");
110
- const prdDir = path.join(projectDir, config.prdDir);
111
- if (fs.existsSync(prdDir)) {
112
- const prds = fs
113
- .readdirSync(prdDir)
114
- .filter((f) => f.endsWith(".md") && f !== "NIGHT-WATCH-SUMMARY.md");
115
- success(`PRD directory found (${prds.length} PRDs)`);
116
- }
117
- else {
118
- warn(`PRD directory not found: ${config.prdDir} (run: night-watch init)`);
119
- }
120
- // Check 5: Webhook configuration
121
- step(5, 5, "Checking webhook configuration...");
105
+ const totalChecks = 8;
106
+ let checkNum = 1;
107
+ let passedChecks = 0;
108
+ let fixedChecks = 0;
109
+ header("Night Watch Doctor");
110
+ // Check 1: Node.js version
111
+ const nodeResult = runCheck(checkNum++, totalChecks, "Node.js version", () => checkNodeVersion(18), options);
112
+ if (nodeResult.passed)
113
+ passedChecks++;
114
+ if (nodeResult.fixed)
115
+ fixedChecks++;
116
+ // Check 2: Git repository
117
+ const gitResult = runCheck(checkNum++, totalChecks, "git repository", () => checkGitRepo(projectDir), options);
118
+ if (gitResult.passed)
119
+ passedChecks++;
120
+ if (gitResult.fixed)
121
+ fixedChecks++;
122
+ // Check 3: GitHub CLI
123
+ const ghResult = runCheck(checkNum++, totalChecks, "GitHub CLI", () => checkGhCli(), options);
124
+ if (ghResult.passed)
125
+ passedChecks++;
126
+ if (ghResult.fixed)
127
+ fixedChecks++;
128
+ // Check 4: Provider CLI
129
+ const providerResult = runCheck(checkNum++, totalChecks, "provider CLI", () => checkProviderCli(config.provider), options);
130
+ if (providerResult.passed)
131
+ passedChecks++;
132
+ if (providerResult.fixed)
133
+ fixedChecks++;
134
+ // Check 5: Config file
135
+ const configResult = runCheck(checkNum++, totalChecks, "config file", () => checkConfigFile(projectDir), options);
136
+ if (configResult.passed)
137
+ passedChecks++;
138
+ if (configResult.fixed)
139
+ fixedChecks++;
140
+ // Check 6: PRD directory
141
+ const prdResult = runCheck(checkNum++, totalChecks, "PRD directory", () => checkPrdDirectory(projectDir, config.prdDir), options);
142
+ if (prdResult.passed)
143
+ passedChecks++;
144
+ if (prdResult.fixed)
145
+ fixedChecks++;
146
+ // Check 7: Logs directory
147
+ const logsResult = runCheck(checkNum++, totalChecks, "logs directory", () => checkLogsDirectory(projectDir), options);
148
+ if (logsResult.passed)
149
+ passedChecks++;
150
+ if (logsResult.fixed)
151
+ fixedChecks++;
152
+ // Check 8: Webhook configuration
153
+ step(checkNum, totalChecks, "Checking webhook configuration...");
122
154
  if (!config.notifications ||
123
155
  config.notifications.webhooks.length === 0) {
124
156
  info("No webhooks configured (optional)");
157
+ passedChecks++;
125
158
  }
126
159
  else {
127
160
  let webhookErrors = 0;
@@ -139,17 +172,27 @@ export function doctorCommand(program) {
139
172
  }
140
173
  if (webhookErrors === 0) {
141
174
  success(`All ${config.notifications.webhooks.length} webhook(s) valid`);
175
+ passedChecks++;
142
176
  }
143
177
  }
178
+ // Check crontab access (non-blocking, informational only)
179
+ const crontabResult = checkCrontabAccess();
180
+ info(crontabResult.message);
144
181
  // Summary
145
182
  console.log();
146
- if (hasErrors) {
147
- uiError("Issues found — fix errors above before running Night Watch");
148
- process.exit(1);
183
+ header("Summary");
184
+ label("Checks passed", `${passedChecks}/${totalChecks}`);
185
+ if (fixedChecks > 0) {
186
+ label("Issues fixed", `${fixedChecks}`);
149
187
  }
150
- else {
188
+ console.log();
189
+ if (passedChecks === totalChecks) {
151
190
  success("All checks passed");
152
191
  }
192
+ else {
193
+ uiError("Issues found — fix errors above before running Night Watch");
194
+ process.exit(1);
195
+ }
153
196
  });
154
197
  }
155
198
  //# sourceMappingURL=doctor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EACL,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,KAAK,IAAI,OAAO,EAChB,IAAI,GACL,MAAM,gBAAgB,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAuB;IACrD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,kBAAkB;IAClB,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,MAAM,WAAW,GAAG;YAClB,eAAe;YACf,YAAY;YACZ,aAAa;YACb,kBAAkB;SACnB,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,MAAM,CAAC,IAAI,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,OAAO;YACV,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC7B,CAAC;iBAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,0BAA0B,CAAC,EAAE,CAAC;gBAC/D,MAAM,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;YAChE,CAAC;YACD,MAAM;QACR,KAAK,SAAS;YACZ,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC7B,CAAC;iBAAM,IACL,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,mCAAmC,CAAC,EAC5D,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;YACzE,CAAC;YACD,MAAM;QACR,KAAK,UAAU;YACb,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAClC,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAChC,CAAC;YACD,MAAM;QACR;YACE,MAAM,CAAC,IAAI,CAAC,yBAAyB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,mDAAmD,CAAC;SAChE,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QACjC,IAAI,SAAS,GAAG,KAAK,CAAC;QAEtB,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAE7B,0BAA0B;QAC1B,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,4BAA4B,CAAC,CAAC;QACzC,IAAI,CAAC;YACH,QAAQ,CAAC,qCAAqC,EAAE;gBAC9C,GAAG,EAAE,UAAU;gBACf,KAAK,EAAE,MAAM;aACd,CAAC,CAAC;YACH,OAAO,CAAC,yBAAyB,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,sBAAsB,CAAC,CAAC;YAChC,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;QAED,sBAAsB;QACtB,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,wBAAwB,CAAC,CAAC;QACrC,IAAI,CAAC;YACH,QAAQ,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,0BAA0B,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,mDAAmD,CAAC,CAAC;QAC5D,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,0BAA0B,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;QACtC,IAAI,CAAC;YACH,QAAQ,CAAC,SAAS,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACxD,OAAO,CAAC,uBAAuB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,2BAA2B,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACtD,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,2BAA2B,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,EAAE;iBACZ,WAAW,CAAC,MAAM,CAAC;iBACnB,MAAM,CACL,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,wBAAwB,CAC3D,CAAC;YACJ,OAAO,CAAC,wBAAwB,IAAI,CAAC,MAAM,QAAQ,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,IAAI,CACF,4BAA4B,MAAM,CAAC,MAAM,0BAA0B,CACpE,CAAC;QACJ,CAAC;QAED,iCAAiC;QACjC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,mCAAmC,CAAC,CAAC;QAChD,IACE,CAAC,MAAM,CAAC,aAAa;YACrB,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAC1C,CAAC;YACD,IAAI,CAAC,mCAAmC,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,IAAI,aAAa,GAAG,CAAC,CAAC;YACtB,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;gBACpD,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;gBACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACxB,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,cAAc,CAAC,CAAC;gBACzC,CAAC;qBAAM,CAAC;oBACN,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;wBAC3B,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,aAAa,KAAK,EAAE,CAAC,CAAC;oBAC5C,CAAC;oBACD,aAAa,EAAE,CAAC;gBAClB,CAAC;YACH,CAAC;YACD,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,CACL,OAAO,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,mBAAmB,CAC/D,CAAC;YACJ,CAAC;QACH,CAAC;QAED,UAAU;QACV,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,CACL,4DAA4D,CAC7D,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * History command — CLI interface to the execution history ledger.
3
+ * Designed for bash script integration (silent stdout, exit-code signaling).
4
+ */
5
+ import { Command } from "commander";
6
+ export declare function historyCommand(program: Command): void;
7
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/commands/history.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyErD"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * History command — CLI interface to the execution history ledger.
3
+ * Designed for bash script integration (silent stdout, exit-code signaling).
4
+ */
5
+ import { isInCooldown, recordExecution, } from "../utils/execution-history.js";
6
+ const VALID_OUTCOMES = [
7
+ "success",
8
+ "failure",
9
+ "timeout",
10
+ "rate_limited",
11
+ ];
12
+ export function historyCommand(program) {
13
+ const history = program
14
+ .command("history")
15
+ .description("Manage PRD execution history ledger");
16
+ history
17
+ .command("record <projectDir> <prdFile> <outcome>")
18
+ .description("Record a PRD execution result")
19
+ .option("--exit-code <n>", "Process exit code", "0")
20
+ .option("--attempt <n>", "Attempt number", "1")
21
+ .action((projectDir, prdFile, outcome, options) => {
22
+ if (!VALID_OUTCOMES.includes(outcome)) {
23
+ process.stderr.write(`Invalid outcome: ${outcome}. Must be one of: ${VALID_OUTCOMES.join(", ")}\n`);
24
+ process.exit(2);
25
+ }
26
+ const exitCode = parseInt(options.exitCode, 10);
27
+ const attempt = parseInt(options.attempt, 10);
28
+ if (isNaN(exitCode)) {
29
+ process.stderr.write(`Invalid exit code: ${options.exitCode}\n`);
30
+ process.exit(2);
31
+ }
32
+ if (isNaN(attempt) || attempt < 1) {
33
+ process.stderr.write(`Invalid attempt: ${options.attempt}\n`);
34
+ process.exit(2);
35
+ }
36
+ recordExecution(projectDir, prdFile, outcome, exitCode, attempt);
37
+ });
38
+ history
39
+ .command("check <projectDir> <prdFile>")
40
+ .description("Check if a PRD is in cooldown (exit 0 = in cooldown, exit 1 = eligible)")
41
+ .option("--cooldown <seconds>", "Cooldown period in seconds", "7200")
42
+ .action((projectDir, prdFile, options) => {
43
+ const cooldownPeriod = parseInt(options.cooldown, 10);
44
+ if (isNaN(cooldownPeriod) || cooldownPeriod < 0) {
45
+ process.stderr.write(`Invalid cooldown period: ${options.cooldown}\n`);
46
+ process.exit(2);
47
+ }
48
+ if (isInCooldown(projectDir, prdFile, cooldownPeriod)) {
49
+ process.exit(0); // in cooldown — caller should skip
50
+ }
51
+ else {
52
+ process.exit(1); // eligible — caller should proceed
53
+ }
54
+ });
55
+ }
56
+ //# sourceMappingURL=history.js.map