pi-startup-redraw-fix 0.1.10 → 0.1.12

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
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.12] - 2026-06-01
4
+
5
+ ### Changed
6
+ - Consolidated clear-sequence constants and normalization into the terminal clear patch while preserving synchronous startup patching.
7
+ - Widened peer dependency ranges to `^0.74.0 || ^0.75.0 || ^0.77.0 || ^0.78.0`.
8
+
9
+ ## [0.1.11] - 2026-05-26
10
+
11
+ ### Changed
12
+ - Widened peer dependency ranges to `^0.74.0 || ^0.75.0`
13
+
3
14
  ## [0.1.10] - 2026-05-22
4
15
 
5
16
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-startup-redraw-fix",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Pi extension that patches terminal full-clear ordering to avoid startup redraw glitches.",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -58,7 +58,7 @@
58
58
  ]
59
59
  },
60
60
  "peerDependencies": {
61
- "@earendil-works/pi-coding-agent": "^0.75.4",
62
- "@earendil-works/pi-tui": "^0.75.4"
61
+ "@earendil-works/pi-coding-agent": "^0.74.0 || ^0.75.0 || ^0.77.0 || ^0.78.0",
62
+ "@earendil-works/pi-tui": "^0.74.0 || ^0.75.0 || ^0.77.0 || ^0.78.0"
63
63
  }
64
64
  }
