pi-claude-code-ui 1.0.85 → 1.0.87
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 +12 -0
- package/extensions/index.ts +56 -6
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
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.87 — 2026-10-19
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- **Expanding image reads no longer crashes Pi** — clear the image-source reuse cache together with the hidden image components when a `read` result is collapsed. Re-expanding standalone or grouped image reads now creates valid image components instead of reusing a missing component and throwing `TypeError: Cannot read properties of undefined (reading 'render')`.
|
|
11
|
+
|
|
12
|
+
## 1.0.86 — 2026-10-08
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **Display-math scanning no longer splits fenced blocks on `$$` and `\[ … \]`** (Perry Trolard, [#33](https://github.com/FammasMaz/pi-cc-tools/issues/33)) - paragraph rebuilding now respects the same Markdown code regions as inline math formatting, so `$$` (shell PID) and `\[ … \]` (grep/ripgrep char-class regexes) inside ```` ``` ```` fences and inline code stay literal instead of cutting the block into a math segment.
|
|
17
|
+
|
|
6
18
|
## 1.0.83 — 2026-09-07
|
|
7
19
|
|
|
8
20
|
### Fixed
|
package/extensions/index.ts
CHANGED
|
@@ -2001,6 +2001,32 @@ function patchTerminalWriteTagScrubber(): void {
|
|
|
2001
2001
|
proto[TERMINAL_SCRUB_PATCH_FLAG] = true;
|
|
2002
2002
|
}
|
|
2003
2003
|
|
|
2004
|
+
// Code spans and fenced blocks are literal Markdown source. Math preprocessing
|
|
2005
|
+
// must never touch delimiters inside them: `$$` is the shell PID and `\[ … \]
|
|
2006
|
+
// appears in grep/ripgrep class regexes. Inline formatting splits on this
|
|
2007
|
+
// expression before transforming; display-math block scanning below reuses it
|
|
2008
|
+
// so a math candidate opening inside code is skipped in favor of real prose.
|
|
2009
|
+
const MARKDOWN_CODE_REGION_RE = /(`{3,}[\s\S]*?`{3,}|`[^`\n]*`)/g;
|
|
2010
|
+
|
|
2011
|
+
interface CodeRegion {
|
|
2012
|
+
start: number;
|
|
2013
|
+
end: number;
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
function findMarkdownCodeRegions(text: string): CodeRegion[] {
|
|
2017
|
+
const regions: CodeRegion[] = [];
|
|
2018
|
+
MARKDOWN_CODE_REGION_RE.lastIndex = 0;
|
|
2019
|
+
let match: RegExpExecArray | null;
|
|
2020
|
+
while ((match = MARKDOWN_CODE_REGION_RE.exec(text))) {
|
|
2021
|
+
regions.push({ start: match.index, end: match.index + match[0].length });
|
|
2022
|
+
}
|
|
2023
|
+
return regions;
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
function codeRegionContaining(regions: CodeRegion[], index: number): CodeRegion | undefined {
|
|
2027
|
+
return regions.find((region) => index >= region.start && index < region.end);
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2004
2030
|
function replaceInlineMath(text: string): string {
|
|
2005
2031
|
if (!hasInlineMathMarkers(text)) return text;
|
|
2006
2032
|
const transform = (segment: string): string => {
|
|
@@ -2012,10 +2038,7 @@ function replaceInlineMath(text: string): string {
|
|
|
2012
2038
|
return `${prefix}${codeSpan(formatMathForDisplay(body, false))}`;
|
|
2013
2039
|
});
|
|
2014
2040
|
};
|
|
2015
|
-
|
|
2016
|
-
// formatting only to prose segments so shell variables such as `$base` and
|
|
2017
|
-
// `$scope` remain byte-for-byte unchanged in displayed/copied commands.
|
|
2018
|
-
const parts = text.split(/(`{3,}[\s\S]*?`{3,}|`[^`\n]*`)/g);
|
|
2041
|
+
const parts = text.split(MARKDOWN_CODE_REGION_RE);
|
|
2019
2042
|
return parts.map((part, index) => index % 2 === 1 ? part : transform(part)).join("");
|
|
2020
2043
|
}
|
|
2021
2044
|
|
|
@@ -2132,14 +2155,31 @@ function buildParagraphSegments(
|
|
|
2132
2155
|
return segments;
|
|
2133
2156
|
}
|
|
2134
2157
|
const scanLoose = shouldScanLooseBracketMath(text);
|
|
2158
|
+
// Code regions are computed once for the whole paragraph: a display-math
|
|
2159
|
+
// candidate must be rejected before its fence gets cut into separate
|
|
2160
|
+
// Markdown segments (issue #33, sibling of the inline fix in 2ccd158).
|
|
2161
|
+
const codeRegions = findMarkdownCodeRegions(text);
|
|
2162
|
+
// `cursor` marks the start of prose not yet emitted; `scanFrom` only advances
|
|
2163
|
+
// past rejected code regions so skipped candidates never erase prose.
|
|
2135
2164
|
let cursor = 0;
|
|
2136
|
-
|
|
2137
|
-
|
|
2165
|
+
let scanFrom = 0;
|
|
2166
|
+
while (scanFrom < text.length) {
|
|
2167
|
+
let next = findNextDisplayMathBlock(text, scanFrom, scanLoose);
|
|
2168
|
+
// Math delimiters found inside a fenced block or code span are literal
|
|
2169
|
+
// source, not math. Resume the scan after that code region so a later
|
|
2170
|
+
// genuine `$$ … $$` in prose is still honored.
|
|
2171
|
+
while (next) {
|
|
2172
|
+
const region = codeRegionContaining(codeRegions, next.index);
|
|
2173
|
+
if (!region) break;
|
|
2174
|
+
scanFrom = region.end;
|
|
2175
|
+
next = findNextDisplayMathBlock(text, scanFrom, scanLoose);
|
|
2176
|
+
}
|
|
2138
2177
|
if (!next) break;
|
|
2139
2178
|
appendMarkdownSegment(segments, text.slice(cursor, next.index), theme, options);
|
|
2140
2179
|
const raw = text.slice(next.contentStart, next.contentEnd).trim();
|
|
2141
2180
|
if (raw) segments.push({ kind: "math", raw });
|
|
2142
2181
|
cursor = next.endIndex;
|
|
2182
|
+
scanFrom = next.endIndex;
|
|
2143
2183
|
}
|
|
2144
2184
|
appendMarkdownSegment(segments, text.slice(cursor), theme, options);
|
|
2145
2185
|
return segments;
|
|
@@ -2976,6 +3016,8 @@ function removeImageChildren(component: any): void {
|
|
|
2976
3016
|
try { component.removeChild?.(child); } catch { /* noop */ }
|
|
2977
3017
|
}
|
|
2978
3018
|
component.imageComponents = [];
|
|
3019
|
+
// Pi reuses image components by matching imageSources; clear both caches.
|
|
3020
|
+
component.imageSources = [];
|
|
2979
3021
|
component.imageSpacers = [];
|
|
2980
3022
|
}
|
|
2981
3023
|
|
|
@@ -7876,3 +7918,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
7876
7918
|
bumpToolBranchVisualEpoch();
|
|
7877
7919
|
});
|
|
7878
7920
|
}
|
|
7921
|
+
|
|
7922
|
+
// Test-only escape hatch: this package is a default-export extension and the
|
|
7923
|
+
// export surface Pi consumes must stay minimal. Regression tests for math
|
|
7924
|
+
// preprocessing reach these internals through this namespace instead of
|
|
7925
|
+
// widening the public export (see scripts/math-preprocess.test.ts).
|
|
7926
|
+
export const __mathPreprocessInternals = {
|
|
7927
|
+
buildParagraphSegments,
|
|
7928
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-claude-code-ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.87",
|
|
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",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"CHANGELOG.md"
|
|
38
38
|
],
|
|
39
39
|
"scripts": {
|
|
40
|
-
"test": "node --experimental-strip-types --test scripts/*.test.ts",
|
|
40
|
+
"test": "node --experimental-strip-types --test scripts/*.test.ts scripts/*.test.mts",
|
|
41
41
|
"test:fullscreen": "node scripts/fullscreen-mouse.test.mjs",
|
|
42
42
|
"typecheck": "tsc --noEmit --target ES2022 --module NodeNext --moduleResolution NodeNext --skipLibCheck extensions/index.ts extensions/spinner.ts",
|
|
43
43
|
"pack:dry-run": "npm pack --dry-run",
|