@huseynsnmz/pi-board 0.15.1 → 0.15.3

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
@@ -5,6 +5,19 @@ conventional commits by `scripts/release_helper.mjs`. Entries are
5
5
  forward-only: they begin with the first release after this file landed —
6
6
  for earlier history, see the git log and the pull-request list.
7
7
 
8
+ ## [0.15.3] - 2026-11-04
9
+
10
+ ### Fixes
11
+
12
+ - **state**: Pi no longer crashes on `/new`, `/resume`, `/fork` or `/reload` (from 0.15.0)
13
+
14
+ ## [0.15.2] - 2026-11-04
15
+
16
+ ### Changes
17
+
18
+ - **deps**: exact versions everywhere, with Pi 1.5.0, TypeScript 7 and @types/node 26 for development
19
+ - **deps**: remove the postinstall script, since Pi 1.5.0 no longer ships the versions it patched
20
+
8
21
  ## [0.15.1] - 2026-11-04
9
22
 
10
23
  ### Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@huseynsnmz/pi-board",
3
- "version": "0.15.1",
3
+ "version": "0.15.3",
4
4
  "description": "A board for Pi's background sessions: start, watch, reply to and attach to them. A fork of @zhuxixi/pi-agent-board.",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -51,7 +51,6 @@
51
51
  "image": "https://github.com/zhuxixi/pi-agent-board/raw/refs/heads/main/assets/banner.png"
52
52
  },
53
53
  "scripts": {
54
- "postinstall": "node scripts/patch-vulns.mjs",
55
54
  "typecheck": "tsc --noEmit",
56
55
  "test": "node scripts/run-tests.mjs",
57
56
  "test:coverage": "c8 node scripts/run-tests.mjs",
@@ -73,14 +72,20 @@
73
72
  }
74
73
  },
75
74
  "devDependencies": {
76
- "@earendil-works/pi-coding-agent": "1.1.0",
77
- "@earendil-works/pi-tui": "1.1.0",
78
- "@types/node": "^25.9.1",
79
- "c8": "^12.0.0",
80
- "typescript": "^5.9.3"
75
+ "@earendil-works/pi-coding-agent": "1.5.0",
76
+ "@earendil-works/pi-tui": "1.5.0",
77
+ "@types/node": "26.6.6",
78
+ "c8": "12.0.0",
79
+ "typescript": "7.0.2"
81
80
  },
82
81
  "dependencies": {
83
- "@xterm/headless": "^6.0.0",
84
- "node-pty": "^1.1.0"
82
+ "@xterm/headless": "6.0.0",
83
+ "node-pty": "1.1.0"
84
+ },
85
+ "overrides": {
86
+ "test-exclude": {
87
+ "glob": "14.0.3",
88
+ "minimatch": "11.0.4"
89
+ }
85
90
  }
86
91
  }
package/src/index.ts CHANGED
@@ -198,6 +198,14 @@ export default function piAgentBoard(pi: ExtensionAPI): void {
198
198
  hostedFrameWitness = { stop: () => cleanup("session-shutdown") };
199
199
  }
200
200
 
