@averyyy/pi-client 1.2.0-piclient.1 → 1.3.0-piclient.1
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 +2 -0
- package/bin/pi-client.js +39 -21
- package/bin/update.js +10 -12
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
### Fixed
|
|
4
4
|
|
|
5
|
+
- Restarted updated runtimes through `/reload` with the current session, branch, and startup options. Shared update generations let each active session switch runtimes, and runtime lookup or handoff errors remain visible without relaunching the old runtime.
|
|
6
|
+
- Invoked npm through Node on Windows so global updates can start without a shell.
|
|
5
7
|
- Reported upstream Pi 1.0.0 and its full source commit in package metadata.
|
|
6
8
|
- Documented remote model operations, server-side credentials, and the 64 KiB UTF-8 request limit.
|
|
7
9
|
- Enabled remote prompt-cache warming with streaming and idle modes, bounded request bodies, and session usage accounting.
|
package/bin/pi-client.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
|
-
import {
|
|
4
|
-
import { tmpdir } from "node:os";
|
|
3
|
+
import { mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
4
|
+
import { homedir, tmpdir } from "node:os";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { runPiClientSend } from "./send.js";
|
|
@@ -33,6 +33,8 @@ function runPiClientCli(args) {
|
|
|
33
33
|
const reloadStatePath = join(reloadDir, "state.json");
|
|
34
34
|
let cliPath = getLocalCliPath();
|
|
35
35
|
let childArgs = args;
|
|
36
|
+
let reloadLeafId;
|
|
37
|
+
let runtimeUpdatedAt = readRuntimeUpdateGeneration();
|
|
36
38
|
|
|
37
39
|
try {
|
|
38
40
|
for (;;) {
|
|
@@ -43,6 +45,8 @@ function runPiClientCli(args) {
|
|
|
43
45
|
PI_SERVER_MODE: "true",
|
|
44
46
|
PI_CLIENT_VERSION: packageVersion,
|
|
45
47
|
PI_CLIENT_RELOAD_STATE_PATH: reloadStatePath,
|
|
48
|
+
PI_CLIENT_RELOAD_LEAF_ID: reloadLeafId,
|
|
49
|
+
PI_CLIENT_RUNTIME_UPDATED_AT: runtimeUpdatedAt,
|
|
46
50
|
},
|
|
47
51
|
stdio: "inherit",
|
|
48
52
|
});
|
|
@@ -53,14 +57,10 @@ function runPiClientCli(args) {
|
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
const state = readReloadState(reloadStatePath);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
rmSync(state.updateMarkerPath, { force: true });
|
|
62
|
-
childArgs = state.sessionDir ? ["--session-dir", state.sessionDir, "--session", state.sessionId] : ["--session", state.sessionId];
|
|
63
|
-
cliPath = getUpdatedGlobalCliPath() ?? getLocalCliPath();
|
|
60
|
+
cliPath = getUpdatedGlobalCliPath();
|
|
61
|
+
reloadLeafId = state.leafId ?? "";
|
|
62
|
+
runtimeUpdatedAt = state.updatedAt;
|
|
63
|
+
childArgs = [...state.args, ...(state.sessionDir ? ["--session-dir", state.sessionDir] : []), "--session", state.sessionId];
|
|
64
64
|
}
|
|
65
65
|
} finally {
|
|
66
66
|
rmSync(reloadDir, { recursive: true, force: true });
|
|
@@ -72,24 +72,42 @@ function getLocalCliPath() {
|
|
|
72
72
|
return join(dirname(entry), "cli.js");
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
function readRuntimeUpdateGeneration() {
|
|
76
|
+
const markerPath = join(process.env.PI_CODING_AGENT_DIR ?? join(homedir(), ".pi", "agent"), "pi-client-update.json");
|
|
77
|
+
try {
|
|
78
|
+
const marker = JSON.parse(readFileSync(markerPath, "utf-8"));
|
|
79
|
+
if (typeof marker?.updatedAt !== "string") throw new Error(`Invalid pi-client update marker: ${markerPath}`);
|
|
80
|
+
return marker.updatedAt;
|
|
81
|
+
} catch (error) {
|
|
82
|
+
if (error.code !== "ENOENT") console.error(`Could not read pi-client update marker: ${error.message}`);
|
|
83
|
+
return "";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
75
87
|
function getUpdatedGlobalCliPath() {
|
|
76
88
|
const npmCli = join(dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
77
|
-
const result =
|
|
89
|
+
const result = process.platform === "win32"
|
|
78
90
|
? spawnSync(process.execPath, [npmCli, "root", "-g"], { encoding: "utf-8" })
|
|
79
91
|
: spawnSync("npm", ["root", "-g"], { encoding: "utf-8" });
|
|
80
|
-
if (result.
|
|
92
|
+
if (result.error) throw result.error;
|
|
93
|
+
if (result.status !== 0) {
|
|
94
|
+
throw new Error(`Could not locate the updated pi-client runtime: ${result.stderr.trim()}`);
|
|
95
|
+
}
|
|
81
96
|
const root = result.stdout.trim();
|
|
82
|
-
|
|
83
|
-
return existsSync(cliPath) ? cliPath : undefined;
|
|
97
|
+
return join(root, "@averyyy", "pi-client", "node_modules", "@earendil-works", "pi-coding-agent", "dist", "cli.js");
|
|
84
98
|
}
|
|
85
99
|
|
|
86
100
|
function readReloadState(path) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
101
|
+
const value = JSON.parse(readFileSync(path, "utf-8"));
|
|
102
|
+
if (
|
|
103
|
+
typeof value?.sessionId !== "string" ||
|
|
104
|
+
typeof value?.updatedAt !== "string" ||
|
|
105
|
+
!Array.isArray(value.args) ||
|
|
106
|
+
!value.args.every((arg) => typeof arg === "string") ||
|
|
107
|
+
(value.leafId !== null && typeof value.leafId !== "string") ||
|
|
108
|
+
(value.sessionDir !== undefined && typeof value.sessionDir !== "string")
|
|
109
|
+
) {
|
|
110
|
+
throw new Error(`Invalid pi-client reload state: ${path}`);
|
|
94
111
|
}
|
|
112
|
+
return value;
|
|
95
113
|
}
|
package/bin/update.js
CHANGED
|
@@ -12,10 +12,6 @@ function readPackageMetadata(packageRoot) {
|
|
|
12
12
|
return JSON.parse(readFileSync(resolve(packageRoot, "package.json"), "utf-8"));
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
function runStep(runner, command, args, cwd, stdio = "inherit") {
|
|
16
|
-
return runner(command, args, { cwd, stdio, encoding: "utf-8" });
|
|
17
|
-
}
|
|
18
|
-
|
|
19
15
|
function defaultUpdateMarkerPath() {
|
|
20
16
|
return join(process.env.PI_CODING_AGENT_DIR ?? join(homedir(), ".pi", "agent"), "pi-client-update.json");
|
|
21
17
|
}
|
|
@@ -25,12 +21,13 @@ function writeUpdateMarker(path) {
|
|
|
25
21
|
writeFileSync(path, `${JSON.stringify({ version: "latest", updatedAt: new Date().toISOString() })}\n`);
|
|
26
22
|
}
|
|
27
23
|
|
|
28
|
-
function runNpmGlobalUpdate(runner, cwd, stdout, stderr, updateMarkerPath) {
|
|
24
|
+
function runNpmGlobalUpdate(runner, cwd, stdout, stderr, updateMarkerPath, platform) {
|
|
29
25
|
stdout.write("Updating npm packages: @averyyy/pi-client@latest @averyyy/pi-server@latest\n");
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
const command = platform === "win32" ? process.execPath : "npm";
|
|
27
|
+
const result = runner(
|
|
28
|
+
command,
|
|
33
29
|
[
|
|
30
|
+
...(platform === "win32" ? [join(dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js")] : []),
|
|
34
31
|
"install",
|
|
35
32
|
"-g",
|
|
36
33
|
"--ignore-scripts",
|
|
@@ -39,7 +36,7 @@ function runNpmGlobalUpdate(runner, cwd, stdout, stderr, updateMarkerPath) {
|
|
|
39
36
|
"@averyyy/pi-client@latest",
|
|
40
37
|
"@averyyy/pi-server@latest",
|
|
41
38
|
],
|
|
42
|
-
cwd,
|
|
39
|
+
{ cwd, stdio: "inherit", encoding: "utf-8" },
|
|
43
40
|
);
|
|
44
41
|
if (result.status !== 0) {
|
|
45
42
|
stderr.write(
|
|
@@ -59,10 +56,11 @@ export async function runPiClientUpdate(_args = [], options = {}) {
|
|
|
59
56
|
const stdout = options.stdout ?? process.stdout;
|
|
60
57
|
const stderr = options.stderr ?? process.stderr;
|
|
61
58
|
const updateMarkerPath = options.updateMarkerPath ?? defaultUpdateMarkerPath();
|
|
59
|
+
const platform = options.platform ?? process.platform;
|
|
62
60
|
const pkg = readPackageMetadata(packageRoot);
|
|
63
|
-
const baseVersion = pkg.piClient
|
|
64
|
-
const baseCommit = pkg.piClient
|
|
61
|
+
const baseVersion = pkg.piClient.basePiVersion;
|
|
62
|
+
const baseCommit = pkg.piClient.basePiCommit;
|
|
65
63
|
|
|
66
64
|
stdout.write(`pi-client ${pkg.version} (based on pi ${baseVersion}, upstream ${baseCommit})\n`);
|
|
67
|
-
return runNpmGlobalUpdate(runner, process.cwd(), stdout, stderr, updateMarkerPath);
|
|
65
|
+
return runNpmGlobalUpdate(runner, process.cwd(), stdout, stderr, updateMarkerPath, platform);
|
|
68
66
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@averyyy/pi-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0-piclient.1",
|
|
4
4
|
"description": "Lightweight CLI wrapper that connects to a pi-server instance",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piClient": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"prepublishOnly": "npm run build"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@earendil-works/pi-coding-agent": "npm:@averyyy/pi-coding-agent@1.
|
|
28
|
+
"@earendil-works/pi-coding-agent": "npm:@averyyy/pi-coding-agent@1.3.0-piclient.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"shx": "0.4.0",
|