pi-session-mcp 0.6.1 → 0.6.2

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
@@ -2,6 +2,35 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.6.2 — 2026-10-09
6
+
7
+ - The server now shuts down when the MCP client closes its stdin. Previously
8
+ only `SIGINT` and `SIGTERM` ran the bounded shutdown, so after stdin EOF an
9
+ idle Pi session and its external MCP server kept running. EOF uses the same
10
+ 15,000 ms shutdown and exits with status `0`; the first of EOF and a signal
11
+ sets the exit status. Public tools, fields, states and error codes are
12
+ unchanged.
13
+ - Built on Pi SDK `1.1.0` (was `1.0.4`). Pi now retries `server_busy` provider
14
+ errors instead of ending the turn. The new `aborted` flag on settled runs is
15
+ not a closed terminal cause, so failed turns still report `turn_failed`.
16
+ Public tools, fields, states and error codes are unchanged.
17
+ - Built on the MCP TypeScript SDK `2.3.1` (was `2.2.0`). Its packages are now
18
+ licensed under Apache-2.0 instead of MIT. The stdio entry point already
19
+ builds one server per connection, which the SDK now requires.
20
+ - Validates with Zod `4.6.5` (was `4.5.4`), which fixes an out-of-memory
21
+ regression of Zod 4.5 in recursive schemas.
22
+ - Development: MCP Inspector `2.10.1` (was the deprecated `0.19.0`). `npm run
23
+ inspect` works as before. Inspector 2.x keeps its catalog in
24
+ `~/.mcp-inspector/`; see the README for its secret storage. The lockfile
25
+ loses 216 packages and gains 89, and the earlier lockfile patches for
26
+ `proxy-addr`, `shell-quote` and `concurrently` leave the tree with the old
27
+ Inspector.
28
+ - Development: TypeScript `7.0.2` (was `5.9.3`), Vitest `5.0.3` (was
29
+ `4.1.11`) and `@types/node` `22.20.5` (was `22.19.19`). The emitted
30
+ JavaScript is byte-identical to the TypeScript 5.9 build.
31
+ - `setup` was re-recorded against Codex CLI `0.162.0` and Claude Code
32
+ `2.1.295`; their `mcp` command contracts are unchanged.
33
+
5
34
  ## 0.6.1 — 2026-10-07
6
35
 
7
36
  - The stdio fixture tests no longer fail when they read a log line that the
package/README.md CHANGED
@@ -29,14 +29,14 @@ It is not the right tool when:
29
29
 
30
30
  ## Status
31
31
 
32
- The package version is **0.6.1**.
32
+ The package version is **0.6.2**.
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.
36
36
  - **Clients:** Codex CLI and Claude Code. The `setup` command does not pin client versions: it accepts a client whose public `mcp` command output matches the expected contract and fails closed otherwise.
37
37
  - **Out of scope by design:** HTTP, a web UI, persistence, resume, remote access and multi-user behavior. One trusted local MCP peer talks to one server process.
38
38
  - **Not a sandbox.** A `coding` profile restricts the Pi tools that a session may use. It does not isolate the process from the operating system.
39
- - **Acceptance.** Every release passes the provider-free checks. The live two-client acceptance has not yet been repeated on a build with Pi SDK `1.0.x`; see [Acceptance](docs/acceptance.md).
39
+ - **Acceptance.** Every release passes the provider-free checks. The live two-client acceptance has not yet been repeated on a build with Pi SDK `1.x`; see [Acceptance](docs/acceptance.md).
40
40
 
41
41
  ## How it works
42
42
 
@@ -124,6 +124,8 @@ npm run inspect
124
124
 
125
125
  Listing tools and testing input validation needs no provider credentials. An accepted prompt needs existing local Pi authentication and an available provider and model.
126
126
 
127
+ Inspector 2.x keeps its server catalog in `~/.mcp-inspector/`. Without an OS keychain it also stores secrets there unencrypted; `MCP_INSPECTOR_SECRET_STORE=memory` keeps them in memory only.
128
+
127
129
  ## Security model
