@ginkoai/cli 1.6.2 → 1.7.1
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.
- package/dist/commands/agent/agent-client.d.ts +150 -0
- package/dist/commands/agent/agent-client.d.ts.map +1 -0
- package/dist/commands/agent/agent-client.js +170 -0
- package/dist/commands/agent/agent-client.js.map +1 -0
- package/dist/commands/agent/index.d.ts +22 -0
- package/dist/commands/agent/index.d.ts.map +1 -0
- package/dist/commands/agent/index.js +121 -0
- package/dist/commands/agent/index.js.map +1 -0
- package/dist/commands/agent/list.d.ts +22 -0
- package/dist/commands/agent/list.d.ts.map +1 -0
- package/dist/commands/agent/list.js +119 -0
- package/dist/commands/agent/list.js.map +1 -0
- package/dist/commands/agent/register.d.ts +21 -0
- package/dist/commands/agent/register.d.ts.map +1 -0
- package/dist/commands/agent/register.js +97 -0
- package/dist/commands/agent/register.js.map +1 -0
- package/dist/commands/agent/status.d.ts +19 -0
- package/dist/commands/agent/status.d.ts.map +1 -0
- package/dist/commands/agent/status.js +271 -0
- package/dist/commands/agent/status.js.map +1 -0
- package/dist/commands/agent/work.d.ts +22 -0
- package/dist/commands/agent/work.d.ts.map +1 -0
- package/dist/commands/agent/work.js +459 -0
- package/dist/commands/agent/work.js.map +1 -0
- package/dist/commands/checkpoint/create.d.ts +27 -0
- package/dist/commands/checkpoint/create.d.ts.map +1 -0
- package/dist/commands/checkpoint/create.js +82 -0
- package/dist/commands/checkpoint/create.js.map +1 -0
- package/dist/commands/checkpoint/index.d.ts +23 -0
- package/dist/commands/checkpoint/index.d.ts.map +1 -0
- package/dist/commands/checkpoint/index.js +91 -0
- package/dist/commands/checkpoint/index.js.map +1 -0
- package/dist/commands/checkpoint/list.d.ts +27 -0
- package/dist/commands/checkpoint/list.d.ts.map +1 -0
- package/dist/commands/checkpoint/list.js +115 -0
- package/dist/commands/checkpoint/list.js.map +1 -0
- package/dist/commands/checkpoint/show.d.ts +23 -0
- package/dist/commands/checkpoint/show.d.ts.map +1 -0
- package/dist/commands/checkpoint/show.js +102 -0
- package/dist/commands/checkpoint/show.js.map +1 -0
- package/dist/commands/dlq.d.ts +24 -0
- package/dist/commands/dlq.d.ts.map +1 -0
- package/dist/commands/dlq.js +172 -0
- package/dist/commands/dlq.js.map +1 -0
- package/dist/commands/escalation/create.d.ts +22 -0
- package/dist/commands/escalation/create.d.ts.map +1 -0
- package/dist/commands/escalation/create.js +122 -0
- package/dist/commands/escalation/create.js.map +1 -0
- package/dist/commands/escalation/escalation-client.d.ts +101 -0
- package/dist/commands/escalation/escalation-client.d.ts.map +1 -0
- package/dist/commands/escalation/escalation-client.js +129 -0
- package/dist/commands/escalation/escalation-client.js.map +1 -0
- package/dist/commands/escalation/index.d.ts +22 -0
- package/dist/commands/escalation/index.d.ts.map +1 -0
- package/dist/commands/escalation/index.js +94 -0
- package/dist/commands/escalation/index.js.map +1 -0
- package/dist/commands/escalation/list.d.ts +24 -0
- package/dist/commands/escalation/list.d.ts.map +1 -0
- package/dist/commands/escalation/list.js +170 -0
- package/dist/commands/escalation/list.js.map +1 -0
- package/dist/commands/escalation/resolve.d.ts +20 -0
- package/dist/commands/escalation/resolve.d.ts.map +1 -0
- package/dist/commands/escalation/resolve.js +102 -0
- package/dist/commands/escalation/resolve.js.map +1 -0
- package/dist/commands/graph/api-client.d.ts +21 -1
- package/dist/commands/graph/api-client.d.ts.map +1 -1
- package/dist/commands/graph/api-client.js +23 -0
- package/dist/commands/graph/api-client.js.map +1 -1
- package/dist/commands/handoff.d.ts.map +1 -1
- package/dist/commands/handoff.js +9 -1
- package/dist/commands/handoff.js.map +1 -1
- package/dist/commands/log.d.ts +3 -0
- package/dist/commands/log.d.ts.map +1 -1
- package/dist/commands/log.js +73 -14
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/notifications/history.d.ts +21 -0
- package/dist/commands/notifications/history.d.ts.map +1 -0
- package/dist/commands/notifications/history.js +160 -0
- package/dist/commands/notifications/history.js.map +1 -0
- package/dist/commands/notifications/index.d.ts +22 -0
- package/dist/commands/notifications/index.d.ts.map +1 -0
- package/dist/commands/notifications/index.js +87 -0
- package/dist/commands/notifications/index.js.map +1 -0
- package/dist/commands/notifications/list.d.ts +19 -0
- package/dist/commands/notifications/list.d.ts.map +1 -0
- package/dist/commands/notifications/list.js +132 -0
- package/dist/commands/notifications/list.js.map +1 -0
- package/dist/commands/notifications/test.d.ts +19 -0
- package/dist/commands/notifications/test.d.ts.map +1 -0
- package/dist/commands/notifications/test.js +217 -0
- package/dist/commands/notifications/test.js.map +1 -0
- package/dist/commands/orchestrate.d.ts +25 -0
- package/dist/commands/orchestrate.d.ts.map +1 -0
- package/dist/commands/orchestrate.js +858 -0
- package/dist/commands/orchestrate.js.map +1 -0
- package/dist/commands/sprint/deps.d.ts +29 -0
- package/dist/commands/sprint/deps.d.ts.map +1 -0
- package/dist/commands/sprint/deps.js +269 -0
- package/dist/commands/sprint/deps.js.map +1 -0
- package/dist/commands/sprint/index.d.ts +10 -5
- package/dist/commands/sprint/index.d.ts.map +1 -1
- package/dist/commands/sprint/index.js +26 -5
- package/dist/commands/sprint/index.js.map +1 -1
- package/dist/commands/start/index.d.ts.map +1 -1
- package/dist/commands/start/index.js +6 -0
- package/dist/commands/start/index.js.map +1 -1
- package/dist/commands/start/start-reflection.d.ts.map +1 -1
- package/dist/commands/start/start-reflection.js +8 -0
- package/dist/commands/start/start-reflection.js.map +1 -1
- package/dist/commands/verify.d.ts +17 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +232 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/core/session-log-manager.d.ts +1 -1
- package/dist/core/session-log-manager.d.ts.map +1 -1
- package/dist/index.js +78 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/__tests__/task-timeout.test.d.ts +12 -0
- package/dist/lib/__tests__/task-timeout.test.d.ts.map +1 -0
- package/dist/lib/__tests__/task-timeout.test.js +278 -0
- package/dist/lib/__tests__/task-timeout.test.js.map +1 -0
- package/dist/lib/agent-heartbeat.d.ts +68 -0
- package/dist/lib/agent-heartbeat.d.ts.map +1 -0
- package/dist/lib/agent-heartbeat.js +117 -0
- package/dist/lib/agent-heartbeat.js.map +1 -0
- package/dist/lib/checkpoint.d.ts +85 -0
- package/dist/lib/checkpoint.d.ts.map +1 -0
- package/dist/lib/checkpoint.js +323 -0
- package/dist/lib/checkpoint.js.map +1 -0
- package/dist/lib/context-metrics.d.ts +230 -0
- package/dist/lib/context-metrics.d.ts.map +1 -0
- package/dist/lib/context-metrics.js +372 -0
- package/dist/lib/context-metrics.js.map +1 -0
- package/dist/lib/dead-letter-queue.d.ts +108 -0
- package/dist/lib/dead-letter-queue.d.ts.map +1 -0
- package/dist/lib/dead-letter-queue.js +378 -0
- package/dist/lib/dead-letter-queue.js.map +1 -0
- package/dist/lib/event-logger.d.ts +9 -1
- package/dist/lib/event-logger.d.ts.map +1 -1
- package/dist/lib/event-logger.js +45 -3
- package/dist/lib/event-logger.js.map +1 -1
- package/dist/lib/event-queue.d.ts.map +1 -1
- package/dist/lib/event-queue.js +13 -2
- package/dist/lib/event-queue.js.map +1 -1
- package/dist/lib/examples/timeout-demo.d.ts +13 -0
- package/dist/lib/examples/timeout-demo.d.ts.map +1 -0
- package/dist/lib/examples/timeout-demo.js +102 -0
- package/dist/lib/examples/timeout-demo.js.map +1 -0
- package/dist/lib/examples/timeout-integration-example.d.ts +17 -0
- package/dist/lib/examples/timeout-integration-example.d.ts.map +1 -0
- package/dist/lib/examples/timeout-integration-example.js +223 -0
- package/dist/lib/examples/timeout-integration-example.js.map +1 -0
- package/dist/lib/notification-hooks.d.ts +103 -0
- package/dist/lib/notification-hooks.d.ts.map +1 -0
- package/dist/lib/notification-hooks.js +223 -0
- package/dist/lib/notification-hooks.js.map +1 -0
- package/dist/lib/notifications/discord.d.ts +20 -0
- package/dist/lib/notifications/discord.d.ts.map +1 -0
- package/dist/lib/notifications/discord.js +140 -0
- package/dist/lib/notifications/discord.js.map +1 -0
- package/dist/lib/notifications/index.d.ts +66 -0
- package/dist/lib/notifications/index.d.ts.map +1 -0
- package/dist/lib/notifications/index.js +120 -0
- package/dist/lib/notifications/index.js.map +1 -0
- package/dist/lib/notifications/slack.d.ts +20 -0
- package/dist/lib/notifications/slack.d.ts.map +1 -0
- package/dist/lib/notifications/slack.js +186 -0
- package/dist/lib/notifications/slack.js.map +1 -0
- package/dist/lib/notifications/teams.d.ts +20 -0
- package/dist/lib/notifications/teams.d.ts.map +1 -0
- package/dist/lib/notifications/teams.js +146 -0
- package/dist/lib/notifications/teams.js.map +1 -0
- package/dist/lib/notifications/webhook.d.ts +23 -0
- package/dist/lib/notifications/webhook.d.ts.map +1 -0
- package/dist/lib/notifications/webhook.js +65 -0
- package/dist/lib/notifications/webhook.js.map +1 -0
- package/dist/lib/orchestrator-state.d.ts +194 -0
- package/dist/lib/orchestrator-state.d.ts.map +1 -0
- package/dist/lib/orchestrator-state.js +332 -0
- package/dist/lib/orchestrator-state.js.map +1 -0
- package/dist/lib/realtime-cursor.d.ts +107 -0
- package/dist/lib/realtime-cursor.d.ts.map +1 -0
- package/dist/lib/realtime-cursor.js +260 -0
- package/dist/lib/realtime-cursor.js.map +1 -0
- package/dist/lib/rollback.d.ts +86 -0
- package/dist/lib/rollback.d.ts.map +1 -0
- package/dist/lib/rollback.js +405 -0
- package/dist/lib/rollback.js.map +1 -0
- package/dist/lib/sprint-loader.d.ts +39 -2
- package/dist/lib/sprint-loader.d.ts.map +1 -1
- package/dist/lib/sprint-loader.js +269 -5
- package/dist/lib/sprint-loader.js.map +1 -1
- package/dist/lib/stale-agent-detector.d.ts +102 -0
- package/dist/lib/stale-agent-detector.d.ts.map +1 -0
- package/dist/lib/stale-agent-detector.js +156 -0
- package/dist/lib/stale-agent-detector.js.map +1 -0
- package/dist/lib/task-dependencies.d.ts +143 -0
- package/dist/lib/task-dependencies.d.ts.map +1 -0
- package/dist/lib/task-dependencies.js +357 -0
- package/dist/lib/task-dependencies.js.map +1 -0
- package/dist/lib/task-timeout.d.ts +153 -0
- package/dist/lib/task-timeout.d.ts.map +1 -0
- package/dist/lib/task-timeout.js +505 -0
- package/dist/lib/task-timeout.js.map +1 -0
- package/dist/lib/verification/build-check.d.ts +55 -0
- package/dist/lib/verification/build-check.d.ts.map +1 -0
- package/dist/lib/verification/build-check.js +111 -0
- package/dist/lib/verification/build-check.js.map +1 -0
- package/dist/lib/verification/index.d.ts +19 -0
- package/dist/lib/verification/index.d.ts.map +1 -0
- package/dist/lib/verification/index.js +17 -0
- package/dist/lib/verification/index.js.map +1 -0
- package/dist/lib/verification/lint-check.d.ts +34 -0
- package/dist/lib/verification/lint-check.d.ts.map +1 -0
- package/dist/lib/verification/lint-check.js +215 -0
- package/dist/lib/verification/lint-check.js.map +1 -0
- package/dist/lib/verification/test-runner.d.ts +50 -0
- package/dist/lib/verification/test-runner.d.ts.map +1 -0
- package/dist/lib/verification/test-runner.js +225 -0
- package/dist/lib/verification/test-runner.js.map +1 -0
- package/dist/utils/command-helpers.d.ts.map +1 -1
- package/dist/utils/command-helpers.js +7 -0
- package/dist/utils/command-helpers.js.map +1 -1
- 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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"}
|