@oxgeneral/orch 0.2.4 → 0.3.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 (143) hide show
  1. package/dist/App-TW35IULR.js +18 -0
  2. package/dist/agent-FRQKL7YI.js +9 -0
  3. package/dist/{orchestrator-OMU46RCE.js → chunk-2UC4SVJB.js} +190 -53
  4. package/dist/chunk-2UC4SVJB.js.map +1 -0
  5. package/dist/chunk-5AJ4LYO5.js +8 -0
  6. package/dist/{chunk-45K2XID7.js → chunk-6DWHQPTE.js} +2 -1
  7. package/dist/chunk-6DWHQPTE.js.map +1 -0
  8. package/dist/{chunk-POUC4CPC.js → chunk-6MJ7V6VY.js} +2 -2
  9. package/dist/{chunk-HNKJ4IF7.js → chunk-B4JQM4NU.js} +34 -10
  10. package/dist/chunk-B4JQM4NU.js.map +1 -0
  11. package/dist/{chunk-6HENRUYZ.js → chunk-CDFA4IIQ.js} +2 -2
  12. package/dist/chunk-CHRW4CLD.js +2 -0
  13. package/dist/{chunk-VAAOW526.js → chunk-GZ2Q56YZ.js} +2 -2
  14. package/dist/{doctor-service-QEJCE5FK.js → chunk-HMMPM7MF.js} +2 -2
  15. package/dist/{chunk-AELEEEV3.js → chunk-HSBYJ5C5.js} +27 -7
  16. package/dist/chunk-HXOMNULD.js +2 -0
  17. package/dist/{chunk-3TGCIXJA.js → chunk-IQXRQBUK.js} +2 -1
  18. package/dist/chunk-IQXRQBUK.js.map +1 -0
  19. package/dist/chunk-L26TK7Y5.js +2 -0
  20. package/dist/chunk-L3FYR45M.js +2 -0
  21. package/dist/chunk-LXNRCJ22.js +2 -0
  22. package/dist/{chunk-TX7WOFCW.js → chunk-MGFMVPRD.js} +4 -7
  23. package/dist/chunk-MGFMVPRD.js.map +1 -0
  24. package/dist/chunk-MNXU3KCD.js +2 -0
  25. package/dist/{chunk-CHIP7O6V.js → chunk-O2MSGW3V.js} +3 -1
  26. package/dist/chunk-O2MSGW3V.js.map +1 -0
  27. package/dist/chunk-PJ5DKXGR.js +2 -0
  28. package/dist/{chunk-2KSBOAW3.js → chunk-QEEM67OA.js} +11 -17
  29. package/dist/chunk-QEEM67OA.js.map +1 -0
  30. package/dist/chunk-UMZEA3JT.js +5 -0
  31. package/dist/{shell-OGTSH4RJ.js → chunk-UW6GUUE6.js} +3 -3
  32. package/dist/chunk-XDVMX2FO.js +8 -0
  33. package/dist/chunk-XDVMX2FO.js.map +1 -0
  34. package/dist/chunk-ZA5Z33GO.js +11 -0
  35. package/dist/claude-E36EGXUV.js +2 -0
  36. package/dist/{chunk-IRN2U2NE.js → claude-RIB3RQS5.js} +5 -2
  37. package/dist/claude-RIB3RQS5.js.map +1 -0
  38. package/dist/cli.js +1 -199
  39. package/dist/clipboard-service-PDTSZIR5.js +25 -0
  40. package/dist/codex-OTZKVESD.js +2 -0
  41. package/dist/{codex-U7LTJTX6.js → codex-VBUSA2GJ.js} +5 -3
  42. package/dist/codex-VBUSA2GJ.js.map +1 -0
  43. package/dist/config-CCSS2P7R.js +2 -0
  44. package/dist/container-OIXLFSX2.js +6 -0
  45. package/dist/context-GSMQHQES.js +7 -0
  46. package/dist/cursor-3DJA6LWS.js +2 -0
  47. package/dist/{cursor-3DI5GKRF.js → cursor-4QIOTDBW.js} +5 -3
  48. package/dist/cursor-4QIOTDBW.js.map +1 -0
  49. package/dist/doctor-KBK5JZBZ.js +2 -0
  50. package/dist/{chunk-K6DMQERQ.js → doctor-service-F2SXDWHS.js} +3 -1
  51. package/dist/doctor-service-F2SXDWHS.js.map +1 -0
  52. package/dist/doctor-service-PB7YBH3F.js +2 -0
  53. package/dist/goal-RFKFPR7M.js +8 -0
  54. package/dist/index.d.ts +105 -43
  55. package/dist/index.js +1817 -5
  56. package/dist/index.js.map +1 -1
  57. package/dist/init-WRDFAFS2.js +53 -0
  58. package/dist/logs-5QHJWMEG.js +12 -0
  59. package/dist/msg-4SCLBO4K.js +9 -0
  60. package/dist/orchestrator-FGGXK3N3.js +5 -0
  61. package/dist/{orchestrator-L6QX2LJ7.js.map → orchestrator-FGGXK3N3.js.map} +1 -1
  62. package/dist/orchestrator-R7IWZUT6.js +13 -0
  63. package/dist/process-manager-33H27MQF.js +2 -0
  64. package/dist/process-manager-A36Y7LHP.js +3 -0
  65. package/dist/{process-manager-TLZOTO4Y.js.map → process-manager-A36Y7LHP.js.map} +1 -1
  66. package/dist/registry-BO2PPRNG.js +2 -0
  67. package/dist/registry-JXXRLJ5J.js +3 -0
  68. package/dist/{registry-UQAHK77P.js.map → registry-JXXRLJ5J.js.map} +1 -1
  69. package/dist/run-HSHRELOP.js +3 -0
  70. package/dist/shell-EOJBDWTH.js +2 -0
  71. package/dist/{chunk-CIIE6LNG.js → shell-IH2MMTVP.js} +3 -2
  72. package/dist/shell-IH2MMTVP.js.map +1 -0
  73. package/dist/status-DLBNWSWM.js +2 -0
  74. package/dist/task-J6ZN7ALI.js +20 -0
  75. package/dist/team-MSIBKOQC.js +4 -0
  76. package/dist/template-engine-MFL5B677.js +3 -0
  77. package/dist/{template-engine-322SCRR6.js.map → template-engine-MFL5B677.js.map} +1 -1
  78. package/dist/template-engine-ONIDVD4F.js +2 -0
  79. package/dist/tui-G4XUFAIP.js +2 -0
  80. package/dist/update-PC2ENCKU.js +2 -0
  81. package/dist/update-check-HGMBDYHL.js +2 -0
  82. package/dist/workspace-manager-KOOYTO7E.js +3 -0
  83. package/dist/{workspace-manager-G5EQRS72.js → workspace-manager-T6AXG7XL.js} +4 -3
  84. package/dist/workspace-manager-T6AXG7XL.js.map +1 -0
  85. package/package.json +2 -1
  86. package/readme.md +5 -4
  87. package/scripts/benchmark.ts +304 -0
  88. package/dist/App-KHUT3IV7.js +0 -4962
  89. package/dist/agent-V5M2C3OC.js +0 -157
  90. package/dist/chunk-33QNTNR6.js +0 -46
  91. package/dist/chunk-6HENRUYZ.js.map +0 -1
  92. package/dist/chunk-AELEEEV3.js.map +0 -1
  93. package/dist/chunk-ED47GL3F.js +0 -29
  94. package/dist/chunk-FRTKB575.js +0 -87
  95. package/dist/chunk-HXYAZGLP.js +0 -15
  96. package/dist/chunk-I5WEMARW.js +0 -166
  97. package/dist/chunk-IZYSGYXG.js +0 -2
  98. package/dist/chunk-IZYSGYXG.js.map +0 -1
  99. package/dist/chunk-P6ATSXGL.js +0 -107
  100. package/dist/chunk-PBFE5V3G.js +0 -2
  101. package/dist/chunk-PBFE5V3G.js.map +0 -1
  102. package/dist/chunk-PNE6LQRF.js +0 -5
  103. package/dist/chunk-POUC4CPC.js.map +0 -1
  104. package/dist/chunk-QTDKQYZI.js +0 -11
  105. package/dist/chunk-QTDKQYZI.js.map +0 -1
  106. package/dist/chunk-VAAOW526.js.map +0 -1
  107. package/dist/chunk-ZTQ3KWXR.js +0 -13
  108. package/dist/chunk-ZTQ3KWXR.js.map +0 -1
  109. package/dist/claude-GH6P2DC5.js +0 -4
  110. package/dist/claude-S47YTIHU.js +0 -2
  111. package/dist/claude-S47YTIHU.js.map +0 -1
  112. package/dist/codex-2CH57B7G.js +0 -2
  113. package/dist/codex-2CH57B7G.js.map +0 -1
  114. package/dist/config-LJFM55LN.js +0 -75
  115. package/dist/container-KPH4HVAJ.js +0 -1532
  116. package/dist/context-EPSDCJTU.js +0 -83
  117. package/dist/cursor-QFUNKPCQ.js +0 -2
  118. package/dist/cursor-QFUNKPCQ.js.map +0 -1
  119. package/dist/doctor-GHRV5I2S.js +0 -67
  120. package/dist/doctor-service-QEJCE5FK.js.map +0 -1
  121. package/dist/doctor-service-TPOMFAIG.js +0 -2
  122. package/dist/goal-I56QP7HS.js +0 -110
  123. package/dist/init-EQTGQ4G2.js +0 -165
  124. package/dist/logs-AK255DEJ.js +0 -207
  125. package/dist/msg-SQWQLJP6.js +0 -95
  126. package/dist/orchestrator-L6QX2LJ7.js +0 -2
  127. package/dist/process-manager-HUVNAPQV.js +0 -2
  128. package/dist/process-manager-TLZOTO4Y.js +0 -2
  129. package/dist/registry-PQWRVNF2.js +0 -2
  130. package/dist/registry-UQAHK77P.js +0 -2
  131. package/dist/run-PSZURVVL.js +0 -95
  132. package/dist/shell-5ZNXFGXV.js +0 -3
  133. package/dist/shell-OGTSH4RJ.js.map +0 -1
  134. package/dist/status-DTF7D3DV.js +0 -56
  135. package/dist/task-35SDKXFC.js +0 -209
  136. package/dist/team-AISPLEJB.js +0 -97
  137. package/dist/template-engine-322SCRR6.js +0 -2
  138. package/dist/template-engine-3CDRZNMJ.js +0 -3
  139. package/dist/tui-AR6PVMBQ.js +0 -230
  140. package/dist/update-DCCWVISK.js +0 -64
  141. package/dist/update-check-4YKLGBFB.js +0 -2
  142. package/dist/workspace-manager-AS4TFA7R.js +0 -3
  143. package/dist/workspace-manager-AS4TFA7R.js.map +0 -1
