pi-session-mcp 0.6.2 → 0.6.4
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/.pi-session-mcp-cli/doctor-cli.js +5 -1
- package/.pi-session-mcp-cli/doctor.js +9 -2
- package/CHANGELOG.md +28 -0
- package/README.md +1 -1
- package/dist/doctor-cli.js +5 -1
- package/dist/doctor.js +9 -2
- package/docs/acceptance.md +44 -0
- package/docs/client-setup.md +31 -0
- package/docs/doctor-design.md +3 -1
- package/docs/installation.md +8 -1
- package/docs/tool-contracts.md +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
1
2
|
import { parseDoctorArgs, renderDoctorHuman, renderDoctorJson, runDoctor } from "./doctor.js";
|
|
3
|
+
// The generated CLI lives one level below the package root. An npm executable runs
|
|
4
|
+
// from any directory, so the working directory says nothing about the package.
|
|
5
|
+
const PACKAGE_ROOT = fileURLToPath(new URL("..", import.meta.url));
|
|
2
6
|
const options = parseDoctorArgs(process.argv.slice(2));
|
|
3
7
|
if (!options) {
|
|
4
8
|
process.stderr.write("Usage: doctor [--json]\n");
|
|
5
9
|
process.exitCode = 64;
|
|
6
10
|
}
|
|
7
11
|
else {
|
|
8
|
-
const result = await runDoctor();
|
|
12
|
+
const result = await runDoctor({ packageRoot: PACKAGE_ROOT });
|
|
9
13
|
process.stdout.write(options.json ? renderDoctorJson(result) : renderDoctorHuman(result));
|
|
10
14
|
process.exitCode = result.exitCode;
|
|
11
15
|
}
|
|
@@ -104,8 +104,15 @@ export async function runDoctor(dependencies = {}) {
|
|
|
104
104
|
const packageMtime = (await fs.stat(join(root, "package.json"))).mtimeMs;
|
|
105
105
|
const lockMtime = await lockfileMtime(fs, root);
|
|
106
106
|
const inputMtimes = [packageMtime, lockMtime].filter((value) => value !== undefined);
|
|
107
|
-
if (!dependencies.fileSystem)
|
|
108
|
-
|
|
107
|
+
if (!dependencies.fileSystem) {
|
|
108
|
+
const buildInputMtimes = await productionBuildInputMtimes(root);
|
|
109
|
+
// npm writes an installed package at extraction time in archive order, so without
|
|
110
|
+
// build inputs the manifest times say nothing about the freshness of the build.
|
|
111
|
+
if (buildInputMtimes.length === 0)
|
|
112
|
+
inputMtimes.length = 0;
|
|
113
|
+
else
|
|
114
|
+
inputMtimes.push(...buildInputMtimes);
|
|
115
|
+
}
|
|
109
116
|
if (inputMtimes.some((mtime) => mtime > buildMtime))
|
|
110
117
|
checks.push(warning("build_stale", "build output", "run the production build"));
|
|
111
118
|
else
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.6.4 — 2026-10-10
|
|
6
|
+
|
|
7
|
+
- `pi-session-mcp-doctor` now checks the package it belongs to, whatever the
|
|
8
|
+
current directory is. Previously it checked the current directory: in an npm
|
|
9
|
+
installation, run from another directory, it failed with
|
|
10
|
+
`package_metadata_unreadable` and `build_missing`, and inside another
|
|
11
|
+
checkout it reported that checkout. `npm run doctor` in a release checkout
|
|
12
|
+
and `setup` were not affected.
|
|
13
|
+
- The installation guide and client setup reference now say that Codex
|
|
14
|
+
rewrites `config.toml` when a registration changes: it groups the
|
|
15
|
+
`[mcp_servers.*]` tables and drops comments directly above them. Copy the
|
|
16
|
+
file first if its comments matter.
|
|
17
|
+
- The client setup reference now explains that `codex exec` rejects
|
|
18
|
+
`pi_session_prompt`, `pi_session_abort` and `pi_session_close` unless they
|
|
19
|
+
are approved, because it never asks and the tools are marked destructive. It
|
|
20
|
+
shows the per-run `-c` approvals.
|
|
21
|
+
|
|
22
|
+
## 0.6.3 — 2026-10-10
|
|
23
|
+
|
|
24
|
+
- Doctor no longer reports a false `build_stale` warning right after
|
|
25
|
+
`npm install` with npm 12. npm 12 writes extracted files with the extraction
|
|
26
|
+
time, and the package lists `dist/` before `package.json`, so the installed
|
|
27
|
+
manifest was always newer than the build. An installation without build
|
|
28
|
+
configuration or TypeScript sources no longer compares manifest times; a
|
|
29
|
+
source checkout still does.
|
|
30
|
+
- `setup` was re-recorded against Claude Code `2.1.296`; its `mcp` command
|
|
31
|
+
contract is unchanged.
|
|
32
|
+
|
|
5
33
|
## 0.6.2 — 2026-10-09
|
|
6
34
|
|
|
7
35
|
- The server now shuts down when the MCP client closes its stdin. Previously
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ It is not the right tool when:
|
|
|
29
29
|
|
|
30
30
|
## Status
|
|
31
31
|
|
|
32
|
-
The package version is **0.6.
|
|
32
|
+
The package version is **0.6.4**.
|
|
33
33
|
|
|
34
34
|
- **Pre-1.0.** The public tool contract is stable within a minor line: a change to tools, fields, states or error codes needs a new minor release.
|
|
35
35
|
- **Linux only**, Node.js 22.19.0 or newer.
|
package/dist/doctor-cli.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
1
2
|
import { parseDoctorArgs, renderDoctorHuman, renderDoctorJson, runDoctor } from "./doctor.js";
|
|
3
|
+
// The generated CLI lives one level below the package root. An npm executable runs
|
|
4
|
+
// from any directory, so the working directory says nothing about the package.
|
|
5
|
+
const PACKAGE_ROOT = fileURLToPath(new URL("..", import.meta.url));
|
|
2
6
|
const options = parseDoctorArgs(process.argv.slice(2));
|
|
3
7
|
if (!options) {
|
|
4
8
|
process.stderr.write("Usage: doctor [--json]\n");
|
|
5
9
|
process.exitCode = 64;
|
|
6
10
|
}
|
|
7
11
|
else {
|
|
8
|
-
const result = await runDoctor();
|
|
12
|
+
const result = await runDoctor({ packageRoot: PACKAGE_ROOT });
|
|
9
13
|
process.stdout.write(options.json ? renderDoctorJson(result) : renderDoctorHuman(result));
|
|
10
14
|
process.exitCode = result.exitCode;
|
|
11
15
|
}
|
package/dist/doctor.js
CHANGED
|
@@ -104,8 +104,15 @@ export async function runDoctor(dependencies = {}) {
|
|
|
104
104
|
const packageMtime = (await fs.stat(join(root, "package.json"))).mtimeMs;
|
|
105
105
|
const lockMtime = await lockfileMtime(fs, root);
|
|
106
106
|
const inputMtimes = [packageMtime, lockMtime].filter((value) => value !== undefined);
|
|
107
|
-
if (!dependencies.fileSystem)
|
|
108
|
-
|
|
107
|
+
if (!dependencies.fileSystem) {
|
|
108
|
+
const buildInputMtimes = await productionBuildInputMtimes(root);
|
|
109
|
+
// npm writes an installed package at extraction time in archive order, so without
|
|
110
|
+
// build inputs the manifest times say nothing about the freshness of the build.
|
|
111
|
+
if (buildInputMtimes.length === 0)
|
|
112
|
+
inputMtimes.length = 0;
|
|
113
|
+
else
|
|
114
|
+
inputMtimes.push(...buildInputMtimes);
|
|
115
|
+
}
|
|
109
116
|
if (inputMtimes.some((mtime) => mtime > buildMtime))
|
|
110
117
|
checks.push(warning("build_stale", "build output", "run the production build"));
|
|
111
118
|
else
|
package/docs/acceptance.md
CHANGED
|
@@ -147,6 +147,9 @@ snapshot and digest tools and the scan for leaked values are prepared per cycle.
|
|
|
147
147
|
- Clients: record the exact client versions and how each client reached the
|
|
148
148
|
server. Prefer a temporary per-invocation MCP configuration, so that no
|
|
149
149
|
global registration changes.
|
|
150
|
+
- Waiting: let each client wait a bounded time between `pi_turn_get` polls,
|
|
151
|
+
for example by allowing a shell `sleep` of a few seconds. A client that may
|
|
152
|
+
call only the Pi Session MCP tools has no way to wait and polls back to back.
|
|
150
153
|
- Pre-registration: fix the plan, the acceptance criteria per task, the prompts,
|
|
151
154
|
the oracles, the tools, the configurations and the fixture digests before the
|
|
152
155
|
first task.
|
|
@@ -182,6 +185,10 @@ repeat a task.
|
|
|
182
185
|
- Liveness: a running turn whose `updatedAt` advanced beyond `startedAt` shows
|
|
183
186
|
observable activity. Its absence only means that the turn finished between
|
|
184
187
|
two polls.
|
|
188
|
+
- Polling cost: count the `pi_turn_get` calls per turn. The counts are evidence
|
|
189
|
+
for the revisit trigger on bounded waiting in
|
|
190
|
+
[ADR 0003](adr/0003-post-mvp-maintenance.md) only when the client could wait
|
|
191
|
+
between polls.
|
|
185
192
|
|
|
186
193
|
### Gate
|
|
187
194
|
|
|
@@ -225,3 +232,40 @@ Release notes state which levels were run for a release and what was not
|
|
|
225
232
|
covered. Pi Session MCP has passed all three levels in earlier private cycles. The
|
|
226
233
|
live two-client acceptance has not yet been repeated on a build with Pi SDK
|
|
227
234
|
`1.x`.
|
|
235
|
+
|
|
236
|
+
`v0.6.2` passed Level 1 on a fresh clone of its tag. It passed Level 2 in all
|
|
237
|
+
three variants: working tree, published release, and published npm package.
|
|
238
|
+
The clients were Codex CLI `0.162.0` (`user`) and Claude Code `2.1.295`
|
|
239
|
+
(`user`, `project`, `local`), on 2026-10-09 and 2026-10-10. It had no Level 3
|
|
240
|
+
cycle.
|
|
241
|
+
|
|
242
|
+
Before its release, `v0.6.3` passed Level 1 and the working-tree Level 2 on its
|
|
243
|
+
release candidate, with Claude Code `2.1.296`. On 2026-10-10 the same candidate
|
|
244
|
+
also passed a narrower live check:
|
|
245
|
+
- Scope: Claude Code `2.1.296` as the only client, with Pi SDK `1.1.0` on a
|
|
246
|
+
local `qwen3.6-35b-a3b-splash` model served by LM Studio.
|
|
247
|
+
- All five tasks of the matrix reached their intended outcome in three
|
|
248
|
+
sequential invocations, and every pre-registered check passed.
|
|
249
|
+
- It covered no Codex task and does not count as a ten-task cycle.
|
|
250
|
+
|
|
251
|
+
After its release, `v0.6.3` passed Level 1 on a fresh clone of its tag. It also
|
|
252
|
+
passed Level 2 as published release and as published npm package, with Codex
|
|
253
|
+
CLI `0.162.0` and Claude Code `2.1.296`, on 2026-10-10.
|
|
254
|
+
|
|
255
|
+
On 2026-10-10, `main` at `4d333da`, which is `v0.6.3` plus the Doctor fix and
|
|
256
|
+
documentation, passed a narrower live check with Codex:
|
|
257
|
+
- Scope: Codex CLI `0.162.0` as the only client, run headless with
|
|
258
|
+
`codex exec` and the three tool approvals that
|
|
259
|
+
[client setup](client-setup.md#run-codex-without-prompts) describes. Pi SDK
|
|
260
|
+
`1.1.0` ran on the same local model.
|
|
261
|
+
- All five tasks of the matrix reached their intended outcome in three
|
|
262
|
+
sequential invocations, and every pre-registered check passed.
|
|
263
|
+
- The client could wait between polls and needed 1 to 3 `pi_turn_get` calls per
|
|
264
|
+
turn.
|
|
265
|
+
- It covered no Claude Code task and does not count as a ten-task cycle. The
|
|
266
|
+
Claude Code check above ran on another commit.
|
|
267
|
+
|
|
268
|
+
Before its release, `v0.6.4` passed Level 1 and the working-tree Level 2 on its
|
|
269
|
+
release candidate, with Codex CLI `0.162.0` and Claude Code `2.1.296`. Its
|
|
270
|
+
server entry point `dist/main.js` is byte-identical to that of `4d333da` and of
|
|
271
|
+
`v0.6.3`.
|
package/docs/client-setup.md
CHANGED
|
@@ -122,6 +122,37 @@ codex mcp list
|
|
|
122
122
|
codex mcp get pi-session-mcp
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
+
`codex mcp add` and `codex mcp remove` rewrite `config.toml`. Codex CLI
|
|
126
|
+
`0.162.0` groups all `[mcp_servers.*]` tables together and drops a comment
|
|
127
|
+
directly above such a table; settings are preserved. Copy the file first if its
|
|
128
|
+
comments matter to you.
|
|
129
|
+
|
|
130
|
+
### Run Codex without prompts
|
|
131
|
+
|
|
132
|
+
Interactive Codex asks before it calls a tool that is marked
|
|
133
|
+
`destructiveHint: true`: `pi_session_prompt`, `pi_session_abort` and
|
|
134
|
+
`pi_session_close`. `codex exec` never asks, so Codex CLI `0.162.0` rejects
|
|
135
|
+
these calls with "MCP tool call requires approval, but approval policy is
|
|
136
|
+
never". A headless run can then start sessions but cannot prompt, abort or
|
|
137
|
+
close them.
|
|
138
|
+
|
|
139
|
+
Approve the three tools for each headless run:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
codex exec \
|
|
143
|
+
-c 'mcp_servers.pi-session-mcp.tools.pi_session_prompt.approval_mode="approve"' \
|
|
144
|
+
-c 'mcp_servers.pi-session-mcp.tools.pi_session_abort.approval_mode="approve"' \
|
|
145
|
+
-c 'mcp_servers.pi-session-mcp.tools.pi_session_close.approval_mode="approve"' \
|
|
146
|
+
'Your task'
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The same `approval_mode` entries can live in `config.toml` under
|
|
150
|
+
`[mcp_servers.pi-session-mcp.tools.<tool>]`. They do not change the output of
|
|
151
|
+
`codex mcp get`, so `setup` still treats the registration as equal. But
|
|
152
|
+
`codex mcp remove`, which `setup --remove` and `--rollback` use, deletes them,
|
|
153
|
+
so they are gone after an upgrade. The per-run overrides do not have this
|
|
154
|
+
problem.
|
|
155
|
+
|
|
125
156
|
## Register with Claude Code
|
|
126
157
|
|
|
127
158
|
Claude Code CLI 2.1.251 was locally confirmed with this command form. Replace every absolute-path placeholder with your local paths; use absolute paths for the Node executable, built entry point, and configuration file.
|
package/docs/doctor-design.md
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
`src/doctor-cli.ts` is a separate local entry point. It never imports the MCP
|
|
4
4
|
server, initializes transport, creates a Pi session, reads credentials, or
|
|
5
5
|
performs network activity.
|
|
6
|
+
It checks the package it was loaded from, never the current working
|
|
7
|
+
directory: an npm executable can run from any directory.
|
|
6
8
|
|
|
7
9
|
`runDoctor` returns one frozen result model (`schemaVersion: 1`, `ok`, a
|
|
8
10
|
sanitized semver `packageVersion` when metadata is available, ordered `checks`,
|
|
@@ -20,7 +22,7 @@ and owners are:
|
|
|
20
22
|
| `node_version_unsupported` | Runtime does not satisfy `package.json#engines.node` | `Node.js` |
|
|
21
23
|
| `package_metadata_unreadable` | Package metadata is missing, unreadable or malformed, or a lockfile is present but malformed | `package metadata` |
|
|
22
24
|
| `build_missing` | `dist/main.js` is absent, inaccessible, or not a regular file | `build output` |
|
|
23
|
-
| `build_stale` | Package, lock, build configuration, or production TypeScript input is newer than the build output, or freshness cannot be established. Inputs that an npm installation does not contain are skipped | `build output` |
|
|
25
|
+
| `build_stale` | Package, lock, build configuration, or production TypeScript input is newer than the build output, or freshness cannot be established. Inputs that an npm installation does not contain are skipped. Without any build configuration or TypeScript input, as in an npm installation, the package and lock times are not compared either, because npm writes extracted files with the extraction time | `build output` |
|
|
24
26
|
| `version_mismatch` | Package and lock versions differ; this is a warning and does not apply to an npm installation, which has no lockfile | `package version` |
|
|
25
27
|
| `config_missing` | `PI_SESSION_MCP_CONFIG` is not set, or the file it names is absent | `configuration` |
|
|
26
28
|
| `config_unreadable` | The supported configuration path cannot be read | `configuration` |
|
package/docs/installation.md
CHANGED
|
@@ -47,7 +47,7 @@ the same arguments.
|
|
|
47
47
|
- Codex CLI or Claude Code. `setup` does not pin client versions. It accepts a
|
|
48
48
|
client whose public `mcp` command output matches the expected contract and
|
|
49
49
|
reports `unsupported` otherwise. The contract was last recorded with Codex CLI
|
|
50
|
-
`0.162.0` and Claude Code `2.1.
|
|
50
|
+
`0.162.0` and Claude Code `2.1.296`. Manual registration, described in the
|
|
51
51
|
[client setup reference](client-setup.md), works independently of `setup`.
|
|
52
52
|
- For real prompts only: local Pi authentication and a provider and model pair
|
|
53
53
|
that the local Pi configuration knows. Installation, Doctor and `setup` need
|
|
@@ -207,6 +207,13 @@ pi-session-mcp-setup --apply --target claude-code:user:pi-session-mcp
|
|
|
207
207
|
pi-session-mcp-setup --verify --target claude-code:user:pi-session-mcp
|
|
208
208
|
```
|
|
209
209
|
|
|
210
|
+
`setup` changes a Codex registration only through `codex mcp add` and
|
|
211
|
+
`codex mcp remove`, and Codex rewrites `config.toml` on each of them. Codex CLI
|
|
212
|
+
`0.162.0` groups all `[mcp_servers.*]` tables together and drops a comment
|
|
213
|
+
directly above such a table; settings are preserved. If your `config.toml`
|
|
214
|
+
contains comments worth keeping, copy it before `--apply`, `--rollback` or
|
|
215
|
+
`--remove` on `codex:user:pi-session-mcp`.
|
|
216
|
+
|
|
210
217
|
Each report has one line for the operation with its overall status, and one line
|
|
211
218
|
per target with a finding in the form `status (code)`:
|
|
212
219
|
|
package/docs/tool-contracts.md
CHANGED
|
@@ -22,7 +22,7 @@ There are exactly eight tools. No `pi_turn_wait` tool or live provider/model inv
|
|
|
22
22
|
```json
|
|
23
23
|
{
|
|
24
24
|
"ok": true,
|
|
25
|
-
"server": { "name": "pi-session-mcp", "version": "0.6.
|
|
25
|
+
"server": { "name": "pi-session-mcp", "version": "0.6.4" },
|
|
26
26
|
"configuration": {
|
|
27
27
|
"fingerprint": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
|
28
28
|
"reloadPolicy": "restart-required"
|