pi-session-mcp 0.7.0 → 0.8.0
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/config.js +47 -7
- package/.pi-session-mcp-cli/doctor.js +68 -2
- package/.pi-session-mcp-cli/execution-profile.js +1 -0
- package/.pi-session-mcp-cli/extension-spec.js +7 -2
- package/.pi-session-mcp-cli/setup-result.js +8 -0
- package/.pi-session-mcp-cli/skill-catalog.js +35 -0
- package/.pi-session-mcp-cli/skill-customize.js +183 -0
- package/.pi-session-mcp-cli/skill-library.js +120 -0
- package/CHANGELOG.md +110 -0
- package/README.md +15 -3
- package/dist/capabilities.d.ts +1 -0
- package/dist/capabilities.js +2 -1
- package/dist/client-adapters/mcp-verifier.js +6 -2
- package/dist/config.d.ts +4 -0
- package/dist/config.js +47 -7
- package/dist/doctor.d.ts +4 -1
- package/dist/doctor.js +68 -2
- package/dist/execution-profile.d.ts +4 -0
- package/dist/execution-profile.js +1 -0
- package/dist/extension-spec.js +7 -2
- package/dist/pi-adapter.d.ts +1 -1
- package/dist/pi-adapter.js +1 -0
- package/dist/pi-skills.d.ts +17 -0
- package/dist/pi-skills.js +64 -0
- package/dist/sdk-pi-adapter.d.ts +7 -3
- package/dist/sdk-pi-adapter.js +57 -11
- package/dist/server.js +1 -0
- package/dist/session-tools.d.ts +1 -1
- package/dist/session-tools.js +20 -4
- package/dist/setup-cli.d.ts +2 -0
- package/dist/setup-cli.js +16 -0
- package/dist/setup-main.d.ts +1 -1
- package/dist/setup-main.js +18 -3
- package/dist/setup-ownership.d.ts +6 -0
- package/dist/setup-ownership.js +29 -5
- package/dist/setup-skills.d.ts +37 -0
- package/dist/setup-skills.js +353 -0
- package/dist/setup.d.ts +7 -0
- package/dist/setup.js +49 -6
- package/dist/skill-catalog.d.ts +26 -0
- package/dist/skill-catalog.js +35 -0
- package/dist/skill-customize.d.ts +23 -0
- package/dist/skill-customize.js +183 -0
- package/dist/skill-library.d.ts +61 -0
- package/dist/skill-library.js +120 -0
- package/docs/acceptance.md +372 -3
- package/docs/adr/0006-pi-extension-allowlist.md +5 -2
- package/docs/adr/0007-profile-skill-selection.md +217 -0
- package/docs/architecture.md +9 -5
- package/docs/client-setup-design.md +133 -1
- package/docs/client-setup.md +74 -3
- package/docs/doctor-design.md +9 -1
- package/docs/installation.md +129 -9
- package/docs/pi-extensions-design.md +41 -12
- package/docs/releasing.md +15 -6
- package/docs/session-mcp.md +7 -2
- package/docs/skills.md +487 -0
- package/docs/threat-model.md +21 -4
- package/docs/tool-contracts.md +9 -5
- package/package.json +3 -1
- package/pi-session-mcp.example.json +9 -3
- package/skills/pi-session-implementation/SKILL.md +42 -0
- package/skills/pi-session-orchestration/SKILL.md +93 -0
- package/skills/pi-session-review/SKILL.md +58 -0
- package/docs/superpowers/plans/2026-10-10-macos-setup.md +0 -1725
- package/docs/superpowers/plans/2026-10-11-pi-extensions.md +0 -2450
package/docs/architecture.md
CHANGED
|
@@ -47,13 +47,13 @@ reconciled only when the registration still matches that binding. A changed
|
|
|
47
47
|
release fails closed and cannot silently inherit or replace another release's
|
|
48
48
|
registration.
|
|
49
49
|
|
|
50
|
-
`pi_capabilities_get` projects the validated workspace and execution-profile maps plus the immutable configuration metadata captured while loading the file. It returns aliases plus the configured permission/provider/model/thinking intent, sorted by alias, and `configuration: { fingerprint, reloadPolicy: "restart-required" }`. The fingerprint is SHA-256 over the exact loaded file bytes, including formatting; it is not a current-file freshness check. The projection makes no provider, authentication, filesystem, network, server-reachability, or catalog-state probe, so it cannot assert availability.
|
|
50
|
+
`pi_capabilities_get` projects the validated workspace and execution-profile maps plus the immutable configuration metadata captured while loading the file. It returns aliases plus the configured permission/provider/model/thinking intent, the configured extension specs and the selected skill aliases, sorted by alias, and `configuration: { fingerprint, reloadPolicy: "restart-required" }`. The fingerprint is SHA-256 over the exact loaded file bytes, including formatting; it is not a current-file freshness check. The projection makes no provider, authentication, filesystem, network, server-reachability, or catalog-state probe, so it cannot assert availability.
|
|
51
51
|
|
|
52
52
|
## Deterministic Pi selection
|
|
53
53
|
|
|
54
|
-
The SDK adapter owns one durable `ModelRuntime
|
|
54
|
+
The SDK adapter owns one durable `ModelRuntime` for profiles without extensions. (A profile with `extensions` creates a fresh runtime for each session; see [Pi extensions design](pi-extensions-design.md).) For the configured profile, it uses that runtime to call `getProvider(providerId)`, `getModel(providerId, modelId)`, `checkAuth()`, `getAuth(model)`, and `getAvailable(providerId)`. It rejects an absent provider or model, missing or unavailable local authentication, and a model not present in the local available-model set before constructing a session. Authentication uses only Pi's existing local mechanism; auth objects are presence-checked and never retained, serialized, or logged.
|
|
55
55
|
|
|
56
|
-
Only then does the adapter call `createAgentSession` with
|
|
56
|
+
Only then does the adapter call `createAgentSession` with that runtime and explicit `model`, `thinkingLevel`, and permission-derived `tools`. It never calls `resolveCliModel` or a fuzzy resolver, and does not depend on SDK settings or first-available fallback behavior. After construction it verifies `session.model.provider`, `session.model.id`, and effective `session.thinkingLevel`. A clamped thinking level or any selection mismatch fails closed. Any post-creation failure disposes the SDK session before a handle can enter the registry.
|
|
57
57
|
|
|
58
58
|
These postchecks establish the selected provider, model, and effective Pi session
|
|
59
59
|
thinking level. They do not inspect provider-side reasoning or enforce a
|
|
@@ -65,11 +65,15 @@ provider/engine behavior rather than inferred from the effective level.
|
|
|
65
65
|
|
|
66
66
|
The registry owns public UUIDs, lifecycle state, the turn read model, background turn promises, abort, and disposal. A per-session operation queue serializes prompt admission and close; concurrent abort callers share one bounded abort attempt for the active turn. It registers a session only after adapter creation and postconditions complete. Once shutdown begins, starts fail with `server_stopping`; a handle created by an already-running start is disposed instead of admitted. The SDK session ID is never exposed.
|
|
67
67
|
|
|
68
|
+
## Skills
|
|
69
|
+
|
|
70
|
+
`skillCatalog` and each profile's `skills` are parsed by `loadConfig`. A path value resolves against the configuration file's directory, like a workspace; a `builtin:<name>` value resolves through the skill library to the operator's override in `skills/<name>` next to the configuration file, else to the skill shipped in the package. Setup, not the server, installs the controller skill into the clients' skill directories. A profile keeps its selected skills as a frozen list of `{alias, path}` pairs; the path never leaves the server. At session start the adapter loads exactly the selected files through the Pi SDK's public `loadSkills` with no default directories and validates them completely (SDK diagnostics, duplicate Pi skill names, aliases that share one canonical file, `disable-model-invocation: true`, files over 256 KiB). The SDK's skill override returns exactly that set, also after extension hooks add resources, so a package's bundled skills, prompt templates and themes no longer reach a session. Any failure is `skill_load_failed` with a fixed message. The model sees the loaded skills in its system prompt and decides itself whether to read one; the server neither guarantees that nor snapshots skill contents. Capability discovery projects only the selected aliases. See [Pi skills](skills.md) and [ADR 0007](adr/0007-profile-skill-selection.md).
|
|
71
|
+
|
|
68
72
|
## Lifecycle and public data
|
|
69
73
|
|
|
70
74
|
`pi_session_prompt` creates a provisional turn identity, invokes Pi preflight, and only after accepted preflight publishes `{session, turn}`; rejected preflight leaves no orphan turn. Completion returns to `idle`; failure is generic. Each active session retains at most 20 turns. A turn is `running`, `completed`, `failed`, or `aborted`; its public view contains IDs, timestamps, and terminal `completedAt`. Completed text is normalized and capped at 64 KiB UTF-8 with Unicode-safe truncation. It can contain model-visible workspace data and remains potentially sensitive.
|
|
71
75
|
|
|
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.
|
|
76
|
+
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, including the selected skill aliases. 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
77
|
|
|
74
78
|
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
79
|
|
|
@@ -79,4 +83,4 @@ Public errors are stable and sanitized. They omit caller values, complete prompt
|
|
|
79
83
|
|
|
80
84
|
## Scope
|
|
81
85
|
|
|
82
|
-
The product boundary is local stdio and in-memory-only operation for one trusted local MCP peer. Allowlisted Pi extensions may persist state of their own outside this boundary
|
|
86
|
+
The product boundary is local stdio and in-memory-only operation for one trusted local MCP peer. Allowlisted Pi extensions may persist state of their own outside this boundary, and their input hooks see every client prompt as `rpc` input, never `interactive`; Pi Session MCP itself keeps no state beyond process memory. A controller keeps one immutable configuration/profile snapshot for its lifetime; file edits require a genuinely new controller process and do not hot-reload, mark stale, or mutate running sessions. Each new session performs external catalog discovery within the loaded grants, so catalog changes do not require a controller restart, but a running session's active tools remain fixed. Skill selection is part of that snapshot, but skill file contents are not: the SDK keeps file paths, so operators must not change a skill file while sessions that use it are active (see [Pi skills](skills.md)). Restarting the controller loses all sessions; reconnecting a client reloads configuration only when it actually starts a new controller process. Capability discovery reports captured metadata only and does not prove current-file freshness, server reachability, provider availability, or catalog state. It excludes HTTP, a web UI, persistence/resume, remote access, multi-user behavior, transcript export, streaming, live provider/model discovery, availability probes during capability discovery, and provider credential management. A coding execution profile is an application-level tool selection, not an OS sandbox.
|
|
@@ -10,6 +10,7 @@ The repository-local command shape is:
|
|
|
10
10
|
|
|
11
11
|
```text
|
|
12
12
|
npm run --silent setup -- [--dry-run|--apply|--verify|--rollback|--remove] [--json] --target CLIENT:SCOPE:pi-session-mcp
|
|
13
|
+
npm run --silent setup -- [--apply] [--json] --customize-skill NAME
|
|
13
14
|
```
|
|
14
15
|
|
|
15
16
|
The script executes the already-built production entry point. Building is a
|
|
@@ -61,6 +62,124 @@ of descendant termination must assert zombie-or-absence without catching their
|
|
|
61
62
|
own failed assertion; fence retention is checked separately with a live member
|
|
62
63
|
and an indeterminate scan.
|
|
63
64
|
|
|
65
|
+
## Skill installation
|
|
66
|
+
|
|
67
|
+
Besides the registration, setup installs the controller skill
|
|
68
|
+
`pi-session-orchestration` (`src/setup-skills.ts`). The skill step runs inside
|
|
69
|
+
the same ownership transaction as the registration, per target and after it.
|
|
70
|
+
`--dry-run` and `--verify` run it for every target. `--apply` runs it only for a
|
|
71
|
+
registration finding of `ok` or `unchanged`, and `--rollback` and `--remove`
|
|
72
|
+
only after the registration finding is `ok`. A skill finding therefore never
|
|
73
|
+
blocks a registration, but `divergent`, `failed` and `unsupported` skill
|
|
74
|
+
findings make the overall result `failed`, like any other finding.
|
|
75
|
+
|
|
76
|
+
**Source.** The effective skill is the operator's override if
|
|
77
|
+
`<override dir>/pi-session-orchestration/SKILL.md` exists, else the shipped skill
|
|
78
|
+
(see [Pi skills](skills.md#the-skill-library)). Setup reads the tree with a
|
|
79
|
+
bounded reader: regular files only, at most 32 files, 1 MiB and 8 levels, no
|
|
80
|
+
links or special files inside the tree, entries whose name starts with `.`
|
|
81
|
+
skipped. A missing or unusable source is `skill_source_invalid`. The fingerprint
|
|
82
|
+
is a SHA-256 over the sorted relative paths and contents.
|
|
83
|
+
|
|
84
|
+
**Slots.** A slot is the skill directory a client reads:
|
|
85
|
+
|
|
86
|
+
| Target | Slot |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| `codex:user` | `~/.agents/skills/pi-session-orchestration` |
|
|
89
|
+
| `claude-code:user`, `claude-code:local` | `~/.claude/skills/pi-session-orchestration` (one shared slot) |
|
|
90
|
+
| `claude-code:project` | `<project>/.claude/skills/pi-session-orchestration` (the directory in which setup runs) |
|
|
91
|
+
|
|
92
|
+
**Ownership records.** One record per client slot holds the target client,
|
|
93
|
+
the scope kind (`project` or `user`, so Claude Code `user` and `local` share a
|
|
94
|
+
record), the phase and a content fingerprint, plus `replaces` during an update (see below). A home slot uses the
|
|
95
|
+
alias `skill:pi-session-orchestration`. A project slot uses
|
|
96
|
+
`skill:pi-session-orchestration@<id>`, where `<id>` is the first 16 hex digits
|
|
97
|
+
of a SHA-256 over the project's real path: an opaque identity, not a path, so a
|
|
98
|
+
`--remove` in another project never touches this project's copy. The `pending`
|
|
99
|
+
phase is written before the first filesystem change and promoted to `owned`
|
|
100
|
+
after a post-install inspection. During an update, the pending record also
|
|
101
|
+
keeps the fingerprint of the copy it replaces (`replaces`), so an interrupted
|
|
102
|
+
update leaves a copy that setup still recognizes as its own: the next
|
|
103
|
+
`--apply` finishes the update and `--remove` deletes it. A later run that finds
|
|
104
|
+
a `pending` record whose slot already equals the source promotes it.
|
|
105
|
+
|
|
106
|
+
**Atomic copy.** Setup creates missing parent directories (mode `0755`), stages
|
|
107
|
+
the tree in a temporary directory in the slot's parent (files `0644`, each file
|
|
108
|
+
and directory fsynced), and re-checks that the slot is unchanged
|
|
109
|
+
(fingerprint, device and inode). It then renames the exact old tree to a backup
|
|
110
|
+
name, renames the staged directory into place, inspects the result, and deletes
|
|
111
|
+
the backup only if it is still the exact old tree it moved. An unhealthy
|
|
112
|
+
ownership fence retains staged and backup content for conservative recovery.
|
|
113
|
+
The slot is never edited in place.
|
|
114
|
+
|
|
115
|
+
**Divergence rules.** Setup never replaces or deletes, and reports
|
|
116
|
+
`skill_divergent` for:
|
|
117
|
+
|
|
118
|
+
- an installed copy whose fingerprint differs from setup's own copy (the
|
|
119
|
+
owned fingerprint, or the one a pending update replaces), even if it happens
|
|
120
|
+
to equal the new source;
|
|
121
|
+
- a copy that differs from the source without a record (a foreign skill of the
|
|
122
|
+
same name);
|
|
123
|
+
- any entry whose name starts with `.` inside the installed copy: setup never
|
|
124
|
+
writes such entries, so they are operator content that the fingerprint over
|
|
125
|
+
the visible files would not protect;
|
|
126
|
+
- a link to anything other than the effective skill, a non-directory at the
|
|
127
|
+
skill entry, or a tree that cannot be read.
|
|
128
|
+
|
|
129
|
+
A copy that equals the source stays unowned when no record exists
|
|
130
|
+
(`skill_equivalent` or `skill_already_equivalent`). A link at the skill entry
|
|
131
|
+
whose real path is exactly the effective library skill directory (your
|
|
132
|
+
override, else the shipped skill) is the operator's own equivalent setup:
|
|
133
|
+
`--dry-run` and `--apply` report `skill_linked` (unchanged), `--verify` reports
|
|
134
|
+
`skill_verified`, and removal leaves it alone (`skill_not_owned`). An unmodified owned copy
|
|
135
|
+
that differs from the source is replaced after a package update or a changed
|
|
136
|
+
override (`skill_update_planned`, `skill_updated`).
|
|
137
|
+
|
|
138
|
+
**Link rules.** The skill entry itself is never followed. In the home
|
|
139
|
+
directory, the client's skills directory (`~/.claude/skills`, `~/.agents/skills`)
|
|
140
|
+
may be the operator's own link, for example into a dotfiles checkout, and is
|
|
141
|
+
resolved to its real path. A project may be untrusted: only the project root is
|
|
142
|
+
canonicalized, and a link anywhere below it makes the slot divergent, so setup
|
|
143
|
+
never writes outside the project. If a slot cannot be resolved at all, the
|
|
144
|
+
finding is `skill_source_invalid` for `--dry-run`, `skill_install_failed` for
|
|
145
|
+
`--apply`, `skill_missing` for `--verify` and `skill_divergent` for removal.
|
|
146
|
+
|
|
147
|
+
**Shared slot.** For `--rollback` and `--remove`, the Claude Code `user` and
|
|
148
|
+
`local` registrations share one slot. While the other registration is still
|
|
149
|
+
`owned`, the skill stays and the finding is `skill_kept_shared`. The last
|
|
150
|
+
removal deletes it (`skill_removed`; `skill_absent` if it is already gone;
|
|
151
|
+
`skill_not_owned` if setup never owned it). A modified copy is left in place
|
|
152
|
+
(`skill_divergent`) and its record stays, so a later run can finish after you
|
|
153
|
+
removed the copy.
|
|
154
|
+
|
|
155
|
+
**Remove retry.** Registration removal can finish before skill cleanup, for
|
|
156
|
+
example after an interruption or a `skill_divergent`. When the registration
|
|
157
|
+
record is gone but setup still owns the skill of that target, `--remove` and
|
|
158
|
+
`--rollback` run once more for that target. They first prove that the
|
|
159
|
+
registration is absent and then report the registration as removed and clean up
|
|
160
|
+
the skill. They never run for a target whose skill setup does not own, nor for
|
|
161
|
+
a Claude Code `user` or `local` target while the other one of the two is still
|
|
162
|
+
registered, and an unowned live registration stays untouched
|
|
163
|
+
(`ownership_unavailable`).
|
|
164
|
+
|
|
165
|
+
Skill reports carry only client, scope, the alias `pi-session-orchestration`,
|
|
166
|
+
status and a stable code. No skill content, fingerprint or path leaves setup.
|
|
167
|
+
|
|
168
|
+
## Skill customization
|
|
169
|
+
|
|
170
|
+
`setup --customize-skill <name>` (and `--apply --customize-skill <name>`,
|
|
171
|
+
`src/skill-customize.ts`) does not touch clients and takes no ownership lock. It
|
|
172
|
+
copies a shipped skill into the override directory `skills/` next to the
|
|
173
|
+
configuration file and records the shipped fingerprint under the skill name in
|
|
174
|
+
`<override dir>/.pi-session-mcp-bases.json` (`{"schemaVersion":1,"bases":{...}}`,
|
|
175
|
+
strictly validated, at most 64 KiB, replaced atomically). The copy is staged in
|
|
176
|
+
a temporary directory and renamed into place; an existing override is never
|
|
177
|
+
overwritten. A changed shipped skill is only reported (`skill_override_outdated`);
|
|
178
|
+
`--apply` then moves the recorded base and nothing else. It cannot be combined
|
|
179
|
+
with `--target`, `--verify`, `--rollback` or `--remove`. The finding target is
|
|
180
|
+
`{ client: "skills", scope: "override", alias: <name> }`; the alias is the
|
|
181
|
+
skill name only if it is valid, else `invalid`.
|
|
182
|
+
|
|
64
183
|
## Verification boundary
|
|
65
184
|
|
|
66
185
|
Production verification requires the offline Doctor, exact public client-CLI registration inspection, and a directly launched bounded MCP handshake. The verifier calls `pi_capabilities_get` with `{}` only; session start/prompt/turn and provider/model operations are forbidden. Its child process is terminated and awaited before success is reported.
|
|
@@ -84,7 +203,20 @@ Stable finding codes are grouped by responsibility:
|
|
|
84
203
|
- verification: `registration_not_equivalent`, `mcp_verified`,
|
|
85
204
|
`mcp_unsupported`, `mcp_timeout`, `mcp_failed`;
|
|
86
205
|
- rollback/removal: `rolled_back`, `removed`, `ownership_diverged`,
|
|
87
|
-
`cleanup_failed
|
|
206
|
+
`cleanup_failed`;
|
|
207
|
+
- controller skill, dry-run: `skill_absent`, `skill_equivalent`, `skill_linked`,
|
|
208
|
+
`skill_update_planned`, `skill_divergent`, `skill_source_invalid`;
|
|
209
|
+
- controller skill, apply: `skill_installed`, `skill_already_equivalent`, `skill_linked`,
|
|
210
|
+
`skill_updated`, `skill_divergent`, `skill_source_invalid`,
|
|
211
|
+
`skill_install_failed`;
|
|
212
|
+
- controller skill, verify: `skill_verified`, `skill_missing`,
|
|
213
|
+
`skill_not_equivalent`;
|
|
214
|
+
- controller skill, rollback/removal: `skill_removed`, `skill_kept_shared`,
|
|
215
|
+
`skill_not_owned`, `skill_absent`, `skill_divergent`;
|
|
216
|
+
- skill customization: `skill_customize_planned`, `skill_customized`,
|
|
217
|
+
`skill_override_current`, `skill_override_outdated`, `skill_base_updated`,
|
|
218
|
+
`skill_not_shipped`, `skill_bases_corrupt`, `skill_override_invalid`,
|
|
219
|
+
`skill_customize_failed`.
|
|
88
220
|
|
|
89
221
|
The public statuses are `planned`, `ok`, `unchanged`, `absent`, `divergent`,
|
|
90
222
|
`unsupported`, and `failed`. Reports never contain command arguments, command
|
package/docs/client-setup.md
CHANGED
|
@@ -90,6 +90,77 @@ bounded direct MCP `initialize`, `tools/list`, and
|
|
|
90
90
|
`pi_capabilities_get({})` check. It never starts a session or invokes
|
|
91
91
|
a provider.
|
|
92
92
|
|
|
93
|
+
### Controller skill
|
|
94
|
+
|
|
95
|
+
Besides the registration, `--apply` installs the controller skill
|
|
96
|
+
`pi-session-orchestration` for each target, as a real copy of the effective
|
|
97
|
+
skill: your override in the skill library if you have one, else the skill
|
|
98
|
+
shipped in the package ([Pi skills](skills.md)). Clients discover it without
|
|
99
|
+
further steps.
|
|
100
|
+
|
|
101
|
+
| Target | Where the skill goes |
|
|
102
|
+
| --- | --- |
|
|
103
|
+
| `codex:user:pi-session-mcp` | `~/.agents/skills/pi-session-orchestration` |
|
|
104
|
+
| `claude-code:user:pi-session-mcp`, `claude-code:local:pi-session-mcp` | `~/.claude/skills/pi-session-orchestration` (one shared directory) |
|
|
105
|
+
| `claude-code:project:pi-session-mcp` | `<project>/.claude/skills/pi-session-orchestration`, where `<project>` is the directory in which setup runs |
|
|
106
|
+
|
|
107
|
+
Every result therefore has a second finding per target, with the same client
|
|
108
|
+
and scope and the alias `pi-session-orchestration`:
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
apply: ok
|
|
112
|
+
claude-code/user/pi-session-mcp: ok (applied)
|
|
113
|
+
claude-code/user/pi-session-orchestration: ok (skill_installed)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Skill findings per operation:
|
|
117
|
+
|
|
118
|
+
- `--dry-run`: `skill_absent` (absent), `skill_equivalent` (unchanged),
|
|
119
|
+
`skill_linked` (unchanged; a link to exactly the effective skill),
|
|
120
|
+
`skill_update_planned` (planned), `skill_divergent` (divergent),
|
|
121
|
+
`skill_source_invalid` (failed).
|
|
122
|
+
- `--apply`: `skill_installed` (ok), `skill_already_equivalent` (unchanged),
|
|
123
|
+
`skill_linked` (unchanged),
|
|
124
|
+
`skill_updated` (ok; setup replaced its own unmodified copy after a package
|
|
125
|
+
update or a changed override), `skill_divergent`, `skill_source_invalid`,
|
|
126
|
+
`skill_install_failed` (failed).
|
|
127
|
+
- `--verify`: `skill_verified` (ok), `skill_missing` and
|
|
128
|
+
`skill_not_equivalent` (failed).
|
|
129
|
+
- `--rollback` and `--remove`: `skill_removed` (ok), `skill_kept_shared`
|
|
130
|
+
(unchanged; the other Claude Code `user` or `local` registration still uses
|
|
131
|
+
the shared directory), `skill_not_owned` (unchanged), `skill_absent` (ok) and
|
|
132
|
+
`skill_divergent` (a modified copy stays in place).
|
|
133
|
+
|
|
134
|
+
Setup never replaces or deletes a modified installed copy, a skill of the same
|
|
135
|
+
name that it did not install, or a link or non-directory at the skill entry; it
|
|
136
|
+
reports `skill_divergent`. That does not block the registration, but it makes
|
|
137
|
+
the overall status `failed` (exit 1). Never edit the installed copy. To
|
|
138
|
+
customize the skill, run `--apply --customize-skill pi-session-orchestration`,
|
|
139
|
+
edit the override, and run `--apply` for the target again. Design and trust
|
|
140
|
+
rules: [setup lifecycle design](client-setup-design.md#skill-installation).
|
|
141
|
+
|
|
142
|
+
Setup installs only `pi-session-orchestration` into clients. Worker skills are
|
|
143
|
+
for Pi profiles and are selected through `builtin:` entries in `skillCatalog`.
|
|
144
|
+
|
|
145
|
+
### Customize a shipped skill
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npm run --silent setup -- --customize-skill pi-session-review
|
|
149
|
+
npm run --silent setup -- --apply --customize-skill pi-session-review
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
This works without `--target` and needs `PI_SESSION_MCP_CONFIG`. It copies the
|
|
153
|
+
shipped skill into the `skills/` directory next to the configuration file and
|
|
154
|
+
records the fingerprint of the shipped skill in
|
|
155
|
+
`.pi-session-mcp-bases.json` there. The finding target is
|
|
156
|
+
`skills/override/<name>`; the codes are `skill_customize_planned` (planned),
|
|
157
|
+
`skill_customized` (ok), `skill_override_current` (unchanged),
|
|
158
|
+
`skill_override_outdated` (planned), `skill_base_updated` (ok),
|
|
159
|
+
`skill_not_shipped`, `skill_bases_corrupt`, `skill_override_invalid` and
|
|
160
|
+
`skill_customize_failed` (failed). An existing override is never overwritten.
|
|
161
|
+
After `skill_override_outdated`, `--apply` moves only the recorded base, which
|
|
162
|
+
acknowledges a change you reviewed. Details: [Pi skills](skills.md#customize-and-add-skills).
|
|
163
|
+
|
|
93
164
|
## Local configuration
|
|
94
165
|
|
|
95
166
|
Create an unversioned JSON configuration file such as `pi-session-mcp.json`:
|
|
@@ -118,7 +189,7 @@ Create an unversioned JSON configuration file such as `pi-session-mcp.json`:
|
|
|
118
189
|
}
|
|
119
190
|
```
|
|
120
191
|
|
|
121
|
-
Configuration is strict. A profile has exactly `default`, `permissionProfile`, `provider`, `model`, and `thinkingLevel`, plus the optional `mcpServers` and `
|
|
192
|
+
Configuration is strict. A profile has exactly `default`, `permissionProfile`, `provider`, `model`, and `thinkingLevel`, plus the optional `mcpServers`, `extensions` and `skills` described in [Installation](installation.md) and [Pi skills](skills.md); aliases follow the configured alias naming rules. At least one profile and exactly one default are required, and that default must be `read-only`. `thinkingLevel` is one of `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`. Workspace paths resolve relative to the configuration file. Clients can select only configured aliases, never an arbitrary working directory.
|
|
122
193
|
|
|
123
194
|
Use placeholders until a locally available provider/model pair is known. Do not put keys, tokens, credential objects, headers, base URLs, or authentication paths in this file.
|
|
124
195
|
|
|
@@ -190,7 +261,7 @@ Claude Code enforces each tool's declared JSON Schema (`additionalProperties: fa
|
|
|
190
261
|
## Expected flow and lifecycle deadlines
|
|
191
262
|
|
|
192
263
|
1. Call `pi_capabilities_get` with `{}` and select explicit workspace and read-only execution-profile aliases from the returned config-derived lists.
|
|
193
|
-
2. Call `pi_session_start` with those aliases. The server resolves the configured provider/model through its
|
|
264
|
+
2. Call `pi_session_start` with those aliases. The server resolves the configured provider/model through its shared `ModelRuntime` (a profile with extensions gets a fresh runtime for each session), loads and validates the profile's selected skills, checks existing local Pi authentication and availability, creates with explicit model/thinking/tools, and verifies the effective SDK result.
|
|
194
265
|
3. Call `pi_session_prompt` with the returned `sessionId` and a read-only prompt. It returns after accepted preflight with a `turnId` in `running` state.
|
|
195
266
|
4. Poll `pi_turn_get` with that `sessionId` and `turnId` until `completed`, `failed`, or `aborted`, with a deadline no longer than three minutes. There is no `pi_turn_wait` tool.
|
|
196
267
|
5. Call `pi_session_close` when the session is no longer needed.
|
|
@@ -246,7 +317,7 @@ Poll `pi_turn_get` for at most three minutes. If it does not become terminal, re
|
|
|
246
317
|
|
|
247
318
|
### A prompt fails immediately after a provider config or credential change
|
|
248
319
|
|
|
249
|
-
`pi_session_prompt` reads the configured provider/model through one `ModelRuntime` that is created once and cached for the lifetime of the Pi Session MCP server process; the underlying SDK reads `~/.pi/agent/models.json` only at that creation. Editing that file (for example adding or fixing a provider API key) does not take effect in an already-running server process, and a resulting turn typically fails (`turn_failed`) within milliseconds rather than after a real provider round trip. Restart or reconnect the MCP server (which restarts the process) after any provider config or credential change, then retry.
|
|
320
|
+
For profiles without extensions, `pi_session_prompt` reads the configured provider/model through one `ModelRuntime` that is created once and cached for the lifetime of the Pi Session MCP server process (a profile with extensions creates a fresh runtime when each session starts); the underlying SDK reads `~/.pi/agent/models.json` only at that creation. Editing that file (for example adding or fixing a provider API key) does not take effect in an already-running server process, and a resulting turn typically fails (`turn_failed`) within milliseconds rather than after a real provider round trip. Restart or reconnect the MCP server (which restarts the process) after any provider config or credential change, then retry.
|
|
250
321
|
|
|
251
322
|
### Session cleanup
|
|
252
323
|
|
package/docs/doctor-design.md
CHANGED
|
@@ -10,7 +10,7 @@ directory: an npm executable can run from any directory.
|
|
|
10
10
|
sanitized semver `packageVersion` when metadata is available, ordered `checks`,
|
|
11
11
|
and `exitCode`). Human and JSON output are projections of that same model.
|
|
12
12
|
Subjects are only fixed component names, validated workspace aliases, or
|
|
13
|
-
validated `<profile>:<package>` pairs; paths, configuration values, errors,
|
|
13
|
+
validated `<profile>:<package>`, `<profile>:<skill-alias>` or `skill:<name>` pairs; paths, configuration values, errors,
|
|
14
14
|
credentials, and provider data are never output.
|
|
15
15
|
|
|
16
16
|
Each check is `{ id, severity, subject, remediation? }`. Severity is `ok`,
|
|
@@ -34,9 +34,17 @@ and owners are:
|
|
|
34
34
|
| `workspace_not_writable` | A workspace is not writable while a coding profile can target it | validated workspace alias |
|
|
35
35
|
| `extension_missing` | Pi has no user install of a package that a profile's `extensions` names | `<profile>:<package>` |
|
|
36
36
|
| `extension_version_mismatch` | The installed manifest's version differs from the pinned version, or the manifest or its `pi.extensions` entries are invalid | `<profile>:<package>` |
|
|
37
|
+
| `skill_missing` | The `SKILL.md` file that a profile's selected skill alias names does not exist; a `builtin:<name>` value that matches no override and no shipped skill resolves to the shipped location and is reported here | `<profile>:<skill-alias>` |
|
|
38
|
+
| `skill_unreadable` | A selected skill path is not a regular file, is larger than 256 KiB, or cannot be read | `<profile>:<skill-alias>` |
|
|
39
|
+
| `skill_duplicate` | Two selected skill aliases of one profile resolve to the same canonical file | `<profile>:<skill-alias>` |
|
|
40
|
+
| `skill_override_outdated` | Warning. The current fingerprint of a shipped skill differs from the base recorded in the skill bases file next to the configuration file, or the bases file is corrupt | `skill:<name>`, or `skill:bases` for a corrupt file |
|
|
37
41
|
|
|
38
42
|
Doctor reads extension manifests from Pi's user install location only; it never installs packages and never imports extension code.
|
|
39
43
|
|
|
44
|
+
The skill checks run after the extension checks. They look only at file availability: Doctor never reads a skill's frontmatter, never parses or executes it, and the subject carries the catalog alias, never a path. Frontmatter, skill-name rules, name collisions and explicit-only flags (`disable-model-invocation`) are checked only at session start by the Pi SDK contract, so a clean Doctor run does not promise that a skill loads. Unknown or duplicate aliases and two selected aliases with one path are configuration errors and surface as `config_invalid`. See [Pi skills](skills.md).
|
|
45
|
+
|
|
46
|
+
`skill_override_outdated` concerns the operator's skill overrides, not a profile. It is `ok` for a recorded base that still matches the shipped skill, and a warning (exit status 1, never blocking `setup`) when the shipped skill changed after the operator ran `pi-session-mcp-setup --customize-skill <name>`; its remediation names `pi-session-mcp-setup --apply --customize-skill <name>` to acknowledge a reviewed change. Only skills with a recorded base are compared, and a recorded name that is no longer shipped is skipped. A corrupt bases file yields a warning with the subject `skill:bases`. Doctor reads the bases file and the shipped skill files only; nothing is executed and the subject is a validated skill name, never a path. The check sorts after `skill_duplicate`.
|
|
47
|
+
|
|
40
48
|
The Doctor reuses `loadConfig`; it does not duplicate alias, profile, thinking
|
|
41
49
|
level, or read-only-default rules. Workspace values are used only for local
|
|
42
50
|
filesystem checks and are never copied into the result.
|
package/docs/installation.md
CHANGED
|
@@ -14,12 +14,14 @@ Pi Session MCP is a local, stdio-only MCP server. An MCP client starts
|
|
|
14
14
|
Nothing listens on a network port, no daemon runs between client sessions, and
|
|
15
15
|
session state exists only in the memory of that child process.
|
|
16
16
|
|
|
17
|
-
An installation consists of
|
|
17
|
+
An installation consists of these locations:
|
|
18
18
|
|
|
19
19
|
| What | Location | Notes |
|
|
20
20
|
| --- | --- | --- |
|
|
21
21
|
| Package | the npm global prefix, or a dedicated directory per release such as `~/.local/share/pi-session-mcp/releases/<tag>` | The built server, `setup` and Doctor. |
|
|
22
22
|
| Configuration | a file outside the package, for example `~/.config/pi-session-mcp/pi-session-mcp.json` | Operator-owned, mode `0600`, never committed. |
|
|
23
|
+
| Skill overrides (optional) | the `skills/` directory next to the configuration file, for example `~/.config/pi-session-mcp/skills/` | Your own or customized skills, plus `.pi-session-mcp-bases.json`. Created by you or by `setup --customize-skill`. See [Pi skills](#pi-skills). |
|
|
24
|
+
| Controller skill | `~/.agents/skills/pi-session-orchestration` (Codex), `~/.claude/skills/pi-session-orchestration` or `<project>/.claude/skills/pi-session-orchestration` (Claude Code) | Written by `setup --apply`; see [Register a client](#4-register-a-client). |
|
|
23
25
|
| Setup ownership state | `~/.local/state/pi-session-mcp/ownership.json` | Written by `setup` only. Path-free and secret-free. |
|
|
24
26
|
|
|
25
27
|
Never register a development checkout. A registered client launches
|
|
@@ -155,7 +157,14 @@ Rules:
|
|
|
155
157
|
- A profile may load Pi extensions that Pi has installed, through
|
|
156
158
|
`extensions`: a list of at most 8 entries of the form
|
|
157
159
|
`npm:<name>@<exact version>`, each package once. Ranges, tags, `git:`
|
|
158
|
-
sources and
|
|
160
|
+
sources, paths and build metadata (`+build`) are rejected. See [Pi extensions](#pi-extensions).
|
|
161
|
+
- A profile may select Pi skills through `skills`: a list of at most 16 aliases
|
|
162
|
+
from the top-level `skillCatalog`, which maps an alias to `builtin:<name>`
|
|
163
|
+
(a skill of the package or of your override directory) or to the path of one
|
|
164
|
+
`SKILL.md` file (at most 64 entries). A relative path resolves against the
|
|
165
|
+
configuration file's directory; `~` is not expanded. The example already uses
|
|
166
|
+
`builtin:` for the two worker skills, so you need not change its skill
|
|
167
|
+
entries. See [Pi skills](#pi-skills).
|
|
159
168
|
- Never put keys, tokens, credential objects, headers, base URLs or
|
|
160
169
|
authentication paths into this file.
|
|
161
170
|
|
|
@@ -217,6 +226,10 @@ pi-session-mcp-setup --apply --target claude-code:user:pi-session-mcp
|
|
|
217
226
|
pi-session-mcp-setup --verify --target claude-code:user:pi-session-mcp
|
|
218
227
|
```
|
|
219
228
|
|
|
229
|
+
`--apply` also installs the controller skill `pi-session-orchestration` for the
|
|
230
|
+
target, after the registration, so the client knows how to drive Pi worker
|
|
231
|
+
sessions. See [Controller skill](#controller-skill).
|
|
232
|
+
|
|
220
233
|
`setup` changes a Codex registration only through `codex mcp add` and
|
|
221
234
|
`codex mcp remove`, and Codex rewrites `config.toml` on each of them. Codex CLI
|
|
222
235
|
`0.162.0` groups all `[mcp_servers.*]` tables together and drops a comment
|
|
@@ -224,12 +237,14 @@ directly above such a table; settings are preserved. If your `config.toml`
|
|
|
224
237
|
contains comments worth keeping, copy it before `--apply`, `--rollback` or
|
|
225
238
|
`--remove` on `codex:user:pi-session-mcp`.
|
|
226
239
|
|
|
227
|
-
Each report has one line for the operation with its overall status, and
|
|
228
|
-
|
|
240
|
+
Each report has one line for the operation with its overall status, and per
|
|
241
|
+
target two lines with a finding in the form `status (code)`: the registration
|
|
242
|
+
and the controller skill, whose alias is `pi-session-orchestration`:
|
|
229
243
|
|
|
230
244
|
```text
|
|
231
245
|
dry-run: planned
|
|
232
246
|
claude-code/user/pi-session-mcp: absent (absent)
|
|
247
|
+
claude-code/user/pi-session-orchestration: absent (skill_absent)
|
|
233
248
|
```
|
|
234
249
|
|
|
235
250
|
Expected results:
|
|
@@ -237,8 +252,11 @@ Expected results:
|
|
|
237
252
|
| Operation | Overall | Finding | Meaning |
|
|
238
253
|
| --- | --- | --- | --- |
|
|
239
254
|
| `--dry-run` | `planned` | `absent (absent)` | No registration exists. Apply will add one. |
|
|
255
|
+
| `--dry-run` | `planned` | `absent (skill_absent)` | The controller skill is not installed. Apply will install it. |
|
|
240
256
|
| `--apply` | `ok` | `ok (applied)` | The registration was added and is now owned by `setup`. |
|
|
257
|
+
| `--apply` | `ok` | `ok (skill_installed)` | The controller skill was copied into the client's skill directory and is owned by `setup`. |
|
|
241
258
|
| `--verify` | `ok` | `ok (mcp_verified)` | Doctor passed, the registration equals the intended one, and a direct MCP handshake listed the eight tools and answered `pi_capabilities_get`. |
|
|
259
|
+
| `--verify` | `ok` | `ok (skill_verified)` | The installed skill equals the effective skill. |
|
|
242
260
|
|
|
243
261
|
Verify never starts a session and never contacts a provider. Add `--json` to
|
|
244
262
|
any operation for the sanitized JSON report. Exit status `0` is success, `1` an
|
|
@@ -255,6 +273,39 @@ If a registration already exists, `setup` never replaces it:
|
|
|
255
273
|
Start a new client session after registering. The client launches the server on
|
|
256
274
|
demand; there is nothing to start by hand.
|
|
257
275
|
|
|
276
|
+
### Controller skill
|
|
277
|
+
|
|
278
|
+
`--apply` copies the effective `pi-session-orchestration` skill (your override
|
|
279
|
+
if you have one, else the shipped skill) as a real copy to the client's skill
|
|
280
|
+
directory, where the client discovers it without further steps:
|
|
281
|
+
|
|
282
|
+
| Target | Skill directory |
|
|
283
|
+
| --- | --- |
|
|
284
|
+
| `codex:user:pi-session-mcp` | `~/.agents/skills/pi-session-orchestration` |
|
|
285
|
+
| `claude-code:user:pi-session-mcp`, `claude-code:local:pi-session-mcp` | `~/.claude/skills/pi-session-orchestration` (one shared directory) |
|
|
286
|
+
| `claude-code:project:pi-session-mcp` | `<project>/.claude/skills/pi-session-orchestration`, where `<project>` is the directory in which you run `setup` |
|
|
287
|
+
|
|
288
|
+
- `setup` never replaces or deletes a modified installed copy, hidden files
|
|
289
|
+
inside it (macOS Finder's `.DS_Store` counts too), a skill of the same name
|
|
290
|
+
that it did not install, or a link or non-directory entry. It reports
|
|
291
|
+
`skill_divergent`; the registration is still made, but the overall status is
|
|
292
|
+
`failed`. A link to exactly the effective skill is accepted as your own
|
|
293
|
+
(`skill_linked`). Inside a project, any link below the project root counts as
|
|
294
|
+
divergent.
|
|
295
|
+
- A package update or a changed override replaces setup's own unmodified copy on
|
|
296
|
+
the next `--apply` (`skill_updated`). `--remove` and `--rollback` delete it
|
|
297
|
+
again (`skill_removed`), except while the other Claude Code registration of
|
|
298
|
+
the shared directory still uses it (`skill_kept_shared`).
|
|
299
|
+
- To change the skill, do not edit the installed copy. Run
|
|
300
|
+
`pi-session-mcp-setup --apply --customize-skill pi-session-orchestration`,
|
|
301
|
+
edit the override it creates, and run `--apply` for the target again.
|
|
302
|
+
- Setup installs only this one skill into clients. Worker skills are for Pi
|
|
303
|
+
profiles; additional controller skills of your own belong in the clients'
|
|
304
|
+
native skill directories.
|
|
305
|
+
|
|
306
|
+
The codes and the rules are in [Pi skills](skills.md#install-the-orchestration-skill-into-codex-and-claude-code)
|
|
307
|
+
and the [setup lifecycle design](client-setup-design.md#skill-installation).
|
|
308
|
+
|
|
258
309
|
### Register without setup
|
|
259
310
|
|
|
260
311
|
`setup` runs on Linux and macOS. On every other platform, Windows included, it
|
|
@@ -277,7 +328,11 @@ acceptance level covers this path.
|
|
|
277
328
|
directory: in an npm installation `echo "$(npm root -g)/pi-session-mcp"`
|
|
278
329
|
prints that directory, in a release checkout it is the checkout. Write the
|
|
279
330
|
resulting absolute path into the command; a substitution inside the single
|
|
280
|
-
quotes of the Codex example would not be expanded.
|
|
331
|
+
quotes of the Codex example would not be expanded. A manual registration
|
|
332
|
+
installs no skill. To use the controller skill, copy (do not link) the
|
|
333
|
+
directory `skills/pi-session-orchestration` of the package to the client's
|
|
334
|
+
skill directory listed under [Controller skill](#controller-skill), and
|
|
335
|
+
repeat the copy after an upgrade.
|
|
281
336
|
3. Check the registration. These checks are not a replacement for
|
|
282
337
|
`setup --verify`: it also performs a bounded direct MCP handshake, and
|
|
283
338
|
outside `setup` nothing does that yet. The last check below depends on the
|
|
@@ -374,13 +429,16 @@ pin the installed version in the profile:
|
|
|
374
429
|
and system-prompt changes. In `read-only` profiles the model still gets only
|
|
375
430
|
`read`, `grep`, `find` and `ls`; in `coding` profiles every extension tool
|
|
376
431
|
may be active. Extension commands never run from client prompts, but
|
|
377
|
-
extension input hooks can still see, rewrite or consume a client prompt
|
|
432
|
+
extension input hooks can still see, rewrite or consume a client prompt;
|
|
433
|
+
they receive it with `source: "rpc"`, never `interactive`.
|
|
378
434
|
- **Fail-closed start.** A session start fails with `extension_load_failed` if
|
|
379
435
|
an extension reports a hook error while binding. It fails the same way if an
|
|
380
436
|
extension registers an MCP server while loading or starting, because Pi's
|
|
381
437
|
built-in MCP extension is not loaded. An extension tool whose name collides
|
|
382
|
-
with another tool, or whose name is not
|
|
383
|
-
|
|
438
|
+
with another tool, or whose name is not 1 to 64 letters, digits, `_` or `-`
|
|
439
|
+
(not starting with `-`), or whose name Pi treats as an MCP tool (starting
|
|
440
|
+
with `mcp__`, or `list_mcp_resources`, `list_mcp_resource_templates`,
|
|
441
|
+
`read_mcp_resource`), fails with `extension_tool_conflict`.
|
|
384
442
|
- **Cursor runtime.** `pi-cursor-sdk` runs Cursor's local agent runtime. That
|
|
385
443
|
runtime starts its own processes (for example git and the MCP servers
|
|
386
444
|
configured for Cursor) and may act through Cursor's own tooling, so a
|
|
@@ -391,6 +449,57 @@ pin the installed version in the profile:
|
|
|
391
449
|
reports a placeholder key. Session start succeeds and the first prompt fails
|
|
392
450
|
with `turn_failed`. Store the key with Pi first.
|
|
393
451
|
|
|
452
|
+
## Pi skills
|
|
453
|
+
|
|
454
|
+
An execution profile can give its sessions Pi skills. The package ships two
|
|
455
|
+
worker skills, `pi-session-implementation` and `pi-session-review`, and the
|
|
456
|
+
controller skill `pi-session-orchestration`, in its `skills/` directory. The
|
|
457
|
+
catalog maps an alias to a skill; the profile selects aliases. MCP callers never
|
|
458
|
+
choose skills.
|
|
459
|
+
|
|
460
|
+
```json
|
|
461
|
+
"skillCatalog": {
|
|
462
|
+
"pi-session-review": "builtin:pi-session-review"
|
|
463
|
+
},
|
|
464
|
+
"executionProfiles": {
|
|
465
|
+
"safe-readonly": {
|
|
466
|
+
"default": true,
|
|
467
|
+
"permissionProfile": "read-only",
|
|
468
|
+
"provider": "your-configured-provider",
|
|
469
|
+
"model": "your-configured-model",
|
|
470
|
+
"thinkingLevel": "medium",
|
|
471
|
+
"skills": ["pi-session-review"]
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
- `builtin:<name>` resolves to your override
|
|
477
|
+
`<directory of the configuration file>/skills/<name>/SKILL.md` if it exists,
|
|
478
|
+
else to the shipped skill. The shipped example configuration already uses
|
|
479
|
+
`builtin:pi-session-implementation` and `builtin:pi-session-review`, so the
|
|
480
|
+
copied example needs no path edits for skills. Adding or removing an override
|
|
481
|
+
needs a server restart, like any configuration change.
|
|
482
|
+
- To adjust a shipped skill, run `pi-session-mcp-setup --customize-skill <name>`
|
|
483
|
+
(a dry-run) and then `pi-session-mcp-setup --apply --customize-skill <name>`
|
|
484
|
+
with `PI_SESSION_MCP_CONFIG` set. It copies the shipped skill into the
|
|
485
|
+
override directory as a starting point and never overwrites an existing
|
|
486
|
+
override. Edit the copy, then restart the server. To add a skill of your own,
|
|
487
|
+
create `<override dir>/<new-name>/SKILL.md` and reference it as
|
|
488
|
+
`builtin:<new-name>`; no command is needed. After a package update, Doctor
|
|
489
|
+
warns with `skill_override_outdated` when a shipped skill changed since you
|
|
490
|
+
copied it.
|
|
491
|
+
- A `builtin:` name with no override and no shipped skill makes Doctor report
|
|
492
|
+
`skill_missing` and the session start fail with `skill_load_failed`.
|
|
493
|
+
- An extension allowlist alone makes none of a package's skills available. If a
|
|
494
|
+
profile relied on them, add a catalog entry with the absolute path of the
|
|
495
|
+
package's `SKILL.md` and select it; see the migration section of [Pi
|
|
496
|
+
skills](skills.md).
|
|
497
|
+
- A skill file is read by the SDK at session start and later by the model.
|
|
498
|
+
Do not change skill files while sessions that use them are active; close
|
|
499
|
+
those sessions first.
|
|
500
|
+
|
|
501
|
+
The complete rules, errors, Doctor checks and limits are in [Pi skills](skills.md).
|
|
502
|
+
|
|
394
503
|
## Upgrade
|
|
395
504
|
|
|
396
505
|
`setup` binds each owned registration to the package manifests and to every
|
|
@@ -398,6 +507,12 @@ built runtime file, so the old version must remove its registration before the
|
|
|
398
507
|
new one applies. Read the [changelog](../CHANGELOG.md) before upgrading; it
|
|
399
508
|
records changes that affect operators, such as renamed provider keys.
|
|
400
509
|
|
|
510
|
+
Removing the registration also removes the controller skill that setup
|
|
511
|
+
installed, unless you modified it, and `--apply` for the new version installs
|
|
512
|
+
the new text. A package update that changes a shipped skill does not touch an
|
|
513
|
+
override of yours; Doctor warns with `skill_override_outdated` so that you can
|
|
514
|
+
review the change.
|
|
515
|
+
|
|
401
516
|
### npm installation
|
|
402
517
|
|
|
403
518
|
An npm upgrade replaces the package in place. Close the client sessions that
|
|
@@ -462,7 +577,12 @@ npm uninstall -g pi-session-mcp
|
|
|
462
577
|
same owned removal and reports `rolled_back`; use it to undo an apply. After
|
|
463
578
|
every target reports `removed`, uninstall the package or delete the release
|
|
464
579
|
directory, and delete the configuration file and
|
|
465
|
-
`~/.local/state/pi-session-mcp/`.
|
|
580
|
+
`~/.local/state/pi-session-mcp/`. The same call removes the controller skill
|
|
581
|
+
that `setup` installed (`skill_removed`). It keeps a copy that you modified
|
|
582
|
+
(`skill_divergent`) and the shared Claude Code directory while the other
|
|
583
|
+
Claude Code registration is still owned (`skill_kept_shared`). Your override
|
|
584
|
+
directory `skills/` next to the configuration file is yours: delete it with the
|
|
585
|
+
configuration file if you no longer need it.
|
|
466
586
|
|
|
467
587
|
## When something fails
|
|
468
588
|
|