@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.
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/cancel.d.ts +46 -0
- package/dist/commands/cancel.d.ts.map +1 -0
- package/dist/commands/cancel.js +239 -0
- package/dist/commands/cancel.js.map +1 -0
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +101 -58
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/history.d.ts +7 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +56 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +11 -73
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.d.ts +11 -0
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +47 -11
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/prds.d.ts +13 -0
- package/dist/commands/prds.d.ts.map +1 -0
- package/dist/commands/prds.js +192 -0
- package/dist/commands/prds.js.map +1 -0
- package/dist/commands/prs.d.ts +13 -0
- package/dist/commands/prs.d.ts.map +1 -0
- package/dist/commands/prs.js +101 -0
- package/dist/commands/prs.js.map +1 -0
- package/dist/commands/retry.d.ts +9 -0
- package/dist/commands/retry.d.ts.map +1 -0
- package/dist/commands/retry.js +72 -0
- package/dist/commands/retry.js.map +1 -0
- package/dist/commands/review.d.ts.map +1 -1
- package/dist/commands/review.js +6 -0
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +11 -0
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/update.d.ts +21 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +87 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +36 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +4 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +7 -0
- package/dist/constants.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/crontab.d.ts.map +1 -1
- package/dist/utils/crontab.js +4 -0
- package/dist/utils/crontab.js.map +1 -1
- package/dist/utils/execution-history.d.ts +48 -0
- package/dist/utils/execution-history.d.ts.map +1 -0
- package/dist/utils/execution-history.js +183 -0
- package/dist/utils/execution-history.js.map +1 -0
- package/package.json +1 -1
- package/scripts/night-watch-cron.sh +142 -55
- package/scripts/night-watch-helpers.sh +189 -1
- package/scripts/night-watch-pr-reviewer-cron.sh +64 -15
- package/templates/night-watch-pr-reviewer.md +7 -11
- 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;
|
|
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 +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;
|
|
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"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Doctor command for Night Watch CLI
|
|
3
|
-
* Validates
|
|
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
|
-
.
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
183
|
+
header("Summary");
|
|
184
|
+
label("Checks passed", `${passedChecks}/${totalChecks}`);
|
|
185
|
+
if (fixedChecks > 0) {
|
|
186
|
+
label("Issues fixed", `${fixedChecks}`);
|
|
149
187
|
}
|
|
150
|
-
|
|
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,
|
|
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
|