oh-my-codex 0.7.4 → 0.7.6
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/README.md +14 -0
- package/dist/cli/__tests__/index.test.js +25 -1
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/ralph.test.d.ts +2 -0
- package/dist/cli/__tests__/ralph.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralph.test.js +64 -0
- package/dist/cli/__tests__/ralph.test.js.map +1 -0
- package/dist/cli/__tests__/team-decompose.test.d.ts +2 -0
- package/dist/cli/__tests__/team-decompose.test.d.ts.map +1 -0
- package/dist/cli/__tests__/team-decompose.test.js +67 -0
- package/dist/cli/__tests__/team-decompose.test.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +25 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/ralph.d.ts +12 -0
- package/dist/cli/ralph.d.ts.map +1 -1
- package/dist/cli/ralph.js +58 -1
- package/dist/cli/ralph.js.map +1 -1
- package/dist/cli/team.d.ts +18 -0
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +108 -16
- package/dist/cli/team.js.map +1 -1
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +8 -0
- package/dist/config/generator.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +10 -7
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +11 -7
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +199 -0
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.d.ts +11 -0
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js +266 -0
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js.map +1 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +4 -5
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/tmux-hook-engine.test.js +36 -1
- package/dist/hooks/__tests__/tmux-hook-engine.test.js.map +1 -1
- package/dist/mcp/__tests__/team-server-cleanup.test.d.ts +2 -0
- package/dist/mcp/__tests__/team-server-cleanup.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/team-server-cleanup.test.js +219 -0
- package/dist/mcp/__tests__/team-server-cleanup.test.js.map +1 -0
- package/dist/mcp/bootstrap.d.ts +1 -1
- package/dist/mcp/bootstrap.d.ts.map +1 -1
- package/dist/mcp/bootstrap.js +1 -0
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +11 -2
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/mcp/team-server.d.ts +24 -0
- package/dist/mcp/team-server.d.ts.map +1 -0
- package/dist/mcp/team-server.js +419 -0
- package/dist/mcp/team-server.js.map +1 -0
- package/dist/notifications/__tests__/verbosity.test.js +35 -0
- package/dist/notifications/__tests__/verbosity.test.js.map +1 -1
- package/dist/notifications/config.d.ts.map +1 -1
- package/dist/notifications/config.js +4 -2
- package/dist/notifications/config.js.map +1 -1
- package/dist/notifications/tmux.d.ts.map +1 -1
- package/dist/notifications/tmux.js +11 -2
- package/dist/notifications/tmux.js.map +1 -1
- package/dist/notifications/types.d.ts +4 -0
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/openclaw/__tests__/index.test.js +40 -0
- package/dist/openclaw/__tests__/index.test.js.map +1 -1
- package/dist/openclaw/index.d.ts.map +1 -1
- package/dist/openclaw/index.js +1 -0
- package/dist/openclaw/index.js.map +1 -1
- package/dist/openclaw/types.d.ts +2 -0
- package/dist/openclaw/types.d.ts.map +1 -1
- package/dist/team/__tests__/role-router.test.d.ts +2 -0
- package/dist/team/__tests__/role-router.test.d.ts.map +1 -0
- package/dist/team/__tests__/role-router.test.js +204 -0
- package/dist/team/__tests__/role-router.test.js.map +1 -0
- package/dist/team/__tests__/runtime-cli.test.d.ts +2 -0
- package/dist/team/__tests__/runtime-cli.test.d.ts.map +1 -0
- package/dist/team/__tests__/runtime-cli.test.js +72 -0
- package/dist/team/__tests__/runtime-cli.test.js.map +1 -0
- package/dist/team/__tests__/runtime.test.js +194 -5
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.js +132 -2
- package/dist/team/__tests__/scaling.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +86 -7
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +38 -0
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/__tests__/worktree.test.js +27 -1
- package/dist/team/__tests__/worktree.test.js.map +1 -1
- package/dist/team/idle-nudge.d.ts +53 -0
- package/dist/team/idle-nudge.d.ts.map +1 -0
- package/dist/team/idle-nudge.js +140 -0
- package/dist/team/idle-nudge.js.map +1 -0
- package/dist/team/mcp-comm.d.ts +1 -1
- package/dist/team/mcp-comm.d.ts.map +1 -1
- package/dist/team/role-router.d.ts +32 -0
- package/dist/team/role-router.d.ts.map +1 -0
- package/dist/team/role-router.js +137 -0
- package/dist/team/role-router.js.map +1 -0
- package/dist/team/runtime-cli.d.ts +18 -0
- package/dist/team/runtime-cli.d.ts.map +1 -0
- package/dist/team/runtime-cli.js +238 -0
- package/dist/team/runtime-cli.js.map +1 -0
- package/dist/team/runtime.d.ts +4 -0
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +108 -42
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts +1 -0
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +41 -20
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state.d.ts +2 -1
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js.map +1 -1
- package/dist/team/tmux-session.d.ts +42 -2
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +219 -65
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts +2 -0
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +29 -5
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/team/worktree.d.ts +5 -1
- package/dist/team/worktree.d.ts.map +1 -1
- package/dist/team/worktree.js +28 -16
- package/dist/team/worktree.js.map +1 -1
- package/package.json +1 -1
- package/scripts/notify-hook/log.js +5 -0
- package/scripts/notify-hook/team-dispatch.js +44 -8
- package/scripts/notify-hook/team-worker.js +26 -4
- package/scripts/notify-hook/tmux-injection.js +45 -4
- package/scripts/notify-hook/visual-verdict.js +109 -0
- package/scripts/notify-hook.js +26 -0
- package/scripts/tmux-hook-engine.js +24 -0
- package/skills/autopilot/SKILL.md +2 -2
- package/skills/doctor/SKILL.md +1 -1
- package/skills/help/SKILL.md +3 -3
- package/skills/skill/SKILL.md +32 -32
- package/skills/team/SKILL.md +43 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI entry point for team runtime.
|
|
3
|
+
* Reads JSON config from stdin, runs startTeam/monitorTeam/shutdownTeam,
|
|
4
|
+
* writes structured JSON result to stdout.
|
|
5
|
+
*
|
|
6
|
+
* Spawned by omx_run_team_start in state-server.ts.
|
|
7
|
+
*/
|
|
8
|
+
import { readdirSync, readFileSync } from 'fs';
|
|
9
|
+
import { writeFile, rename } from 'fs/promises';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
import { startTeam, monitorTeam, shutdownTeam } from './runtime.js';
|
|
12
|
+
import { teamReadConfig as readTeamConfig } from './team-ops.js';
|
|
13
|
+
async function writePanesFile(jobId, paneIds, leaderPaneId) {
|
|
14
|
+
const omxJobsDir = process.env.OMX_JOBS_DIR;
|
|
15
|
+
if (!jobId || !omxJobsDir)
|
|
16
|
+
return;
|
|
17
|
+
const panesPath = join(omxJobsDir, `${jobId}-panes.json`);
|
|
18
|
+
await writeFile(panesPath + '.tmp', JSON.stringify({ paneIds: [...paneIds], leaderPaneId }));
|
|
19
|
+
await rename(panesPath + '.tmp', panesPath);
|
|
20
|
+
}
|
|
21
|
+
export async function loadLivePaneState(teamName, cwd) {
|
|
22
|
+
const config = await readTeamConfig(teamName, cwd);
|
|
23
|
+
if (!config)
|
|
24
|
+
return null;
|
|
25
|
+
return {
|
|
26
|
+
paneIds: config.workers
|
|
27
|
+
.map((worker) => worker.pane_id)
|
|
28
|
+
.filter((paneId) => typeof paneId === 'string' && paneId.trim().length > 0),
|
|
29
|
+
leaderPaneId: config.leader_pane_id ?? '',
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export async function shutdownWithForceFallback(teamName, cwd) {
|
|
33
|
+
try {
|
|
34
|
+
await shutdownTeam(teamName, cwd);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
38
|
+
if (!message.includes('shutdown_gate_blocked') && !message.includes('shutdown_rejected')) {
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
await shutdownTeam(teamName, cwd, { force: true });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function detectDeadWorkerFailure(deadWorkerCount, liveWorkerPaneCount, hasOutstandingWork, phase) {
|
|
45
|
+
const allWorkersDead = liveWorkerPaneCount > 0 && deadWorkerCount >= liveWorkerPaneCount;
|
|
46
|
+
return {
|
|
47
|
+
deadWorkerFailure: allWorkersDead && hasOutstandingWork,
|
|
48
|
+
fixingWithNoWorkers: phase === 'team-fix' && allWorkersDead,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function collectTaskResults(stateRoot, teamName) {
|
|
52
|
+
const tasksDir = join(stateRoot, 'team', teamName, 'tasks');
|
|
53
|
+
try {
|
|
54
|
+
const files = readdirSync(tasksDir).filter(f => f.endsWith('.json'));
|
|
55
|
+
return files.map(f => {
|
|
56
|
+
try {
|
|
57
|
+
const raw = readFileSync(join(tasksDir, f), 'utf-8');
|
|
58
|
+
const task = JSON.parse(raw);
|
|
59
|
+
return {
|
|
60
|
+
taskId: task.id ?? f.replace('.json', ''),
|
|
61
|
+
status: task.status ?? 'unknown',
|
|
62
|
+
summary: (task.result ?? task.summary) ?? '',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return { taskId: f.replace('.json', ''), status: 'unknown', summary: '' };
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function main() {
|
|
75
|
+
const startTime = Date.now();
|
|
76
|
+
// Read stdin
|
|
77
|
+
const chunks = [];
|
|
78
|
+
for await (const chunk of process.stdin) {
|
|
79
|
+
chunks.push(chunk);
|
|
80
|
+
}
|
|
81
|
+
const rawInput = Buffer.concat(chunks).toString('utf-8').trim();
|
|
82
|
+
let input;
|
|
83
|
+
try {
|
|
84
|
+
input = JSON.parse(rawInput);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
process.stderr.write(`[runtime-cli] Failed to parse stdin JSON: ${err}\n`);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
// Validate required fields
|
|
91
|
+
const missing = [];
|
|
92
|
+
if (!input.teamName)
|
|
93
|
+
missing.push('teamName');
|
|
94
|
+
if (!input.agentTypes || !Array.isArray(input.agentTypes) || input.agentTypes.length === 0)
|
|
95
|
+
missing.push('agentTypes');
|
|
96
|
+
if (!input.tasks || !Array.isArray(input.tasks) || input.tasks.length === 0)
|
|
97
|
+
missing.push('tasks');
|
|
98
|
+
if (!input.cwd)
|
|
99
|
+
missing.push('cwd');
|
|
100
|
+
if (missing.length > 0) {
|
|
101
|
+
process.stderr.write(`[runtime-cli] Missing required fields: ${missing.join(', ')}\n`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
const { teamName, agentTypes, tasks, cwd, pollIntervalMs = 5000, } = input;
|
|
105
|
+
const workerCount = input.workerCount ?? agentTypes.length;
|
|
106
|
+
const stateRoot = join(cwd, '.omx', 'state');
|
|
107
|
+
let runtime = null;
|
|
108
|
+
let finalStatus = 'failed';
|
|
109
|
+
let pollActive = true;
|
|
110
|
+
function exitCodeFor(status) {
|
|
111
|
+
return status === 'completed' ? 0 : 1;
|
|
112
|
+
}
|
|
113
|
+
async function doShutdown(status) {
|
|
114
|
+
pollActive = false;
|
|
115
|
+
finalStatus = status;
|
|
116
|
+
// 1. Collect task results
|
|
117
|
+
const taskResults = collectTaskResults(stateRoot, teamName);
|
|
118
|
+
// 2. Shutdown team
|
|
119
|
+
if (runtime) {
|
|
120
|
+
try {
|
|
121
|
+
if (status === 'failed') {
|
|
122
|
+
// Failure/cancellation path must force cleanup to bypass shutdown gate.
|
|
123
|
+
await shutdownTeam(runtime.teamName, runtime.cwd, { force: true });
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
await shutdownWithForceFallback(runtime.teamName, runtime.cwd);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
process.stderr.write(`[runtime-cli] shutdownTeam error: ${err}\n`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const duration = (Date.now() - startTime) / 1000;
|
|
134
|
+
const output = {
|
|
135
|
+
status: finalStatus,
|
|
136
|
+
teamName,
|
|
137
|
+
taskResults,
|
|
138
|
+
duration,
|
|
139
|
+
workerCount,
|
|
140
|
+
};
|
|
141
|
+
// 3. Write result to stdout
|
|
142
|
+
process.stdout.write(JSON.stringify(output) + '\n');
|
|
143
|
+
// 4. Exit
|
|
144
|
+
process.exit(exitCodeFor(status));
|
|
145
|
+
}
|
|
146
|
+
// Register signal handlers before poll loop
|
|
147
|
+
process.on('SIGINT', () => {
|
|
148
|
+
process.stderr.write('[runtime-cli] Received SIGINT, shutting down...\n');
|
|
149
|
+
doShutdown('failed').catch(() => process.exit(1));
|
|
150
|
+
});
|
|
151
|
+
process.on('SIGTERM', () => {
|
|
152
|
+
process.stderr.write('[runtime-cli] Received SIGTERM, shutting down...\n');
|
|
153
|
+
doShutdown('failed').catch(() => process.exit(1));
|
|
154
|
+
});
|
|
155
|
+
// Start the team — OMX's startTeam takes individual parameters
|
|
156
|
+
const agentType = agentTypes[0] ?? 'codex';
|
|
157
|
+
try {
|
|
158
|
+
runtime = await startTeam(teamName, tasks.map(t => t.subject).join('; '), agentType, workerCount, tasks, cwd);
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
process.stderr.write(`[runtime-cli] startTeam failed: ${err}\n`);
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
// Persist pane IDs so MCP server can clean up explicitly via omx_run_team_cleanup.
|
|
165
|
+
const jobId = process.env.OMX_JOB_ID;
|
|
166
|
+
try {
|
|
167
|
+
const livePanes = await loadLivePaneState(teamName, cwd);
|
|
168
|
+
if (livePanes) {
|
|
169
|
+
await writePanesFile(jobId, livePanes.paneIds, livePanes.leaderPaneId);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
const fallbackPaneIds = runtime.config.workers
|
|
173
|
+
.map((worker) => worker.pane_id)
|
|
174
|
+
.filter((paneId) => typeof paneId === 'string' && paneId.trim().length > 0);
|
|
175
|
+
await writePanesFile(jobId, fallbackPaneIds, runtime.config.leader_pane_id ?? '');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
process.stderr.write(`[runtime-cli] Failed to persist pane IDs: ${err}\n`);
|
|
180
|
+
}
|
|
181
|
+
// Poll loop
|
|
182
|
+
while (pollActive) {
|
|
183
|
+
await new Promise(r => setTimeout(r, pollIntervalMs));
|
|
184
|
+
if (!pollActive)
|
|
185
|
+
break;
|
|
186
|
+
let snap;
|
|
187
|
+
try {
|
|
188
|
+
snap = await monitorTeam(teamName, cwd);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
process.stderr.write(`[runtime-cli] monitorTeam error: ${err}\n`);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (!snap) {
|
|
195
|
+
process.stderr.write(`[runtime-cli] monitorTeam returned null\n`);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
// Refresh pane IDs (workers may have scaled)
|
|
199
|
+
let livePaneState = null;
|
|
200
|
+
try {
|
|
201
|
+
livePaneState = await loadLivePaneState(teamName, cwd);
|
|
202
|
+
if (livePaneState) {
|
|
203
|
+
await writePanesFile(jobId, livePaneState.paneIds, livePaneState.leaderPaneId);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
process.stderr.write(`[runtime-cli] Failed to persist pane IDs: ${err}\n`);
|
|
208
|
+
}
|
|
209
|
+
const perfMs = snap.performance?.total_ms ?? 0;
|
|
210
|
+
process.stderr.write(`[runtime-cli] phase=${snap.phase} pending=${snap.tasks.pending} inProgress=${snap.tasks.in_progress} completed=${snap.tasks.completed} failed=${snap.tasks.failed} dead=${snap.deadWorkers.length} monitorMs=${perfMs.toFixed(0)}\n`);
|
|
211
|
+
// Check completion
|
|
212
|
+
if (snap.phase === 'complete') {
|
|
213
|
+
await doShutdown('completed');
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (snap.phase === 'failed' || snap.phase === 'cancelled') {
|
|
217
|
+
await doShutdown('failed');
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
// Check failure heuristics
|
|
221
|
+
const hasOutstandingWork = (snap.tasks.pending + snap.tasks.in_progress) > 0;
|
|
222
|
+
const liveWorkerPaneCount = livePaneState?.paneIds.length ?? 0;
|
|
223
|
+
const { deadWorkerFailure, fixingWithNoWorkers } = detectDeadWorkerFailure(snap.deadWorkers.length, liveWorkerPaneCount, hasOutstandingWork, snap.phase);
|
|
224
|
+
if (deadWorkerFailure || fixingWithNoWorkers) {
|
|
225
|
+
process.stderr.write(`[runtime-cli] Failure detected: deadWorkerFailure=${deadWorkerFailure} fixingWithNoWorkers=${fixingWithNoWorkers}\n`);
|
|
226
|
+
await doShutdown('failed');
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const shouldAutoStart = process.env.OMX_RUNTIME_CLI_DISABLE_AUTO_START !== '1';
|
|
232
|
+
if (shouldAutoStart) {
|
|
233
|
+
main().catch(err => {
|
|
234
|
+
process.stderr.write(`[runtime-cli] Fatal error: ${err}\n`);
|
|
235
|
+
process.exit(1);
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=runtime-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-cli.js","sourceRoot":"","sources":["../../src/team/runtime-cli.ts"],"names":[],"mappings":"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"}
|
package/dist/team/runtime.d.ts
CHANGED
|
@@ -45,9 +45,13 @@ export interface TeamRuntime {
|
|
|
45
45
|
}
|
|
46
46
|
interface ShutdownOptions {
|
|
47
47
|
force?: boolean;
|
|
48
|
+
/** When true, applies ralph-specific cleanup policy: no force-kill on failure, detailed audit logging. */
|
|
49
|
+
ralph?: boolean;
|
|
48
50
|
}
|
|
49
51
|
export interface TeamStartOptions {
|
|
50
52
|
worktreeMode?: WorktreeMode;
|
|
53
|
+
/** When true, applies ralph-specific cleanup policy during startup rollback (skip branch deletion). */
|
|
54
|
+
ralph?: boolean;
|
|
51
55
|
}
|
|
52
56
|
export { TEAM_LOW_COMPLEXITY_DEFAULT_MODEL };
|
|
53
57
|
export declare function resolveCanonicalTeamStateRoot(leaderCwd: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/team/runtime.ts"],"names":[],"mappings":"AA4BA,OAAO,
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/team/runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/team/runtime.js
CHANGED
|
@@ -3,10 +3,12 @@ import { existsSync } from 'fs';
|
|
|
3
3
|
import { readdir, readFile } from 'fs/promises';
|
|
4
4
|
import { performance } from 'perf_hooks';
|
|
5
5
|
import { spawn } from 'child_process';
|
|
6
|
-
import { sanitizeTeamName, isTmuxAvailable, createTeamSession, buildWorkerProcessLaunchSpec, resolveTeamWorkerCli, resolveTeamWorkerCliPlan, resolveTeamWorkerLaunchMode, waitForWorkerReady, dismissTrustPromptIfPresent, sleepFractionalSeconds, sendToWorker,
|
|
7
|
-
import { teamInit as initTeamState, DEFAULT_MAX_WORKERS, teamReadConfig as readTeamConfig, teamWriteWorkerIdentity as writeWorkerIdentity, teamReadWorkerHeartbeat as readWorkerHeartbeat, teamReadWorkerStatus as readWorkerStatus, teamWriteWorkerInbox as writeWorkerInbox, teamCreateTask as createStateTask, teamReadTask as readTask, teamListTasks as listTasks, teamReadManifest as readTeamManifestV2, teamNormalizePolicy as normalizeTeamPolicy, teamClaimTask as claimTask, teamReleaseTaskClaim as releaseTaskClaim, teamAppendEvent as appendTeamEvent, teamReadTaskApproval as readTaskApproval, teamListMailbox as listMailboxMessages, teamMarkMessageNotified as markMessageNotified, teamEnqueueDispatchRequest as enqueueDispatchRequest, teamMarkDispatchRequestNotified as markDispatchRequestNotified, teamTransitionDispatchRequest as transitionDispatchRequest, teamReadDispatchRequest as readDispatchRequest, teamCleanup as cleanupTeamState, teamSaveConfig as saveTeamConfig, teamWriteShutdownRequest as writeShutdownRequest, teamReadShutdownAck as readShutdownAck, teamReadMonitorSnapshot as readMonitorSnapshot, teamWriteMonitorSnapshot as writeMonitorSnapshot, teamReadPhase as readTeamPhaseState, teamWritePhase as writeTeamPhaseState, } from './team-ops.js';
|
|
6
|
+
import { sanitizeTeamName, isTmuxAvailable, createTeamSession, buildWorkerProcessLaunchSpec, resolveTeamWorkerCli, resolveTeamWorkerCliPlan, resolveTeamWorkerLaunchMode, waitForWorkerReady, dismissTrustPromptIfPresent, sleepFractionalSeconds, sendToWorker, sendToLeaderPane, sendToWorkerStdin, isWorkerAlive, getWorkerPanePid, killWorkerByPaneIdAsync, teardownWorkerPanes, unregisterResizeHook, destroyTeamSession, listTeamSessions, } from './tmux-session.js';
|
|
7
|
+
import { teamInit as initTeamState, DEFAULT_MAX_WORKERS, teamReadConfig as readTeamConfig, teamWriteWorkerIdentity as writeWorkerIdentity, teamReadWorkerHeartbeat as readWorkerHeartbeat, teamReadWorkerStatus as readWorkerStatus, teamWriteWorkerInbox as writeWorkerInbox, teamCreateTask as createStateTask, teamReadTask as readTask, teamListTasks as listTasks, teamReadManifest as readTeamManifestV2, teamNormalizePolicy as normalizeTeamPolicy, teamClaimTask as claimTask, teamReleaseTaskClaim as releaseTaskClaim, teamAppendEvent as appendTeamEvent, teamReadTaskApproval as readTaskApproval, teamListMailbox as listMailboxMessages, teamMarkMessageDelivered as markMessageDelivered, teamMarkMessageNotified as markMessageNotified, teamEnqueueDispatchRequest as enqueueDispatchRequest, teamMarkDispatchRequestNotified as markDispatchRequestNotified, teamTransitionDispatchRequest as transitionDispatchRequest, teamReadDispatchRequest as readDispatchRequest, teamCleanup as cleanupTeamState, teamSaveConfig as saveTeamConfig, teamWriteShutdownRequest as writeShutdownRequest, teamReadShutdownAck as readShutdownAck, teamReadMonitorSnapshot as readMonitorSnapshot, teamWriteMonitorSnapshot as writeMonitorSnapshot, teamReadPhase as readTeamPhaseState, teamWritePhase as writeTeamPhaseState, } from './team-ops.js';
|
|
8
8
|
import { queueInboxInstruction, queueDirectMailboxMessage, queueBroadcastMailboxMessage, waitForDispatchReceipt, } from './mcp-comm.js';
|
|
9
9
|
import { generateWorkerOverlay, writeTeamWorkerInstructionsFile, removeTeamWorkerInstructionsFile, generateInitialInbox, generateTaskAssignmentInbox, generateShutdownInbox, generateTriggerMessage, generateMailboxTriggerMessage, } from './worker-bootstrap.js';
|
|
10
|
+
import { loadRolePrompt } from './role-router.js';
|
|
11
|
+
import { codexPromptsDir } from '../utils/paths.js';
|
|
10
12
|
import { isLowComplexityAgentType, resolveTeamWorkerLaunchArgs, TEAM_LOW_COMPLEXITY_DEFAULT_MODEL, resolveTeamLowComplexityDefaultModel, parseTeamWorkerLaunchArgs, splitWorkerLaunchArgs, } from './model-contract.js';
|
|
11
13
|
import { inferPhaseTargetFromTaskCounts, reconcilePhaseStateForMonitor } from './phase-controller.js';
|
|
12
14
|
import { getTeamTmuxSessions } from '../notifications/tmux.js';
|
|
@@ -401,11 +403,24 @@ export async function startTeam(teamName, task, agentType, workerCount, tasks, c
|
|
|
401
403
|
const workerWorkspace = workerWorkspaceByName.get(workerName) ?? { cwd: leaderCwd };
|
|
402
404
|
// Get tasks assigned to this worker
|
|
403
405
|
const workerTasks = allTasks.filter(t => t.owner === workerName);
|
|
406
|
+
// Resolve per-worker role from assigned task roles
|
|
407
|
+
const taskRoles = workerTasks.map(t => t.role).filter(Boolean);
|
|
408
|
+
const uniqueTaskRoles = new Set(taskRoles);
|
|
409
|
+
const workerRole = taskRoles.length > 0 && uniqueTaskRoles.size === 1
|
|
410
|
+
? taskRoles[0]
|
|
411
|
+
: agentType;
|
|
412
|
+
if (uniqueTaskRoles.size > 1) {
|
|
413
|
+
console.log(`[omx:team] ${workerName}: mixed task roles [${[...uniqueTaskRoles].join(', ')}], falling back to ${agentType}`);
|
|
414
|
+
}
|
|
415
|
+
// Load role-specific prompt content if role differs from default
|
|
416
|
+
const rolePromptContent = workerRole !== agentType
|
|
417
|
+
? await loadRolePrompt(workerRole, codexPromptsDir())
|
|
418
|
+
: null;
|
|
404
419
|
// Write worker identity
|
|
405
420
|
const identity = {
|
|
406
421
|
name: workerName,
|
|
407
422
|
index: i,
|
|
408
|
-
role:
|
|
423
|
+
role: workerRole,
|
|
409
424
|
worker_cli: workerCliPlan[i - 1],
|
|
410
425
|
assigned_tasks: workerTasks.map(t => t.id),
|
|
411
426
|
working_dir: workerWorkspace.cwd,
|
|
@@ -448,6 +463,8 @@ export async function startTeam(teamName, task, agentType, workerCount, tasks, c
|
|
|
448
463
|
const inbox = generateInitialInbox(workerName, sanitized, agentType, workerTasks, {
|
|
449
464
|
teamStateRoot,
|
|
450
465
|
leaderCwd,
|
|
466
|
+
workerRole,
|
|
467
|
+
rolePromptContent: rolePromptContent ?? undefined,
|
|
451
468
|
});
|
|
452
469
|
const trigger = generateTriggerMessage(workerName, sanitized);
|
|
453
470
|
const maxStartupDispatchRetries = 3;
|
|
@@ -524,13 +541,13 @@ export async function startTeam(teamName, task, agentType, workerCount, tasks, c
|
|
|
524
541
|
if (sessionName.includes(':')) {
|
|
525
542
|
for (const paneId of createdWorkerPaneIds) {
|
|
526
543
|
try {
|
|
527
|
-
|
|
544
|
+
await killWorkerByPaneIdAsync(paneId, createdLeaderPaneId);
|
|
528
545
|
}
|
|
529
546
|
catch { /* ignore */ }
|
|
530
547
|
}
|
|
531
548
|
if (config?.hud_pane_id) {
|
|
532
549
|
try {
|
|
533
|
-
|
|
550
|
+
await killWorkerByPaneIdAsync(config.hud_pane_id, createdLeaderPaneId);
|
|
534
551
|
}
|
|
535
552
|
catch { /* ignore */ }
|
|
536
553
|
}
|
|
@@ -573,7 +590,9 @@ export async function startTeam(teamName, task, agentType, workerCount, tasks, c
|
|
|
573
590
|
}
|
|
574
591
|
if (provisionedWorktrees.length > 0) {
|
|
575
592
|
try {
|
|
576
|
-
await rollbackProvisionedWorktrees(provisionedWorktrees
|
|
593
|
+
await rollbackProvisionedWorktrees(provisionedWorktrees, {
|
|
594
|
+
skipBranchDeletion: options.ralph === true,
|
|
595
|
+
});
|
|
577
596
|
}
|
|
578
597
|
catch (cleanupError) {
|
|
579
598
|
rollbackErrors.push(`rollbackProvisionedWorktrees: ${String(cleanupError)}`);
|
|
@@ -691,6 +710,20 @@ export async function monitorTeam(teamName, cwd) {
|
|
|
691
710
|
const mailboxDeliveryStartMs = performance.now();
|
|
692
711
|
const mailboxNotifiedByMessageId = await deliverPendingMailboxMessages(sanitized, config, workers, previousSnapshot?.mailboxNotifiedByMessageId ?? {}, dispatchPolicy, cwd);
|
|
693
712
|
const mailboxDeliveryMs = performance.now() - mailboxDeliveryStartMs;
|
|
713
|
+
// Prune ephemeral status messages from leader mailbox (TTL: 60s)
|
|
714
|
+
try {
|
|
715
|
+
const leaderMailbox = await listMailboxMessages(sanitized, 'leader-fixed', cwd);
|
|
716
|
+
const now = Date.now();
|
|
717
|
+
for (const msg of leaderMailbox) {
|
|
718
|
+
if (msg.from_worker === 'system' && msg.created_at) {
|
|
719
|
+
const age = now - new Date(msg.created_at).getTime();
|
|
720
|
+
if (age > 60_000) {
|
|
721
|
+
await markMessageDelivered(sanitized, 'leader-fixed', msg.message_id, cwd);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
catch { /* best-effort */ }
|
|
694
727
|
const updatedAt = new Date().toISOString();
|
|
695
728
|
const totalMs = performance.now() - monitorStartMs;
|
|
696
729
|
await writeMonitorSnapshot(sanitized, {
|
|
@@ -788,7 +821,7 @@ export async function assignTask(teamName, workerName, taskId, cwd) {
|
|
|
788
821
|
waitForWorkerReady(config.tmux_session, workerInfo.index, 15_000, workerInfo.pane_id);
|
|
789
822
|
}
|
|
790
823
|
else {
|
|
791
|
-
|
|
824
|
+
await new Promise(r => setTimeout(r, assignRetryDelayS * 1000));
|
|
792
825
|
}
|
|
793
826
|
}
|
|
794
827
|
}
|
|
@@ -827,6 +860,7 @@ export async function reassignTask(teamName, taskId, _fromWorker, toWorker, cwd)
|
|
|
827
860
|
*/
|
|
828
861
|
export async function shutdownTeam(teamName, cwd, options = {}) {
|
|
829
862
|
const force = options.force === true;
|
|
863
|
+
const ralph = options.ralph === true;
|
|
830
864
|
const sanitized = sanitizeTeamName(teamName);
|
|
831
865
|
const config = await readTeamConfig(sanitized, cwd);
|
|
832
866
|
if (!config) {
|
|
@@ -854,10 +888,22 @@ export async function shutdownTeam(teamName, cwd, options = {}) {
|
|
|
854
888
|
await appendTeamEvent(sanitized, {
|
|
855
889
|
type: 'shutdown_gate',
|
|
856
890
|
worker: 'leader-fixed',
|
|
857
|
-
reason: `allowed=${gate.allowed} total=${gate.total} pending=${gate.pending} blocked=${gate.blocked} in_progress=${gate.in_progress} completed=${gate.completed} failed=${gate.failed}`,
|
|
891
|
+
reason: `allowed=${gate.allowed} total=${gate.total} pending=${gate.pending} blocked=${gate.blocked} in_progress=${gate.in_progress} completed=${gate.completed} failed=${gate.failed}${ralph ? ' policy=ralph' : ''}`,
|
|
858
892
|
}, cwd).catch(() => { });
|
|
859
893
|
if (!gate.allowed) {
|
|
860
|
-
|
|
894
|
+
const hasActiveWork = gate.pending > 0 || gate.blocked > 0 || gate.in_progress > 0;
|
|
895
|
+
if (ralph && !hasActiveWork) {
|
|
896
|
+
// Ralph policy: bypass on failure-only scenarios (no pending/blocked/in_progress tasks).
|
|
897
|
+
// This allows the ralph loop to retry rather than leaving stale team state.
|
|
898
|
+
await appendTeamEvent(sanitized, {
|
|
899
|
+
type: 'ralph_cleanup_policy',
|
|
900
|
+
worker: 'leader-fixed',
|
|
901
|
+
reason: `gate_bypassed:pending=${gate.pending},blocked=${gate.blocked},in_progress=${gate.in_progress},failed=${gate.failed}`,
|
|
902
|
+
}, cwd).catch(() => { });
|
|
903
|
+
}
|
|
904
|
+
else {
|
|
905
|
+
throw new Error(`shutdown_gate_blocked:pending=${gate.pending},blocked=${gate.blocked},in_progress=${gate.in_progress},failed=${gate.failed}`);
|
|
906
|
+
}
|
|
861
907
|
}
|
|
862
908
|
}
|
|
863
909
|
if (force) {
|
|
@@ -954,19 +1000,13 @@ export async function shutdownTeam(teamName, cwd, options = {}) {
|
|
|
954
1000
|
if (resizeHookWarning) {
|
|
955
1001
|
console.warn(`[team shutdown] ${sanitized}: ${resizeHookWarning}; continuing teardown`);
|
|
956
1002
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
if (isWorkerAlive(sessionName, w.index, w.pane_id)) {
|
|
965
|
-
killWorker(sessionName, w.index, w.pane_id, leaderPaneId ?? undefined);
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
catch { /* ignore */ }
|
|
969
|
-
}
|
|
1003
|
+
const workerPaneIds = config.workers
|
|
1004
|
+
.map((w) => w.pane_id)
|
|
1005
|
+
.filter((paneId) => typeof paneId === 'string' && paneId.trim().length > 0);
|
|
1006
|
+
await teardownWorkerPanes(workerPaneIds, {
|
|
1007
|
+
leaderPaneId,
|
|
1008
|
+
hudPaneId,
|
|
1009
|
+
});
|
|
970
1010
|
// 4. Destroy tmux session
|
|
971
1011
|
if (!sessionName.includes(':')) {
|
|
972
1012
|
try {
|
|
@@ -993,7 +1033,19 @@ export async function shutdownTeam(teamName, cwd, options = {}) {
|
|
|
993
1033
|
}
|
|
994
1034
|
catch { /* ignore */ }
|
|
995
1035
|
restoreTeamModelInstructionsFile(sanitized);
|
|
996
|
-
// 6.
|
|
1036
|
+
// 6. Ralph stricter completion logging
|
|
1037
|
+
if (ralph) {
|
|
1038
|
+
const finalTasks = await listTasks(sanitized, cwd).catch(() => []);
|
|
1039
|
+
const completed = finalTasks.filter((t) => t.status === 'completed').length;
|
|
1040
|
+
const failed = finalTasks.filter((t) => t.status === 'failed').length;
|
|
1041
|
+
const pending = finalTasks.filter((t) => t.status === 'pending').length;
|
|
1042
|
+
await appendTeamEvent(sanitized, {
|
|
1043
|
+
type: 'ralph_cleanup_summary',
|
|
1044
|
+
worker: 'leader-fixed',
|
|
1045
|
+
reason: `total=${finalTasks.length} completed=${completed} failed=${failed} pending=${pending} force=${force}`,
|
|
1046
|
+
}, cwd).catch(() => { });
|
|
1047
|
+
}
|
|
1048
|
+
// 7. Cleanup state
|
|
997
1049
|
await cleanupTeamState(sanitized, cwd);
|
|
998
1050
|
}
|
|
999
1051
|
/**
|
|
@@ -1144,7 +1196,7 @@ async function emitMonitorDerivedEvents(teamName, tasks, workers, previous, cwd)
|
|
|
1144
1196
|
}
|
|
1145
1197
|
}
|
|
1146
1198
|
}
|
|
1147
|
-
function notifyWorkerOutcome(config, workerIndex, message, workerPaneId) {
|
|
1199
|
+
async function notifyWorkerOutcome(config, workerIndex, message, workerPaneId) {
|
|
1148
1200
|
const worker = config.workers.find((candidate) => candidate.index === workerIndex);
|
|
1149
1201
|
if (!worker)
|
|
1150
1202
|
return { ok: false, transport: 'none', reason: 'worker_not_found' };
|
|
@@ -1168,7 +1220,7 @@ function notifyWorkerOutcome(config, workerIndex, message, workerPaneId) {
|
|
|
1168
1220
|
return { ok: false, transport: 'tmux_send_keys', reason: 'tmux_unavailable' };
|
|
1169
1221
|
}
|
|
1170
1222
|
try {
|
|
1171
|
-
sendToWorker(config.tmux_session, workerIndex, message, workerPaneId, worker.worker_cli);
|
|
1223
|
+
await sendToWorker(config.tmux_session, workerIndex, message, workerPaneId, worker.worker_cli);
|
|
1172
1224
|
return { ok: true, transport: 'tmux_send_keys', reason: 'tmux_send_keys_sent' };
|
|
1173
1225
|
}
|
|
1174
1226
|
catch (error) {
|
|
@@ -1240,7 +1292,7 @@ async function dispatchCriticalInboxInstruction(params) {
|
|
|
1240
1292
|
return { ok: true, transport: 'hook', reason: `hook_receipt_${receipt.status}`, request_id: queued.request_id };
|
|
1241
1293
|
}
|
|
1242
1294
|
if (receipt?.status === 'failed') {
|
|
1243
|
-
const fallback = notifyWorkerOutcome(config, workerIndex, triggerMessage, paneId);
|
|
1295
|
+
const fallback = await notifyWorkerOutcome(config, workerIndex, triggerMessage, paneId);
|
|
1244
1296
|
if (fallback.ok) {
|
|
1245
1297
|
await transitionDispatchRequest(teamName, queued.request_id, 'failed', 'failed', { last_reason: `fallback_confirmed_after_failed_receipt:${fallback.reason}` }, cwd).catch(() => { });
|
|
1246
1298
|
return {
|
|
@@ -1258,7 +1310,7 @@ async function dispatchCriticalInboxInstruction(params) {
|
|
|
1258
1310
|
request_id: queued.request_id,
|
|
1259
1311
|
};
|
|
1260
1312
|
}
|
|
1261
|
-
const fallback = notifyWorkerOutcome(config, workerIndex, triggerMessage, paneId);
|
|
1313
|
+
const fallback = await notifyWorkerOutcome(config, workerIndex, triggerMessage, paneId);
|
|
1262
1314
|
if (fallback.ok) {
|
|
1263
1315
|
const marked = await markDispatchRequestNotified(teamName, queued.request_id, { last_reason: `fallback_confirmed:${fallback.reason}` }, cwd);
|
|
1264
1316
|
if (!marked) {
|
|
@@ -1293,9 +1345,9 @@ async function finalizeHookPreferredMailboxDispatch(params) {
|
|
|
1293
1345
|
return { ok: true, transport: 'hook', reason: `hook_receipt_${receipt.status}`, request_id: requestId, message_id: messageId };
|
|
1294
1346
|
}
|
|
1295
1347
|
const fallback = fallbackNotify
|
|
1296
|
-
? fallbackNotify()
|
|
1348
|
+
? await fallbackNotify()
|
|
1297
1349
|
: (typeof workerIndex === 'number'
|
|
1298
|
-
? notifyWorkerOutcome(config, workerIndex, triggerMessage, paneId)
|
|
1350
|
+
? await notifyWorkerOutcome(config, workerIndex, triggerMessage, paneId)
|
|
1299
1351
|
: { ok: false, transport: 'none', reason: 'missing_worker_index' });
|
|
1300
1352
|
if (receipt?.status === 'failed') {
|
|
1301
1353
|
if (fallback.ok) {
|
|
@@ -1344,10 +1396,24 @@ async function finalizeHookPreferredMailboxDispatch(params) {
|
|
|
1344
1396
|
message_id: messageId,
|
|
1345
1397
|
};
|
|
1346
1398
|
}
|
|
1347
|
-
function
|
|
1399
|
+
async function notifyLeaderAsync(config, message, cwd) {
|
|
1400
|
+
// Primary: inject directly into the leader pane via tmux send-keys.
|
|
1401
|
+
// This is the fallback path when hook-based dispatch timed out, so the
|
|
1402
|
+
// leader needs a direct tmux notification to wake up. Fixes #437.
|
|
1403
|
+
if (config.leader_pane_id && isTmuxAvailable()) {
|
|
1404
|
+
try {
|
|
1405
|
+
await sendToLeaderPane(config.leader_pane_id, message);
|
|
1406
|
+
return true;
|
|
1407
|
+
}
|
|
1408
|
+
catch {
|
|
1409
|
+
// Fall through to mailbox
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
// Fallback: write to leader mailbox (leader picks up on next hook cycle)
|
|
1348
1413
|
if (!config.tmux_session)
|
|
1349
1414
|
return false;
|
|
1350
|
-
|
|
1415
|
+
const { notifyLeaderMailboxAsync } = await import('./tmux-session.js');
|
|
1416
|
+
return notifyLeaderMailboxAsync(config.name, 'system', message, cwd);
|
|
1351
1417
|
}
|
|
1352
1418
|
async function deliverPendingMailboxMessages(teamName, config, workers, previousNotifications, dispatchPolicy, cwd) {
|
|
1353
1419
|
const nextNotifications = {};
|
|
@@ -1410,7 +1476,7 @@ async function deliverPendingMailboxMessages(teamName, config, workers, previous
|
|
|
1410
1476
|
});
|
|
1411
1477
|
}
|
|
1412
1478
|
else {
|
|
1413
|
-
const direct = notifyWorkerOutcome(config, workerInfo.index, triggerMessage, workerInfo.pane_id);
|
|
1479
|
+
const direct = await notifyWorkerOutcome(config, workerInfo.index, triggerMessage, workerInfo.pane_id);
|
|
1414
1480
|
outcome = { ...direct, request_id: queued.request.request_id, message_id: msg.message_id };
|
|
1415
1481
|
if (outcome.ok) {
|
|
1416
1482
|
await markMessageNotified(teamName, worker.name, msg.message_id, cwd).catch(() => false);
|
|
@@ -1451,9 +1517,9 @@ export async function sendWorkerMessage(teamName, fromWorker, toWorker, body, cw
|
|
|
1451
1517
|
cwd,
|
|
1452
1518
|
transportPreference: leaderTransportPreference,
|
|
1453
1519
|
fallbackAllowed: leaderTransportPreference === 'hook_preferred_with_fallback',
|
|
1454
|
-
notify: (_target, message) => (leaderTransportPreference === 'hook_preferred_with_fallback'
|
|
1520
|
+
notify: async (_target, message) => (leaderTransportPreference === 'hook_preferred_with_fallback'
|
|
1455
1521
|
? { ok: true, transport: 'hook', reason: 'queued_for_hook_dispatch' }
|
|
1456
|
-
: { ok:
|
|
1522
|
+
: { ok: await notifyLeaderAsync(config, message, cwd), transport: 'mailbox', reason: 'leader_mailbox_notified' }),
|
|
1457
1523
|
});
|
|
1458
1524
|
let finalOutcome = outcome;
|
|
1459
1525
|
const canLeaderFallbackDirectly = Boolean(config.leader_pane_id) && isTmuxAvailable();
|
|
@@ -1471,10 +1537,10 @@ export async function sendWorkerMessage(teamName, fromWorker, toWorker, body, cw
|
|
|
1471
1537
|
config,
|
|
1472
1538
|
dispatchPolicy,
|
|
1473
1539
|
cwd,
|
|
1474
|
-
fallbackNotify: () => ({
|
|
1475
|
-
ok:
|
|
1476
|
-
transport: '
|
|
1477
|
-
reason: '
|
|
1540
|
+
fallbackNotify: async () => ({
|
|
1541
|
+
ok: await notifyLeaderAsync(config, leaderTriggerMessage, cwd),
|
|
1542
|
+
transport: 'mailbox',
|
|
1543
|
+
reason: 'leader_mailbox_notified',
|
|
1478
1544
|
}),
|
|
1479
1545
|
});
|
|
1480
1546
|
}
|
|
@@ -1500,9 +1566,9 @@ export async function sendWorkerMessage(teamName, fromWorker, toWorker, body, cw
|
|
|
1500
1566
|
cwd,
|
|
1501
1567
|
transportPreference,
|
|
1502
1568
|
fallbackAllowed: transportPreference === 'hook_preferred_with_fallback',
|
|
1503
|
-
notify: (_target, message) => (transportPreference === 'hook_preferred_with_fallback'
|
|
1569
|
+
notify: async (_target, message) => (transportPreference === 'hook_preferred_with_fallback'
|
|
1504
1570
|
? { ok: true, transport: 'hook', reason: 'queued_for_hook_dispatch' }
|
|
1505
|
-
: notifyWorkerOutcome(config, recipient.index, message, recipient.pane_id)),
|
|
1571
|
+
: await notifyWorkerOutcome(config, recipient.index, message, recipient.pane_id)),
|
|
1506
1572
|
});
|
|
1507
1573
|
let finalOutcome = outcome;
|
|
1508
1574
|
if (transportPreference === 'hook_preferred_with_fallback') {
|
|
@@ -1544,10 +1610,10 @@ export async function broadcastWorkerMessage(teamName, fromWorker, body, cwd) {
|
|
|
1544
1610
|
triggerFor: (workerName) => generateMailboxTriggerMessage(workerName, sanitized, 1),
|
|
1545
1611
|
transportPreference,
|
|
1546
1612
|
fallbackAllowed: transportPreference === 'hook_preferred_with_fallback',
|
|
1547
|
-
notify: (target, message) => transportPreference === 'hook_preferred_with_fallback'
|
|
1613
|
+
notify: async (target, message) => transportPreference === 'hook_preferred_with_fallback'
|
|
1548
1614
|
? { ok: true, transport: 'hook', reason: 'queued_for_hook_dispatch' }
|
|
1549
1615
|
: (typeof target.workerIndex === 'number'
|
|
1550
|
-
? notifyWorkerOutcome(config, target.workerIndex, message, target.paneId)
|
|
1616
|
+
? await notifyWorkerOutcome(config, target.workerIndex, message, target.paneId)
|
|
1551
1617
|
: { ok: false, transport: 'none', reason: 'missing_worker_index' }),
|
|
1552
1618
|
});
|
|
1553
1619
|
const finalizedOutcomes = [];
|