pi-claude-code-ui 1.0.76 → 1.0.78

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
@@ -3,6 +3,24 @@
3
3
  > [!IMPORTANT]
4
4
  > **1.0.69 — package rename (permanent).** Canonical npm name is now [`pi-claude-code-ui`](https://www.npmjs.com/package/pi-claude-code-ui). `pi-claude-style-tools` is legacy and will not receive further releases. Install with `pi install npm:pi-claude-code-ui` or `npm i pi-claude-code-ui`.
5
5
 
6
+ ## 1.0.78 — 2026-08-22
7
+
8
+ ### Fixed
9
+
10
+ - **Hide transient Magic Context tags** — dynamically filter Magic Context tags (like `§N§`) from all Markdown view components in the Terminal UI. This covers thinking blocks, user messages, assistant prose, and subagent frames, without mutating the underlying message text content or breaking LLM prompt tracking.
11
+
12
+ ## 1.0.77 — 2026-08-21
13
+
14
+ ### Fixed
15
+
16
+ - **Dynamic Turn Took lines** — the end line `✻ Turn took xs` is now rendered dynamically in the Terminal UI instead of being baked into the message text content. This avoids polluting saved session databases and other UIs (like VSCode or web interfaces), and prevents interference with tools like TPS counters that read the message text.
17
+
18
+ ## 1.0.76 — 2026-08-07
19
+
20
+ ### Fixed
21
+
22
+ - **Hide transient context tags** — hide transient context tags in streaming prose.
23
+
6
24
  ## 1.0.75 — 2026-07-29
7
25
 
8
26
  ### Fixed
@@ -1408,14 +1408,7 @@ function hasWorkedDurationLine(message: any): boolean {
1408
1408
  });
1409
1409
  }
1410
1410
 
1411
- function appendWorkedDurationLine(message: any, durationMs: number, sessionTotalMs?: number, turns?: number): void {
1412
- if (!message || message.role !== "assistant" || !Array.isArray(message.content)) return;
1413
- const textBlocks = message.content.filter((block: any) => block?.type === "text" && typeof block.text === "string" && block.text.trim());
1414
- const lastText = textBlocks[textBlocks.length - 1];
1415
- if (!lastText) return;
1416
- const text = lastText.text.includes(WORKED_DURATION_MARKER) ? stripWorkedDurationLine(lastText.text) : lastText.text;
1417
- lastText.text = `${text.trimEnd()}\n\n${inlineWorkedDurationText(durationMs, sessionTotalMs, turns)}`;
1418
- }
1411
+
1419
1412
 
1420
1413
  type MarkdownThemeLike = ConstructorParameters<typeof Markdown>[3];
1421
1414
 
@@ -1790,7 +1783,7 @@ class ThinkingParagraph {
1790
1783
  _markdownTheme: ConstructorParameters<typeof Markdown>[3],
1791
1784
  _defaultTextStyle?: ConstructorParameters<typeof Markdown>[4],
1792
1785
  ) {
1793
- this.text = text;
1786
+ this.text = stripTransientMagicContextTags(text);
1794
1787
  }
1795
1788
 
1796
1789
  private thinkingMarkdown(): InstanceType<typeof Markdown> {
@@ -1968,6 +1961,16 @@ function patchCustomMessageRender(): void {
1968
1961
  syncToolBackgroundMode();
1969
1962
  const cached = messageRenderCacheHit(this, width);
1970
1963
  if (cached) return cached;
1964
+ visitMarkdownDescendants(this, (child) => {
1965
+ const markdownAny = child as any;
1966
+ if (typeof markdownAny.text === "string") {
1967
+ const stripped = stripTransientMagicContextTags(markdownAny.text);
1968
+ if (stripped !== markdownAny.text) {
1969
+ markdownAny.text = stripped;
1970
+ child.invalidate?.();
1971
+ }
1972
+ }
1973
+ });
1971
1974
  const lines = originalRender.call(this, width);
1972
1975
  if (!Array.isArray(lines)) return lines;
1973
1976
  const result = isSubagentNotificationMessage(this?.message)
@@ -2065,6 +2068,13 @@ function patchUserMessageRender(): void {
2065
2068
  if (cached) return cached;
2066
2069
  visitMarkdownDescendants(this, (child) => {
2067
2070
  const markdownAny = child as any;
2071
+ if (typeof markdownAny.text === "string") {
2072
+ const stripped = stripTransientMagicContextTags(markdownAny.text);
2073
+ if (stripped !== markdownAny.text) {
2074
+ markdownAny.text = stripped;
2075
+ child.invalidate?.();
2076
+ }
2077
+ }
2068
2078
  makeMarkdownLinksCopySafe(child);
2069
2079
  if (markdownAny.defaultTextStyle?.bgColor) {
2070
2080
  markdownAny.defaultTextStyle.bgColor = undefined;
@@ -2094,6 +2104,16 @@ function patchAssistantMessages(): void {
2094
2104
  proto.render = function patchedAssistantMessageRender(width: number) {
2095
2105
  const cached = messageRenderCacheHit(this, width);
2096
2106
  if (cached) return cached;
2107
+ visitMarkdownDescendants(this, (child) => {
2108
+ const markdownAny = child as any;
2109
+ if (typeof markdownAny.text === "string") {
2110
+ const stripped = stripTransientMagicContextTags(markdownAny.text);
2111
+ if (stripped !== markdownAny.text) {
2112
+ markdownAny.text = stripped;
2113
+ child.invalidate?.();
2114
+ }
2115
+ }
2116
+ });
2097
2117
  const lines = originalRender.call(this, width);
2098
2118
  if (!Array.isArray(lines) || lines.length === 0) return lines;
2099
2119
  if ((this as any).hasToolCalls) {
@@ -4850,15 +4870,14 @@ function registerThinkingLabels(pi: ExtensionAPI): void {
4850
4870
  (message as any)[WORKED_DURATION_KEY] = durationMs;
4851
4871
  if (typeof sessionTotalMs === "number") (message as any)[WORKED_SESSION_TOTAL_KEY] = sessionTotalMs;
4852
4872
  if (typeof turns === "number") (message as any)[WORKED_TURNS_KEY] = turns;
4853
- // Mutate the message itself before pi renders/persists it. This is more
4854
- // reliable than the spinner because pi removes the loader on agent_end,
4855
- // and more reliable than component monkey-patching when extensions are
4856
- // loaded from a different package instance than the running TUI.
4857
- appendWorkedDurationLine(message, durationMs, sessionTotalMs, turns);
4858
4873
  }
4859
4874
  currentAssistantMessageStartMs = undefined;
4860
4875
  }
4861
4876
  patchMessage(event, ctx.ui?.theme);
4877
+ try {
4878
+ (ctx as any)?.ui?.invalidate?.();
4879
+ (ctx as any)?.ui?.requestRender?.();
4880
+ } catch { /* noop */ }
4862
4881
  });
4863
4882
  pi.on("agent_end", async () => {
4864
4883
  currentAgentWorkStartMs = undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-claude-code-ui",
3
- "version": "1.0.76",
3
+ "version": "1.0.78",
4
4
  "description": "Claude Code-style grouped tool rows for pi with Ctrl+O/Ctrl+Shift+O previews, math rendering, and consistent built-in, MCP, and custom tool rendering",
5
5
  "keywords": [
6
6
  "pi-package",