@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.
- 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 +255 -4
- 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,332 @@
|
|
|
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
|
+
/**
|
|
12
|
+
* Orchestrator State Management (EPIC-004 Sprint 4 TASK-10)
|
|
13
|
+
*
|
|
14
|
+
* Handles:
|
|
15
|
+
* - State persistence to local filesystem and graph
|
|
16
|
+
* - State recovery on restart
|
|
17
|
+
* - Checkpoint creation for respawn scenarios
|
|
18
|
+
* - Exit condition tracking
|
|
19
|
+
*
|
|
20
|
+
* Exit Codes:
|
|
21
|
+
* - 0: Success (all tasks complete or graceful shutdown)
|
|
22
|
+
* - 1: Error (unrecoverable failure or no progress)
|
|
23
|
+
* - 75: Respawn needed (context pressure or max runtime)
|
|
24
|
+
*/
|
|
25
|
+
import fs from 'fs/promises';
|
|
26
|
+
import path from 'path';
|
|
27
|
+
// ============================================================
|
|
28
|
+
// Constants
|
|
29
|
+
// ============================================================
|
|
30
|
+
export const EXIT_CODE_SUCCESS = 0;
|
|
31
|
+
export const EXIT_CODE_ERROR = 1;
|
|
32
|
+
export const EXIT_CODE_RESPAWN = 75;
|
|
33
|
+
const CHECKPOINT_FILENAME = 'orchestrator-checkpoint.json';
|
|
34
|
+
const STATE_NODE_LABEL = 'OrchestratorState';
|
|
35
|
+
// ============================================================
|
|
36
|
+
// Checkpoint Manager
|
|
37
|
+
// ============================================================
|
|
38
|
+
export class OrchestratorStateManager {
|
|
39
|
+
projectRoot;
|
|
40
|
+
graphId;
|
|
41
|
+
constructor(projectRoot, graphId) {
|
|
42
|
+
this.projectRoot = projectRoot;
|
|
43
|
+
this.graphId = graphId;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get the local checkpoint file path
|
|
47
|
+
*/
|
|
48
|
+
getCheckpointPath() {
|
|
49
|
+
return path.join(this.projectRoot, '.ginko', CHECKPOINT_FILENAME);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Check if a checkpoint exists
|
|
53
|
+
*/
|
|
54
|
+
async hasCheckpoint() {
|
|
55
|
+
try {
|
|
56
|
+
await fs.access(this.getCheckpointPath());
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Load checkpoint from filesystem
|
|
65
|
+
*/
|
|
66
|
+
async loadCheckpoint() {
|
|
67
|
+
try {
|
|
68
|
+
const checkpointPath = this.getCheckpointPath();
|
|
69
|
+
const content = await fs.readFile(checkpointPath, 'utf-8');
|
|
70
|
+
const checkpoint = JSON.parse(content);
|
|
71
|
+
// Validate version
|
|
72
|
+
if (!checkpoint.version || checkpoint.version < 1) {
|
|
73
|
+
console.warn('Warning: Old checkpoint format, may have missing fields');
|
|
74
|
+
}
|
|
75
|
+
return checkpoint;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (error.code === 'ENOENT') {
|
|
79
|
+
return null; // No checkpoint exists
|
|
80
|
+
}
|
|
81
|
+
throw new Error(`Failed to load checkpoint: ${error.message}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Save checkpoint to filesystem
|
|
86
|
+
*/
|
|
87
|
+
async saveCheckpoint(checkpoint, options) {
|
|
88
|
+
const checkpointPath = this.getCheckpointPath();
|
|
89
|
+
// Update with exit info if provided
|
|
90
|
+
const finalCheckpoint = {
|
|
91
|
+
...checkpoint,
|
|
92
|
+
savedAt: new Date().toISOString(),
|
|
93
|
+
version: 1,
|
|
94
|
+
...(options?.exitReason && { exitReason: options.exitReason }),
|
|
95
|
+
...(options?.exitCode !== undefined && { exitCode: options.exitCode }),
|
|
96
|
+
};
|
|
97
|
+
// Ensure directory exists
|
|
98
|
+
await fs.mkdir(path.dirname(checkpointPath), { recursive: true });
|
|
99
|
+
// Write atomically (write to temp, then rename)
|
|
100
|
+
const tempPath = `${checkpointPath}.tmp`;
|
|
101
|
+
await fs.writeFile(tempPath, JSON.stringify(finalCheckpoint, null, 2), 'utf-8');
|
|
102
|
+
await fs.rename(tempPath, checkpointPath);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Delete checkpoint (after successful completion or explicit reset)
|
|
106
|
+
*/
|
|
107
|
+
async deleteCheckpoint() {
|
|
108
|
+
try {
|
|
109
|
+
await fs.unlink(this.getCheckpointPath());
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
if (error.code !== 'ENOENT') {
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
// Ignore if file doesn't exist
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Create a fresh checkpoint from current state
|
|
120
|
+
* Accepts either a ContextMonitor (from runtime) or ContextMetrics (from tests)
|
|
121
|
+
*/
|
|
122
|
+
createCheckpoint(state) {
|
|
123
|
+
// Get metrics from monitor or use provided metrics
|
|
124
|
+
const metrics = state.contextMonitor?.getMetrics() ?? state.contextMetrics;
|
|
125
|
+
if (!metrics) {
|
|
126
|
+
throw new Error('Either contextMonitor or contextMetrics must be provided');
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
orchestratorId: state.orchestratorId,
|
|
130
|
+
orchestratorName: state.orchestratorName,
|
|
131
|
+
graphId: state.graphId,
|
|
132
|
+
sprintId: state.sprintId,
|
|
133
|
+
startedAt: state.startedAt.toISOString(),
|
|
134
|
+
savedAt: new Date().toISOString(),
|
|
135
|
+
lastProgressAt: state.lastProgressAt.toISOString(),
|
|
136
|
+
cyclesWithoutProgress: state.cyclesWithoutProgress,
|
|
137
|
+
completedTasks: Array.from(state.completedTasks),
|
|
138
|
+
inProgressTasks: Object.fromEntries(state.inProgressTasks),
|
|
139
|
+
blockedTasks: Array.from(state.blockedTasks),
|
|
140
|
+
assignmentHistory: state.assignmentHistory.map(a => ({
|
|
141
|
+
taskId: a.taskId,
|
|
142
|
+
agentId: a.agentId,
|
|
143
|
+
assignedAt: a.assignedAt.toISOString(),
|
|
144
|
+
status: a.status,
|
|
145
|
+
})),
|
|
146
|
+
contextMetrics: {
|
|
147
|
+
estimatedTokens: metrics.estimatedTokens,
|
|
148
|
+
contextLimit: metrics.contextLimit,
|
|
149
|
+
pressure: metrics.pressure,
|
|
150
|
+
messageCount: metrics.messageCount,
|
|
151
|
+
toolCallCount: metrics.toolCallCount,
|
|
152
|
+
eventsSinceStart: metrics.eventsSinceStart,
|
|
153
|
+
model: metrics.model,
|
|
154
|
+
},
|
|
155
|
+
version: 1,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Restore runtime state from checkpoint
|
|
160
|
+
*/
|
|
161
|
+
restoreFromCheckpoint(checkpoint) {
|
|
162
|
+
return {
|
|
163
|
+
completedTasks: new Set(checkpoint.completedTasks),
|
|
164
|
+
inProgressTasks: new Map(Object.entries(checkpoint.inProgressTasks)),
|
|
165
|
+
blockedTasks: new Set(checkpoint.blockedTasks),
|
|
166
|
+
assignmentHistory: checkpoint.assignmentHistory.map(a => ({
|
|
167
|
+
taskId: a.taskId,
|
|
168
|
+
agentId: a.agentId,
|
|
169
|
+
assignedAt: new Date(a.assignedAt),
|
|
170
|
+
status: a.status,
|
|
171
|
+
})),
|
|
172
|
+
startedAt: new Date(checkpoint.startedAt),
|
|
173
|
+
lastProgressAt: new Date(checkpoint.lastProgressAt),
|
|
174
|
+
cyclesWithoutProgress: checkpoint.cyclesWithoutProgress,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// ============================================================
|
|
179
|
+
// Graph Persistence (TASK-8: Orchestrator Recovery)
|
|
180
|
+
// ============================================================
|
|
181
|
+
/**
|
|
182
|
+
* Save orchestrator state to graph
|
|
183
|
+
* This enables cross-machine state recovery and team visibility
|
|
184
|
+
*/
|
|
185
|
+
export async function persistStateToGraph(checkpoint, graphApiClient) {
|
|
186
|
+
// Create or update OrchestratorState node
|
|
187
|
+
await graphApiClient.request('POST', '/api/v1/orchestrator/state', {
|
|
188
|
+
graphId: checkpoint.graphId,
|
|
189
|
+
orchestratorId: checkpoint.orchestratorId,
|
|
190
|
+
state: checkpoint,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Recover orchestrator state from graph
|
|
195
|
+
* Attempts to find the most recent state for the given epic/sprint
|
|
196
|
+
*/
|
|
197
|
+
export async function recoverStateFromGraph(graphId, epicId, graphApiClient) {
|
|
198
|
+
try {
|
|
199
|
+
// Query for most recent orchestrator state for this epic
|
|
200
|
+
const response = await graphApiClient.request('GET', `/api/v1/orchestrator/state?graphId=${graphId}&epicId=${epicId}`);
|
|
201
|
+
return response.state;
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
// If endpoint doesn't exist yet or other error, return null
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Reconcile task statuses after recovery
|
|
210
|
+
* Re-scans actual task status and compares with persisted state
|
|
211
|
+
* Handles discrepancies (e.g., task marked complete externally)
|
|
212
|
+
*/
|
|
213
|
+
export async function reconcileTaskStatuses(checkpoint, actualTasks, graphApiClient) {
|
|
214
|
+
const reconciledCheckpoint = { ...checkpoint };
|
|
215
|
+
const changes = [];
|
|
216
|
+
// Check completed tasks
|
|
217
|
+
for (const taskId of checkpoint.completedTasks) {
|
|
218
|
+
const actual = actualTasks.find(t => t.id === taskId);
|
|
219
|
+
if (actual && actual.status !== 'complete') {
|
|
220
|
+
// Task was marked incomplete externally - revert
|
|
221
|
+
reconciledCheckpoint.completedTasks = reconciledCheckpoint.completedTasks.filter(id => id !== taskId);
|
|
222
|
+
changes.push(`Task ${taskId} reverted from complete to ${actual.status}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// Check in-progress tasks
|
|
226
|
+
const inProgressEntries = Object.entries(checkpoint.inProgressTasks);
|
|
227
|
+
for (const [taskId, agentId] of inProgressEntries) {
|
|
228
|
+
const actual = actualTasks.find(t => t.id === taskId);
|
|
229
|
+
if (actual?.status === 'complete') {
|
|
230
|
+
// Task completed externally - move to completed
|
|
231
|
+
delete reconciledCheckpoint.inProgressTasks[taskId];
|
|
232
|
+
if (!reconciledCheckpoint.completedTasks.includes(taskId)) {
|
|
233
|
+
reconciledCheckpoint.completedTasks.push(taskId);
|
|
234
|
+
}
|
|
235
|
+
changes.push(`Task ${taskId} completed externally`);
|
|
236
|
+
}
|
|
237
|
+
else if (!actual) {
|
|
238
|
+
// Task no longer exists - remove
|
|
239
|
+
delete reconciledCheckpoint.inProgressTasks[taskId];
|
|
240
|
+
changes.push(`Task ${taskId} no longer exists`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Check for newly completed tasks not in checkpoint
|
|
244
|
+
for (const task of actualTasks) {
|
|
245
|
+
if (task.status === 'complete' && !reconciledCheckpoint.completedTasks.includes(task.id)) {
|
|
246
|
+
reconciledCheckpoint.completedTasks.push(task.id);
|
|
247
|
+
changes.push(`Task ${task.id} completed externally`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Log reconciliation if changes detected
|
|
251
|
+
if (changes.length > 0) {
|
|
252
|
+
console.log(`Reconciled ${changes.length} task status changes:`);
|
|
253
|
+
for (const change of changes) {
|
|
254
|
+
console.log(` - ${change}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return reconciledCheckpoint;
|
|
258
|
+
}
|
|
259
|
+
// ============================================================
|
|
260
|
+
// Exit Condition Helpers
|
|
261
|
+
// ============================================================
|
|
262
|
+
/**
|
|
263
|
+
* Determine exit code from reason
|
|
264
|
+
*/
|
|
265
|
+
export function getExitCode(reason) {
|
|
266
|
+
switch (reason) {
|
|
267
|
+
case 'all_complete':
|
|
268
|
+
case 'user_interrupt':
|
|
269
|
+
case 'manual_stop':
|
|
270
|
+
return EXIT_CODE_SUCCESS;
|
|
271
|
+
case 'context_pressure':
|
|
272
|
+
case 'max_runtime':
|
|
273
|
+
return EXIT_CODE_RESPAWN;
|
|
274
|
+
case 'no_progress':
|
|
275
|
+
case 'error':
|
|
276
|
+
default:
|
|
277
|
+
return EXIT_CODE_ERROR;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Check if exit code indicates respawn is needed
|
|
282
|
+
*/
|
|
283
|
+
export function shouldRespawn(exitCode) {
|
|
284
|
+
return exitCode === EXIT_CODE_RESPAWN;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Get human-readable exit message
|
|
288
|
+
*/
|
|
289
|
+
export function getExitMessage(reason) {
|
|
290
|
+
switch (reason) {
|
|
291
|
+
case 'all_complete':
|
|
292
|
+
return 'All tasks completed successfully';
|
|
293
|
+
case 'context_pressure':
|
|
294
|
+
return 'Context pressure exceeded threshold - respawn needed';
|
|
295
|
+
case 'max_runtime':
|
|
296
|
+
return 'Maximum runtime exceeded - respawn needed';
|
|
297
|
+
case 'no_progress':
|
|
298
|
+
return 'No progress detected for extended period - investigation needed';
|
|
299
|
+
case 'user_interrupt':
|
|
300
|
+
return 'Graceful shutdown requested';
|
|
301
|
+
case 'manual_stop':
|
|
302
|
+
return 'Orchestrator stopped manually';
|
|
303
|
+
case 'error':
|
|
304
|
+
return 'Unrecoverable error occurred';
|
|
305
|
+
default:
|
|
306
|
+
return 'Unknown exit reason';
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// ============================================================
|
|
310
|
+
// Singleton Instance (for global access)
|
|
311
|
+
// ============================================================
|
|
312
|
+
let stateManagerInstance = null;
|
|
313
|
+
/**
|
|
314
|
+
* Get or create state manager instance
|
|
315
|
+
*/
|
|
316
|
+
export function getStateManager(projectRoot, graphId) {
|
|
317
|
+
if (!stateManagerInstance && projectRoot) {
|
|
318
|
+
stateManagerInstance = new OrchestratorStateManager(projectRoot, graphId);
|
|
319
|
+
}
|
|
320
|
+
if (!stateManagerInstance) {
|
|
321
|
+
throw new Error('State manager not initialized. Call getStateManager with projectRoot first.');
|
|
322
|
+
}
|
|
323
|
+
return stateManagerInstance;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Reset state manager (for testing)
|
|
327
|
+
*/
|
|
328
|
+
export function resetStateManager() {
|
|
329
|
+
stateManagerInstance = null;
|
|
330
|
+
}
|
|
331
|
+
export default OrchestratorStateManager;
|
|
332
|
+
//# sourceMappingURL=orchestrator-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator-state.js","sourceRoot":"","sources":["../../src/lib/orchestrator-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileType: utility
|
|
3
|
+
* @status: current
|
|
4
|
+
* @updated: 2025-12-05
|
|
5
|
+
* @tags: [cursor, realtime, epic-004, multi-agent, event-stream]
|
|
6
|
+
* @related: [event-logger.ts, event-queue.ts, ../commands/graph/api-client.ts]
|
|
7
|
+
* @priority: high
|
|
8
|
+
* @complexity: medium
|
|
9
|
+
* @dependencies: [auth-storage]
|
|
10
|
+
*
|
|
11
|
+
* Real-time cursor updates for EPIC-004 multi-agent coordination.
|
|
12
|
+
*
|
|
13
|
+
* Purpose: Push cursor position to cloud immediately after significant actions,
|
|
14
|
+
* enabling other agents to see work in near-real-time (< 5 seconds).
|
|
15
|
+
*
|
|
16
|
+
* When to update:
|
|
17
|
+
* - After task claim
|
|
18
|
+
* - After each logged event
|
|
19
|
+
* - After task completion
|
|
20
|
+
* - On session start/resume
|
|
21
|
+
*
|
|
22
|
+
* Configuration:
|
|
23
|
+
* - Flag: --realtime-cursor (default: true)
|
|
24
|
+
* - Env: GINKO_REALTIME_CURSOR=true|false
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Cursor position update payload
|
|
28
|
+
*/
|
|
29
|
+
export interface CursorUpdate {
|
|
30
|
+
userId: string;
|
|
31
|
+
projectId: string;
|
|
32
|
+
branch: string;
|
|
33
|
+
lastEventId?: string;
|
|
34
|
+
currentTask?: string;
|
|
35
|
+
status: 'active' | 'idle' | 'busy';
|
|
36
|
+
timestamp: string;
|
|
37
|
+
action?: 'session_start' | 'event_logged' | 'task_claimed' | 'task_completed' | 'handoff';
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Cursor update response from API
|
|
41
|
+
*/
|
|
42
|
+
export interface CursorUpdateResponse {
|
|
43
|
+
success: boolean;
|
|
44
|
+
cursor: {
|
|
45
|
+
userId: string;
|
|
46
|
+
projectId: string;
|
|
47
|
+
lastEventId?: string;
|
|
48
|
+
updatedAt: string;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Real-time cursor configuration
|
|
53
|
+
*/
|
|
54
|
+
interface RealtimeCursorConfig {
|
|
55
|
+
enabled: boolean;
|
|
56
|
+
apiUrl: string;
|
|
57
|
+
debounceMs: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Set runtime override for realtime cursor
|
|
61
|
+
* Called by CLI when --no-realtime-cursor is passed
|
|
62
|
+
*/
|
|
63
|
+
export declare function setRealtimeCursorEnabled(enabled: boolean): void;
|
|
64
|
+
/**
|
|
65
|
+
* Get configuration for realtime cursor updates
|
|
66
|
+
*/
|
|
67
|
+
export declare function getRealtimeCursorConfig(): RealtimeCursorConfig;
|
|
68
|
+
/**
|
|
69
|
+
* Check if realtime cursor updates are enabled
|
|
70
|
+
*/
|
|
71
|
+
export declare function isRealtimeCursorEnabled(): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Push cursor update to cloud immediately
|
|
74
|
+
*
|
|
75
|
+
* Uses debouncing to prevent rapid-fire updates (e.g., multiple events logged in quick succession).
|
|
76
|
+
* Guarantees update within config.debounceMs after last call.
|
|
77
|
+
*
|
|
78
|
+
* @param update - Cursor update payload
|
|
79
|
+
* @returns Promise resolving when update is sent (or debounced)
|
|
80
|
+
*/
|
|
81
|
+
export declare function pushCursorUpdate(update: CursorUpdate): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Update cursor on session start/resume
|
|
84
|
+
*/
|
|
85
|
+
export declare function onSessionStart(): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Update cursor after event is logged
|
|
88
|
+
*/
|
|
89
|
+
export declare function onEventLogged(eventId: string): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Update cursor when task is claimed
|
|
92
|
+
*/
|
|
93
|
+
export declare function onTaskClaimed(taskId: string): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Update cursor when task is completed
|
|
96
|
+
*/
|
|
97
|
+
export declare function onTaskCompleted(taskId: string): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Update cursor on handoff
|
|
100
|
+
*/
|
|
101
|
+
export declare function onHandoff(finalEventId?: string): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Flush any pending cursor update (for shutdown)
|
|
104
|
+
*/
|
|
105
|
+
export declare function flushPendingCursorUpdate(): Promise<void>;
|
|
106
|
+
export {};
|
|
107
|
+
//# sourceMappingURL=realtime-cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime-cursor.d.ts","sourceRoot":"","sources":["../../src/lib/realtime-cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAOH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,eAAe,GAAG,cAAc,GAAG,cAAc,GAAG,gBAAgB,GAAG,SAAS,CAAC;CAC3F;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,UAAU,oBAAoB;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAOD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE/D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,oBAAoB,CAmB9D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD;AASD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC1E;AA2ED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAUpD;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWlE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWjE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWnE;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWpE;AAED;;GAEG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CAU9D"}
|