@@ -1,12 +1,57 @@
1
- #!/usr/bin/env node
2
- import { DEFAULT_PROMPT_TEMPLATE, buildPromptContext } from './chunk-HNKJ4IF7.js';
3
- import { resolveFailureStatus, isDispatchable, isTerminal, isBlocked, resolveCompletionStatus, calculateRetryDelay } from './chunk-33QNTNR6.js';
4
- import { AUTONOMOUS_LABEL } from './chunk-PNE6LQRF.js';
5
- import { LockConflictError, WorkspaceError, TaskAlreadyRunningError, NoAgentsError } from './chunk-3TGCIXJA.js';
1
+ import { LockConflictError, WorkspaceError, TaskAlreadyRunningError, NoAgentsError } from './chunk-IQXRQBUK.js';
2
+ import { AUTONOMOUS_LABEL, DEFAULT_PROMPT_TEMPLATE, buildPromptContext } from './chunk-B4JQM4NU.js';
6
3
  import { dirname } from 'path';
7
4
  import fs from 'fs/promises';
8
5
  import { execFile } from 'child_process';
9
6
 
7
+ // src/domain/transitions.ts
8
+ var VALID_TRANSITIONS = {
9
+ todo: ["in_progress", "cancelled"],
10
+ in_progress: ["review", "retrying", "failed", "cancelled"],
11
+ retrying: ["in_progress", "failed", "cancelled"],
12
+ review: ["done", "todo", "cancelled"],
13
+ done: [],
14
+ failed: ["todo", "retrying"],
15
+ cancelled: ["todo"]
16
+ };
17
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["done", "failed", "cancelled"]);
18
+ function canTransition(from, to) {
19
+ return VALID_TRANSITIONS[from].includes(to);
20
+ }
21
+ function isTerminal(status) {
22
+ return TERMINAL_STATUSES.has(status);
23
+ }
24
+ function isDispatchable(status) {
25
+ return status === "todo" || status === "retrying";
26
+ }
27
+ function isBlocked(task, allTasks) {
28
+ if (task.depends_on.length === 0) return false;
29
+ if (allTasks instanceof Map) {
30
+ return task.depends_on.some((depId) => {
31
+ const dep = allTasks.get(depId);
32
+ return !dep || dep.status !== "done";
33
+ });
34
+ }
35
+ return task.depends_on.some((depId) => {
36
+ const dep = allTasks.find((t) => t.id === depId);
37
+ return !dep || dep.status !== "done";
38
+ });
39
+ }
40
+ function resolveFailureStatus(task) {
41
+ if (task.attempts < task.max_attempts) {
42
+ return "retrying";
43
+ }
44
+ return "failed";
45
+ }
46
+ function resolveCompletionStatus(task, success, _autoApprove) {
47
+ {
48
+ return "review";
49
+ }
50
+ }
51
+ function calculateRetryDelay(attempt, baseDelayMs, maxDelayMs) {
52
+ const delay = baseDelayMs * Math.pow(2, attempt);
53
+ return Math.min(delay, maxDelayMs);
54
+ }
10
55
  function scopesOverlap(a, b) {
11
56
  if (!a?.length || !b?.length) return false;
12
57
  for (const pa of a) {
@@ -16,6 +61,54 @@ function scopesOverlap(a, b) {
16
61
  }
17
62
  return false;
18
63
  }
64
+ function computePatternInfo(pattern) {
65
+ const base = pattern.split("*")[0];
66
+ const isFile = !base.endsWith("/");
67
+ const dir = isFile ? dirname(base) : "";
68
+ return { raw: pattern, base, isFile, dir };
69
+ }
70
+ var ScopeIndex = class {
71
+ entries;
72
+ constructor(scopes) {
73
+ this.entries = [];
74
+ for (const scope of scopes) {
75
+ if (scope?.length) {
76
+ for (const p of scope) {
77
+ this.entries.push(computePatternInfo(p));
78
+ }
79
+ }
80
+ }
81
+ }
82
+ /** Returns true if the given scope overlaps with any pattern in the index. */
83
+ overlapsAny(scope) {
84
+ if (!scope?.length || this.entries.length === 0) return false;
85
+ for (const raw of scope) {
86
+ const info = computePatternInfo(raw);
87
+ for (const entry of this.entries) {
88
+ if (patternsOverlapInfo(info, entry)) return true;
89
+ }
90
+ }
91
+ return false;
92
+ }
93
+ /** Add patterns to the index (e.g. from an approved candidate). */
94
+ add(scope) {
95
+ if (!scope?.length) return;
96
+ for (const p of scope) {
97
+ this.entries.push(computePatternInfo(p));
98
+ }
99
+ }
100
+ get size() {
101
+ return this.entries.length;
102
+ }
103
+ };
104
+ function patternsOverlapInfo(a, b) {
105
+ if (a.raw === b.raw) return true;
106
+ if (a.base.startsWith(b.base) || b.base.startsWith(a.base)) return true;
107
+ if (a.isFile && b.isFile) {
108
+ return a.dir === b.dir && a.dir !== ".";
109
+ }
110
+ return false;
111
+ }
19
112
  function patternsOverlap(a, b) {
20
113
  if (a === b) return true;
21
114
  const aBase = a.split("*")[0];
@@ -28,29 +121,37 @@ function patternsOverlap(a, b) {
28
121
  }
29
122
  return false;
30
123
  }
124
+ var acquireMutex = Promise.resolve();
31
125
  async function acquireLock(lockPath) {
32
- const bakPath = lockPath + ".bak";
126
+ let release;
127
+ const gate = new Promise((r) => {
128
+ release = r;
129
+ });
130
+ const prev = acquireMutex;
131
+ acquireMutex = gate;
132
+ await prev;
133
+ try {
134
+ return await doAcquire(lockPath);
135
+ } finally {
136
+ release();
137
+ }
138
+ }
139
+ async function doAcquire(lockPath) {
33
140
  const existing = await readLockPid(lockPath);
34
141
  if (existing !== null) {
35
142
  if (isProcessAlive(existing)) {
36
143
  return { acquired: false, pid: existing };
37
144
  }
38
- try {
39
- await fs.rename(lockPath, bakPath);
40
- } catch {
41
- }
145
+ await fs.unlink(lockPath).catch(() => {
146
+ });
42
147
  }
43
148
  try {
44
149
  const fd = await fs.open(lockPath, "wx");
45
150
  await fd.writeFile(String(process.pid), "utf-8");
46
151
  await fd.close();
47
- await fs.unlink(bakPath).catch(() => {
48
- });
49
152
  return { acquired: true, pid: process.pid };
50
153
  } catch (err) {
51
154
  if (err.code === "EEXIST") {
52
- await fs.rename(bakPath, lockPath).catch(() => {
53
- });
54
155
  const pid = await readLockPid(lockPath);
55
156
  return { acquired: false, pid: pid ?? void 0 };
56
157
  }
@@ -87,7 +188,7 @@ var CachedTaskStore = class {
87
188
  }
88
189
  cache = /* @__PURE__ */ new Map();
89
190
  async list(filter) {
90
- const key = filter?.status ?? "__all__";
191
+ const key = filter ? `${filter.status ?? ""}:${filter.goalId ?? ""}` : "__all__";
91
192
  if (this.cache.has(key)) {
92
193
  return this.cache.get(key);
93
194
  }
@@ -115,6 +216,7 @@ var CachedAgentStore = class {
115
216
  this.inner = inner;
116
217
  }
117
218
  listCache = null;
219
+ nameCache = /* @__PURE__ */ new Map();
118
220
  async list() {
119
221
  if (this.listCache) {
120
222
  return this.listCache;
@@ -127,18 +229,26 @@ var CachedAgentStore = class {
127
229
  return this.inner.get(id);
128
230
  }
129
231
  async getByName(name) {
130
- return this.inner.getByName(name);
232
+ if (this.nameCache.has(name)) {
233
+ return this.nameCache.get(name) ?? null;
234
+ }
235
+ const result = await this.inner.getByName(name);
236
+ this.nameCache.set(name, result);
237
+ return result;
131
238
  }
132
239
  async save(agent) {
133
240
  await this.inner.save(agent);
134
241
  this.listCache = null;
242
+ this.nameCache.clear();
135
243
  }
136
244
  async delete(id) {
137
245
  await this.inner.delete(id);
138
246
  this.listCache = null;
247
+ this.nameCache.clear();
139
248
  }
140
249
  invalidate() {
141
250
  this.listCache = null;
251
+ this.nameCache.clear();
142
252
  }
143
253
  };
144
254
  var CachedGoalStore = class {
@@ -446,7 +556,7 @@ var Orchestrator = class {
446
556
  await this.deps.agentService.setStatus(entry.agent_id, "idle");
447
557
  }
448
558
  this.state.running = {};
449
- this.state.claimed = [];
559
+ this.state.claimed = /* @__PURE__ */ new Set();
450
560
  this.state.pid = void 0;
451
561
  this.state.started_at = void 0;
452
562
  await this.saveState();
@@ -594,8 +704,13 @@ var Orchestrator = class {
594
704
  async reconcile() {
595
705
  const state = this.state;
596
706
  const now = Date.now();
597
- for (const [taskId, entry] of Object.entries(state.running)) {
598
- const taskData = await this.deps.taskStore.get(taskId);
707
+ const runningEntries = Object.entries(state.running);
708
+ const runningTaskData = await Promise.all(
709
+ runningEntries.map(([taskId]) => this.deps.taskStore.get(taskId))
710
+ );
711
+ for (let i = 0; i < runningEntries.length; i++) {
712
+ const [taskId, entry] = runningEntries[i];
713
+ const taskData = runningTaskData[i];
599
714
  if (!taskData || isTerminal(taskData.status)) {
600
715
  this.abortControllers.delete(taskId);
601
716
  delete state.running[taskId];
@@ -664,12 +779,16 @@ var Orchestrator = class {
664
779
  });
665
780
  }
666
781
  }
667
- for (let i = state.retry_queue.length - 1; i >= 0; i--) {
668
- const retry = state.retry_queue[i];
782
+ const dueRetries = [];
783
+ state.retry_queue = state.retry_queue.filter((retry) => {
669
784
  if (now >= new Date(retry.due_at).getTime()) {
670
- state.retry_queue.splice(i, 1);
671
- await this.dispatchTask(retry.task_id);
785
+ dueRetries.push(retry.task_id);
786
+ return false;
672
787
  }
788
+ return true;
789
+ });
790
+ for (const taskId of dueRetries) {
791
+ await this.dispatchTask(taskId);
673
792
  }
674
793
  await this.saveState();
675
794
  }
@@ -714,7 +833,8 @@ Agent role: ${role}` : `Autonomous work cycle. Agent role: ${role}`;
714
833
  description,
715
834
  assignee: agent.id,
716
835
  labels: [AUTONOMOUS_LABEL],
717
- priority: 3
836
+ priority: 3,
837
+ goalId: goal?.id
718
838
  });
719
839
  anyCreated = true;
720
840
  } catch (err) {
@@ -738,8 +858,9 @@ Agent role: ${role}` : `Autonomous work cycle. Agent role: ${role}`;
738
858
  const availableSlots = maxConcurrent - currentRunning;
739
859
  if (availableSlots <= 0) return;
740
860
  const allTasks = await this.cachedTaskStore.list();
861
+ const taskMap = new Map(allTasks.map((t) => [t.id, t]));
741
862
  const candidates = allTasks.filter(
742
- (t) => isDispatchable(t.status) && !isBlocked(t, allTasks) && !state.running[t.id] && !state.claimed.includes(t.id)
863
+ (t) => isDispatchable(t.status) && !isBlocked(t, taskMap) && !state.running[t.id] && !state.claimed.has(t.id)
743
864
  ).sort((a, b) => {
744
865
  const bTime = b.updated_at ?? "";
745
866
  const aTime = a.updated_at ?? "";
@@ -747,25 +868,21 @@ Agent role: ${role}` : `Autonomous work cycle. Agent role: ${role}`;
747
868
  }).slice(0, availableSlots);
748
869
  const blockedIds = /* @__PURE__ */ new Set();
749
870
  const inProgressScoped = allTasks.filter((t) => t.status === "in_progress" && t.scope?.length);
750
- for (let i = 0; i < candidates.length; i++) {
751
- const candidate = candidates[i];
871
+ const scopeIndex = new ScopeIndex(inProgressScoped.map((t) => t.scope));
872
+ for (const candidate of candidates) {
752
873
  if (!candidate.scope?.length) continue;
753
- const approvedPeers = candidates.slice(0, i).filter((c) => !blockedIds.has(c.id));
754
- const compareTo = [...inProgressScoped, ...approvedPeers];
755
- let overlapping = false;
756
- for (const other of compareTo) {
757
- if (scopesOverlap(candidate.scope, other.scope)) {
758
- this.deps.eventBus.emit({
759
- type: "task:scope_overlap",
760
- taskId: candidate.id,
761
- overlappingTaskId: other.id,
762
- patterns: candidate.scope
763
- });
764
- overlapping = true;
765
- break;
766
- }
874
+ if (scopeIndex.overlapsAny(candidate.scope)) {
875
+ const overlapper = inProgressScoped.find((t) => scopesOverlap(candidate.scope, t.scope));
876
+ this.deps.eventBus.emit({
877
+ type: "task:scope_overlap",
878
+ taskId: candidate.id,
879
+ overlappingTaskId: overlapper?.id ?? candidate.id,
880
+ patterns: candidate.scope
881
+ });
882
+ blockedIds.add(candidate.id);
883
+ } else {
884
+ scopeIndex.add(candidate.scope);
767
885
  }
768
- if (overlapping) blockedIds.add(candidate.id);
769
886
  }
770
887
  for (const task of candidates) {
771
888
  if (blockedIds.has(task.id)) continue;
@@ -802,13 +919,13 @@ Agent role: ${role}` : `Autonomous work cycle. Agent role: ${role}`;
802
919
  throw new TaskAlreadyRunningError(taskId, entry.run_id, entry.agent_id);
803
920
  }
804
921
  const task = await this.deps.taskService.get(taskId);
805
- state.claimed.push(taskId);
922
+ state.claimed.add(taskId);
806
923
  await this.saveState();
807
924
  try {
925
+ const allAgents = await this.cachedAgentStore.list();
808
926
  const agent = await this.deps.agentService.findBestAgent(task);
809
927
  if (!agent) {
810
- const allAgents2 = await this.cachedAgentStore.list();
811
- if (allAgents2.length === 0) {
928
+ if (allAgents.length === 0) {
812
929
  throw new NoAgentsError();
813
930
  }
814
931
  this.unclaim(taskId);
@@ -821,7 +938,6 @@ Agent role: ${role}` : `Autonomous work cycle. Agent role: ${role}`;
821
938
  this.deps.config
822
939
  );
823
940
  const template = this.deps.config.prompt?.template ?? DEFAULT_PROMPT_TEMPLATE;
824
- const allAgents = await this.cachedAgentStore.list();
825
941
  const attempt = task.attempts + 1;
826
942
  let retryContext;
827
943
  if (attempt > 1) {
@@ -833,15 +949,35 @@ Agent role: ${role}` : `Autonomous work cycle. Agent role: ${role}`;
833
949
  };
834
950
  }
835
951
  }
836
- const sharedContext = this.deps.contextStore ? await this.deps.contextStore.getAll() : void 0;
837
- const pendingMessages = this.deps.messageService ? await this.deps.messageService.drainMailbox(agent.id, task.id) : [];
952
+ const goalId = task.goalId;
953
+ const [sharedContext, pendingMessages, goalRaw] = await Promise.all([
954
+ this.deps.contextStore?.getAll(),
955
+ this.deps.messageService ? this.deps.messageService.drainMailbox(agent.id, task.id) : [],
956
+ goalId && this.cachedGoalStore ? this.cachedGoalStore.get(goalId).catch(() => null) : null
957
+ ]);
958
+ let goalContext;
959
+ if (goalRaw) {
960
+ const allTasks = await this.cachedTaskStore.list();
961
+ const goalTasks = allTasks.filter((t) => t.goalId === goalId);
962
+ const progressEntry = await this.deps.contextStore?.get(`${goalId}-progress`);
963
+ const MAX_GOAL_TASK_NAMES = 30;
964
+ const taskNames = goalTasks.map((t) => `[${t.status}] ${t.title}`);
965
+ goalContext = {
966
+ id: goalRaw.id,
967
+ title: goalRaw.title,
968
+ description: goalRaw.description,
969
+ status: goalRaw.status,
970
+ task_names: taskNames.length > MAX_GOAL_TASK_NAMES ? [...taskNames.slice(0, MAX_GOAL_TASK_NAMES), `... and ${taskNames.length - MAX_GOAL_TASK_NAMES} more`] : taskNames,
971
+ progress: progressEntry?.value
972
+ };
973
+ }
838
974
  const context = buildPromptContext(
839
975
  task,
840
976
  agent,
841
977
  attempt,
842
978
  workspacePath,
843
979
  this.deps.config,
844
- { allAgents, retryContext, sharedContext, feedback: task.feedback, messages: pendingMessages.length ? pendingMessages : void 0 }
980
+ { allAgents, retryContext, sharedContext, feedback: task.feedback, messages: pendingMessages.length ? pendingMessages : void 0, goal: goalContext }
845
981
  );
846
982
  const prompt = await this.deps.templateEngine.render(template, context);
847
983
  const run = await this.deps.runService.create({
@@ -1018,7 +1154,7 @@ Agent role: ${role}` : `Autonomous work cycle. Agent role: ${role}`;
1018
1154
  const agent = await this.deps.agentStore.get(agentId);
1019
1155
  const isAutonomousTask = task.labels?.includes(AUTONOMOUS_LABEL);
1020
1156
  const autoApprove = isAutonomousTask || agent?.config.approval_policy === "auto";
1021
- const newStatus = resolveCompletionStatus(task, true, autoApprove);
1157
+ const newStatus = resolveCompletionStatus();
1022
1158
  await this.deps.runService.finish(runId, "succeeded", tokens);
1023
1159
  const runningEntry = state.running[taskId];
1024
1160
  const successRuntimeMs = runningEntry ? Date.now() - new Date(runningEntry.started_at).getTime() : 0;
@@ -1251,8 +1387,7 @@ ${task.proof?.agent_summary ?? ""}`.slice(0, 2e3),
1251
1387
  await this.saveState();
1252
1388
  }
1253
1389
  unclaim(taskId) {
1254
- const idx = this.state.claimed.indexOf(taskId);
1255
- if (idx !== -1) this.state.claimed.splice(idx, 1);
1390
+ this.state.claimed.delete(taskId);
1256
1391
  }
1257
1392
  /**
1258
1393
  * Throw if this instance doesn't own the lock (read-only session).
@@ -1317,4 +1452,6 @@ function serializeEventData(data, maxLen) {
1317
1452
  return str.length > maxLen ? str.slice(0, maxLen) + "\u2026" : str;
1318
1453
  }
1319
1454
 
1320
- export { Orchestrator };
1455
+ export { Orchestrator, canTransition, isBlocked, isDispatchable, isTerminal, resolveFailureStatus };
1456
+ //# sourceMappingURL=chunk-2UC4SVJB.js.map
1457
+ //# sourceMappingURL=chunk-2UC4SVJB.js.map