@oxgeneral/orch 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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/dist/App-CPQPQTZU.js +4751 -0
  3. package/dist/agent-J62U7ABO.js +157 -0
  4. package/dist/chunk-2B32FPEB.js +11 -0
  5. package/dist/chunk-2B32FPEB.js.map +1 -0
  6. package/dist/chunk-2VSAM7RH.js +166 -0
  7. package/dist/chunk-33QNTNR6.js +46 -0
  8. package/dist/chunk-45K2XID7.js +29 -0
  9. package/dist/chunk-6GFVB6EK.js +101 -0
  10. package/dist/chunk-6HENRUYZ.js +2 -0
  11. package/dist/chunk-6HENRUYZ.js.map +1 -0
  12. package/dist/chunk-AELEEEV3.js +92 -0
  13. package/dist/chunk-AELEEEV3.js.map +1 -0
  14. package/dist/chunk-CHIP7O6V.js +83 -0
  15. package/dist/chunk-CIIE6LNG.js +217 -0
  16. package/dist/chunk-E3TCKHU6.js +13 -0
  17. package/dist/chunk-E3TCKHU6.js.map +1 -0
  18. package/dist/chunk-ED47GL3F.js +29 -0
  19. package/dist/chunk-HNKJ4IF7.js +177 -0
  20. package/dist/chunk-HXYAZGLP.js +15 -0
  21. package/dist/chunk-IRN2U2NE.js +79 -0
  22. package/dist/chunk-IZYSGYXG.js +2 -0
  23. package/dist/chunk-IZYSGYXG.js.map +1 -0
  24. package/dist/chunk-O5AO5QIR.js +76 -0
  25. package/dist/chunk-P6ATSXGL.js +107 -0
  26. package/dist/chunk-PBFE5V3G.js +2 -0
  27. package/dist/chunk-PBFE5V3G.js.map +1 -0
  28. package/dist/chunk-PNE6LQRF.js +5 -0
  29. package/dist/chunk-POUC4CPC.js +2 -0
  30. package/dist/chunk-POUC4CPC.js.map +1 -0
  31. package/dist/chunk-TX7WOFCW.js +59 -0
  32. package/dist/chunk-VTA74YWX.js +291 -0
  33. package/dist/chunk-XI4TU6VU.js +50 -0
  34. package/dist/chunk-ZU6AY2VU.js +2 -0
  35. package/dist/chunk-ZU6AY2VU.js.map +1 -0
  36. package/dist/claude-GH6P2DC5.js +4 -0
  37. package/dist/claude-S47YTIHU.js +2 -0
  38. package/dist/claude-S47YTIHU.js.map +1 -0
  39. package/dist/cli.js +205 -0
  40. package/dist/codex-2CH57B7G.js +2 -0
  41. package/dist/codex-2CH57B7G.js.map +1 -0
  42. package/dist/codex-U7LTJTX6.js +115 -0
  43. package/dist/config-VN4MYHSY.js +75 -0
  44. package/dist/container-74P43KDY.js +1532 -0
  45. package/dist/context-EPHCF34F.js +83 -0
  46. package/dist/cursor-3DI5GKRF.js +92 -0
  47. package/dist/cursor-QFUNKPCQ.js +2 -0
  48. package/dist/cursor-QFUNKPCQ.js.map +1 -0
  49. package/dist/doctor-BK46WCQ5.js +67 -0
  50. package/dist/doctor-service-A34DHPKI.js +2 -0
  51. package/dist/doctor-service-NTWBWOM2.js +2 -0
  52. package/dist/doctor-service-NTWBWOM2.js.map +1 -0
  53. package/dist/goal-KGAIM3ZK.js +110 -0
  54. package/dist/index.d.ts +1356 -0
  55. package/dist/index.js +6 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/init-QBWCEDCI.js +152 -0
  58. package/dist/logs-PYEKMQE2.js +207 -0
  59. package/dist/msg-BBIPCGDO.js +95 -0
  60. package/dist/orchestrator-TAFBYQQ5.js +2 -0
  61. package/dist/orchestrator-TAFBYQQ5.js.map +1 -0
  62. package/dist/orchestrator-VGYKSOZJ.js +1292 -0
  63. package/dist/output-5VQVCJ2K.js +2 -0
  64. package/dist/process-manager-HUVNAPQV.js +2 -0
  65. package/dist/process-manager-TLZOTO4Y.js +2 -0
  66. package/dist/process-manager-TLZOTO4Y.js.map +1 -0
  67. package/dist/registry-PQWRVNF2.js +2 -0
  68. package/dist/registry-UQAHK77P.js +2 -0
  69. package/dist/registry-UQAHK77P.js.map +1 -0
  70. package/dist/run-4GSZFGQZ.js +95 -0
  71. package/dist/shell-5ZNXFGXV.js +3 -0
  72. package/dist/shell-OGTSH4RJ.js +3 -0
  73. package/dist/shell-OGTSH4RJ.js.map +1 -0
  74. package/dist/status-KIISF542.js +56 -0
  75. package/dist/task-NUCRHYW7.js +209 -0
  76. package/dist/team-IBUP5XV4.js +97 -0
  77. package/dist/template-engine-322SCRR6.js +2 -0
  78. package/dist/template-engine-322SCRR6.js.map +1 -0
  79. package/dist/template-engine-3CDRZNMJ.js +3 -0
  80. package/dist/tui-WWZA73IO.js +225 -0
  81. package/dist/update-RJ4IYACQ.js +64 -0
  82. package/dist/update-check-4RV7Z6WT.js +2 -0
  83. package/dist/workspace-manager-47KI7B27.js +179 -0
  84. package/dist/workspace-manager-7M46ESUL.js +2 -0
  85. package/dist/workspace-manager-7M46ESUL.js.map +1 -0
  86. package/package.json +79 -0
  87. package/readme.md +270 -0
