@jonit-dev/night-watch-cli 1.7.10 → 1.7.13

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 (315) hide show
  1. package/LICENSE +1 -1
  2. package/dist/commands/dashboard/tab-config.d.ts.map +1 -1
  3. package/dist/commands/dashboard/tab-config.js +8 -1
  4. package/dist/commands/dashboard/tab-config.js.map +1 -1
  5. package/dist/commands/doctor.d.ts.map +1 -1
  6. package/dist/commands/doctor.js +3 -0
  7. package/dist/commands/doctor.js.map +1 -1
  8. package/dist/commands/review.d.ts +4 -0
  9. package/dist/commands/review.d.ts.map +1 -1
  10. package/dist/commands/review.js +30 -0
  11. package/dist/commands/review.js.map +1 -1
  12. package/dist/commands/run.d.ts +11 -0
  13. package/dist/commands/run.d.ts.map +1 -1
  14. package/dist/commands/run.js +47 -7
  15. package/dist/commands/run.js.map +1 -1
  16. package/dist/server/index.d.ts.map +1 -1
  17. package/dist/server/index.js +43 -3
  18. package/dist/server/index.js.map +1 -1
  19. package/dist/shared/types.d.ts +223 -0
  20. package/dist/shared/types.d.ts.map +1 -0
  21. package/dist/shared/types.js +7 -0
  22. package/dist/shared/types.js.map +1 -0
  23. package/dist/src/agents/soul-compiler.d.ts +11 -0
  24. package/dist/src/agents/soul-compiler.d.ts.map +1 -0
  25. package/dist/src/agents/soul-compiler.js +103 -0
  26. package/dist/src/agents/soul-compiler.js.map +1 -0
  27. package/dist/src/board/factory.d.ts +3 -0
  28. package/dist/src/board/factory.d.ts.map +1 -0
  29. package/dist/src/board/factory.js +10 -0
  30. package/dist/src/board/factory.js.map +1 -0
  31. package/dist/src/board/providers/github-graphql.d.ts +16 -0
  32. package/dist/src/board/providers/github-graphql.d.ts.map +1 -0
  33. package/dist/src/board/providers/github-graphql.js +43 -0
  34. package/dist/src/board/providers/github-graphql.js.map +1 -0
  35. package/dist/src/board/providers/github-projects.d.ts +51 -0
  36. package/dist/src/board/providers/github-projects.d.ts.map +1 -0
  37. package/dist/src/board/providers/github-projects.js +672 -0
  38. package/dist/src/board/providers/github-projects.js.map +1 -0
  39. package/dist/src/board/types.d.ts +60 -0
  40. package/dist/src/board/types.d.ts.map +1 -0
  41. package/dist/src/board/types.js +4 -0
  42. package/dist/src/board/types.js.map +1 -0
  43. package/dist/src/cli.d.ts +3 -0
  44. package/dist/src/cli.d.ts.map +1 -0
  45. package/dist/src/cli.js +80 -0
  46. package/dist/src/cli.js.map +1 -0
  47. package/dist/src/commands/board.d.ts +9 -0
  48. package/dist/src/commands/board.d.ts.map +1 -0
  49. package/dist/src/commands/board.js +294 -0
  50. package/dist/src/commands/board.js.map +1 -0
  51. package/dist/src/commands/cancel.d.ts +46 -0
  52. package/dist/src/commands/cancel.d.ts.map +1 -0
  53. package/dist/src/commands/cancel.js +241 -0
  54. package/dist/src/commands/cancel.js.map +1 -0
  55. package/dist/src/commands/dashboard/tab-actions.d.ts +10 -0
  56. package/dist/src/commands/dashboard/tab-actions.d.ts.map +1 -0
  57. package/dist/src/commands/dashboard/tab-actions.js +245 -0
  58. package/dist/src/commands/dashboard/tab-actions.js.map +1 -0
  59. package/dist/src/commands/dashboard/tab-config.d.ts +21 -0
  60. package/dist/src/commands/dashboard/tab-config.d.ts.map +1 -0
  61. package/dist/src/commands/dashboard/tab-config.js +829 -0
  62. package/dist/src/commands/dashboard/tab-config.js.map +1 -0
  63. package/dist/src/commands/dashboard/tab-logs.d.ts +10 -0
  64. package/dist/src/commands/dashboard/tab-logs.d.ts.map +1 -0
  65. package/dist/src/commands/dashboard/tab-logs.js +178 -0
  66. package/dist/src/commands/dashboard/tab-logs.js.map +1 -0
  67. package/dist/src/commands/dashboard/tab-schedules.d.ts +21 -0
  68. package/dist/src/commands/dashboard/tab-schedules.d.ts.map +1 -0
  69. package/dist/src/commands/dashboard/tab-schedules.js +304 -0
  70. package/dist/src/commands/dashboard/tab-schedules.js.map +1 -0
  71. package/dist/src/commands/dashboard/tab-status.d.ts +32 -0
  72. package/dist/src/commands/dashboard/tab-status.d.ts.map +1 -0
  73. package/dist/src/commands/dashboard/tab-status.js +421 -0
  74. package/dist/src/commands/dashboard/tab-status.js.map +1 -0
  75. package/dist/src/commands/dashboard/types.d.ts +43 -0
  76. package/dist/src/commands/dashboard/types.d.ts.map +1 -0
  77. package/dist/src/commands/dashboard/types.js +5 -0
  78. package/dist/src/commands/dashboard/types.js.map +1 -0
  79. package/dist/src/commands/dashboard.d.ts +11 -0
  80. package/dist/src/commands/dashboard.d.ts.map +1 -0
  81. package/dist/src/commands/dashboard.js +239 -0
  82. package/dist/src/commands/dashboard.js.map +1 -0
  83. package/dist/src/commands/doctor.d.ts +16 -0
  84. package/dist/src/commands/doctor.d.ts.map +1 -0
  85. package/dist/src/commands/doctor.js +202 -0
  86. package/dist/src/commands/doctor.js.map +1 -0
  87. package/dist/src/commands/history.d.ts +7 -0
  88. package/dist/src/commands/history.d.ts.map +1 -0
  89. package/dist/src/commands/history.js +56 -0
  90. package/dist/src/commands/history.js.map +1 -0
  91. package/dist/src/commands/init.d.ts +25 -0
  92. package/dist/src/commands/init.d.ts.map +1 -0
  93. package/dist/src/commands/init.js +543 -0
  94. package/dist/src/commands/init.js.map +1 -0
  95. package/dist/src/commands/install.d.ts +48 -0
  96. package/dist/src/commands/install.d.ts.map +1 -0
  97. package/dist/src/commands/install.js +303 -0
  98. package/dist/src/commands/install.js.map +1 -0
  99. package/dist/src/commands/logs.d.ts +15 -0
  100. package/dist/src/commands/logs.d.ts.map +1 -0
  101. package/dist/src/commands/logs.js +104 -0
  102. package/dist/src/commands/logs.js.map +1 -0
  103. package/dist/src/commands/prd-state.d.ts +12 -0
  104. package/dist/src/commands/prd-state.d.ts.map +1 -0
  105. package/dist/src/commands/prd-state.js +47 -0
  106. package/dist/src/commands/prd-state.js.map +1 -0
  107. package/dist/src/commands/prd.d.ts +24 -0
  108. package/dist/src/commands/prd.d.ts.map +1 -0
  109. package/dist/src/commands/prd.js +283 -0
  110. package/dist/src/commands/prd.js.map +1 -0
  111. package/dist/src/commands/prds.d.ts +13 -0
  112. package/dist/src/commands/prds.d.ts.map +1 -0
  113. package/dist/src/commands/prds.js +196 -0
  114. package/dist/src/commands/prds.js.map +1 -0
  115. package/dist/src/commands/prs.d.ts +14 -0
  116. package/dist/src/commands/prs.d.ts.map +1 -0
  117. package/dist/src/commands/prs.js +106 -0
  118. package/dist/src/commands/prs.js.map +1 -0
  119. package/dist/src/commands/qa.d.ts +30 -0
  120. package/dist/src/commands/qa.d.ts.map +1 -0
  121. package/dist/src/commands/qa.js +159 -0
  122. package/dist/src/commands/qa.js.map +1 -0
  123. package/dist/src/commands/retry.d.ts +9 -0
  124. package/dist/src/commands/retry.d.ts.map +1 -0
  125. package/dist/src/commands/retry.js +72 -0
  126. package/dist/src/commands/retry.js.map +1 -0
  127. package/dist/src/commands/review.d.ts +35 -0
  128. package/dist/src/commands/review.d.ts.map +1 -0
  129. package/dist/src/commands/review.js +252 -0
  130. package/dist/src/commands/review.js.map +1 -0
  131. package/dist/src/commands/run.d.ts +61 -0
  132. package/dist/src/commands/run.d.ts.map +1 -0
  133. package/dist/src/commands/run.js +364 -0
  134. package/dist/src/commands/run.js.map +1 -0
  135. package/dist/src/commands/serve.d.ts +7 -0
  136. package/dist/src/commands/serve.d.ts.map +1 -0
  137. package/dist/src/commands/serve.js +27 -0
  138. package/dist/src/commands/serve.js.map +1 -0
  139. package/dist/src/commands/slice.d.ts +26 -0
  140. package/dist/src/commands/slice.d.ts.map +1 -0
  141. package/dist/src/commands/slice.js +175 -0
  142. package/dist/src/commands/slice.js.map +1 -0
  143. package/dist/src/commands/state.d.ts +8 -0
  144. package/dist/src/commands/state.d.ts.map +1 -0
  145. package/dist/src/commands/state.js +56 -0
  146. package/dist/src/commands/state.js.map +1 -0
  147. package/dist/src/commands/status.d.ts +14 -0
  148. package/dist/src/commands/status.d.ts.map +1 -0
  149. package/dist/src/commands/status.js +147 -0
  150. package/dist/src/commands/status.js.map +1 -0
  151. package/dist/src/commands/uninstall.d.ts +25 -0
  152. package/dist/src/commands/uninstall.d.ts.map +1 -0
  153. package/dist/src/commands/uninstall.js +141 -0
  154. package/dist/src/commands/uninstall.js.map +1 -0
  155. package/dist/src/commands/update.d.ts +21 -0
  156. package/dist/src/commands/update.d.ts.map +1 -0
  157. package/dist/src/commands/update.js +87 -0
  158. package/dist/src/commands/update.js.map +1 -0
  159. package/dist/src/config.d.ts +23 -0
  160. package/dist/src/config.d.ts.map +1 -0
  161. package/dist/src/config.js +629 -0
  162. package/dist/src/config.js.map +1 -0
  163. package/dist/src/constants.d.ts +60 -0
  164. package/dist/src/constants.d.ts.map +1 -0
  165. package/dist/src/constants.js +118 -0
  166. package/dist/src/constants.js.map +1 -0
  167. package/dist/src/server/index.d.ts +23 -0
  168. package/dist/src/server/index.d.ts.map +1 -0
  169. package/dist/src/server/index.js +1645 -0
  170. package/dist/src/server/index.js.map +1 -0
  171. package/dist/src/slack/channel-manager.d.ts +32 -0
  172. package/dist/src/slack/channel-manager.d.ts.map +1 -0
  173. package/dist/src/slack/channel-manager.js +128 -0
  174. package/dist/src/slack/channel-manager.js.map +1 -0
  175. package/dist/src/slack/client.d.ts +63 -0
  176. package/dist/src/slack/client.d.ts.map +1 -0
  177. package/dist/src/slack/client.js +151 -0
  178. package/dist/src/slack/client.js.map +1 -0
  179. package/dist/src/slack/deliberation.d.ts +45 -0
  180. package/dist/src/slack/deliberation.d.ts.map +1 -0
  181. package/dist/src/slack/deliberation.js +539 -0
  182. package/dist/src/slack/deliberation.js.map +1 -0
  183. package/dist/src/slack/index.d.ts +6 -0
  184. package/dist/src/slack/index.d.ts.map +1 -0
  185. package/dist/src/slack/index.js +5 -0
  186. package/dist/src/slack/index.js.map +1 -0
  187. package/dist/src/slack/interaction-listener.d.ts +53 -0
  188. package/dist/src/slack/interaction-listener.d.ts.map +1 -0
  189. package/dist/src/slack/interaction-listener.js +253 -0
  190. package/dist/src/slack/interaction-listener.js.map +1 -0
  191. package/dist/src/storage/json-state-migrator.d.ts +24 -0
  192. package/dist/src/storage/json-state-migrator.d.ts.map +1 -0
  193. package/dist/src/storage/json-state-migrator.js +197 -0
  194. package/dist/src/storage/json-state-migrator.js.map +1 -0
  195. package/dist/src/storage/repositories/index.d.ts +25 -0
  196. package/dist/src/storage/repositories/index.d.ts.map +1 -0
  197. package/dist/src/storage/repositories/index.js +43 -0
  198. package/dist/src/storage/repositories/index.js.map +1 -0
  199. package/dist/src/storage/repositories/interfaces.d.ts +59 -0
  200. package/dist/src/storage/repositories/interfaces.d.ts.map +1 -0
  201. package/dist/src/storage/repositories/interfaces.js +6 -0
  202. package/dist/src/storage/repositories/interfaces.js.map +1 -0
  203. package/dist/src/storage/repositories/sqlite/agent-persona-repository.d.ts +27 -0
  204. package/dist/src/storage/repositories/sqlite/agent-persona-repository.d.ts.map +1 -0
  205. package/dist/src/storage/repositories/sqlite/agent-persona-repository.js +569 -0
  206. package/dist/src/storage/repositories/sqlite/agent-persona-repository.js.map +1 -0
  207. package/dist/src/storage/repositories/sqlite/execution-history-repository.d.ts +21 -0
  208. package/dist/src/storage/repositories/sqlite/execution-history-repository.d.ts.map +1 -0
  209. package/dist/src/storage/repositories/sqlite/execution-history-repository.js +94 -0
  210. package/dist/src/storage/repositories/sqlite/execution-history-repository.js.map +1 -0
  211. package/dist/src/storage/repositories/sqlite/prd-state-repository.d.ts +17 -0
  212. package/dist/src/storage/repositories/sqlite/prd-state-repository.d.ts.map +1 -0
  213. package/dist/src/storage/repositories/sqlite/prd-state-repository.js +74 -0
  214. package/dist/src/storage/repositories/sqlite/prd-state-repository.js.map +1 -0
  215. package/dist/src/storage/repositories/sqlite/project-registry-repository.d.ts +17 -0
  216. package/dist/src/storage/repositories/sqlite/project-registry-repository.d.ts.map +1 -0
  217. package/dist/src/storage/repositories/sqlite/project-registry-repository.js +43 -0
  218. package/dist/src/storage/repositories/sqlite/project-registry-repository.js.map +1 -0
  219. package/dist/src/storage/repositories/sqlite/roadmap-state-repository.d.ts +14 -0
  220. package/dist/src/storage/repositories/sqlite/roadmap-state-repository.d.ts.map +1 -0
  221. package/dist/src/storage/repositories/sqlite/roadmap-state-repository.js +47 -0
  222. package/dist/src/storage/repositories/sqlite/roadmap-state-repository.js.map +1 -0
  223. package/dist/src/storage/repositories/sqlite/slack-discussion-repository.d.ts +20 -0
  224. package/dist/src/storage/repositories/sqlite/slack-discussion-repository.d.ts.map +1 -0
  225. package/dist/src/storage/repositories/sqlite/slack-discussion-repository.js +88 -0
  226. package/dist/src/storage/repositories/sqlite/slack-discussion-repository.js.map +1 -0
  227. package/dist/src/storage/sqlite/client.d.ts +23 -0
  228. package/dist/src/storage/sqlite/client.d.ts.map +1 -0
  229. package/dist/src/storage/sqlite/client.js +47 -0
  230. package/dist/src/storage/sqlite/client.js.map +1 -0
  231. package/dist/src/storage/sqlite/migrations.d.ts +11 -0
  232. package/dist/src/storage/sqlite/migrations.d.ts.map +1 -0
  233. package/dist/src/storage/sqlite/migrations.js +94 -0
  234. package/dist/src/storage/sqlite/migrations.js.map +1 -0
  235. package/dist/src/templates/prd-template.d.ts +11 -0
  236. package/dist/src/templates/prd-template.d.ts.map +1 -0
  237. package/dist/src/templates/prd-template.js +166 -0
  238. package/dist/src/templates/prd-template.js.map +1 -0
  239. package/dist/src/templates/slicer-prompt.d.ts +54 -0
  240. package/dist/src/templates/slicer-prompt.d.ts.map +1 -0
  241. package/dist/src/templates/slicer-prompt.js +163 -0
  242. package/dist/src/templates/slicer-prompt.js.map +1 -0
  243. package/dist/src/types.d.ts +127 -0
  244. package/dist/src/types.d.ts.map +1 -0
  245. package/dist/src/types.js +5 -0
  246. package/dist/src/types.js.map +1 -0
  247. package/dist/src/utils/checks.d.ts +55 -0
  248. package/dist/src/utils/checks.d.ts.map +1 -0
  249. package/dist/src/utils/checks.js +246 -0
  250. package/dist/src/utils/checks.js.map +1 -0
  251. package/dist/src/utils/config-writer.d.ts +16 -0
  252. package/dist/src/utils/config-writer.d.ts.map +1 -0
  253. package/dist/src/utils/config-writer.js +45 -0
  254. package/dist/src/utils/config-writer.js.map +1 -0
  255. package/dist/src/utils/crontab.d.ts +62 -0
  256. package/dist/src/utils/crontab.d.ts.map +1 -0
  257. package/dist/src/utils/crontab.js +168 -0
  258. package/dist/src/utils/crontab.js.map +1 -0
  259. package/dist/src/utils/execution-history.d.ts +54 -0
  260. package/dist/src/utils/execution-history.d.ts.map +1 -0
  261. package/dist/src/utils/execution-history.js +80 -0
  262. package/dist/src/utils/execution-history.js.map +1 -0
  263. package/dist/src/utils/github.d.ts +40 -0
  264. package/dist/src/utils/github.d.ts.map +1 -0
  265. package/dist/src/utils/github.js +126 -0
  266. package/dist/src/utils/github.js.map +1 -0
  267. package/dist/src/utils/notify.d.ts +63 -0
  268. package/dist/src/utils/notify.d.ts.map +1 -0
  269. package/dist/src/utils/notify.js +389 -0
  270. package/dist/src/utils/notify.js.map +1 -0
  271. package/dist/src/utils/prd-states.d.ts +16 -0
  272. package/dist/src/utils/prd-states.d.ts.map +1 -0
  273. package/dist/src/utils/prd-states.js +28 -0
  274. package/dist/src/utils/prd-states.js.map +1 -0
  275. package/dist/src/utils/registry.d.ts +45 -0
  276. package/dist/src/utils/registry.d.ts.map +1 -0
  277. package/dist/src/utils/registry.js +86 -0
  278. package/dist/src/utils/registry.js.map +1 -0
  279. package/dist/src/utils/roadmap-parser.d.ts +45 -0
  280. package/dist/src/utils/roadmap-parser.d.ts.map +1 -0
  281. package/dist/src/utils/roadmap-parser.js +136 -0
  282. package/dist/src/utils/roadmap-parser.js.map +1 -0
  283. package/dist/src/utils/roadmap-scanner.d.ts +92 -0
  284. package/dist/src/utils/roadmap-scanner.d.ts.map +1 -0
  285. package/dist/src/utils/roadmap-scanner.js +349 -0
  286. package/dist/src/utils/roadmap-scanner.js.map +1 -0
  287. package/dist/src/utils/roadmap-state.d.ts +90 -0
  288. package/dist/src/utils/roadmap-state.d.ts.map +1 -0
  289. package/dist/src/utils/roadmap-state.js +154 -0
  290. package/dist/src/utils/roadmap-state.js.map +1 -0
  291. package/dist/src/utils/script-result.d.ts +12 -0
  292. package/dist/src/utils/script-result.d.ts.map +1 -0
  293. package/dist/src/utils/script-result.js +46 -0
  294. package/dist/src/utils/script-result.js.map +1 -0
  295. package/dist/src/utils/shell.d.ts +27 -0
  296. package/dist/src/utils/shell.d.ts.map +1 -0
  297. package/dist/src/utils/shell.js +64 -0
  298. package/dist/src/utils/shell.js.map +1 -0
  299. package/dist/src/utils/status-data.d.ts +148 -0
  300. package/dist/src/utils/status-data.d.ts.map +1 -0
  301. package/dist/src/utils/status-data.js +593 -0
  302. package/dist/src/utils/status-data.js.map +1 -0
  303. package/dist/src/utils/ui.d.ts +55 -0
  304. package/dist/src/utils/ui.d.ts.map +1 -0
  305. package/dist/src/utils/ui.js +121 -0
  306. package/dist/src/utils/ui.js.map +1 -0
  307. package/package.json +3 -1
  308. package/scripts/night-watch-cron.sh +7 -0
  309. package/scripts/night-watch-helpers.sh +33 -4
  310. package/scripts/night-watch-pr-reviewer-cron.sh +11 -3
  311. package/web/dist/assets/index-BtxQU4oX.css +1 -0
  312. package/web/dist/assets/index-CzAWcldp.js +473 -0
  313. package/web/dist/index.html +2 -2
  314. package/web/dist/assets/index-BPW-7_1C.js +0 -380
  315. package/web/dist/assets/index-DVqjjJEO.css +0 -1
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Shared validation utilities for Night Watch CLI
3
+ * Used by init, doctor, and other commands that need to verify environment
4
+ */
5
+ import { Provider } from "../types.js";
6
+ /**
7
+ * Result of an environment check
8
+ */
9
+ export interface ICheckResult {
10
+ passed: boolean;
11
+ message: string;
12
+ fixable: boolean;
13
+ fix?: () => void;
14
+ }
15
+ /**
16
+ * Check if directory is a git repository
17
+ */
18
+ export declare function checkGitRepo(cwd: string): ICheckResult;
19
+ /**
20
+ * Check if GitHub CLI is authenticated
21
+ */
22
+ export declare function checkGhCli(): ICheckResult;
23
+ /**
24
+ * Check if a specific provider CLI is available
25
+ */
26
+ export declare function checkProviderCli(provider: Provider): ICheckResult;
27
+ /**
28
+ * Detect which AI provider CLIs are installed
29
+ */
30
+ export declare function detectProviders(): Provider[];
31
+ /**
32
+ * Check if Node.js version meets minimum requirement
33
+ */
34
+ export declare function checkNodeVersion(minMajor: number): ICheckResult;
35
+ /**
36
+ * Check if config file exists and is valid JSON
37
+ */
38
+ export declare function checkConfigFile(projectDir: string): ICheckResult;
39
+ /**
40
+ * Check if PRD directory exists
41
+ */
42
+ export declare function checkPrdDirectory(projectDir: string, prdDir: string): ICheckResult;
43
+ /**
44
+ * Check if logs directory exists
45
+ */
46
+ export declare function checkLogsDirectory(projectDir: string): ICheckResult;
47
+ /**
48
+ * Check if crontab is accessible
49
+ */
50
+ export declare function checkCrontabAccess(): ICheckResult;
51
+ /**
52
+ * Run all environment checks and return results
53
+ */
54
+ export declare function runAllChecks(projectDir: string, prdDir: string): ICheckResult[];
55
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../../src/utils/checks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAOtD;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,YAAY,CAkBzC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,YAAY,CAkBjE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,QAAQ,EAAE,CAc5C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAsB/D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,CA4BhE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,YAAY,CA0Bd;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,CAmBnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAoBjD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,YAAY,EAAE,CAuChB"}
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Shared validation utilities for Night Watch CLI
3
+ * Used by init, doctor, and other commands that need to verify environment
4
+ */
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import { execSync } from "child_process";
8
+ import { CONFIG_FILE_NAME, LOG_DIR, VALID_PROVIDERS } from "../constants.js";
9
+ /**
10
+ * Check if directory is a git repository
11
+ */
12
+ export function checkGitRepo(cwd) {
13
+ const isRepo = fs.existsSync(path.join(cwd, ".git"));
14
+ return {
15
+ passed: isRepo,
16
+ message: isRepo ? "Git repository found" : "Not a git repository",
17
+ fixable: false,
18
+ };
19
+ }
20
+ /**
21
+ * Check if GitHub CLI is authenticated
22
+ */
23
+ export function checkGhCli() {
24
+ try {
25
+ execSync("gh auth status", {
26
+ encoding: "utf-8",
27
+ stdio: ["pipe", "pipe", "pipe"],
28
+ });
29
+ return {
30
+ passed: true,
31
+ message: "GitHub CLI authenticated",
32
+ fixable: false,
33
+ };
34
+ }
35
+ catch {
36
+ return {
37
+ passed: false,
38
+ message: "GitHub CLI not authenticated (run: gh auth login)",
39
+ fixable: false,
40
+ };
41
+ }
42
+ }
43
+ /**
44
+ * Check if a specific provider CLI is available
45
+ */
46
+ export function checkProviderCli(provider) {
47
+ try {
48
+ execSync(`which ${provider}`, {
49
+ encoding: "utf-8",
50
+ stdio: ["pipe", "pipe", "pipe"],
51
+ });
52
+ return {
53
+ passed: true,
54
+ message: `Provider CLI found: ${provider}`,
55
+ fixable: false,
56
+ };
57
+ }
58
+ catch {
59
+ return {
60
+ passed: false,
61
+ message: `Provider CLI not found: ${provider}`,
62
+ fixable: false,
63
+ };
64
+ }
65
+ }
66
+ /**
67
+ * Detect which AI provider CLIs are installed
68
+ */
69
+ export function detectProviders() {
70
+ const providers = [];
71
+ for (const provider of VALID_PROVIDERS) {
72
+ try {
73
+ execSync(`which ${provider}`, {
74
+ encoding: "utf-8",
75
+ stdio: ["pipe", "pipe", "pipe"],
76
+ });
77
+ providers.push(provider);
78
+ }
79
+ catch {
80
+ // Provider not available
81
+ }
82
+ }
83
+ return providers;
84
+ }
85
+ /**
86
+ * Check if Node.js version meets minimum requirement
87
+ */
88
+ export function checkNodeVersion(minMajor) {
89
+ const nodeVersion = process.version;
90
+ const match = nodeVersion.match(/^v?(\d+)/);
91
+ if (!match) {
92
+ return {
93
+ passed: false,
94
+ message: `Could not determine Node.js version (got: ${nodeVersion})`,
95
+ fixable: false,
96
+ };
97
+ }
98
+ const major = parseInt(match[1], 10);
99
+ const passed = major >= minMajor;
100
+ return {
101
+ passed,
102
+ message: passed
103
+ ? `Node.js version ${nodeVersion} (>= ${minMajor}.0.0)`
104
+ : `Node.js version ${nodeVersion} is too old (minimum: ${minMajor}.0.0)`,
105
+ fixable: false,
106
+ };
107
+ }
108
+ /**
109
+ * Check if config file exists and is valid JSON
110
+ */
111
+ export function checkConfigFile(projectDir) {
112
+ const configPath = path.join(projectDir, CONFIG_FILE_NAME);
113
+ if (!fs.existsSync(configPath)) {
114
+ return {
115
+ passed: false,
116
+ message: `Config file not found: ${CONFIG_FILE_NAME} (run: night-watch init)`,
117
+ fixable: false,
118
+ };
119
+ }
120
+ try {
121
+ const content = fs.readFileSync(configPath, "utf-8");
122
+ JSON.parse(content);
123
+ return {
124
+ passed: true,
125
+ message: `Config file valid: ${CONFIG_FILE_NAME}`,
126
+ fixable: false,
127
+ };
128
+ }
129
+ catch (err) {
130
+ const errorMsg = err instanceof Error ? err.message : String(err);
131
+ return {
132
+ passed: false,
133
+ message: `Config file has invalid JSON: ${errorMsg}`,
134
+ fixable: false,
135
+ };
136
+ }
137
+ }
138
+ /**
139
+ * Check if PRD directory exists
140
+ */
141
+ export function checkPrdDirectory(projectDir, prdDir) {
142
+ const prdPath = path.join(projectDir, prdDir);
143
+ if (!fs.existsSync(prdPath)) {
144
+ return {
145
+ passed: false,
146
+ message: `PRD directory not found: ${prdDir}`,
147
+ fixable: true,
148
+ fix: () => {
149
+ fs.mkdirSync(prdPath, { recursive: true });
150
+ // Also create the done subdirectory
151
+ fs.mkdirSync(path.join(prdPath, "done"), { recursive: true });
152
+ },
153
+ };
154
+ }
155
+ // Count PRD files (exclude summary and files in done/)
156
+ const prds = fs
157
+ .readdirSync(prdPath)
158
+ .filter((f) => f.endsWith(".md") && f !== "NIGHT-WATCH-SUMMARY.md");
159
+ return {
160
+ passed: true,
161
+ message: `PRD directory found: ${prdDir} (${prds.length} PRDs)`,
162
+ fixable: false,
163
+ };
164
+ }
165
+ /**
166
+ * Check if logs directory exists
167
+ */
168
+ export function checkLogsDirectory(projectDir) {
169
+ const logsPath = path.join(projectDir, LOG_DIR);
170
+ if (!fs.existsSync(logsPath)) {
171
+ return {
172
+ passed: false,
173
+ message: `Logs directory not found: ${LOG_DIR}`,
174
+ fixable: true,
175
+ fix: () => {
176
+ fs.mkdirSync(logsPath, { recursive: true });
177
+ },
178
+ };
179
+ }
180
+ return {
181
+ passed: true,
182
+ message: `Logs directory found: ${LOG_DIR}`,
183
+ fixable: false,
184
+ };
185
+ }
186
+ /**
187
+ * Check if crontab is accessible
188
+ */
189
+ export function checkCrontabAccess() {
190
+ try {
191
+ execSync("crontab -l", {
192
+ encoding: "utf-8",
193
+ stdio: ["pipe", "pipe", "pipe"],
194
+ });
195
+ return {
196
+ passed: true,
197
+ message: "Crontab accessible",
198
+ fixable: false,
199
+ };
200
+ }
201
+ catch {
202
+ // crontab -l returns error if no crontab exists, but that's still "accessible"
203
+ // We check if the error is about access or just "no crontab"
204
+ return {
205
+ passed: true,
206
+ message: "Crontab accessible (empty)",
207
+ fixable: false,
208
+ };
209
+ }
210
+ }
211
+ /**
212
+ * Run all environment checks and return results
213
+ */
214
+ export function runAllChecks(projectDir, prdDir) {
215
+ const results = [];
216
+ // Check Node version
217
+ results.push(checkNodeVersion(18));
218
+ // Check git repo
219
+ results.push(checkGitRepo(projectDir));
220
+ // Check GitHub CLI
221
+ results.push(checkGhCli());
222
+ // Check provider CLIs
223
+ const providers = detectProviders();
224
+ if (providers.length === 0) {
225
+ results.push({
226
+ passed: false,
227
+ message: "No AI provider CLI found (install claude or codex)",
228
+ fixable: false,
229
+ });
230
+ }
231
+ else {
232
+ for (const provider of providers) {
233
+ results.push(checkProviderCli(provider));
234
+ }
235
+ }
236
+ // Check config file
237
+ results.push(checkConfigFile(projectDir));
238
+ // Check PRD directory
239
+ results.push(checkPrdDirectory(projectDir, prdDir));
240
+ // Check logs directory
241
+ results.push(checkLogsDirectory(projectDir));
242
+ // Check crontab access
243
+ results.push(checkCrontabAccess());
244
+ return results;
245
+ }
246
+ //# sourceMappingURL=checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.js","sourceRoot":"","sources":["../../../src/utils/checks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Config writer utility for Night Watch CLI
3
+ * Saves partial config changes to night-watch.config.json while preserving unknown keys
4
+ */
5
+ import { INightWatchConfig } from "../types.js";
6
+ export interface ISaveConfigResult {
7
+ success: boolean;
8
+ error?: string;
9
+ }
10
+ /**
11
+ * Save partial config changes to the night-watch.config.json file.
12
+ * Reads the existing file, merges changes, and writes back.
13
+ * Preserves unknown keys (like $schema, projectName).
14
+ */
15
+ export declare function saveConfig(projectDir: string, changes: Partial<INightWatchConfig>): ISaveConfigResult;
16
+ //# sourceMappingURL=config-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-writer.d.ts","sourceRoot":"","sources":["../../../src/utils/config-writer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAClC,iBAAiB,CAiCnB"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Config writer utility for Night Watch CLI
3
+ * Saves partial config changes to night-watch.config.json while preserving unknown keys
4
+ */
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import { CONFIG_FILE_NAME } from "../constants.js";
8
+ /**
9
+ * Save partial config changes to the night-watch.config.json file.
10
+ * Reads the existing file, merges changes, and writes back.
11
+ * Preserves unknown keys (like $schema, projectName).
12
+ */
13
+ export function saveConfig(projectDir, changes) {
14
+ const configPath = path.join(projectDir, CONFIG_FILE_NAME);
15
+ try {
16
+ // Read existing file
17
+ let existing = {};
18
+ if (fs.existsSync(configPath)) {
19
+ const content = fs.readFileSync(configPath, "utf-8");
20
+ existing = JSON.parse(content);
21
+ }
22
+ // Merge changes (shallow merge for top-level keys, deep merge for notifications)
23
+ const merged = { ...existing };
24
+ for (const [key, value] of Object.entries(changes)) {
25
+ if (value !== undefined) {
26
+ if (key === "notifications" && existing.notifications && typeof existing.notifications === "object") {
27
+ merged.notifications = { ...existing.notifications, ...value };
28
+ }
29
+ else {
30
+ merged[key] = value;
31
+ }
32
+ }
33
+ }
34
+ // Write back with consistent formatting
35
+ fs.writeFileSync(configPath, JSON.stringify(merged, null, 2) + "\n");
36
+ return { success: true };
37
+ }
38
+ catch (err) {
39
+ return {
40
+ success: false,
41
+ error: err instanceof Error ? err.message : String(err),
42
+ };
43
+ }
44
+ }
45
+ //# sourceMappingURL=config-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-writer.js","sourceRoot":"","sources":["../../../src/utils/config-writer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAQnD;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,UAAkB,EAClB,OAAmC;IAEnC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;IAE3D,IAAI,CAAC;QACH,qBAAqB;QACrB,IAAI,QAAQ,GAA4B,EAAE,CAAC;QAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACrD,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;QAC5D,CAAC;QAED,iFAAiF;QACjF,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,IAAI,GAAG,KAAK,eAAe,IAAI,QAAQ,CAAC,aAAa,IAAI,OAAO,QAAQ,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;oBACpG,MAAM,CAAC,aAAa,GAAG,EAAE,GAAI,QAAQ,CAAC,aAAyC,EAAE,GAAG,KAAgC,EAAE,CAAC;gBACzH,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;QAED,wCAAwC;QACxC,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAErE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,62 @@
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
+ /**
51
+ * Get all Night Watch entries for a project directory (independent of marker text)
52
+ * @param projectDir - Absolute project directory
53
+ */
54
+ export declare function getProjectEntries(projectDir: string): string[];
55
+ /**
56
+ * Remove Night Watch entries for a project directory and/or marker
57
+ * @param projectDir - Absolute project directory
58
+ * @param marker - Optional marker for backward compatibility
59
+ * @returns Number of entries removed
60
+ */
61
+ export declare function removeEntriesForProject(projectDir: string, marker?: string): number;
62
+ //# 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;AAOH;;GAEG;AACH,eAAO,MAAM,qBAAqB,uBAAuB,CAAC;AAqB1D;;;GAGG;AACH,wBAAgB,WAAW,IAAI,MAAM,EAAE,CAYtC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAkClD;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;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAG9D;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAYnF"}
@@ -0,0 +1,168 @@
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
+ import * as fs from "fs";
7
+ import * as os from "os";
8
+ import * as path from "path";
9
+ /**
10
+ * Marker prefix used to identify Night Watch entries
11
+ */
12
+ export const CRONTAB_MARKER_PREFIX = "# night-watch-cli:";
13
+ /**
14
+ * Check whether a crontab line belongs to the given project directory.
15
+ * Supports unquoted, single-quoted, and double-quoted cd paths.
16
+ */
17
+ function isEntryForProject(line, projectDir) {
18
+ if (!line.includes(CRONTAB_MARKER_PREFIX)) {
19
+ return false;
20
+ }
21
+ const normalized = projectDir.replace(/\/+$/, "");
22
+ const candidates = [
23
+ `cd ${normalized}`,
24
+ `cd '${normalized}'`,
25
+ `cd "${normalized}"`,
26
+ ];
27
+ return candidates.some((candidate) => line.includes(candidate));
28
+ }
29
+ /**
30
+ * Read current crontab entries
31
+ * Returns empty array if user has no crontab
32
+ */
33
+ export function readCrontab() {
34
+ try {
35
+ const output = execSync("crontab -l 2>/dev/null", {
36
+ encoding: "utf-8",
37
+ stdio: ["pipe", "pipe", "pipe"],
38
+ });
39
+ return output.trim().split("\n").filter((line) => line.length > 0);
40
+ }
41
+ catch {
42
+ // crontab -l returns error if no crontab exists
43
+ // This is expected and should return empty array
44
+ return [];
45
+ }
46
+ }
47
+ /**
48
+ * Write crontab entries
49
+ * @param lines - Array of crontab lines to write
50
+ * @throws Error if crontab write fails
51
+ */
52
+ export function writeCrontab(lines) {
53
+ if (process.env.NW_EXECUTION_CONTEXT === "agent") {
54
+ throw new Error("Crontab writes are blocked during agent execution (NW_EXECUTION_CONTEXT=agent). " +
55
+ "This prevents the running agent from accidentally modifying its own scheduling.");
56
+ }
57
+ const content = lines.join("\n");
58
+ // Create a backup first
59
+ try {
60
+ const currentCrontab = readCrontab();
61
+ if (currentCrontab.length > 0) {
62
+ execSync(`crontab -l > /tmp/night-watch-crontab-backup-$(date +%s).txt`, {
63
+ encoding: "utf-8",
64
+ });
65
+ }
66
+ }
67
+ catch {
68
+ // Ignore backup errors
69
+ }
70
+ // Write new crontab via temp file to avoid shell line length limits
71
+ const tmpFile = path.join(os.tmpdir(), `night-watch-crontab-${Date.now()}.txt`);
72
+ try {
73
+ fs.writeFileSync(tmpFile, content + "\n");
74
+ execSync(`crontab ${tmpFile}`, { encoding: "utf-8" });
75
+ }
76
+ catch (error) {
77
+ throw new Error(`Failed to write crontab: ${error instanceof Error ? error.message : String(error)}`);
78
+ }
79
+ finally {
80
+ try {
81
+ fs.unlinkSync(tmpFile);
82
+ }
83
+ catch { /* ignore cleanup errors */ }
84
+ }
85
+ }
86
+ /**
87
+ * Generate a marker comment for identifying entries
88
+ * @param projectName - Name of the project
89
+ */
90
+ export function generateMarker(projectName) {
91
+ return `${CRONTAB_MARKER_PREFIX} ${projectName}`;
92
+ }
93
+ /**
94
+ * Add a crontab entry if it doesn't already exist
95
+ * @param entry - The crontab entry to add
96
+ * @param marker - The marker to use for deduplication
97
+ * @returns true if entry was added, false if it already existed
98
+ */
99
+ export function addEntry(entry, marker) {
100
+ // Check if entry already exists
101
+ if (hasEntry(marker)) {
102
+ return false;
103
+ }
104
+ const lines = readCrontab();
105
+ // Add the entry with marker comment on the same line
106
+ const entryWithMarker = entry.endsWith(marker)
107
+ ? entry
108
+ : `${entry} ${marker}`;
109
+ lines.push(entryWithMarker);
110
+ writeCrontab(lines);
111
+ return true;
112
+ }
113
+ /**
114
+ * Remove all crontab entries containing the marker
115
+ * @param marker - The marker to search for
116
+ * @returns Number of entries removed
117
+ */
118
+ export function removeEntries(marker) {
119
+ const lines = readCrontab();
120
+ const filtered = lines.filter((line) => !line.includes(marker));
121
+ const removedCount = lines.length - filtered.length;
122
+ if (removedCount > 0) {
123
+ writeCrontab(filtered);
124
+ }
125
+ return removedCount;
126
+ }
127
+ /**
128
+ * Check if an entry with the marker exists
129
+ * @param marker - The marker to search for
130
+ * @returns true if entry exists
131
+ */
132
+ export function hasEntry(marker) {
133
+ const lines = readCrontab();
134
+ return lines.some((line) => line.includes(marker));
135
+ }
136
+ /**
137
+ * Get all entries containing the marker
138
+ * @param marker - The marker to search for
139
+ * @returns Array of matching entries
140
+ */
141
+ export function getEntries(marker) {
142
+ const lines = readCrontab();
143
+ return lines.filter((line) => line.includes(marker));
144
+ }
145
+ /**
146
+ * Get all Night Watch entries for a project directory (independent of marker text)
147
+ * @param projectDir - Absolute project directory
148
+ */
149
+ export function getProjectEntries(projectDir) {
150
+ const lines = readCrontab();
151
+ return lines.filter((line) => isEntryForProject(line, projectDir));
152
+ }
153
+ /**
154
+ * Remove Night Watch entries for a project directory and/or marker
155
+ * @param projectDir - Absolute project directory
156
+ * @param marker - Optional marker for backward compatibility
157
+ * @returns Number of entries removed
158
+ */
159
+ export function removeEntriesForProject(projectDir, marker) {
160
+ const lines = readCrontab();
161
+ const filtered = lines.filter((line) => !isEntryForProject(line, projectDir) && !(marker && line.includes(marker)));
162
+ const removedCount = lines.length - filtered.length;
163
+ if (removedCount > 0) {
164
+ writeCrontab(filtered);
165
+ }
166
+ return removedCount;
167
+ }
168
+ //# sourceMappingURL=crontab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crontab.js","sourceRoot":"","sources":["../../../src/utils/crontab.ts"],"names":[],"mappings":"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"}