201
+ // After this the context they hold is stale, and using one takes Pi down.
202
+ pi.on("session_shutdown", () => {
203
+ stopDoubleLeft?.();
204
+ stopDoubleLeft = null;
205
+ stopWaiting?.();
206
+ stopWaiting = null;
207
+ });
208
+
201
209
  pi.on("session_start", async (event, ctx) => {
202
210
  if (!isHostedChild && ctx.mode === "tui") {
203
211
  stopDoubleLeft?.();
@@ -20,7 +20,11 @@ export function watchDoubleLeft(ctx: ExtensionContext): () => void {
20
20
  return { data: "\r" };
21
21
  });
22
22
  return () => {
23
- stop();
23
+ try {
24
+ stop();
25
+ } catch {
26
+ /* see focus.stop */
27
+ }
24
28
  focus.stop();
25
29
  };
26
30
  }
package/src/ui/focus.ts CHANGED
@@ -21,6 +21,12 @@ export function watchFocus(ctx: ExtensionContext, widget: string): Focus {
21
21
  return {
22
22
  promptText: () => (focused?.() as Editorish | null | undefined)?.getExpandedText?.(),
23
23
  known: () => focused !== null,
24
- stop: () => ctx.ui.setWidget(widget, undefined),
24
+ stop: () => {
25
+ try {
26
+ ctx.ui.setWidget(widget, undefined);
27
+ } catch {
28
+ /* the session it belonged to has already gone, and its widget with it */
29
+ }
30
+ },
25
31
  };
26
32
  }
package/src/ui/waiting.ts CHANGED
@@ -11,11 +11,16 @@ export function watchWaiting(ctx: ExtensionContext, changed: (waiting: boolean)
11
11
  const focus = watchFocus(ctx, "agent-board-waiting");
12
12
  let waiting = false;
13
13
  const timer = setInterval(() => {
14
- const now = focus.known() && !ctx.isIdle() && focus.promptText() === undefined;
15
- if (now === waiting) return;
16
- waiting = now;
17
- // If the run has ended too, its own end has already said so, and this would undo that.
18
- if (now || !ctx.isIdle()) changed(now);
14
+ try {
15
+ const now = focus.known() && !ctx.isIdle() && focus.promptText() === undefined;
16
+ if (now === waiting) return;
17
+ waiting = now;
18
+ // If the run has ended too, its own end has already said so, and this would undo that.
19
+ if (now || !ctx.isIdle()) changed(now);
20
+ } catch {
21
+ // The session was replaced before this could be stopped. An error here would end Pi.
22
+ clearInterval(timer);
23
+ }
19
24
  }, CHECK_MS);
20
25
  timer.unref?.();
21
26
  return () => {
@@ -1,59 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * postinstall: patch vulnerable transitive dependencies that are locked behind
4
- * @earendil-works/pi-coding-agent's npm-shrinkwrap.json (which prevents npm
5
- * "overrides" from taking effect).
6
- *
7
- * Vulnerabilities patched:
8
- * - brace-expansion <=5.0.7 → 5.0.8 (GHSA-3jxr-9vmj-r5cp, GHSA-mh99-v99m-4gvg)
9
- * - protobufjs 7.5.0–7.6.4 → 7.6.5 (GHSA-j3f2-48v5-ccww)
10
- */
11
- import { execSync } from "node:child_process";
12
- import { existsSync, rmSync, mkdirSync } from "node:fs";
13
- import { join, dirname } from "node:path";
14
- import { fileURLToPath } from "node:url";
15
-
16
- const root = join(dirname(fileURLToPath(import.meta.url)), "..");
17
- const nested = join(
18
- root,
19
- "node_modules",
20
- "@earendil-works",
21
- "pi-coding-agent",
22
- "node_modules",
23
- );
24
-
25
- const patches = [
26
- { name: "brace-expansion", version: "5.0.8" },
27
- { name: "protobufjs", version: "7.6.5" },
28
- ];
29
-
30
- for (const { name, version } of patches) {
31
- const target = join(nested, name);
32
- if (!existsSync(target)) {
33
- console.log(`[patch-vulns] ${name} not found nested, skipping`);
34
- continue;
35
- }
36
-
37
- console.log(`[patch-vulns] patching ${name} → ${version}`);
38
- rmSync(target, { recursive: true, force: true });
39
- mkdirSync(target, { recursive: true });
40
-
41
- // Install the patched version into a temp dir, then move it into place
42
- const tmp = join(root, `.patch-tmp-${name}`);
43
- rmSync(tmp, { recursive: true, force: true });
44
- mkdirSync(tmp, { recursive: true });
45
-
46
- try {
47
- execSync(`npm install ${name}@${version} --prefix "${tmp}" --ignore-scripts`, {
48
- stdio: "pipe",
49
- cwd: root,
50
- });
51
- const installed = join(tmp, "node_modules", name);
52
- rmSync(target, { recursive: true, force: true });
53
- execSync(`mv "${installed}" "${target}"`);
54
- } finally {
55
- rmSync(tmp, { recursive: true, force: true });
56
- }
57
- }
58
-
59
- console.log("[patch-vulns] done");