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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wogiflow",
3
- "version": "2.5.3",
3
+ "version": "2.5.4",
4
4
  "description": "AI-powered development workflow management system with multi-model support",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -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');