wogiflow 2.5.3 → 2.5.4
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/lib/workspace.js +44 -0
- package/package.json +1 -1
- package/scripts/hooks/core/task-completed.js +57 -0
package/lib/workspace.js
CHANGED
|
@@ -594,6 +594,50 @@ ${Object.entries(config.channels?.members || {}).map(([name, ch]) =>
|
|
|
594
594
|
\`\`\`
|
|
595
595
|
Then read responses from \`.workspace/messages/\` and synthesize findings.
|
|
596
596
|
|
|
597
|
+
## Waiting for Worker Results (CRITICAL — Automatic Return Path)
|
|
598
|
+
|
|
599
|
+
Workers **automatically write results** to \`.workspace/messages/\` when they complete a task. You do NOT need to ask them to report back — the task-completed hook writes a \`task-complete\` message automatically.
|
|
600
|
+
|
|
601
|
+
**After dispatching a task, poll for results:**
|
|
602
|
+
\`\`\`bash
|
|
603
|
+
# List all pending messages (newest first)
|
|
604
|
+
ls -t .workspace/messages/*.json 2>/dev/null | head -5
|
|
605
|
+
|
|
606
|
+
# Read the latest message
|
|
607
|
+
cat .workspace/messages/$(ls -t .workspace/messages/*.json 2>/dev/null | head -1) 2>/dev/null
|
|
608
|
+
\`\`\`
|
|
609
|
+
|
|
610
|
+
**Or read all messages from a specific worker:**
|
|
611
|
+
\`\`\`bash
|
|
612
|
+
# Find messages from a specific repo
|
|
613
|
+
grep -l '"from": "<repo-name>"' .workspace/messages/*.json 2>/dev/null
|
|
614
|
+
\`\`\`
|
|
615
|
+
|
|
616
|
+
**Polling pattern after dispatch:**
|
|
617
|
+
1. Dispatch task via \`curl -s -X POST http://localhost:{port} -d "..."\`
|
|
618
|
+
2. Wait ~5 seconds for the worker to start processing
|
|
619
|
+
3. Poll \`.workspace/messages/\` for new \`task-complete\` messages from that worker
|
|
620
|
+
4. If no message after 30s, check the worker's \`ready.json\` for task status
|
|
621
|
+
5. Once message arrives, read it and present the results to the user
|
|
622
|
+
|
|
623
|
+
**Message format** (what workers write automatically):
|
|
624
|
+
\`\`\`json
|
|
625
|
+
{
|
|
626
|
+
"id": "msg-XXXXXXXX",
|
|
627
|
+
"from": "<repo-name>",
|
|
628
|
+
"to": "manager",
|
|
629
|
+
"type": "task-complete",
|
|
630
|
+
"subject": "Task completed: <title>",
|
|
631
|
+
"body": "**Task**: ...\\n**Files changed**: ...\\n**Summary**: ...",
|
|
632
|
+
"taskId": "wf-XXXXXXXX",
|
|
633
|
+
"status": "pending"
|
|
634
|
+
}
|
|
635
|
+
\`\`\`
|
|
636
|
+
|
|
637
|
+
**After reading a result**: Present the findings to the user. If the task requires follow-up (e.g., bug investigation found the issue in the other repo), dispatch the fix to the appropriate worker.
|
|
638
|
+
|
|
639
|
+
**You are the SINGLE interface for the user.** They should never need to look at worker terminals. Read the messages, synthesize, and present.
|
|
640
|
+
|
|
597
641
|
## Reading Member State (What to Read, When)
|
|
598
642
|
|
|
599
643
|
| When | What to Read | Path |
|
package/package.json
CHANGED
|
@@ -282,6 +282,63 @@ async function handleTaskCompleted(input) {
|
|
|
282
282
|
} catch (_err) {
|
|
283
283
|
// Non-critical - registry manager may not be available
|
|
284
284
|
}
|
|
285
|
+
// Write results back to workspace message bus if running as a workspace worker
|
|
286
|
+
if (result.completed && process.env.WOGI_WORKSPACE_ROOT) {
|
|
287
|
+
try {
|
|
288
|
+
const workspaceRoot = process.env.WOGI_WORKSPACE_ROOT;
|
|
289
|
+
const repoName = process.env.WOGI_REPO_NAME || path.basename(process.cwd());
|
|
290
|
+
const messagesDir = path.join(workspaceRoot, '.workspace', 'messages');
|
|
291
|
+
fs.mkdirSync(messagesDir, { recursive: true });
|
|
292
|
+
|
|
293
|
+
// Build a summary from available task data
|
|
294
|
+
const summary = [];
|
|
295
|
+
if (completedTask.title) summary.push(`**Task**: ${completedTask.title}`);
|
|
296
|
+
if (completedTask.type) summary.push(`**Type**: ${completedTask.type}`);
|
|
297
|
+
if (input.changedFiles?.length) summary.push(`**Files changed**: ${input.changedFiles.join(', ')}`);
|
|
298
|
+
if (input.summary) summary.push(`**Summary**: ${input.summary}`);
|
|
299
|
+
|
|
300
|
+
// Read the last request-log entry for richer context
|
|
301
|
+
try {
|
|
302
|
+
const logPath = path.join(PATHS.root, 'request-log.md');
|
|
303
|
+
if (fs.existsSync(logPath)) {
|
|
304
|
+
const logContent = fs.readFileSync(logPath, 'utf-8');
|
|
305
|
+
const lastEntry = logContent.split(/^### R-/m).pop();
|
|
306
|
+
if (lastEntry && lastEntry.length < 2000) {
|
|
307
|
+
summary.push(`**Log entry**:\n${lastEntry.trim()}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
} catch (_err) {
|
|
311
|
+
// Non-critical
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const message = {
|
|
315
|
+
id: 'msg-' + require('node:crypto').randomBytes(4).toString('hex'),
|
|
316
|
+
from: repoName,
|
|
317
|
+
to: 'manager',
|
|
318
|
+
type: 'task-complete',
|
|
319
|
+
priority: 'medium',
|
|
320
|
+
timestamp: new Date().toISOString(),
|
|
321
|
+
subject: `Task completed: ${completedTask.title || completedTask.id}`,
|
|
322
|
+
body: summary.join('\n') || `Task ${completedTask.id} completed successfully.`,
|
|
323
|
+
taskId: completedTask.id,
|
|
324
|
+
actionRequired: false,
|
|
325
|
+
status: 'pending'
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const msgPath = path.join(messagesDir, `${message.id}.json`);
|
|
329
|
+
fs.writeFileSync(msgPath, JSON.stringify(message, null, 2));
|
|
330
|
+
|
|
331
|
+
if (process.env.DEBUG) {
|
|
332
|
+
console.error(`[Task Completed] Workspace message written: ${msgPath}`);
|
|
333
|
+
}
|
|
334
|
+
} catch (err) {
|
|
335
|
+
// Non-critical — workspace messaging is best-effort
|
|
336
|
+
if (process.env.DEBUG) {
|
|
337
|
+
console.error(`[Task Completed] Workspace message failed: ${err.message}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
285
342
|
// Check pending queue — notify user if items are waiting
|
|
286
343
|
try {
|
|
287
344
|
const { getPendingCount } = require('../../flow-pending');
|