diff --git a/controller.ts b/controller.ts index 57db316..5a1faef 100644 --- a/controller.ts +++ b/controller.ts @@ -223,6 +223,34 @@ export class FanoutController { proc.unref(); } + private readJobOutput(job: FanoutJob): string { + if (!fs.existsSync(job.outputFile)) return ""; + try { + const lines = fs + .readFileSync(job.outputFile, "utf-8") + .split("\n") + .filter(Boolean); + const messages: Message[] = []; + for (const line of lines) { + try { + const event = JSON.parse(line); + if (event.type === "message_end" && event.message) messages.push(event.message as Message); + if (event.type === "tool_result_end" && event.message) messages.push(event.message as Message); + } catch {} + } + return getFinalOutput(messages); + } catch { + return ""; + } + } + + private getJobPreview(job: FanoutJob, maxChars = 500): string { + const output = this.readJobOutput(job); + if (!output) return ""; + if (output.length <= maxChars) return output; + return output.slice(0, maxChars) + "\n… (truncated)"; + } + private processOutputLine(job: FanoutJob, line: string) { let event: any; try { event = JSON.parse(line); } catch { return; } @@ -283,11 +311,18 @@ export class FanoutController { job.notified = true; this.persist(job); const outcome = job.status === "done" ? "completed" : `failed (exit ${job.exitCode ?? "?"})`; + const preview = this.getJobPreview(job, 2000); try { - this.pi.sendUserMessage( - `Fanout job \`${job.id}\` (${job.agent}) ${outcome}. Use \`fanout_collect\` to retrieve results.`, - { deliverAs: "followUp" }, - ); + const parts = [ + `Fanout job \`${job.id}\` (${job.agent}) ${outcome}.`, + ]; + if (preview) { + parts.push(`\n\`\`\`\n${preview}\n\`\`\``); + } + if (preview && preview.length >= 2000) { + parts.push("\n*(output truncated — run `fanout_collect` for full result)*"); + } + this.pi.sendUserMessage(parts.join(""), { deliverAs: "followUp" }); } catch { // If sendUserMessage fails (e.g. no active session), ignore. } @@ -309,6 +344,7 @@ export class FanoutController { pid: job.pid, turns: job.usage.turns, cost: job.usage.cost, + preview: this.getJobPreview(job, 300), }); } return { jobs }; diff --git a/package.json b/package.json index 2cbf6ab..2ee0f25 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,10 @@ "name": "pi-fanout", "version": "0.1.0", "description": "Non-blocking async agent fanout for pi", + "keywords": ["pi-package"], "type": "module", "main": "index.ts", + "license": "MIT", "peerDependencies": { "@earendil-works/pi-coding-agent": "*", "@earendil-works/pi-agent-core": "*", diff --git a/types.ts b/types.ts index 19d0cbb..733ab4a 100644 --- a/types.ts +++ b/types.ts @@ -44,6 +44,7 @@ export interface StatusResult { pid?: number; turns?: number; cost?: number; + preview?: string; }>; }