package/src/constants.ts CHANGED
@@ -1,2 +1 @@
1
- export const BROKEN_FULL_CLEAR_SEQUENCE = "\x1b[3J\x1b[2J\x1b[H";
2
- export const FIXED_FULL_CLEAR_SEQUENCE = "\x1b[H\x1b[2J\x1b[3J";
1
+ export { BROKEN_FULL_CLEAR_SEQUENCE, FIXED_FULL_CLEAR_SEQUENCE } from "./terminal-clear-patch.js";
package/src/index.ts CHANGED
@@ -1,18 +1,23 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
-
3
- import { applyTerminalClearSequencePatch } from "./terminal-clear-patch.js";
4
-
5
- export default function startupRedrawFixExtension(pi: ExtensionAPI): void {
6
- const patchResult = applyTerminalClearSequencePatch();
7
-
8
- pi.on("session_start", async (_event, ctx) => {
9
- if (!ctx.hasUI) {
10
- return;
11
- }
12
-
13
- if (!patchResult.patched && !patchResult.alreadyPatched) {
14
- const reason = patchResult.error ?? "unknown error";
15
- ctx.ui.notify(`startup-redraw-fix: failed to patch terminal clear sequence (${reason})`, "warning");
16
- }
17
- });
18
- }
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+
3
+ import { applyTerminalClearSequencePatch } from "./terminal-clear-patch.js";
4
+
5
+ export default function startupRedrawFixExtension(pi: ExtensionAPI): void {
6
+ // The terminal clear-sequence patch must be installed before the first
7
+ // full-clear write at startup, so it is applied synchronously at registration
8
+ // rather than deferred. The local import graph is tiny (a few dozen lines) and
9
+ // the only package dependency, pi-tui, is already loaded by Pi core, so there
10
+ // is no meaningful startup transpile cost to defer here.
11
+ const patchResult = applyTerminalClearSequencePatch();
12
+
13
+ pi.on("session_start", async (_event, ctx) => {
14
+ if (!ctx.hasUI) {
15
+ return;
16
+ }
17
+
18
+ if (!patchResult.patched && !patchResult.alreadyPatched) {
19
+ const reason = patchResult.error ?? "unknown error";
20
+ ctx.ui.notify(`startup-redraw-fix: failed to patch terminal clear sequence (${reason})`, "warning");
21
+ }
22
+ });
23
+ }
@@ -1,9 +1 @@
1
- import { BROKEN_FULL_CLEAR_SEQUENCE, FIXED_FULL_CLEAR_SEQUENCE } from "./constants.js";
2
-
3
- export function normalizeTerminalClearSequence(data: string): string {
4
- if (!data.includes(BROKEN_FULL_CLEAR_SEQUENCE)) {
5
- return data;
6
- }
7
-
8
- return data.split(BROKEN_FULL_CLEAR_SEQUENCE).join(FIXED_FULL_CLEAR_SEQUENCE);
9
- }
1
+ export { normalizeTerminalClearSequence } from "./terminal-clear-patch.js";
@@ -1,44 +1,53 @@
1
- import { ProcessTerminal } from "@earendil-works/pi-tui";
2
-
3
- import { normalizeTerminalClearSequence } from "./normalize-clear-sequence.js";
4
-
5
- const PATCH_FLAG_KEY = "__piStartupRedrawFixPatched__" as const;
6
-
7
- type ProcessTerminalPrototype = typeof ProcessTerminal.prototype & {
8
- [PATCH_FLAG_KEY]?: boolean;
9
- };
10
-
11
- export interface PatchResult {
12
- patched: boolean;
13
- alreadyPatched: boolean;
14
- error?: string;
15
- }
16
-
17
- export function applyTerminalClearSequencePatch(): PatchResult {
18
- const prototype = ProcessTerminal.prototype as ProcessTerminalPrototype;
19
-
20
- if (prototype[PATCH_FLAG_KEY]) {
21
- return { patched: false, alreadyPatched: true };
22
- }
23
-
24
- const originalWrite = prototype.write;
25
- if (typeof originalWrite !== "function") {
26
- return {
27
- patched: false,
28
- alreadyPatched: false,
29
- error: "ProcessTerminal.write is unavailable",
30
- };
31
- }
32
-
33
- prototype.write = function patchedProcessTerminalWrite(data: string): void {
34
- const normalized = typeof data === "string"
35
- ? normalizeTerminalClearSequence(data)
36
- : data;
37
-
38
- originalWrite.call(this, normalized);
39
- };
40
-
41
- prototype[PATCH_FLAG_KEY] = true;
42
-
43
- return { patched: true, alreadyPatched: false };
44
- }
1
+ import { ProcessTerminal } from "@earendil-works/pi-tui";
2
+
3
+ export const BROKEN_FULL_CLEAR_SEQUENCE = "\x1b[3J\x1b[2J\x1b[H";
4
+ export const FIXED_FULL_CLEAR_SEQUENCE = "\x1b[H\x1b[2J\x1b[3J";
5
+
6
+ const PATCH_FLAG_KEY = "__piStartupRedrawFixPatched__" as const;
7
+
8
+ type ProcessTerminalPrototype = typeof ProcessTerminal.prototype & {
9
+ [PATCH_FLAG_KEY]?: boolean;
10
+ };
11
+
12
+ export interface PatchResult {
13
+ patched: boolean;
14
+ alreadyPatched: boolean;
15
+ error?: string;
16
+ }
17
+
18
+ export function normalizeTerminalClearSequence(data: string): string {
19
+ if (!data.includes(BROKEN_FULL_CLEAR_SEQUENCE)) {
20
+ return data;
21
+ }
22
+
23
+ return data.split(BROKEN_FULL_CLEAR_SEQUENCE).join(FIXED_FULL_CLEAR_SEQUENCE);
24
+ }
25
+
26
+ export function applyTerminalClearSequencePatch(): PatchResult {
27
+ const prototype = ProcessTerminal.prototype as ProcessTerminalPrototype;
28
+
29
+ if (prototype[PATCH_FLAG_KEY]) {
30
+ return { patched: false, alreadyPatched: true };
31
+ }
32
+
33
+ const originalWrite = prototype.write;
34
+ if (typeof originalWrite !== "function") {
35
+ return {
36
+ patched: false,
37
+ alreadyPatched: false,
38
+ error: "ProcessTerminal.write is unavailable",
39
+ };
40
+ }
41
+
42
+ prototype.write = function patchedProcessTerminalWrite(data: string): void {
43
+ const normalized = typeof data === "string"
44
+ ? normalizeTerminalClearSequence(data)
45
+ : data;
46
+
47
+ originalWrite.call(this, normalized);
48
+ };
49
+
50
+ prototype[PATCH_FLAG_KEY] = true;
51
+
52
+ return { patched: true, alreadyPatched: false };
53
+ }