@ginkoai/cli 1.6.2 → 1.7.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 (224) hide show
  1. package/dist/commands/agent/agent-client.d.ts +150 -0
  2. package/dist/commands/agent/agent-client.d.ts.map +1 -0
  3. package/dist/commands/agent/agent-client.js +170 -0
  4. package/dist/commands/agent/agent-client.js.map +1 -0
  5. package/dist/commands/agent/index.d.ts +22 -0
  6. package/dist/commands/agent/index.d.ts.map +1 -0
  7. package/dist/commands/agent/index.js +121 -0
  8. package/dist/commands/agent/index.js.map +1 -0
  9. package/dist/commands/agent/list.d.ts +22 -0
  10. package/dist/commands/agent/list.d.ts.map +1 -0
  11. package/dist/commands/agent/list.js +119 -0
  12. package/dist/commands/agent/list.js.map +1 -0
  13. package/dist/commands/agent/register.d.ts +21 -0
  14. package/dist/commands/agent/register.d.ts.map +1 -0
  15. package/dist/commands/agent/register.js +97 -0
  16. package/dist/commands/agent/register.js.map +1 -0
  17. package/dist/commands/agent/status.d.ts +19 -0
  18. package/dist/commands/agent/status.d.ts.map +1 -0
  19. package/dist/commands/agent/status.js +271 -0
  20. package/dist/commands/agent/status.js.map +1 -0
  21. package/dist/commands/agent/work.d.ts +22 -0
  22. package/dist/commands/agent/work.d.ts.map +1 -0
  23. package/dist/commands/agent/work.js +459 -0
  24. package/dist/commands/agent/work.js.map +1 -0
  25. package/dist/commands/checkpoint/create.d.ts +27 -0
  26. package/dist/commands/checkpoint/create.d.ts.map +1 -0
  27. package/dist/commands/checkpoint/create.js +82 -0
  28. package/dist/commands/checkpoint/create.js.map +1 -0
  29. package/dist/commands/checkpoint/index.d.ts +23 -0
  30. package/dist/commands/checkpoint/index.d.ts.map +1 -0
  31. package/dist/commands/checkpoint/index.js +91 -0
  32. package/dist/commands/checkpoint/index.js.map +1 -0
  33. package/dist/commands/checkpoint/list.d.ts +27 -0
  34. package/dist/commands/checkpoint/list.d.ts.map +1 -0
  35. package/dist/commands/checkpoint/list.js +115 -0
  36. package/dist/commands/checkpoint/list.js.map +1 -0
  37. package/dist/commands/checkpoint/show.d.ts +23 -0
  38. package/dist/commands/checkpoint/show.d.ts.map +1 -0
  39. package/dist/commands/checkpoint/show.js +102 -0
  40. package/dist/commands/checkpoint/show.js.map +1 -0
  41. package/dist/commands/dlq.d.ts +24 -0
  42. package/dist/commands/dlq.d.ts.map +1 -0
  43. package/dist/commands/dlq.js +172 -0
  44. package/dist/commands/dlq.js.map +1 -0
  45. package/dist/commands/escalation/create.d.ts +22 -0
  46. package/dist/commands/escalation/create.d.ts.map +1 -0
  47. package/dist/commands/escalation/create.js +122 -0
  48. package/dist/commands/escalation/create.js.map +1 -0
  49. package/dist/commands/escalation/escalation-client.d.ts +101 -0
  50. package/dist/commands/escalation/escalation-client.d.ts.map +1 -0
  51. package/dist/commands/escalation/escalation-client.js +129 -0
  52. package/dist/commands/escalation/escalation-client.js.map +1 -0
  53. package/dist/commands/escalation/index.d.ts +22 -0
  54. package/dist/commands/escalation/index.d.ts.map +1 -0
  55. package/dist/commands/escalation/index.js +94 -0
  56. package/dist/commands/escalation/index.js.map +1 -0
  57. package/dist/commands/escalation/list.d.ts +24 -0
  58. package/dist/commands/escalation/list.d.ts.map +1 -0
  59. package/dist/commands/escalation/list.js +170 -0
  60. package/dist/commands/escalation/list.js.map +1 -0
  61. package/dist/commands/escalation/resolve.d.ts +20 -0
  62. package/dist/commands/escalation/resolve.d.ts.map +1 -0
  63. package/dist/commands/escalation/resolve.js +102 -0
  64. package/dist/commands/escalation/resolve.js.map +1 -0
  65. package/dist/commands/graph/api-client.d.ts +21 -1
  66. package/dist/commands/graph/api-client.d.ts.map +1 -1
  67. package/dist/commands/graph/api-client.js +23 -0
  68. package/dist/commands/graph/api-client.js.map +1 -1
  69. package/dist/commands/handoff.d.ts.map +1 -1
  70. package/dist/commands/handoff.js +9 -1
  71. package/dist/commands/handoff.js.map +1 -1
  72. package/dist/commands/log.d.ts +3 -0
  73. package/dist/commands/log.d.ts.map +1 -1
  74. package/dist/commands/log.js +73 -14
  75. package/dist/commands/log.js.map +1 -1
  76. package/dist/commands/notifications/history.d.ts +21 -0
  77. package/dist/commands/notifications/history.d.ts.map +1 -0
  78. package/dist/commands/notifications/history.js +160 -0
  79. package/dist/commands/notifications/history.js.map +1 -0
  80. package/dist/commands/notifications/index.d.ts +22 -0
  81. package/dist/commands/notifications/index.d.ts.map +1 -0
  82. package/dist/commands/notifications/index.js +87 -0
  83. package/dist/commands/notifications/index.js.map +1 -0
  84. package/dist/commands/notifications/list.d.ts +19 -0
  85. package/dist/commands/notifications/list.d.ts.map +1 -0
  86. package/dist/commands/notifications/list.js +132 -0
  87. package/dist/commands/notifications/list.js.map +1 -0
  88. package/dist/commands/notifications/test.d.ts +19 -0
  89. package/dist/commands/notifications/test.d.ts.map +1 -0
  90. package/dist/commands/notifications/test.js +217 -0
  91. package/dist/commands/notifications/test.js.map +1 -0
  92. package/dist/commands/orchestrate.d.ts +25 -0
  93. package/dist/commands/orchestrate.d.ts.map +1 -0
  94. package/dist/commands/orchestrate.js +858 -0
  95. package/dist/commands/orchestrate.js.map +1 -0
  96. package/dist/commands/sprint/deps.d.ts +29 -0
  97. package/dist/commands/sprint/deps.d.ts.map +1 -0
  98. package/dist/commands/sprint/deps.js +269 -0
  99. package/dist/commands/sprint/deps.js.map +1 -0
  100. package/dist/commands/sprint/index.d.ts +10 -5
  101. package/dist/commands/sprint/index.d.ts.map +1 -1
  102. package/dist/commands/sprint/index.js +26 -5
  103. package/dist/commands/sprint/index.js.map +1 -1
  104. package/dist/commands/start/index.d.ts.map +1 -1
  105. package/dist/commands/start/index.js +6 -0
  106. package/dist/commands/start/index.js.map +1 -1
  107. package/dist/commands/start/start-reflection.d.ts.map +1 -1
  108. package/dist/commands/start/start-reflection.js +8 -0
  109. package/dist/commands/start/start-reflection.js.map +1 -1
  110. package/dist/commands/verify.d.ts +17 -0
  111. package/dist/commands/verify.d.ts.map +1 -0
  112. package/dist/commands/verify.js +232 -0
  113. package/dist/commands/verify.js.map +1 -0
  114. package/dist/core/session-log-manager.d.ts +1 -1
  115. package/dist/core/session-log-manager.d.ts.map +1 -1
  116. package/dist/index.js +78 -1
  117. package/dist/index.js.map +1 -1
  118. package/dist/lib/__tests__/task-timeout.test.d.ts +12 -0
  119. package/dist/lib/__tests__/task-timeout.test.d.ts.map +1 -0
  120. package/dist/lib/__tests__/task-timeout.test.js +278 -0
  121. package/dist/lib/__tests__/task-timeout.test.js.map +1 -0
  122. package/dist/lib/agent-heartbeat.d.ts +68 -0
  123. package/dist/lib/agent-heartbeat.d.ts.map +1 -0
  124. package/dist/lib/agent-heartbeat.js +117 -0
  125. package/dist/lib/agent-heartbeat.js.map +1 -0
  126. package/dist/lib/checkpoint.d.ts +85 -0
  127. package/dist/lib/checkpoint.d.ts.map +1 -0
  128. package/dist/lib/checkpoint.js +323 -0
  129. package/dist/lib/checkpoint.js.map +1 -0
  130. package/dist/lib/context-metrics.d.ts +230 -0
  131. package/dist/lib/context-metrics.d.ts.map +1 -0
  132. package/dist/lib/context-metrics.js +372 -0
  133. package/dist/lib/context-metrics.js.map +1 -0
  134. package/dist/lib/dead-letter-queue.d.ts +108 -0
  135. package/dist/lib/dead-letter-queue.d.ts.map +1 -0
  136. package/dist/lib/dead-letter-queue.js +378 -0
  137. package/dist/lib/dead-letter-queue.js.map +1 -0
  138. package/dist/lib/event-logger.d.ts +9 -1
  139. package/dist/lib/event-logger.d.ts.map +1 -1
  140. package/dist/lib/event-logger.js +45 -3
  141. package/dist/lib/event-logger.js.map +1 -1
  142. package/dist/lib/event-queue.d.ts.map +1 -1
  143. package/dist/lib/event-queue.js +13 -2
  144. package/dist/lib/event-queue.js.map +1 -1
  145. package/dist/lib/examples/timeout-demo.d.ts +13 -0
  146. package/dist/lib/examples/timeout-demo.d.ts.map +1 -0
  147. package/dist/lib/examples/timeout-demo.js +102 -0
  148. package/dist/lib/examples/timeout-demo.js.map +1 -0
  149. package/dist/lib/examples/timeout-integration-example.d.ts +17 -0
  150. package/dist/lib/examples/timeout-integration-example.d.ts.map +1 -0
  151. package/dist/lib/examples/timeout-integration-example.js +223 -0
  152. package/dist/lib/examples/timeout-integration-example.js.map +1 -0
  153. package/dist/lib/notification-hooks.d.ts +103 -0
  154. package/dist/lib/notification-hooks.d.ts.map +1 -0
  155. package/dist/lib/notification-hooks.js +223 -0
  156. package/dist/lib/notification-hooks.js.map +1 -0
  157. package/dist/lib/notifications/discord.d.ts +20 -0
  158. package/dist/lib/notifications/discord.d.ts.map +1 -0
  159. package/dist/lib/notifications/discord.js +140 -0
  160. package/dist/lib/notifications/discord.js.map +1 -0
  161. package/dist/lib/notifications/index.d.ts +66 -0
  162. package/dist/lib/notifications/index.d.ts.map +1 -0
  163. package/dist/lib/notifications/index.js +120 -0
  164. package/dist/lib/notifications/index.js.map +1 -0
  165. package/dist/lib/notifications/slack.d.ts +20 -0
  166. package/dist/lib/notifications/slack.d.ts.map +1 -0
  167. package/dist/lib/notifications/slack.js +186 -0
  168. package/dist/lib/notifications/slack.js.map +1 -0
  169. package/dist/lib/notifications/teams.d.ts +20 -0
  170. package/dist/lib/notifications/teams.d.ts.map +1 -0
  171. package/dist/lib/notifications/teams.js +146 -0
  172. package/dist/lib/notifications/teams.js.map +1 -0
  173. package/dist/lib/notifications/webhook.d.ts +23 -0
  174. package/dist/lib/notifications/webhook.d.ts.map +1 -0
  175. package/dist/lib/notifications/webhook.js +65 -0
  176. package/dist/lib/notifications/webhook.js.map +1 -0
  177. package/dist/lib/orchestrator-state.d.ts +194 -0
  178. package/dist/lib/orchestrator-state.d.ts.map +1 -0
  179. package/dist/lib/orchestrator-state.js +332 -0
  180. package/dist/lib/orchestrator-state.js.map +1 -0
  181. package/dist/lib/realtime-cursor.d.ts +107 -0
  182. package/dist/lib/realtime-cursor.d.ts.map +1 -0
  183. package/dist/lib/realtime-cursor.js +260 -0
  184. package/dist/lib/realtime-cursor.js.map +1 -0
  185. package/dist/lib/rollback.d.ts +86 -0
  186. package/dist/lib/rollback.d.ts.map +1 -0
  187. package/dist/lib/rollback.js +405 -0
  188. package/dist/lib/rollback.js.map +1 -0
  189. package/dist/lib/sprint-loader.d.ts +39 -2
  190. package/dist/lib/sprint-loader.d.ts.map +1 -1
  191. package/dist/lib/sprint-loader.js +255 -4
  192. package/dist/lib/sprint-loader.js.map +1 -1
  193. package/dist/lib/stale-agent-detector.d.ts +102 -0
  194. package/dist/lib/stale-agent-detector.d.ts.map +1 -0
  195. package/dist/lib/stale-agent-detector.js +156 -0
  196. package/dist/lib/stale-agent-detector.js.map +1 -0
  197. package/dist/lib/task-dependencies.d.ts +143 -0
  198. package/dist/lib/task-dependencies.d.ts.map +1 -0
  199. package/dist/lib/task-dependencies.js +357 -0
  200. package/dist/lib/task-dependencies.js.map +1 -0
  201. package/dist/lib/task-timeout.d.ts +153 -0
  202. package/dist/lib/task-timeout.d.ts.map +1 -0
  203. package/dist/lib/task-timeout.js +505 -0
  204. package/dist/lib/task-timeout.js.map +1 -0
  205. package/dist/lib/verification/build-check.d.ts +55 -0
  206. package/dist/lib/verification/build-check.d.ts.map +1 -0
  207. package/dist/lib/verification/build-check.js +111 -0
  208. package/dist/lib/verification/build-check.js.map +1 -0
  209. package/dist/lib/verification/index.d.ts +19 -0
  210. package/dist/lib/verification/index.d.ts.map +1 -0
  211. package/dist/lib/verification/index.js +17 -0
  212. package/dist/lib/verification/index.js.map +1 -0
  213. package/dist/lib/verification/lint-check.d.ts +34 -0
  214. package/dist/lib/verification/lint-check.d.ts.map +1 -0
  215. package/dist/lib/verification/lint-check.js +215 -0
  216. package/dist/lib/verification/lint-check.js.map +1 -0
  217. package/dist/lib/verification/test-runner.d.ts +50 -0
  218. package/dist/lib/verification/test-runner.d.ts.map +1 -0
  219. package/dist/lib/verification/test-runner.js +225 -0
  220. package/dist/lib/verification/test-runner.js.map +1 -0
  221. package/dist/utils/command-helpers.d.ts.map +1 -1
  222. package/dist/utils/command-helpers.js +7 -0
  223. package/dist/utils/command-helpers.js.map +1 -1
  224. package/package.json +1 -1
