@jonit-dev/night-watch-cli 1.0.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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +509 -0
  3. package/bin/night-watch.mjs +2 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +35 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/init.d.ts +8 -0
  9. package/dist/commands/init.d.ts.map +1 -0
  10. package/dist/commands/init.js +376 -0
  11. package/dist/commands/init.js.map +1 -0
  12. package/dist/commands/install.d.ts +15 -0
  13. package/dist/commands/install.d.ts.map +1 -0
  14. package/dist/commands/install.js +135 -0
  15. package/dist/commands/install.js.map +1 -0
  16. package/dist/commands/logs.d.ts +15 -0
  17. package/dist/commands/logs.d.ts.map +1 -0
  18. package/dist/commands/logs.js +104 -0
  19. package/dist/commands/logs.js.map +1 -0
  20. package/dist/commands/review.d.ts +26 -0
  21. package/dist/commands/review.d.ts.map +1 -0
  22. package/dist/commands/review.js +144 -0
  23. package/dist/commands/review.js.map +1 -0
  24. package/dist/commands/run.d.ts +26 -0
  25. package/dist/commands/run.d.ts.map +1 -0
  26. package/dist/commands/run.js +161 -0
  27. package/dist/commands/run.js.map +1 -0
  28. package/dist/commands/status.d.ts +14 -0
  29. package/dist/commands/status.d.ts.map +1 -0
  30. package/dist/commands/status.js +303 -0
  31. package/dist/commands/status.js.map +1 -0
  32. package/dist/commands/uninstall.d.ts +13 -0
  33. package/dist/commands/uninstall.d.ts.map +1 -0
  34. package/dist/commands/uninstall.js +97 -0
  35. package/dist/commands/uninstall.js.map +1 -0
  36. package/dist/config.d.ts +23 -0
  37. package/dist/config.d.ts.map +1 -0
  38. package/dist/config.js +213 -0
  39. package/dist/config.js.map +1 -0
  40. package/dist/constants.d.ts +21 -0
  41. package/dist/constants.d.ts.map +1 -0
  42. package/dist/constants.js +33 -0
  43. package/dist/constants.js.map +1 -0
  44. package/dist/types.d.ts +35 -0
  45. package/dist/types.d.ts.map +1 -0
  46. package/dist/types.js +5 -0
  47. package/dist/types.js.map +1 -0
  48. package/dist/utils/crontab.d.ts +50 -0
  49. package/dist/utils/crontab.d.ts.map +1 -0
  50. package/dist/utils/crontab.js +116 -0
  51. package/dist/utils/crontab.js.map +1 -0
  52. package/dist/utils/shell.d.ts +13 -0
  53. package/dist/utils/shell.d.ts.map +1 -0
  54. package/dist/utils/shell.js +44 -0
  55. package/dist/utils/shell.js.map +1 -0
  56. package/dist/utils/ui.d.ts +55 -0
  57. package/dist/utils/ui.d.ts.map +1 -0
  58. package/dist/utils/ui.js +121 -0
  59. package/dist/utils/ui.js.map +1 -0
  60. package/package.json +64 -0
  61. package/scripts/night-watch-cron.sh +148 -0
  62. package/scripts/night-watch-helpers.sh +155 -0
  63. package/scripts/night-watch-pr-reviewer-cron.sh +135 -0
  64. package/templates/night-watch-pr-reviewer.md +144 -0
  65. package/templates/night-watch.config.json +21 -0
  66. package/templates/night-watch.md +100 -0
  67. package/templates/prd-executor.md +235 -0
