@harness-engineering/orchestrator 0.2.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/LICENSE +21 -0
- package/dist/index.d.mts +443 -0
- package/dist/index.d.ts +443 -0
- package/dist/index.js +1380 -0
- package/dist/index.mjs +1330 -0
- package/package.json +67 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
import { Issue, AgentEvent, TokenUsage, WorkflowConfig, Result, WorkflowDefinition, IssueTrackerClient, TrackerConfig, WorkspaceConfig, HooksConfig, AgentBackend, SessionStartParams, AgentSession, AgentError, TurnParams, TurnResult } from '@harness-engineering/types';
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Run attempt lifecycle phases (internal to orchestrator).
|
|
6
|
+
* Tracks the current phase of a single run attempt.
|
|
7
|
+
*/
|
|
8
|
+
type RunAttemptPhase = 'PreparingWorkspace' | 'BuildingPrompt' | 'LaunchingAgent' | 'InitializingSession' | 'StreamingTurn' | 'Finishing' | 'Succeeded' | 'Failed' | 'TimedOut' | 'Stalled' | 'CanceledByReconciliation';
|
|
9
|
+
/**
|
|
10
|
+
* Live session metadata tracked while an agent subprocess is running.
|
|
11
|
+
*/
|
|
12
|
+
interface LiveSession {
|
|
13
|
+
sessionId: string;
|
|
14
|
+
backendName: string;
|
|
15
|
+
agentPid: number | null;
|
|
16
|
+
startedAt: string;
|
|
17
|
+
lastEvent: string | null;
|
|
18
|
+
lastTimestamp: string | null;
|
|
19
|
+
lastMessage: string | null;
|
|
20
|
+
inputTokens: number;
|
|
21
|
+
outputTokens: number;
|
|
22
|
+
totalTokens: number;
|
|
23
|
+
lastReportedInputTokens: number;
|
|
24
|
+
lastReportedOutputTokens: number;
|
|
25
|
+
lastReportedTotalTokens: number;
|
|
26
|
+
turnCount: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Entry in the running map: one active worker.
|
|
30
|
+
*/
|
|
31
|
+
interface RunningEntry {
|
|
32
|
+
issueId: string;
|
|
33
|
+
identifier: string;
|
|
34
|
+
issue: Issue;
|
|
35
|
+
attempt: number | null;
|
|
36
|
+
workspacePath: string;
|
|
37
|
+
startedAt: string;
|
|
38
|
+
phase: RunAttemptPhase;
|
|
39
|
+
session: LiveSession | null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Entry in the retry queue.
|
|
43
|
+
*/
|
|
44
|
+
interface RetryEntry {
|
|
45
|
+
issueId: string;
|
|
46
|
+
identifier: string;
|
|
47
|
+
attempt: number;
|
|
48
|
+
dueAtMs: number;
|
|
49
|
+
error: string | null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Token totals for observability.
|
|
53
|
+
*/
|
|
54
|
+
interface TokenTotals {
|
|
55
|
+
inputTokens: number;
|
|
56
|
+
outputTokens: number;
|
|
57
|
+
totalTokens: number;
|
|
58
|
+
secondsRunning: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Rate limit snapshot (populated by agent events).
|
|
62
|
+
*/
|
|
63
|
+
interface RateLimitSnapshot {
|
|
64
|
+
requestsRemaining: number | null;
|
|
65
|
+
requestsLimit: number | null;
|
|
66
|
+
tokensRemaining: number | null;
|
|
67
|
+
tokensLimit: number | null;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Single authoritative in-memory orchestrator state.
|
|
71
|
+
*/
|
|
72
|
+
interface OrchestratorState {
|
|
73
|
+
pollIntervalMs: number;
|
|
74
|
+
maxConcurrentAgents: number;
|
|
75
|
+
running: Map<string, RunningEntry>;
|
|
76
|
+
claimed: Set<string>;
|
|
77
|
+
retryAttempts: Map<string, RetryEntry>;
|
|
78
|
+
completed: Set<string>;
|
|
79
|
+
tokenTotals: TokenTotals;
|
|
80
|
+
rateLimits: RateLimitSnapshot;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Discriminated union of events that drive the orchestrator state machine.
|
|
85
|
+
* All events are data -- the caller constructs them from I/O results.
|
|
86
|
+
*/
|
|
87
|
+
type OrchestratorEvent = TickEvent | WorkerExitEvent | AgentUpdateEvent | RetryFiredEvent | StallDetectedEvent;
|
|
88
|
+
interface TickEvent {
|
|
89
|
+
type: 'tick';
|
|
90
|
+
candidates: Issue[];
|
|
91
|
+
runningStates: Map<string, Issue>;
|
|
92
|
+
/** Caller-supplied wall clock (ms since epoch). Keeps state machine pure. */
|
|
93
|
+
nowMs: number;
|
|
94
|
+
}
|
|
95
|
+
interface WorkerExitEvent {
|
|
96
|
+
type: 'worker_exit';
|
|
97
|
+
issueId: string;
|
|
98
|
+
reason: 'normal' | 'error';
|
|
99
|
+
error?: string | undefined;
|
|
100
|
+
attempt: number | null;
|
|
101
|
+
}
|
|
102
|
+
interface AgentUpdateEvent {
|
|
103
|
+
type: 'agent_update';
|
|
104
|
+
issueId: string;
|
|
105
|
+
event: AgentEvent;
|
|
106
|
+
}
|
|
107
|
+
interface RetryFiredEvent {
|
|
108
|
+
type: 'retry_fired';
|
|
109
|
+
issueId: string;
|
|
110
|
+
candidates: Issue[];
|
|
111
|
+
/** Caller-supplied wall clock (ms since epoch). Keeps state machine pure. */
|
|
112
|
+
nowMs: number;
|
|
113
|
+
}
|
|
114
|
+
interface StallDetectedEvent {
|
|
115
|
+
type: 'stall_detected';
|
|
116
|
+
issueId: string;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Discriminated union of side effects returned by the state machine.
|
|
120
|
+
* These are data describing what to do -- the orchestrator loop executes them.
|
|
121
|
+
*/
|
|
122
|
+
type SideEffect = DispatchEffect | StopEffect | ScheduleRetryEffect | ReleaseClaimEffect | CleanWorkspaceEffect | UpdateTokensEffect | EmitLogEffect;
|
|
123
|
+
interface DispatchEffect {
|
|
124
|
+
type: 'dispatch';
|
|
125
|
+
issue: Issue;
|
|
126
|
+
attempt: number | null;
|
|
127
|
+
}
|
|
128
|
+
interface StopEffect {
|
|
129
|
+
type: 'stop';
|
|
130
|
+
issueId: string;
|
|
131
|
+
reason: string;
|
|
132
|
+
}
|
|
133
|
+
interface ScheduleRetryEffect {
|
|
134
|
+
type: 'scheduleRetry';
|
|
135
|
+
issueId: string;
|
|
136
|
+
identifier: string;
|
|
137
|
+
attempt: number;
|
|
138
|
+
delayMs: number;
|
|
139
|
+
error: string | null;
|
|
140
|
+
}
|
|
141
|
+
interface ReleaseClaimEffect {
|
|
142
|
+
type: 'releaseClaim';
|
|
143
|
+
issueId: string;
|
|
144
|
+
}
|
|
145
|
+
interface CleanWorkspaceEffect {
|
|
146
|
+
type: 'cleanWorkspace';
|
|
147
|
+
issueId: string;
|
|
148
|
+
identifier: string;
|
|
149
|
+
}
|
|
150
|
+
interface UpdateTokensEffect {
|
|
151
|
+
type: 'updateTokens';
|
|
152
|
+
issueId: string;
|
|
153
|
+
usage: TokenUsage;
|
|
154
|
+
}
|
|
155
|
+
interface EmitLogEffect {
|
|
156
|
+
type: 'emitLog';
|
|
157
|
+
level: 'info' | 'warn' | 'error';
|
|
158
|
+
message: string;
|
|
159
|
+
context?: Record<string, unknown>;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Calculate retry delay based on attempt number and retry type.
|
|
164
|
+
*
|
|
165
|
+
* Continuation retries: fixed 1000ms delay.
|
|
166
|
+
* Failure retries: exponential backoff 10000 * 2^(attempt-1), capped at maxRetryBackoffMs.
|
|
167
|
+
*/
|
|
168
|
+
declare function calculateRetryDelay(attempt: number, type: 'continuation' | 'failure', maxRetryBackoffMs?: number): number;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Sort candidates by dispatch priority (stable sort).
|
|
172
|
+
* 1. priority ascending (1..4 preferred; null sorts last)
|
|
173
|
+
* 2. createdAt oldest first (null sorts last)
|
|
174
|
+
* 3. identifier lexicographic tie-breaker
|
|
175
|
+
*/
|
|
176
|
+
declare function sortCandidates(issues: readonly Issue[]): Issue[];
|
|
177
|
+
/**
|
|
178
|
+
* Check if a single issue is dispatch-eligible.
|
|
179
|
+
* State comparisons are case-insensitive.
|
|
180
|
+
*/
|
|
181
|
+
declare function isEligible(issue: Issue, state: OrchestratorState, activeStates: string[], terminalStates: string[]): boolean;
|
|
182
|
+
/**
|
|
183
|
+
* Select and sort eligible candidates from a list of issues.
|
|
184
|
+
*/
|
|
185
|
+
declare function selectCandidates(issues: readonly Issue[], state: OrchestratorState, activeStates: string[], terminalStates: string[]): Issue[];
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Get the number of available global concurrency slots.
|
|
189
|
+
*/
|
|
190
|
+
declare function getAvailableSlots(state: OrchestratorState): number;
|
|
191
|
+
/**
|
|
192
|
+
* Count running entries by normalized (lowercase) issue state.
|
|
193
|
+
*/
|
|
194
|
+
declare function getPerStateCount(running: ReadonlyMap<string, RunningEntry>): Map<string, number>;
|
|
195
|
+
/**
|
|
196
|
+
* Check if dispatching an issue in the given state is allowed
|
|
197
|
+
* by both global and per-state concurrency limits.
|
|
198
|
+
*/
|
|
199
|
+
declare function canDispatch(state: OrchestratorState, issueState: string, maxConcurrentAgentsByState: Record<string, number>): boolean;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Reconcile running issues against their current tracker states.
|
|
203
|
+
*
|
|
204
|
+
* For each running issue found in runningStates:
|
|
205
|
+
* - Terminal state -> stop + cleanWorkspace + releaseClaim
|
|
206
|
+
* - Neither active nor terminal -> stop + releaseClaim (no workspace cleanup)
|
|
207
|
+
* - Still active -> no effects (keep running)
|
|
208
|
+
*
|
|
209
|
+
* Issues not found in runningStates are left running (state refresh may have
|
|
210
|
+
* partially failed; retry next tick per spec).
|
|
211
|
+
*/
|
|
212
|
+
declare function reconcile(state: OrchestratorState, runningStates: ReadonlyMap<string, Issue>, activeStates: string[], terminalStates: string[]): SideEffect[];
|
|
213
|
+
|
|
214
|
+
interface ApplyEventResult {
|
|
215
|
+
nextState: OrchestratorState;
|
|
216
|
+
effects: SideEffect[];
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Pure state machine transition function.
|
|
220
|
+
*
|
|
221
|
+
* Takes the current state, an event, and config.
|
|
222
|
+
* Returns the next state and a list of side effects to execute.
|
|
223
|
+
* No I/O is performed -- all side effects are returned as data.
|
|
224
|
+
*/
|
|
225
|
+
declare function applyEvent(state: OrchestratorState, event: OrchestratorEvent, config: WorkflowConfig): ApplyEventResult;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Create an empty OrchestratorState initialized from config.
|
|
229
|
+
*/
|
|
230
|
+
declare function createEmptyState(config: WorkflowConfig): OrchestratorState;
|
|
231
|
+
|
|
232
|
+
declare class WorkflowLoader {
|
|
233
|
+
loadWorkflow(filePath: string): Promise<Result<WorkflowDefinition, Error>>;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
declare function validateWorkflowConfig(config: unknown): Result<WorkflowConfig, Error>;
|
|
237
|
+
declare function getDefaultConfig(): WorkflowConfig;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Adapter for using a markdown roadmap file as an issue tracker.
|
|
241
|
+
*
|
|
242
|
+
* This adapter parses a standard Harness roadmap file, extracts features,
|
|
243
|
+
* and maps them to the internal Issue model using deterministic hashing
|
|
244
|
+
* for identifiers.
|
|
245
|
+
*/
|
|
246
|
+
declare class RoadmapTrackerAdapter implements IssueTrackerClient {
|
|
247
|
+
private config;
|
|
248
|
+
/**
|
|
249
|
+
* Creates a new RoadmapTrackerAdapter.
|
|
250
|
+
*
|
|
251
|
+
* @param config - The tracker configuration including the file path
|
|
252
|
+
*/
|
|
253
|
+
constructor(config: TrackerConfig);
|
|
254
|
+
/**
|
|
255
|
+
* Fetches all issues that are in an "active" state according to the config.
|
|
256
|
+
*/
|
|
257
|
+
fetchCandidateIssues(): Promise<Result<Issue[], Error>>;
|
|
258
|
+
/**
|
|
259
|
+
* Fetches issues that match any of the given state names.
|
|
260
|
+
*
|
|
261
|
+
* @param stateNames - List of statuses to filter by
|
|
262
|
+
*/
|
|
263
|
+
fetchIssuesByStates(stateNames: string[]): Promise<Result<Issue[], Error>>;
|
|
264
|
+
/**
|
|
265
|
+
* Fetches full issue details for a list of identifiers.
|
|
266
|
+
*
|
|
267
|
+
* @param issueIds - List of issue IDs to fetch
|
|
268
|
+
*/
|
|
269
|
+
fetchIssueStatesByIds(issueIds: string[]): Promise<Result<Map<string, Issue>, Error>>;
|
|
270
|
+
/**
|
|
271
|
+
* Maps a raw RoadmapFeature from the parser to the unified Issue model.
|
|
272
|
+
*/
|
|
273
|
+
private mapFeatureToIssue;
|
|
274
|
+
/**
|
|
275
|
+
* Generates a deterministic, URL-safe identifier for a feature name.
|
|
276
|
+
*/
|
|
277
|
+
private generateId;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Interface for Linear GraphQL tool extension.
|
|
282
|
+
* This is a stub implementation for Phase 4.
|
|
283
|
+
*/
|
|
284
|
+
interface LinearGraphQLExtension {
|
|
285
|
+
query(query: string, variables?: Record<string, unknown>): Promise<Result<unknown, Error>>;
|
|
286
|
+
}
|
|
287
|
+
declare class LinearGraphQLStub implements LinearGraphQLExtension {
|
|
288
|
+
query(query: string, _variables?: Record<string, unknown>): Promise<Result<unknown, Error>>;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
declare class WorkspaceManager {
|
|
292
|
+
private config;
|
|
293
|
+
constructor(config: WorkspaceConfig);
|
|
294
|
+
/**
|
|
295
|
+
* Sanitizes an issue identifier to be safe for use as a directory name.
|
|
296
|
+
*/
|
|
297
|
+
sanitizeIdentifier(identifier: string): string;
|
|
298
|
+
/**
|
|
299
|
+
* Resolves the full path for an issue's workspace.
|
|
300
|
+
*/
|
|
301
|
+
resolvePath(identifier: string): string;
|
|
302
|
+
/**
|
|
303
|
+
* Ensures the workspace directory exists.
|
|
304
|
+
*/
|
|
305
|
+
ensureWorkspace(identifier: string): Promise<Result<string, Error>>;
|
|
306
|
+
/**
|
|
307
|
+
* Checks if a workspace exists.
|
|
308
|
+
*/
|
|
309
|
+
exists(identifier: string): Promise<boolean>;
|
|
310
|
+
/**
|
|
311
|
+
* Removes a workspace directory.
|
|
312
|
+
*/
|
|
313
|
+
removeWorkspace(identifier: string): Promise<Result<void, Error>>;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
declare class WorkspaceHooks {
|
|
317
|
+
private config;
|
|
318
|
+
constructor(config: HooksConfig);
|
|
319
|
+
/**
|
|
320
|
+
* Executes a shell hook in the specified workspace directory.
|
|
321
|
+
*/
|
|
322
|
+
executeHook(hookName: keyof Omit<HooksConfig, 'timeoutMs'>, cwd: string): Promise<Result<void, Error>>;
|
|
323
|
+
afterCreate(cwd: string): Promise<Result<void, Error>>;
|
|
324
|
+
beforeRun(cwd: string): Promise<Result<void, Error>>;
|
|
325
|
+
afterRun(cwd: string): Promise<Result<void, Error>>;
|
|
326
|
+
beforeRemove(cwd: string): Promise<Result<void, Error>>;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
declare class MockBackend implements AgentBackend {
|
|
330
|
+
readonly name = "mock";
|
|
331
|
+
startSession(params: SessionStartParams): Promise<Result<AgentSession, AgentError>>;
|
|
332
|
+
runTurn(session: AgentSession, _params: TurnParams): AsyncGenerator<AgentEvent, TurnResult, void>;
|
|
333
|
+
stopSession(_session: AgentSession): Promise<Result<void, AgentError>>;
|
|
334
|
+
healthCheck(): Promise<Result<void, AgentError>>;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
declare class ClaudeBackend implements AgentBackend {
|
|
338
|
+
readonly name = "claude";
|
|
339
|
+
private command;
|
|
340
|
+
constructor(command?: string);
|
|
341
|
+
startSession(params: SessionStartParams): Promise<Result<AgentSession, AgentError>>;
|
|
342
|
+
runTurn(session: AgentSession, params: TurnParams): AsyncGenerator<AgentEvent, TurnResult, void>;
|
|
343
|
+
stopSession(_session: AgentSession): Promise<Result<void, AgentError>>;
|
|
344
|
+
healthCheck(): Promise<Result<void, AgentError>>;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
declare class PromptRenderer {
|
|
348
|
+
private engine;
|
|
349
|
+
constructor();
|
|
350
|
+
render(template: string, context: Record<string, unknown>): Promise<string>;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* The central orchestrator that manages the lifecycle of coding agents.
|
|
355
|
+
*
|
|
356
|
+
* It polls an issue tracker for candidate tasks, manages ephemeral workspaces,
|
|
357
|
+
* runs agents to resolve issues, and updates the tracker with progress.
|
|
358
|
+
*
|
|
359
|
+
* @fires Orchestrator#state_change Emitted when the internal state machine transitions
|
|
360
|
+
* @fires Orchestrator#agent_event Emitted when an agent produces an output or thought
|
|
361
|
+
*/
|
|
362
|
+
declare class Orchestrator extends EventEmitter {
|
|
363
|
+
private state;
|
|
364
|
+
private config;
|
|
365
|
+
private tracker;
|
|
366
|
+
private workspace;
|
|
367
|
+
private hooks;
|
|
368
|
+
private runner;
|
|
369
|
+
private renderer;
|
|
370
|
+
private promptTemplate;
|
|
371
|
+
private server?;
|
|
372
|
+
private interval?;
|
|
373
|
+
private logger;
|
|
374
|
+
/**
|
|
375
|
+
* Creates a new Orchestrator instance.
|
|
376
|
+
*
|
|
377
|
+
* @param config - The workflow configuration
|
|
378
|
+
* @param promptTemplate - The template used to generate agent instructions
|
|
379
|
+
* @param overrides - Optional dependency overrides for testing or custom behavior
|
|
380
|
+
*/
|
|
381
|
+
constructor(config: WorkflowConfig, promptTemplate: string, overrides?: {
|
|
382
|
+
tracker?: IssueTrackerClient;
|
|
383
|
+
backend?: AgentBackend;
|
|
384
|
+
});
|
|
385
|
+
private createTracker;
|
|
386
|
+
private createBackend;
|
|
387
|
+
/**
|
|
388
|
+
* Run a single tick of the orchestrator loop.
|
|
389
|
+
*
|
|
390
|
+
* This method fetches the latest issue states, applies them to the state machine,
|
|
391
|
+
* and executes any resulting side effects (dispatching new agents, stopping agents, etc.).
|
|
392
|
+
*/
|
|
393
|
+
tick(): Promise<void>;
|
|
394
|
+
/**
|
|
395
|
+
* Processes a side effect generated by the state machine.
|
|
396
|
+
*
|
|
397
|
+
* @param effect - The effect to handle
|
|
398
|
+
*/
|
|
399
|
+
private handleEffect;
|
|
400
|
+
/**
|
|
401
|
+
* Dispatches a new agent to work on an issue.
|
|
402
|
+
*
|
|
403
|
+
* @param issue - The issue to resolve
|
|
404
|
+
* @param attempt - The retry attempt number
|
|
405
|
+
*/
|
|
406
|
+
private dispatchIssue;
|
|
407
|
+
/**
|
|
408
|
+
* Runs an agent session in a background task to avoid blocking the main loop.
|
|
409
|
+
*/
|
|
410
|
+
private runAgentInBackgroundTask;
|
|
411
|
+
/**
|
|
412
|
+
* Informs the state machine that an agent worker has exited.
|
|
413
|
+
*/
|
|
414
|
+
private emitWorkerExit;
|
|
415
|
+
/**
|
|
416
|
+
* Stops execution for a specific issue.
|
|
417
|
+
*
|
|
418
|
+
* @param issueId - The ID of the issue to stop
|
|
419
|
+
*/
|
|
420
|
+
private stopIssue;
|
|
421
|
+
/**
|
|
422
|
+
* Starts the polling loop and the internal HTTP server.
|
|
423
|
+
*/
|
|
424
|
+
start(): void;
|
|
425
|
+
/**
|
|
426
|
+
* Stops the orchestrator, clearing the polling interval and stopping the server.
|
|
427
|
+
*/
|
|
428
|
+
stop(): Promise<void>;
|
|
429
|
+
/**
|
|
430
|
+
* Returns a point-in-time snapshot of the orchestrator's internal state.
|
|
431
|
+
*/
|
|
432
|
+
getSnapshot(): Record<string, unknown>;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Launches the Ink TUI for the given Orchestrator instance.
|
|
437
|
+
* Returns a function to wait for the TUI to exit.
|
|
438
|
+
*/
|
|
439
|
+
declare function launchTUI(orchestrator: Orchestrator): {
|
|
440
|
+
waitUntilExit: () => Promise<void>;
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
export { type AgentUpdateEvent, type ApplyEventResult, ClaudeBackend, type CleanWorkspaceEffect, type DispatchEffect, type EmitLogEffect, type LinearGraphQLExtension, LinearGraphQLStub, type LiveSession, MockBackend, Orchestrator, type OrchestratorEvent, type OrchestratorState, PromptRenderer, type RateLimitSnapshot, type ReleaseClaimEffect, type RetryEntry, type RetryFiredEvent, RoadmapTrackerAdapter, type RunAttemptPhase, type RunningEntry, type ScheduleRetryEffect, type SideEffect, type StallDetectedEvent, type StopEffect, type TickEvent, type TokenTotals, type UpdateTokensEffect, type WorkerExitEvent, WorkflowLoader, WorkspaceHooks, WorkspaceManager, applyEvent, calculateRetryDelay, canDispatch, createEmptyState, getAvailableSlots, getDefaultConfig, getPerStateCount, isEligible, launchTUI, reconcile, selectCandidates, sortCandidates, validateWorkflowConfig };
|