128
130
 
129
131
  - **Local and single-peer.** No network listener, no daemon between client sessions, no persisted session state.
package/dist/config.d.ts CHANGED
@@ -10,19 +10,19 @@ export declare const configSchema: z.ZodObject<{
10
10
  executionProfiles: z.ZodRecord<z.ZodString, z.ZodObject<{
11
11
  default: z.ZodBoolean;
12
12
  permissionProfile: z.ZodEnum<{
13
- "read-only": "read-only";
14
13
  coding: "coding";
14
+ "read-only": "read-only";
15
15
  }>;
16
16
  provider: z.ZodString;
17
17
  model: z.ZodString;
18
18
  thinkingLevel: z.ZodEnum<{
19
- off: "off";
20
- minimal: "minimal";
19
+ high: "high";
21
20
  low: "low";
21
+ max: "max";
22
22
  medium: "medium";
23
- high: "high";
23
+ minimal: "minimal";
24
+ off: "off";
24
25
  xhigh: "xhigh";
25
- max: "max";
26
26
  }>;
27
27
  mcpServers: z.ZodOptional<z.ZodCustom<Readonly<Record<string, import("./mcp-config.js").McpServerConfig>>, Readonly<Record<string, import("./mcp-config.js").McpServerConfig>>>>;
28
28
  }, z.core.$strict>>;
package/dist/main.js CHANGED
@@ -40,5 +40,12 @@ async function main() {
40
40
  };
41
41
  process.once("SIGINT", () => { void shutdown(130); });
42
42
  process.once("SIGTERM", () => { void shutdown(143); });
43
+ // On stdin EOF the SDK closes only its transport and server instance; sessions and
44
+ // their MCP children need the same bounded shutdown as a signal. The first trigger wins.
45
+ const endOfInput = () => { void shutdown(0); };
46
+ process.stdin.once("end", endOfInput);
47
+ process.stdin.once("close", endOfInput);
48
+ if (process.stdin.readableEnded || process.stdin.destroyed)
49
+ endOfInput();
43
50
  }
44
51
  await main();
@@ -224,4 +224,4 @@ not count as a ten-task cycle.
224
224
  Release notes state which levels were run for a release and what was not
225
225
  covered. Pi Session MCP has passed all three levels in earlier private cycles. The
226
226
  live two-client acceptance has not yet been repeated on a build with Pi SDK
227
- `1.0.x`.
227
+ `1.x`.
@@ -1,10 +1,10 @@
1
1
  # Architecture
2
2
 
3
- ## Validated dependency baseline (2026-09-30)
3
+ ## Validated dependency baseline (2026-10-09)
4
4
 
