@jonit-dev/night-watch-cli 1.8.12-beta.0 → 1.8.12-beta.10

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 (154) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.js +3281 -651
  3. package/dist/cli.js.map +1 -0
  4. package/dist/commands/agent.d.ts +12 -0
  5. package/dist/commands/agent.d.ts.map +1 -0
  6. package/dist/commands/agent.js +307 -0
  7. package/dist/commands/agent.js.map +1 -0
  8. package/dist/commands/analytics.d.ts +14 -0
  9. package/dist/commands/analytics.d.ts.map +1 -1
  10. package/dist/commands/analytics.js +129 -0
  11. package/dist/commands/analytics.js.map +1 -0
  12. package/dist/commands/audit.d.ts +19 -0
  13. package/dist/commands/audit.d.ts.map +1 -1
  14. package/dist/commands/audit.js +189 -0
  15. package/dist/commands/audit.js.map +1 -0
  16. package/dist/commands/board.d.ts +9 -0
  17. package/dist/commands/board.js +702 -0
  18. package/dist/commands/board.js.map +1 -0
  19. package/dist/commands/cancel.d.ts +46 -0
  20. package/dist/commands/cancel.js +239 -0
  21. package/dist/commands/cancel.js.map +1 -0
  22. package/dist/commands/cron.d.ts +8 -0
  23. package/dist/commands/cron.js +134 -0
  24. package/dist/commands/cron.js.map +1 -0
  25. package/dist/commands/dashboard/tab-actions.d.ts +10 -0
  26. package/dist/commands/dashboard/tab-actions.js +247 -0
  27. package/dist/commands/dashboard/tab-actions.js.map +1 -0
  28. package/dist/commands/dashboard/tab-config.d.ts +21 -0
  29. package/dist/commands/dashboard/tab-config.js +874 -0
  30. package/dist/commands/dashboard/tab-config.js.map +1 -0
  31. package/dist/commands/dashboard/tab-logs.d.ts +10 -0
  32. package/dist/commands/dashboard/tab-logs.js +202 -0
  33. package/dist/commands/dashboard/tab-logs.js.map +1 -0
  34. package/dist/commands/dashboard/tab-schedules.d.ts +21 -0
  35. package/dist/commands/dashboard/tab-schedules.js +320 -0
  36. package/dist/commands/dashboard/tab-schedules.js.map +1 -0
  37. package/dist/commands/dashboard/tab-status.d.ts +32 -0
  38. package/dist/commands/dashboard/tab-status.js +424 -0
  39. package/dist/commands/dashboard/tab-status.js.map +1 -0
  40. package/dist/commands/dashboard/types.d.ts +42 -0
  41. package/dist/commands/dashboard/types.js +5 -0
  42. package/dist/commands/dashboard/types.js.map +1 -0
  43. package/dist/commands/dashboard.d.ts +11 -0
  44. package/dist/commands/dashboard.js +242 -0
  45. package/dist/commands/dashboard.js.map +1 -0
  46. package/dist/commands/doctor.d.ts +16 -0
  47. package/dist/commands/doctor.js +195 -0
  48. package/dist/commands/doctor.js.map +1 -0
  49. package/dist/commands/history.d.ts +7 -0
  50. package/dist/commands/history.js +49 -0
  51. package/dist/commands/history.js.map +1 -0
  52. package/dist/commands/init.d.ts +45 -0
  53. package/dist/commands/init.d.ts.map +1 -1
  54. package/dist/commands/init.js +13 -0
  55. package/dist/commands/init.js.map +1 -1
  56. package/dist/commands/install.d.ts +65 -0
  57. package/dist/commands/install.js +405 -0
  58. package/dist/commands/install.js.map +1 -0
  59. package/dist/commands/logs.d.ts +15 -0
  60. package/dist/commands/logs.js +155 -0
  61. package/dist/commands/logs.js.map +1 -0
  62. package/dist/commands/merge.d.ts +26 -0
  63. package/dist/commands/merge.d.ts.map +1 -1
  64. package/dist/commands/merge.js +186 -0
  65. package/dist/commands/merge.js.map +1 -0
  66. package/dist/commands/notify.d.ts +7 -0
  67. package/dist/commands/notify.js +43 -0
  68. package/dist/commands/notify.js.map +1 -0
  69. package/dist/commands/plan.d.ts +19 -0
  70. package/dist/commands/plan.d.ts.map +1 -1
  71. package/dist/commands/plan.js +133 -0
  72. package/dist/commands/plan.js.map +1 -0
  73. package/dist/commands/prd-state.d.ts +12 -0
  74. package/dist/commands/prd-state.js +47 -0
  75. package/dist/commands/prd-state.js.map +1 -0
  76. package/dist/commands/prd.d.ts +18 -0
  77. package/dist/commands/prd.js +363 -0
  78. package/dist/commands/prd.js.map +1 -0
  79. package/dist/commands/prds.d.ts +13 -0
  80. package/dist/commands/prds.js +194 -0
  81. package/dist/commands/prds.js.map +1 -0
  82. package/dist/commands/prs.d.ts +14 -0
  83. package/dist/commands/prs.js +104 -0
  84. package/dist/commands/prs.js.map +1 -0
  85. package/dist/commands/qa.d.ts +34 -0
  86. package/dist/commands/qa.d.ts.map +1 -1
  87. package/dist/commands/qa.js +238 -0
  88. package/dist/commands/qa.js.map +1 -0
  89. package/dist/commands/queue.d.ts +8 -0
  90. package/dist/commands/queue.d.ts.map +1 -1
  91. package/dist/commands/queue.js +398 -0
  92. package/dist/commands/queue.js.map +1 -0
  93. package/dist/commands/resolve.d.ts +26 -0
  94. package/dist/commands/resolve.d.ts.map +1 -1
  95. package/dist/commands/resolve.js +212 -0
  96. package/dist/commands/resolve.js.map +1 -0
  97. package/dist/commands/retry.d.ts +9 -0
  98. package/dist/commands/retry.js +71 -0
  99. package/dist/commands/retry.js.map +1 -0
  100. package/dist/commands/review.d.ts +79 -0
  101. package/dist/commands/review.d.ts.map +1 -1
  102. package/dist/commands/review.js +47 -75
  103. package/dist/commands/review.js.map +1 -1
  104. package/dist/commands/run.d.ts +88 -0
  105. package/dist/commands/run.d.ts.map +1 -1
  106. package/dist/commands/run.js +85 -1
  107. package/dist/commands/run.js.map +1 -1
  108. package/dist/commands/serve.d.ts +19 -0
  109. package/dist/commands/serve.js +142 -0
  110. package/dist/commands/serve.js.map +1 -0
  111. package/dist/commands/shared/env-builder.d.ts +49 -0
  112. package/dist/commands/shared/env-builder.d.ts.map +1 -1
  113. package/dist/commands/shared/env-builder.js +152 -0
  114. package/dist/commands/shared/env-builder.js.map +1 -0
  115. package/dist/commands/shared/feedback.d.ts +24 -0
  116. package/dist/commands/shared/feedback.d.ts.map +1 -0
  117. package/dist/commands/shared/feedback.js +38 -0
  118. package/dist/commands/shared/feedback.js.map +1 -0
  119. package/dist/commands/slice.d.ts +35 -0
  120. package/dist/commands/slice.d.ts.map +1 -1
  121. package/dist/commands/slice.js +363 -0
  122. package/dist/commands/slice.js.map +1 -0
  123. package/dist/commands/state.d.ts +8 -0
  124. package/dist/commands/state.js +54 -0
  125. package/dist/commands/state.js.map +1 -0
  126. package/dist/commands/status.d.ts +14 -0
  127. package/dist/commands/status.js +297 -0
  128. package/dist/commands/status.js.map +1 -0
  129. package/dist/commands/summary.d.ts +14 -0
  130. package/dist/commands/summary.js +193 -0
  131. package/dist/commands/summary.js.map +1 -0
  132. package/dist/commands/uninstall.d.ts +25 -0
  133. package/dist/commands/uninstall.js +134 -0
  134. package/dist/commands/uninstall.js.map +1 -0
  135. package/dist/commands/update.d.ts +22 -0
  136. package/dist/commands/update.js +90 -0
  137. package/dist/commands/update.js.map +1 -0
  138. package/dist/scripts/night-watch-audit-cron.sh +1 -0
  139. package/dist/scripts/night-watch-cron.sh +186 -23
  140. package/dist/scripts/night-watch-helpers.sh +65 -2
  141. package/dist/scripts/night-watch-merger-cron.sh +137 -36
  142. package/dist/scripts/night-watch-plan-cron.sh +2 -0
  143. package/dist/scripts/night-watch-pr-resolver-cron.sh +6 -0
  144. package/dist/scripts/night-watch-pr-reviewer-cron.sh +22 -5
  145. package/dist/scripts/night-watch-qa-cron.sh +8 -1
  146. package/dist/scripts/night-watch-slicer-cron.sh +3 -0
  147. package/dist/templates/night-watch.config.json +21 -20
  148. package/dist/templates/slicer.md +3 -0
  149. package/dist/web/assets/index-C-xpWpS8.css +1 -0
  150. package/dist/web/assets/index-CEYe-290.js +412 -0
  151. package/dist/web/assets/index-DpvzoXEv.js +442 -0
  152. package/dist/web/assets/index-DyME41HV.css +1 -0
  153. package/dist/web/index.html +2 -2
  154. package/package.json +3 -1
