@nklisch/pi-enhanced 0.1.9 → 0.1.10

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,12 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.1.10
4
+
5
+ ### Fixed
6
+
7
+ - Rebundle `@nklisch/pi-plugins` v0.3.8 so externally installed Pi hosts retain the complete subagent tool family after process restart instead of loading only the separate model-list helper.
8
+ - Rebundle `@nklisch/pi-clearance` v0.2.4 with five supported native targets; Windows ARM64 is no longer built or shipped.
9
+
3
10
  ## v0.1.9
4
11
 
5
12
  ### Changed
@@ -30,8 +30,10 @@ TypeScript owns Pi lifecycle, config I/O, package discovery, settings, audit, an
30
30
  - `src/replay/` — TypeScript corpus acquisition and proposal/presentation adapters; replay computation is delegated to native kernels.
31
31
 
32
32
  Release CI builds every declared native target on an appropriate runner, then
33
- stages all six `clearance-core.<platform>.node` artifacts into the existing
34
- `@nklisch/pi-clearance` package. The loader selects the matching bundled artifact
33
+ stages all five supported `clearance-core.<platform>.node` artifacts into the
34
+ existing `@nklisch/pi-clearance` package. Windows ARM is intentionally excluded
35
+ from the release matrix; Linux x64/ARM64, macOS x64/ARM64, and Windows x64 are
36
+ supported. The loader selects the matching bundled artifact
35
37
  at runtime. Publishing fails unless every declared target is present, preventing a
36
38
  release that works only on the publisher's host. Installation never builds Rust and
37
39
  does not create separate platform packages. Clearance defines no npm install
@@ -15,7 +15,7 @@ Pi Clearance is a Pi extension that structurally analyzes tool calls, evaluates
15
15
  - Package installation makes packs available, not active. Explicit user-owned enablement is required. Clearance defines no npm install lifecycle hooks and package installation never reads or writes user config.
16
16
  - Global and project config written through Clearance is sparse: `version` plus recursively retained non-default user choices. Defaults remain runtime-only. Invalid or obsolete files fail strict validation and runtime falls back to floor-only policy; package installation does not migrate them.
17
17
  - Pre-public migrations are clean cutovers. Removed keys fail strict schema validation; there are no translators or aliases. Trusted TypeScript rule modules are deliberately cut and are never loaded.
18
- - The native engine is distributed as prebuilt Node-API artifacts for Linux x64 glibc, Linux arm64 glibc, macOS x64, macOS arm64, Windows x64 MSVC, and Windows arm64 MSVC. Installation never runs Cargo; a missing or unsupported artifact fails closed.
18
+ - The native engine is distributed as prebuilt Node-API artifacts for Linux x64 glibc, Linux arm64 glibc, macOS x64, macOS arm64, and Windows x64 MSVC. Windows ARM is not a release target. Installation never runs Cargo; a missing or unsupported artifact fails closed.
19
19
 
20
20
  ## Config
21
21
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nklisch/pi-clearance",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Configurable auto-reviewer Pi extension for parsed, structural command policy",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -24,8 +24,7 @@
24
24
  "aarch64-unknown-linux-gnu",
25
25
  "x86_64-apple-darwin",
26
26
  "aarch64-apple-darwin",
27
- "x86_64-pc-windows-msvc",
28
- "aarch64-pc-windows-msvc"
27
+ "x86_64-pc-windows-msvc"
29
28
  ]
30
29
  },
