pi-extended-teams 2.3.2 → 2.3.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.
@@ -28,7 +28,7 @@ export interface AgentFollowTranscriptOptions {
28
28
 
29
29
  type TranscriptBlock =
30
30
  | { kind: "section"; label: "user" | "thinking" | "assistant"; text: string }
31
- | { kind: "tool"; id?: string; name: string; args: unknown; result?: string; details?: unknown; isError?: boolean };
31
+ | { kind: "tool"; id?: string; name: string; args: unknown; result?: string; readSummary?: string; details?: unknown; isError?: boolean };
32
32
 
33
33
  function stringifyToolArgs(args: unknown): string {
34
34
  if (args === undefined) return "";
@@ -42,6 +42,7 @@ function stringifyToolArgs(args: unknown): string {
42
42
  function compactToolArgs(name: string, args: unknown): string {
43
43
  if (!args || typeof args !== "object") return sanitizeTuiLine(stringifyToolArgs(args));
44
44
  const values = args as Record<string, unknown>;
45
+ if (name === "ls") return compactTranscriptLine(String(values.path ?? "."));
45
46
  const primary = name === "bash"
46
47
  ? values.command
47
48
  : name === "read"
@@ -226,6 +227,14 @@ function renderToolBlock(theme: ExtendedTeamsTheme, block: Extract<TranscriptBlo
226
227
  if (compactBlock) return compactBlock;
227
228
 
228
229
  const header = renderToolHeader(theme, block);
230
+ if (!expandLargeToolResults && (block.name === "read" || block.name === "bash" || block.name === "ls")) {
231
+ const state = block.result === undefined
232
+ ? pendingText(theme, "working")
233
+ : block.isError ? failureText(theme, "✗") : successText(theme, "✓");
234
+ const summary = block.name === "read" && !block.isError && block.readSummary
235
+ ? mutedText(theme, ` · ${block.readSummary}`) : "";
236
+ return [boundTranscriptLine(`${header}${summary}${mutedText(theme, " · ")}${state}`, width)];
237
+ }
229
238
  if (block.result === undefined) {
230
239
  return [header, `${structuralText(theme, "│")} ${pendingText(theme, "waiting for result…")}`, `${structuralText(theme, "╰─")} ${pendingText(theme, "running")}`, ""];
231
240
  }
@@ -290,28 +299,40 @@ export function formatAgentFollowTranscript(messages: any[], options: AgentFollo
290
299
  const name = sanitizeTuiLine(String(message.toolName || "tool"));
291
300
  const matchingTool = (id ? toolsById.get(id) : undefined)
292
301
  ?? blocks.slice().reverse().find((block): block is Extract<TranscriptBlock, { kind: "tool" }> => block.kind === "tool" && block.result === undefined && block.name === name);
302
+ let readSummary: string | undefined;
303
+ if ((matchingTool?.name ?? name) === "read") {
304
+ const text = typeof message.content === "string" ? message.content
305
+ : (Array.isArray(message.content) ? message.content : [])
306
+ .filter((part: any) => part?.type === "text" && typeof part.text === "string")
307
+ .map((part: any) => part.text).join("\n");
308
+ const lineCount = text ? text.replace(/\r\n?/g, "\n").replace(/\n$/, "").split("\n").length : 0;
309
+ readSummary = `${lineCount} line${lineCount === 1 ? "" : "s"} · ${formatResultSize(text)}`;
310
+ }
293
311
  const result = sanitizeTuiText(extractTextParts(message.content));
294
312
  const isError = typeof message.isError === "boolean" ? message.isError : undefined;
295
313
  if (matchingTool) {
296
314
  matchingTool.result = result;
315
+ matchingTool.readSummary = readSummary;
297
316
  matchingTool.details = message.details;
298
317
  matchingTool.isError = isError;
299
318
  } else {
300
- blocks.push({ kind: "tool", id, name, args: undefined, result, details: message.details, isError });
319
+ blocks.push({ kind: "tool", id, name, args: undefined, result, readSummary, details: message.details, isError });
301
320
  }
302
321
  }
303
322
  }
304
323
 
305
- const lines = blocks.flatMap(block => {
324
+ const lines: string[] = [];
325
+ for (const block of blocks) {
306
326
  if (block.kind === "tool") {
307
- return renderToolBlock(theme, block, options.expandLargeToolResults === true, options.width);
327
+ lines.push(...renderToolBlock(theme, block, options.expandLargeToolResults === true, options.width));
328
+ } else if (block.label === "thinking") {
329
+ if (lines.length > 0 && lines[lines.length - 1] !== "") lines.push("");
330
+ lines.push(theme.fg("thinkingText", block.label), block.text.replace(/\*\*/g, ""), "");
331
+ } else {
332
+ const labelToken = block.label === "user" ? "customMessageLabel" : "accent";
333
+ lines.push(theme.fg(labelToken, block.label), block.text, "");
308
334
  }
309
- if (block.label === "thinking") {
310
- return [theme.fg("thinkingText", block.label), block.text.replace(/\*\*/g, ""), ""];
311
- }
312
- const labelToken = block.label === "user" ? "customMessageLabel" : "accent";
313
- return [theme.fg(labelToken, block.label), block.text, ""];
314
- });
335
+ }
315
336
  return lines.length > 0 ? lines : [theme.fg("dim", "Waiting for the agent's first transcript event…")];
316
337
  }
317
338
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-extended-teams",
3
- "version": "2.3.2",
3
+ "version": "2.3.3",
4
4
  "description": "Control-first, session-connected subagents for Pi with live navigation and intent-tier routing",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,7 +28,7 @@
28
28
  "scripts": {
29
29
  "typecheck": "tsc --noEmit",
30
30
  "test": "vitest run",
31
- "test:focused": "vitest run src/utils/claims.test.ts src/utils/tasks.test.ts src/utils/model-resolution.test.ts src/utils/settings.test.ts src/utils/write-queue.test.ts src/utils/shared-memory.test.ts extensions/index.test.ts extensions/events/register-events.test.ts extensions/internal/session-files.test.ts extensions/team/contracts.test.ts extensions/tools/delegation-guard.test.ts extensions/tools/agent-communication-tools.test.ts extensions/tools/read-helper.test.ts extensions/agents/read-agent.test.ts extensions/agents/write-agent.test.ts extensions/tools/team-tools.read-agent.test.ts extensions/ui/agent-follow-view.test.ts extensions/tools/coordination-tools.test.ts",
31
+ "test:focused": "vitest run --maxWorkers=2 src/utils/claims.test.ts src/utils/tasks.test.ts src/utils/model-resolution.test.ts src/utils/settings.test.ts src/utils/write-queue.test.ts src/utils/shared-memory.test.ts extensions/index.test.ts extensions/events/register-events.test.ts extensions/internal/session-files.test.ts extensions/team/contracts.test.ts extensions/tools/delegation-guard.test.ts extensions/tools/agent-communication-tools.test.ts extensions/tools/read-helper.test.ts extensions/agents/read-agent.test.ts extensions/agents/write-agent.test.ts extensions/tools/team-tools.read-agent.test.ts extensions/ui/agent-follow-view.test.ts extensions/tools/coordination-tools.test.ts",
32
32
  "build": "tsc --noEmit"
33
33
  },
34
34
  "main": "extensions/index.ts",