pi-herdr-agents 1.2.2 → 1.2.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/CHANGELOG.md CHANGED
@@ -7,11 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
9
9
 
10
- ## [v1.2.2](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.2.1...v1.2.2)
10
+ ## [v1.2.3](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.2.2...v1.2.3)
11
+
12
+ ### Commits
13
+
14
+ - fix: shorten worktree labels [`4caeabb`](https://github.com/giuseppecrj/pi-herdr-agents/commit/4caeabb4db088b8c60d0caf701ec49fe538f8df2)
15
+ - docs: add release workflow skill [`9937f34`](https://github.com/giuseppecrj/pi-herdr-agents/commit/9937f3402ab672023525c19a50dee3cbd7d579bb)
16
+
17
+ ## [v1.2.2](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.2.1...v1.2.2) - 2026-08-18
11
18
 
12
19
  ### Commits
13
20
 
14
21
  - fix: hide completion tool from auto-exit children [`e4cad6b`](https://github.com/giuseppecrj/pi-herdr-agents/commit/e4cad6bdbe5d1952f5bb838640493c20ab332dbd)
22
+ - chore: release v1.2.2 [`ab7843b`](https://github.com/giuseppecrj/pi-herdr-agents/commit/ab7843b4919574789029c985f27509b968242b05)
15
23
 
16
24
  ## [v1.2.1](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.2.0...v1.2.1) - 2026-08-13
17
25
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-herdr-agents",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "Asynchronous Pi subagents and approved review workflows in Herdr, with optional isolated Git worktrees",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -232,8 +232,7 @@ const SubagentParams = Type.Object({
232
232
  Type.Object({
233
233
  branch: Type.String({
234
234
  minLength: 1,
235
- description:
236
- "New branch name for an isolated Herdr-managed Git worktree",
235
+ description: "New branch name for an isolated Herdr-managed Git worktree",
237
236
  }),
238
237
  base: Type.Optional(
239
238
  Type.String({
@@ -361,7 +360,7 @@ function getFrontmatterValue(
361
360
  }
362
361
 
363
362
  function parseOptionalBoolean(value: string | undefined): boolean | undefined {
364
- return value != null ? value === "true" : undefined;
363
+ return value == null ? undefined : value === "true";
365
364
  }
366
365
 
367
366
  function parseSessionMode(
@@ -401,12 +400,8 @@ function parseAgentDefinition(
401
400
  getFrontmatterValue(frontmatter, "skill"),
402
401
  thinking: thinking && isThinkingLevel(thinking) ? thinking : undefined,
403
402
  denyTools: getFrontmatterValue(frontmatter, "deny-tools"),
404
- spawning: parseOptionalBoolean(
405
- getFrontmatterValue(frontmatter, "spawning"),
406
- ),
407
- autoExit: parseOptionalBoolean(
408
- getFrontmatterValue(frontmatter, "auto-exit"),
409
- ),
403
+ spawning: parseOptionalBoolean(getFrontmatterValue(frontmatter, "spawning")),
404
+ autoExit: parseOptionalBoolean(getFrontmatterValue(frontmatter, "auto-exit")),
410
405
  interactive: parseOptionalBoolean(
411
406
  getFrontmatterValue(frontmatter, "interactive"),
412
407
  ),
@@ -462,8 +457,7 @@ function findPackageMetadata(path: string): {
462
457
  const pkg = JSON.parse(readFileSync(packagePath, "utf8"));
463
458
  return {
464
459
  provider: typeof pkg.name === "string" ? pkg.name : undefined,
465
- providerVersion:
466
- typeof pkg.version === "string" ? pkg.version : undefined,
460
+ providerVersion: typeof pkg.version === "string" ? pkg.version : undefined,
467
461
  };
468
462
  } catch {
469
463
  return {};
@@ -490,8 +484,7 @@ function discoverRolePackPaths(pi?: Pick<ExtensionAPI, "events">): {
490
484
  if (typeof path !== "string" || !isAbsolute(path)) {
491
485
  diagnostics.push({
492
486
  code: "invalid-role-pack-path",
493
- message:
494
- "Role packs must register an absolute file or directory path.",
487
+ message: "Role packs must register an absolute file or directory path.",
495
488
  });
496
489
  return;
497
490
  }
@@ -528,8 +521,7 @@ function discoverAgentCatalog(pi?: Pick<ExtensionAPI, "events">): AgentCatalog {
528
521
  continue;
529
522
  }
530
523
  const parsed = parseAgentDefinition(content, fallbackName);
531
- if (parsed)
532
- agents.set(parsed.name, { ...parsed, source, path: filePath });
524
+ if (parsed) agents.set(parsed.name, { ...parsed, source, path: filePath });
533
525
  }
534
526
  };
535
527
 
@@ -1030,9 +1022,9 @@ function resolveResultPresentation(
1030
1022
  `subagent or resume the session with subagent_resume.`;
1031
1023
  } else {
1032
1024
  body =
1033
- result.exitCode !== 0
1034
- ? `Sub-agent "${name}" failed (exit code ${result.exitCode}).\n\n${result.summary}`
1035
- : `Sub-agent "${name}" completed (${formatElapsed(result.elapsed)}).\n\n${result.summary}`;
1025
+ result.exitCode === 0
1026
+ ? `Sub-agent "${name}" completed (${formatElapsed(result.elapsed)}).\n\n${result.summary}`
1027
+ : `Sub-agent "${name}" failed (exit code ${result.exitCode}).\n\n${result.summary}`;
1036
1028
  }
1037
1029
 
1038
1030
  if (result.fallbackAttempts && result.fallbackAttempts.length > 1) {
@@ -1463,15 +1455,13 @@ function ensureLifecycle(running: RunningSubagent): SubagentLifecycle {
1463
1455
  turnActive: state.phase === "active",
1464
1456
  providerActive: false,
1465
1457
  toolActive: state.activeScope === "tool",
1466
- ...(state.activeScope
1467
- ? { activeScope: state.activeScope as any }
1468
- : {}),
1469
- ...(state.activeSinceMs != null
1470
- ? { activeSince: state.activeSinceMs }
1471
- : {}),
1472
- ...(state.waitingSinceMs != null
1473
- ? { waitingSince: state.waitingSinceMs }
1474
- : {}),
1458
+ ...(state.activeScope ? { activeScope: state.activeScope as any } : {}),
1459
+ ...(state.activeSinceMs == null
1460
+ ? {}
1461
+ : { activeSince: state.activeSinceMs }),
1462
+ ...(state.waitingSinceMs == null
1463
+ ? {}
1464
+ : { waitingSince: state.waitingSinceMs }),
1475
1465
  ...(state.activityLabel && state.activeScope === "tool"
1476
1466
  ? { toolName: state.activityLabel }
1477
1467
  : {}),
@@ -1667,10 +1657,7 @@ function startStatusRefresh(pi: ExtensionAPI) {
1667
1657
  pi.sendMessage(
1668
1658
  {
1669
1659
  customType: "subagent_status",
1670
- content: formatStatusAggregate(
1671
- transitionLines,
1672
- statusConfig.lineLimit,
1673
- ),
1660
+ content: formatStatusAggregate(transitionLines, statusConfig.lineLimit),
1674
1661
  display: true,
1675
1662
  details: { lines: capped.visibleLines, overflow: capped.overflow },
1676
1663
  },
@@ -1940,9 +1927,7 @@ function resolveSubagentRuntimePlans(
1940
1927
  wrapPiModelRegistry(ctx.modelRegistry),
1941
1928
  );
1942
1929
  if (params.worktree && plans.length > 1) {
1943
- throw new Error(
1944
- "Model fallbacks are not supported for worktree subagents.",
1945
- );
1930
+ throw new Error("Model fallbacks are not supported for worktree subagents.");
1946
1931
  }
1947
1932
  return plans;
1948
1933
  }
@@ -2025,9 +2010,9 @@ async function watchSubagent(
2025
2010
  ? observed.thinking
2026
2011
  : undefined;
2027
2012
  const mismatch =
2028
- observedModel !== running.runtimePlan.model
2029
- ? `Resolved model ${running.runtimePlan.model} but child reported ${observedModel}`
2030
- : undefined;
2013
+ observedModel === running.runtimePlan.model
2014
+ ? undefined
2015
+ : `Resolved model ${running.runtimePlan.model} but child reported ${observedModel}`;
2031
2016
  running.runtimePlan = {
2032
2017
  ...running.runtimePlan,
2033
2018
  ...(observedThinking ? { thinking: observedThinking } : {}),
@@ -2042,15 +2027,15 @@ async function watchSubagent(
2042
2027
  findLastAssistantMessage(allEntries) ??
2043
2028
  (result.errorMessage
2044
2029
  ? `Subagent error: ${result.errorMessage}`
2045
- : result.exitCode !== 0
2046
- ? `Sub-agent exited with code ${result.exitCode}`
2047
- : "Sub-agent exited without output");
2030
+ : result.exitCode === 0
2031
+ ? "Sub-agent exited without output"
2032
+ : `Sub-agent exited with code ${result.exitCode}`);
2048
2033
  } else {
2049
2034
  summary = result.errorMessage
2050
2035
  ? `Subagent error: ${result.errorMessage}`
2051
- : result.exitCode !== 0
2052
- ? `Sub-agent exited with code ${result.exitCode}`
2053
- : "Sub-agent exited without output";
2036
+ : result.exitCode === 0
2037
+ ? "Sub-agent exited without output"
2038
+ : `Sub-agent exited with code ${result.exitCode}`;
2054
2039
  }
2055
2040
 
2056
2041
  const worktreeHandoff = finalizeSubagentSurface(
@@ -2358,11 +2343,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
2358
2343
  );
2359
2344
  }
2360
2345
  const id = `workflow-${candidate.runId}-${Math.random().toString(16).slice(2, 10)}`;
2361
- const sessionFile = join(
2362
- dirname(candidate.path),
2363
- "sessions",
2364
- `${id}.jsonl`,
2365
- );
2346
+ const sessionFile = join(dirname(candidate.path), "sessions", `${id}.jsonl`);
2366
2347
  let surface: string | undefined;
2367
2348
  let launched = false;
2368
2349
  const childController = new AbortController();
@@ -2472,10 +2453,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
2472
2453
  if (childController.signal.aborted)
2473
2454
  return workflowFailure("cancelled", "Workflow cancelled.");
2474
2455
  const message = error instanceof Error ? error.message : String(error);
2475
- return workflowFailure(
2476
- launched ? "child_error" : "launch_error",
2477
- message,
2478
- );
2456
+ return workflowFailure(launched ? "child_error" : "launch_error", message);
2479
2457
  } finally {
2480
2458
  owner.controller.signal.removeEventListener("abort", onOwnerAbort);
2481
2459
  owner.children.delete(id);
@@ -2500,7 +2478,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
2500
2478
  const envelope = {
2501
2479
  runId: candidate.runId,
2502
2480
  state: outcome.state,
2503
- ...(outcome.result !== undefined ? { result: outcome.result } : {}),
2481
+ ...(outcome.result === undefined ? {} : { result: outcome.result }),
2504
2482
  ...(outcome.error ? { error: outcome.error } : {}),
2505
2483
  ...(checkoutResult ? { checkout: checkoutResult } : {}),
2506
2484
  };
@@ -2542,9 +2520,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
2542
2520
  ) => {
2543
2521
  if (!claimWorkflowTerminal(owner.gate, outcome)) {
2544
2522
  return (
2545
- owner.gate.outcome ??
2546
- runtime.workflowOutcomes.get(owner.runId) ??
2547
- outcome
2523
+ owner.gate.outcome ?? runtime.workflowOutcomes.get(owner.runId) ?? outcome
2548
2524
  );
2549
2525
  }
2550
2526
  runtime.workflowOutcomes.set(owner.runId, outcome);
@@ -2823,7 +2799,8 @@ export default function subagentsExtension(pi: ExtensionAPI) {
2823
2799
  content: [
2824
2800
  {
2825
2801
  type: "text",
2826
- text: "Error: start pi with a persistent session before preparing a workflow.",
2802
+ text:
2803
+ "Error: start pi with a persistent session before preparing a workflow.",
2827
2804
  },
2828
2805
  ],
2829
2806
  details: { error: "workflow_persistent_session_required" },
@@ -2838,9 +2815,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
2838
2815
  });
2839
2816
  runtime.pendingWorkflow = candidate;
2840
2817
  return {
2841
- content: [
2842
- { type: "text", text: formatApprovalPacket(candidate) },
2843
- ],
2818
+ content: [{ type: "text", text: formatApprovalPacket(candidate) }],
2844
2819
  details: {
2845
2820
  runId: candidate.runId,
2846
2821
  scriptHash: candidate.scriptHash,
@@ -2978,13 +2953,9 @@ export default function subagentsExtension(pi: ExtensionAPI) {
2978
2953
  }
2979
2954
  try {
2980
2955
  const root = realpathSync(
2981
- execFileSync(
2982
- "git",
2983
- ["-C", ctx.cwd, "rev-parse", "--show-toplevel"],
2984
- {
2985
- encoding: "utf8",
2986
- },
2987
- ).trim(),
2956
+ execFileSync("git", ["-C", ctx.cwd, "rev-parse", "--show-toplevel"], {
2957
+ encoding: "utf8",
2958
+ }).trim(),
2988
2959
  );
2989
2960
  const commonDir = realpathSync(
2990
2961
  execFileSync(
@@ -3007,7 +2978,8 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3007
2978
  content: [
3008
2979
  {
3009
2980
  type: "text",
3010
- text: "Error: workflow cancellation must use the approved repository identity.",
2981
+ text:
2982
+ "Error: workflow cancellation must use the approved repository identity.",
3011
2983
  },
3012
2984
  ],
3013
2985
  details: { error: "workflow_cancel_identity_mismatch" },
@@ -3039,9 +3011,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3039
3011
  };
3040
3012
  }
3041
3013
  return {
3042
- content: [
3043
- { type: "text", text: "Error: unsupported workflow action." },
3044
- ],
3014
+ content: [{ type: "text", text: "Error: unsupported workflow action." }],
3045
3015
  details: { error: "workflow_action_unavailable" },
3046
3016
  };
3047
3017
  },
@@ -3114,7 +3084,8 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3114
3084
  content: [
3115
3085
  {
3116
3086
  type: "text",
3117
- text: "Error: no session file. Start pi with a persistent session to use subagents.",
3087
+ text:
3088
+ "Error: no session file. Start pi with a persistent session to use subagents.",
3118
3089
  },
3119
3090
  ],
3120
3091
  details: { error: "no session file" },
@@ -3132,9 +3103,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3132
3103
  parentThinking !== "xhigh" &&
3133
3104
  parentThinking !== "max"
3134
3105
  ) {
3135
- throw new Error(
3136
- `Unsupported parent thinking level: ${parentThinking}`,
3137
- );
3106
+ throw new Error(`Unsupported parent thinking level: ${parentThinking}`);
3138
3107
  }
3139
3108
  const runtimePlans = resolveSubagentRuntimePlans(
3140
3109
  params,
@@ -3227,9 +3196,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3227
3196
  exitCode: result.exitCode,
3228
3197
  elapsed: result.elapsed,
3229
3198
  sessionFile: result.sessionFile,
3230
- ...(result.errorMessage
3231
- ? { errorMessage: result.errorMessage }
3232
- : {}),
3199
+ ...(result.errorMessage ? { errorMessage: result.errorMessage } : {}),
3233
3200
  ...(result.fallbackAttempts
3234
3201
  ? { fallbackAttempts: result.fallbackAttempts }
3235
3202
  : {}),
@@ -3276,9 +3243,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3276
3243
  (running.worktree
3277
3244
  ? ` in worktree ${running.worktree.path} on branch ${running.worktree.branch}. `
3278
3245
  : ". ") +
3279
- (worktreeLaunchWarning
3280
- ? `Warning: ${worktreeLaunchWarning} `
3281
- : "") +
3246
+ (worktreeLaunchWarning ? `Warning: ${worktreeLaunchWarning} ` : "") +
3282
3247
  `Do NOT generate or assume any results — you have no idea what the sub-agent will do or produce. ` +
3283
3248
  `The results will be delivered to you automatically as a steer message when the sub-agent finishes. ` +
3284
3249
  `Until then, move on to other work or tell the user you're waiting.`,
@@ -3295,9 +3260,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3295
3260
  thinking: running.runtimePlan?.thinking,
3296
3261
  runtimePlan: running.runtimePlan,
3297
3262
  ...(running.worktree ? { worktree: running.worktree } : {}),
3298
- ...(worktreeLaunchWarning
3299
- ? { warning: worktreeLaunchWarning }
3300
- : {}),
3263
+ ...(worktreeLaunchWarning ? { warning: worktreeLaunchWarning } : {}),
3301
3264
  status: "started",
3302
3265
  },
3303
3266
  };
@@ -3309,8 +3272,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3309
3272
  typeof partialArgs.name === "string" && partialArgs.name
3310
3273
  ? partialArgs.name
3311
3274
  : "(unnamed)";
3312
- const task =
3313
- typeof partialArgs.task === "string" ? partialArgs.task : "";
3275
+ const task = typeof partialArgs.task === "string" ? partialArgs.task : "";
3314
3276
  const agent =
3315
3277
  typeof partialArgs.agent === "string" && partialArgs.agent
3316
3278
  ? theme.fg("dim", ` (${partialArgs.agent})`)
@@ -3319,9 +3281,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3319
3281
  typeof partialArgs.cwd === "string" && partialArgs.cwd
3320
3282
  ? theme.fg("dim", ` in ${partialArgs.cwd}`)
3321
3283
  : "";
3322
- const worktree = partialArgs.worktree as
3323
- | { branch?: unknown }
3324
- | undefined;
3284
+ const worktree = partialArgs.worktree as { branch?: unknown } | undefined;
3325
3285
  const worktreeHint =
3326
3286
  typeof worktree?.branch === "string"
3327
3287
  ? theme.fg("dim", ` on ${worktree.branch} (worktree)`)
@@ -3337,8 +3297,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3337
3297
  // LLM generates tool arguments, so args.task grows token by token.
3338
3298
  // We keep it compact here — Ctrl+O on renderResult expands the full content.
3339
3299
  if (task) {
3340
- const firstLine =
3341
- task.split("\n").find((l: string) => l.trim()) ?? "";
3300
+ const firstLine = task.split("\n").find((l: string) => l.trim()) ?? "";
3342
3301
  const preview =
3343
3302
  firstLine.length > 100 ? firstLine.slice(0, 100) + "…" : firstLine;
3344
3303
  if (preview) {
@@ -3477,21 +3436,13 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3477
3436
  const agents = details?.agents ?? [];
3478
3437
  const diagnostics = details?.diagnostics ?? [];
3479
3438
  if (agents.length === 0 && diagnostics.length === 0) {
3480
- return new Text(
3481
- theme.fg("dim", "No subagent definitions found."),
3482
- 0,
3483
- 0,
3484
- );
3439
+ return new Text(theme.fg("dim", "No subagent definitions found."), 0, 0);
3485
3440
  }
3486
3441
  const lines = agents.map((a: any) => {
3487
3442
  const source =
3488
- a.source === "package" && a.provider
3489
- ? `package:${a.provider}`
3490
- : a.source;
3443
+ a.source === "package" && a.provider ? `package:${a.provider}` : a.source;
3491
3444
  const badge = theme.fg("accent", ` (${source})`);
3492
- const desc = a.description
3493
- ? theme.fg("dim", ` — ${a.description}`)
3494
- : "";
3445
+ const desc = a.description ? theme.fg("dim", ` — ${a.description}`) : "";
3495
3446
  const model = a.model ? theme.fg("dim", ` [${a.model}]`) : "";
3496
3447
  return ` ${theme.fg("toolTitle", theme.bold(a.name))}${badge}${model}${desc}`;
3497
3448
  });
@@ -3648,17 +3599,14 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3648
3599
  return;
3649
3600
  }
3650
3601
 
3651
- const allEntries = getNewEntries(
3652
- params.sessionPath,
3653
- entryCountBefore,
3654
- );
3602
+ const allEntries = getNewEntries(params.sessionPath, entryCountBefore);
3655
3603
  const summary =
3656
3604
  findLastAssistantMessage(allEntries) ??
3657
3605
  (result.errorMessage
3658
3606
  ? `Subagent error: ${result.errorMessage}`
3659
- : result.exitCode !== 0
3660
- ? `Resumed session exited with code ${result.exitCode}`
3661
- : "Resumed session exited without new output");
3607
+ : result.exitCode === 0
3608
+ ? "Resumed session exited without new output"
3609
+ : `Resumed session exited with code ${result.exitCode}`);
3662
3610
  const presentation = resolveResultPresentation(
3663
3611
  { ...result, summary, sessionFile: params.sessionPath },
3664
3612
  name,
@@ -3671,12 +3619,8 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3671
3619
  exitCode: result.exitCode,
3672
3620
  elapsed: result.elapsed,
3673
3621
  sessionFile: params.sessionPath,
3674
- ...(result.errorMessage
3675
- ? { errorMessage: result.errorMessage }
3676
- : {}),
3677
- ...(running.runtimePlan
3678
- ? { runtimePlan: running.runtimePlan }
3679
- : {}),
3622
+ ...(result.errorMessage ? { errorMessage: result.errorMessage } : {}),
3623
+ ...(running.runtimePlan ? { runtimePlan: running.runtimePlan } : {}),
3680
3624
  });
3681
3625
  })
3682
3626
  .catch((err) => {
@@ -3847,10 +3791,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3847
3791
 
3848
3792
  const branch = parts.shift();
3849
3793
  if (!branch || branch === "list") {
3850
- ctx.ui.notify(
3851
- "Usage: /worktree <name> [task] | /worktree list",
3852
- "warning",
3853
- );
3794
+ ctx.ui.notify("Usage: /worktree <name> [task] | /worktree list", "warning");
3854
3795
  return;
3855
3796
  }
3856
3797
  if (!isTerminalAvailable()) {
@@ -3886,7 +3827,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3886
3827
  );
3887
3828
  const result = await launchPiWorktreeHandoff({
3888
3829
  kind: "fresh",
3889
- name: `Worktree: ${branch}`,
3830
+ name: `wt: ${branch}`,
3890
3831
  task,
3891
3832
  cwd: ctx.cwd,
3892
3833
  worktree: { branch },
@@ -3951,10 +3892,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
3951
3892
  ...formatVisibleAgentDefinitions(catalog.agents),
3952
3893
  ...formatAgentDiagnostics(catalog.diagnostics),
3953
3894
  ];
3954
- ctx.ui.notify(
3955
- lines.join("\n") || "No subagent definitions found.",
3956
- "info",
3957
- );
3895
+ ctx.ui.notify(lines.join("\n") || "No subagent definitions found.", "info");
3958
3896
  return;
3959
3897
  }
3960
3898
  if (!trimmed) {
@@ -4004,7 +3942,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
4004
3942
  typeof details.errorMessage === "string" ? details.errorMessage : "";
4005
3943
  const failed = exitCode !== 0 || !!errorMessage;
4006
3944
  const elapsed =
4007
- details.elapsed != null ? formatElapsed(details.elapsed) : "?";
3945
+ details.elapsed == null ? "?" : formatElapsed(details.elapsed);
4008
3946
  const bgFn = failed
4009
3947
  ? (text: string) => theme.bg("toolErrorBg", text)
4010
3948
  : (text: string) => theme.bg("toolSuccessBg", text);
@@ -4030,10 +3968,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
4030
3968
  const summary = rawContent
4031
3969
  .replace(/\n\nSession: .+\nResume: .+$/, "")
4032
3970
  .replace(`Sub-agent "${name}" completed (${elapsed}).\n\n`, "")
4033
- .replace(
4034
- `Sub-agent "${name}" failed (exit code ${exitCode}).\n\n`,
4035
- "",
4036
- )
3971
+ .replace(`Sub-agent "${name}" failed (exit code ${exitCode}).\n\n`, "")
4037
3972
  .replace(
4038
3973
  new RegExp(
4039
3974
  `^Sub-agent "${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}" failed after ${elapsed} \\(provider/agent error — auto-retry exhausted\\)\\.\\n\\n`,
@@ -4053,9 +3988,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
4053
3988
  }
4054
3989
  if (details.sessionFile) {
4055
3990
  contentLines.push("");
4056
- contentLines.push(
4057
- theme.fg("dim", `Session: ${details.sessionFile}`),
4058
- );
3991
+ contentLines.push(theme.fg("dim", `Session: ${details.sessionFile}`));
4059
3992
  contentLines.push(
4060
3993
  theme.fg("dim", `Resume: pi --session ${details.sessionFile}`),
4061
3994
  );
@@ -4069,9 +4002,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
4069
4002
  }
4070
4003
  const totalLines = summary.split("\n").length;
4071
4004
  if (totalLines > 5) {
4072
- contentLines.push(
4073
- theme.fg("muted", `… ${totalLines - 5} more lines`),
4074
- );
4005
+ contentLines.push(theme.fg("muted", `… ${totalLines - 5} more lines`));
4075
4006
  }
4076
4007
  }
4077
4008
  contentLines.push(
@@ -4091,8 +4022,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
4091
4022
  pi.registerMessageRenderer("subagent_status", (message, options, theme) => {
4092
4023
  const details = message.details as any;
4093
4024
  const lines = Array.isArray(details?.lines) ? details.lines : [];
4094
- const overflow =
4095
- typeof details?.overflow === "number" ? details.overflow : 0;
4025
+ const overflow = typeof details?.overflow === "number" ? details.overflow : 0;
4096
4026
  if (lines.length === 0 && overflow === 0) return undefined;
4097
4027
 
4098
4028
  return {
@@ -4148,9 +4078,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
4148
4078
  contentLines.push(details.message ?? "");
4149
4079
  if (details.sessionFile) {
4150
4080
  contentLines.push("");
4151
- contentLines.push(
4152
- theme.fg("dim", `Session: ${details.sessionFile}`),
4153
- );
4081
+ contentLines.push(theme.fg("dim", `Session: ${details.sessionFile}`));
4154
4082
  }
4155
4083
  } else {
4156
4084
  const preview = (details.message ?? "")