@@ -0,0 +1,1356 @@
1
+ import { SpawnOptions, ChildProcess } from 'node:child_process';
2
+
3
+ /**
4
+ * Task domain model.
5
+ *
6
+ * A Task is the unit of work in the orchestrator.
7
+ * It moves through a state machine: todo → in_progress → review → done.
8
+ */
9
+ type TaskStatus = 'todo' | 'in_progress' | 'retrying' | 'review' | 'done' | 'failed' | 'cancelled';
10
+ type WorkspaceMode = 'shared' | 'worktree' | 'isolated';
11
+ type ReviewCriterion = 'test_pass' | 'typecheck' | 'lint';
12
+ interface ReviewResult {
13
+ criterion: ReviewCriterion;
14
+ passed: boolean;
15
+ output: string;
16
+ }
17
+ interface TaskProof {
18
+ branch?: string;
19
+ pr_url?: string;
20
+ files_changed: string[];
21
+ test_results?: string;
22
+ agent_summary?: string;
23
+ }
24
+ interface Task {
25
+ id: string;
26
+ title: string;
27
+ description: string;
28
+ status: TaskStatus;
29
+ priority: number;
30
+ assignee?: string;
31
+ labels: string[];
32
+ depends_on: string[];
33
+ created_at: string;
34
+ updated_at: string;
35
+ attempts: number;
36
+ max_attempts: number;
37
+ workspace_mode?: WorkspaceMode;
38
+ workspace?: string;
39
+ proof?: TaskProof;
40
+ review_criteria?: ReviewCriterion[];
41
+ review_results?: ReviewResult[];
42
+ scope?: string[];
43
+ feedback?: string;
44
+ }
45
+ interface CreateTaskInput {
46
+ title: string;
47
+ description?: string;
48
+ priority?: number;
49
+ assignee?: string;
50
+ labels?: string[];
51
+ depends_on?: string[];
52
+ max_attempts?: number;
53
+ workspace_mode?: WorkspaceMode;
54
+ review_criteria?: ReviewCriterion[];
55
+ scope?: string[];
56
+ }
57
+
58
+ /**
59
+ * Agent domain model.
60
+ *
61
+ * An Agent is a configured AI tool (Claude, Codex, Shell, etc.)
62
+ * that can be assigned to execute Tasks.
63
+ */
64
+ type AgentStatus = 'idle' | 'running' | 'error' | 'disabled';
65
+ type ApprovalPolicy = 'suggest' | 'auto' | 'manual';
66
+ interface AgentConfig {
67
+ command?: string;
68
+ model?: string;
69
+ approval_policy?: ApprovalPolicy;
70
+ max_turns?: number;
71
+ timeout_ms?: number;
72
+ stall_timeout_ms?: number;
73
+ env?: Record<string, string>;
74
+ system_prompt?: string;
75
+ workspace_mode?: WorkspaceMode;
76
+ skills?: string[];
77
+ }
78
+ interface AgentStats {
79
+ tasks_completed: number;
80
+ tasks_failed: number;
81
+ total_runs: number;
82
+ total_runtime_ms: number;
83
+ tokens_used?: number;
84
+ }
85
+ interface Agent {
86
+ id: string;
87
+ name: string;
88
+ adapter: string;
89
+ role?: string;
90
+ config: AgentConfig;
91
+ status: AgentStatus;
92
+ current_task?: string;
93
+ autonomous?: boolean;
94
+ stats: AgentStats;
95
+ }
96
+ interface CreateAgentInput {
97
+ name: string;
98
+ adapter: string;
99
+ role?: string;
100
+ command?: string;
101
+ model?: string;
102
+ approval_policy?: ApprovalPolicy;
103
+ max_turns?: number;
104
+ timeout_ms?: number;
105
+ stall_timeout_ms?: number;
106
+ env?: Record<string, string>;
107
+ system_prompt?: string;
108
+ workspace_mode?: WorkspaceMode;
109
+ skills?: string[];
110
+ }
111
+
112
+ /**
113
+ * Run domain model.
114
+ *
115
+ * A Run represents a single execution attempt of a Task by an Agent.
116
+ * Events are stored in separate .jsonl files (append-only), not in memory.
117
+ */
118
+ type RunStatus = 'preparing' | 'running' | 'succeeded' | 'failed' | 'timed_out' | 'cancelled';
119
+ interface Run {
120
+ id: string;
121
+ task_id: string;
122
+ agent_id: string;
123
+ attempt: number;
124
+ status: RunStatus;
125
+ started_at: string;
126
+ finished_at?: string;
127
+ workspace_path: string;
128
+ prompt: string;
129
+ pid?: number;
130
+ error?: string;
131
+ tokens?: TokenUsage;
132
+ }
133
+ interface TokenUsage {
134
+ input: number;
135
+ output: number;
136
+ total: number;
137
+ }
138
+ /** Create TokenUsage with total always computed as input + output. */
139
+ declare function createTokenUsage(input: number, output: number): TokenUsage;
140
+ interface RunEvent {
141
+ timestamp: string;
142
+ type: RunEventType;
143
+ data: unknown;
144
+ }
145
+ type RunEventType = 'agent_output' | 'file_changed' | 'command_run' | 'tool_call' | 'error' | 'done';
146
+
147
+ /**
148
+ * Configuration domain model.
149
+ *
150
+ * Represents the structure of .orchestry/config.yml
151
+ */
152
+
153
+ interface ProjectConfig {
154
+ name: string;
155
+ description?: string;
156
+ }
157
+ interface AgentDefaults {
158
+ adapter: string;
159
+ approval_policy: ApprovalPolicy;
160
+ max_turns: number;
161
+ timeout_ms: number;
162
+ stall_timeout_ms: number;
163
+ workspace_mode: WorkspaceMode;
164
+ }
165
+ interface TaskDefaults {
166
+ max_attempts: number;
167
+ priority: number;
168
+ }
169
+ interface SchedulingConfig {
170
+ poll_interval_ms: number;
171
+ max_concurrent_agents: number;
172
+ retry_base_delay_ms: number;
173
+ retry_max_delay_ms: number;
174
+ }
175
+ interface OrchestratorConfig {
176
+ project: ProjectConfig;
177
+ defaults: {
178
+ agent: AgentDefaults;
179
+ task: TaskDefaults;
180
+ };
181
+ scheduling: SchedulingConfig;
182
+ prompt?: {
183
+ template?: string;
184
+ };
185
+ }
186
+
187
+ /**
188
+ * Orchestrator runtime state.
189
+ *
190
+ * Persisted in .orchestry/state.json.
191
+ * Updated on every mutation. Not intended for git.
192
+ */
193
+ interface RunningEntry {
194
+ run_id: string;
195
+ agent_id: string;
196
+ task_id: string;
197
+ pid: number;
198
+ started_at: string;
199
+ last_event_at: string;
200
+ }
201
+ interface RetryEntry {
202
+ task_id: string;
203
+ attempt: number;
204
+ due_at: string;
205
+ error: string;
206
+ }
207
+ interface OrchestratorState {
208
+ version: 1;
209
+ pid?: number;
210
+ started_at?: string;
211
+ running: Record<string, RunningEntry>;
212
+ claimed: string[];
213
+ retry_queue: RetryEntry[];
214
+ stats: {
215
+ total_runs: number;
216
+ total_tasks_completed: number;
217
+ total_tasks_failed: number;
218
+ total_tokens: {
219
+ input: number;
220
+ output: number;
221
+ total: number;
222
+ };
223
+ total_runtime_ms: number;
224
+ };
225
+ }
226
+
227
+ /**
228
+ * Goal domain model.
229
+ *
230
+ * A Goal is a persistent objective that drives autonomous agent work.
231
+ * Goals have lower priority than tasks — agents work on goals only
232
+ * when no regular tasks are available.
233
+ *
234
+ * State machine: active → achieved | abandoned
235
+ * active ↔ paused
236
+ */
237
+ declare const GOAL_STATUSES: readonly ["active", "paused", "achieved", "abandoned"];
238
+ type GoalStatus = (typeof GOAL_STATUSES)[number];
239
+ interface Goal {
240
+ id: string;
241
+ title: string;
242
+ description: string;
243
+ status: GoalStatus;
244
+ assignee?: string;
245
+ created_at: string;
246
+ updated_at?: string;
247
+ }
248
+ interface CreateGoalInput {
249
+ title: string;
250
+ description?: string;
251
+ assignee?: string;
252
+ }
253
+
254
+ /**
255
+ * Message domain model.
256
+ *
257
+ * A Message is a unit of inter-agent communication.
258
+ * Messages are stored as JSON files and injected into agent prompts at dispatch time.
259
+ */
260
+ type MessageChannel = 'direct' | 'broadcast' | 'lead';
261
+ type MessageStatus = 'pending' | 'delivered' | 'expired';
262
+ interface Message {
263
+ id: string;
264
+ channel: MessageChannel;
265
+ from_agent_id: string;
266
+ to_agent_id: string | null;
267
+ subject: string;
268
+ body: string;
269
+ created_at: string;
270
+ expires_at?: string;
271
+ status: MessageStatus;
272
+ delivered_at?: string;
273
+ team_id?: string;
274
+ reply_to?: string;
275
+ }
276
+ interface CreateMessageInput {
277
+ channel: MessageChannel;
278
+ from_agent_id: string;
279
+ to_agent_id?: string;
280
+ subject: string;
281
+ body: string;
282
+ ttl_ms?: number;
283
+ team_id?: string;
284
+ reply_to?: string;
285
+ }
286
+
287
+ /**
288
+ * Orchestrator event system.
289
+ *
290
+ * All communication between layers goes through typed events.
291
+ * The EventBus emits these synchronously; subscribers (TUI, logger,
292
+ * run store, state) react independently.
293
+ */
294
+
295
+ type OrchestratorEvent = {
296
+ type: 'task:created';
297
+ task: Task;
298
+ } | {
299
+ type: 'task:assigned';
300
+ taskId: string;
301
+ agentId: string;
302
+ } | {
303
+ type: 'task:status_changed';
304
+ taskId: string;
305
+ from: TaskStatus;
306
+ to: TaskStatus;
307
+ } | {
308
+ type: 'task:auto_reviewed';
309
+ taskId: string;
310
+ passed: boolean;
311
+ results: ReviewResult[];
312
+ } | {
313
+ type: 'agent:started';
314
+ agentId: string;
315
+ taskId: string;
316
+ runId: string;
317
+ } | {
318
+ type: 'agent:output';
319
+ runId: string;
320
+ agentId: string;
321
+ data: string;
322
+ } | {
323
+ type: 'agent:file_changed';
324
+ runId: string;
325
+ agentId: string;
326
+ path: string;
327
+ } | {
328
+ type: 'agent:completed';
329
+ runId: string;
330
+ agentId: string;
331
+ success: boolean;
332
+ } | {
333
+ type: 'agent:error';
334
+ runId: string;
335
+ agentId: string;
336
+ error: string;
337
+ } | {
338
+ type: 'run:retry';
339
+ runId: string;
340
+ attempt: number;
341
+ delay_ms: number;
342
+ } | {
343
+ type: 'orchestrator:tick';
344
+ running: number;
345
+ queued: number;
346
+ } | {
347
+ type: 'orchestrator:stall_detected';
348
+ runId: string;
349
+ } | {
350
+ type: 'task:scope_overlap';
351
+ taskId: string;
352
+ overlappingTaskId: string;
353
+ patterns: string[];
354
+ } | {
355
+ type: 'workspace:merge_succeeded';
356
+ taskId: string;
357
+ branch: string;
358
+ } | {
359
+ type: 'workspace:merge_conflict';
360
+ taskId: string;
361
+ branch: string;
362
+ conflictInfo: string;
363
+ } | {
364
+ type: 'task:orphaned';
365
+ taskId: string;
366
+ } | {
367
+ type: 'orchestrator:error';
368
+ error: string;
369
+ context: string;
370
+ fatal: boolean;
371
+ } | {
372
+ type: 'orchestrator:shutdown';
373
+ reason: string;
374
+ } | {
375
+ type: 'message:sent';
376
+ messageId: string;
377
+ fromAgentId: string;
378
+ toAgentId: string | null;
379
+ channel: MessageChannel;
380
+ } | {
381
+ type: 'message:delivered';
382
+ messageId: string;
383
+ toAgentId: string;
384
+ taskId: string;
385
+ } | {
386
+ type: 'team:created';
387
+ teamId: string;
388
+ name: string;
389
+ leadAgentId: string;
390
+ } | {
391
+ type: 'team:member_joined';
392
+ teamId: string;
393
+ agentId: string;
394
+ } | {
395
+ type: 'team:member_left';
396
+ teamId: string;
397
+ agentId: string;
398
+ } | {
399
+ type: 'team:task_claimed';
400
+ teamId: string;
401
+ taskId: string;
402
+ agentId: string;
403
+ } | {
404
+ type: 'team:disbanded';
405
+ teamId: string;
406
+ } | {
407
+ type: 'team:task_added';
408
+ teamId: string;
409
+ taskId: string;
410
+ } | {
411
+ type: 'agent:autonomous_toggled';
412
+ agentId: string;
413
+ autonomous: boolean;
414
+ } | {
415
+ type: 'goal:created';
416
+ goalId: string;
417
+ title: string;
418
+ } | {
419
+ type: 'goal:status_changed';
420
+ goalId: string;
421
+ from: GoalStatus;
422
+ to: GoalStatus;
423
+ } | {
424
+ type: 'goal:updated';
425
+ goalId: string;
426
+ } | {
427
+ type: 'goal:deleted';
428
+ goalId: string;
429
+ };
430
+ type OrchestratorEventType = OrchestratorEvent['type'];
431
+ /**
432
+ * Extract event payload by type discriminator.
433
+ */
434
+ type EventPayload<T extends OrchestratorEventType> = Extract<OrchestratorEvent, {
435
+ type: T;
436
+ }>;
437
+
438
+ /**
439
+ * Typed error hierarchy for the orchestrator.
440
+ *
441
+ * Every error carries an exit code (matching CLI_UI_DESIGN.md §11)
442
+ * and an optional hint for the user.
443
+ *
444
+ * Exit codes:
445
+ * 0 - Success
446
+ * 1 - General error
447
+ * 2 - Invalid arguments
448
+ * 3 - Not initialized (.orchestry/ not found)
449
+ * 4 - Lock conflict (orchestrator already running)
450
+ * 5 - Agent error (adapter test failed)
451
+ */
452
+ declare class OrchestryError extends Error {
453
+ readonly exitCode: number;
454
+ readonly hint?: string | undefined;
455
+ constructor(message: string, exitCode: number, hint?: string | undefined);
456
+ }
457
+ declare class NotInitializedError extends OrchestryError {
458
+ constructor();
459
+ }
460
+ declare class TaskNotFoundError extends OrchestryError {
461
+ constructor(taskId: string);
462
+ }
463
+ declare class AgentNotFoundError extends OrchestryError {
464
+ constructor(agentId: string);
465
+ }
466
+
467
+ /**
468
+ * Task state machine — pure functions, no side effects.
469
+ *
470
+ * State diagram:
471
+ * todo → in_progress → review → done
472
+ * ↘ retrying → in_progress
473
+ * ↘ failed (max attempts)
474
+ * review → todo (rejected)
475
+ * * → cancelled
476
+ * failed → todo | retrying (manual reactivation)
477
+ * cancelled → todo (manual reactivation)
478
+ *
479
+ * Terminal statuses (done, failed, cancelled) are not auto-dispatched
480
+ * by the orchestrator but may have manual outgoing transitions.
481
+ */
482
+
483
+ /**
484
+ * Check if a status transition is valid.
485
+ */
486
+ declare function canTransition(from: TaskStatus, to: TaskStatus): boolean;
487
+ /**
488
+ * Check if a task status is terminal — the orchestrator will not
489
+ * auto-dispatch or retry it. Terminal tasks may still have valid
490
+ * manual transitions (e.g. cancelled → todo, failed → todo).
491
+ */
492
+ declare function isTerminal(status: TaskStatus): boolean;
493
+ /**
494
+ * Check if a task can be dispatched (ready for execution).
495
+ */
496
+ declare function isDispatchable(status: TaskStatus): boolean;
497
+ /**
498
+ * Check if a task is blocked by unfinished dependencies.
499
+ */
500
+ declare function isBlocked(task: Task, allTasks: Task[]): boolean;
501
+ /**
502
+ * Determine the next status after a task failure (run error or shutdown).
503
+ * Returns 'retrying' if attempts remain, 'failed' otherwise.
504
+ */
505
+ declare function resolveFailureStatus(task: Task): TaskStatus;
506
+
507
+ /**
508
+ * Typed event bus.
509
+ *
510
+ * The single communication channel between all layers.
511
+ * Synchronous emit — handlers run inline.
512
+ * TUI, logger, run store, state all subscribe independently.
513
+ */
514
+
515
+ type Handler<T> = (event: T) => void;
516
+ declare class EventBus {
517
+ private handlers;
518
+ private wildcardHandlers;
519
+ private maxListeners;
520
+ private warnedTypes;
521
+ /**
522
+ * Set the maximum number of listeners per event type before a warning is emitted.
523
+ * Helps detect memory leaks from repeated subscriptions in watch mode.
524
+ */
525
+ setMaxListeners(n: number): void;
526
+ getMaxListeners(): number;
527
+ /**
528
+ * Get the number of listeners for a specific event type.
529
+ */
530
+ listenerCount(type: OrchestratorEventType): number;
531
+ /**
532
+ * Subscribe to events of a specific type.
533
+ * Returns an unsubscribe function.
534
+ */
535
+ on<T extends OrchestratorEventType>(type: T, handler: Handler<EventPayload<T>>): () => void;
536
+ /**
537
+ * Subscribe to an event type, auto-unsubscribe after first call.
538
+ */
539
+ once<T extends OrchestratorEventType>(type: T, handler: Handler<EventPayload<T>>): () => void;
540
+ /**
541
+ * Unsubscribe a handler from an event type.
542
+ */
543
+ off<T extends OrchestratorEventType>(type: T, handler: Handler<EventPayload<T>>): void;
544
+ /**
545
+ * Emit an event synchronously to all subscribed handlers.
546
+ */
547
+ emit(event: OrchestratorEvent): void;
548
+ private dispatchToSet;
549
+ /**
550
+ * Subscribe to ALL events regardless of type.
551
+ */
552
+ onAny(handler: Handler<OrchestratorEvent>): () => void;
553
+ /**
554
+ * Remove all handlers.
555
+ */
556
+ clear(): void;
557
+ }
558
+
559
+ /**
560
+ * Team domain model.
561
+ *
562
+ * A Team groups agents with a lead for coordinated work.
563
+ * Teams share a task pool and enable broadcast messaging.
564
+ */
565
+ type TeamStatus = 'active' | 'paused' | 'disbanded';
566
+ interface TeamMember {
567
+ agent_id: string;
568
+ role: 'lead' | 'member';
569
+ joined_at: string;
570
+ }
571
+ interface Team {
572
+ id: string;
573
+ name: string;
574
+ description?: string;
575
+ status: TeamStatus;
576
+ members: TeamMember[];
577
+ task_pool: string[];
578
+ lead_agent_id: string;
579
+ created_at: string;
580
+ updated_at: string;
581
+ config: TeamConfig;
582
+ }
583
+ interface TeamConfig {
584
+ max_concurrent_tasks?: number;
585
+ auto_claim: boolean;
586
+ message_ttl_ms?: number;
587
+ }
588
+ interface CreateTeamInput {
589
+ name: string;
590
+ description?: string;
591
+ lead_agent_id: string;
592
+ member_agent_ids?: string[];
593
+ config?: Partial<TeamConfig>;
594
+ }
595
+
596
+ /**
597
+ * Storage layer interfaces.
598
+ *
599
+ * All persistence goes through these contracts.
600
+ * Implementations use atomic file writes (temp → rename).
601
+ * Services depend on interfaces, not concrete stores.
602
+ */
603
+
604
+ interface ITaskStore {
605
+ list(filter?: {
606
+ status?: TaskStatus;
607
+ }): Promise<Task[]>;
608
+ get(id: string): Promise<Task | null>;
609
+ save(task: Task): Promise<void>;
610
+ delete(id: string): Promise<void>;
611
+ }
612
+ interface IAgentStore {
613
+ list(): Promise<Agent[]>;
614
+ get(id: string): Promise<Agent | null>;
615
+ getByName(name: string): Promise<Agent | null>;
616
+ save(agent: Agent): Promise<void>;
617
+ delete(id: string): Promise<void>;
618
+ }
619
+ interface IRunStore {
620
+ save(run: Run): Promise<void>;
621
+ get(id: string): Promise<Run | null>;
622
+ listAll(): Promise<Run[]>;
623
+ listForTask(taskId: string): Promise<Run[]>;
624
+ listForAgent(agentId: string): Promise<Run[]>;
625
+ appendEvent(runId: string, event: RunEvent): Promise<void>;
626
+ readEvents(runId: string): Promise<RunEvent[]>;
627
+ readEventsTail(runId: string, count: number): Promise<RunEvent[]>;
628
+ streamEvents(runId: string, signal?: AbortSignal): AsyncGenerator<RunEvent>;
629
+ }
630
+ interface IStateStore {
631
+ read(): Promise<OrchestratorState>;
632
+ write(state: OrchestratorState): Promise<void>;
633
+ }
634
+ interface IConfigStore {
635
+ read(): Promise<OrchestratorConfig>;
636
+ write(config: OrchestratorConfig): Promise<void>;
637
+ get(keyPath: string): Promise<unknown>;
638
+ set(keyPath: string, value: unknown): Promise<void>;
639
+ }
640
+ interface ContextEntry {
641
+ key: string;
642
+ value: string;
643
+ created_at: string;
644
+ updated_at: string;
645
+ ttl_ms?: number;
646
+ expires_at?: string;
647
+ }
648
+ interface IContextStore {
649
+ get(key: string): Promise<ContextEntry | null>;
650
+ set(key: string, value: string, ttlMs?: number): Promise<void>;
651
+ delete(key: string): Promise<void>;
652
+ list(): Promise<ContextEntry[]>;
653
+ getAll(): Promise<Record<string, string>>;
654
+ }
655
+ interface IMessageStore {
656
+ save(message: Message): Promise<void>;
657
+ get(id: string): Promise<Message | null>;
658
+ list(): Promise<Message[]>;
659
+ listPending(agentId: string): Promise<Message[]>;
660
+ markDelivered(id: string): Promise<void>;
661
+ delete(id: string): Promise<void>;
662
+ purgeExpired(): Promise<number>;
663
+ }
664
+ interface IGoalStore {
665
+ list(filter?: {
666
+ status?: GoalStatus;
667
+ }): Promise<Goal[]>;
668
+ get(id: string): Promise<Goal | null>;
669
+ save(goal: Goal): Promise<void>;
670
+ delete(id: string): Promise<void>;
671
+ }
672
+ interface ITeamStore {
673
+ save(team: Team): Promise<void>;
674
+ get(id: string): Promise<Team | null>;
675
+ getByName(name: string): Promise<Team | null>;
676
+ list(): Promise<Team[]>;
677
+ delete(id: string): Promise<void>;
678
+ }
679
+
680
+ /**
681
+ * Task service — business logic for task lifecycle.
682
+ *
683
+ * Validates state transitions, emits events, manages CRUD.
684
+ * CLI commands call this service, not storage directly.
685
+ */
686
+
687
+ declare class TaskService {
688
+ private readonly taskStore;
689
+ private readonly eventBus;
690
+ private readonly config;
691
+ constructor(taskStore: ITaskStore, eventBus: EventBus, config: OrchestratorConfig);
692
+ create(input: CreateTaskInput): Promise<Task>;
693
+ list(filter?: {
694
+ status?: TaskStatus;
695
+ }): Promise<Task[]>;
696
+ get(id: string): Promise<Task>;
697
+ updateStatus(id: string, newStatus: TaskStatus): Promise<Task>;
698
+ assign(taskId: string, agentId: string): Promise<Task>;
699
+ cancel(id: string): Promise<Task>;
700
+ retry(id: string): Promise<Task>;
701
+ reject(id: string, feedback?: string): Promise<Task>;
702
+ update(id: string, fields: {
703
+ title?: string;
704
+ description?: string;
705
+ priority?: number;
706
+ labels?: string[];
707
+ }): Promise<Task>;
708
+ delete(id: string): Promise<void>;
709
+ incrementAttempts(id: string): Promise<Task>;
710
+ }
711
+
712
+ /**
713
+ * Agent service — business logic for agent lifecycle.
714
+ *
715
+ * Manages agent CRUD, availability, and task assignment matching.
716
+ */
717
+
718
+ declare class AgentService {
719
+ private readonly agentStore;
720
+ private readonly stateStore;
721
+ private readonly eventBus;
722
+ private readonly config;
723
+ constructor(agentStore: IAgentStore, stateStore: IStateStore, eventBus: EventBus, config: OrchestratorConfig);
724
+ create(input: CreateAgentInput): Promise<Agent>;
725
+ list(): Promise<Agent[]>;
726
+ get(id: string): Promise<Agent>;
727
+ remove(id: string): Promise<void>;
728
+ update(id: string, fields: {
729
+ name?: string;
730
+ role?: string;
731
+ model?: string;
732
+ approval_policy?: Agent['config']['approval_policy'];
733
+ }): Promise<Agent>;
734
+ disable(id: string): Promise<Agent>;
735
+ enable(id: string): Promise<Agent>;
736
+ setAutonomous(id: string, enabled: boolean): Promise<Agent>;
737
+ setStatus(id: string, status: AgentStatus): Promise<Agent>;
738
+ updateStats(id: string, update: Partial<Agent['stats']>): Promise<Agent>;
739
+ /**
740
+ * Find the best available agent for a task using scoring.
741
+ *
742
+ * Scoring:
743
+ * - Explicit assignee match = 100
744
+ * - Skill match with task labels = 50 per match
745
+ * - Role match with task labels = 30
746
+ * - Idle status bonus = 20
747
+ * - Success rate bonus = 0–10 (scaled by completed / total)
748
+ */
749
+ findBestAgent(task: Task): Promise<Agent | null>;
750
+ }
751
+
752
+ /**
753
+ * Run service — manages run lifecycle and event streaming.
754
+ */
755
+
756
+ declare class RunService {
757
+ private readonly runStore;
758
+ private readonly eventBus;
759
+ constructor(runStore: IRunStore, eventBus: EventBus);
760
+ create(params: {
761
+ taskId: string;
762
+ agentId: string;
763
+ attempt: number;
764
+ prompt: string;
765
+ workspacePath: string;
766
+ }): Promise<Run>;
767
+ get(id: string): Promise<Run | null>;
768
+ start(id: string, pid: number): Promise<Run>;
769
+ finish(id: string, status: RunStatus, tokens?: TokenUsage, error?: string): Promise<Run>;
770
+ appendEvent(runId: string, event: RunEvent): Promise<void>;
771
+ listAll(): Promise<Run[]>;
772
+ listForTask(taskId: string): Promise<Run[]>;
773
+ listForAgent(agentId: string): Promise<Run[]>;
774
+ readEvents(runId: string): Promise<RunEvent[]>;
775
+ readEventsTail(runId: string, count: number): Promise<RunEvent[]>;
776
+ /**
777
+ * Get error and last N lines of output from the most recent failed run for a task.
778
+ * Used to provide retry context so agents can learn from previous failures.
779
+ */
780
+ getLastFailedRunContext(taskId: string, maxOutputLines?: number): Promise<{
781
+ error: string;
782
+ output: string;
783
+ } | null>;
784
+ }
785
+
786
+ /**
787
+ * MessageService — business logic for inter-agent messaging.
788
+ *
789
+ * Handles message creation, routing (direct/broadcast/lead),
790
+ * delivery into agent prompts, and cleanup of expired messages.
791
+ */
792
+
793
+ declare class MessageService {
794
+ private readonly messageStore;
795
+ private readonly agentStore;
796
+ private readonly teamStore;
797
+ private readonly eventBus;
798
+ constructor(messageStore: IMessageStore, agentStore: IAgentStore, teamStore: ITeamStore, eventBus: EventBus);
799
+ /**
800
+ * Send a message. For broadcast, creates one message per recipient agent.
801
+ * For 'lead' channel, resolves team lead and sends direct.
802
+ */
803
+ send(input: CreateMessageInput): Promise<Message[]>;
804
+ /**
805
+ * Drain mailbox: fetch pending messages for an agent and mark them delivered.
806
+ * Called by the orchestrator during dispatchTask.
807
+ */
808
+ drainMailbox(agentId: string, taskId: string): Promise<Message[]>;
809
+ listAll(): Promise<Message[]>;
810
+ listPendingForAgent(agentId: string): Promise<Message[]>;
811
+ listForAgent(agentId: string): Promise<Message[]>;
812
+ purgeExpired(): Promise<number>;
813
+ private emitSent;
814
+ }
815
+
816
+ /**
817
+ * Agent adapter interface.
818
+ *
819
+ * Every AI tool (Claude, Codex, Shell, etc.) implements this contract.
820
+ * execute() returns an AsyncGenerator for pull-based streaming of events.
821
+ */
822
+
823
+ interface AdapterTestResult {
824
+ ok: boolean;
825
+ version?: string;
826
+ error?: string;
827
+ details?: Record<string, unknown>;
828
+ }
829
+ interface ExecuteParams {
830
+ prompt: string;
831
+ workspace: string;
832
+ env?: Record<string, string>;
833
+ config: AgentConfig;
834
+ signal?: AbortSignal;
835
+ }
836
+ interface AgentEvent {
837
+ type: 'output' | 'file_change' | 'command' | 'tool_call' | 'error' | 'done';
838
+ timestamp: string;
839
+ data: unknown;
840
+ tokens?: {
841
+ input: number;
842
+ output: number;
843
+ total: number;
844
+ };
845
+ }
846
+ interface ExecuteHandle {
847
+ pid: number;
848
+ events: AsyncGenerator<AgentEvent>;
849
+ }
850
+ interface IAgentAdapter {
851
+ readonly kind: string;
852
+ test(): Promise<AdapterTestResult>;
853
+ execute(params: ExecuteParams): ExecuteHandle;
854
+ stop(pid: number): Promise<void>;
855
+ }
856
+
857
+ /**
858
+ * Adapter registry.
859
+ *
860
+ * Maps adapter kind strings to adapter instances.
861
+ * Pre-populated at startup in the container.
862
+ */
863
+
864
+ declare class AdapterRegistry {
865
+ private readonly adapters;
866
+ register(adapter: IAgentAdapter): void;
867
+ get(kind: string): IAgentAdapter | undefined;
868
+ require(kind: string): IAgentAdapter;
869
+ list(): IAgentAdapter[];
870
+ listKinds(): string[];
871
+ has(kind: string): boolean;
872
+ }
873
+
874
+ /**
875
+ * Process management utilities.
876
+ *
877
+ * Handles spawning subprocesses, PID checks, graceful kill.
878
+ */
879
+
880
+ interface SpawnResult {
881
+ process: ChildProcess;
882
+ pid: number;
883
+ }
884
+ interface IProcessManager {
885
+ isAlive(pid: number): boolean;
886
+ kill(pid: number, signal?: NodeJS.Signals): void;
887
+ killWithGrace(pid: number, graceMs?: number): Promise<void>;
888
+ spawn(command: string, args: string[], options?: SpawnOptions): SpawnResult;
889
+ }
890
+
891
+ /**
892
+ * Git merge strategy for worktree branches.
893
+ *
894
+ * Encapsulates `git merge --no-ff` execution and conflict handling.
895
+ */
896
+
897
+ type MergeResult = {
898
+ success: true;
899
+ } | {
900
+ success: false;
901
+ conflictInfo: string;
902
+ };
903
+
904
+ /**
905
+ * Workspace manager interface.
906
+ */
907
+
908
+ interface PrepareResult {
909
+ path: string;
910
+ branch?: string;
911
+ }
912
+ interface IWorkspaceManager {
913
+ prepare(task: Task, agent: Agent, config: OrchestratorConfig): Promise<PrepareResult>;
914
+ mergeBack(branch: string): Promise<MergeResult>;
915
+ cleanup(taskId: string): Promise<void>;
916
+ validate(workspacePath: string, projectRoot: string): void;
917
+ }
918
+
919
+ interface ITemplateEngine {
920
+ render(template: string, context: PromptContext): Promise<string>;
921
+ }
922
+ interface AgentInfo {
923
+ id: string;
924
+ name: string;
925
+ role?: string;
926
+ adapter: string;
927
+ }
928
+ interface RetryContext {
929
+ previous_error: string;
930
+ previous_output: string;
931
+ }
932
+ interface PromptContext {
933
+ project: {
934
+ name: string;
935
+ description?: string;
936
+ };
937
+ task: {
938
+ id: string;
939
+ title: string;
940
+ description: string;
941
+ priority: number;
942
+ labels: string[];
943
+ scope?: string[];
944
+ is_autonomous: boolean;
945
+ };
946
+ agent: {
947
+ id: string;
948
+ name: string;
949
+ role?: string;
950
+ };
951
+ agents: AgentInfo[];
952
+ attempt: number | null;
953
+ workspace_path: string;
954
+ retry?: RetryContext;
955
+ feedback?: string;
956
+ shared_context?: Record<string, string>;
957
+ messages?: Array<{
958
+ id: string;
959
+ from: string;
960
+ subject: string;
961
+ body: string;
962
+ sent_at: string;
963
+ reply_to?: string;
964
+ }>;
965
+ }
966
+
967
+ interface OrchestratorDeps {
968
+ taskStore: ITaskStore;
969
+ agentStore: IAgentStore;
970
+ runStore: IRunStore;
971
+ stateStore: IStateStore;
972
+ adapterRegistry: AdapterRegistry;
973
+ workspaceManager: IWorkspaceManager;
974
+ templateEngine: ITemplateEngine;
975
+ processManager: IProcessManager;
976
+ eventBus: EventBus;
977
+ taskService: TaskService;
978
+ agentService: AgentService;
979
+ runService: RunService;
980
+ contextStore?: IContextStore;
981
+ messageService?: MessageService;
982
+ goalStore?: IGoalStore;
983
+ config: OrchestratorConfig;
984
+ projectRoot: string;
985
+ lockPath: string;
986
+ }
987
+ declare class Orchestrator {
988
+ private readonly deps;
989
+ private intervalId;
990
+ private shuttingDown;
991
+ private state;
992
+ private abortControllers;
993
+ private readonly cachedTaskStore;
994
+ private readonly cachedAgentStore;
995
+ private readonly cachedGoalStore;
996
+ private saveStateTimer;
997
+ private saveStateDirty;
998
+ private lockAcquired;
999
+ private consecutiveTickFailures;
1000
+ private readonly maxConsecutiveTickFailures;
1001
+ private readonly maxRetryQueueSize;
1002
+ private signalHandlers;
1003
+ private immediateDispatchTimer;
1004
+ private taskCreatedUnsub;
1005
+ private tickInProgress;
1006
+ /** Promise-chain mutex to serialize critical state mutations. */
1007
+ private stateMutex;
1008
+ constructor(deps: OrchestratorDeps);
1009
+ /**
1010
+ * Check if this instance owns the lock (can mutate state).
1011
+ */
1012
+ get isOwner(): boolean;
1013
+ /**
1014
+ * Serialize access to state mutations via a Promise-chain mutex.
1015
+ * Prevents concurrent tick/stop/reconcile from reading stale state.
1016
+ */
1017
+ private withStateLock;
1018
+ /**
1019
+ * Run a single task by ID. Acquires lock for the duration of the run.
1020
+ */
1021
+ runTask(taskId: string): Promise<void>;
1022
+ /**
1023
+ * Run all dispatchable tasks. Acquires lock for the duration of the run.
1024
+ */
1025
+ runAll(): Promise<void>;
1026
+ /**
1027
+ * Acquire lock, run fn, then release lock.
1028
+ * Used by single-shot commands (runTask, runAll) that don't go through startWatch.
1029
+ */
1030
+ private withTemporaryLock;
1031
+ /**
1032
+ * Start watch mode — continuous tick loop.
1033
+ * Acquires a PID lock to prevent multiple orchestrators.
1034
+ */
1035
+ startWatch(): Promise<void>;
1036
+ /**
1037
+ * Register SIGINT/SIGTERM handlers for graceful shutdown.
1038
+ */
1039
+ private registerSignalHandlers;
1040
+ /**
1041
+ * Remove signal handlers to avoid listener leaks.
1042
+ */
1043
+ private removeSignalHandlers;
1044
+ /**
1045
+ * Stop the watch loop and clean up.
1046
+ */
1047
+ stop(): Promise<void>;
1048
+ /**
1049
+ * Cancel a running task: kill agent process, clean state, mark cancelled.
1050
+ * Acquires lock if not already owned (standalone CLI invocation).
1051
+ */
1052
+ cancelTask(taskId: string): Promise<void>;
1053
+ /**
1054
+ * Force-stop a specific agent: kill process, clean state, release agent.
1055
+ * Acquires lock if not already owned (standalone CLI invocation).
1056
+ */
1057
+ forceStopAgent(agentId: string): Promise<void>;
1058
+ /**
1059
+ * Single tick: Reconcile → Dispatch → Collect
1060
+ * Serialized via mutex to prevent concurrent ticks from racing on state.
1061
+ */
1062
+ private tick;
1063
+ /**
1064
+ * Schedule an immediate dispatch with 500ms debounce.
1065
+ * Called on task:created to avoid waiting for the next 30s tick.
1066
+ */
1067
+ private scheduleImmediateDispatch;
1068
+ /**
1069
+ * Mini-tick: invalidate caches → loadState → dispatchAll → saveState.
1070
+ * Skips reconcile/collect — only dispatches new tasks immediately.
1071
+ */
1072
+ private immediateDispatch;
1073
+ /**
1074
+ * Reconcile: check PID liveness, detect stalls, process retry queue.
1075
+ */
1076
+ private reconcile;
1077
+ /**
1078
+ * Create tasks for autonomous agents that have no active work.
1079
+ *
1080
+ * Priority: active Goals assigned to the agent come first.
1081
+ * If no goals, falls back to role-based autonomous work.
1082
+ */
1083
+ private seedAutonomousTasks;
1084
+ /**
1085
+ * Dispatch all dispatchable tasks up to max_concurrent_agents.
1086
+ */
1087
+ private dispatchAll;
1088
+ /**
1089
+ * Dispatch a single task: claim → assign → execute.
1090
+ */
1091
+ private dispatchTask;
1092
+ /**
1093
+ * Collect events from an adapter's async generator.
1094
+ */
1095
+ private collectEvents;
1096
+ private handleRunSuccess;
1097
+ private _handleRunSuccess;
1098
+ private handleRunFailure;
1099
+ private _handleRunFailure;
1100
+ /**
1101
+ * Run automatic review criteria on a task in 'review' status.
1102
+ * If all criteria pass, transition review → done.
1103
+ * If any fail, stay in review with results attached.
1104
+ */
1105
+ private runAutoReview;
1106
+ /**
1107
+ * Force a task to 'review' status with a summary prefix.
1108
+ * Used when merge-back fails (conflict or infrastructure error).
1109
+ */
1110
+ private forceTaskToReview;
1111
+ private unclaim;
1112
+ /**
1113
+ * Throw if this instance doesn't own the lock (read-only session).
1114
+ */
1115
+ private requireOwnership;
1116
+ private loadState;
1117
+ private saveState;
1118
+ /**
1119
+ * Debounced saveState — batches rapid writes within 500ms window.
1120
+ * Used for non-critical updates like last_event_at in collectEvents.
1121
+ */
1122
+ private saveStateLazy;
1123
+ /**
1124
+ * Flush any pending debounced saveState immediately.
1125
+ * Call before critical transitions to ensure state is persisted.
1126
+ */
1127
+ private flushStateLazy;
1128
+ }
1129
+
1130
+ /**
1131
+ * CLI context — resolved project root and global flags.
1132
+ *
1133
+ * Validated at entry point before any command runs.
1134
+ */
1135
+ interface CliContext {
1136
+ projectRoot: string;
1137
+ json: boolean;
1138
+ quiet: boolean;
1139
+ noColor: boolean;
1140
+ ascii: boolean;
1141
+ }
1142
+
1143
+ /**
1144
+ * Global configuration — persists across projects.
1145
+ *
1146
+ * Stored at ~/.orchestry/global.yml
1147
+ */
1148
+ /** Activity feed filter preset name */
1149
+ type ActivityFilterPreset = 'all' | 'text' | 'tools' | 'errors' | 'events';
1150
+ interface TuiPreferences {
1151
+ activity_filter: ActivityFilterPreset;
1152
+ }
1153
+ interface GlobalConfig {
1154
+ tui: TuiPreferences;
1155
+ }
1156
+
1157
+ /**
1158
+ * Path resolution for .orchestry/ directory.
1159
+ *
1160
+ * All path construction goes through this module.
1161
+ * Validates initialization state and sanitizes identifiers.
1162
+ */
1163
+ declare class Paths {
1164
+ private readonly projectRoot;
1165
+ constructor(projectRoot: string);
1166
+ /** Root .orchestry/ directory */
1167
+ get root(): string;
1168
+ get configPath(): string;
1169
+ get statePath(): string;
1170
+ get lockPath(): string;
1171
+ get tasksDir(): string;
1172
+ get agentsDir(): string;
1173
+ get runsDir(): string;
1174
+ get templatesDir(): string;
1175
+ get logsDir(): string;
1176
+ get contextDir(): string;
1177
+ contextPath(key: string): string;
1178
+ get messagesDir(): string;
1179
+ messagePath(id: string): string;
1180
+ get goalsDir(): string;
1181
+ goalPath(id: string): string;
1182
+ get teamsDir(): string;
1183
+ teamPath(id: string): string;
1184
+ get gitignorePath(): string;
1185
+ get workspaceExcludePath(): string;
1186
+ taskPath(id: string): string;
1187
+ agentPath(id: string): string;
1188
+ runPath(id: string): string;
1189
+ runEventsPath(id: string): string;
1190
+ defaultTemplatePath(): string;
1191
+ isInitialized(): Promise<boolean>;
1192
+ requireInit(): Promise<void>;
1193
+ }
1194
+
1195
+ /**
1196
+ * Global config store — reads/writes ~/.orchestry/global.yml
1197
+ *
1198
+ * Persists across projects. Creates directory if needed.
1199
+ */
1200
+
1201
+ declare class GlobalConfigStore {
1202
+ read(): Promise<GlobalConfig>;
1203
+ write(config: GlobalConfig): Promise<void>;
1204
+ set<K extends keyof GlobalConfig['tui']>(key: K, value: GlobalConfig['tui'][K]): Promise<void>;
1205
+ }
1206
+
1207
+ /**
1208
+ * Goal service — business logic for goal lifecycle.
1209
+ *
1210
+ * Goals are persistent objectives that drive autonomous agent work.
1211
+ * State machine: active → achieved | abandoned
1212
+ * active ↔ paused
1213
+ *
1214
+ * Side effect: assigning an agent to a goal auto-enables autonomous mode;
1215
+ * removing the last active goal from an agent auto-disables it.
1216
+ */
1217
+
1218
+ declare class GoalService {
1219
+ private readonly goalStore;
1220
+ private readonly eventBus;
1221
+ private readonly agentService?;
1222
+ private readonly taskService?;
1223
+ constructor(goalStore: IGoalStore, eventBus: EventBus, agentService?: AgentService | undefined, taskService?: TaskService | undefined);
1224
+ create(input: CreateGoalInput): Promise<Goal>;
1225
+ list(filter?: {
1226
+ status?: GoalStatus;
1227
+ }): Promise<Goal[]>;
1228
+ get(id: string): Promise<Goal>;
1229
+ updateStatus(id: string, newStatus: GoalStatus): Promise<Goal>;
1230
+ update(id: string, fields: {
1231
+ title?: string;
1232
+ description?: string;
1233
+ assignee?: string;
1234
+ }): Promise<Goal>;
1235
+ delete(id: string): Promise<void>;
1236
+ /** Enable autonomous mode on an agent. */
1237
+ private enableAutonomous;
1238
+ /** Check if an agent has at least one active goal. */
1239
+ private hasActiveGoalsForAgent;
1240
+ /** Cancel dispatchable (todo/retrying) autonomous tasks assigned to the agent. */
1241
+ private cancelPendingAutonomousTasks;
1242
+ /** Disable autonomous if agent has no other active goals. */
1243
+ private maybeDisableAutonomous;
1244
+ }
1245
+
1246
+ /**
1247
+ * TeamService — business logic for team lifecycle.
1248
+ *
1249
+ * Manages team creation, membership, task pool, and self-claiming.
1250
+ */
1251
+
1252
+ declare class TeamService {
1253
+ private readonly teamStore;
1254
+ private readonly agentStore;
1255
+ private readonly taskStore;
1256
+ private readonly eventBus;
1257
+ constructor(teamStore: ITeamStore, agentStore: IAgentStore, taskStore: ITaskStore, eventBus: EventBus);
1258
+ create(input: CreateTeamInput): Promise<Team>;
1259
+ get(id: string): Promise<Team>;
1260
+ list(): Promise<Team[]>;
1261
+ join(teamId: string, agentId: string): Promise<Team>;
1262
+ leave(teamId: string, agentId: string): Promise<Team>;
1263
+ addTask(teamId: string, taskId: string): Promise<Team>;
1264
+ removeTask(teamId: string, taskId: string): Promise<Team>;
1265
+ setLead(teamId: string, agentId: string): Promise<Team>;
1266
+ disband(teamId: string): Promise<void>;
1267
+ /**
1268
+ * Find the team an agent belongs to (if any).
1269
+ */
1270
+ findTeamForAgent(agentId: string): Promise<Team | null>;
1271
+ }
1272
+
1273
+ /**
1274
+ * Doctor service — diagnostics and health checks.
1275
+ *
1276
+ * Checks adapter availability, system dependencies, project state.
1277
+ */
1278
+
1279
+ interface DoctorCheck {
1280
+ name: string;
1281
+ status: 'ok' | 'fail' | 'skip';
1282
+ detail?: string;
1283
+ }
1284
+ interface DoctorReport {
1285
+ checks: DoctorCheck[];
1286
+ adaptersReady: number;
1287
+ adaptersTotal: number;
1288
+ }
1289
+ declare class DoctorService {
1290
+ private readonly adapterRegistry;
1291
+ private readonly processManager;
1292
+ constructor(adapterRegistry: AdapterRegistry, processManager: IProcessManager);
1293
+ runAll(): Promise<DoctorReport>;
1294
+ private checkCommand;
1295
+ }
1296
+
1297
+ /**
1298
+ * Dependency injection container.
1299
+ *
1300
+ * Plain TypeScript object — no framework, no decorators.
1301
+ * Two modes:
1302
+ * - LightContainer: stores + services only (fast, for read-only commands)
1303
+ * - Container: full (+ orchestrator, adapters, template engine)
1304
+ */
1305
+
1306
+ /** Light container — stores + services. No heavy deps (adapters, orchestrator, LiquidJS). */
1307
+ interface LightContainer {
1308
+ context: CliContext;
1309
+ paths: Paths;
1310
+ config: OrchestratorConfig;
1311
+ taskStore: ITaskStore;
1312
+ agentStore: IAgentStore;
1313
+ runStore: IRunStore;
1314
+ stateStore: IStateStore;
1315
+ configStore: IConfigStore;
1316
+ globalConfigStore: GlobalConfigStore;
1317
+ globalConfig: GlobalConfig;
1318
+ contextStore: IContextStore;
1319
+ messageStore: IMessageStore;
1320
+ goalStore: IGoalStore;
1321
+ teamStore: ITeamStore;
1322
+ eventBus: EventBus;
1323
+ taskService: TaskService;
1324
+ agentService: AgentService;
1325
+ runService: RunService;
1326
+ messageService: MessageService;
1327
+ goalService: GoalService;
1328
+ teamService: TeamService;
1329
+ }
1330
+ /** Full container — everything from light + orchestrator, adapters, workspace, template. */
1331
+ interface Container extends LightContainer {
1332
+ processManager: IProcessManager;
1333
+ adapterRegistry: AdapterRegistry;
1334
+ workspaceManager: IWorkspaceManager;
1335
+ templateEngine: ITemplateEngine;
1336
+ doctorService: DoctorService;
1337
+ orchestrator: Orchestrator;
1338
+ }
1339
+ /**
1340
+ * Build a light container (stores + services).
1341
+ * Fast — no ProcessManager, no adapters, no LiquidJS, no Orchestrator.
1342
+ * Used by read-only commands: task, agent, context, msg, goal, team, logs, status, config.
1343
+ */
1344
+ declare function buildLightContainer(context: CliContext): Promise<LightContainer>;
1345
+ /**
1346
+ * Build a full container (light + orchestrator + adapters + template).
1347
+ * Used by: run, tui, doctor.
1348
+ */
1349
+ declare function buildFullContainer(context: CliContext): Promise<Container>;
1350
+ /**
1351
+ * @deprecated Use buildLightContainer or buildFullContainer directly.
1352
+ * Kept for backward compatibility with tests.
1353
+ */
1354
+ declare function buildContainer(context: CliContext): Promise<Container>;
1355
+
1356
+ export { AdapterRegistry, type AdapterTestResult, type Agent, type AgentConfig, type AgentEvent, AgentNotFoundError, AgentService, type AgentStats, type AgentStatus, type ApprovalPolicy, type Container, type CreateAgentInput, type CreateTaskInput, EventBus, type EventPayload, type ExecuteParams, type IAgentAdapter, type LightContainer, NotInitializedError, Orchestrator, type OrchestratorConfig, type OrchestratorEvent, type OrchestratorEventType, type OrchestratorState, OrchestryError, type ProjectConfig, type RetryEntry, type Run, type RunEvent, type RunEventType, RunService, type RunStatus, type RunningEntry, type SchedulingConfig, type Task, TaskNotFoundError, type TaskProof, TaskService, type TaskStatus, type TokenUsage, type WorkspaceMode, buildContainer, buildFullContainer, buildLightContainer, canTransition, createTokenUsage, isBlocked, isDispatchable, isTerminal, resolveFailureStatus };