31
30
  "exports": {
@@ -1,5 +1,6 @@
1
1
  import { join } from "node:path";
2
2
  import * as piAi from "@earendil-works/pi-ai";
3
+ import * as piAiCompat from "@earendil-works/pi-ai/compat";
3
4
  import * as piCodingAgent from "@earendil-works/pi-coding-agent";
4
5
  import * as piTui from "@earendil-works/pi-tui";
5
6
  import { createJiti } from "jiti/static";
@@ -25,6 +26,11 @@ function loader() {
25
26
  packageLoader ??= createJiti(import.meta.url, {
26
27
  virtualModules: {
27
28
  "@earendil-works/pi-ai": piAi,
29
+ // The nested package may use public peer-package subpaths. Jiti's
30
+ // virtual-module bridge is exact-keyed, so mapping only the package root
31
+ // works in a colocated test install but fails when Pi owns the peers in a
32
+ // separate global tree—the normal pi-enhanced deployment shape.
33
+ "@earendil-works/pi-ai/compat": piAiCompat,
28
34
  "@earendil-works/pi-coding-agent": piCodingAgent,
29
35
  "@earendil-works/pi-tui": piTui,
30
36
  },
@@ -1 +1 @@
1
- {"version":3,"file":"pi-subagents-package.js","sourceRoot":"","sources":["../../../src/runtime/subagents/pi-subagents-package.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pi-subagents-package.js","sourceRoot":"","sources":["../../../src/runtime/subagents/pi-subagents-package.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nklisch/pi-plugins",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "private": false,
5
5
  "description": "Native marketplace and plugin lifecycle management for Pi, with Claude Code and Codex compatibility.",
6
6
  "license": "MIT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nklisch/pi-enhanced",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Pi, enhanced — one install for nklisch's full harness: policy-gated command review, plugin marketplace, subagents, background tasks, research tools, search, model modes, and a curated UX set.",
5
5
  "author": {
6
6
  "name": "nklisch"
@@ -101,6 +101,6 @@
101
101
  "pi-web-access"
102
102
  ],
103
103
  "scripts": {
104
- "test": "node test/verify-bundle.mjs"
104
+ "test": "node test/verify-bundle.mjs && node test/verify-subagent-restart.mjs"
105
105
  }
106
106
  }
@@ -0,0 +1,186 @@
1
+ import { spawn } from "node:child_process";
2
+ import { execFileSync } from "node:child_process";
3
+ import {
4
+ cpSync,
5
+ mkdtempSync,
6
+ mkdirSync,
7
+ readFileSync,
8
+ rmSync,
9
+ writeFileSync,
10
+ } from "node:fs";
11
+ import { tmpdir } from "node:os";
12
+ import { dirname, join, resolve } from "node:path";
13
+ import { fileURLToPath } from "node:url";
14
+
15
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
16
+ const repoRoot = resolve(packageRoot, "../..");
17
+ const scratch = mkdtempSync(join(tmpdir(), "pi-enhanced-subagent-restart-"));
18
+ const packOut = join(scratch, "pack");
19
+ const extracted = join(scratch, "extracted");
20
+ const sessionDir = join(scratch, "sessions");
21
+ const inspector = join(scratch, "inspect-tools.mjs");
22
+ const sessionId = "019d9a5f-7b13-7000-8000-000000000001";
23
+ const requiredTools = ["subagent", "get_subagent_result", "steer_subagent"];
24
+ const liveChildren = new Set();
25
+
26
+ function stageRuntimeDependency(candidateRoot, name) {
27
+ const target = resolve(repoRoot, "node_modules", name);
28
+ const destination = join(candidateRoot, "node_modules", name);
29
+ mkdirSync(dirname(destination), { recursive: true });
30
+ cpSync(target, destination, { recursive: true });
31
+ }
32
+
33
+ function startPi(extensionPath, extraArgs = []) {
34
+ const cli = resolve(repoRoot, "node_modules/@earendil-works/pi-coding-agent/dist/cli.js");
35
+ const child = spawn(process.execPath, [
36
+ cli,
37
+ "--offline",
38
+ "--approve",
39
+ "--no-extensions",
40
+ "--no-skills",
41
+ "--no-prompt-templates",
42
+ "--no-themes",
43
+ "--no-context-files",
44
+ "--extension", extensionPath,
45
+ "--extension", inspector,
46
+ "--mode", "rpc",
47
+ "--session-dir", sessionDir,
48
+ "--session-id", sessionId,
49
+ ...extraArgs,
50
+ ], {
51
+ cwd: repoRoot,
52
+ env: process.env,
53
+ stdio: ["pipe", "pipe", "pipe"],
54
+ });
55
+
56
+ liveChildren.add(child);
57
+ let stdout = "";
58
+ let stderr = "";
59
+ let sequence = 0;
60
+ const pending = new Map();
61
+ child.stderr.on("data", chunk => { stderr += chunk; });
62
+ child.stdout.on("data", chunk => {
63
+ stdout += chunk;
64
+ for (;;) {
65
+ const newline = stdout.indexOf("\n");
66
+ if (newline < 0) break;
67
+ const line = stdout.slice(0, newline);
68
+ stdout = stdout.slice(newline + 1);
69
+ if (!line) continue;
70
+ let event;
71
+ try { event = JSON.parse(line); }
72
+ catch { continue; }
73
+ if (event.type !== "response" || typeof event.id !== "string") continue;
74
+ const waiter = pending.get(event.id);
75
+ if (!waiter) continue;
76
+ pending.delete(event.id);
77
+ waiter.resolve(event);
78
+ }
79
+ });
80
+ const exited = new Promise(resolvePromise => {
81
+ child.once("exit", (code, signal) => {
82
+ liveChildren.delete(child);
83
+ const error = new Error(`Pi exited before responding (${code ?? signal})\n${stderr}`);
84
+ for (const waiter of pending.values()) waiter.reject(error);
85
+ pending.clear();
86
+ resolvePromise({ code, signal });
87
+ });
88
+ });
89
+
90
+ async function request(command) {
91
+ const id = `restart-${++sequence}`;
92
+ const response = new Promise((resolvePromise, reject) => {
93
+ pending.set(id, { resolve: resolvePromise, reject });
94
+ });
95
+ child.stdin.write(`${JSON.stringify({ id, ...command })}\n`);
96
+ const timer = setTimeout(() => {
97
+ const waiter = pending.get(id);
98
+ if (!waiter) return;
99
+ pending.delete(id);
100
+ waiter.reject(new Error(`Pi RPC timed out for ${command.type}\n${stderr}`));
101
+ }, 20_000);
102
+ timer.unref?.();
103
+ try {
104
+ const result = await response;
105
+ if (!result.success) throw new Error(`Pi RPC ${command.type} failed: ${result.error ?? "unknown error"}\n${stderr}`);
106
+ return result;
107
+ } finally {
108
+ clearTimeout(timer);
109
+ pending.delete(id);
110
+ }
111
+ }
112
+
113
+ return { child, exited, request, stderr: () => stderr };
114
+ }
115
+
116
+ async function inspect(runtime) {
117
+ await runtime.request({ type: "get_commands" });
118
+ await runtime.request({ type: "prompt", message: "/inspect-tools" });
119
+ const entries = await runtime.request({ type: "get_entries" });
120
+ const report = entries.data.entries.findLast(
121
+ entry => entry.type === "custom" && entry.customType === "subagent-tool-regression",
122
+ )?.data;
123
+ if (!report) throw new Error(`Inspector produced no report\n${runtime.stderr()}`);
124
+ for (const name of requiredTools) {
125
+ if (!report.registered.includes(name) || !report.active.includes(name)) {
126
+ throw new Error(`Missing active subagent tool ${name}: ${JSON.stringify(report)}\n${runtime.stderr()}`);
127
+ }
128
+ }
129
+ }
130
+
131
+ try {
132
+ mkdirSync(packOut, { recursive: true });
133
+ mkdirSync(extracted, { recursive: true });
134
+ mkdirSync(sessionDir, { recursive: true });
135
+ const raw = execFileSync(
136
+ process.execPath,
137
+ [resolve(repoRoot, "scripts/pack-package.mjs"), packageRoot, "--out", packOut],
138
+ { encoding: "utf8" },
139
+ );
140
+ const report = JSON.parse(raw);
141
+ const tarball = join(packOut, report[0].filename);
142
+ execFileSync("tar", ["-xzf", tarball, "-C", extracted]);
143
+ const candidate = join(extracted, "package");
144
+
145
+ // A normal npm installation provides these ordinary dependencies beside the
146
+ // bundled packages. Keep Pi's peer packages absent from this tree: the test
147
+ // specifically exercises the bridge from an externally installed Pi host.
148
+ stageRuntimeDependency(candidate, "jiti");
149
+ stageRuntimeDependency(candidate, "@sinclair/typebox");
150
+
151
+ writeFileSync(inspector, `
152
+ export default function (pi) {
153
+ pi.registerCommand("inspect-tools", {
154
+ description: "Inspect subagent tool registration",
155
+ handler: async () => {
156
+ pi.appendEntry("subagent-tool-regression", {
157
+ registered: pi.getAllTools().map(tool => tool.name),
158
+ active: pi.getActiveTools(),
159
+ });
160
+ },
161
+ });
162
+ }
163
+ `);
164
+
165
+ const manifest = JSON.parse(readFileSync(join(candidate, "package.json"), "utf8"));
166
+ const extensionPath = resolve(candidate, manifest.pi.extensions.find(path => path.includes("production-subagents-extension")));
167
+
168
+ const first = startPi(extensionPath);
169
+ await inspect(first);
170
+ first.child.kill("SIGKILL");
171
+ await first.exited;
172
+
173
+ const resumed = startPi(extensionPath);
174
+ await inspect(resumed);
175
+ resumed.child.stdin.end();
176
+ const exit = await resumed.exited;
177
+ if (exit.code !== 0) throw new Error(`Resumed Pi exited unsuccessfully: ${JSON.stringify(exit)}\n${resumed.stderr()}`);
178
+
179
+ console.log("Subagent tools remain registered and active after abrupt Pi process replacement.");
180
+ } finally {
181
+ const children = [...liveChildren];
182
+ const exits = children.map(child => new Promise(resolvePromise => child.once("exit", resolvePromise)));
183
+ for (const child of children) child.kill("SIGKILL");
184
+ await Promise.allSettled(exits);
185
+ rmSync(scratch, { recursive: true, force: true });
186
+ }