package/dist/config.js ADDED
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Configuration loader for Night Watch CLI
3
+ * Loads config from: defaults -> config file -> environment variables
4
+ */
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import { DEFAULT_PRD_DIR, DEFAULT_MAX_RUNTIME, DEFAULT_REVIEWER_MAX_RUNTIME, DEFAULT_CRON_SCHEDULE, DEFAULT_REVIEWER_SCHEDULE, DEFAULT_BRANCH_PREFIX, DEFAULT_BRANCH_PATTERNS, DEFAULT_MIN_REVIEW_SCORE, DEFAULT_MAX_LOG_SIZE, DEFAULT_PROVIDER, DEFAULT_REVIEWER_ENABLED, VALID_PROVIDERS, CONFIG_FILE_NAME, } from "./constants.js";
8
+ /**
9
+ * Get the default configuration values
10
+ */
11
+ export function getDefaultConfig() {
12
+ return {
13
+ // PRD execution
14
+ prdDir: DEFAULT_PRD_DIR,
15
+ maxRuntime: DEFAULT_MAX_RUNTIME,
16
+ reviewerMaxRuntime: DEFAULT_REVIEWER_MAX_RUNTIME,
17
+ branchPrefix: DEFAULT_BRANCH_PREFIX,
18
+ branchPatterns: [...DEFAULT_BRANCH_PATTERNS],
19
+ minReviewScore: DEFAULT_MIN_REVIEW_SCORE,
20
+ maxLogSize: DEFAULT_MAX_LOG_SIZE,
21
+ // Cron scheduling
22
+ cronSchedule: DEFAULT_CRON_SCHEDULE,
23
+ reviewerSchedule: DEFAULT_REVIEWER_SCHEDULE,
24
+ // Provider configuration
25
+ provider: DEFAULT_PROVIDER,
26
+ reviewerEnabled: DEFAULT_REVIEWER_ENABLED,
27
+ };
28
+ }
29
+ /**
30
+ * Load configuration from a JSON file
31
+ */
32
+ function loadConfigFile(configPath) {
33
+ try {
34
+ if (!fs.existsSync(configPath)) {
35
+ return null;
36
+ }
37
+ const content = fs.readFileSync(configPath, "utf-8");
38
+ const config = JSON.parse(content);
39
+ return config;
40
+ }
41
+ catch (error) {
42
+ // If file exists but can't be parsed, warn but don't fail
43
+ console.warn(`Warning: Could not parse config file at ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
44
+ return null;
45
+ }
46
+ }
47
+ /**
48
+ * Parse a boolean string value
49
+ */
50
+ function parseBoolean(value) {
51
+ const normalized = value.toLowerCase().trim();
52
+ if (normalized === "true" || normalized === "1") {
53
+ return true;
54
+ }
55
+ if (normalized === "false" || normalized === "0") {
56
+ return false;
57
+ }
58
+ return null;
59
+ }
60
+ /**
61
+ * Validate and return a provider value
62
+ */
63
+ function validateProvider(value) {
64
+ if (VALID_PROVIDERS.includes(value)) {
65
+ return value;
66
+ }
67
+ return null;
68
+ }
69
+ /**
70
+ * Deep merge configuration objects
71
+ * Environment values take precedence over file values
72
+ */
73
+ function mergeConfigs(base, fileConfig, envConfig) {
74
+ const merged = { ...base };
75
+ // Merge file config
76
+ if (fileConfig) {
77
+ if (fileConfig.prdDir !== undefined)
78
+ merged.prdDir = fileConfig.prdDir;
79
+ if (fileConfig.maxRuntime !== undefined)
80
+ merged.maxRuntime = fileConfig.maxRuntime;
81
+ if (fileConfig.reviewerMaxRuntime !== undefined)
82
+ merged.reviewerMaxRuntime = fileConfig.reviewerMaxRuntime;
83
+ if (fileConfig.branchPrefix !== undefined)
84
+ merged.branchPrefix = fileConfig.branchPrefix;
85
+ if (fileConfig.branchPatterns !== undefined)
86
+ merged.branchPatterns = [...fileConfig.branchPatterns];
87
+ if (fileConfig.minReviewScore !== undefined)
88
+ merged.minReviewScore = fileConfig.minReviewScore;
89
+ if (fileConfig.maxLogSize !== undefined)
90
+ merged.maxLogSize = fileConfig.maxLogSize;
91
+ if (fileConfig.cronSchedule !== undefined)
92
+ merged.cronSchedule = fileConfig.cronSchedule;
93
+ if (fileConfig.reviewerSchedule !== undefined)
94
+ merged.reviewerSchedule = fileConfig.reviewerSchedule;
95
+ if (fileConfig.provider !== undefined)
96
+ merged.provider = fileConfig.provider;
97
+ if (fileConfig.reviewerEnabled !== undefined)
98
+ merged.reviewerEnabled = fileConfig.reviewerEnabled;
99
+ }
100
+ // Merge env config (takes precedence)
101
+ if (envConfig.prdDir !== undefined)
102
+ merged.prdDir = envConfig.prdDir;
103
+ if (envConfig.maxRuntime !== undefined)
104
+ merged.maxRuntime = envConfig.maxRuntime;
105
+ if (envConfig.reviewerMaxRuntime !== undefined)
106
+ merged.reviewerMaxRuntime = envConfig.reviewerMaxRuntime;
107
+ if (envConfig.branchPrefix !== undefined)
108
+ merged.branchPrefix = envConfig.branchPrefix;
109
+ if (envConfig.branchPatterns !== undefined)
110
+ merged.branchPatterns = [...envConfig.branchPatterns];
111
+ if (envConfig.minReviewScore !== undefined)
112
+ merged.minReviewScore = envConfig.minReviewScore;
113
+ if (envConfig.maxLogSize !== undefined)
114
+ merged.maxLogSize = envConfig.maxLogSize;
115
+ if (envConfig.cronSchedule !== undefined)
116
+ merged.cronSchedule = envConfig.cronSchedule;
117
+ if (envConfig.reviewerSchedule !== undefined)
118
+ merged.reviewerSchedule = envConfig.reviewerSchedule;
119
+ if (envConfig.provider !== undefined)
120
+ merged.provider = envConfig.provider;
121
+ if (envConfig.reviewerEnabled !== undefined)
122
+ merged.reviewerEnabled = envConfig.reviewerEnabled;
123
+ return merged;
124
+ }
125
+ /**
126
+ * Load Night Watch configuration
127
+ * Priority: defaults < config file < environment variables
128
+ *
129
+ * @param projectDir - The project directory to load config from
130
+ * @returns Merged configuration object
131
+ */
132
+ export function loadConfig(projectDir) {
133
+ // Start with defaults
134
+ const defaults = getDefaultConfig();
135
+ // Load config file
136
+ const configPath = path.join(projectDir, CONFIG_FILE_NAME);
137
+ const fileConfig = loadConfigFile(configPath);
138
+ // Load environment overrides
139
+ const envConfig = {};
140
+ // NW_* environment variables
141
+ if (process.env.NW_PRD_DIR) {
142
+ envConfig.prdDir = process.env.NW_PRD_DIR;
143
+ }
144
+ if (process.env.NW_MAX_RUNTIME) {
145
+ const runtime = parseInt(process.env.NW_MAX_RUNTIME, 10);
146
+ if (!isNaN(runtime)) {
147
+ envConfig.maxRuntime = runtime;
148
+ }
149
+ }
150
+ if (process.env.NW_REVIEWER_MAX_RUNTIME) {
151
+ const runtime = parseInt(process.env.NW_REVIEWER_MAX_RUNTIME, 10);
152
+ if (!isNaN(runtime)) {
153
+ envConfig.reviewerMaxRuntime = runtime;
154
+ }
155
+ }
156
+ if (process.env.NW_BRANCH_PREFIX) {
157
+ envConfig.branchPrefix = process.env.NW_BRANCH_PREFIX;
158
+ }
159
+ if (process.env.NW_BRANCH_PATTERNS) {
160
+ try {
161
+ envConfig.branchPatterns = JSON.parse(process.env.NW_BRANCH_PATTERNS);
162
+ }
163
+ catch {
164
+ // If not valid JSON, treat as comma-separated
165
+ envConfig.branchPatterns = process.env.NW_BRANCH_PATTERNS.split(",").map((s) => s.trim());
166
+ }
167
+ }
168
+ if (process.env.NW_MIN_REVIEW_SCORE) {
169
+ const score = parseInt(process.env.NW_MIN_REVIEW_SCORE, 10);
170
+ if (!isNaN(score)) {
171
+ envConfig.minReviewScore = score;
172
+ }
173
+ }
174
+ if (process.env.NW_MAX_LOG_SIZE) {
175
+ const size = parseInt(process.env.NW_MAX_LOG_SIZE, 10);
176
+ if (!isNaN(size)) {
177
+ envConfig.maxLogSize = size;
178
+ }
179
+ }
180
+ if (process.env.NW_CRON_SCHEDULE) {
181
+ envConfig.cronSchedule = process.env.NW_CRON_SCHEDULE;
182
+ }
183
+ if (process.env.NW_REVIEWER_SCHEDULE) {
184
+ envConfig.reviewerSchedule = process.env.NW_REVIEWER_SCHEDULE;
185
+ }
186
+ // NW_PROVIDER environment variable
187
+ if (process.env.NW_PROVIDER) {
188
+ const provider = validateProvider(process.env.NW_PROVIDER);
189
+ if (provider !== null) {
190
+ envConfig.provider = provider;
191
+ }
192
+ // If invalid, fallback to default (don't set envConfig.provider)
193
+ }
194
+ // NW_REVIEWER_ENABLED environment variable
195
+ if (process.env.NW_REVIEWER_ENABLED) {
196
+ const reviewerEnabled = parseBoolean(process.env.NW_REVIEWER_ENABLED);
197
+ if (reviewerEnabled !== null) {
198
+ envConfig.reviewerEnabled = reviewerEnabled;
199
+ }
200
+ }
201
+ // Merge all configs
202
+ return mergeConfigs(defaults, fileConfig, envConfig);
203
+ }
204
+ /**
205
+ * Get the path to a bundled script
206
+ * This returns the path to a script in the package's scripts/ directory
207
+ */
208
+ export function getScriptPath(scriptName) {
209
+ // In development, scripts are in scripts/ relative to package root
210
+ // In production (after npm pack), they're still in scripts/
211
+ return path.join(path.dirname(new URL(import.meta.url).pathname), "..", "scripts", scriptName);
212
+ }
213
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Default configuration values for Night Watch CLI
3
+ */
4
+ import { Provider } from "./types.js";
5
+ export declare const DEFAULT_PRD_DIR = "docs/PRDs/night-watch";
6
+ export declare const DEFAULT_MAX_RUNTIME = 7200;
7
+ export declare const DEFAULT_REVIEWER_MAX_RUNTIME = 3600;
8
+ export declare const DEFAULT_CRON_SCHEDULE = "0 0-15 * * *";
9
+ export declare const DEFAULT_REVIEWER_SCHEDULE = "0 0,3,6,9,12,15 * * *";
10
+ export declare const DEFAULT_BRANCH_PREFIX = "night-watch";
11
+ export declare const DEFAULT_BRANCH_PATTERNS: string[];
12
+ export declare const DEFAULT_MIN_REVIEW_SCORE = 80;
13
+ export declare const DEFAULT_MAX_LOG_SIZE = 524288;
14
+ export declare const DEFAULT_PROVIDER: Provider;
15
+ export declare const DEFAULT_REVIEWER_ENABLED = true;
16
+ export declare const VALID_PROVIDERS: Provider[];
17
+ export declare const PROVIDER_COMMANDS: Record<Provider, string>;
18
+ export declare const CONFIG_FILE_NAME = "night-watch.config.json";
19
+ export declare const LOCK_FILE_PREFIX = "/tmp/night-watch-";
20
+ export declare const LOG_DIR = "logs";
21
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,eAAO,MAAM,eAAe,0BAA0B,CAAC;AAGvD,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAGjD,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AACpD,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAGjE,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AACnD,eAAO,MAAM,uBAAuB,UAA4B,CAAC;AAGjE,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAG3C,eAAO,MAAM,oBAAoB,SAAS,CAAC;AAG3C,eAAO,MAAM,gBAAgB,EAAE,QAAmB,CAAC;AACnD,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAG7C,eAAO,MAAM,eAAe,EAAE,QAAQ,EAAwB,CAAC;AAG/D,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAGtD,CAAC;AAGF,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAC1D,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AACpD,eAAO,MAAM,OAAO,SAAS,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Default configuration values for Night Watch CLI
3
+ */
4
+ // PRD Configuration
5
+ export const DEFAULT_PRD_DIR = "docs/PRDs/night-watch";
6
+ // Runtime Configuration (in seconds)
7
+ export const DEFAULT_MAX_RUNTIME = 7200;
8
+ export const DEFAULT_REVIEWER_MAX_RUNTIME = 3600;
9
+ // Cron Schedule Configuration
10
+ export const DEFAULT_CRON_SCHEDULE = "0 0-15 * * *";
11
+ export const DEFAULT_REVIEWER_SCHEDULE = "0 0,3,6,9,12,15 * * *";
12
+ // Branch Configuration
13
+ export const DEFAULT_BRANCH_PREFIX = "night-watch";
14
+ export const DEFAULT_BRANCH_PATTERNS = ["feat/", "night-watch/"];
15
+ // Review Configuration
16
+ export const DEFAULT_MIN_REVIEW_SCORE = 80;
17
+ // Log Configuration
18
+ export const DEFAULT_MAX_LOG_SIZE = 524288; // 512 KB
19
+ // Provider Configuration
20
+ export const DEFAULT_PROVIDER = "claude";
21
+ export const DEFAULT_REVIEWER_ENABLED = true;
22
+ // Valid providers
23
+ export const VALID_PROVIDERS = ["claude", "codex"];
24
+ // Provider commands configuration
25
+ export const PROVIDER_COMMANDS = {
26
+ claude: "claude",
27
+ codex: "codex",
28
+ };
29
+ // File Names and Paths
30
+ export const CONFIG_FILE_NAME = "night-watch.config.json";
31
+ export const LOCK_FILE_PREFIX = "/tmp/night-watch-";
32
+ export const LOG_DIR = "logs";
33
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,oBAAoB;AACpB,MAAM,CAAC,MAAM,eAAe,GAAG,uBAAuB,CAAC;AAEvD,qCAAqC;AACrC,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACxC,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAEjD,8BAA8B;AAC9B,MAAM,CAAC,MAAM,qBAAqB,GAAG,cAAc,CAAC;AACpD,MAAM,CAAC,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AAEjE,uBAAuB;AACvB,MAAM,CAAC,MAAM,qBAAqB,GAAG,aAAa,CAAC;AACnD,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;AAEjE,uBAAuB;AACvB,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAE3C,oBAAoB;AACpB,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,CAAC,SAAS;AAErD,yBAAyB;AACzB,MAAM,CAAC,MAAM,gBAAgB,GAAa,QAAQ,CAAC;AACnD,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C,kBAAkB;AAClB,MAAM,CAAC,MAAM,eAAe,GAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAE/D,kCAAkC;AAClC,MAAM,CAAC,MAAM,iBAAiB,GAA6B;IACzD,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;CACf,CAAC;AAEF,uBAAuB;AACvB,MAAM,CAAC,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAC1D,MAAM,CAAC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AACpD,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * TypeScript interfaces for Night Watch CLI configuration
3
+ */
4
+ /**
5
+ * Supported AI providers
6
+ */
7
+ export type Provider = "claude" | "codex";
8
+ /**
9
+ * Complete Night Watch configuration
10
+ */
11
+ export interface INightWatchConfig {
12
+ /** Directory containing PRD files (relative to project root) */
13
+ prdDir: string;
14
+ /** Maximum runtime in seconds for PRD execution */
15
+ maxRuntime: number;
16
+ /** Maximum runtime in seconds for PR reviewer */
17
+ reviewerMaxRuntime: number;
18
+ /** Prefix for night-watch branches */
19
+ branchPrefix: string;
20
+ /** Branch patterns to match for PR reviewer */
21
+ branchPatterns: string[];
22
+ /** Minimum review score (out of 100) to consider PR complete */
23
+ minReviewScore: number;
24
+ /** Maximum log file size in bytes before rotation */
25
+ maxLogSize: number;
26
+ /** Cron schedule for PRD execution */
27
+ cronSchedule: string;
28
+ /** Cron schedule for PR reviewer */
29
+ reviewerSchedule: string;
30
+ /** AI provider to use for execution */
31
+ provider: Provider;
32
+ /** Whether the reviewer is enabled */
33
+ reviewerEnabled: boolean;
34
+ }
35
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAGhC,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IAEf,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IAEnB,iDAAiD;IACjD,kBAAkB,EAAE,MAAM,CAAC;IAE3B,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IAErB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,EAAE,CAAC;IAEzB,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;IAEvB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IAInB,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IAErB,oCAAoC;IACpC,gBAAgB,EAAE,MAAM,CAAC;IAIzB,uCAAuC;IACvC,QAAQ,EAAE,QAAQ,CAAC;IAEnB,sCAAsC;IACtC,eAAe,EAAE,OAAO,CAAC;CAC1B"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * TypeScript interfaces for Night Watch CLI configuration
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Crontab utility functions for Night Watch CLI
3
+ * Provides safe read/write operations for user crontab
4
+ */
5
+ /**
6
+ * Marker prefix used to identify Night Watch entries
7
+ */
8
+ export declare const CRONTAB_MARKER_PREFIX = "# night-watch-cli:";
9
+ /**
10
+ * Read current crontab entries
11
+ * Returns empty array if user has no crontab
12
+ */
13
+ export declare function readCrontab(): string[];
14
+ /**
15
+ * Write crontab entries
16
+ * @param lines - Array of crontab lines to write
17
+ * @throws Error if crontab write fails
18
+ */
19
+ export declare function writeCrontab(lines: string[]): void;
20
+ /**
21
+ * Generate a marker comment for identifying entries
22
+ * @param projectName - Name of the project
23
+ */
24
+ export declare function generateMarker(projectName: string): string;
25
+ /**
26
+ * Add a crontab entry if it doesn't already exist
27
+ * @param entry - The crontab entry to add
28
+ * @param marker - The marker to use for deduplication
29
+ * @returns true if entry was added, false if it already existed
30
+ */
31
+ export declare function addEntry(entry: string, marker: string): boolean;
32
+ /**
33
+ * Remove all crontab entries containing the marker
34
+ * @param marker - The marker to search for
35
+ * @returns Number of entries removed
36
+ */
37
+ export declare function removeEntries(marker: string): number;
38
+ /**
39
+ * Check if an entry with the marker exists
40
+ * @param marker - The marker to search for
41
+ * @returns true if entry exists
42
+ */
43
+ export declare function hasEntry(marker: string): boolean;
44
+ /**
45
+ * Get all entries containing the marker
46
+ * @param marker - The marker to search for
47
+ * @returns Array of matching entries
48
+ */
49
+ export declare function getEntries(marker: string): string[];
50
+ //# sourceMappingURL=crontab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crontab.d.ts","sourceRoot":"","sources":["../../src/utils/crontab.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,eAAO,MAAM,qBAAqB,uBAAuB,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,WAAW,IAAI,MAAM,EAAE,CAYtC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAyBlD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAiB/D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUpD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGhD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAGnD"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Crontab utility functions for Night Watch CLI
3
+ * Provides safe read/write operations for user crontab
4
+ */
5
+ import { execSync } from "child_process";
6
+ /**
7
+ * Marker prefix used to identify Night Watch entries
8
+ */
9
+ export const CRONTAB_MARKER_PREFIX = "# night-watch-cli:";
10
+ /**
11
+ * Read current crontab entries
12
+ * Returns empty array if user has no crontab
13
+ */
14
+ export function readCrontab() {
15
+ try {
16
+ const output = execSync("crontab -l 2>/dev/null", {
17
+ encoding: "utf-8",
18
+ stdio: ["pipe", "pipe", "pipe"],
19
+ });
20
+ return output.trim().split("\n").filter((line) => line.length > 0);
21
+ }
22
+ catch (error) {
23
+ // crontab -l returns error if no crontab exists
24
+ // This is expected and should return empty array
25
+ return [];
26
+ }
27
+ }
28
+ /**
29
+ * Write crontab entries
30
+ * @param lines - Array of crontab lines to write
31
+ * @throws Error if crontab write fails
32
+ */
33
+ export function writeCrontab(lines) {
34
+ const content = lines.join("\n");
35
+ // Create a backup first
36
+ try {
37
+ const currentCrontab = readCrontab();
38
+ if (currentCrontab.length > 0) {
39
+ execSync(`crontab -l > /tmp/night-watch-crontab-backup-$(date +%s).txt`, {
40
+ encoding: "utf-8",
41
+ });
42
+ }
43
+ }
44
+ catch {
45
+ // Ignore backup errors
46
+ }
47
+ // Write new crontab using echo and pipe
48
+ try {
49
+ execSync(`echo "${content.replace(/"/g, '\\"')}" | crontab -`, {
50
+ encoding: "utf-8",
51
+ });
52
+ }
53
+ catch (error) {
54
+ throw new Error(`Failed to write crontab: ${error instanceof Error ? error.message : String(error)}`);
55
+ }
56
+ }
57
+ /**
58
+ * Generate a marker comment for identifying entries
59
+ * @param projectName - Name of the project
60
+ */
61
+ export function generateMarker(projectName) {
62
+ return `${CRONTAB_MARKER_PREFIX} ${projectName}`;
63
+ }
64
+ /**
65
+ * Add a crontab entry if it doesn't already exist
66
+ * @param entry - The crontab entry to add
67
+ * @param marker - The marker to use for deduplication
68
+ * @returns true if entry was added, false if it already existed
69
+ */
70
+ export function addEntry(entry, marker) {
71
+ // Check if entry already exists
72
+ if (hasEntry(marker)) {
73
+ return false;
74
+ }
75
+ const lines = readCrontab();
76
+ // Add the entry with marker comment on the same line
77
+ const entryWithMarker = entry.endsWith(marker)
78
+ ? entry
79
+ : `${entry} ${marker}`;
80
+ lines.push(entryWithMarker);
81
+ writeCrontab(lines);
82
+ return true;
83
+ }
84
+ /**
85
+ * Remove all crontab entries containing the marker
86
+ * @param marker - The marker to search for
87
+ * @returns Number of entries removed
88
+ */
89
+ export function removeEntries(marker) {
90
+ const lines = readCrontab();
91
+ const filtered = lines.filter((line) => !line.includes(marker));
92
+ const removedCount = lines.length - filtered.length;
93
+ if (removedCount > 0) {
94
+ writeCrontab(filtered);
95
+ }
96
+ return removedCount;
97
+ }
98
+ /**
99
+ * Check if an entry with the marker exists
100
+ * @param marker - The marker to search for
101
+ * @returns true if entry exists
102
+ */
103
+ export function hasEntry(marker) {
104
+ const lines = readCrontab();
105
+ return lines.some((line) => line.includes(marker));
106
+ }
107
+ /**
108
+ * Get all entries containing the marker
109
+ * @param marker - The marker to search for
110
+ * @returns Array of matching entries
111
+ */
112
+ export function getEntries(marker) {
113
+ const lines = readCrontab();
114
+ return lines.filter((line) => line.includes(marker));
115
+ }
116
+ //# sourceMappingURL=crontab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crontab.js","sourceRoot":"","sources":["../../src/utils/crontab.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,oBAAoB,CAAC;AAE1D;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,wBAAwB,EAAE;YAChD,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,gDAAgD;QAChD,iDAAiD;QACjD,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAe;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEjC,wBAAwB;IACxB,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,WAAW,EAAE,CAAC;QACrC,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,QAAQ,CAAC,8DAA8D,EAAE;gBACvE,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,uBAAuB;IACzB,CAAC;IAED,wCAAwC;IACxC,IAAI,CAAC;QACH,QAAQ,CAAC,SAAS,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,eAAe,EAAE;YAC7D,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACrF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,OAAO,GAAG,qBAAqB,IAAI,WAAW,EAAE,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,MAAc;IACpD,gCAAgC;IAChC,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;IAE5B,qDAAqD;IACrD,MAAM,eAAe,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC5C,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,GAAG,KAAK,KAAK,MAAM,EAAE,CAAC;IAE1B,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC5B,YAAY,CAAC,KAAK,CAAC,CAAC;IAEpB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAEpD,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACrB,YAAY,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAc;IACrC,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;IAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;IAC5B,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Shell execution utility for running bash scripts
3
+ */
4
+ /**
5
+ * Execute a bash script with arguments and environment variables
6
+ *
7
+ * @param scriptPath - Absolute path to the bash script to execute
8
+ * @param args - Arguments to pass to the script
9
+ * @param env - Environment variables to set for the child process
10
+ * @returns Promise that resolves with the exit code (0 for success)
11
+ */
12
+ export declare function executeScript(scriptPath: string, args?: string[], env?: Record<string, string>): Promise<number>;
13
+ //# sourceMappingURL=shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,MAAM,EAAO,EACnB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC/B,OAAO,CAAC,MAAM,CAAC,CAmCjB"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Shell execution utility for running bash scripts
3
+ */
4
+ import { spawn } from "child_process";
5
+ /**
6
+ * Execute a bash script with arguments and environment variables
7
+ *
8
+ * @param scriptPath - Absolute path to the bash script to execute
9
+ * @param args - Arguments to pass to the script
10
+ * @param env - Environment variables to set for the child process
11
+ * @returns Promise that resolves with the exit code (0 for success)
12
+ */
13
+ export async function executeScript(scriptPath, args = [], env = {}) {
14
+ return new Promise((resolve, reject) => {
15
+ // Merge provided env with process.env, with provided env taking precedence
16
+ const childEnv = {
17
+ ...process.env,
18
+ ...env,
19
+ };
20
+ const child = spawn("bash", [scriptPath, ...args], {
21
+ env: childEnv,
22
+ stdio: ["inherit", "pipe", "pipe"],
23
+ });
24
+ // Stream stdout to console in real-time
25
+ child.stdout?.on("data", (data) => {
26
+ process.stdout.write(data);
27
+ });
28
+ // Stream stderr to console in real-time
29
+ child.stderr?.on("data", (data) => {
30
+ process.stderr.write(data);
31
+ });
32
+ // Handle process errors
33
+ child.on("error", (error) => {
34
+ console.error(`Failed to execute script: ${scriptPath}`);
35
+ console.error(error.message);
36
+ reject(error);
37
+ });
38
+ // Handle process completion
39
+ child.on("close", (code) => {
40
+ resolve(code ?? 1);
41
+ });
42
+ });
43
+ }
44
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAkB,EAClB,OAAiB,EAAE,EACnB,MAA8B,EAAE;IAEhC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,2EAA2E;QAC3E,MAAM,QAAQ,GAAsB;YAClC,GAAG,OAAO,CAAC,GAAG;YACd,GAAG,GAAG;SACP,CAAC;QAEF,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,EAAE;YACjD,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC;SACnC,CAAC,CAAC;QAEH,wCAAwC;QACxC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,wCAAwC;QACxC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,wBAAwB;QACxB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;YACjC,OAAO,CAAC,KAAK,CAAC,6BAA6B,UAAU,EAAE,CAAC,CAAC;YACzD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,4BAA4B;QAC5B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAmB,EAAE,EAAE;YACxC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * UI utilities for Night Watch CLI
3
+ * Provides colored output, spinners, and table formatting
4
+ */
5
+ import { type Ora } from "ora";
6
+ import Table from "cli-table3";
7
+ /**
8
+ * Print a success message with green check prefix
9
+ */
10
+ export declare function success(msg: string): void;
11
+ /**
12
+ * Print an error message with red cross prefix
13
+ */
14
+ export declare function error(msg: string): void;
15
+ /**
16
+ * Print a warning message with yellow warning prefix
17
+ */
18
+ export declare function warn(msg: string): void;
19
+ /**
20
+ * Print an info message with cyan info prefix
21
+ */
22
+ export declare function info(msg: string): void;
23
+ /**
24
+ * Print a bold section header with underline
25
+ */
26
+ export declare function header(title: string): void;
27
+ /**
28
+ * Print dimmed text for secondary information
29
+ */
30
+ export declare function dim(msg: string): void;
31
+ /**
32
+ * Format and print a key-value pair with consistent alignment
33
+ */
34
+ export declare function label(key: string, value: string): void;
35
+ /**
36
+ * Create an ora spinner instance
37
+ */
38
+ export declare function createSpinner(text: string): Ora;
39
+ /**
40
+ * Create a configured cli-table3 instance with sensible defaults
41
+ */
42
+ export declare function createTable(options?: Table.TableConstructorOptions): Table.Table;
43
+ /**
44
+ * Format status indicator: green running or dim not running
45
+ */
46
+ export declare function formatRunningStatus(running: boolean, pid: number | null): string;
47
+ /**
48
+ * Format installed status: green installed or yellow not installed
49
+ */
50
+ export declare function formatInstalledStatus(installed: boolean): string;
51
+ /**
52
+ * Print a step message with step number
53
+ */
54
+ export declare function step(current: number, total: number, msg: string): void;
55
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAY,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B;;GAEG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEvC;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK1C;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAErC;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGtD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAK/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,uBAAuB,GAAG,KAAK,CAAC,KAAK,CA4BhF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAQhF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAKhE;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtE"}