5
- - [`@earendil-works/pi-coding-agent` 1.0.4](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) supplies the documented root exports used by this server, including `ModelRuntime` and `createAgentSession`. Since 0.99 the prompt preflight hook reports a dispatch disposition (`started`, `queued`, `handled`) and is not called on rejection; only `started` admits a public turn (`admitsTurn` in `src/sdk-pi-adapter.ts`). Model-visible tools are declared on transcript system messages rather than in the provider context. `test/sdk-contract.test.ts` pins both assumptions provider-free.
6
- - [`@modelcontextprotocol/server` 2.2.0](https://www.npmjs.com/package/@modelcontextprotocol/server) supplies `McpServer`, structured tool output, and the stdio entry point.
7
- - [Zod 4.5.4](https://zod.dev/) validates strict configuration, tool input, and structured output.
5
+ - [`@earendil-works/pi-coding-agent` 1.1.0](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) supplies the documented root exports used by this server, including `ModelRuntime` and `createAgentSession`. Since 0.99 the prompt preflight hook reports a dispatch disposition (`started`, `queued`, `handled`) and is not called on rejection; only `started` admits a public turn (`admitsTurn` in `src/sdk-pi-adapter.ts`). Model-visible tools are declared on transcript system messages rather than in the provider context. `test/sdk-contract.test.ts` pins both assumptions provider-free.
6
+ - [`@modelcontextprotocol/server` 2.3.1](https://www.npmjs.com/package/@modelcontextprotocol/server) supplies `McpServer`, structured tool output, and the stdio entry point.
7
+ - [Zod 4.6.5](https://zod.dev/) validates strict configuration, tool input, and structured output.
8
8
 
9
9
  All are exact direct pins. No API is taken from an unexported package path. A nightly canary checks the unchanged sources against the newest published Pi SDK without changing the pin (see the README section "Checks").
10
10
 
@@ -71,9 +71,9 @@ The registry owns public UUIDs, lifecycle state, the turn read model, background
71
71
 
72
72
  Session metadata contains only whitelisted values: public session ID, workspace alias, execution-profile alias, derived permission `profile`, post-verified provider/model/effective thinking level, lifecycle state, and timestamps. Capability metadata uses a separate whitelist: server name/version, loaded configuration fingerprint/reload policy, workspace aliases, and configured profile fields. Neither view contains workspace paths, full model objects, SDK session IDs, auth sources, credential paths, headers, base URLs, prompts, transcripts, or raw provider errors.
73
73
 
74
- Profile-specific authentication/catalog operations and session creation have fixed server-side deadlines of 5,000 ms and 10,000 ms. Prompt preflight, abort, close cleanup, registry shutdown, and signal handling have fixed server-side deadlines of 5,000 ms, 5,000 ms, 5,000 ms, 12,000 ms, and 15,000 ms respectively. A preflight timeout returns `prompt_timeout` without publishing a turn. The unpublished operation remains quarantined until its prompt and abort cannot race with later work; late settlement can release that quarantine but never publish the turn. An abort timeout returns `abort_timeout` without falsely marking the turn aborted; a later normal outcome or successful SDK abort may still terminalize it exactly once. Close marks the session terminal, removes its public registry entry deterministically, and performs best-effort abort/dispose. Repeated close calls return a cached closed view while its tombstone is retained. Each SDK handle is disposed at most once. A late promise cannot revive a removed session or mutate a removed turn.
74
+ Profile-specific authentication/catalog operations and session creation have fixed server-side deadlines of 5,000 ms and 10,000 ms. Prompt preflight, abort, close cleanup, registry shutdown, and process shutdown have fixed server-side deadlines of 5,000 ms, 5,000 ms, 5,000 ms, 12,000 ms, and 15,000 ms respectively. A preflight timeout returns `prompt_timeout` without publishing a turn. The unpublished operation remains quarantined until its prompt and abort cannot race with later work; late settlement can release that quarantine but never publish the turn. An abort timeout returns `abort_timeout` without falsely marking the turn aborted; a later normal outcome or successful SDK abort may still terminalize it exactly once. Close marks the session terminal, removes its public registry entry deterministically, and performs best-effort abort/dispose. Repeated close calls return a cached closed view while its tombstone is retained. Each SDK handle is disposed at most once. A late promise cannot revive a removed session or mutate a removed turn.
75
75
 
76
- The public SDK does not provide a hard-kill guarantee for a blocked provider/network operation, so a timeout must not be described as graceful provider cancellation. Shutdown closes registry entries and the MCP transport best-effort; the signal handler then explicitly exits the Pi Session MCP process no later than its 15,000 ms deadline. That terminal process policy may cut off still-running external work and does not prove the provider stopped cleanly. Closed tombstones are FIFO-retained up to 100 entries and contain no turn data. All sessions, turns, tombstones, and loaded configuration snapshots disappear on process exit; there is no persistence or reconnect/resume.
76
+ The public SDK does not provide a hard-kill guarantee for a blocked provider/network operation, so a timeout must not be described as graceful provider cancellation. `SIGINT`, `SIGTERM`, and stdin EOF from the MCP client start the same process shutdown. The first trigger wins and sets the exit status (130, 143, or 0). Stdin EOF or the first `SIGINT` or `SIGTERM` during a running shutdown neither restarts it nor changes that status; a signal that arrives a second time keeps Node's default effect and ends the process immediately. Shutdown closes registry entries and the MCP transport best-effort, then explicitly exits the Pi Session MCP process no later than its 15,000 ms deadline. That terminal process policy may cut off still-running external work and does not prove the provider stopped cleanly. Closed tombstones are FIFO-retained up to 100 entries and contain no turn data. All sessions, turns, tombstones, and loaded configuration snapshots disappear on process exit; there is no persistence or reconnect/resume.
77
77
 
78
78
  Public errors are stable and sanitized. They omit caller values, complete prompts, paths, provider/SDK details, authentication data, credential locations, and SDK identifiers.
79
79
 
@@ -151,7 +151,7 @@ Claude Code enforces each tool's declared JSON Schema (`additionalProperties: fa
151
151
 
152
152
  Capability discovery sorts both arrays by alias and returns no workspace paths. It reports configured provider/model intent without checking authentication, provider availability, the filesystem, or the network. Session start remains the first runtime check.
153
153
 
154
- Server deadlines are profile-specific authentication/catalog work 5,000 ms per operation, session creation 10,000 ms, preflight 5,000 ms, abort 5,000 ms, close cleanup 5,000 ms, registry shutdown 12,000 ms, and process signal shutdown 15,000 ms. A preflight timeout returns `prompt_timeout` (`Pi prompt preflight timed out`) without a public turn. An abort timeout returns `abort_timeout` (`Pi abort timed out`) without claiming abortion; rejection/failure remain `prompt_rejected`/`abort_failed`. Close removes the public entry after best-effort cleanup and remains idempotent for retained tombstones. Shutdown rejects new starts with `server_stopping`; the signal handler explicitly exits the process after its bounded cleanup window. These limits do not prove graceful cancellation of a blocked provider request. Late SDK promises cannot publish a turn or revive a removed session. At most 100 closed tombstones are retained FIFO.
154
+ Server deadlines are profile-specific authentication/catalog work 5,000 ms per operation, session creation 10,000 ms, preflight 5,000 ms, abort 5,000 ms, close cleanup 5,000 ms, registry shutdown 12,000 ms, and process shutdown on a signal or stdin EOF 15,000 ms. A preflight timeout returns `prompt_timeout` (`Pi prompt preflight timed out`) without a public turn. An abort timeout returns `abort_timeout` (`Pi abort timed out`) without claiming abortion; rejection/failure remain `prompt_rejected`/`abort_failed`. Close removes the public entry after best-effort cleanup and remains idempotent for retained tombstones. Shutdown rejects new starts with `server_stopping`; process shutdown explicitly exits the process after its bounded cleanup window. These limits do not prove graceful cancellation of a blocked provider request. Late SDK promises cannot publish a turn or revive a removed session. At most 100 closed tombstones are retained FIFO.
155
155
 
156
156
  There are eight tools: `pi_capabilities_get`, `pi_session_start`, `pi_session_list`, `pi_session_get`, `pi_session_prompt`, `pi_session_abort`, `pi_session_close`, and `pi_turn_get`. Capability discovery accepts only `{}`. `pi_session_start` rejects the old `profile` input, raw `provider`, `model`, `thinkingLevel`, credential-like fields, and all unknown fields. Its safe session metadata includes the configured execution-profile alias and post-verified provider/model/effective thinking level; the existing `profile` output remains derived permission metadata.
157
157
 
@@ -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.159.2` and Claude Code `2.1.292`. Manual registration, described in the
50
+ `0.162.0` and Claude Code `2.1.295`. 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
package/docs/releasing.md CHANGED
@@ -118,8 +118,8 @@ Patch transitive advisories in the lockfile only:
118
118
  `package-lock.json` changed. Direct pins in `package.json` stay untouched.
119
119
  2. If an advisory remains because a parent package pins an affected version
120
120
  exactly, resolve the parent at another version inside the range that its own
121
- dependent declares. The development-only `concurrently` is resolved this way
122
- at `9.2.0`.
121
+ dependent declares. The development-only `concurrently` was resolved this
122
+ way at `9.2.0` until MCP Inspector 2.x stopped depending on it.
123
123
  3. Run `npm ci`, both audit commands and the Level 1 checks.
124
124
  4. Name every patched package, its versions, its advisory and whether it is in
125
125
  the production install path in the changelog.
@@ -171,14 +171,26 @@ package contains exactly the tagged sources:
171
171
  git clone --branch v<x.y.z> --depth 1 https://github.com/plagor44-ux/pi-session-mcp.git /tmp/pi-session-mcp-release
172
172
  cd /tmp/pi-session-mcp-release
173
173
  npm ci
174
- npm pack --dry-run # review the file list: dist/, .pi-session-mcp-cli/, scripts/doctor.mjs, docs/
175
- npm publish --otp=<code> # the prepack script builds the server, setup and Doctor
176
- npm view pi-session-mcp@<x.y.z> version dist.tarball
174
+ npm publish --dry-run # review the file list: dist/, .pi-session-mcp-cli/, scripts/doctor.mjs, docs/
175
+ npm stage publish # the prepack script builds the server, setup and Doctor
177
176
  ```
178
177
 
179
- Publishing needs the npm account of the maintainer with two-factor
180
- authentication; `--otp` takes the current one-time code. Finally create the
181
- GitHub release:
178
+ `npm stage publish` (npm 11.15 or later) places the version in the registry's
179
+ staging area without a second factor. The maintainer then approves it with the
180
+ account's second factor, on npmjs.com under the package's **Staged Packages**
181
+ tab or with `npm stage approve <stage-id>`. Staging a package that does not
182
+ exist yet also creates the public placeholder version `0.0.0-stage`. A direct
183
+ `npm publish` works as well when the second factor can be entered in the
184
+ terminal.
185
+
186
+ After the approval, confirm that the registry serves the staged bytes:
187
+
188
+ ```bash
189
+ npm view pi-session-mcp@<x.y.z> version dist.shasum
190
+ ```
191
+
192
+ The shasum must equal the one that `npm stage publish` printed. Finally create
193
+ the GitHub release:
182
194
 
183
195
  ```bash
184
196
  gh release create v<x.y.z> --title "pi-session-mcp v<x.y.z>" --notes-file <notes-file>
@@ -243,6 +243,9 @@ npm test
243
243
  `test/mcp-session-tools.test.ts` covers policy, discovery, mapping, result/error
244
244
  handling, cancellation, deadlines, shutdown and per-session ownership.
245
245
  `test/mcp-registry-cleanup.test.ts` covers asynchronous disposal and shutdown races.
246
+ `test/process-stdin-eof.test.ts` starts the freshly compiled server entry point with
247
+ a placeholder loopback provider and checks that stdin EOF, alone or racing `SIGTERM`,
248
+ closes idle, running and still-starting sessions and their MCP children.
246
249
  `test/mcp-sdk-integration.test.ts` covers config/capabilities and adapter wiring with
247
250
  a fake model runtime and fake MCP connection. It is not a live protocol test.
248
251
  `test/mcp-error-projection.test.ts` exercises the pinned Pi SDK and a real local
@@ -60,9 +60,9 @@ Pi Session MCP trusts the local process that launches and speaks MCP over inheri
60
60
  - **Secret/prompt disclosure:** stdout is protocol-only. Stderr diagnostics use stable code and safe context only. Public metadata is whitelisted and omits auth objects/sources, credential paths, headers, base URLs, complete model objects, SDK IDs, raw provider errors, prompts, transcripts, and tool data. Completed `assistantText` can still repeat model-visible data and is potentially sensitive.
61
61
  - **Capability-enumeration disclosure:** the trusted local MCP peer can read configured workspace aliases and execution-profile provider/model intent. Discovery omits workspace paths, authentication state, SDK state, sessions, turns, prompts, transcripts, and tool data. Operators must choose aliases that are suitable for this trusted-peer boundary.
62
62
  - **Stale capability assumptions:** discovery reads configuration only. It makes no provider, authentication, filesystem, or network probe and cannot prove that a configured provider/model is available. Session creation keeps the existing exact runtime checks.
63
- - **Availability:** input length is bounded; profile-specific authentication/catalog work and session creation have 5,000 ms and 10,000 ms deadlines. Preflight, abort, close cleanup, registry shutdown, and signal shutdown have 5,000 ms, 5,000 ms, 5,000 ms, 12,000 ms, and 15,000 ms server-side deadlines. Active sessions retain 20 turns and 64 KiB UTF-8 of final text per turn. The registry rejects starts after shutdown begins and disposes a late-created handle. The signal path explicitly exits the process after its cleanup deadline, but cannot prove graceful termination of a blocked provider operation.
63
+ - **Availability:** input length is bounded; profile-specific authentication/catalog work and session creation have 5,000 ms and 10,000 ms deadlines. Preflight, abort, close cleanup, registry shutdown, and process shutdown (signal or stdin EOF) have 5,000 ms, 5,000 ms, 5,000 ms, 12,000 ms, and 15,000 ms server-side deadlines. Active sessions retain 20 turns and 64 KiB UTF-8 of final text per turn. The registry rejects starts after shutdown begins and disposes a late-created handle. The process shutdown path explicitly exits the process after its cleanup deadline, but cannot prove graceful termination of a blocked provider operation.
64
64
  - **Misleading annotations:** annotations are client hints only and never grant access.
65
- - **Shutdown orphaning:** signals invoke bounded registry cleanup and transport close. Handles are disposed at most once; late promises are ignored after removal. Explicit process exit prevents local shutdown from hanging indefinitely, but SDK limitations can leave external work unconfirmed or abruptly cut off.
65
+ - **Shutdown orphaning:** `SIGINT`, `SIGTERM`, and stdin EOF invoke the same bounded registry cleanup and transport close, so a client that only closes stdin does not leave sessions or their MCP children running. Handles are disposed at most once; late promises are ignored after removal. Explicit process exit prevents local shutdown from hanging indefinitely, but SDK limitations can leave external work unconfirmed or abruptly cut off.
66
66
 
67
67
  ## Residual risks
68
68
 
@@ -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.1" },
25
+ "server": { "name": "pi-session-mcp", "version": "0.6.2" },
26
26
  "configuration": {
27
27
  "fingerprint": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
28
28
  "reloadPolicy": "restart-required"
@@ -79,7 +79,7 @@ Invalid execution-profile configuration prevents startup, so it cannot be an MCP
79
79
  | `invalid_execution_profile_config` | The execution-profile configuration violates its invariants or strict shape. |
80
80
  | `invalid_thinking_level` | A configured thinking level is outside the supported enum. |
81
81
 
82
- `pi_session_prompt` returns `{session,turn}` only after successful Pi preflight. Preflight is bounded at 5,000 ms; a missing callback, hanging prompt acceptance, or timeout returns `prompt_timeout` / `Pi prompt preflight timed out` and creates no public turn. Late settlement may only release the unpublished operation's quarantine; it cannot publish a turn. `pi_session_abort` waits at most 5,000 ms per caller for one shared SDK abort attempt and returns `abort_timeout` / `Pi abort timed out` without claiming the turn was aborted. Rejection/failure remain `prompt_rejected`/`abort_failed`. Close allows at most 5,000 ms for abort cleanup, then performs best-effort disposal and removes the public registry entry; it remains idempotent through the retained tombstone. Registry shutdown rejects new starts, allows 12,000 ms, and disposes a handle from a late-resolving start instead of admitting it. Signal shutdown allows 15,000 ms, attempts transport cleanup even after registry failure/timeout, then explicitly exits the process. These boundaries do not guarantee graceful cancellation of a provider request. `pi_turn_get` returns a `TurnView` with `turnId`, `sessionId`, state, timestamps, and `completedAt` for terminal turns. Completed views add normalized final `assistantText` and `truncated`; failed views contain only `{code:"turn_failed",message:"Pi turn failed"}`. Final assistant text is capped at 64 KiB UTF-8 bytes, each active session retains at most 20 turns, and close removes its turn data.
82
+ `pi_session_prompt` returns `{session,turn}` only after successful Pi preflight. Preflight is bounded at 5,000 ms; a missing callback, hanging prompt acceptance, or timeout returns `prompt_timeout` / `Pi prompt preflight timed out` and creates no public turn. Late settlement may only release the unpublished operation's quarantine; it cannot publish a turn. `pi_session_abort` waits at most 5,000 ms per caller for one shared SDK abort attempt and returns `abort_timeout` / `Pi abort timed out` without claiming the turn was aborted. Rejection/failure remain `prompt_rejected`/`abort_failed`. Close allows at most 5,000 ms for abort cleanup, then performs best-effort disposal and removes the public registry entry; it remains idempotent through the retained tombstone. Registry shutdown rejects new starts, allows 12,000 ms, and disposes a handle from a late-resolving start instead of admitting it. Process shutdown, started by `SIGINT`, `SIGTERM`, or stdin EOF, allows 15,000 ms, attempts transport cleanup even after registry failure/timeout, then explicitly exits the process. These boundaries do not guarantee graceful cancellation of a provider request. `pi_turn_get` returns a `TurnView` with `turnId`, `sessionId`, state, timestamps, and `completedAt` for terminal turns. Completed views add normalized final `assistantText` and `truncated`; failed views contain only `{code:"turn_failed",message:"Pi turn failed"}`. Final assistant text is capped at 64 KiB UTF-8 bytes, each active session retains at most 20 turns, and close removes its turn data.
83
83
 
84
84
  While a turn runs, `updatedAt` is the controller's last-activity stamp: it advances after each completed tool execution and each completed assistant message, then freezes at the terminal transition. It is a liveness lower bound only. A stamp that has not moved can still be a working turn (a long model response, thinking, or a first token), so it never justifies a claim that a turn is hung; it is a wall-clock ISO-8601 millisecond stamp for ordering, not a progress count, duration, or step total, and activity within one millisecond simply reuses the stamp. It is never derived from event payloads.
85
85
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-session-mcp",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Local stdio MCP server for controlled Pi coding-agent sessions",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -52,15 +52,15 @@
52
52
  "prepack": "npm run build && npm run build:cli"
53
53
  },
54
54
  "dependencies": {
55
- "@earendil-works/pi-coding-agent": "1.0.4",
56
- "@modelcontextprotocol/client": "2.2.0",
57
- "@modelcontextprotocol/server": "2.2.0",
58
- "zod": "4.5.4"
55
+ "@earendil-works/pi-coding-agent": "1.1.0",
56
+ "@modelcontextprotocol/client": "2.3.1",
57
+ "@modelcontextprotocol/server": "2.3.1",
58
+ "zod": "4.6.5"
59
59
  },
60
60
  "devDependencies": {
61
- "@modelcontextprotocol/inspector": "0.19.0",
62
- "@types/node": "22.19.19",
63
- "typescript": "5.9.3",
64
- "vitest": "4.1.11"
61
+ "@modelcontextprotocol/inspector": "2.10.1",
62
+ "@types/node": "22.20.5",
63
+ "typescript": "7.0.2",
64
+ "vitest": "5.0.3"
65
65
  }
66
66
  }