@arhen/pi-core-subagent 1.0.4 → 1.0.5

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.ts +20 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arhen/pi-core-subagent",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "type": "module",
5
5
  "description": "pi extension: fast in-process subagents with single/parallel/chain, background runs, intercom and agent-to-agent mailbox. Leader defines agents inline.",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
@@ -383,7 +383,7 @@ class SubagentManager {
383
383
  private mailboxes: Mailbox = createMailbox();
384
384
  private runControllers = new Map<string, AbortController>();
385
385
  private widgetTimer: ReturnType<typeof setTimeout> | undefined;
386
- private widgetRun: RunSnapshot | undefined;
386
+ private widgetRuns: RunSnapshot[] = [];
387
387
 
388
388
  turnActivity = false;
389
389
 
@@ -399,7 +399,7 @@ class SubagentManager {
399
399
 
400
400
  /** Hide the widget. */
401
401
  clearWidget(ctx: ExtensionContext): void {
402
- this.widgetRun = undefined;
402
+ this.widgetRuns = [];
403
403
  this.widgetTui = null;
404
404
  if (ctx.hasUI) {
405
405
  try {
@@ -425,7 +425,7 @@ class SubagentManager {
425
425
  this.widgetTui = null; // force re-registration on the next session
426
426
  if (this.widgetTimer) clearTimeout(this.widgetTimer);
427
427
  this.widgetTimer = undefined;
428
- this.widgetRun = undefined;
428
+ this.widgetRuns = [];
429
429
  }
430
430
 
431
431
  // ── persistence (sidecar per parent session) ────────────────────────
@@ -508,19 +508,27 @@ class SubagentManager {
508
508
  // The component self-animates the spinner via its own 100ms interval;
509
509
  // scheduleWidget just throttles status changes into requestRender calls.
510
510
  private widgetTui: TUI | null = null;
511
+ /** Upsert a run into the widget's visible set (all runs, not just the latest). */
512
+ private upsertWidgetRun(run: RunSnapshot | undefined): void {
513
+ if (!run) return;
514
+ const idx = this.widgetRuns.findIndex((r) => r.id === run.id);
515
+ if (idx >= 0) this.widgetRuns[idx] = run;
516
+ else this.widgetRuns.push(run);
517
+ }
511
518
  private scheduleWidget(run: RunSnapshot | undefined, ctx?: ExtensionContext, onUpdate?: (partial: any) => void): void {
512
- if (run) this.widgetRun = run;
513
- if (this.widgetTimer || !this.widgetRun) return;
519
+ this.upsertWidgetRun(run);
520
+ if (this.widgetTimer || this.widgetRuns.length === 0) return;
514
521
  this.widgetTimer = setTimeout(() => {
515
522
  this.widgetTimer = undefined;
516
- const target = this.widgetRun; // read at fire: never render a stale run
517
- if (!target) return;
523
+ if (this.widgetRuns.length === 0) return;
524
+ const targets = [...this.widgetRuns]; // read at fire: never render stale runs
518
525
  if (ctx?.hasUI) {
519
- ctx.ui.setStatus("subagents", `subagents: ${target.tasks.filter((t) => !TERMINAL.includes(t.status)).length} running`);
526
+ const live = targets.reduce((n, r) => n + r.tasks.filter((t) => !TERMINAL.includes(t.status)).length, 0);
527
+ ctx.ui.setStatus("subagents", `subagents: ${live} running`);
520
528
  this.ensureWidget(ctx);
521
529
  this.widgetTui?.requestRender();
522
530
  }
523
- onUpdate?.({ content: [{ type: "text", text: compactLines(target).join("\n") }] });
531
+ onUpdate?.({ content: [{ type: "text", text: targets.flatMap(compactLines).join("\n") }] });
524
532
  }, WIDGET_THROTTLE_MS);
525
533
  }
526
534
  private flushWidget(ctx?: ExtensionContext, onUpdate?: (partial: any) => void): void {
@@ -528,14 +536,12 @@ class SubagentManager {
528
536
  clearTimeout(this.widgetTimer);
529
537
  this.widgetTimer = undefined;
530
538
  }
531
- const run = this.widgetRun;
532
- if (!run) return;
539
+ if (this.widgetRuns.length === 0) return;
533
540
  if (ctx?.hasUI) {
534
- ctx.ui.setStatus("subagents", `subagents: ${run.status}`);
535
541
  this.ensureWidget(ctx);
536
542
  this.widgetTui?.requestRender();
537
543
  }
538
- onUpdate?.({ content: [{ type: "text", text: compactLines(run).join("\n") }] });
544
+ onUpdate?.({ content: [{ type: "text", text: this.widgetRuns.flatMap(compactLines).join("\n") }] });
539
545
  }
540
546
  private ensureWidget(ctx: ExtensionContext): void {
541
547
  if (this.widgetTui !== null || !ctx.hasUI) return;
@@ -543,7 +549,7 @@ class SubagentManager {
543
549
  "subagents",
544
550
  (tui, theme) => {
545
551
  this.widgetTui = tui;
546
- return new SubagentsWidget(() => this.widgetRun, theme);
552
+ return new SubagentsWidget(() => [...this.widgetRuns], theme);
547
553
  },
548
554
  { placement: "aboveEditor" },
549
555
  );