@monotykamary/pi-loop 0.1.13 → 0.1.15
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 +2 -2
- package/src/ui/renderer.ts +6 -4
- package/tests/width-regression.test.ts +41 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monotykamary/pi-loop",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"description": "A pi extension that closes the verification loop on task completion",
|
|
5
5
|
"author": "monotykamary",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@commitlint/cli": "21.0.1",
|
|
42
42
|
"@commitlint/config-conventional": "21.0.1",
|
|
43
|
-
"@earendil-works/pi-tui": "0.
|
|
43
|
+
"@earendil-works/pi-tui": "0.83.0",
|
|
44
44
|
"@types/node": "25.9.1",
|
|
45
45
|
"@vitest/coverage-v8": "4.1.7",
|
|
46
46
|
"knip": "6.14.1",
|
package/src/ui/renderer.ts
CHANGED
|
@@ -175,6 +175,8 @@ function renderWithState(
|
|
|
175
175
|
return {
|
|
176
176
|
render: (width: number) => {
|
|
177
177
|
const paddedWidth = Math.max(0, width - 1);
|
|
178
|
+
const fitLines = (lines: string[]) =>
|
|
179
|
+
lines.map((line) => truncateToWidth(line, paddedWidth, ''));
|
|
178
180
|
widgetState.lastRenderedWidth = paddedWidth;
|
|
179
181
|
const suffix = suffixParts.length > 0 ? sep + suffixParts.join(sep) : '';
|
|
180
182
|
|
|
@@ -206,7 +208,7 @@ function renderWithState(
|
|
|
206
208
|
const visibleLines = widgetState.lastThinkingLines
|
|
207
209
|
.slice(0, visibleCount)
|
|
208
210
|
.map((ln) => theme.fg('dim', ln));
|
|
209
|
-
return [l1, ...visibleLines];
|
|
211
|
+
return fitLines([l1, ...visibleLines]);
|
|
210
212
|
}
|
|
211
213
|
|
|
212
214
|
// For non-analyzing states (steering/done/waiting), preserve existing line breaks.
|
|
@@ -214,12 +216,12 @@ function renderWithState(
|
|
|
214
216
|
const isAnalyzing = action.type === 'analyzing';
|
|
215
217
|
if (!isAnalyzing && widgetState.lastThinkingLines.length > 0) {
|
|
216
218
|
const visibleLines = widgetState.lastThinkingLines.map((ln) => theme.fg('dim', ln));
|
|
217
|
-
return [l1, ...visibleLines];
|
|
219
|
+
return fitLines([l1, ...visibleLines]);
|
|
218
220
|
}
|
|
219
221
|
|
|
220
222
|
// No thinking to display
|
|
221
223
|
if (!rawThinking) {
|
|
222
|
-
return [l1];
|
|
224
|
+
return fitLines([l1]);
|
|
223
225
|
}
|
|
224
226
|
|
|
225
227
|
const thinkingIndent = stripAnsi(thinkingPrefix).length;
|
|
@@ -249,7 +251,7 @@ function renderWithState(
|
|
|
249
251
|
}
|
|
250
252
|
|
|
251
253
|
widgetState.lastThinkingLines = plainLines;
|
|
252
|
-
return [l1, ...thinkingLines];
|
|
254
|
+
return fitLines([l1, ...thinkingLines]);
|
|
253
255
|
},
|
|
254
256
|
invalidate: () => {},
|
|
255
257
|
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { updateUI } from '../src/ui/status-widget.js';
|
|
3
|
+
|
|
4
|
+
vi.mock('@earendil-works/pi-tui', () => ({
|
|
5
|
+
truncateToWidth: (text: string, width: number) => text.slice(0, Math.max(0, width)),
|
|
6
|
+
}));
|
|
7
|
+
|
|
8
|
+
const theme = { fg: (_color: string, text: string) => text };
|
|
9
|
+
|
|
10
|
+
describe('loop widget width', () => {
|
|
11
|
+
it('bounds long words and cached lines after a terminal shrink', () => {
|
|
12
|
+
const setWidget = vi.fn();
|
|
13
|
+
const ctx = {
|
|
14
|
+
ui: { setWidget, setStatus: vi.fn(), notify: vi.fn(), select: vi.fn() },
|
|
15
|
+
sessionManager: { getBranch: vi.fn(() => []) },
|
|
16
|
+
model: { provider: 'test', id: 'model' },
|
|
17
|
+
} as any;
|
|
18
|
+
const state = {
|
|
19
|
+
active: true,
|
|
20
|
+
outcome: 'goal',
|
|
21
|
+
interventions: [],
|
|
22
|
+
turnCount: 1,
|
|
23
|
+
justSteered: false,
|
|
24
|
+
lastAnalyzedTurn: 0,
|
|
25
|
+
snapshotBuffer: [],
|
|
26
|
+
reframeTier: 0,
|
|
27
|
+
lastSteerTurn: -1,
|
|
28
|
+
} as any;
|
|
29
|
+
|
|
30
|
+
updateUI(ctx, state, { type: 'analyzing', turn: 1, thinking: 'x'.repeat(200) });
|
|
31
|
+
let factory = setWidget.mock.calls.at(-1)[1];
|
|
32
|
+
factory(null, theme).render(100);
|
|
33
|
+
|
|
34
|
+
updateUI(ctx, state, { type: 'done' });
|
|
35
|
+
factory = setWidget.mock.calls.at(-1)[1];
|
|
36
|
+
const width = 20;
|
|
37
|
+
const lines = factory(null, theme).render(width);
|
|
38
|
+
|
|
39
|
+
expect(lines.every((line: string) => line.length <= width - 1)).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
});
|