pi-bar 0.3.25 → 0.3.26

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/README.md CHANGED
@@ -9,9 +9,9 @@
9
9
  claude-opus-4.7 ❯ think:med ❯ 2.6% / 1.0M ❯ Inspecting package structure ❯ plan:active
10
10
  ```
11
11
 
12
- ![pi-bar with low context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.25/assets/screenshot-green.png)
13
- ![pi-bar with medium context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.25/assets/screenshot-yellow.png)
14
- ![pi-bar with high context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.25/assets/screenshot-red.png)
12
+ ![pi-bar with low context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.26/assets/screenshot-green.png)
13
+ ![pi-bar with medium context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.26/assets/screenshot-yellow.png)
14
+ ![pi-bar with high context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.26/assets/screenshot-red.png)
15
15
 
16
16
  ## Why use it?
17
17
 
@@ -43,11 +43,7 @@ type SerializedStatusFilter =
43
43
  type TldrActivityType =
44
44
  | "user_message"
45
45
  | "assistant_update"
46
- | "tool_input_start"
47
- | "tool_input_update"
48
- | "tool_input_end"
49
46
  | "tool_call"
50
- | "tool_execution_update"
51
47
  | "tool_result"
52
48
  | "assistant_final"
53
49
  | "assistant_failure";
@@ -58,36 +54,17 @@ type TldrActivity = {
58
54
  displayPriority: TldrDisplayPriority;
59
55
  text: string;
60
56
  toolCallId?: string;
61
- // Identifies a continuous streaming run (tool input arg streaming, or tool
62
- // execution output streaming). Activities sharing a group represent updates
63
- // to the same task; staleness handling treats them as one stream.
64
- progressGroup?: string;
65
57
  };
66
58
  type TldrCheckpoint = {
67
59
  activityIndex: number;
68
- activityType: TldrActivityType;
69
60
  displayPriority: TldrDisplayPriority;
70
61
  text: string;
71
- progressGroup?: string;
72
62
  };
73
63
  type TldrCheckpointJob = {
74
64
  activityIndex: number;
75
- activityType: TldrActivityType;
76
65
  displayPriority: TldrDisplayPriority;
77
66
  runId: number;
78
- progressGroup?: string;
79
67
  };
80
-
81
- // Activities that represent ongoing streaming work. These are treated
82
- // specially: their checkpoints can render even when newer same-stream activity
83
- // exists, and the display refresh slows to a 10s cadence for repeat renders so
84
- // the footer does not become a model-call ticker.
85
- function isToolProgressActivity(activityType: TldrActivityType): boolean {
86
- return (
87
- activityType === "tool_input_update" ||
88
- activityType === "tool_execution_update"
89
- );
90
- }
91
68
  type TldrModelPreference = { provider: string; id: string };
92
69
  type FastModelAuth = {
93
70
  model: Parameters<typeof complete>[0];
@@ -111,12 +88,6 @@ const TLDR_MAX_TOKENS = 120;
111
88
  const TLDR_REQUEST_TIMEOUT_MS = 2_000;
112
89
  const TLDR_DISPLAY_UPDATE_INTERVAL_MS = 1_200;
113
90
  const TLDR_TARGET_SUMMARY_CHARS = 60;
114
- // While rendering successive progress checkpoints from the same stream (e.g.
115
- // long bash output), slow the display refresh dramatically. The TLDR text
116
- // barely changes between adjacent chunks; refreshing every 1.2s would burn API
117
- // calls and footer renders for noise.
118
- const TOOL_PROGRESS_DISPLAY_UPDATE_INTERVAL_MS = 10_000;
119
- const MAX_TOOL_PROGRESS_PARTIAL_CHARS = 280;
120
91
  // Burst debouncing on the generation side: coalesce rapid-fire activities into
121
92
  // one model call. Quiet window catches short bursts; max wait surfaces progress
122
93
  // during continuous activity.
@@ -477,58 +448,13 @@ function extractTextContent(content: readonly unknown[] | undefined): string | u
477
448
  return compacted.length > 0 ? compacted : undefined;
478
449
  }
479
450
 
480
- type ToolInputAssistantEvent =
481
- | { type: "toolcall_start"; contentIndex: number; partial: unknown }
482
- | {
483
- type: "toolcall_delta";
484
- contentIndex: number;
485
- delta: string;
486
- partial: unknown;
487
- }
488
- | {
489
- type: "toolcall_end";
490
- contentIndex: number;
491
- toolCall: { id: string; name: string; arguments?: unknown };
492
- partial: unknown;
493
- };
494
-
495
- function toolCallAtContentIndex(
496
- partial: unknown,
497
- contentIndex: number,
498
- ): { id: string; name: string; arguments?: unknown } | undefined {
499
- if (!partial || typeof partial !== "object") return undefined;
500
- const content = (partial as { content?: unknown }).content;
501
- if (!Array.isArray(content)) return undefined;
502
- const block = content[contentIndex];
503
- if (!block || typeof block !== "object") return undefined;
504
- const record = block as Record<string, unknown>;
505
- if (record.type !== "toolCall") return undefined;
506
- if (typeof record.id !== "string" || typeof record.name !== "string") {
507
- return undefined;
508
- }
509
- return {
510
- id: record.id,
511
- name: record.name,
512
- arguments: record.arguments,
513
- };
514
- }
515
-
516
451
  class TldrFactCollector {
517
452
  private nextIndex = 1;
518
453
  private readonly activities: TldrActivity[] = [];
519
- // Streaming tool inputs (`toolcall_start/delta/end` from message_update)
520
- // arrive before the final tool id is available; content index is the best
521
- // stable anchor until the id appears.
522
- private readonly activeToolInputAnchors = new Map<string, string>();
523
454
 
524
455
  resetConversation(): void {
525
456
  this.nextIndex = 1;
526
457
  this.activities.splice(0);
527
- this.activeToolInputAnchors.clear();
528
- }
529
-
530
- latestActivity(): TldrActivity | undefined {
531
- return this.activities[this.activities.length - 1];
532
458
  }
533
459
 
534
460
  recordUserMessage(prompt: string): TldrActivity {
@@ -560,79 +486,6 @@ class TldrFactCollector {
560
486
  );
561
487
  }
562
488
 
563
- // Stage 1: tool input streaming. The model is writing tool name + args; pi
564
- // surfaces this via `assistantMessageEvent` on `message_update` with
565
- // toolcall_start / toolcall_delta / toolcall_end. Useful when args are long
566
- // (big edits, structured plans) and the user wants visible progress before
567
- // the actual tool execution starts.
568
- recordToolInputActivity(
569
- event: ToolInputAssistantEvent | undefined,
570
- ): TldrActivity | undefined {
571
- if (!event) return undefined;
572
-
573
- switch (event.type) {
574
- case "toolcall_start": {
575
- const toolCall = toolCallAtContentIndex(event.partial, event.contentIndex);
576
- const toolName = toolCall?.name ?? "unknown";
577
- const anchorKey = toolCall?.id ?? `content:${event.contentIndex}`;
578
- const anchorText = `tool input: ${toolName}`;
579
- this.activeToolInputAnchors.set(anchorKey, anchorText);
580
- return this.addActivity(
581
- "tool_input_start",
582
- "normal",
583
- anchorText,
584
- toolCall?.id,
585
- );
586
- }
587
- case "toolcall_delta": {
588
- const toolCall = toolCallAtContentIndex(event.partial, event.contentIndex);
589
- const anchorKey = toolCall?.id ?? `content:${event.contentIndex}`;
590
- const anchorText =
591
- this.activeToolInputAnchors.get(anchorKey) ??
592
- `tool input: ${toolCall?.name ?? "unknown"}`;
593
-
594
- // Repeated delta updates for the same call collapse into the latest
595
- // snapshot. Otherwise long arg streams would push out useful facts.
596
- const last = this.activities[this.activities.length - 1];
597
- if (
598
- last?.activityType === "tool_input_update" &&
599
- last.progressGroup === `tool-input:${anchorKey}`
600
- ) {
601
- this.activities.pop();
602
- }
603
-
604
- const argSnapshot = compactValue(toolCall?.arguments, 200);
605
- const chunk = event.delta
606
- ? `latest: ${truncateText(compactText(event.delta), 120)}`
607
- : undefined;
608
- const update = [argSnapshot, chunk].filter(Boolean).join("; ");
609
-
610
- return this.addActivity(
611
- "tool_input_update",
612
- "normal",
613
- `${anchorText}; ${update || "streaming"}`,
614
- toolCall?.id,
615
- `tool-input:${anchorKey}`,
616
- );
617
- }
618
- case "toolcall_end": {
619
- const anchorKey = event.toolCall.id;
620
- const anchorText =
621
- this.activeToolInputAnchors.get(anchorKey) ??
622
- `tool input: ${event.toolCall.name}`;
623
- this.activeToolInputAnchors.delete(anchorKey);
624
-
625
- const args = compactValue(event.toolCall.arguments, 240);
626
- return this.addActivity(
627
- "tool_input_end",
628
- "normal",
629
- args ? `${anchorText} completed; ${args}` : `${anchorText} completed`,
630
- event.toolCall.id,
631
- );
632
- }
633
- }
634
- }
635
-
636
489
  recordToolCall(event: {
637
490
  toolName: string;
638
491
  input?: Record<string, unknown>;
@@ -646,45 +499,6 @@ class TldrFactCollector {
646
499
  );
647
500
  }
648
501
 
649
- // Stage 2: tool execution streaming. The host is running the tool and
650
- // emitting partial output. Tagged with progressGroup so adjacent chunks of
651
- // the same execution are treated as one continuous stream.
652
- recordToolExecutionUpdate(event: {
653
- toolCallId: string;
654
- toolName: string;
655
- partialResult: unknown;
656
- }): TldrActivity {
657
- const partialText =
658
- extractTextContent(
659
- Array.isArray((event.partialResult as { content?: unknown })?.content)
660
- ? ((event.partialResult as { content: unknown[] }).content as unknown[])
661
- : undefined,
662
- ) ??
663
- compactValue(event.partialResult, MAX_TOOL_PROGRESS_PARTIAL_CHARS) ??
664
- "streaming";
665
-
666
- const progressGroup = `tool-execution:${event.toolCallId}`;
667
-
668
- // Adjacent execution-update activities for the same stream collapse into
669
- // the latest. The retained activity list stays bounded and the model sees
670
- // one current snapshot of in-progress output.
671
- const last = this.activities[this.activities.length - 1];
672
- if (
673
- last?.activityType === "tool_execution_update" &&
674
- last.progressGroup === progressGroup
675
- ) {
676
- this.activities.pop();
677
- }
678
-
679
- return this.addActivity(
680
- "tool_execution_update",
681
- "normal",
682
- `running ${event.toolName}; ${tailText(partialText, MAX_TOOL_PROGRESS_PARTIAL_CHARS)}`,
683
- event.toolCallId,
684
- progressGroup,
685
- );
686
- }
687
-
688
502
  recordToolResult(event: {
689
503
  toolName: string;
690
504
  input?: Record<string, unknown>;
@@ -703,24 +517,15 @@ class TldrFactCollector {
703
517
  const status = isError ? "error" : "ok";
704
518
  const tool = compactToolInput(event.toolName, event.input);
705
519
 
706
- // The completed result fact subsumes all in-progress facts for the same
707
- // call: the original tool_call, any tool_input_* lifecycle facts, and any
708
- // tool_execution_update progress. The model only needs the final outcome.
520
+ // Result fact subsumes the prior tool_call fact for the same call. Drop the
521
+ // matching tool_call so the model sees one combined fact instead of two.
709
522
  if (event.toolCallId) {
710
- const id = event.toolCallId;
711
- for (let i = this.activities.length - 1; i >= 0; i--) {
712
- const activity = this.activities[i];
713
- if (activity.toolCallId !== id) continue;
714
- if (
715
- activity.activityType === "tool_call" ||
716
- activity.activityType === "tool_input_start" ||
717
- activity.activityType === "tool_input_update" ||
718
- activity.activityType === "tool_input_end" ||
719
- activity.activityType === "tool_execution_update"
720
- ) {
721
- this.activities.splice(i, 1);
722
- }
723
- }
523
+ const idx = this.activities.findIndex(
524
+ (activity) =>
525
+ activity.activityType === "tool_call" &&
526
+ activity.toolCallId === event.toolCallId,
527
+ );
528
+ if (idx !== -1) this.activities.splice(idx, 1);
724
529
  }
725
530
 
726
531
  return this.addActivity(
@@ -788,15 +593,13 @@ class TldrFactCollector {
788
593
  displayPriority: TldrDisplayPriority,
789
594
  text: string,
790
595
  toolCallId?: string,
791
- progressGroup?: string,
792
596
  ): TldrActivity {
793
- const activity: TldrActivity = {
597
+ const activity = {
794
598
  index: this.nextIndex,
795
599
  activityType,
796
600
  displayPriority,
797
601
  text: truncateText(text, MAX_ACTIVITY_TEXT_CHARS),
798
602
  toolCallId,
799
- progressGroup,
800
603
  };
801
604
  this.nextIndex++;
802
605
  this.activities.push(activity);
@@ -828,9 +631,6 @@ class FooterTldrEngine {
828
631
  private pendingNormalCheckpoint?: TldrCheckpointJob;
829
632
  private normalCheckpointTimer?: ReturnType<typeof setTimeout>;
830
633
  private normalCheckpointBurstStartedAt?: number;
831
- // Last progress stream that produced a rendered checkpoint. Used to slow the
832
- // display refresh for repeat renders from the same stream.
833
- private lastRenderedProgressGroup?: string;
834
634
 
835
635
  constructor(private readonly requestRender: () => void) {}
836
636
 
@@ -855,22 +655,7 @@ class FooterTldrEngine {
855
655
  this.enqueue(ctx, this.facts.recordUserMessage(prompt));
856
656
  }
857
657
 
858
- recordAssistantUpdate(
859
- ctx: ExtensionContext,
860
- message: unknown,
861
- assistantMessageEvent?: unknown,
862
- ): void {
863
- // Tool input streaming hides inside `message_update`. Drain that signal
864
- // first; only if no tool-input fact was produced does this look like a
865
- // plain assistant text update worth recording.
866
- const toolInputActivity = this.facts.recordToolInputActivity(
867
- normalizeToolInputEvent(assistantMessageEvent),
868
- );
869
- if (toolInputActivity) {
870
- this.enqueue(ctx, toolInputActivity);
871
- return;
872
- }
873
-
658
+ recordAssistantUpdate(ctx: ExtensionContext, message: unknown): void {
874
659
  const activity = this.facts.recordAssistantUpdate(message);
875
660
  if (activity) this.enqueue(ctx, activity);
876
661
  }
@@ -882,17 +667,6 @@ class FooterTldrEngine {
882
667
  this.enqueue(ctx, this.facts.recordToolCall(event));
883
668
  }
884
669
 
885
- recordToolExecutionUpdate(
886
- ctx: ExtensionContext,
887
- event: {
888
- toolCallId: string;
889
- toolName: string;
890
- partialResult: unknown;
891
- },
892
- ): void {
893
- this.enqueue(ctx, this.facts.recordToolExecutionUpdate(event));
894
- }
895
-
896
670
  recordToolResult(
897
671
  ctx: ExtensionContext,
898
672
  event: {
@@ -927,7 +701,6 @@ class FooterTldrEngine {
927
701
  this.lastDisplayAt = Number.NEGATIVE_INFINITY;
928
702
  this.acceptedCheckpoints.splice(0);
929
703
  this.pendingDisplayCheckpoint = undefined;
930
- this.lastRenderedProgressGroup = undefined;
931
704
  this.currentText = null;
932
705
  this.requestRender();
933
706
  }
@@ -996,12 +769,10 @@ class FooterTldrEngine {
996
769
 
997
770
  private enqueue(ctx: ExtensionContext, activity: TldrActivity): void {
998
771
  if (!ctx.hasUI) return;
999
- const job: TldrCheckpointJob = {
772
+ const job = {
1000
773
  activityIndex: activity.index,
1001
- activityType: activity.activityType,
1002
774
  displayPriority: activity.displayPriority,
1003
775
  runId: this.runId,
1004
- progressGroup: activity.progressGroup,
1005
776
  };
1006
777
 
1007
778
  if (job.displayPriority === "immediate") {
@@ -1035,13 +806,9 @@ class FooterTldrEngine {
1035
806
  this.scheduleNormalCheckpoint(ctx, job);
1036
807
  }
1037
808
 
1038
- private clearDisplayTimer(): void {
809
+ private clearPendingDisplay(): void {
1039
810
  if (this.displayTimer) clearTimeout(this.displayTimer);
1040
811
  this.displayTimer = undefined;
1041
- }
1042
-
1043
- private clearPendingDisplay(): void {
1044
- this.clearDisplayTimer();
1045
812
  this.pendingDisplayCheckpoint = undefined;
1046
813
  }
1047
814
 
@@ -1099,12 +866,10 @@ class FooterTldrEngine {
1099
866
  const rawText = extractTextContent(response.content) ?? "";
1100
867
  const text = sanitizeTldrText(rawText);
1101
868
  if (!text) return;
1102
- const checkpoint: TldrCheckpoint = {
869
+ const checkpoint = {
1103
870
  activityIndex: job.activityIndex,
1104
- activityType: job.activityType,
1105
871
  displayPriority: job.displayPriority,
1106
872
  text,
1107
- progressGroup: job.progressGroup,
1108
873
  };
1109
874
  this.acceptCheckpoint(checkpoint);
1110
875
  this.considerDisplayingCheckpoint(ctx, checkpoint);
@@ -1136,7 +901,7 @@ class FooterTldrEngine {
1136
901
  checkpoint: TldrCheckpoint,
1137
902
  ): void {
1138
903
  if (checkpoint.activityIndex <= this.lastRenderedActivityIndex) return;
1139
- if (this.shouldDropStaleCheckpoint(checkpoint)) return;
904
+ if (checkpoint.activityIndex !== this.facts.latestActivityIndex()) return;
1140
905
 
1141
906
  if (checkpoint.displayPriority !== "normal" || !this.lastRenderedText) {
1142
907
  this.clearPendingDisplay();
@@ -1144,66 +909,22 @@ class FooterTldrEngine {
1144
909
  return;
1145
910
  }
1146
911
 
1147
- const displayIntervalMs = this.displayIntervalFor(checkpoint);
1148
912
  const elapsedMs = performance.now() - this.lastDisplayAt;
1149
- if (elapsedMs >= displayIntervalMs) {
913
+ if (elapsedMs >= TLDR_DISPLAY_UPDATE_INTERVAL_MS) {
1150
914
  this.clearPendingDisplay();
1151
915
  this.renderCheckpoint(checkpoint);
1152
916
  return;
1153
917
  }
1154
918
 
1155
919
  this.pendingDisplayCheckpoint = checkpoint;
1156
- // Recompute the timer for each newly accepted pending checkpoint. A long
1157
- // 10s progress-stream debounce should not block a subsequent ordinary
1158
- // update that wants to render at the normal 1.2s cadence.
1159
- this.clearDisplayTimer();
920
+ if (this.displayTimer) return;
1160
921
  this.displayTimer = setTimeout(() => {
1161
922
  this.displayTimer = undefined;
1162
923
  const pending = this.pendingDisplayCheckpoint;
1163
924
  this.pendingDisplayCheckpoint = undefined;
1164
- if (!pending) return;
1165
- if (this.shouldDropStaleCheckpoint(pending)) return;
925
+ if (!pending || pending.activityIndex !== this.facts.latestActivityIndex()) return;
1166
926
  this.renderCheckpoint(pending);
1167
- }, displayIntervalMs - elapsedMs);
1168
- }
1169
-
1170
- // A model call for chunk N may finish after chunk N+1 has been recorded.
1171
- // Most stale checkpoints are dropped, but progress streams are an exception:
1172
- // while the same stream is still active, a slightly-behind TLDR is still
1173
- // useful, and dropping it would leave the footer stuck on older text.
1174
- private shouldDropStaleCheckpoint(checkpoint: TldrCheckpoint): boolean {
1175
- if (checkpoint.activityIndex === this.facts.latestActivityIndex()) {
1176
- return false;
1177
- }
1178
-
1179
- // Boundary checkpoints (user_message, assistant_final, etc.) must stay
1180
- // latest-only. A stale prompt-start or final TLDR would describe the wrong
1181
- // turn entirely.
1182
- if (checkpoint.displayPriority !== "normal") return true;
1183
-
1184
- if (!isToolProgressActivity(checkpoint.activityType)) return true;
1185
- if (!checkpoint.progressGroup) return true;
1186
-
1187
- const latestActivity = this.facts.latestActivity();
1188
- return !(
1189
- latestActivity &&
1190
- latestActivity.index > checkpoint.activityIndex &&
1191
- latestActivity.activityType === checkpoint.activityType &&
1192
- latestActivity.progressGroup === checkpoint.progressGroup
1193
- );
1194
- }
1195
-
1196
- private displayIntervalFor(checkpoint: TldrCheckpoint): number {
1197
- if (!isToolProgressActivity(checkpoint.activityType)) {
1198
- return TLDR_DISPLAY_UPDATE_INTERVAL_MS;
1199
- }
1200
- // First render from a new progress group uses the normal cadence so the
1201
- // user sees the stream's first TLDR quickly. Subsequent renders for the
1202
- // same group slow down: the model output barely changes between chunks.
1203
- return checkpoint.progressGroup &&
1204
- checkpoint.progressGroup === this.lastRenderedProgressGroup
1205
- ? TOOL_PROGRESS_DISPLAY_UPDATE_INTERVAL_MS
1206
- : TLDR_DISPLAY_UPDATE_INTERVAL_MS;
927
+ }, TLDR_DISPLAY_UPDATE_INTERVAL_MS - elapsedMs);
1207
928
  }
1208
929
 
1209
930
  private renderCheckpoint(checkpoint: TldrCheckpoint): void {
@@ -1212,9 +933,6 @@ class FooterTldrEngine {
1212
933
  this.lastRenderedActivityIndex = checkpoint.activityIndex;
1213
934
  this.lastRenderedText = checkpoint.text;
1214
935
  this.lastDisplayAt = performance.now();
1215
- this.lastRenderedProgressGroup = isToolProgressActivity(checkpoint.activityType)
1216
- ? checkpoint.progressGroup
1217
- : undefined;
1218
936
  this.currentText = checkpoint.text;
1219
937
  this.requestRender();
1220
938
  }
@@ -1283,50 +1001,6 @@ function formatRawActivity(activity: TldrActivity): string {
1283
1001
  return `- ${activity.text}`;
1284
1002
  }
1285
1003
 
1286
- // Narrows the unknown `assistantMessageEvent` from `message_update` to the
1287
- // three tool-input streaming variants. Other event shapes (text_start, etc.)
1288
- // produce undefined, signalling "no tool input fact to record".
1289
- function normalizeToolInputEvent(value: unknown): ToolInputAssistantEvent | undefined {
1290
- if (!value || typeof value !== "object") return undefined;
1291
- const record = value as Record<string, unknown>;
1292
- const type = record.type;
1293
- if (type !== "toolcall_start" && type !== "toolcall_delta" && type !== "toolcall_end") {
1294
- return undefined;
1295
- }
1296
- if (typeof record.contentIndex !== "number") return undefined;
1297
-
1298
- if (type === "toolcall_delta") {
1299
- return {
1300
- type,
1301
- contentIndex: record.contentIndex,
1302
- delta: typeof record.delta === "string" ? record.delta : "",
1303
- partial: record.partial,
1304
- };
1305
- }
1306
- if (type === "toolcall_end") {
1307
- const toolCall = record.toolCall;
1308
- if (
1309
- !toolCall ||
1310
- typeof toolCall !== "object" ||
1311
- typeof (toolCall as Record<string, unknown>).id !== "string" ||
1312
- typeof (toolCall as Record<string, unknown>).name !== "string"
1313
- ) {
1314
- return undefined;
1315
- }
1316
- return {
1317
- type,
1318
- contentIndex: record.contentIndex,
1319
- toolCall: toolCall as { id: string; name: string; arguments?: unknown },
1320
- partial: record.partial,
1321
- };
1322
- }
1323
- return {
1324
- type,
1325
- contentIndex: record.contentIndex,
1326
- partial: record.partial,
1327
- };
1328
- }
1329
-
1330
1004
  // Strips ANSI/CSI/OSC/DCS/SOS/PM/APC escape sequences from model output before
1331
1005
  // it lands in the terminal. The TLDR text is model-controlled and renders into
1332
1006
  // the footer; the system prompt asking for plain text is not a security
@@ -1744,18 +1418,11 @@ export default function (pi: ExtensionAPI) {
1744
1418
  tldr.recordUserMessage(ctx, event.prompt);
1745
1419
  });
1746
1420
  pi.on("message_update", async (event, ctx) => {
1747
- tldr.recordAssistantUpdate(
1748
- ctx,
1749
- event.message,
1750
- (event as { assistantMessageEvent?: unknown }).assistantMessageEvent,
1751
- );
1421
+ tldr.recordAssistantUpdate(ctx, event.message);
1752
1422
  });
1753
1423
  pi.on("tool_call", async (event, ctx) => {
1754
1424
  tldr.recordToolCall(ctx, event);
1755
1425
  });
1756
- pi.on("tool_execution_update", async (event, ctx) => {
1757
- tldr.recordToolExecutionUpdate(ctx, event);
1758
- });
1759
1426
  pi.on("tool_result", async (event, ctx) => {
1760
1427
  tldr.recordToolResult(ctx, event);
1761
1428
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-bar",
3
- "version": "0.3.25",
3
+ "version": "0.3.26",
4
4
  "description": "Pi footer/statusline showing active model, thinking level, context pressure, live TLDR, and extension statuses.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -51,6 +51,6 @@
51
51
  "extensions": [
52
52
  "./extensions/status-footer.ts"
53
53
  ],
54
- "image": "https://cdn.jsdelivr.net/npm/pi-bar@0.3.25/assets/screenshot-yellow.png"
54
+ "image": "https://cdn.jsdelivr.net/npm/pi-bar@0.3.26/assets/screenshot-yellow.png"
55
55
  }
56
56
  }