@jonit-dev/night-watch-cli 1.8.11 → 1.8.12-beta.1

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 (120) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.js +2363 -1382
  3. package/dist/cli.js.map +1 -0
  4. package/dist/commands/analytics.d.ts +14 -0
  5. package/dist/commands/analytics.js +69 -0
  6. package/dist/commands/analytics.js.map +1 -0
  7. package/dist/commands/audit.d.ts +19 -0
  8. package/dist/commands/audit.js +144 -0
  9. package/dist/commands/audit.js.map +1 -0
  10. package/dist/commands/board.d.ts +9 -0
  11. package/dist/commands/board.js +702 -0
  12. package/dist/commands/board.js.map +1 -0
  13. package/dist/commands/cancel.d.ts +46 -0
  14. package/dist/commands/cancel.js +239 -0
  15. package/dist/commands/cancel.js.map +1 -0
  16. package/dist/commands/cron.d.ts +8 -0
  17. package/dist/commands/cron.js +134 -0
  18. package/dist/commands/cron.js.map +1 -0
  19. package/dist/commands/dashboard/tab-actions.d.ts +10 -0
  20. package/dist/commands/dashboard/tab-actions.js +247 -0
  21. package/dist/commands/dashboard/tab-actions.js.map +1 -0
  22. package/dist/commands/dashboard/tab-config.d.ts +21 -0
  23. package/dist/commands/dashboard/tab-config.js +874 -0
  24. package/dist/commands/dashboard/tab-config.js.map +1 -0
  25. package/dist/commands/dashboard/tab-logs.d.ts +10 -0
  26. package/dist/commands/dashboard/tab-logs.js +202 -0
  27. package/dist/commands/dashboard/tab-logs.js.map +1 -0
  28. package/dist/commands/dashboard/tab-schedules.d.ts +21 -0
  29. package/dist/commands/dashboard/tab-schedules.js +320 -0
  30. package/dist/commands/dashboard/tab-schedules.js.map +1 -0
  31. package/dist/commands/dashboard/tab-status.d.ts +32 -0
  32. package/dist/commands/dashboard/tab-status.js +424 -0
  33. package/dist/commands/dashboard/tab-status.js.map +1 -0
  34. package/dist/commands/dashboard/types.d.ts +42 -0
  35. package/dist/commands/dashboard/types.js +5 -0
  36. package/dist/commands/dashboard/types.js.map +1 -0
  37. package/dist/commands/dashboard.d.ts +11 -0
  38. package/dist/commands/dashboard.js +242 -0
  39. package/dist/commands/dashboard.js.map +1 -0
  40. package/dist/commands/doctor.d.ts +16 -0
  41. package/dist/commands/doctor.js +195 -0
  42. package/dist/commands/doctor.js.map +1 -0
  43. package/dist/commands/history.d.ts +7 -0
  44. package/dist/commands/history.js +49 -0
  45. package/dist/commands/history.js.map +1 -0
  46. package/dist/commands/init.d.ts +45 -0
  47. package/dist/commands/install.d.ts +65 -0
  48. package/dist/commands/install.js +405 -0
  49. package/dist/commands/install.js.map +1 -0
  50. package/dist/commands/logs.d.ts +15 -0
  51. package/dist/commands/logs.js +155 -0
  52. package/dist/commands/logs.js.map +1 -0
  53. package/dist/commands/merge.d.ts +26 -0
  54. package/dist/commands/merge.js +159 -0
  55. package/dist/commands/merge.js.map +1 -0
  56. package/dist/commands/notify.d.ts +7 -0
  57. package/dist/commands/notify.js +43 -0
  58. package/dist/commands/notify.js.map +1 -0
  59. package/dist/commands/plan.d.ts +19 -0
  60. package/dist/commands/plan.js +88 -0
  61. package/dist/commands/plan.js.map +1 -0
  62. package/dist/commands/prd-state.d.ts +12 -0
  63. package/dist/commands/prd-state.js +47 -0
  64. package/dist/commands/prd-state.js.map +1 -0
  65. package/dist/commands/prd.d.ts +18 -0
  66. package/dist/commands/prd.js +363 -0
  67. package/dist/commands/prd.js.map +1 -0
  68. package/dist/commands/prds.d.ts +13 -0
  69. package/dist/commands/prds.js +194 -0
  70. package/dist/commands/prds.js.map +1 -0
  71. package/dist/commands/prs.d.ts +14 -0
  72. package/dist/commands/prs.js +104 -0
  73. package/dist/commands/prs.js.map +1 -0
  74. package/dist/commands/qa.d.ts +34 -0
  75. package/dist/commands/qa.js +214 -0
  76. package/dist/commands/qa.js.map +1 -0
  77. package/dist/commands/queue.d.ts +8 -0
  78. package/dist/commands/queue.js +378 -0
  79. package/dist/commands/queue.js.map +1 -0
  80. package/dist/commands/resolve.d.ts +26 -0
  81. package/dist/commands/resolve.js +186 -0
  82. package/dist/commands/resolve.js.map +1 -0
  83. package/dist/commands/retry.d.ts +9 -0
  84. package/dist/commands/retry.js +71 -0
  85. package/dist/commands/retry.js.map +1 -0
  86. package/dist/commands/review.d.ts +77 -0
  87. package/dist/commands/review.d.ts.map +1 -1
  88. package/dist/commands/review.js +447 -0
  89. package/dist/commands/review.js.map +1 -0
  90. package/dist/commands/run.d.ts +73 -0
  91. package/dist/commands/serve.d.ts +19 -0
  92. package/dist/commands/serve.js +142 -0
  93. package/dist/commands/serve.js.map +1 -0
  94. package/dist/commands/shared/env-builder.d.ts +49 -0
  95. package/dist/commands/shared/env-builder.js +151 -0
  96. package/dist/commands/shared/env-builder.js.map +1 -0
  97. package/dist/commands/slice.d.ts +35 -0
  98. package/dist/commands/slice.js +316 -0
  99. package/dist/commands/slice.js.map +1 -0
  100. package/dist/commands/state.d.ts +8 -0
  101. package/dist/commands/state.js +54 -0
  102. package/dist/commands/state.js.map +1 -0
  103. package/dist/commands/status.d.ts +14 -0
  104. package/dist/commands/status.js +297 -0
  105. package/dist/commands/status.js.map +1 -0
  106. package/dist/commands/summary.d.ts +14 -0
  107. package/dist/commands/summary.js +193 -0
  108. package/dist/commands/summary.js.map +1 -0
  109. package/dist/commands/uninstall.d.ts +25 -0
  110. package/dist/commands/uninstall.js +134 -0
  111. package/dist/commands/uninstall.js.map +1 -0
  112. package/dist/commands/update.d.ts +22 -0
  113. package/dist/commands/update.js +90 -0
  114. package/dist/commands/update.js.map +1 -0
  115. package/dist/scripts/night-watch-pr-reviewer-cron.sh +146 -32
  116. package/dist/templates/night-watch.config.json +1 -21
  117. package/package.json +1 -1
  118. package/dist/web/assets/index-B6E6kOoR.js +0 -406
  119. package/dist/web/assets/index-DIMUXIP8.css +0 -1
  120. package/dist/web/assets/index-NR27JE3b.js +0 -406
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Uninstall command for Night Watch CLI
3
+ * Removes crontab entries for the current project
4
+ */
5
+ import * as path from 'path';
6
+ import * as fs from 'fs';
7
+ import { dim, generateMarker, getEntries, getProjectEntries, getProjectName, removeEntriesForProject, success, error as uiError, unregisterProject, warn, } from '@night-watch/core';
8
+ /**
9
+ * Core uninstall logic, reusable from dashboard.
10
+ * Returns result without printing to console.
11
+ */
12
+ export function performUninstall(projectDir, options) {
13
+ try {
14
+ const projectName = getProjectName(projectDir);
15
+ const marker = generateMarker(projectName);
16
+ const existingEntries = Array.from(new Set([...getEntries(marker), ...getProjectEntries(projectDir)]));
17
+ if (existingEntries.length === 0) {
18
+ unregisterProject(projectDir);
19
+ return { success: true, removedCount: 0 };
20
+ }
21
+ const removedCount = removeEntriesForProject(projectDir, marker);
22
+ unregisterProject(projectDir);
23
+ if (!options?.keepLogs) {
24
+ const logDir = path.join(projectDir, 'logs');
25
+ if (fs.existsSync(logDir)) {
26
+ const logFiles = [
27
+ 'executor.log',
28
+ 'reviewer.log',
29
+ 'slicer.log',
30
+ 'audit.log',
31
+ 'pr-resolver.log',
32
+ ];
33
+ logFiles.forEach((logFile) => {
34
+ const logPath = path.join(logDir, logFile);
35
+ if (fs.existsSync(logPath)) {
36
+ fs.unlinkSync(logPath);
37
+ }
38
+ });
39
+ try {
40
+ const remainingFiles = fs.readdirSync(logDir);
41
+ if (remainingFiles.length === 0) {
42
+ fs.rmdirSync(logDir);
43
+ }
44
+ }
45
+ catch {
46
+ // Ignore errors removing directory
47
+ }
48
+ }
49
+ }
50
+ return { success: true, removedCount };
51
+ }
52
+ catch (err) {
53
+ return {
54
+ success: false,
55
+ removedCount: 0,
56
+ error: err instanceof Error ? err.message : String(err),
57
+ };
58
+ }
59
+ }
60
+ /**
61
+ * Uninstall crontab entries for night-watch
62
+ */
63
+ export function uninstallCommand(program) {
64
+ program
65
+ .command('uninstall')
66
+ .description('Remove crontab entries')
67
+ .option('--keep-logs', 'Preserve log files')
68
+ .action(async (options) => {
69
+ try {
70
+ // Get project directory
71
+ const projectDir = process.cwd();
72
+ // Get project name
73
+ const projectName = getProjectName(projectDir);
74
+ const marker = generateMarker(projectName);
75
+ // Check if there are entries to remove
76
+ const existingEntries = Array.from(new Set([...getEntries(marker), ...getProjectEntries(projectDir)]));
77
+ if (existingEntries.length === 0) {
78
+ warn(`No Night Watch crontab entries found for ${projectName}.`);
79
+ dim('Nothing to uninstall.');
80
+ return;
81
+ }
82
+ // Show entries that will be removed
83
+ dim(`Removing Night Watch crontab entries for ${projectName}:`);
84
+ existingEntries.forEach((entry) => dim(` ${entry}`));
85
+ // Remove entries
86
+ const removedCount = removeEntriesForProject(projectDir, marker);
87
+ // Handle log files
88
+ if (!options.keepLogs) {
89
+ const logDir = path.join(projectDir, 'logs');
90
+ if (fs.existsSync(logDir)) {
91
+ const logFiles = [
92
+ 'executor.log',
93
+ 'reviewer.log',
94
+ 'slicer.log',
95
+ 'audit.log',
96
+ 'pr-resolver.log',
97
+ ];
98
+ let logsRemoved = 0;
99
+ logFiles.forEach((logFile) => {
100
+ const logPath = path.join(logDir, logFile);
101
+ if (fs.existsSync(logPath)) {
102
+ fs.unlinkSync(logPath);
103
+ logsRemoved++;
104
+ }
105
+ });
106
+ // Try to remove log directory if empty
107
+ try {
108
+ const remainingFiles = fs.readdirSync(logDir);
109
+ if (remainingFiles.length === 0) {
110
+ fs.rmdirSync(logDir);
111
+ }
112
+ }
113
+ catch {
114
+ // Ignore errors removing directory
115
+ }
116
+ if (logsRemoved > 0) {
117
+ console.log();
118
+ dim(`Removed ${logsRemoved} log file(s).`);
119
+ }
120
+ }
121
+ }
122
+ else {
123
+ console.log();
124
+ dim('Log files preserved.');
125
+ }
126
+ success(`Successfully removed ${removedCount} crontab entry/entries.`);
127
+ }
128
+ catch (err) {
129
+ uiError(`Error uninstalling Night Watch: ${err instanceof Error ? err.message : String(err)}`);
130
+ process.exit(1);
131
+ }
132
+ });
133
+ }
134
+ //# sourceMappingURL=uninstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
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
+ global?: 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
+ export declare function shouldInstallGlobal(options: Pick<IUpdateOptions, 'global'>): boolean;
18
+ /**
19
+ * Register update command.
20
+ */
21
+ export declare function updateCommand(program: Command): void;
22
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1,90 @@
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 '@night-watch/core';
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
+ export function shouldInstallGlobal(options) {
26
+ return options.global !== false;
27
+ }
28
+ function runCommand(command, args, cwd) {
29
+ const result = spawnSync(command, args, {
30
+ cwd,
31
+ env: process.env,
32
+ stdio: 'inherit',
33
+ });
34
+ if (result.error) {
35
+ throw result.error;
36
+ }
37
+ if ((result.status ?? 1) !== 0) {
38
+ const location = cwd ? ` in ${cwd}` : '';
39
+ throw new Error(`Command failed${location}: ${command} ${args.join(' ')}`);
40
+ }
41
+ }
42
+ function resolveNightWatchBin() {
43
+ const result = spawnSync('which', ['night-watch'], {
44
+ encoding: 'utf-8',
45
+ env: process.env,
46
+ });
47
+ if (result.status === 0 && typeof result.stdout === 'string' && result.stdout.trim().length > 0) {
48
+ return result.stdout.trim();
49
+ }
50
+ return 'night-watch';
51
+ }
52
+ /**
53
+ * Register update command.
54
+ */
55
+ export function updateCommand(program) {
56
+ program
57
+ .command('update')
58
+ .description('Update global CLI and refresh cron for project(s)')
59
+ .option('--projects <dirs>', 'Comma-separated project directories (default: current directory)')
60
+ .option('--global-spec <spec>', 'npm package spec used for global install', DEFAULT_GLOBAL_SPEC)
61
+ .option('--no-global', 'Skip global npm install and only refresh project cron')
62
+ .action(async (options) => {
63
+ try {
64
+ const cwd = process.cwd();
65
+ const projectDirs = parseProjectDirs(options.projects, cwd);
66
+ if (shouldInstallGlobal(options)) {
67
+ dim(`Updating global install: npm install -g ${options.globalSpec}`);
68
+ runCommand('npm', ['install', '-g', options.globalSpec]);
69
+ success('Global CLI update completed.');
70
+ }
71
+ const nightWatchBin = resolveNightWatchBin();
72
+ for (const projectDir of projectDirs) {
73
+ if (!fs.existsSync(projectDir) || !fs.statSync(projectDir).isDirectory()) {
74
+ warn(`Skipping invalid project directory: ${projectDir}`);
75
+ continue;
76
+ }
77
+ dim(`Refreshing cron in ${projectDir}`);
78
+ runCommand(nightWatchBin, ['uninstall'], projectDir);
79
+ runCommand(nightWatchBin, ['install'], projectDir);
80
+ success(`Refreshed project: ${projectDir}`);
81
+ }
82
+ success('Update completed.');
83
+ }
84
+ catch (err) {
85
+ uiError(`Update failed: ${err instanceof Error ? err.message : String(err)}`);
86
+ process.exit(1);
87
+ }
88
+ });
89
+ }
90
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzE,MAAM,CAAC,MAAM,mBAAmB,GAAG,mCAAmC,CAAC;AAQvE;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAA4B,EAAE,GAAW;IACxE,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ;SAClB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;SACnC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAE5C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAuC;IACzE,OAAO,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC;AAClC,CAAC;AAED,SAAS,UAAU,CAAC,OAAe,EAAE,IAAc,EAAE,GAAY;IAC/D,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE;QACtC,GAAG;QACH,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,MAAM,CAAC,KAAK,CAAC;IACrB,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,iBAAiB,QAAQ,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB;IAC3B,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,aAAa,CAAC,EAAE;QACjD,QAAQ,EAAE,OAAO;QACjB,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChG,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,mDAAmD,CAAC;SAChE,MAAM,CAAC,mBAAmB,EAAE,kEAAkE,CAAC;SAC/F,MAAM,CAAC,sBAAsB,EAAE,0CAA0C,EAAE,mBAAmB,CAAC;SAC/F,MAAM,CAAC,aAAa,EAAE,uDAAuD,CAAC;SAC9E,MAAM,CAAC,KAAK,EAAE,OAAuB,EAAE,EAAE;QACxC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;YAC1B,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YAE5D,IAAI,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjC,GAAG,CAAC,2CAA2C,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;gBACrE,UAAU,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;gBACzD,OAAO,CAAC,8BAA8B,CAAC,CAAC;YAC1C,CAAC;YAED,MAAM,aAAa,GAAG,oBAAoB,EAAE,CAAC;YAE7C,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;gBACrC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;oBACzE,IAAI,CAAC,uCAAuC,UAAU,EAAE,CAAC,CAAC;oBAC1D,SAAS;gBACX,CAAC;gBAED,GAAG,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;gBACxC,UAAU,CAAC,aAAa,EAAE,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,CAAC;gBACrD,UAAU,CAAC,aAAa,EAAE,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,CAAC;gBACnD,OAAO,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;YAC9C,CAAC;YAED,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,kBAAkB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -79,6 +79,9 @@ else
79
79
  fi
