@xynogen/pix-subagent 0.1.2 → 0.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xynogen/pix-subagent",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Pi tool — planner-driven sub-agents: spawn, fetch, steer scoped child agents",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/index.ts CHANGED
@@ -86,7 +86,6 @@ export default function registerPixSubagent(pi: ExtensionAPI): void {
86
86
  // onComplete — fire subagent-notification nudge for each finished bg agent
87
87
  (record) => {
88
88
  agentActivity.delete(record.id);
89
- widget.markFinished(record.id);
90
89
 
91
90
  if (record.resultConsumed) {
92
91
  widget.update();
package/src/tools.ts CHANGED
@@ -296,12 +296,10 @@ export function createAgentTool(
296
296
 
297
297
  const stats = buildStats(details, theme);
298
298
 
299
- // Streaming / running
299
+ // Streaming / running — live state shown by the ● Agents widget, so the
300
+ // inline transcript stays empty to avoid stacking one card per agent.
300
301
  if (isPartial || details.status === "running") {
301
- const frame = SPINNER[details.spinnerFrame ?? 0];
302
- let line = theme.fg("accent", frame) + (stats ? ` ${stats}` : "");
303
- line += `\n${theme.fg("dim", ` ⎿ ${details.activity ?? "thinking…"}`)}`;
304
- return new Text(line, 0, 0);
302
+ return new Text("", 0, 0);
305
303
  }
306
304
 
307
305
  // Background launched
package/src/ui/widget.ts CHANGED
@@ -133,8 +133,8 @@ export class AgentWidget {
133
133
  private uiCtx: UICtx | undefined;
134
134
  private widgetFrame = 0;
135
135
  private widgetInterval: ReturnType<typeof setInterval> | undefined;
136
- private finishedTurnAge = new Map<string, number>();
137
- private static readonly ERROR_LINGER_TURNS = 2;
136
+ private static readonly FINISHED_LINGER_MS = 5_000;
137
+ private static readonly ERROR_LINGER_MS = 15_000;
138
138
  private widgetRegistered = false;
139
139
  private tui: unknown = undefined;
140
140
  private lastStatusText: string | undefined;
@@ -154,9 +154,6 @@ export class AgentWidget {
154
154
  }
155
155
 
156
156
  onTurnStart() {
157
- for (const [id, age] of this.finishedTurnAge) {
158
- this.finishedTurnAge.set(id, age + 1);
159
- }
160
157
  this.update();
161
158
  }
162
159
 
@@ -166,18 +163,14 @@ export class AgentWidget {
166
163
  }
167
164
  }
168
165
 
169
- private shouldShowFinished(agentId: string, status: string): boolean {
170
- const age = this.finishedTurnAge.get(agentId) ?? 0;
171
- const maxAge = ERROR_STATUSES.has(status)
172
- ? AgentWidget.ERROR_LINGER_TURNS
173
- : 1;
174
- return age < maxAge;
175
- }
176
-
177
- markFinished(agentId: string) {
178
- if (!this.finishedTurnAge.has(agentId)) {
179
- this.finishedTurnAge.set(agentId, 0);
180
- }
166
+ private shouldShowFinished(status: string, completedAt: number): boolean {
167
+ // Linger a few seconds after finish, then drop. The ✓ … Done line in the
168
+ // transcript is the permanent record; errors stay longer so failures are
169
+ // noticed. The 80ms widget timer re-evaluates this continuously.
170
+ const linger = ERROR_STATUSES.has(status)
171
+ ? AgentWidget.ERROR_LINGER_MS
172
+ : AgentWidget.FINISHED_LINGER_MS;
173
+ return Date.now() - completedAt < linger;
181
174
  }
182
175
 
183
176
  private renderFinishedLine(
@@ -246,8 +239,8 @@ export class AgentWidget {
246
239
  (a) =>
247
240
  a.status !== "running" &&
248
241
  a.status !== "queued" &&
249
- a.completedAt &&
250
- this.shouldShowFinished(a.id, a.status),
242
+ a.completedAt != null &&
243
+ this.shouldShowFinished(a.status, a.completedAt),
251
244
  );
252
245
 
253
246
  if (running.length === 0 && queued.length === 0 && finished.length === 0)
@@ -403,7 +396,10 @@ export class AgentWidget {
403
396
  for (const a of allAgents) {
404
397
  if (a.status === "running") runningCount++;
405
398
  else if (a.status === "queued") queuedCount++;
406
- else if (a.completedAt && this.shouldShowFinished(a.id, a.status))
399
+ else if (
400
+ a.completedAt != null &&
401
+ this.shouldShowFinished(a.status, a.completedAt)
402
+ )
407
403
  hasFinished = true;
408
404
  }
409
405
  const hasActive = runningCount > 0 || queuedCount > 0;
@@ -422,10 +418,6 @@ export class AgentWidget {
422
418
  clearInterval(this.widgetInterval);
423
419
  this.widgetInterval = undefined;
424
420
  }
425
- for (const [id] of this.finishedTurnAge) {
426
- if (!allAgents.some((a) => a.id === id))
427
- this.finishedTurnAge.delete(id);
428
- }
429
421
  return;
430
422
  }
431
423