@@ -0,0 +1,186 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2025-12-07
5
+ * @tags: [notifications, slack, webhook, epic-004]
6
+ * @related: [index.ts, notification-hooks.ts, discord.ts, teams.ts, webhook.ts]
7
+ * @priority: high
8
+ * @complexity: low
9
+ * @dependencies: []
10
+ */
11
+ import { retryWithBackoff, formatSeverity, truncate } from './index.js';
12
+ /**
13
+ * Send notification to Slack via webhook
14
+ *
15
+ * @param config - Slack configuration (must include webhook_url)
16
+ * @param payload - Notification payload
17
+ * @returns Promise<boolean> - True if notification sent successfully
18
+ */
19
+ export async function sendNotification(config, payload) {
20
+ const slackConfig = config;
21
+ // Validate required config
22
+ if (!slackConfig.webhook_url) {
23
+ console.error('[SlackNotification] Missing webhook_url in config');
24
+ return false;
25
+ }
26
+ try {
27
+ // Build Slack message
28
+ const message = buildSlackMessage(slackConfig, payload);
29
+ // Send with retry logic
30
+ await retryWithBackoff(async () => {
31
+ const response = await fetch(slackConfig.webhook_url, {
32
+ method: 'POST',
33
+ headers: {
34
+ 'Content-Type': 'application/json',
35
+ },
36
+ body: JSON.stringify(message),
37
+ signal: AbortSignal.timeout(5000), // 5 second timeout
38
+ });
39
+ if (!response.ok) {
40
+ throw new Error(`Slack webhook returned ${response.status}: ${response.statusText}`);
41
+ }
42
+ return response;
43
+ });
44
+ return true;
45
+ }
46
+ catch (error) {
47
+ console.error('[SlackNotification] Failed to send notification:', error instanceof Error ? error.message : String(error));
48
+ return false;
49
+ }
50
+ }
51
+ /**
52
+ * Build Slack message with rich formatting
53
+ *
54
+ * @param config - Slack configuration
55
+ * @param payload - Notification payload
56
+ * @returns Slack message object
57
+ */
58
+ function buildSlackMessage(config, payload) {
59
+ const blocks = [];
60
+ // Header block with severity emoji
61
+ const severityEmoji = getSeverityEmoji(payload.severity);
62
+ blocks.push({
63
+ type: 'header',
64
+ text: {
65
+ type: 'plain_text',
66
+ text: `${severityEmoji} ${payload.title}`,
67
+ },
68
+ });
69
+ // Description block
70
+ blocks.push({
71
+ type: 'section',
72
+ text: {
73
+ type: 'mrkdwn',
74
+ text: truncate(payload.description, 3000), // Slack limit: 3000 chars per text block
75
+ },
76
+ });
77
+ // Details block (if metadata available)
78
+ const fields = buildFields(payload);
79
+ if (fields.length > 0) {
80
+ blocks.push({
81
+ type: 'section',
82
+ fields,
83
+ });
84
+ }
85
+ // Context block with timestamp
86
+ blocks.push({
87
+ type: 'context',
88
+ elements: [
89
+ {
90
+ type: 'mrkdwn',
91
+ text: `*Event:* ${payload.event} | *Time:* <!date^${Math.floor(new Date(payload.timestamp).getTime() / 1000)}^{date_short_pretty} at {time}|${payload.timestamp}>`,
92
+ },
93
+ ],
94
+ });
95
+ // Build final message
96
+ const message = {
97
+ blocks,
98
+ };
99
+ // Add optional overrides
100
+ if (config.channel) {
101
+ message.channel = config.channel;
102
+ }
103
+ if (config.username) {
104
+ message.username = config.username;
105
+ }
106
+ if (config.icon_emoji) {
107
+ message.icon_emoji = config.icon_emoji;
108
+ }
109
+ return message;
110
+ }
111
+ /**
112
+ * Build fields for Slack message
113
+ *
114
+ * @param payload - Notification payload
115
+ * @returns Array of Slack fields
116
+ */
117
+ function buildFields(payload) {
118
+ const fields = [];
119
+ if (payload.severity) {
120
+ fields.push({
121
+ type: 'mrkdwn',
122
+ text: `*Severity:*\n${formatSeverity(payload.severity)}`,
123
+ });
124
+ }
125
+ if (payload.taskId) {
126
+ fields.push({
127
+ type: 'mrkdwn',
128
+ text: `*Task:*\n${payload.taskId}`,
129
+ });
130
+ }
131
+ if (payload.epicId) {
132
+ fields.push({
133
+ type: 'mrkdwn',
134
+ text: `*Epic:*\n${payload.epicId}`,
135
+ });
136
+ }
137
+ if (payload.agentId) {
138
+ fields.push({
139
+ type: 'mrkdwn',
140
+ text: `*Agent:*\n${payload.agentId}`,
141
+ });
142
+ }
143
+ // Add custom metadata fields
144
+ if (payload.metadata) {
145
+ for (const [key, value] of Object.entries(payload.metadata)) {
146
+ // Limit to 10 fields total (Slack limit)
147
+ if (fields.length >= 10)
148
+ break;
149
+ fields.push({
150
+ type: 'mrkdwn',
151
+ text: `*${capitalizeFirst(key)}:*\n${String(value)}`,
152
+ });
153
+ }
154
+ }
155
+ return fields;
156
+ }
157
+ /**
158
+ * Get severity emoji
159
+ *
160
+ * @param severity - Severity level
161
+ * @returns Emoji string
162
+ */
163
+ function getSeverityEmoji(severity) {
164
+ switch (severity) {
165
+ case 'critical':
166
+ return '🚨';
167
+ case 'high':
168
+ return '⚠️';
169
+ case 'medium':
170
+ return '💡';
171
+ case 'low':
172
+ return 'ℹ️';
173
+ default:
174
+ return '📢';
175
+ }
176
+ }
177
+ /**
178
+ * Capitalize first letter of string
179
+ *
180
+ * @param str - String to capitalize
181
+ * @returns Capitalized string
182
+ */
183
+ function capitalizeFirst(str) {
184
+ return str.charAt(0).toUpperCase() + str.slice(1);
185
+ }
186
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../src/lib/notifications/slack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2025-12-07
5
+ * @tags: [notifications, teams, webhook, epic-004]
6
+ * @related: [index.ts, notification-hooks.ts, slack.ts, discord.ts, webhook.ts]
7
+ * @priority: high
8
+ * @complexity: medium
9
+ * @dependencies: []
10
+ */
11
+ import { NotificationPayload } from '../notification-hooks.js';
12
+ /**
13
+ * Send notification to Microsoft Teams via webhook
14
+ *
15
+ * @param config - Teams configuration (must include webhook_url)
16
+ * @param payload - Notification payload
17
+ * @returns Promise<boolean> - True if notification sent successfully
18
+ */
19
+ export declare function sendNotification(config: Record<string, string>, payload: NotificationPayload): Promise<boolean>;
20
+ //# sourceMappingURL=teams.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teams.d.ts","sourceRoot":"","sources":["../../../src/lib/notifications/teams.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAU/D;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAoClB"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2025-12-07
5
+ * @tags: [notifications, teams, webhook, epic-004]
6
+ * @related: [index.ts, notification-hooks.ts, slack.ts, discord.ts, webhook.ts]
7
+ * @priority: high
8
+ * @complexity: medium
9
+ * @dependencies: []
10
+ */
11
+ import { retryWithBackoff, formatSeverity, truncate } from './index.js';
12
+ /**
13
+ * Send notification to Microsoft Teams via webhook
14
+ *
15
+ * @param config - Teams configuration (must include webhook_url)
16
+ * @param payload - Notification payload
17
+ * @returns Promise<boolean> - True if notification sent successfully
18
+ */
19
+ export async function sendNotification(config, payload) {
20
+ const teamsConfig = config;
21
+ // Validate required config
22
+ if (!teamsConfig.webhook_url) {
23
+ console.error('[TeamsNotification] Missing webhook_url in config');
24
+ return false;
25
+ }
26
+ try {
27
+ // Build Teams message (Adaptive Card format)
28
+ const message = buildTeamsMessage(payload);
29
+ // Send with retry logic
30
+ await retryWithBackoff(async () => {
31
+ const response = await fetch(teamsConfig.webhook_url, {
32
+ method: 'POST',
33
+ headers: {
34
+ 'Content-Type': 'application/json',
35
+ },
36
+ body: JSON.stringify(message),
37
+ signal: AbortSignal.timeout(5000), // 5 second timeout
38
+ });
39
+ if (!response.ok) {
40
+ throw new Error(`Teams webhook returned ${response.status}: ${response.statusText}`);
41
+ }
42
+ return response;
43
+ });
44
+ return true;
45
+ }
46
+ catch (error) {
47
+ console.error('[TeamsNotification] Failed to send notification:', error instanceof Error ? error.message : String(error));
48
+ return false;
49
+ }
50
+ }
51
+ /**
52
+ * Build Microsoft Teams message with Adaptive Card
53
+ *
54
+ * @param payload - Notification payload
55
+ * @returns Teams message object
56
+ */
57
+ function buildTeamsMessage(payload) {
58
+ const themeColor = getSeverityColor(payload.severity);
59
+ // Build facts array for metadata
60
+ const facts = [
61
+ {
62
+ title: 'Severity',
63
+ value: formatSeverity(payload.severity)
64
+ },
65
+ {
66
+ title: 'Event',
67
+ value: payload.event
68
+ },
69
+ ];
70
+ if (payload.taskId) {
71
+ facts.push({
72
+ title: 'Task',
73
+ value: payload.taskId
74
+ });
75
+ }
76
+ if (payload.epicId) {
77
+ facts.push({
78
+ title: 'Epic',
79
+ value: payload.epicId
80
+ });
81
+ }
82
+ if (payload.agentId) {
83
+ facts.push({
84
+ title: 'Agent',
85
+ value: payload.agentId
86
+ });
87
+ }
88
+ // Add custom metadata
89
+ if (payload.metadata) {
90
+ for (const [key, value] of Object.entries(payload.metadata)) {
91
+ // Limit to 10 facts total
92
+ if (facts.length >= 10)
93
+ break;
94
+ facts.push({
95
+ title: capitalizeFirst(key),
96
+ value: String(value)
97
+ });
98
+ }
99
+ }
100
+ // Build message card
101
+ const message = {
102
+ '@type': 'MessageCard',
103
+ '@context': 'https://schema.org/extensions',
104
+ summary: truncate(payload.title, 100),
105
+ themeColor,
106
+ sections: [
107
+ {
108
+ activityTitle: payload.title,
109
+ activitySubtitle: new Date(payload.timestamp).toLocaleString(),
110
+ facts,
111
+ text: truncate(payload.description, 5000)
112
+ }
113
+ ]
114
+ };
115
+ return message;
116
+ }
117
+ /**
118
+ * Get theme color for severity level (Teams uses hex colors)
119
+ *
120
+ * @param severity - Severity level
121
+ * @returns Hex color string
122
+ */
123
+ function getSeverityColor(severity) {
124
+ switch (severity) {
125
+ case 'critical':
126
+ return 'FF0000'; // Red
127
+ case 'high':
128
+ return 'FF8C00'; // Orange
129
+ case 'medium':
130
+ return 'FFD700'; // Yellow/Gold
131
+ case 'low':
132
+ return '1E90FF'; // Blue
133
+ default:
134
+ return '808080'; // Gray
135
+ }
136
+ }
137
+ /**
138
+ * Capitalize first letter of string
139
+ *
140
+ * @param str - String to capitalize
141
+ * @returns Capitalized string
142
+ */
143
+ function capitalizeFirst(str) {
144
+ return str.charAt(0).toUpperCase() + str.slice(1);
145
+ }
146
+ //# sourceMappingURL=teams.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teams.js","sourceRoot":"","sources":["../../../src/lib/notifications/teams.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2025-12-07
5
+ * @tags: [notifications, webhook, generic, epic-004]
6
+ * @related: [index.ts, notification-hooks.ts, slack.ts, discord.ts, teams.ts]
7
+ * @priority: high
8
+ * @complexity: low
9
+ * @dependencies: []
10
+ */
11
+ import { NotificationPayload } from '../notification-hooks.js';
12
+ /**
13
+ * Send notification to generic webhook endpoint
14
+ *
15
+ * Sends the raw notification payload as JSON to any webhook URL.
16
+ * Supports custom headers for authentication.
17
+ *
18
+ * @param config - Webhook configuration (must include webhook_url)
19
+ * @param payload - Notification payload
20
+ * @returns Promise<boolean> - True if notification sent successfully
21
+ */
22
+ export declare function sendNotification(config: Record<string, string>, payload: NotificationPayload): Promise<boolean>;
23
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../../src/lib/notifications/webhook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAW/D;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,OAAO,CAAC,CA+ClB"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2025-12-07
5
+ * @tags: [notifications, webhook, generic, epic-004]
6
+ * @related: [index.ts, notification-hooks.ts, slack.ts, discord.ts, teams.ts]
7
+ * @priority: high
8
+ * @complexity: low
9
+ * @dependencies: []
10
+ */
11
+ import { retryWithBackoff } from './index.js';
12
+ /**
13
+ * Send notification to generic webhook endpoint
14
+ *
15
+ * Sends the raw notification payload as JSON to any webhook URL.
16
+ * Supports custom headers for authentication.
17
+ *
18
+ * @param config - Webhook configuration (must include webhook_url)
19
+ * @param payload - Notification payload
20
+ * @returns Promise<boolean> - True if notification sent successfully
21
+ */
22
+ export async function sendNotification(config, payload) {
23
+ const webhookConfig = config;
24
+ // Validate required config
25
+ if (!webhookConfig.webhook_url) {
26
+ console.error('[WebhookNotification] Missing webhook_url in config');
27
+ return false;
28
+ }
29
+ try {
30
+ // Parse custom headers if provided
31
+ let customHeaders = {};
32
+ if (webhookConfig.headers) {
33
+ try {
34
+ customHeaders = JSON.parse(webhookConfig.headers);
35
+ }
36
+ catch (error) {
37
+ console.warn('[WebhookNotification] Failed to parse custom headers, using defaults');
38
+ }
39
+ }
40
+ // Build headers - custom headers can override defaults
41
+ const headers = {
42
+ 'Content-Type': 'application/json',
43
+ ...customHeaders,
44
+ };
45
+ // Send with retry logic
46
+ await retryWithBackoff(async () => {
47
+ const response = await fetch(webhookConfig.webhook_url, {
48
+ method: 'POST',
49
+ headers,
50
+ body: JSON.stringify(payload),
51
+ signal: AbortSignal.timeout(5000), // 5 second timeout
52
+ });
53
+ if (!response.ok) {
54
+ throw new Error(`Webhook returned ${response.status}: ${response.statusText}`);
55
+ }
56
+ return response;
57
+ });
58
+ return true;
59
+ }
60
+ catch (error) {
61
+ console.error('[WebhookNotification] Failed to send notification:', error instanceof Error ? error.message : String(error));
62
+ return false;
63
+ }
64
+ }
65
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../../src/lib/notifications/webhook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAU9C;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAA8B,EAC9B,OAA4B;IAE5B,MAAM,aAAa,GAAG,MAAkC,CAAC;IAEzD,2BAA2B;IAC3B,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,mCAAmC;QACnC,IAAI,aAAa,GAA2B,EAAE,CAAC;QAC/C,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YAC1B,IAAI,CAAC;gBACH,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACpD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;YACvF,CAAC;QACH,CAAC;QAED,uDAAuD;QACvD,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,GAAG,aAAa;SACjB,CAAC;QAEF,wBAAwB;QACxB,MAAM,gBAAgB,CAAC,KAAK,IAAI,EAAE;YAChC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,WAAY,EAAE;gBACvD,MAAM,EAAE,MAAM;gBACd,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAC7B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,mBAAmB;aACvD,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YACjF,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,oDAAoD,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5H,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2025-12-07
5
+ * @tags: [orchestrator, state, checkpoint, lifecycle, epic-004, sprint-4, task-10]
6
+ * @related: [../commands/orchestrate.ts, context-metrics.ts, graph/api-client.ts]
7
+ * @priority: high
8
+ * @complexity: medium
9
+ * @dependencies: [fs-extra, path]
10
+ */
11
+ import { ContextMetrics, ContextMonitor } from './context-metrics.js';
12
+ export declare const EXIT_CODE_SUCCESS = 0;
13
+ export declare const EXIT_CODE_ERROR = 1;
14
+ export declare const EXIT_CODE_RESPAWN = 75;
15
+ /**
16
+ * Assignment record for tracking task assignments
17
+ */
18
+ export interface AssignmentRecord {
19
+ taskId: string;
20
+ agentId: string;
21
+ assignedAt: string;
22
+ status: 'assigned' | 'completed' | 'released' | 'failed';
23
+ completedAt?: string;
24
+ failureReason?: string;
25
+ }
26
+ /**
27
+ * Serializable orchestrator state for persistence
28
+ */
29
+ export interface OrchestratorCheckpoint {
30
+ orchestratorId: string;
31
+ orchestratorName: string;
32
+ graphId: string;
33
+ sprintId: string;
34
+ startedAt: string;
35
+ savedAt: string;
36
+ lastProgressAt: string;
37
+ cyclesWithoutProgress: number;
38
+ completedTasks: string[];
39
+ inProgressTasks: Record<string, string>;
40
+ blockedTasks: string[];
41
+ assignmentHistory: AssignmentRecord[];
42
+ contextMetrics: {
43
+ estimatedTokens: number;
44
+ contextLimit: number;
45
+ pressure: number;
46
+ messageCount: number;
47
+ toolCallCount: number;
48
+ eventsSinceStart: number;
49
+ model: string;
50
+ };
51
+ exitReason?: ExitReason;
52
+ exitCode?: number;
53
+ persistedAt?: string;
54
+ recoveredFrom?: string;
55
+ version: number;
56
+ }
57
+ /**
58
+ * Exit reasons for orchestrator
59
+ */
60
+ export type ExitReason = 'all_complete' | 'context_pressure' | 'max_runtime' | 'no_progress' | 'user_interrupt' | 'error' | 'manual_stop';
61
+ /**
62
+ * Options for loading checkpoint
63
+ */
64
+ export interface LoadCheckpointOptions {
65
+ projectRoot: string;
66
+ fromGraph?: boolean;
67
+ graphId?: string;
68
+ }
69
+ /**
70
+ * Options for saving checkpoint
71
+ */
72
+ export interface SaveCheckpointOptions {
73
+ projectRoot: string;
74
+ toGraph?: boolean;
75
+ graphId?: string;
76
+ exitReason?: ExitReason;
77
+ exitCode?: number;
78
+ }
79
+ export declare class OrchestratorStateManager {
80
+ private projectRoot;
81
+ private graphId?;
82
+ constructor(projectRoot: string, graphId?: string);
83
+ /**
84
+ * Get the local checkpoint file path
85
+ */
86
+ getCheckpointPath(): string;
87
+ /**
88
+ * Check if a checkpoint exists
89
+ */
90
+ hasCheckpoint(): Promise<boolean>;
91
+ /**
92
+ * Load checkpoint from filesystem
93
+ */
94
+ loadCheckpoint(): Promise<OrchestratorCheckpoint | null>;
95
+ /**
96
+ * Save checkpoint to filesystem
97
+ */
98
+ saveCheckpoint(checkpoint: OrchestratorCheckpoint, options?: {
99
+ exitReason?: ExitReason;
100
+ exitCode?: number;
101
+ }): Promise<void>;
102
+ /**
103
+ * Delete checkpoint (after successful completion or explicit reset)
104
+ */
105
+ deleteCheckpoint(): Promise<void>;
106
+ /**
107
+ * Create a fresh checkpoint from current state
108
+ * Accepts either a ContextMonitor (from runtime) or ContextMetrics (from tests)
109
+ */
110
+ createCheckpoint(state: {
111
+ orchestratorId: string;
112
+ orchestratorName: string;
113
+ graphId: string;
114
+ sprintId: string;
115
+ startedAt: Date;
116
+ lastProgressAt: Date;
117
+ cyclesWithoutProgress: number;
118
+ completedTasks: Set<string>;
119
+ inProgressTasks: Map<string, string>;
120
+ blockedTasks: Set<string>;
121
+ assignmentHistory: Array<{
122
+ taskId: string;
123
+ agentId: string;
124
+ assignedAt: Date;
125
+ status: 'assigned' | 'completed' | 'released' | 'failed';
126
+ }>;
127
+ contextMonitor?: ContextMonitor;
128
+ contextMetrics?: ContextMetrics;
129
+ }): OrchestratorCheckpoint;
130
+ /**
131
+ * Restore runtime state from checkpoint
132
+ */
133
+ restoreFromCheckpoint(checkpoint: OrchestratorCheckpoint): {
134
+ completedTasks: Set<string>;
135
+ inProgressTasks: Map<string, string>;
136
+ blockedTasks: Set<string>;
137
+ assignmentHistory: Array<{
138
+ taskId: string;
139
+ agentId: string;
140
+ assignedAt: Date;
141
+ status: 'assigned' | 'completed' | 'released' | 'failed';
142
+ }>;
143
+ startedAt: Date;
144
+ lastProgressAt: Date;
145
+ cyclesWithoutProgress: number;
146
+ };
147
+ }
148
+ /**
149
+ * Save orchestrator state to graph
150
+ * This enables cross-machine state recovery and team visibility
151
+ */
152
+ export declare function persistStateToGraph(checkpoint: OrchestratorCheckpoint, graphApiClient: {
153
+ request: <T>(method: string, endpoint: string, body?: unknown) => Promise<T>;
154
+ }): Promise<void>;
155
+ /**
156
+ * Recover orchestrator state from graph
157
+ * Attempts to find the most recent state for the given epic/sprint
158
+ */
159
+ export declare function recoverStateFromGraph(graphId: string, epicId: string, graphApiClient: {
160
+ request: <T>(method: string, endpoint: string, body?: unknown) => Promise<T>;
161
+ }): Promise<OrchestratorCheckpoint | null>;
162
+ /**
163
+ * Reconcile task statuses after recovery
164
+ * Re-scans actual task status and compares with persisted state
165
+ * Handles discrepancies (e.g., task marked complete externally)
166
+ */
167
+ export declare function reconcileTaskStatuses(checkpoint: OrchestratorCheckpoint, actualTasks: Array<{
168
+ id: string;
169
+ status: string;
170
+ }>, graphApiClient: {
171
+ request: <T>(method: string, endpoint: string, body?: unknown) => Promise<T>;
172
+ }): Promise<OrchestratorCheckpoint>;
173
+ /**
174
+ * Determine exit code from reason
175
+ */
176
+ export declare function getExitCode(reason: ExitReason): number;
177
+ /**
178
+ * Check if exit code indicates respawn is needed
179
+ */
180
+ export declare function shouldRespawn(exitCode: number): boolean;
181
+ /**
182
+ * Get human-readable exit message
183
+ */
184
+ export declare function getExitMessage(reason: ExitReason): string;
185
+ /**
186
+ * Get or create state manager instance
187
+ */
188
+ export declare function getStateManager(projectRoot?: string, graphId?: string): OrchestratorStateManager;
189
+ /**
190
+ * Reset state manager (for testing)
191
+ */
192
+ export declare function resetStateManager(): void;
193
+ export default OrchestratorStateManager;
194
+ //# sourceMappingURL=orchestrator-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator-state.d.ts","sourceRoot":"","sources":["../../src/lib/orchestrator-state.ts"],"names":[],"mappings":"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"}