@proletariat/cli 0.3.105 → 0.3.109

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 (227) hide show
  1. package/dist/commands/agent/cleanup.js +13 -1
  2. package/dist/commands/agent/cleanup.js.map +1 -1
  3. package/dist/commands/claude/index.js +2 -2
  4. package/dist/commands/claude/index.js.map +1 -1
  5. package/dist/commands/feedback/list.js +4 -9
  6. package/dist/commands/feedback/list.js.map +1 -1
  7. package/dist/commands/feedback/submit.js +4 -9
  8. package/dist/commands/feedback/submit.js.map +1 -1
  9. package/dist/commands/feedback/view.js +4 -9
  10. package/dist/commands/feedback/view.js.map +1 -1
  11. package/dist/commands/gc.d.ts +1 -0
  12. package/dist/commands/gc.js +34 -1
  13. package/dist/commands/gc.js.map +1 -1
  14. package/dist/commands/notify/connect.d.ts +34 -0
  15. package/dist/commands/notify/connect.js +166 -0
  16. package/dist/commands/notify/connect.js.map +1 -0
  17. package/dist/commands/notify/disconnect.d.ts +16 -0
  18. package/dist/commands/notify/disconnect.js +45 -0
  19. package/dist/commands/notify/disconnect.js.map +1 -0
  20. package/dist/commands/notify/list.d.ts +15 -0
  21. package/dist/commands/notify/list.js +101 -0
  22. package/dist/commands/notify/list.js.map +1 -0
  23. package/dist/commands/notify/rules/add.d.ts +26 -0
  24. package/dist/commands/notify/rules/add.js +95 -0
  25. package/dist/commands/notify/rules/add.js.map +1 -0
  26. package/dist/commands/notify/rules/list.d.ts +14 -0
  27. package/dist/commands/notify/rules/list.js +82 -0
  28. package/dist/commands/notify/rules/list.js.map +1 -0
  29. package/dist/commands/notify/rules/remove.d.ts +16 -0
  30. package/dist/commands/notify/rules/remove.js +44 -0
  31. package/dist/commands/notify/rules/remove.js.map +1 -0
  32. package/dist/commands/notify/test.d.ts +16 -0
  33. package/dist/commands/notify/test.js +63 -0
  34. package/dist/commands/notify/test.js.map +1 -0
  35. package/dist/commands/orchestrate/index.js +11 -6
  36. package/dist/commands/orchestrate/index.js.map +1 -1
  37. package/dist/commands/orchestrate/machine.d.ts +29 -0
  38. package/dist/commands/orchestrate/machine.js +230 -0
  39. package/dist/commands/orchestrate/machine.js.map +1 -0
  40. package/dist/commands/pr/checks.js +4 -8
  41. package/dist/commands/pr/checks.js.map +1 -1
  42. package/dist/commands/pr/close.js +4 -8
  43. package/dist/commands/pr/close.js.map +1 -1
  44. package/dist/commands/pr/create.js +4 -8
  45. package/dist/commands/pr/create.js.map +1 -1
  46. package/dist/commands/pr/index.js +1 -1
  47. package/dist/commands/pr/index.js.map +1 -1
  48. package/dist/commands/pr/link.js +4 -8
  49. package/dist/commands/pr/link.js.map +1 -1
  50. package/dist/commands/pr/list.js +5 -9
  51. package/dist/commands/pr/list.js.map +1 -1
  52. package/dist/commands/pr/merge.d.ts +5 -0
  53. package/dist/commands/pr/merge.js +35 -11
  54. package/dist/commands/pr/merge.js.map +1 -1
  55. package/dist/commands/pr/status.js +5 -4
  56. package/dist/commands/pr/status.js.map +1 -1
  57. package/dist/commands/qa/index.js +2 -2
  58. package/dist/commands/qa/index.js.map +1 -1
  59. package/dist/commands/repo/create.js +4 -8
  60. package/dist/commands/repo/create.js.map +1 -1
  61. package/dist/commands/session/list.js +81 -41
  62. package/dist/commands/session/list.js.map +1 -1
  63. package/dist/commands/session/poke.d.ts +1 -11
  64. package/dist/commands/session/poke.js +20 -78
  65. package/dist/commands/session/poke.js.map +1 -1
  66. package/dist/commands/session/prune.js +3 -0
  67. package/dist/commands/session/prune.js.map +1 -1
  68. package/dist/commands/ticket/move.d.ts +12 -0
  69. package/dist/commands/ticket/move.js +75 -2
  70. package/dist/commands/ticket/move.js.map +1 -1
  71. package/dist/commands/work/drop.js +2 -2
  72. package/dist/commands/work/drop.js.map +1 -1
  73. package/dist/commands/work/ready.js +3 -3
  74. package/dist/commands/work/ready.js.map +1 -1
  75. package/dist/commands/work/rebase.js +4 -8
  76. package/dist/commands/work/rebase.js.map +1 -1
  77. package/dist/commands/work/run.d.ts +58 -0
  78. package/dist/commands/work/run.js +411 -0
  79. package/dist/commands/work/run.js.map +1 -0
  80. package/dist/commands/work/ship.d.ts +6 -0
  81. package/dist/commands/work/ship.js +93 -51
  82. package/dist/commands/work/ship.js.map +1 -1
  83. package/dist/commands/work/start.d.ts +1 -0
  84. package/dist/commands/work/start.js +126 -13
  85. package/dist/commands/work/start.js.map +1 -1
  86. package/dist/lib/agents/commands.d.ts +6 -0
  87. package/dist/lib/agents/commands.js +55 -2
  88. package/dist/lib/agents/commands.js.map +1 -1
  89. package/dist/lib/database/credential-store.js +2 -3
  90. package/dist/lib/database/credential-store.js.map +1 -1
  91. package/dist/lib/database/db-safety.d.ts +25 -0
  92. package/dist/lib/database/db-safety.js +35 -0
  93. package/dist/lib/database/db-safety.js.map +1 -1
  94. package/dist/lib/database/driver.js +6 -12
  95. package/dist/lib/database/driver.js.map +1 -1
  96. package/dist/lib/database/drizzle-schema.d.ts +3 -3
  97. package/dist/lib/database/drizzle.js +3 -3
  98. package/dist/lib/database/drizzle.js.map +1 -1
  99. package/dist/lib/database/index.d.ts +1 -1
  100. package/dist/lib/database/index.js +1 -1
  101. package/dist/lib/database/index.js.map +1 -1
  102. package/dist/lib/database/migrations/0021_notification_system.d.ts +2 -0
  103. package/dist/lib/database/migrations/0021_notification_system.js +39 -0
  104. package/dist/lib/database/migrations/0021_notification_system.js.map +1 -0
  105. package/dist/lib/database/migrations/0022_hook_mode_tiers.d.ts +11 -0
  106. package/dist/lib/database/migrations/0022_hook_mode_tiers.js +53 -0
  107. package/dist/lib/database/migrations/0022_hook_mode_tiers.js.map +1 -0
  108. package/dist/lib/database/migrations/index.js +4 -0
  109. package/dist/lib/database/migrations/index.js.map +1 -1
  110. package/dist/lib/database/pmo-bootstrap.js +6 -2
  111. package/dist/lib/database/pmo-bootstrap.js.map +1 -1
  112. package/dist/lib/database/workspace.js +5 -13
  113. package/dist/lib/database/workspace.js.map +1 -1
  114. package/dist/lib/events/emitting-runner.js +10 -0
  115. package/dist/lib/events/emitting-runner.js.map +1 -1
  116. package/dist/lib/execution/cc-version.d.ts +62 -0
  117. package/dist/lib/execution/cc-version.js +103 -0
  118. package/dist/lib/execution/cc-version.js.map +1 -0
  119. package/dist/lib/execution/devcontainer.js +2 -1
  120. package/dist/lib/execution/devcontainer.js.map +1 -1
  121. package/dist/lib/execution/runners/devcontainer.js +4 -1
  122. package/dist/lib/execution/runners/devcontainer.js.map +1 -1
  123. package/dist/lib/execution/runners/docker-management.js +10 -46
  124. package/dist/lib/execution/runners/docker-management.js.map +1 -1
  125. package/dist/lib/execution/runners/orchestrator.js +13 -39
  126. package/dist/lib/execution/runners/orchestrator.js.map +1 -1
  127. package/dist/lib/execution/session-utils.d.ts +88 -1
  128. package/dist/lib/execution/session-utils.js +120 -46
  129. package/dist/lib/execution/session-utils.js.map +1 -1
  130. package/dist/lib/execution/storage.js +20 -2
  131. package/dist/lib/execution/storage.js.map +1 -1
  132. package/dist/lib/flags/resolver.d.ts +8 -1
  133. package/dist/lib/flags/resolver.js +35 -2
  134. package/dist/lib/flags/resolver.js.map +1 -1
  135. package/dist/lib/gc/cascade.d.ts +99 -0
  136. package/dist/lib/gc/cascade.js +357 -0
  137. package/dist/lib/gc/cascade.js.map +1 -0
  138. package/dist/lib/gc/config.d.ts +69 -0
  139. package/dist/lib/gc/config.js +134 -0
  140. package/dist/lib/gc/config.js.map +1 -0
  141. package/dist/lib/gc/index.d.ts +36 -0
  142. package/dist/lib/gc/index.js +209 -1
  143. package/dist/lib/gc/index.js.map +1 -1
  144. package/dist/lib/init/index.js +10 -1
  145. package/dist/lib/init/index.js.map +1 -1
  146. package/dist/lib/machine-db.d.ts +144 -0
  147. package/dist/lib/machine-db.js +338 -0
  148. package/dist/lib/machine-db.js.map +1 -0
  149. package/dist/lib/machine-orchestrator.d.ts +35 -0
  150. package/dist/lib/machine-orchestrator.js +139 -0
  151. package/dist/lib/machine-orchestrator.js.map +1 -0
  152. package/dist/lib/notifications/dispatcher.d.ts +29 -0
  153. package/dist/lib/notifications/dispatcher.js +281 -0
  154. package/dist/lib/notifications/dispatcher.js.map +1 -0
  155. package/dist/lib/notifications/index.d.ts +13 -0
  156. package/dist/lib/notifications/index.js +18 -0
  157. package/dist/lib/notifications/index.js.map +1 -0
  158. package/dist/lib/notifications/manager.d.ts +46 -0
  159. package/dist/lib/notifications/manager.js +200 -0
  160. package/dist/lib/notifications/manager.js.map +1 -0
  161. package/dist/lib/notifications/storage.d.ts +60 -0
  162. package/dist/lib/notifications/storage.js +182 -0
  163. package/dist/lib/notifications/storage.js.map +1 -0
  164. package/dist/lib/notifications/types.d.ts +126 -0
  165. package/dist/lib/notifications/types.js +16 -0
  166. package/dist/lib/notifications/types.js.map +1 -0
  167. package/dist/lib/orchestrate/actions.js +182 -3
  168. package/dist/lib/orchestrate/actions.js.map +1 -1
  169. package/dist/lib/orchestrate/config-loader.js +9 -35
  170. package/dist/lib/orchestrate/config-loader.js.map +1 -1
  171. package/dist/lib/orchestrate/engine.d.ts +53 -1
  172. package/dist/lib/orchestrate/engine.js +74 -3
  173. package/dist/lib/orchestrate/engine.js.map +1 -1
  174. package/dist/lib/orchestrate/escalation.d.ts +87 -0
  175. package/dist/lib/orchestrate/escalation.js +63 -0
  176. package/dist/lib/orchestrate/escalation.js.map +1 -0
  177. package/dist/lib/orchestrate/index.d.ts +2 -0
  178. package/dist/lib/orchestrate/index.js +1 -0
  179. package/dist/lib/orchestrate/index.js.map +1 -1
  180. package/dist/lib/orchestrate/llm-agent.d.ts +101 -0
  181. package/dist/lib/orchestrate/llm-agent.js +295 -0
  182. package/dist/lib/orchestrate/llm-agent.js.map +1 -0
  183. package/dist/lib/orchestrate/presets.d.ts +4 -3
  184. package/dist/lib/orchestrate/presets.js +13 -8
  185. package/dist/lib/orchestrate/presets.js.map +1 -1
  186. package/dist/lib/orchestrate/types.d.ts +7 -1
  187. package/dist/lib/orchestrate/types.js +1 -0
  188. package/dist/lib/orchestrate/types.js.map +1 -1
  189. package/dist/lib/pmo/base-command.js +1 -1
  190. package/dist/lib/pmo/base-command.js.map +1 -1
  191. package/dist/lib/pmo/find-pmo.d.ts +8 -0
  192. package/dist/lib/pmo/find-pmo.js +63 -2
  193. package/dist/lib/pmo/find-pmo.js.map +1 -1
  194. package/dist/lib/pmo/index.d.ts +1 -1
  195. package/dist/lib/pmo/index.js +1 -1
  196. package/dist/lib/pmo/index.js.map +1 -1
  197. package/dist/lib/pmo/pmo-context.js +1 -1
  198. package/dist/lib/pmo/pmo-context.js.map +1 -1
  199. package/dist/lib/pmo/storage/index.js +2 -1
  200. package/dist/lib/pmo/storage/index.js.map +1 -1
  201. package/dist/lib/pr/index.d.ts +32 -0
  202. package/dist/lib/pr/index.js +45 -0
  203. package/dist/lib/pr/index.js.map +1 -1
  204. package/dist/lib/registry/index.js +0 -1
  205. package/dist/lib/registry/index.js.map +1 -1
  206. package/dist/lib/signal-handler.d.ts +8 -0
  207. package/dist/lib/signal-handler.js +33 -0
  208. package/dist/lib/signal-handler.js.map +1 -1
  209. package/dist/lib/themes.js +8 -1
  210. package/dist/lib/themes.js.map +1 -1
  211. package/dist/lib/work-lifecycle/container-cleanup-hook.d.ts +17 -7
  212. package/dist/lib/work-lifecycle/container-cleanup-hook.js +64 -11
  213. package/dist/lib/work-lifecycle/container-cleanup-hook.js.map +1 -1
  214. package/dist/lib/work-lifecycle/hooks/executor.d.ts +22 -2
  215. package/dist/lib/work-lifecycle/hooks/executor.js +46 -8
  216. package/dist/lib/work-lifecycle/hooks/executor.js.map +1 -1
  217. package/dist/lib/work-lifecycle/hooks/manager.d.ts +62 -3
  218. package/dist/lib/work-lifecycle/hooks/manager.js +285 -4
  219. package/dist/lib/work-lifecycle/hooks/manager.js.map +1 -1
  220. package/dist/lib/work-lifecycle/hooks/types.d.ts +36 -5
  221. package/dist/lib/work-lifecycle/hooks/types.js +1 -1
  222. package/dist/lib/work-lifecycle/hooks/types.js.map +1 -1
  223. package/dist/lib/workspace-resolution.d.ts +73 -0
  224. package/dist/lib/workspace-resolution.js +188 -0
  225. package/dist/lib/workspace-resolution.js.map +1 -0
  226. package/oclif.manifest.json +2830 -2142
  227. package/package.json +1 -1
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Notification Manager
3
+ *
4
+ * Integrates with the EventBus and hook system to dispatch notifications.
5
+ * Subscribes to hookable events, looks up notification rules, and dispatches
6
+ * through configured providers. Manages escalation chains with timeout-based
7
+ * escalation (e.g., Slack first, SMS after 10min, email after 30min).
8
+ */
9
+ import { NotificationStorage } from './storage.js';
10
+ import { dispatchNotification } from './dispatcher.js';
11
+ import { HOOKABLE_EVENTS } from '../work-lifecycle/hooks/types.js';
12
+ export class NotificationManager {
13
+ storage;
14
+ log;
15
+ unsubscribers = [];
16
+ activeEscalations = new Map();
17
+ constructor(options) {
18
+ this.storage = new NotificationStorage(options.db);
19
+ this.log = options.log ?? (() => { });
20
+ }
21
+ /**
22
+ * Start listening to events on the EventBus.
23
+ * Dynamically imports event-bus to avoid circular dependency at module load.
24
+ */
25
+ async start() {
26
+ const { getEventBus } = await import('../events/event-bus.js');
27
+ const bus = getEventBus();
28
+ for (const event of HOOKABLE_EVENTS) {
29
+ // Use `any` for the listener callback since event payload types vary
30
+ // and we normalize them into NotificationContext in handleEvent.
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ const unsub = bus.on(event, (payload) => {
33
+ void this.handleEvent(event, payload);
34
+ });
35
+ this.unsubscribers.push(unsub);
36
+ }
37
+ }
38
+ /** Stop listening and clear all escalation timers. */
39
+ stop() {
40
+ for (const unsub of this.unsubscribers) {
41
+ unsub();
42
+ }
43
+ this.unsubscribers = [];
44
+ // Clear all escalation timers
45
+ for (const escalation of this.activeEscalations.values()) {
46
+ if (escalation.timerId) {
47
+ clearTimeout(escalation.timerId);
48
+ }
49
+ }
50
+ this.activeEscalations.clear();
51
+ }
52
+ /**
53
+ * Manually fire a notification for an event.
54
+ * Returns results for all matched rules.
55
+ */
56
+ async fireEvent(event, context) {
57
+ return this.handleEvent(event, context);
58
+ }
59
+ /**
60
+ * Acknowledge an escalation chain (stops further escalation).
61
+ */
62
+ acknowledgeEscalation(group) {
63
+ const escalation = this.activeEscalations.get(group);
64
+ if (!escalation)
65
+ return false;
66
+ escalation.acknowledged = true;
67
+ if (escalation.timerId) {
68
+ clearTimeout(escalation.timerId);
69
+ }
70
+ this.activeEscalations.delete(group);
71
+ this.log(`Escalation group "${group}" acknowledged — stopping further escalation`);
72
+ return true;
73
+ }
74
+ /** Get active escalation chains. */
75
+ getActiveEscalations() {
76
+ return Array.from(this.activeEscalations.values());
77
+ }
78
+ // ─── Internal ─────────────────────────────────────────────────
79
+ async handleEvent(event, rawContext) {
80
+ const context = this.normalizeContext(event, rawContext);
81
+ const rulesWithProviders = this.storage.getRulesWithProviders(event);
82
+ if (rulesWithProviders.length === 0)
83
+ return [];
84
+ // Separate immediate rules from escalation rules
85
+ const immediateRules = rulesWithProviders.filter(rp => !rp.rule.escalationGroup);
86
+ const escalationRules = rulesWithProviders.filter(rp => rp.rule.escalationGroup);
87
+ // Dispatch immediate notifications
88
+ const results = [];
89
+ for (const { rule, provider } of immediateRules) {
90
+ this.log(`Dispatching ${provider.type} notification via "${provider.name}" for ${event}`);
91
+ const result = await dispatchNotification(provider, context);
92
+ results.push(result);
93
+ if (!result.success) {
94
+ this.log(`Notification failed: ${result.error}`);
95
+ }
96
+ }
97
+ // Start escalation chains
98
+ const escalationGroups = new Map();
99
+ for (const { rule, provider } of escalationRules) {
100
+ const group = rule.escalationGroup;
101
+ if (!escalationGroups.has(group)) {
102
+ escalationGroups.set(group, []);
103
+ }
104
+ escalationGroups.get(group).push({
105
+ rule,
106
+ provider,
107
+ delaySeconds: rule.escalationDelaySeconds ?? 0,
108
+ });
109
+ }
110
+ for (const [group, steps] of escalationGroups) {
111
+ // Sort by delay (ascending) so we escalate in order
112
+ steps.sort((a, b) => a.delaySeconds - b.delaySeconds);
113
+ this.startEscalationChain(group, event, context, steps);
114
+ }
115
+ return results;
116
+ }
117
+ startEscalationChain(group, event, context, steps) {
118
+ // If there's already an active escalation for this group, skip
119
+ if (this.activeEscalations.has(group))
120
+ return;
121
+ const escalation = {
122
+ group,
123
+ event,
124
+ context,
125
+ steps,
126
+ currentStep: 0,
127
+ startedAt: Date.now(),
128
+ acknowledged: false,
129
+ };
130
+ this.activeEscalations.set(group, escalation);
131
+ this.log(`Starting escalation chain "${group}" with ${steps.length} step(s)`);
132
+ // Execute the first step immediately if delay is 0
133
+ void this.executeEscalationStep(escalation);
134
+ }
135
+ async executeEscalationStep(escalation) {
136
+ if (escalation.acknowledged || escalation.currentStep >= escalation.steps.length) {
137
+ this.activeEscalations.delete(escalation.group);
138
+ return;
139
+ }
140
+ const step = escalation.steps[escalation.currentStep];
141
+ const elapsed = (Date.now() - escalation.startedAt) / 1000;
142
+ const remainingDelay = Math.max(0, step.delaySeconds - elapsed);
143
+ if (remainingDelay > 0) {
144
+ // Schedule this step for later
145
+ escalation.timerId = setTimeout(() => {
146
+ void this.executeEscalationStep(escalation);
147
+ }, remainingDelay * 1000);
148
+ return;
149
+ }
150
+ // Execute this step now
151
+ this.log(`Escalation "${escalation.group}" step ${escalation.currentStep + 1}/${escalation.steps.length}: ${step.provider.type} via "${step.provider.name}"`);
152
+ await dispatchNotification(step.provider, escalation.context);
153
+ escalation.currentStep++;
154
+ // Schedule next step if available
155
+ if (escalation.currentStep < escalation.steps.length) {
156
+ const nextStep = escalation.steps[escalation.currentStep];
157
+ const nextElapsed = (Date.now() - escalation.startedAt) / 1000;
158
+ const nextDelay = Math.max(0, nextStep.delaySeconds - nextElapsed);
159
+ escalation.timerId = setTimeout(() => {
160
+ void this.executeEscalationStep(escalation);
161
+ }, nextDelay * 1000);
162
+ }
163
+ else {
164
+ this.activeEscalations.delete(escalation.group);
165
+ }
166
+ }
167
+ normalizeContext(event, raw) {
168
+ return {
169
+ event,
170
+ ticket: raw.ticket ?? raw.ticketId,
171
+ pr: raw.pr ?? raw.prNumber,
172
+ branch: raw.branch,
173
+ agent: raw.agent ?? raw.sessionId,
174
+ container: raw.container,
175
+ message: raw.message,
176
+ ...raw,
177
+ };
178
+ }
179
+ }
180
+ // =============================================================================
181
+ // Singleton
182
+ // =============================================================================
183
+ let _instance = null;
184
+ export function initNotificationManager(options) {
185
+ if (_instance) {
186
+ _instance.stop();
187
+ }
188
+ _instance = new NotificationManager(options);
189
+ return _instance;
190
+ }
191
+ export function getNotificationManager() {
192
+ return _instance;
193
+ }
194
+ export function stopNotificationManager() {
195
+ if (_instance) {
196
+ _instance.stop();
197
+ _instance = null;
198
+ }
199
+ }
200
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/lib/notifications/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Notification Storage
3
+ *
4
+ * CRUD operations for notification providers and rules in the workspace database.
5
+ * Follows the WorkHookStorage pattern.
6
+ */
7
+ import type Database from 'better-sqlite3';
8
+ import type { NotificationProvider, NotificationProviderType, NotificationRule, NotificationEvent, ProviderConfig } from './types.js';
9
+ export declare class NotificationStorage {
10
+ private db;
11
+ constructor(db: Database.Database);
12
+ /** List all providers, optionally filtered by type or enabled status. */
13
+ listProviders(options?: {
14
+ type?: NotificationProviderType;
15
+ enabled?: boolean;
16
+ }): NotificationProvider[];
17
+ /** Get a single provider by ID. */
18
+ getProviderById(id: string): NotificationProvider | null;
19
+ /** Get a single provider by name. */
20
+ getProviderByName(name: string): NotificationProvider | null;
21
+ /** Create a new notification provider. */
22
+ createProvider(params: {
23
+ type: NotificationProviderType;
24
+ name: string;
25
+ config: ProviderConfig;
26
+ }): NotificationProvider;
27
+ /** Update a provider's configuration. */
28
+ updateProvider(id: string, updates: {
29
+ name?: string;
30
+ config?: ProviderConfig;
31
+ enabled?: boolean;
32
+ }): boolean;
33
+ /** Delete a provider by ID (cascades to rules). */
34
+ deleteProvider(id: string): boolean;
35
+ /** List all rules, optionally filtered by event or provider. */
36
+ listRules(options?: {
37
+ event?: string;
38
+ providerId?: string;
39
+ enabled?: boolean;
40
+ }): NotificationRule[];
41
+ /** Get a single rule by ID. */
42
+ getRuleById(id: string): NotificationRule | null;
43
+ /** Create a new notification rule. */
44
+ createRule(params: {
45
+ event: NotificationEvent;
46
+ providerId: string;
47
+ priority?: number;
48
+ escalationDelaySeconds?: number | null;
49
+ escalationGroup?: string | null;
50
+ }): NotificationRule;
51
+ /** Delete a rule by ID. */
52
+ deleteRule(id: string): boolean;
53
+ /** Enable or disable a rule. */
54
+ setRuleEnabled(id: string, enabled: boolean): boolean;
55
+ /** Get rules for an event with their providers resolved. */
56
+ getRulesWithProviders(event: string): Array<{
57
+ rule: NotificationRule;
58
+ provider: NotificationProvider;
59
+ }>;
60
+ }
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Notification Storage
3
+ *
4
+ * CRUD operations for notification providers and rules in the workspace database.
5
+ * Follows the WorkHookStorage pattern.
6
+ */
7
+ import { randomUUID } from 'node:crypto';
8
+ // =============================================================================
9
+ // Row Converters
10
+ // =============================================================================
11
+ function providerRowToModel(row) {
12
+ let config = {};
13
+ try {
14
+ config = JSON.parse(row.config);
15
+ }
16
+ catch {
17
+ // Invalid JSON — use empty config
18
+ }
19
+ return {
20
+ id: row.id,
21
+ type: row.type,
22
+ name: row.name,
23
+ config,
24
+ enabled: row.enabled === 1,
25
+ createdAt: row.created_at,
26
+ updatedAt: row.updated_at,
27
+ };
28
+ }
29
+ function ruleRowToModel(row) {
30
+ return {
31
+ id: row.id,
32
+ event: row.event,
33
+ providerId: row.provider_id,
34
+ priority: row.priority,
35
+ escalationDelaySeconds: row.escalation_delay_seconds,
36
+ escalationGroup: row.escalation_group,
37
+ enabled: row.enabled === 1,
38
+ createdAt: row.created_at,
39
+ };
40
+ }
41
+ // =============================================================================
42
+ // NotificationStorage
43
+ // =============================================================================
44
+ export class NotificationStorage {
45
+ db;
46
+ constructor(db) {
47
+ this.db = db;
48
+ }
49
+ // ─── Provider CRUD ──────────────────────────────────────────
50
+ /** List all providers, optionally filtered by type or enabled status. */
51
+ listProviders(options) {
52
+ const params = [];
53
+ let where = ' WHERE 1=1';
54
+ if (options?.type) {
55
+ where += ' AND type = ?';
56
+ params.push(options.type);
57
+ }
58
+ if (options?.enabled !== undefined) {
59
+ where += ' AND enabled = ?';
60
+ params.push(options.enabled ? 1 : 0);
61
+ }
62
+ const sql = `SELECT * FROM notification_providers${where} ORDER BY created_at ASC`;
63
+ const rows = this.db.prepare(sql).all(...params);
64
+ return rows.map(providerRowToModel);
65
+ }
66
+ /** Get a single provider by ID. */
67
+ getProviderById(id) {
68
+ const row = this.db.prepare('SELECT * FROM notification_providers WHERE id = ?').get(id);
69
+ return row ? providerRowToModel(row) : null;
70
+ }
71
+ /** Get a single provider by name. */
72
+ getProviderByName(name) {
73
+ const row = this.db.prepare('SELECT * FROM notification_providers WHERE name = ?').get(name);
74
+ return row ? providerRowToModel(row) : null;
75
+ }
76
+ /** Create a new notification provider. */
77
+ createProvider(params) {
78
+ const id = randomUUID();
79
+ this.db.prepare(`
80
+ INSERT INTO notification_providers (id, type, name, config)
81
+ VALUES (?, ?, ?, ?)
82
+ `).run(id, params.type, params.name, JSON.stringify(params.config));
83
+ return this.getProviderById(id);
84
+ }
85
+ /** Update a provider's configuration. */
86
+ updateProvider(id, updates) {
87
+ const sets = [];
88
+ const params = [];
89
+ if (updates.name !== undefined) {
90
+ sets.push('name = ?');
91
+ params.push(updates.name);
92
+ }
93
+ if (updates.config !== undefined) {
94
+ sets.push('config = ?');
95
+ params.push(JSON.stringify(updates.config));
96
+ }
97
+ if (updates.enabled !== undefined) {
98
+ sets.push('enabled = ?');
99
+ params.push(updates.enabled ? 1 : 0);
100
+ }
101
+ if (sets.length === 0)
102
+ return false;
103
+ sets.push('updated_at = CURRENT_TIMESTAMP');
104
+ params.push(id);
105
+ const result = this.db.prepare(`UPDATE notification_providers SET ${sets.join(', ')} WHERE id = ?`).run(...params);
106
+ return result.changes > 0;
107
+ }
108
+ /** Delete a provider by ID (cascades to rules). */
109
+ deleteProvider(id) {
110
+ const result = this.db.prepare('DELETE FROM notification_providers WHERE id = ?').run(id);
111
+ return result.changes > 0;
112
+ }
113
+ // ─── Rule CRUD ──────────────────────────────────────────────
114
+ /** List all rules, optionally filtered by event or provider. */
115
+ listRules(options) {
116
+ const params = [];
117
+ let where = ' WHERE 1=1';
118
+ if (options?.event) {
119
+ where += ' AND event = ?';
120
+ params.push(options.event);
121
+ }
122
+ if (options?.providerId) {
123
+ where += ' AND provider_id = ?';
124
+ params.push(options.providerId);
125
+ }
126
+ if (options?.enabled !== undefined) {
127
+ where += ' AND enabled = ?';
128
+ params.push(options.enabled ? 1 : 0);
129
+ }
130
+ const sql = `SELECT * FROM notification_rules${where} ORDER BY priority ASC, created_at ASC`;
131
+ const rows = this.db.prepare(sql).all(...params);
132
+ return rows.map(ruleRowToModel);
133
+ }
134
+ /** Get a single rule by ID. */
135
+ getRuleById(id) {
136
+ const row = this.db.prepare('SELECT * FROM notification_rules WHERE id = ?').get(id);
137
+ return row ? ruleRowToModel(row) : null;
138
+ }
139
+ /** Create a new notification rule. */
140
+ createRule(params) {
141
+ const id = randomUUID();
142
+ this.db.prepare(`
143
+ INSERT INTO notification_rules (id, event, provider_id, priority, escalation_delay_seconds, escalation_group)
144
+ VALUES (?, ?, ?, ?, ?, ?)
145
+ `).run(id, params.event, params.providerId, params.priority ?? 0, params.escalationDelaySeconds ?? null, params.escalationGroup ?? null);
146
+ return this.getRuleById(id);
147
+ }
148
+ /** Delete a rule by ID. */
149
+ deleteRule(id) {
150
+ const result = this.db.prepare('DELETE FROM notification_rules WHERE id = ?').run(id);
151
+ return result.changes > 0;
152
+ }
153
+ /** Enable or disable a rule. */
154
+ setRuleEnabled(id, enabled) {
155
+ const result = this.db.prepare('UPDATE notification_rules SET enabled = ? WHERE id = ?').run(enabled ? 1 : 0, id);
156
+ return result.changes > 0;
157
+ }
158
+ /** Get rules for an event with their providers resolved. */
159
+ getRulesWithProviders(event) {
160
+ const sql = `
161
+ SELECT r.*, p.id as p_id, p.type as p_type, p.name as p_name, p.config as p_config, p.enabled as p_enabled, p.created_at as p_created_at, p.updated_at as p_updated_at
162
+ FROM notification_rules r
163
+ JOIN notification_providers p ON r.provider_id = p.id
164
+ WHERE r.event = ? AND r.enabled = 1 AND p.enabled = 1
165
+ ORDER BY r.priority ASC, r.created_at ASC
166
+ `;
167
+ const rows = this.db.prepare(sql).all(event);
168
+ return rows.map(row => ({
169
+ rule: ruleRowToModel(row),
170
+ provider: providerRowToModel({
171
+ id: row.p_id,
172
+ type: row.p_type,
173
+ name: row.p_name,
174
+ config: row.p_config,
175
+ enabled: row.p_enabled,
176
+ created_at: row.p_created_at,
177
+ updated_at: row.p_updated_at,
178
+ }),
179
+ }));
180
+ }
181
+ }
182
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/lib/notifications/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Notification Layer Types
3
+ *
4
+ * Defines the shape of notification providers, rules, and dispatch results.
5
+ * Providers are configured channels (Slack, Email, SMS, Terminal, Browser Push).
6
+ * Rules map events to providers, with optional escalation chains.
7
+ */
8
+ import type { HookableEvent } from '../work-lifecycle/hooks/types.js';
9
+ import type { OrchestrateEvent } from '../orchestrate/types.js';
10
+ /** Supported notification channel types. */
11
+ export type NotificationProviderType = 'slack' | 'email' | 'sms' | 'terminal' | 'browser_push';
12
+ /** All valid provider types. */
13
+ export declare const NOTIFICATION_PROVIDER_TYPES: NotificationProviderType[];
14
+ /** Slack provider configuration. */
15
+ export interface SlackProviderConfig {
16
+ webhook_url: string;
17
+ channel?: string;
18
+ username?: string;
19
+ }
20
+ /** Email provider configuration (SendGrid or SES). */
21
+ export interface EmailProviderConfig {
22
+ provider: 'sendgrid' | 'ses';
23
+ api_key: string;
24
+ from: string;
25
+ to: string[];
26
+ }
27
+ /** SMS provider configuration (Twilio). */
28
+ export interface SmsProviderConfig {
29
+ account_sid: string;
30
+ auth_token: string;
31
+ from: string;
32
+ to: string[];
33
+ }
34
+ /** Terminal provider configuration (no external config needed). */
35
+ export interface TerminalProviderConfig {
36
+ prefix?: string;
37
+ }
38
+ /** Browser push provider configuration (placeholder for prlt web). */
39
+ export interface BrowserPushProviderConfig {
40
+ endpoint?: string;
41
+ }
42
+ /** Union of all provider config shapes. */
43
+ export type ProviderConfig = SlackProviderConfig | EmailProviderConfig | SmsProviderConfig | TerminalProviderConfig | BrowserPushProviderConfig;
44
+ /** Persisted notification provider configuration. */
45
+ export interface NotificationProvider {
46
+ id: string;
47
+ type: NotificationProviderType;
48
+ name: string;
49
+ config: ProviderConfig;
50
+ enabled: boolean;
51
+ createdAt: string;
52
+ updatedAt: string;
53
+ }
54
+ /** Database row shape for notification_providers (snake_case). */
55
+ export interface NotificationProviderRow {
56
+ id: string;
57
+ type: string;
58
+ name: string;
59
+ config: string;
60
+ enabled: number;
61
+ created_at: string;
62
+ updated_at: string;
63
+ }
64
+ /** Notification event — same set as hookable + orchestrate events. */
65
+ export type NotificationEvent = HookableEvent | OrchestrateEvent;
66
+ /** Persisted notification rule — maps an event to a provider. */
67
+ export interface NotificationRule {
68
+ id: string;
69
+ event: NotificationEvent;
70
+ providerId: string;
71
+ priority: number;
72
+ /** Delay in seconds before sending (for escalation chains). null = immediate. */
73
+ escalationDelaySeconds: number | null;
74
+ /** Group ID for escalation chains. Rules in the same group escalate sequentially. */
75
+ escalationGroup: string | null;
76
+ enabled: boolean;
77
+ createdAt: string;
78
+ }
79
+ /** Database row shape for notification_rules (snake_case). */
80
+ export interface NotificationRuleRow {
81
+ id: string;
82
+ event: string;
83
+ provider_id: string;
84
+ priority: number;
85
+ escalation_delay_seconds: number | null;
86
+ escalation_group: string | null;
87
+ enabled: number;
88
+ created_at: string;
89
+ }
90
+ /** Result of sending a single notification. */
91
+ export interface NotificationResult {
92
+ providerId: string;
93
+ providerName: string;
94
+ providerType: NotificationProviderType;
95
+ success: boolean;
96
+ error?: string;
97
+ durationMs: number;
98
+ }
99
+ /** Context passed to notification handlers. */
100
+ export interface NotificationContext {
101
+ event: string;
102
+ ticket?: string;
103
+ pr?: number;
104
+ branch?: string;
105
+ agent?: string;
106
+ container?: string;
107
+ message?: string;
108
+ [key: string]: unknown;
109
+ }
110
+ /** A resolved escalation step with timing. */
111
+ export interface EscalationStep {
112
+ rule: NotificationRule;
113
+ provider: NotificationProvider;
114
+ delaySeconds: number;
115
+ }
116
+ /** An active escalation chain being tracked. */
117
+ export interface ActiveEscalation {
118
+ group: string;
119
+ event: string;
120
+ context: NotificationContext;
121
+ steps: EscalationStep[];
122
+ currentStep: number;
123
+ startedAt: number;
124
+ timerId?: ReturnType<typeof setTimeout>;
125
+ acknowledged: boolean;
126
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Notification Layer Types
3
+ *
4
+ * Defines the shape of notification providers, rules, and dispatch results.
5
+ * Providers are configured channels (Slack, Email, SMS, Terminal, Browser Push).
6
+ * Rules map events to providers, with optional escalation chains.
7
+ */
8
+ /** All valid provider types. */
9
+ export const NOTIFICATION_PROVIDER_TYPES = [
10
+ 'slack',
11
+ 'email',
12
+ 'sms',
13
+ 'terminal',
14
+ 'browser_push',
15
+ ];
16
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/notifications/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,gCAAgC;AAChC,MAAM,CAAC,MAAM,2BAA2B,GAA+B;IACrE,OAAO;IACP,OAAO;IACP,KAAK;IACL,UAAU;IACV,cAAc;CACf,CAAA"}