@jonit-dev/night-watch-cli 1.1.4 → 1.2.0

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 (74) hide show
  1. package/README.md +49 -426
  2. package/dist/cli.js +9 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/dashboard.d.ts +29 -0
  5. package/dist/commands/dashboard.d.ts.map +1 -0
  6. package/dist/commands/dashboard.js +297 -0
  7. package/dist/commands/dashboard.js.map +1 -0
  8. package/dist/commands/doctor.d.ts +16 -0
  9. package/dist/commands/doctor.d.ts.map +1 -0
  10. package/dist/commands/doctor.js +155 -0
  11. package/dist/commands/doctor.js.map +1 -0
  12. package/dist/commands/init.d.ts.map +1 -1
  13. package/dist/commands/init.js +23 -17
  14. package/dist/commands/init.js.map +1 -1
  15. package/dist/commands/install.d.ts +1 -1
  16. package/dist/commands/install.d.ts.map +1 -1
  17. package/dist/commands/install.js +2 -2
  18. package/dist/commands/install.js.map +1 -1
  19. package/dist/commands/logs.d.ts +1 -1
  20. package/dist/commands/logs.d.ts.map +1 -1
  21. package/dist/commands/logs.js +1 -1
  22. package/dist/commands/logs.js.map +1 -1
  23. package/dist/commands/prd.d.ts +24 -0
  24. package/dist/commands/prd.d.ts.map +1 -0
  25. package/dist/commands/prd.js +283 -0
  26. package/dist/commands/prd.js.map +1 -0
  27. package/dist/commands/review.d.ts +3 -3
  28. package/dist/commands/review.d.ts.map +1 -1
  29. package/dist/commands/review.js +26 -2
  30. package/dist/commands/review.js.map +1 -1
  31. package/dist/commands/run.d.ts +22 -3
  32. package/dist/commands/run.d.ts.map +1 -1
  33. package/dist/commands/run.js +57 -8
  34. package/dist/commands/run.js.map +1 -1
  35. package/dist/commands/status.d.ts +1 -1
  36. package/dist/commands/status.d.ts.map +1 -1
  37. package/dist/commands/status.js +21 -182
  38. package/dist/commands/status.js.map +1 -1
  39. package/dist/commands/uninstall.d.ts +1 -1
  40. package/dist/commands/uninstall.d.ts.map +1 -1
  41. package/dist/commands/uninstall.js +2 -2
  42. package/dist/commands/uninstall.js.map +1 -1
  43. package/dist/config.d.ts.map +1 -1
  44. package/dist/config.js +40 -1
  45. package/dist/config.js.map +1 -1
  46. package/dist/constants.d.ts +3 -1
  47. package/dist/constants.d.ts.map +1 -1
  48. package/dist/constants.js +3 -0
  49. package/dist/constants.js.map +1 -1
  50. package/dist/templates/prd-template.d.ts +11 -0
  51. package/dist/templates/prd-template.d.ts.map +1 -0
  52. package/dist/templates/prd-template.js +166 -0
  53. package/dist/templates/prd-template.js.map +1 -0
  54. package/dist/types.d.ts +14 -0
  55. package/dist/types.d.ts.map +1 -1
  56. package/dist/utils/crontab.js +1 -1
  57. package/dist/utils/crontab.js.map +1 -1
  58. package/dist/utils/github.d.ts +30 -0
  59. package/dist/utils/github.d.ts.map +1 -0
  60. package/dist/utils/github.js +104 -0
  61. package/dist/utils/github.js.map +1 -0
  62. package/dist/utils/notify.d.ts +63 -0
  63. package/dist/utils/notify.d.ts.map +1 -0
  64. package/dist/utils/notify.js +237 -0
  65. package/dist/utils/notify.js.map +1 -0
  66. package/dist/utils/status-data.d.ts +128 -0
  67. package/dist/utils/status-data.d.ts.map +1 -0
  68. package/dist/utils/status-data.js +403 -0
  69. package/dist/utils/status-data.js.map +1 -0
  70. package/package.json +13 -5
  71. package/scripts/night-watch-cron.sh +8 -1
  72. package/scripts/night-watch-helpers.sh +51 -0
  73. package/scripts/test-helpers.bats +77 -0
  74. package/templates/prd.md +26 -0
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Notification utilities for Night Watch CLI
3
+ * Sends webhook notifications to Slack, Discord, and Telegram
4
+ */
5
+ import { info, warn } from "./ui.js";
6
+ import { extractSummary } from "./github.js";
7
+ /**
8
+ * Get the emoji for a notification event
9
+ */
10
+ export function getEventEmoji(event) {
11
+ switch (event) {
12
+ case "run_succeeded":
13
+ return "\u2705";
14
+ case "run_failed":
15
+ return "\u274C";
16
+ case "run_timeout":
17
+ return "\u23F0";
18
+ case "review_completed":
19
+ return "\uD83D\uDD0D";
20
+ }
21
+ }
22
+ /**
23
+ * Get a human-readable title for a notification event
24
+ */
25
+ export function getEventTitle(event) {
26
+ switch (event) {
27
+ case "run_succeeded":
28
+ return "PRD Execution Succeeded";
29
+ case "run_failed":
30
+ return "PRD Execution Failed";
31
+ case "run_timeout":
32
+ return "PRD Execution Timed Out";
33
+ case "review_completed":
34
+ return "PR Review Completed";
35
+ }
36
+ }
37
+ /**
38
+ * Get the Discord embed color for a notification event
39
+ */
40
+ export function getEventColor(event) {
41
+ switch (event) {
42
+ case "run_succeeded":
43
+ return 0x00ff00;
44
+ case "run_failed":
45
+ return 0xff0000;
46
+ case "run_timeout":
47
+ return 0xff0000;
48
+ case "review_completed":
49
+ return 0x0099ff;
50
+ }
51
+ }
52
+ /**
53
+ * Build a description string from notification context
54
+ */
55
+ export function buildDescription(ctx) {
56
+ const lines = [];
57
+ lines.push(`Project: ${ctx.projectName}`);
58
+ lines.push(`Provider: ${ctx.provider}`);
59
+ lines.push(`Exit code: ${ctx.exitCode}`);
60
+ if (ctx.prdName) {
61
+ lines.push(`PRD: ${ctx.prdName}`);
62
+ }
63
+ if (ctx.branchName) {
64
+ lines.push(`Branch: ${ctx.branchName}`);
65
+ }
66
+ if (ctx.prNumber !== undefined) {
67
+ lines.push(`PR: #${ctx.prNumber}`);
68
+ }
69
+ if (ctx.duration !== undefined) {
70
+ lines.push(`Duration: ${ctx.duration}s`);
71
+ }
72
+ return lines.join("\n");
73
+ }
74
+ /**
75
+ * Escape special characters for Telegram MarkdownV2 format
76
+ */
77
+ function escapeMarkdownV2(text) {
78
+ return text.replace(/[_*[\]()~`>#+=|{}.!-]/g, "\\$&");
79
+ }
80
+ /**
81
+ * Format a notification payload for Slack incoming webhooks
82
+ */
83
+ export function formatSlackPayload(ctx) {
84
+ const emoji = getEventEmoji(ctx.event);
85
+ const title = getEventTitle(ctx.event);
86
+ const description = buildDescription(ctx);
87
+ let color;
88
+ if (ctx.event === "run_succeeded") {
89
+ color = "#00ff00";
90
+ }
91
+ else if (ctx.event === "review_completed") {
92
+ color = "#0099ff";
93
+ }
94
+ else {
95
+ color = "#ff0000";
96
+ }
97
+ return {
98
+ attachments: [
99
+ {
100
+ color,
101
+ blocks: [
102
+ {
103
+ type: "section",
104
+ text: {
105
+ type: "mrkdwn",
106
+ text: `*${emoji} ${title}*\n${description}`,
107
+ },
108
+ },
109
+ ],
110
+ },
111
+ ],
112
+ };
113
+ }
114
+ /**
115
+ * Format a notification payload for Discord webhooks
116
+ */
117
+ export function formatDiscordPayload(ctx) {
118
+ const emoji = getEventEmoji(ctx.event);
119
+ const title = getEventTitle(ctx.event);
120
+ const description = buildDescription(ctx);
121
+ return {
122
+ embeds: [
123
+ {
124
+ title: `${emoji} ${title}`,
125
+ description,
126
+ color: getEventColor(ctx.event),
127
+ timestamp: new Date().toISOString(),
128
+ },
129
+ ],
130
+ };
131
+ }
132
+ /**
133
+ * Build a structured Telegram message when PR details are available.
134
+ * Falls back to the basic format when they are not.
135
+ */
136
+ export function formatTelegramPayload(ctx) {
137
+ const emoji = getEventEmoji(ctx.event);
138
+ const title = getEventTitle(ctx.event);
139
+ // If PR details are present, use the rich structured template
140
+ if (ctx.prUrl && ctx.prTitle) {
141
+ const lines = [];
142
+ lines.push(`*${escapeMarkdownV2(emoji + " " + title)}*`);
143
+ lines.push("");
144
+ lines.push(`${escapeMarkdownV2("📋")} *${escapeMarkdownV2("PR #" + (ctx.prNumber ?? "") + ": " + ctx.prTitle)}*`);
145
+ lines.push(`${escapeMarkdownV2("🔗")} ${escapeMarkdownV2(ctx.prUrl)}`);
146
+ // Summary from PR body
147
+ if (ctx.prBody && ctx.prBody.trim().length > 0) {
148
+ const summary = extractSummary(ctx.prBody);
149
+ if (summary) {
150
+ lines.push("");
151
+ lines.push(`${escapeMarkdownV2("📝 Summary")}`);
152
+ lines.push(escapeMarkdownV2(summary));
153
+ }
154
+ }
155
+ // Stats
156
+ if (ctx.filesChanged !== undefined || ctx.additions !== undefined) {
157
+ lines.push("");
158
+ lines.push(`${escapeMarkdownV2("📊 Stats")}`);
159
+ const stats = [];
160
+ if (ctx.filesChanged !== undefined) {
161
+ stats.push(`Files changed: ${ctx.filesChanged}`);
162
+ }
163
+ if (ctx.additions !== undefined && ctx.deletions !== undefined) {
164
+ stats.push(`+${ctx.additions} / -${ctx.deletions}`);
165
+ }
166
+ lines.push(escapeMarkdownV2(stats.join(" | ")));
167
+ }
168
+ // Footer
169
+ lines.push("");
170
+ lines.push(escapeMarkdownV2(`⚙️ Project: ${ctx.projectName} | Provider: ${ctx.provider}`));
171
+ return {
172
+ text: lines.join("\n"),
173
+ parse_mode: "MarkdownV2",
174
+ };
175
+ }
176
+ // Fallback: basic format (no PR details)
177
+ const description = buildDescription(ctx);
178
+ return {
179
+ text: `*${escapeMarkdownV2(emoji + " " + title)}*\n\n${escapeMarkdownV2(description)}`,
180
+ parse_mode: "MarkdownV2",
181
+ };
182
+ }
183
+ /**
184
+ * Send a notification to a single webhook endpoint
185
+ * Silently catches errors — never throws
186
+ */
187
+ export async function sendWebhook(webhook, ctx) {
188
+ // Skip if this event is not in the webhook's configured events
189
+ if (!webhook.events.includes(ctx.event)) {
190
+ return;
191
+ }
192
+ try {
193
+ let url;
194
+ let body;
195
+ switch (webhook.type) {
196
+ case "slack": {
197
+ url = webhook.url;
198
+ body = JSON.stringify(formatSlackPayload(ctx));
199
+ break;
200
+ }
201
+ case "discord": {
202
+ url = webhook.url;
203
+ body = JSON.stringify(formatDiscordPayload(ctx));
204
+ break;
205
+ }
206
+ case "telegram": {
207
+ url = `https://api.telegram.org/bot${webhook.botToken}/sendMessage`;
208
+ const telegramPayload = formatTelegramPayload(ctx);
209
+ body = JSON.stringify({ chat_id: webhook.chatId, ...telegramPayload });
210
+ break;
211
+ }
212
+ }
213
+ await fetch(url, {
214
+ method: "POST",
215
+ headers: { "Content-Type": "application/json" },
216
+ body,
217
+ });
218
+ }
219
+ catch (err) {
220
+ const message = err instanceof Error ? err.message : String(err);
221
+ warn(`Notification failed (${webhook.type}): ${message}`);
222
+ }
223
+ }
224
+ /**
225
+ * Send notifications to all configured webhooks
226
+ */
227
+ export async function sendNotifications(config, ctx) {
228
+ if (!config.notifications || config.notifications.webhooks.length === 0) {
229
+ return;
230
+ }
231
+ const webhooks = config.notifications.webhooks;
232
+ const results = await Promise.allSettled(webhooks.map((wh) => sendWebhook(wh, ctx)));
233
+ const sent = results.filter((r) => r.status === "fulfilled").length;
234
+ const total = webhooks.length;
235
+ info(`Sent ${sent}/${total} notifications`);
236
+ }
237
+ //# sourceMappingURL=notify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/utils/notify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Status data layer for Night Watch CLI
3
+ * Provides data-fetching functions used by both the status command and the dashboard TUI.
4
+ */
5
+ import { INightWatchConfig } from "../types.js";
6
+ /**
7
+ * Information about a single PRD file
8
+ */
9
+ export interface IPrdInfo {
10
+ name: string;
11
+ status: "ready" | "blocked" | "in-progress" | "done";
12
+ dependencies: string[];
13
+ unmetDependencies: string[];
14
+ }
15
+ /**
16
+ * Information about a running process
17
+ */
18
+ export interface IProcessInfo {
19
+ name: string;
20
+ running: boolean;
21
+ pid: number | null;
22
+ }
23
+ /**
24
+ * Information about a pull request
25
+ */
26
+ export interface IPrInfo {
27
+ number: number;
28
+ title: string;
29
+ branch: string;
30
+ ciStatus: "pass" | "fail" | "pending" | "unknown";
31
+ reviewScore: number | null;
32
+ }
33
+ /**
34
+ * Information about a log file
35
+ */
36
+ export interface ILogInfo {
37
+ name: string;
38
+ path: string;
39
+ exists: boolean;
40
+ size: number;
41
+ lastLines: string[];
42
+ }
43
+ /**
44
+ * Complete status snapshot of the project
45
+ */
46
+ export interface IStatusSnapshot {
47
+ projectName: string;
48
+ projectDir: string;
49
+ config: INightWatchConfig;
50
+ prds: IPrdInfo[];
51
+ processes: IProcessInfo[];
52
+ prs: IPrInfo[];
53
+ logs: ILogInfo[];
54
+ crontab: {
55
+ installed: boolean;
56
+ entries: string[];
57
+ };
58
+ timestamp: Date;
59
+ }
60
+ /**
61
+ * Get the project name from directory or package.json
62
+ */
63
+ export declare function getProjectName(projectDir: string): string;
64
+ /**
65
+ * Check if a process with the given PID is running
66
+ */
67
+ export declare function isProcessRunning(pid: number): boolean;
68
+ /**
69
+ * Read PID from lock file and check if process is running
70
+ */
71
+ export declare function checkLockFile(lockPath: string): {
72
+ running: boolean;
73
+ pid: number | null;
74
+ };
75
+ /**
76
+ * Count PRDs in the PRD directory and return counts
77
+ */
78
+ export declare function countPRDs(projectDir: string, prdDir: string, maxRuntime: number): {
79
+ pending: number;
80
+ claimed: number;
81
+ done: number;
82
+ };
83
+ /**
84
+ * Parse dependency references from a PRD file.
85
+ * Looks for a line matching "depends on: `name1`, `name2`" (case-insensitive).
86
+ */
87
+ export declare function parsePrdDependencies(prdPath: string): string[];
88
+ /**
89
+ * Collect PRD info items from the PRD directory
90
+ */
91
+ export declare function collectPrdInfo(projectDir: string, prdDir: string, maxRuntime: number): IPrdInfo[];
92
+ /**
93
+ * Count open PRs on night-watch/ or feat/ branches using gh CLI
94
+ */
95
+ export declare function countOpenPRs(projectDir: string, branchPatterns: string[]): number;
96
+ /**
97
+ * Collect open PR info using gh CLI
98
+ */
99
+ export declare function collectPrInfo(projectDir: string, branchPatterns: string[]): IPrInfo[];
100
+ /**
101
+ * Get last N lines from a log file
102
+ */
103
+ export declare function getLastLogLines(logPath: string, lines: number): string[];
104
+ /**
105
+ * Get log file info
106
+ */
107
+ export declare function getLogInfo(logPath: string, lastLines?: number): {
108
+ path: string;
109
+ lastLines: string[];
110
+ exists: boolean;
111
+ size: number;
112
+ };
113
+ /**
114
+ * Collect log info as ILogInfo items
115
+ */
116
+ export declare function collectLogInfo(projectDir: string): ILogInfo[];
117
+ /**
118
+ * Get crontab information for a project
119
+ */
120
+ export declare function getCrontabInfo(projectName: string, projectDir: string): {
121
+ installed: boolean;
122
+ entries: string[];
123
+ };
124
+ /**
125
+ * Fetch a complete status snapshot for the given project
126
+ */
127
+ export declare function fetchStatusSnapshot(projectDir: string, config: INightWatchConfig): IStatusSnapshot;
128
+ //# sourceMappingURL=status-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-data.d.ts","sourceRoot":"","sources":["../../src/utils/status-data.ts"],"names":[],"mappings":"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"}