80
80
 
81
81
  SCRIPT_TYPE="reviewer"
82
+ READY_FOR_REVIEW_LABEL="${NW_READY_FOR_REVIEW_LABEL:-ready-for-review}"
83
+ READY_FOR_REVIEW_MARKER_NAME="night-watch-ready-for-review"
84
+ READY_TO_MERGE_LABEL="${NW_PR_RESOLVER_READY_LABEL:-ready-to-merge}"
82
85
 
83
86
  emit_result() {
84
87
  local status="${1:?status required}"
@@ -98,6 +101,80 @@ extract_review_score_from_text() {
98
101
  | grep -oP '\d+(?=/100)' || echo ""
99
102
  }
100
103
 
104
+ build_ready_for_review_marker() {
105
+ local head_sha="${1:-}"
106
+ [ -z "${head_sha}" ] && return 1
107
+ printf '<!-- %s headRefOid:%s -->' "${READY_FOR_REVIEW_MARKER_NAME}" "${head_sha}"
108
+ }
109
+
110
+ has_ready_for_human_review_marker() {
111
+ local comments_text="${1:-}"
112
+ local head_sha="${2:-}"
113
+ local marker=""
114
+
115
+ marker=$(build_ready_for_review_marker "${head_sha}" || true)
116
+ [ -z "${marker}" ] && return 1
117
+
118
+ printf '%s\n' "${comments_text}" | grep -Fq "${marker}"
119
+ }
120
+
121
+ get_pr_comments() {
122
+ local pr_number="${1:?PR number required}"
123
+
124
+ {
125
+ gh pr view "${pr_number}" --json comments --jq '.comments[].body' 2>/dev/null || true
126
+ if [ -n "${REPO:-}" ]; then
127
+ gh api "repos/${REPO}/issues/${pr_number}/comments" --jq '.[].body' 2>/dev/null || true
128
+ fi
129
+ } | awk '!seen[$0]++'
130
+ }
131
+
132
+ get_pr_head_ref_oid() {
133
+ local pr_number="${1:?PR number required}"
134
+ gh pr view "${pr_number}" --json headRefOid --jq '.headRefOid' 2>/dev/null || echo ""
135
+ }
136
+
137
+ clear_ready_for_human_review_label() {
138
+ local pr_number="${1:?PR number required}"
139
+ gh pr edit "${pr_number}" --remove-label "${READY_FOR_REVIEW_LABEL}" 2>/dev/null || true
140
+ }
141
+
142
+ ensure_ready_for_human_review_comment() {
143
+ local pr_number="${1:?PR number required}"
144
+ local final_score="${2:-}"
145
+ local head_sha="${3:-}"
146
+ local comments_text=""
147
+ local marker=""
148
+ local score_note=""
149
+ local short_sha=""
150
+ local body=""
151
+
152
+ [ -z "${head_sha}" ] && return 0
153
+
154
+ comments_text=$(get_pr_comments "${pr_number}")
155
+ if has_ready_for_human_review_marker "${comments_text}" "${head_sha}"; then
156
+ gh pr edit "${pr_number}" --add-label "${READY_FOR_REVIEW_LABEL}" 2>/dev/null || true
157
+ return 0
158
+ fi
159
+
160
+ marker=$(build_ready_for_review_marker "${head_sha}" || true)
161
+ short_sha=$(printf '%s' "${head_sha}" | cut -c1-12)
162
+ if [ -n "${final_score}" ]; then
163
+ score_note=" (score: ${final_score}/100)"
164
+ fi
165
+
166
+ body="${marker}
167
+
168
+ ## ✅ Ready for Human Review
169
+
170
+ Night Watch reviewed this PR${score_note} at commit \`${short_sha}\` and found no automated fixes to apply for the current head.
171
+
172
+ This PR is ready for human review and merge."
173
+
174
+ gh pr comment "${pr_number}" --body "${body}" 2>/dev/null || true
175
+ gh pr edit "${pr_number}" --add-label "${READY_FOR_REVIEW_LABEL}" 2>/dev/null || true
176
+ }
177
+
101
178
  # ── Global Job Queue Gate ────────────────────────────────────────────────────
102
179
  # Atomically claim a DB slot or enqueue for later dispatch — no flock needed.
103
180
  if [ "${NW_QUEUE_ENABLED:-0}" = "1" ]; then
@@ -399,14 +476,7 @@ build_prd_context_prompt() {
399
476
  get_pr_score() {
400
477
  local pr_number="${1:?PR number required}"
401
478
  local all_comments
402
- all_comments=$(
403
- {
404
- gh pr view "${pr_number}" --json comments --jq '.comments[].body' 2>/dev/null || true
405
- if [ -n "${REPO:-}" ]; then
406
- gh api "repos/${REPO}/issues/${pr_number}/comments" --jq '.[].body' 2>/dev/null || true
407
- fi
408
- } | awk '!seen[$0]++'
409
- )
479
+ all_comments=$(get_pr_comments "${pr_number}")
410
480
  extract_review_score_from_text "${all_comments}"
411
481
  }
412
482
 
@@ -612,8 +682,14 @@ fi
612
682
  NEEDS_WORK=0
613
683
  REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner' 2>/dev/null || echo "")
614
684
  PRS_NEEDING_WORK=""
685
+ SKIPPED_ALREADY_REVIEWED_CURRENT_HEAD=0
615
686
 
616
687
  while IFS=$'\t' read -r pr_number pr_branch pr_labels; do
688
+ local_ready_for_review_label_present=0
689
+ current_head_sha=""
690
+ all_comments=""
691
+ latest_score=""
692
+
617
693
  if [ -z "${pr_number}" ] || [ -z "${pr_branch}" ]; then
618
694
  continue
619
695
  fi
@@ -626,6 +702,11 @@ while IFS=$'\t' read -r pr_number pr_branch pr_labels; do
626
702
  continue
627
703
  fi
628
704
 
705
+ if csv_has_label "${pr_labels:-}" "${READY_TO_MERGE_LABEL}"; then
706
+ log "INFO: PR #${pr_number} (${pr_branch}) is labeled ${READY_TO_MERGE_LABEL}; skipping automated review"
707
+ continue
708
+ fi
709
+
629
710
  if printf '%s\n' "${pr_labels:-}" | tr ',' '\n' | grep -Fxq 'needs-human-review'; then
630
711
  log "INFO: PR #${pr_number} (${pr_branch}) is labeled needs-human-review; skipping automated review"
631
712
  continue
@@ -636,17 +717,58 @@ while IFS=$'\t' read -r pr_number pr_branch pr_labels; do
636
717
  continue
637
718
  fi
638
719
 
720
+ if csv_has_label "${pr_labels:-}" "${READY_FOR_REVIEW_LABEL}"; then
721
+ local_ready_for_review_label_present=1
722
+ fi
723
+
639
724
  # Merge-conflict signal: this PR needs action even if CI and score look fine.
640
725
  MERGE_STATE=$(gh pr view "${pr_number}" --json mergeStateStatus --jq '.mergeStateStatus' 2>/dev/null || echo "")
641
726
  if [ "${MERGE_STATE}" = "DIRTY" ] || [ "${MERGE_STATE}" = "CONFLICTING" ]; then
727
+ if [ "${local_ready_for_review_label_present}" -eq 1 ]; then
728
+ log "INFO: PR #${pr_number} (${pr_branch}) is actionable again; removing stale ${READY_FOR_REVIEW_LABEL} label"
729
+ clear_ready_for_human_review_label "${pr_number}"
730
+ fi
642
731
  log "INFO: PR #${pr_number} (${pr_branch}) has merge conflicts (${MERGE_STATE})"
643
732
  NEEDS_WORK=1
644
733
  PRS_NEEDING_WORK="${PRS_NEEDING_WORK} #${pr_number}"
645
734
  continue
646
735
  fi
647
736
 
737
+ current_head_sha=$(get_pr_head_ref_oid "${pr_number}")
738
+ all_comments=$(get_pr_comments "${pr_number}")
739
+ latest_score=$(extract_review_score_from_text "${all_comments}")
740
+ if [ -z "${latest_score}" ]; then
741
+ if [ "${local_ready_for_review_label_present}" -eq 1 ]; then
742
+ log "INFO: PR #${pr_number} (${pr_branch}) needs a fresh review; removing stale ${READY_FOR_REVIEW_LABEL} label"
743
+ clear_ready_for_human_review_label "${pr_number}"
744
+ fi
745
+ log "INFO: PR #${pr_number} (${pr_branch}) has no review score yet — needs initial review"
746
+ NEEDS_WORK=1
747
+ PRS_NEEDING_WORK="${PRS_NEEDING_WORK} #${pr_number}"
748
+ continue
749
+ elif [ "${latest_score}" -lt "${MIN_REVIEW_SCORE}" ]; then
750
+ if [ "${local_ready_for_review_label_present}" -eq 1 ]; then
751
+ log "INFO: PR #${pr_number} (${pr_branch}) fell below review threshold; removing stale ${READY_FOR_REVIEW_LABEL} label"
752
+ clear_ready_for_human_review_label "${pr_number}"
753
+ fi
754
+ log "INFO: PR #${pr_number} (${pr_branch}) has review score ${latest_score}/100 (threshold: ${MIN_REVIEW_SCORE})"
755
+ NEEDS_WORK=1
756
+ PRS_NEEDING_WORK="${PRS_NEEDING_WORK} #${pr_number}"
757
+ continue
758
+ fi
759
+
760
+ if has_ready_for_human_review_marker "${all_comments}" "${current_head_sha}"; then
761
+ SKIPPED_ALREADY_REVIEWED_CURRENT_HEAD=1
762
+ log "INFO: PR #${pr_number} (${pr_branch}) is already marked ready for human review at head ${current_head_sha:0:12}; skipping repeat automated review"
763
+ continue
764
+ fi
765
+
648
766
  FAILED_CHECKS=$(get_pr_failed_ci_checks "${pr_number}")
649
767
  if [ "${FAILED_CHECKS}" -gt 0 ]; then
768
+ if [ "${local_ready_for_review_label_present}" -eq 1 ]; then
769
+ log "INFO: PR #${pr_number} (${pr_branch}) is actionable again; removing stale ${READY_FOR_REVIEW_LABEL} label"
770
+ clear_ready_for_human_review_label "${pr_number}"
771
+ fi
650
772
  FAILED_SUMMARY=$(get_pr_failed_ci_summary "${pr_number}")
651
773
  if [ -n "${FAILED_SUMMARY}" ]; then
652
774
  log "INFO: PR #${pr_number} (${pr_branch}) has ${FAILED_CHECKS} failed CI check(s): ${FAILED_SUMMARY}"
@@ -655,26 +777,6 @@ while IFS=$'\t' read -r pr_number pr_branch pr_labels; do
655
777
  fi
656
778
  NEEDS_WORK=1
657
779
  PRS_NEEDING_WORK="${PRS_NEEDING_WORK} #${pr_number}"
658
- continue
659
- fi
660
-
661
- ALL_COMMENTS=$(
662
- {
663
- gh pr view "${pr_number}" --json comments --jq '.comments[].body' 2>/dev/null || true
664
- if [ -n "${REPO}" ]; then
665
- gh api "repos/${REPO}/issues/${pr_number}/comments" --jq '.[].body' 2>/dev/null || true
666
- fi
667
- } | awk '!seen[$0]++'
668
- )
669
- LATEST_SCORE=$(extract_review_score_from_text "${ALL_COMMENTS}")
670
- if [ -z "${LATEST_SCORE}" ]; then
671
- log "INFO: PR #${pr_number} (${pr_branch}) has no review score yet — needs initial review"
672
- NEEDS_WORK=1
673
- PRS_NEEDING_WORK="${PRS_NEEDING_WORK} #${pr_number}"
674
- elif [ "${LATEST_SCORE}" -lt "${MIN_REVIEW_SCORE}" ]; then
675
- log "INFO: PR #${pr_number} (${pr_branch}) has review score ${LATEST_SCORE}/100 (threshold: ${MIN_REVIEW_SCORE})"
676
- NEEDS_WORK=1
677
- PRS_NEEDING_WORK="${PRS_NEEDING_WORK} #${pr_number}"
678
780
  fi
679
781
  done < <(
680
782
  gh pr list --state open --json number,headRefName,labels \
@@ -682,14 +784,25 @@ done < <(
682
784
  )
683
785
 
684
786
  if [ "${NEEDS_WORK}" -eq 0 ]; then
685
- log "SKIP: All ${OPEN_PRS} open PR(s) have passing CI and review score >= ${MIN_REVIEW_SCORE}"
787
+ if [ "${SKIPPED_ALREADY_REVIEWED_CURRENT_HEAD}" -eq 1 ]; then
788
+ log "SKIP: All ${OPEN_PRS} open PR(s) already pass review threshold or have already been reviewed for their current head"
686
789
 
687
- if [ "${WORKER_MODE}" != "1" ]; then
688
- send_telegram_status_message "🔍 Night Watch Reviewer: nothing to do" "Project: ${PROJECT_NAME}
790
+ if [ "${WORKER_MODE}" != "1" ]; then
791
+ send_telegram_status_message "🔍 Night Watch Reviewer: nothing actionable" "Project: ${PROJECT_NAME}
792
+ Provider (model): ${PROVIDER_MODEL_DISPLAY}
793
+ Result: all ${OPEN_PRS} matching PRs either already pass review threshold or were already reviewed for their current head."
794
+ fi
795
+ emit_result "skip_no_actionable_prs"
796
+ else
797
+ log "SKIP: All ${OPEN_PRS} open PR(s) have passing CI and review score >= ${MIN_REVIEW_SCORE}"
798
+
799
+ if [ "${WORKER_MODE}" != "1" ]; then
800
+ send_telegram_status_message "🔍 Night Watch Reviewer: nothing to do" "Project: ${PROJECT_NAME}
689
801
  Provider (model): ${PROVIDER_MODEL_DISPLAY}
690
802
  Result: all ${OPEN_PRS} matching PRs already pass CI and review threshold (${MIN_REVIEW_SCORE})."
803
+ fi
804
+ emit_result "skip_all_passing"
691
805
  fi
692
- emit_result "skip_all_passing"
693
806
  exit 0
694
807
  fi
695
808
 
@@ -1215,6 +1328,7 @@ if [ "${EXIT_CODE}" -eq 0 ] && [ -n "${TARGET_PR}" ] && [ -n "${PR_BRANCH_HEAD_B
1215
1328
  NO_CHANGES_NEEDED=1
1216
1329
  NO_CHANGES_PRS="#${TARGET_PR}"
1217
1330
  log "INFO: PR #${TARGET_PR} — reviewer made no commits; marking as ready for human review"
1331
+ ensure_ready_for_human_review_comment "${TARGET_PR}" "${FINAL_SCORE}" "${PR_BRANCH_HEAD_AFTER}"
1218
1332
  fi
1219
1333
  fi
1220
1334
 
@@ -55,9 +55,7 @@
55
55
  "audit": 10
56
56
  }
57
57
  },
58
- "jobProviders": {
59
- "reviewer": "g51claude"
60
- },
58
+ "jobProviders": {},
61
59
  "autoMerge": false,
62
60
  "autoMergeMethod": "squash",
63
61
  "fallbackOnRateLimit": true,
@@ -75,23 +73,5 @@
75
73
  "enabled": true,
76
74
  "schedule": "50 3 * * 1",
77
75
  "maxRuntime": 1800
78
- },
79
- "providerPresets": {
80
- "g51claude": {
81
- "name": "GLM-5.1 Claude",
82
- "command": "claude",
83
- "promptFlag": "-p",
84
- "autoApproveFlag": "--dangerously-skip-permissions",
85
- "modelFlag": "--model",
86
- "model": "glm-5.1",
87
- "envVars": {
88
- "ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic",
89
- "API_TIMEOUT_MS": "3000000",
90
- "ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-5.1",
91
- "ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-5.1",
92
- "ANTHROPIC_AUTH_TOKEN": "efaeca456dab4ae69cb9ce1fa8d99a1a.KSTifNTWPS6NgC6L",
93
- "ANTHROPIC_API_KEY": "efaeca456dab4ae69cb9ce1fa8d99a1a.KSTifNTWPS6NgC6L"
94
- }
95
- }
96
76
  }
97
77
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jonit-dev/night-watch-cli",
3
- "version": "1.8.11",
3
+ "version": "1.8.12-beta.1",
4
4
  "description": "AI agent that implements your specs, opens PRs, and reviews code overnight. Queue GitHub issues or PRDs, wake up to pull requests.",
5
5
  "type": "module",
6
6
  "bin": {