pi-agent-flow 1.5.0 → 1.6.0

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": "pi-agent-flow",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Flow-state delegation extension for Pi coding agent.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -108,12 +108,15 @@ export function getTruncationBudget(prefixLength: number): number {
108
108
  /** Fixed content budget for collapsed-line text (dir/act/log). */
109
109
  export const CONTENT_MAX = 60;
110
110
 
111
+ /** Longer budget for detail lines (act/msg) to show more content. */
112
+ export const DETAIL_CONTENT_MAX = 80;
113
+
111
114
  /**
112
115
  * Compute how many visible chars of content fit after a prefix,
113
- * using the fixed CONTENT_MAX budget. Floor of 8 to keep things readable.
116
+ * using the given budget (defaults to CONTENT_MAX). Floor of 8 to keep things readable.
114
117
  */
115
- export function contentBudget(prefixVisibleLen: number): number {
116
- return Math.max(CONTENT_MAX - prefixVisibleLen, 8);
118
+ export function contentBudget(prefixVisibleLen: number, max = CONTENT_MAX): number {
119
+ return Math.max(max - prefixVisibleLen, 8);
117
120
  }
118
121
 
119
122
  /**
package/src/render.ts CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  isFlowError,
23
23
  isFlowSuccess,
24
24
  } from "./types.js";
25
- import { formatCompactStats, formatCompactTokenPair, formatCountdown, formatFlowTypeName, truncateChars, tailText, contentBudget, visibleLength } from "./render-utils.js";
25
+ import { formatCompactStats, formatCompactTokenPair, formatCountdown, formatFlowTypeName, truncateChars, tailText, contentBudget, visibleLength, DETAIL_CONTENT_MAX } from "./render-utils.js";
26
26
 
27
27
  function shortenPath(p: string): string {
28
28
  const home = os.homedir();
@@ -33,6 +33,12 @@ type ThemeFg = (color: string, text: string) => string;
33
33
  type ThemeBg = (color: string, text: string) => string;
34
34
  type FlowTheme = { fg: ThemeFg; bold: (s: string) => string; bg: ThemeBg };
35
35
 
36
+ const COLLAPSED_FLOW_HEADER_TYPE_WIDTH = 8;
37
+
38
+ function formatCollapsedFlowHeaderTypeName(type: string): string {
39
+ return formatFlowTypeName(type).padEnd(COLLAPSED_FLOW_HEADER_TYPE_WIDTH, " ");
40
+ }
41
+
36
42
  function formatFlowToolCall(toolName: string, args: Record<string, unknown>, fg: ThemeFg): string {
37
43
  const pathArg = (args.file_path || args.path || "...") as string;
38
44
 
@@ -320,8 +326,8 @@ function renderFlowCollapsed(
320
326
  const container = new Container();
321
327
  const maxWidth = process.stdout.columns ?? 80;
322
328
  const stats = formatCompactStats(r.usage, r.model, maxWidth, { skipTokens: true });
323
- const typeName = formatFlowTypeName(r.type);
324
- let header = `${theme.fg("accent", theme.bold(typeName))} ${theme.fg("dim", stats)}`;
329
+ const typeName = formatCollapsedFlowHeaderTypeName(r.type);
330
+ let header = `${theme.fg("accent", theme.bold(typeName))}${theme.fg("dim", `· ${stats}`)}`;
325
331
  if (error && r.stopReason) header += ` ${theme.fg("error", `[${r.stopReason}]`)}`;
326
332
  container.addChild(new TruncatedText(header, 0, 0));
327
333
 
@@ -337,13 +343,13 @@ function renderFlowCollapsed(
337
343
  if (lastTool) {
338
344
  const actStr = formatFlowToolCall(lastTool.name, lastTool.args, theme.fg.bind(theme));
339
345
  const actPrefix = `├─ act: [${r.usage.toolCalls}] - `;
340
- const actContent = truncateChars(actStr, contentBudget(visibleLength(actPrefix)));
346
+ const actContent = truncateChars(actStr, contentBudget(visibleLength(actPrefix), DETAIL_CONTENT_MAX));
341
347
  container.addChild(new TruncatedText(`${theme.fg("dim", actPrefix)}${actContent}`, 0, 0));
342
348
  }
343
349
 
344
350
  // msg: line (last assistant text or streaming)
345
351
  const msgPrefix = formatMsgLinePrefix("└─", r);
346
- const msgBudget = contentBudget(visibleLength(msgPrefix));
352
+ const msgBudget = contentBudget(visibleLength(msgPrefix), DETAIL_CONTENT_MAX);
347
353
  if (r.exitCode === -1 && streamingText) {
348
354
  const logContent = tailText(streamingText, msgBudget);
349
355
  container.addChild(new TruncatedText(`${theme.fg("dim", msgPrefix)}${theme.fg("dim", logContent)}`, 0, 0));
@@ -453,11 +459,11 @@ function renderActivityPanel(
453
459
  const isLast = i === results.length - 1;
454
460
  const stats = formatCompactStats(r.usage, r.model, maxWidth, { skipTokens: true });
455
461
  const error = isFlowError(r);
456
- const typeName = formatFlowTypeName(r.type);
462
+ const typeName = formatCollapsedFlowHeaderTypeName(r.type);
457
463
 
458
464
  // Header line
459
465
  const headerPrefix = isLast ? "└─" : "├─";
460
- let headerLine = `${theme.fg("dim", headerPrefix)} ${theme.fg("accent", theme.bold(typeName))} ${theme.fg("dim", stats)}`;
466
+ let headerLine = `${theme.fg("dim", headerPrefix)} ${theme.fg("accent", theme.bold(typeName))}${theme.fg("dim", `· ${stats}`)}`;
461
467
  if (error && r.stopReason) {
462
468
  headerLine += ` ${theme.fg("error", `[${r.stopReason}]`)}`;
463
469
  }
@@ -478,13 +484,13 @@ function renderActivityPanel(
478
484
  if (lastTool) {
479
485
  const actStr = formatFlowToolCall(lastTool.name, lastTool.args, theme.fg.bind(theme));
480
486
  const actPrefix = `${indent}├─ act: [${r.usage.toolCalls}] - `;
481
- const actContent = truncateChars(actStr, contentBudget(visibleLength(actPrefix)));
487
+ const actContent = truncateChars(actStr, contentBudget(visibleLength(actPrefix), DETAIL_CONTENT_MAX));
482
488
  container.addChild(new TruncatedText(`${theme.fg("dim", actPrefix)}${actContent}`, 0, 0));
483
489
  }
484
490
 
485
491
  // msg: line (live streaming text or last assistant text)
486
492
  const msgPrefix = formatMsgLinePrefix(indent + "└─", r);
487
- const msgBudget = contentBudget(visibleLength(msgPrefix));
493
+ const msgBudget = contentBudget(visibleLength(msgPrefix), DETAIL_CONTENT_MAX);
488
494
  const liveText = r.exitCode === -1 ? r.streamingText : undefined;
489
495
  const lastText = liveText || getLastAssistantText(r.messages);
490
496
  if (lastText) {