@@ -0,0 +1,398 @@
1
+ /**
2
+ * Queue command — manage the global job queue.
3
+ * Provides subcommands for viewing, clearing, and dispatching queued jobs.
4
+ */
5
+ import * as path from 'path';
6
+ import { spawn } from 'child_process';
7
+ import chalk from 'chalk';
8
+ import { Command } from 'commander';
9
+ import { DEFAULT_QUEUE_MAX_WAIT_TIME, canStartJob, claimJobSlot, clearQueue, dispatchNextJob, enqueueJob, expireStaleJobs, getQueueStatus, getScriptPath, loadConfig, markJobRunning, removeJob, resolveJobProvider, resolvePreset, resolveProviderBucketKey, updateJobStatus, } from '@night-watch/core';
10
+ import { createLogger } from '@night-watch/core';
11
+ import { buildQueuedJobEnv } from './shared/env-builder.js';
12
+ const logger = createLogger('queue');
13
+ const VALID_JOB_TYPES = [
14
+ 'executor',
15
+ 'reviewer',
16
+ 'qa',
17
+ 'audit',
18
+ 'slicer',
19
+ 'planner',
20
+ 'pr-resolver',
21
+ 'merger',
22
+ ];
23
+ function formatTimestamp(unixTs) {
24
+ if (unixTs === null)
25
+ return '-';
26
+ return new Date(unixTs * 1000).toLocaleString();
27
+ }
28
+ function formatDuration(unixTs) {
29
+ const now = Math.floor(Date.now() / 1000);
30
+ const diff = now - unixTs;
31
+ if (diff < 60)
32
+ return `${diff}s ago`;
33
+ if (diff < 3600)
34
+ return `${Math.floor(diff / 60)}m ago`;
35
+ if (diff < 86400)
36
+ return `${Math.floor(diff / 3600)}h ago`;
37
+ return `${Math.floor(diff / 86400)}d ago`;
38
+ }
39
+ function printQueueEntry(entry, indent = '') {
40
+ console.log(`${indent}${chalk.bold(`[${entry.id}]`)} ${chalk.cyan(entry.jobType)} for ${chalk.dim(entry.projectName)}`);
41
+ console.log(`${indent} Status: ${entry.status} | Priority: ${entry.priority} | Enqueued: ${formatDuration(entry.enqueuedAt)}`);
42
+ if (entry.dispatchedAt) {
43
+ console.log(`${indent} Dispatched: ${formatTimestamp(entry.dispatchedAt)}`);
44
+ }
45
+ }
46
+ function isJobPaused(projectDir, jobType) {
47
+ try {
48
+ return loadConfig(projectDir).pausedJobs?.[jobType] === true;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ export function createQueueCommand() {
55
+ const queue = new Command('queue');
56
+ queue.description('Manage the global job queue');
57
+ // night-watch queue status
58
+ queue
59
+ .command('status')
60
+ .description('Show current queue status')
61
+ .option('--json', 'Output as JSON')
62
+ .action((opts) => {
63
+ const status = getQueueStatus();
64
+ if (opts.json) {
65
+ console.log(JSON.stringify({ ...status, enabled: true }, null, 2));
66
+ return;
67
+ }
68
+ console.log(chalk.bold('\n📦 Global Job Queue Status\n'));
69
+ if (status.running) {
70
+ console.log(chalk.yellow('🔄 Running:'));
71
+ printQueueEntry(status.running, ' ');
72
+ console.log();
73
+ }
74
+ else {
75
+ console.log(chalk.dim(' No job currently running'));
76
+ }
77
+ console.log();
78
+ console.log(chalk.bold(`📋 Pending: ${status.pending.total} jobs`));
79
+ if (status.pending.total > 0) {
80
+ const byType = Object.entries(status.pending.byType);
81
+ if (byType.length > 0) {
82
+ console.log(' By type:');
83
+ for (const [type, count] of byType) {
84
+ console.log(` ${type}: ${count}`);
85
+ }
86
+ }
87
+ console.log();
88
+ console.log(chalk.dim(' Next up:'));
89
+ const nextUp = status.items.find((i) => i.status === 'pending');
90
+ if (nextUp) {
91
+ printQueueEntry(nextUp, ' ');
92
+ }
93
+ }
94
+ if (status.items.length > 1) {
95
+ console.log();
96
+ console.log(chalk.dim(' All queued items:'));
97
+ for (const item of status.items) {
98
+ if (item.status === 'pending') {
99
+ printQueueEntry(item, ' ');
100
+ }
101
+ }
102
+ }
103
+ console.log();
104
+ });
105
+ // night-watch queue list
106
+ queue
107
+ .command('list')
108
+ .description('List all queue entries')
109
+ .option('--status <status>', 'Filter by status (pending, running, dispatched, expired)')
110
+ .option('--json', 'Output as JSON')
111
+ .action((opts) => {
112
+ const status = getQueueStatus();
113
+ let items = status.items;
114
+ if (opts.status) {
115
+ items = items.filter((i) => i.status === opts.status);
116
+ }
117
+ if (opts.json) {
118
+ console.log(JSON.stringify(items, null, 2));
119
+ return;
120
+ }
121
+ if (items.length === 0) {
122
+ console.log(chalk.dim('No queue entries found.'));
123
+ return;
124
+ }
125
+ console.log(chalk.bold(`\n📋 Queue Entries (${items.length})\n`));
126
+ for (const item of items) {
127
+ printQueueEntry(item);
128
+ console.log();
129
+ }
130
+ });
131
+ // night-watch queue clear
132
+ queue
133
+ .command('clear')
134
+ .description('Clear pending jobs from the queue')
135
+ .option('--type <type>', 'Only clear jobs of this type')
136
+ .option('--all', 'Clear all entries including running (dangerous)')
137
+ .action((opts) => {
138
+ if (opts.type && !VALID_JOB_TYPES.includes(opts.type)) {
139
+ console.error(chalk.red(`Invalid job type: ${opts.type}`));
140
+ console.error(chalk.dim(`Valid types: ${VALID_JOB_TYPES.join(', ')}`));
141
+ process.exit(1);
142
+ }
143
+ const count = clearQueue(opts.type);
144
+ console.log(chalk.green(`Cleared ${count} pending job(s) from the queue.`));
145
+ });
146
+ // night-watch queue enqueue
147
+ queue
148
+ .command('enqueue <job-type> <project-dir>')
149
+ .description('Manually enqueue a job')
150
+ .option('--env <json>', 'JSON object of environment variables to store', '{}')
151
+ .option('--provider-key <key>', 'Provider bucket key (e.g. claude-native, codex)')
152
+ .action((jobType, projectDir, opts) => {
153
+ if (!VALID_JOB_TYPES.includes(jobType)) {
154
+ console.error(chalk.red(`Invalid job type: ${jobType}`));
155
+ console.error(chalk.dim(`Valid types: ${VALID_JOB_TYPES.join(', ')}`));
156
+ process.exit(1);
157
+ }
158
+ let envVars = {};
159
+ if (opts.env) {
160
+ try {
161
+ envVars = JSON.parse(opts.env);
162
+ }
163
+ catch {
164
+ console.error(chalk.red('Invalid JSON for --env'));
165
+ process.exit(1);
166
+ }
167
+ }
168
+ const projectName = path.basename(projectDir);
169
+ const queueConfig = loadConfig(projectDir).queue;
170
+ if (isJobPaused(projectDir, jobType)) {
171
+ logger.info(`Skipping enqueue for paused job: ${jobType}`);
172
+ return;
173
+ }
174
+ const id = enqueueJob(projectDir, projectName, jobType, envVars, queueConfig, opts.providerKey);
175
+ console.log(chalk.green(`Enqueued ${jobType} for ${projectName} (ID: ${id})`));
176
+ });
177
+ // night-watch queue resolve-key
178
+ queue
179
+ .command('resolve-key')
180
+ .description('Resolve the provider bucket key for a given project and job type')
181
+ .requiredOption('--project <dir>', 'Project directory')
182
+ .requiredOption('--job-type <type>', 'Job type (executor, reviewer, qa, audit, slicer, planner, pr-resolver, merger)')
183
+ .action((opts) => {
184
+ try {
185
+ const config = loadConfig(opts.project);
186
+ const presetId = resolveJobProvider(config, opts.jobType);
187
+ const preset = resolvePreset(config, presetId);
188
+ const effectiveProviderEnv = {
189
+ ...(config.providerEnv ?? {}),
190
+ ...(preset.envVars ?? {}),
191
+ };
192
+ const key = resolveProviderBucketKey(preset.command, effectiveProviderEnv);
193
+ process.stdout.write(`${key}\n`);
194
+ }
195
+ catch {
196
+ process.stdout.write('');
197
+ }
198
+ process.exit(0);
199
+ });
200
+ // night-watch queue dispatch
201
+ queue
202
+ .command('dispatch')
203
+ .description('Dispatch the next pending job (used by cron scripts)')
204
+ .option('--log <file>', 'Log file to write dispatch output')
205
+ .option('--project-dir <dir>', 'Project directory to load queue config from (defaults to cwd)')
206
+ .action((_opts) => {
207
+ const configDir = _opts.projectDir ?? process.cwd();
208
+ const entry = dispatchNextJob(loadConfig(configDir).queue);
209
+ if (!entry) {
210
+ logger.info('No pending jobs to dispatch');
211
+ return;
212
+ }
213
+ if (isJobPaused(entry.projectPath, entry.jobType)) {
214
+ logger.info(`Skipping paused queued job: ${entry.jobType} for ${entry.projectName}`);
215
+ removeJob(entry.id);
216
+ return;
217
+ }
218
+ logger.info(`Dispatching ${entry.jobType} for ${entry.projectName} (ID: ${entry.id})`);
219
+ // Construct the spawn command based on job type
220
+ const scriptName = getScriptNameForJobType(entry.jobType);
221
+ if (!scriptName) {
222
+ logger.error(`Unknown job type: ${entry.jobType}`);
223
+ return;
224
+ }
225
+ // Rebuild env from queued project's config (not from dispatcher process.env)
226
+ // This ensures provider-specific env (ANTHROPIC_BASE_URL, API keys, model ids)
227
+ // always comes from the queued job's own project config.
228
+ let projectEnv;
229
+ try {
230
+ projectEnv = buildQueuedJobEnv(entry);
231
+ }
232
+ catch {
233
+ // If config load fails, fall back to process env
234
+ projectEnv = {};
235
+ }
236
+ const env = {
237
+ ...process.env,
238
+ ...projectEnv,
239
+ // Overlay persisted runtime-only NW_* queue markers from the queue entry
240
+ // (These are queue-specific flags, not provider identity)
241
+ ...filterQueueMarkers(entry.envJson),
242
+ NW_QUEUE_DISPATCHED: '1',
243
+ NW_QUEUE_ENTRY_ID: String(entry.id),
244
+ };
245
+ // Resolve the bundled script path for the current install context.
246
+ const scriptPath = getScriptPath(scriptName);
247
+ logger.info(`Spawning: ${scriptPath} ${entry.projectPath}`);
248
+ try {
249
+ // Spawn as detached to let it run independently
250
+ const child = spawn('bash', [scriptPath, entry.projectPath], {
251
+ detached: true,
252
+ stdio: 'ignore',
253
+ env,
254
+ cwd: entry.projectPath,
255
+ });
256
+ child.unref();
257
+ logger.info(`Spawned PID: ${child.pid}`);
258
+ // Mark as running now that the process is launched
259
+ markJobRunning(entry.id, child.pid ?? undefined);
260
+ }
261
+ catch (error) {
262
+ updateJobStatus(entry.id, 'pending');
263
+ logger.error(`Failed to dispatch ${entry.jobType} for ${entry.projectName}: ${error instanceof Error ? error.message : String(error)}`);
264
+ process.exit(1);
265
+ }
266
+ });
267
+ // night-watch queue claim
268
+ queue
269
+ .command('claim <job-type> <project-dir>')
270
+ .description('Atomically claim a concurrency slot and insert a running entry (used by cron scripts)')
271
+ .option('--provider-key <key>', 'Provider bucket key (e.g. claude-native, codex)')
272
+ .option('--pid <pid>', 'PID of the calling process (stored for stale-job detection)')
273
+ .action((jobType, projectDir, opts) => {
274
+ if (!VALID_JOB_TYPES.includes(jobType)) {
275
+ console.error(`Invalid job type: ${jobType}`);
276
+ console.error(`Valid types: ${VALID_JOB_TYPES.join(', ')}`);
277
+ process.exit(1);
278
+ }
279
+ const queueConfig = loadConfig(projectDir).queue;
280
+ if (isJobPaused(projectDir, jobType)) {
281
+ process.exit(2);
282
+ }
283
+ const projectName = path.basename(projectDir);
284
+ const callerPid = opts.pid ? parseInt(opts.pid, 10) : undefined;
285
+ const result = claimJobSlot(projectDir, projectName, jobType, opts.providerKey, queueConfig, callerPid);
286
+ if (!result.claimed) {
287
+ process.exit(1);
288
+ }
289
+ // Print only the numeric ID so bash callers can capture it cleanly.
290
+ process.stdout.write(`${result.id}\n`);
291
+ process.exit(0);
292
+ });
293
+ queue
294
+ .command('complete <id>')
295
+ .description('Remove a completed queue entry (used by cron scripts)')
296
+ .action((id) => {
297
+ const queueId = parseInt(id, 10);
298
+ if (isNaN(queueId) || queueId < 1) {
299
+ console.error(chalk.red('Queue entry id must be a positive integer'));
300
+ process.exit(1);
301
+ }
302
+ removeJob(queueId);
303
+ });
304
+ queue
305
+ .command('can-start')
306
+ .description('Return a zero exit status when the global queue has an available slot')
307
+ .option('--project-dir <dir>', 'Project directory to load queue config from (defaults to cwd)')
308
+ .action((opts) => {
309
+ const configDir = opts.projectDir ?? process.cwd();
310
+ const queueConfig = loadConfig(configDir).queue;
311
+ process.exit(canStartJob(queueConfig) ? 0 : 1);
312
+ });
313
+ // night-watch queue expire
314
+ queue
315
+ .command('expire')
316
+ .description('Expire stale queued jobs')
317
+ .option('--max-wait <seconds>', 'Maximum wait time in seconds', String(DEFAULT_QUEUE_MAX_WAIT_TIME))
318
+ .action((opts) => {
319
+ const maxWait = parseInt(opts.maxWait, 10);
320
+ if (isNaN(maxWait) || maxWait < 60) {
321
+ console.error(chalk.red('--max-wait must be at least 60 seconds'));
322
+ process.exit(1);
323
+ }
324
+ const count = expireStaleJobs(maxWait);
325
+ if (count > 0) {
326
+ console.log(chalk.yellow(`Expired ${count} stale job(s)`));
327
+ }
328
+ else {
329
+ console.log(chalk.dim('No stale jobs to expire'));
330
+ }
331
+ });
332
+ return queue;
333
+ }
334
+ /**
335
+ * NW_* env keys that are legitimate queue/runtime markers (not provider identity keys).
336
+ * Only these keys from a queued entry's envJson are forwarded at dispatch time.
337
+ * Provider identity (ANTHROPIC_BASE_URL, API keys, model ids) is always recomputed
338
+ * from the queued job's own project config via buildQueuedJobEnv.
339
+ */
340
+ const QUEUE_MARKER_KEYS = new Set([
341
+ 'NW_DRY_RUN',
342
+ 'NW_CRON_TRIGGER',
343
+ 'NW_DEFAULT_BRANCH',
344
+ 'NW_TARGET_PR',
345
+ 'NW_REVIEWER_WORKER_MODE',
346
+ 'NW_REVIEWER_PARALLEL',
347
+ 'NW_REVIEWER_WORKER_STAGGER',
348
+ 'NW_REVIEWER_MAX_RUNTIME',
349
+ 'NW_REVIEWER_MAX_RETRIES',
350
+ 'NW_REVIEWER_RETRY_DELAY',
351
+ 'NW_REVIEWER_MAX_PRS_PER_RUN',
352
+ 'NW_MIN_REVIEW_SCORE',
353
+ 'NW_BRANCH_PATTERNS',
354
+ 'NW_PRD_DIR',
355
+ 'NW_AUTO_MERGE',
356
+ 'NW_AUTO_MERGE_METHOD',
357
+ 'NW_MAX_RUNTIME',
358
+ 'NW_QA_MAX_RUNTIME',
359
+ ]);
360
+ /**
361
+ * Filter envJson to only pass through legitimate queue/runtime markers.
362
+ * Drops any provider identity keys that may have been persisted in the queue entry.
363
+ */
364
+ function filterQueueMarkers(envJson) {
365
+ const result = {};
366
+ for (const [key, value] of Object.entries(envJson)) {
367
+ if (QUEUE_MARKER_KEYS.has(key)) {
368
+ result[key] = value;
369
+ }
370
+ }
371
+ return result;
372
+ }
373
+ function getScriptNameForJobType(jobType) {
374
+ switch (jobType) {
375
+ case 'executor':
376
+ return 'night-watch-cron.sh';
377
+ case 'reviewer':
378
+ return 'night-watch-pr-reviewer-cron.sh';
379
+ case 'qa':
380
+ return 'night-watch-qa-cron.sh';
381
+ case 'audit':
382
+ return 'night-watch-audit-cron.sh';
383
+ case 'slicer':
384
+ return 'night-watch-slicer-cron.sh';
385
+ case 'planner':
386
+ return 'night-watch-plan-cron.sh';
387
+ case 'pr-resolver':
388
+ return 'night-watch-pr-resolver-cron.sh';
389
+ case 'merger':
390
+ return 'night-watch-merger-cron.sh';
391
+ default:
392
+ return null;
393
+ }
394
+ }
395
+ export function queueCommand(program) {
396
+ program.addCommand(createQueueCommand());
397
+ }
398
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/commands/queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Resolve command - executes the PR resolver cron script
3
+ */
4
+ import { Command } from 'commander';
5
+ import { INightWatchConfig } from '@night-watch/core';
6
+ /**
7
+ * Options for the resolve command
8
+ */
9
+ export interface IResolveOptions {
10
+ dryRun: boolean;
11
+ timeout?: string;
12
+ provider?: string;
13
+ }
14
+ /**
15
+ * Build environment variables map from config and CLI options for PR resolver
16
+ */
17
+ export declare function buildEnvVars(config: INightWatchConfig, options: IResolveOptions): Record<string, string>;
18
+ /**
19
+ * Apply CLI flag overrides to the config for PR resolver
20
+ */
21
+ export declare function applyCliOverrides(config: INightWatchConfig, options: IResolveOptions): INightWatchConfig;
22
+ /**
23
+ * Register the resolve command with the program
24
+ */
25
+ export declare function resolveCommand(program: Command): void;
26
+ //# sourceMappingURL=resolve.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/commands/resolve.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,iBAAiB,EAalB,MAAM,mBAAmB,CAAC;AAS3B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,eAAe,GACvB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAcxB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,eAAe,GACvB,iBAAiB,CAgBnB;AA6BD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyIrD"}
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/commands/resolve.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,iBAAiB,EAalB,MAAM,mBAAmB,CAAC;AAU3B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,eAAe,GACvB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAcxB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,eAAe,GACvB,iBAAiB,CAgBnB;AA6BD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkKrD"}
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Resolve command - executes the PR resolver cron script
3
+ */
4
+ import { createSpinner, createTable, dim, executeScriptWithOutput, getScriptPath, header, info, loadConfig, parseScriptResult, resolveJobProvider, sendNotifications, error as uiError, } from '@night-watch/core';
5
+ import { buildBaseEnvVars, formatProviderDisplay, maybeApplyCronSchedulingDelay, } from './shared/env-builder.js';
6
+ import { recordJobOutcome } from './shared/feedback.js';
7
+ import { execFileSync } from 'child_process';
8
+ import * as path from 'path';
9
+ /**
10
+ * Build environment variables map from config and CLI options for PR resolver
11
+ */
12
+ export function buildEnvVars(config, options) {
13
+ // Start with base env vars shared by all job types
14
+ const env = buildBaseEnvVars(config, 'pr-resolver', options.dryRun);
15
+ // Runtime for PR resolver (uses NW_PR_RESOLVER_* variables)
16
+ env.NW_PR_RESOLVER_MAX_RUNTIME = String(config.prResolver.maxRuntime);
17
+ env.NW_PR_RESOLVER_MAX_PRS_PER_RUN = String(config.prResolver.maxPrsPerRun);
18
+ env.NW_PR_RESOLVER_PER_PR_TIMEOUT = String(config.prResolver.perPrTimeout);
19
+ env.NW_PR_RESOLVER_AI_CONFLICT_RESOLUTION = config.prResolver.aiConflictResolution ? '1' : '0';
20
+ env.NW_PR_RESOLVER_AI_REVIEW_RESOLUTION = config.prResolver.aiReviewResolution ? '1' : '0';
21
+ env.NW_PR_RESOLVER_READY_LABEL = config.prResolver.readyLabel;
22
+ env.NW_PR_RESOLVER_BRANCH_PATTERNS = config.prResolver.branchPatterns.join(',');
23
+ return env;
24
+ }
25
+ /**
26
+ * Apply CLI flag overrides to the config for PR resolver
27
+ */
28
+ export function applyCliOverrides(config, options) {
29
+ const overridden = { ...config, prResolver: { ...config.prResolver } };
30
+ if (options.timeout) {
31
+ const timeout = parseInt(options.timeout, 10);
32
+ if (!isNaN(timeout)) {
33
+ overridden.prResolver.maxRuntime = timeout;
34
+ }
35
+ }
36
+ if (options.provider) {
37
+ // Use _cliProviderOverride to ensure CLI flag takes precedence over jobProviders
38
+ overridden._cliProviderOverride = options.provider;
39
+ }
40
+ return overridden;
41
+ }
42
+ /**
43
+ * Get open PRs with conflict status (no branch pattern filtering)
44
+ */
45
+ function getOpenPrs() {
46
+ try {
47
+ const args = ['pr', 'list', '--state', 'open', '--json', 'number,title,headRefName,mergeable'];
48
+ const result = execFileSync('gh', args, {
49
+ encoding: 'utf-8',
50
+ stdio: ['pipe', 'pipe', 'pipe'],
51
+ });
52
+ const prs = JSON.parse(result.trim() || '[]');
53
+ return prs.map((pr) => ({
54
+ number: pr.number,
55
+ title: pr.title,
56
+ branch: pr.headRefName,
57
+ mergeable: pr.mergeable,
58
+ }));
59
+ }
60
+ catch {
61
+ // gh CLI not available or not authenticated
62
+ return [];
63
+ }
64
+ }
65
+ /**
66
+ * Register the resolve command with the program
67
+ */
68
+ export function resolveCommand(program) {
69
+ program
70
+ .command('resolve')
71
+ .description('Run PR conflict resolver now')
72
+ .option('--dry-run', 'Show what would be executed without running')
73
+ .option('--timeout <seconds>', 'Override max runtime')
74
+ .option('--provider <string>', 'AI provider to use')
75
+ .action(async (options) => {
76
+ // Get the project directory (current working directory)
77
+ const projectDir = process.cwd();
78
+ // Load config from file and environment
79
+ let config = loadConfig(projectDir);
80
+ // Apply CLI flag overrides
81
+ config = applyCliOverrides(config, options);
82
+ if (!config.prResolver.enabled && !options.dryRun) {
83
+ info('PR resolver is disabled in config; skipping.');
84
+ process.exit(0);
85
+ }
86
+ // Build environment variables
87
+ const envVars = buildEnvVars(config, options);
88
+ // Get the script path
89
+ const scriptPath = getScriptPath('night-watch-pr-resolver-cron.sh');
90
+ if (options.dryRun) {
91
+ header('Dry Run: PR Resolver');
92
+ // Resolve resolver-specific provider
93
+ const resolverProvider = resolveJobProvider(config, 'pr-resolver');
94
+ // Configuration section with table
95
+ header('Configuration');
96
+ const configTable = createTable({ head: ['Setting', 'Value'] });
97
+ configTable.push(['Provider', resolverProvider]);
98
+ configTable.push([
99
+ 'Max Runtime',
100
+ `${config.prResolver.maxRuntime}s (${Math.floor(config.prResolver.maxRuntime / 60)}min)`,
101
+ ]);
102
+ configTable.push([
103
+ 'Max PRs Per Run',
104
+ config.prResolver.maxPrsPerRun === 0
105
+ ? 'Unlimited'
106
+ : String(config.prResolver.maxPrsPerRun),
107
+ ]);
108
+ configTable.push(['Per-PR Timeout', `${config.prResolver.perPrTimeout}s`]);
109
+ configTable.push([
110
+ 'AI Conflict Resolution',
111
+ config.prResolver.aiConflictResolution ? 'Enabled' : 'Disabled',
112
+ ]);
113
+ configTable.push([
114
+ 'AI Review Resolution',
115
+ config.prResolver.aiReviewResolution ? 'Enabled' : 'Disabled',
116
+ ]);
117
+ configTable.push(['Ready Label', config.prResolver.readyLabel]);
118
+ configTable.push([
119
+ 'Branch Patterns',
120
+ config.prResolver.branchPatterns.length > 0
121
+ ? config.prResolver.branchPatterns.join(', ')
122
+ : '(all)',
123
+ ]);
124
+ console.log(configTable.toString());
125
+ // Check for open PRs
126
+ header('Open PRs');
127
+ const openPrs = getOpenPrs();
128
+ if (openPrs.length === 0) {
129
+ dim(' (no open PRs found)');
130
+ }
131
+ else {
132
+ for (const pr of openPrs) {
133
+ const conflictStatus = pr.mergeable === 'CONFLICTING' ? ' [CONFLICT]' : '';
134
+ info(`#${pr.number}: ${pr.title}${conflictStatus}`);
135
+ dim(` Branch: ${pr.branch}`);
136
+ }
137
+ }
138
+ // Environment variables
139
+ header('Environment Variables');
140
+ for (const [key, value] of Object.entries(envVars)) {
141
+ dim(` ${key}=${value}`);
142
+ }
143
+ // Full command that would be executed
144
+ header('Command');
145
+ dim(` bash ${scriptPath} ${projectDir}`);
146
+ console.log();
147
+ process.exit(0);
148
+ }
149
+ // Execute the script with spinner
150
+ const spinner = createSpinner('Running PR resolver...');
151
+ spinner.start();
152
+ try {
153
+ const startedAt = Date.now();
154
+ await maybeApplyCronSchedulingDelay(config, 'pr-resolver', projectDir);
155
+ const { exitCode, stdout, stderr } = await executeScriptWithOutput(scriptPath, [projectDir], envVars);
156
+ const finishedAt = Date.now();
157
+ const scriptResult = parseScriptResult(`${stdout}\n${stderr}`);
158
+ if (exitCode === 0) {
159
+ if (scriptResult?.status === 'queued') {
160
+ spinner.succeed('PR resolver queued — another job is currently running');
161
+ }
162
+ else if (scriptResult?.status?.startsWith('skip_')) {
163
+ spinner.succeed('PR resolver completed (no PRs needed resolution)');
164
+ }
165
+ else {
166
+ spinner.succeed('PR resolver completed successfully');
167
+ }
168
+ }
169
+ else {
170
+ spinner.fail(`PR resolver exited with code ${exitCode}`);
171
+ }
172
+ // Send notifications (fire-and-forget, failures do not affect exit code)
173
+ const notificationEvent = exitCode === 0 ? 'pr_resolver_completed' : 'pr_resolver_failed';
174
+ if (!options.dryRun) {
175
+ try {
176
+ recordJobOutcome({
177
+ config,
178
+ exitCode,
179
+ finishedAt,
180
+ jobType: 'pr-resolver',
181
+ metadata: {
182
+ providerCommand: envVars.NW_PROVIDER_CMD,
183
+ providerLabel: envVars.NW_PROVIDER_LABEL,
184
+ },
185
+ projectDir,
186
+ providerKey: envVars.NW_PROVIDER_KEY ?? resolveJobProvider(config, 'pr-resolver'),
187
+ scriptResult,
188
+ startedAt,
189
+ stderr,
190
+ stdout,
191
+ });
192
+ }
193
+ catch {
194
+ // Outcome persistence must not change command exit behavior.
195
+ }
196
+ }
197
+ await sendNotifications(config, {
198
+ event: notificationEvent,
199
+ projectName: path.basename(projectDir),
200
+ exitCode,
201
+ provider: formatProviderDisplay(envVars.NW_PROVIDER_CMD, envVars.NW_PROVIDER_LABEL),
202
+ });
203
+ process.exit(exitCode);
204
+ }
205
+ catch (err) {
206
+ spinner.fail('Failed to execute resolve command');
207
+ uiError(`${err instanceof Error ? err.message : String(err)}`);
208
+ process.exit(1);
209
+ }
210
+ });
211
+ }
212
+ //# sourceMappingURL=resolve.js.map