specweave 0.28.67 → 0.29.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 (239) hide show
  1. package/CLAUDE.md +3 -2
  2. package/README.md +19 -2
  3. package/dist/src/cli/commands/discrepancies.d.ts +89 -0
  4. package/dist/src/cli/commands/discrepancies.d.ts.map +1 -0
  5. package/dist/src/cli/commands/discrepancies.js +385 -0
  6. package/dist/src/cli/commands/discrepancies.js.map +1 -0
  7. package/dist/src/cli/commands/notifications.d.ts +70 -0
  8. package/dist/src/cli/commands/notifications.d.ts.map +1 -0
  9. package/dist/src/cli/commands/notifications.js +236 -0
  10. package/dist/src/cli/commands/notifications.js.map +1 -0
  11. package/dist/src/cli/commands/sync-logs.d.ts +54 -0
  12. package/dist/src/cli/commands/sync-logs.d.ts.map +1 -0
  13. package/dist/src/cli/commands/sync-logs.js +240 -0
  14. package/dist/src/cli/commands/sync-logs.js.map +1 -0
  15. package/dist/src/cli/commands/sync-monitor.d.ts +42 -0
  16. package/dist/src/cli/commands/sync-monitor.d.ts.map +1 -0
  17. package/dist/src/cli/commands/sync-monitor.js +191 -0
  18. package/dist/src/cli/commands/sync-monitor.js.map +1 -0
  19. package/dist/src/cli/helpers/init/brownfield-analysis.d.ts +45 -0
  20. package/dist/src/cli/helpers/init/brownfield-analysis.d.ts.map +1 -0
  21. package/dist/src/cli/helpers/init/brownfield-analysis.js +431 -0
  22. package/dist/src/cli/helpers/init/brownfield-analysis.js.map +1 -0
  23. package/dist/src/cli/helpers/init/index.d.ts +1 -0
  24. package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
  25. package/dist/src/cli/helpers/init/index.js +2 -0
  26. package/dist/src/cli/helpers/init/index.js.map +1 -1
  27. package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
  28. package/dist/src/cli/helpers/issue-tracker/ado.js +14 -5
  29. package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
  30. package/dist/src/cli/workers/brownfield-worker.d.ts +66 -0
  31. package/dist/src/cli/workers/brownfield-worker.d.ts.map +1 -0
  32. package/dist/src/cli/workers/brownfield-worker.js +417 -0
  33. package/dist/src/cli/workers/brownfield-worker.js.map +1 -0
  34. package/dist/src/core/background/brownfield-launcher.d.ts +86 -0
  35. package/dist/src/core/background/brownfield-launcher.d.ts.map +1 -0
  36. package/dist/src/core/background/brownfield-launcher.js +295 -0
  37. package/dist/src/core/background/brownfield-launcher.js.map +1 -0
  38. package/dist/src/core/background/index.d.ts +2 -0
  39. package/dist/src/core/background/index.d.ts.map +1 -1
  40. package/dist/src/core/background/index.js +2 -0
  41. package/dist/src/core/background/index.js.map +1 -1
  42. package/dist/src/core/background/types.d.ts +23 -2
  43. package/dist/src/core/background/types.d.ts.map +1 -1
  44. package/dist/src/core/config/index.d.ts +1 -0
  45. package/dist/src/core/config/index.d.ts.map +1 -1
  46. package/dist/src/core/config/index.js +1 -0
  47. package/dist/src/core/config/index.js.map +1 -1
  48. package/dist/src/core/config/types.d.ts +6 -0
  49. package/dist/src/core/config/types.d.ts.map +1 -1
  50. package/dist/src/core/config/types.js.map +1 -1
  51. package/dist/src/core/dashboard/dashboard-data.d.ts +156 -0
  52. package/dist/src/core/dashboard/dashboard-data.d.ts.map +1 -0
  53. package/dist/src/core/dashboard/dashboard-data.js +191 -0
  54. package/dist/src/core/dashboard/dashboard-data.js.map +1 -0
  55. package/dist/src/core/dashboard/index.d.ts +9 -0
  56. package/dist/src/core/dashboard/index.d.ts.map +1 -0
  57. package/dist/src/core/dashboard/index.js +9 -0
  58. package/dist/src/core/dashboard/index.js.map +1 -0
  59. package/dist/src/core/discrepancy/analyzers/api-route-analyzer.d.ts +77 -0
  60. package/dist/src/core/discrepancy/analyzers/api-route-analyzer.d.ts.map +1 -0
  61. package/dist/src/core/discrepancy/analyzers/api-route-analyzer.js +286 -0
  62. package/dist/src/core/discrepancy/analyzers/api-route-analyzer.js.map +1 -0
  63. package/dist/src/core/discrepancy/analyzers/index.d.ts +8 -0
  64. package/dist/src/core/discrepancy/analyzers/index.d.ts.map +1 -0
  65. package/dist/src/core/discrepancy/analyzers/index.js +8 -0
  66. package/dist/src/core/discrepancy/analyzers/index.js.map +1 -0
  67. package/dist/src/core/discrepancy/analyzers/typescript-analyzer.d.ts +96 -0
  68. package/dist/src/core/discrepancy/analyzers/typescript-analyzer.d.ts.map +1 -0
  69. package/dist/src/core/discrepancy/analyzers/typescript-analyzer.js +247 -0
  70. package/dist/src/core/discrepancy/analyzers/typescript-analyzer.js.map +1 -0
  71. package/dist/src/core/discrepancy/brownfield-manager.d.ts +88 -0
  72. package/dist/src/core/discrepancy/brownfield-manager.d.ts.map +1 -0
  73. package/dist/src/core/discrepancy/brownfield-manager.js +520 -0
  74. package/dist/src/core/discrepancy/brownfield-manager.js.map +1 -0
  75. package/dist/src/core/discrepancy/brownfield-types.d.ts +174 -0
  76. package/dist/src/core/discrepancy/brownfield-types.d.ts.map +1 -0
  77. package/dist/src/core/discrepancy/brownfield-types.js +11 -0
  78. package/dist/src/core/discrepancy/brownfield-types.js.map +1 -0
  79. package/dist/src/core/discrepancy/detector.d.ts +92 -0
  80. package/dist/src/core/discrepancy/detector.d.ts.map +1 -0
  81. package/dist/src/core/discrepancy/detector.js +346 -0
  82. package/dist/src/core/discrepancy/detector.js.map +1 -0
  83. package/dist/src/core/discrepancy/increment-generator.d.ts +51 -0
  84. package/dist/src/core/discrepancy/increment-generator.d.ts.map +1 -0
  85. package/dist/src/core/discrepancy/increment-generator.js +234 -0
  86. package/dist/src/core/discrepancy/increment-generator.js.map +1 -0
  87. package/dist/src/core/discrepancy/index.d.ts +18 -0
  88. package/dist/src/core/discrepancy/index.d.ts.map +1 -0
  89. package/dist/src/core/discrepancy/index.js +24 -0
  90. package/dist/src/core/discrepancy/index.js.map +1 -0
  91. package/dist/src/core/discrepancy/severity-classifier.d.ts +81 -0
  92. package/dist/src/core/discrepancy/severity-classifier.d.ts.map +1 -0
  93. package/dist/src/core/discrepancy/severity-classifier.js +289 -0
  94. package/dist/src/core/discrepancy/severity-classifier.js.map +1 -0
  95. package/dist/src/core/discrepancy/spec-parser.d.ts +74 -0
  96. package/dist/src/core/discrepancy/spec-parser.d.ts.map +1 -0
  97. package/dist/src/core/discrepancy/spec-parser.js +213 -0
  98. package/dist/src/core/discrepancy/spec-parser.js.map +1 -0
  99. package/dist/src/core/discrepancy/update-recommender.d.ts +77 -0
  100. package/dist/src/core/discrepancy/update-recommender.d.ts.map +1 -0
  101. package/dist/src/core/discrepancy/update-recommender.js +323 -0
  102. package/dist/src/core/discrepancy/update-recommender.js.map +1 -0
  103. package/dist/src/core/living-docs/living-docs-sync.d.ts +13 -16
  104. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  105. package/dist/src/core/living-docs/living-docs-sync.js +31 -112
  106. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  107. package/dist/src/core/logs/index.d.ts +10 -0
  108. package/dist/src/core/logs/index.d.ts.map +1 -0
  109. package/dist/src/core/logs/index.js +10 -0
  110. package/dist/src/core/logs/index.js.map +1 -0
  111. package/dist/src/core/logs/log-aggregator.d.ts +130 -0
  112. package/dist/src/core/logs/log-aggregator.d.ts.map +1 -0
  113. package/dist/src/core/logs/log-aggregator.js +206 -0
  114. package/dist/src/core/logs/log-aggregator.js.map +1 -0
  115. package/dist/src/core/logs/log-exporter.d.ts +81 -0
  116. package/dist/src/core/logs/log-exporter.d.ts.map +1 -0
  117. package/dist/src/core/logs/log-exporter.js +141 -0
  118. package/dist/src/core/logs/log-exporter.js.map +1 -0
  119. package/dist/src/core/notifications/command-integration.d.ts +82 -0
  120. package/dist/src/core/notifications/command-integration.d.ts.map +1 -0
  121. package/dist/src/core/notifications/command-integration.js +80 -0
  122. package/dist/src/core/notifications/command-integration.js.map +1 -0
  123. package/dist/src/core/notifications/index.d.ts +12 -0
  124. package/dist/src/core/notifications/index.d.ts.map +1 -0
  125. package/dist/src/core/notifications/index.js +12 -0
  126. package/dist/src/core/notifications/index.js.map +1 -0
  127. package/dist/src/core/notifications/notification-display.d.ts +70 -0
  128. package/dist/src/core/notifications/notification-display.d.ts.map +1 -0
  129. package/dist/src/core/notifications/notification-display.js +177 -0
  130. package/dist/src/core/notifications/notification-display.js.map +1 -0
  131. package/dist/src/core/notifications/notification-manager.d.ts +126 -0
  132. package/dist/src/core/notifications/notification-manager.d.ts.map +1 -0
  133. package/dist/src/core/notifications/notification-manager.js +287 -0
  134. package/dist/src/core/notifications/notification-manager.js.map +1 -0
  135. package/dist/src/core/notifications/notification-types.d.ts +159 -0
  136. package/dist/src/core/notifications/notification-types.d.ts.map +1 -0
  137. package/dist/src/core/notifications/notification-types.js +93 -0
  138. package/dist/src/core/notifications/notification-types.js.map +1 -0
  139. package/dist/src/core/scheduler/index.d.ts +11 -0
  140. package/dist/src/core/scheduler/index.d.ts.map +1 -0
  141. package/dist/src/core/scheduler/index.js +11 -0
  142. package/dist/src/core/scheduler/index.js.map +1 -0
  143. package/dist/src/core/scheduler/job-scheduler.d.ts +179 -0
  144. package/dist/src/core/scheduler/job-scheduler.d.ts.map +1 -0
  145. package/dist/src/core/scheduler/job-scheduler.js +282 -0
  146. package/dist/src/core/scheduler/job-scheduler.js.map +1 -0
  147. package/dist/src/core/scheduler/schedule-persistence.d.ts +83 -0
  148. package/dist/src/core/scheduler/schedule-persistence.d.ts.map +1 -0
  149. package/dist/src/core/scheduler/schedule-persistence.js +180 -0
  150. package/dist/src/core/scheduler/schedule-persistence.js.map +1 -0
  151. package/dist/src/core/scheduler/scheduled-job.d.ts +188 -0
  152. package/dist/src/core/scheduler/scheduled-job.d.ts.map +1 -0
  153. package/dist/src/core/scheduler/scheduled-job.js +182 -0
  154. package/dist/src/core/scheduler/scheduled-job.js.map +1 -0
  155. package/dist/src/core/sync/permission-enforcer.d.ts +206 -0
  156. package/dist/src/core/sync/permission-enforcer.d.ts.map +1 -0
  157. package/dist/src/core/sync/permission-enforcer.js +268 -0
  158. package/dist/src/core/sync/permission-enforcer.js.map +1 -0
  159. package/dist/src/core/sync/sync-audit-logger.d.ts +217 -0
  160. package/dist/src/core/sync/sync-audit-logger.d.ts.map +1 -0
  161. package/dist/src/core/sync/sync-audit-logger.js +327 -0
  162. package/dist/src/core/sync/sync-audit-logger.js.map +1 -0
  163. package/dist/src/core/sync/sync-interceptor.d.ts +190 -0
  164. package/dist/src/core/sync/sync-interceptor.d.ts.map +1 -0
  165. package/dist/src/core/sync/sync-interceptor.js +224 -0
  166. package/dist/src/core/sync/sync-interceptor.js.map +1 -0
  167. package/dist/src/core/types/increment-metadata.d.ts +5 -2
  168. package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
  169. package/dist/src/core/types/sync-config.d.ts +267 -0
  170. package/dist/src/core/types/sync-config.d.ts.map +1 -0
  171. package/dist/src/core/types/sync-config.js +304 -0
  172. package/dist/src/core/types/sync-config.js.map +1 -0
  173. package/dist/src/hooks/index.d.ts +11 -0
  174. package/dist/src/hooks/index.d.ts.map +1 -0
  175. package/dist/src/hooks/index.js +11 -0
  176. package/dist/src/hooks/index.js.map +1 -0
  177. package/dist/src/hooks/platform.d.ts +125 -0
  178. package/dist/src/hooks/platform.d.ts.map +1 -0
  179. package/dist/src/hooks/platform.js +325 -0
  180. package/dist/src/hooks/platform.js.map +1 -0
  181. package/dist/src/hooks/processor.d.ts +20 -0
  182. package/dist/src/hooks/processor.d.ts.map +1 -0
  183. package/dist/src/hooks/processor.js +317 -0
  184. package/dist/src/hooks/processor.js.map +1 -0
  185. package/dist/src/hooks/scheduler-startup.d.ts +19 -0
  186. package/dist/src/hooks/scheduler-startup.d.ts.map +1 -0
  187. package/dist/src/hooks/scheduler-startup.js +92 -0
  188. package/dist/src/hooks/scheduler-startup.js.map +1 -0
  189. package/dist/src/hooks/session-start.d.ts +16 -0
  190. package/dist/src/hooks/session-start.d.ts.map +1 -0
  191. package/dist/src/hooks/session-start.js +92 -0
  192. package/dist/src/hooks/session-start.js.map +1 -0
  193. package/dist/src/importers/duplicate-detector.d.ts +13 -2
  194. package/dist/src/importers/duplicate-detector.d.ts.map +1 -1
  195. package/dist/src/importers/duplicate-detector.js +21 -2
  196. package/dist/src/importers/duplicate-detector.js.map +1 -1
  197. package/dist/src/importers/item-converter.d.ts +41 -2
  198. package/dist/src/importers/item-converter.d.ts.map +1 -1
  199. package/dist/src/importers/item-converter.js +231 -45
  200. package/dist/src/importers/item-converter.js.map +1 -1
  201. package/dist/src/living-docs/fs-id-allocator.d.ts +7 -0
  202. package/dist/src/living-docs/fs-id-allocator.d.ts.map +1 -1
  203. package/dist/src/living-docs/fs-id-allocator.js +30 -4
  204. package/dist/src/living-docs/fs-id-allocator.js.map +1 -1
  205. package/dist/src/sync/ado-sync-wrapper.d.ts +137 -0
  206. package/dist/src/sync/ado-sync-wrapper.d.ts.map +1 -0
  207. package/dist/src/sync/ado-sync-wrapper.js +148 -0
  208. package/dist/src/sync/ado-sync-wrapper.js.map +1 -0
  209. package/dist/src/sync/github-sync-wrapper.d.ts +195 -0
  210. package/dist/src/sync/github-sync-wrapper.d.ts.map +1 -0
  211. package/dist/src/sync/github-sync-wrapper.js +220 -0
  212. package/dist/src/sync/github-sync-wrapper.js.map +1 -0
  213. package/dist/src/sync/jira-sync-wrapper.d.ts +155 -0
  214. package/dist/src/sync/jira-sync-wrapper.d.ts.map +1 -0
  215. package/dist/src/sync/jira-sync-wrapper.js +175 -0
  216. package/dist/src/sync/jira-sync-wrapper.js.map +1 -0
  217. package/dist/src/utils/feature-id-derivation.d.ts +58 -0
  218. package/dist/src/utils/feature-id-derivation.d.ts.map +1 -0
  219. package/dist/src/utils/feature-id-derivation.js +77 -0
  220. package/dist/src/utils/feature-id-derivation.js.map +1 -0
  221. package/package.json +1 -1
  222. package/plugins/specweave/commands/specweave-discrepancies.md +141 -0
  223. package/plugins/specweave/commands/specweave-discrepancy-to-increment.md +160 -0
  224. package/plugins/specweave/commands/specweave-jobs.md +45 -2
  225. package/plugins/specweave/commands/specweave-notifications.md +92 -0
  226. package/plugins/specweave/commands/specweave-sync-logs.md +131 -0
  227. package/plugins/specweave/commands/specweave-sync-monitor.md +57 -0
  228. package/plugins/specweave/hooks/hooks.json +3 -3
  229. package/plugins/specweave/hooks/lib/scheduler-startup.sh +72 -0
  230. package/plugins/specweave/hooks/universal/dispatcher.mjs +246 -0
  231. package/plugins/specweave/hooks/universal/session-start.cmd +16 -0
  232. package/plugins/specweave/hooks/universal/session-start.ps1 +16 -0
  233. package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +14 -5
  234. package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +5 -2
  235. package/plugins/specweave/skills/discrepancy-viewer.md +154 -0
  236. package/plugins/specweave-ado/lib/ado-project-detector.js +11 -5
  237. package/plugins/specweave-ado/lib/ado-project-detector.ts +16 -5
  238. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +34 -0
  239. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +51 -0
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Scheduler Module
3
+ *
4
+ * Exports job scheduling functionality for the sync orchestration system.
5
+ *
6
+ * @module core/scheduler
7
+ */
8
+ export * from './scheduled-job.js';
9
+ export * from './job-scheduler.js';
10
+ export * from './schedule-persistence.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/scheduler/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Scheduler Module
3
+ *
4
+ * Exports job scheduling functionality for the sync orchestration system.
5
+ *
6
+ * @module core/scheduler
7
+ */
8
+ export * from './scheduled-job.js';
9
+ export * from './job-scheduler.js';
10
+ export * from './schedule-persistence.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/scheduler/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Job Scheduler
3
+ *
4
+ * Core scheduler that manages recurring jobs with configurable intervals.
5
+ * Supports pause/resume, retry with backoff, and job state tracking.
6
+ *
7
+ * @module core/scheduler/job-scheduler
8
+ */
9
+ import { ScheduledJob, ScheduledJobConfig, JobType } from './scheduled-job.js';
10
+ import { Logger } from '../../utils/logger.js';
11
+ /**
12
+ * Job scheduler configuration
13
+ */
14
+ export interface JobSchedulerOptions {
15
+ /**
16
+ * Logger instance
17
+ */
18
+ logger?: Logger;
19
+ }
20
+ /**
21
+ * Job scheduler events
22
+ */
23
+ export type JobSchedulerEvent = 'job-registered' | 'job-unregistered' | 'job-started' | 'job-completed' | 'job-failed' | 'job-paused' | 'job-resumed';
24
+ /**
25
+ * Event listener callback
26
+ */
27
+ export type JobSchedulerEventListener = (event: JobSchedulerEvent, job: ScheduledJob, data?: Record<string, unknown>) => void;
28
+ /**
29
+ * JobScheduler - Manages recurring background jobs
30
+ *
31
+ * Key features:
32
+ * - Register/unregister jobs dynamically
33
+ * - Check for due jobs (for execution by caller)
34
+ * - Track job state (idle, running, failed, disabled)
35
+ * - Exponential backoff for failed jobs
36
+ * - Event notifications for state changes
37
+ */
38
+ export declare class JobScheduler {
39
+ private jobs;
40
+ private listeners;
41
+ private readonly logger;
42
+ constructor(options?: JobSchedulerOptions);
43
+ /**
44
+ * Register a new job with the scheduler
45
+ *
46
+ * @param config - Job configuration
47
+ * @throws Error if job with same ID already exists
48
+ */
49
+ registerJob(config: ScheduledJobConfig): void;
50
+ /**
51
+ * Unregister a job from the scheduler
52
+ *
53
+ * @param jobId - Job ID to remove
54
+ * @returns true if job was removed, false if not found
55
+ */
56
+ unregisterJob(jobId: string): boolean;
57
+ /**
58
+ * Get a job by ID
59
+ *
60
+ * @param jobId - Job ID
61
+ * @returns Job or undefined if not found
62
+ */
63
+ getJob(jobId: string): ScheduledJob | undefined;
64
+ /**
65
+ * Get all registered jobs
66
+ *
67
+ * @returns Array of all jobs
68
+ */
69
+ getAllJobs(): ScheduledJob[];
70
+ /**
71
+ * Get jobs by type
72
+ *
73
+ * @param type - Job type to filter by
74
+ * @returns Array of matching jobs
75
+ */
76
+ getJobsByType(type: JobType): ScheduledJob[];
77
+ /**
78
+ * Get all jobs that are due for execution
79
+ *
80
+ * @returns Array of due jobs (sorted by next run time)
81
+ */
82
+ getNextDueJobs(): ScheduledJob[];
83
+ /**
84
+ * Mark a job as started (running)
85
+ *
86
+ * @param jobId - Job ID
87
+ * @throws Error if job not found or not in idle state
88
+ */
89
+ markJobStarted(jobId: string): void;
90
+ /**
91
+ * Mark a job as completed successfully
92
+ *
93
+ * @param jobId - Job ID
94
+ * @param data - Optional result data
95
+ * @throws Error if job not found
96
+ */
97
+ markJobComplete(jobId: string, data?: Record<string, unknown>): void;
98
+ /**
99
+ * Mark a job as failed
100
+ *
101
+ * @param jobId - Job ID
102
+ * @param error - Error message
103
+ * @throws Error if job not found
104
+ */
105
+ markJobFailed(jobId: string, error: string): void;
106
+ /**
107
+ * Pause a job (stops scheduling but preserves state)
108
+ *
109
+ * @param jobId - Job ID
110
+ * @throws Error if job not found
111
+ */
112
+ pauseJob(jobId: string): void;
113
+ /**
114
+ * Resume a paused job
115
+ *
116
+ * @param jobId - Job ID
117
+ * @throws Error if job not found
118
+ */
119
+ resumeJob(jobId: string): void;
120
+ /**
121
+ * Reset a failed job for retry
122
+ *
123
+ * @param jobId - Job ID
124
+ * @throws Error if job not found
125
+ */
126
+ resetJob(jobId: string): void;
127
+ /**
128
+ * Update job interval
129
+ *
130
+ * @param jobId - Job ID
131
+ * @param intervalMs - New interval in milliseconds
132
+ * @throws Error if job not found
133
+ */
134
+ updateJobInterval(jobId: string, intervalMs: number): void;
135
+ /**
136
+ * Load jobs from persisted state
137
+ *
138
+ * @param jobs - Array of persisted jobs
139
+ */
140
+ loadJobs(jobs: ScheduledJob[]): void;
141
+ /**
142
+ * Get all jobs for persistence
143
+ *
144
+ * @returns Array of all jobs
145
+ */
146
+ getJobsForPersistence(): ScheduledJob[];
147
+ /**
148
+ * Add an event listener
149
+ *
150
+ * @param listener - Callback function
151
+ */
152
+ addEventListener(listener: JobSchedulerEventListener): void;
153
+ /**
154
+ * Remove an event listener
155
+ *
156
+ * @param listener - Callback function
157
+ */
158
+ removeEventListener(listener: JobSchedulerEventListener): void;
159
+ /**
160
+ * Get scheduler statistics
161
+ *
162
+ * @returns Scheduler stats
163
+ */
164
+ getStats(): {
165
+ totalJobs: number;
166
+ byStatus: Record<string, number>;
167
+ byType: Record<string, number>;
168
+ dueCount: number;
169
+ };
170
+ /**
171
+ * Emit an event to all listeners
172
+ */
173
+ private emit;
174
+ /**
175
+ * Get a job or throw if not found
176
+ */
177
+ private getJobOrThrow;
178
+ }
179
+ //# sourceMappingURL=job-scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-scheduler.d.ts","sourceRoot":"","sources":["../../../../src/core/scheduler/job-scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,OAAO,EASR,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAiB,MAAM,uBAAuB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,gBAAgB,GAChB,kBAAkB,GAClB,aAAa,GACb,eAAe,GACf,YAAY,GACZ,YAAY,GACZ,aAAa,CAAC;AAElB;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,iBAAiB,EACxB,GAAG,EAAE,YAAY,EACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC3B,IAAI,CAAC;AAEV;;;;;;;;;GASG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAA4B;IACxC,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,GAAE,mBAAwB;IAM7C;;;;;OAKG;IACH,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAY7C;;;;;OAKG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAYrC;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI/C;;;;OAIG;IACH,UAAU,IAAI,YAAY,EAAE;IAI5B;;;;;OAKG;IACH,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,EAAE;IAI5C;;;;OAIG;IACH,cAAc,IAAI,YAAY,EAAE;IAWhC;;;;;OAKG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAcnC;;;;;;OAMG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAUpE;;;;;;OAMG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAcjD;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAU7B;;;;;OAKG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAU9B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAS7B;;;;;;OAMG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAe1D;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI;IAQpC;;;;OAIG;IACH,qBAAqB,IAAI,YAAY,EAAE;IAIvC;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,yBAAyB,GAAG,IAAI;IAI3D;;;;OAIG;IACH,mBAAmB,CAAC,QAAQ,EAAE,yBAAyB,GAAG,IAAI;IAI9D;;;;OAIG;IACH,QAAQ,IAAI;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,QAAQ,EAAE,MAAM,CAAC;KAClB;IAkBD;;OAEG;IACH,OAAO,CAAC,IAAI;IAcZ;;OAEG;IACH,OAAO,CAAC,aAAa;CAOtB"}
@@ -0,0 +1,282 @@
1
+ /**
2
+ * Job Scheduler
3
+ *
4
+ * Core scheduler that manages recurring jobs with configurable intervals.
5
+ * Supports pause/resume, retry with backoff, and job state tracking.
6
+ *
7
+ * @module core/scheduler/job-scheduler
8
+ */
9
+ import { createScheduledJob, isJobDue, markJobComplete, markJobFailed, markJobRunning, pauseJob, resumeJob, resetJob, } from './scheduled-job.js';
10
+ import { consoleLogger } from '../../utils/logger.js';
11
+ /**
12
+ * JobScheduler - Manages recurring background jobs
13
+ *
14
+ * Key features:
15
+ * - Register/unregister jobs dynamically
16
+ * - Check for due jobs (for execution by caller)
17
+ * - Track job state (idle, running, failed, disabled)
18
+ * - Exponential backoff for failed jobs
19
+ * - Event notifications for state changes
20
+ */
21
+ export class JobScheduler {
22
+ constructor(options = {}) {
23
+ this.jobs = new Map();
24
+ this.listeners = new Set();
25
+ this.logger = options.logger ?? consoleLogger;
26
+ }
27
+ /**
28
+ * Register a new job with the scheduler
29
+ *
30
+ * @param config - Job configuration
31
+ * @throws Error if job with same ID already exists
32
+ */
33
+ registerJob(config) {
34
+ if (this.jobs.has(config.id)) {
35
+ throw new Error(`Job with ID "${config.id}" already registered`);
36
+ }
37
+ const job = createScheduledJob(config);
38
+ this.jobs.set(config.id, job);
39
+ this.logger.debug(`Registered job: ${config.id} (interval: ${config.intervalMs}ms)`);
40
+ this.emit('job-registered', job);
41
+ }
42
+ /**
43
+ * Unregister a job from the scheduler
44
+ *
45
+ * @param jobId - Job ID to remove
46
+ * @returns true if job was removed, false if not found
47
+ */
48
+ unregisterJob(jobId) {
49
+ const job = this.jobs.get(jobId);
50
+ if (!job) {
51
+ return false;
52
+ }
53
+ this.jobs.delete(jobId);
54
+ this.logger.debug(`Unregistered job: ${jobId}`);
55
+ this.emit('job-unregistered', job);
56
+ return true;
57
+ }
58
+ /**
59
+ * Get a job by ID
60
+ *
61
+ * @param jobId - Job ID
62
+ * @returns Job or undefined if not found
63
+ */
64
+ getJob(jobId) {
65
+ return this.jobs.get(jobId);
66
+ }
67
+ /**
68
+ * Get all registered jobs
69
+ *
70
+ * @returns Array of all jobs
71
+ */
72
+ getAllJobs() {
73
+ return Array.from(this.jobs.values());
74
+ }
75
+ /**
76
+ * Get jobs by type
77
+ *
78
+ * @param type - Job type to filter by
79
+ * @returns Array of matching jobs
80
+ */
81
+ getJobsByType(type) {
82
+ return this.getAllJobs().filter((job) => job.type === type);
83
+ }
84
+ /**
85
+ * Get all jobs that are due for execution
86
+ *
87
+ * @returns Array of due jobs (sorted by next run time)
88
+ */
89
+ getNextDueJobs() {
90
+ const dueJobs = this.getAllJobs().filter(isJobDue);
91
+ // Sort by next run time (earliest first)
92
+ return dueJobs.sort((a, b) => {
93
+ const aTime = a.schedule.nextRun ? new Date(a.schedule.nextRun).getTime() : 0;
94
+ const bTime = b.schedule.nextRun ? new Date(b.schedule.nextRun).getTime() : 0;
95
+ return aTime - bTime;
96
+ });
97
+ }
98
+ /**
99
+ * Mark a job as started (running)
100
+ *
101
+ * @param jobId - Job ID
102
+ * @throws Error if job not found or not in idle state
103
+ */
104
+ markJobStarted(jobId) {
105
+ const job = this.getJobOrThrow(jobId);
106
+ if (job.status !== 'idle') {
107
+ throw new Error(`Cannot start job "${jobId}" - status is "${job.status}", expected "idle"`);
108
+ }
109
+ const updatedJob = markJobRunning(job);
110
+ this.jobs.set(jobId, updatedJob);
111
+ this.logger.debug(`Job started: ${jobId}`);
112
+ this.emit('job-started', updatedJob);
113
+ }
114
+ /**
115
+ * Mark a job as completed successfully
116
+ *
117
+ * @param jobId - Job ID
118
+ * @param data - Optional result data
119
+ * @throws Error if job not found
120
+ */
121
+ markJobComplete(jobId, data) {
122
+ const job = this.getJobOrThrow(jobId);
123
+ const updatedJob = markJobComplete(job);
124
+ this.jobs.set(jobId, updatedJob);
125
+ this.logger.debug(`Job completed: ${jobId}, next run: ${updatedJob.schedule.nextRun}`);
126
+ this.emit('job-completed', updatedJob, data);
127
+ }
128
+ /**
129
+ * Mark a job as failed
130
+ *
131
+ * @param jobId - Job ID
132
+ * @param error - Error message
133
+ * @throws Error if job not found
134
+ */
135
+ markJobFailed(jobId, error) {
136
+ const job = this.getJobOrThrow(jobId);
137
+ const updatedJob = markJobFailed(job, error);
138
+ this.jobs.set(jobId, updatedJob);
139
+ const retryInfo = updatedJob.status === 'failed'
140
+ ? 'max retries reached'
141
+ : `retry ${updatedJob.schedule.retryCount}/${updatedJob.schedule.maxRetries}`;
142
+ this.logger.warn(`Job failed: ${jobId} - ${error} (${retryInfo})`);
143
+ this.emit('job-failed', updatedJob, { error });
144
+ }
145
+ /**
146
+ * Pause a job (stops scheduling but preserves state)
147
+ *
148
+ * @param jobId - Job ID
149
+ * @throws Error if job not found
150
+ */
151
+ pauseJob(jobId) {
152
+ const job = this.getJobOrThrow(jobId);
153
+ const updatedJob = pauseJob(job);
154
+ this.jobs.set(jobId, updatedJob);
155
+ this.logger.debug(`Job paused: ${jobId}`);
156
+ this.emit('job-paused', updatedJob);
157
+ }
158
+ /**
159
+ * Resume a paused job
160
+ *
161
+ * @param jobId - Job ID
162
+ * @throws Error if job not found
163
+ */
164
+ resumeJob(jobId) {
165
+ const job = this.getJobOrThrow(jobId);
166
+ const updatedJob = resumeJob(job);
167
+ this.jobs.set(jobId, updatedJob);
168
+ this.logger.debug(`Job resumed: ${jobId}, next run: ${updatedJob.schedule.nextRun}`);
169
+ this.emit('job-resumed', updatedJob);
170
+ }
171
+ /**
172
+ * Reset a failed job for retry
173
+ *
174
+ * @param jobId - Job ID
175
+ * @throws Error if job not found
176
+ */
177
+ resetJob(jobId) {
178
+ const job = this.getJobOrThrow(jobId);
179
+ const updatedJob = resetJob(job);
180
+ this.jobs.set(jobId, updatedJob);
181
+ this.logger.debug(`Job reset: ${jobId}`);
182
+ }
183
+ /**
184
+ * Update job interval
185
+ *
186
+ * @param jobId - Job ID
187
+ * @param intervalMs - New interval in milliseconds
188
+ * @throws Error if job not found
189
+ */
190
+ updateJobInterval(jobId, intervalMs) {
191
+ const job = this.getJobOrThrow(jobId);
192
+ const updatedJob = {
193
+ ...job,
194
+ schedule: {
195
+ ...job.schedule,
196
+ intervalMs,
197
+ },
198
+ };
199
+ this.jobs.set(jobId, updatedJob);
200
+ this.logger.debug(`Job interval updated: ${jobId} -> ${intervalMs}ms`);
201
+ }
202
+ /**
203
+ * Load jobs from persisted state
204
+ *
205
+ * @param jobs - Array of persisted jobs
206
+ */
207
+ loadJobs(jobs) {
208
+ this.jobs.clear();
209
+ for (const job of jobs) {
210
+ this.jobs.set(job.id, job);
211
+ }
212
+ this.logger.debug(`Loaded ${jobs.length} jobs from persistence`);
213
+ }
214
+ /**
215
+ * Get all jobs for persistence
216
+ *
217
+ * @returns Array of all jobs
218
+ */
219
+ getJobsForPersistence() {
220
+ return this.getAllJobs();
221
+ }
222
+ /**
223
+ * Add an event listener
224
+ *
225
+ * @param listener - Callback function
226
+ */
227
+ addEventListener(listener) {
228
+ this.listeners.add(listener);
229
+ }
230
+ /**
231
+ * Remove an event listener
232
+ *
233
+ * @param listener - Callback function
234
+ */
235
+ removeEventListener(listener) {
236
+ this.listeners.delete(listener);
237
+ }
238
+ /**
239
+ * Get scheduler statistics
240
+ *
241
+ * @returns Scheduler stats
242
+ */
243
+ getStats() {
244
+ const jobs = this.getAllJobs();
245
+ const byStatus = {};
246
+ const byType = {};
247
+ for (const job of jobs) {
248
+ byStatus[job.status] = (byStatus[job.status] || 0) + 1;
249
+ byType[job.type] = (byType[job.type] || 0) + 1;
250
+ }
251
+ return {
252
+ totalJobs: jobs.length,
253
+ byStatus,
254
+ byType,
255
+ dueCount: this.getNextDueJobs().length,
256
+ };
257
+ }
258
+ /**
259
+ * Emit an event to all listeners
260
+ */
261
+ emit(event, job, data) {
262
+ for (const listener of this.listeners) {
263
+ try {
264
+ listener(event, job, data);
265
+ }
266
+ catch (err) {
267
+ this.logger.error(`Error in job scheduler event listener: ${err}`);
268
+ }
269
+ }
270
+ }
271
+ /**
272
+ * Get a job or throw if not found
273
+ */
274
+ getJobOrThrow(jobId) {
275
+ const job = this.jobs.get(jobId);
276
+ if (!job) {
277
+ throw new Error(`Job not found: ${jobId}`);
278
+ }
279
+ return job;
280
+ }
281
+ }
282
+ //# sourceMappingURL=job-scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-scheduler.js","sourceRoot":"","sources":["../../../../src/core/scheduler/job-scheduler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Schedule Persistence
3
+ *
4
+ * Persists job schedules to disk so they survive session restarts.
5
+ * Uses atomic writes to prevent corruption.
6
+ *
7
+ * @module core/scheduler/schedule-persistence
8
+ */
9
+ import { ScheduledJob } from './scheduled-job.js';
10
+ import { Logger } from '../../utils/logger.js';
11
+ /**
12
+ * Schedule persistence options
13
+ */
14
+ export interface SchedulePersistenceOptions {
15
+ /**
16
+ * Path to .specweave directory
17
+ * @default process.cwd() + '/.specweave'
18
+ */
19
+ specweavePath?: string;
20
+ /**
21
+ * Logger instance
22
+ */
23
+ logger?: Logger;
24
+ }
25
+ /**
26
+ * SchedulePersistence - Saves and loads job schedules from disk
27
+ *
28
+ * Features:
29
+ * - Atomic writes using temp file + rename
30
+ * - Schema versioning for migration
31
+ * - Corruption recovery with defaults
32
+ */
33
+ export declare class SchedulePersistence {
34
+ private readonly filePath;
35
+ private readonly logger;
36
+ constructor(options?: SchedulePersistenceOptions);
37
+ /**
38
+ * Load schedules from disk
39
+ *
40
+ * @returns Array of persisted jobs, empty array if file doesn't exist or is corrupted
41
+ */
42
+ loadSchedules(): Promise<ScheduledJob[]>;
43
+ /**
44
+ * Save schedules to disk
45
+ *
46
+ * Uses atomic write (write to temp file, then rename) to prevent corruption.
47
+ *
48
+ * @param jobs - Jobs to persist
49
+ */
50
+ saveSchedules(jobs: ScheduledJob[]): Promise<void>;
51
+ /**
52
+ * Update a single job in persistence
53
+ *
54
+ * @param jobId - Job ID to update
55
+ * @param updates - Partial job updates
56
+ */
57
+ updateJob(jobId: string, updates: Partial<ScheduledJob>): Promise<void>;
58
+ /**
59
+ * Delete a job from persistence
60
+ *
61
+ * @param jobId - Job ID to delete
62
+ */
63
+ deleteJob(jobId: string): Promise<void>;
64
+ /**
65
+ * Check if persistence file exists
66
+ *
67
+ * @returns true if file exists
68
+ */
69
+ exists(): Promise<boolean>;
70
+ /**
71
+ * Get file path (for testing/debugging)
72
+ */
73
+ getFilePath(): string;
74
+ /**
75
+ * Migrate schedules from older schema versions
76
+ */
77
+ private migrateSchedules;
78
+ /**
79
+ * Backup corrupted file for debugging
80
+ */
81
+ private backupCorruptedFile;
82
+ }
83
+ //# sourceMappingURL=schedule-persistence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-persistence.d.ts","sourceRoot":"","sources":["../../../../src/core/scheduler/schedule-persistence.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAiB,MAAM,uBAAuB,CAAC;AA2B9D;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,GAAE,0BAA+B;IAMpD;;;;OAIG;IACG,aAAa,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IA4C9C;;;;;;OAMG;IACG,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA+BxD;;;;;OAKG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAa7E;;;;OAIG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7C;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAShC;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;YACW,gBAAgB;IAM9B;;OAEG;YACW,mBAAmB;CASlC"}