pi-session-mcp 0.7.1 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.pi-session-mcp-cli/config.js +47 -7
- package/.pi-session-mcp-cli/doctor.js +75 -2
- package/.pi-session-mcp-cli/execution-profile.js +1 -0
- package/.pi-session-mcp-cli/override-lock.js +125 -0
- package/.pi-session-mcp-cli/setup-platform.js +195 -0
- 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 +268 -0
- package/.pi-session-mcp-cli/skill-library.js +188 -0
- package/CHANGELOG.md +176 -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 +7 -1
- package/dist/doctor.js +75 -2
- package/dist/execution-profile.d.ts +4 -0
- package/dist/execution-profile.js +1 -0
- package/dist/override-lock.d.ts +34 -0
- package/dist/override-lock.js +125 -0
- package/dist/pi-adapter.d.ts +7 -5
- 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 +82 -16
- package/dist/server.js +1 -0
- package/dist/session-registry.d.ts +8 -6
- package/dist/session-registry.js +3 -2
- 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 +9 -0
- package/dist/setup-ownership.js +32 -5
- package/dist/setup-skills.d.ts +76 -0
- package/dist/setup-skills.js +586 -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 +41 -0
- package/dist/skill-customize.js +268 -0
- package/dist/skill-library.d.ts +106 -0
- package/dist/skill-library.js +188 -0
- package/docs/acceptance.md +593 -1
- package/docs/adr/0006-pi-extension-allowlist.md +3 -0
- package/docs/adr/0007-profile-skill-selection.md +228 -0
- package/docs/architecture.md +10 -6
- package/docs/client-setup-design.md +219 -1
- package/docs/client-setup.md +86 -3
- package/docs/doctor-design.md +9 -1
- package/docs/installation.md +128 -5
- package/docs/pi-extensions-design.md +28 -4
- package/docs/releasing.md +18 -9
- package/docs/session-mcp.md +7 -2
- package/docs/skills.md +616 -0
- package/docs/threat-model.md +19 -2
- package/docs/tool-contracts.md +9 -5
- package/package.json +2 -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 +94 -0
- package/skills/pi-session-review/SKILL.md +58 -0
package/docs/threat-model.md
CHANGED
|
@@ -26,6 +26,14 @@ Pi Session MCP trusts the local process that launches and speaks MCP over inheri
|
|
|
26
26
|
`process.execPath`, `dist/`, and `PI_SESSION_MCP_CONFIG`; no arbitrary `cwd` is
|
|
27
27
|
accepted. Durable pending/owned ownership state contains neither paths nor
|
|
28
28
|
secrets.
|
|
29
|
+
- **Skill installation into clients:** `setup --apply` writes the controller skill `pi-session-orchestration` into the clients' skill directories, in the home directory (`~/.agents/skills`, `~/.claude/skills`) and, for Claude Code `project`, in the project that setup runs in (`<project>/.claude/skills`). What is written there becomes instructions for the controlling agent, so the copy is as trusted as the package or the override it comes from. Mitigations:
|
|
30
|
+
- Copies come only from the package's `skills/` directory or from the operator's override directory next to the configuration file. No tool argument, client prompt or workspace names a source.
|
|
31
|
+
- The override directory and its `.pi-session-mcp-bases.json` are operator-trusted configuration next to the configuration file, never a workspace. Keep them out of every workspace and writable only by the operator; a `coding` session that can write there could change what setup installs next.
|
|
32
|
+
- Setup reads a bounded tree of regular files (at most 32 files and 1 MiB, no links or special files) and installs it as a real copy, never as a link. The copy is staged and renamed into place. An update renames the old tree to a backup named after the pending record's transaction id and deletes it only after verifying that it is the exact old tree; leftover intermediates are deleted only by their exact names and only after verification, and anything modified or foreign stays (`skill_recovery_retained`).
|
|
33
|
+
- Setup never replaces or deletes a modified installed copy, hidden operator entries inside it, a foreign skill of the same name or a linked or non-directory entry; it reports `skill_divergent`. A link to exactly the effective skill is accepted as the operator's own (`skill_linked`) and never written through or deleted. Ownership records hold a version 2 content fingerprint (and, during an update, the replaced fingerprint), no path. A bare version 1 value from 0.8.0 names a copy only when a trusted reference (a released 0.8.0 shipped tree or the current library tree) has that value and the copy's exact bytes; otherwise setup reports `skill_legacy_unverified` and changes nothing; a project record carries an unsalted, truncated SHA-256 of the project's real path as an opaque identity, which someone who can read the state file could test against guessed paths.
|
|
34
|
+
- A project may be untrusted. Inside a project setup never follows a link: any link below the project root makes the slot divergent, so a repository cannot redirect the write outside itself. In the home directory the client's skills directory may be the operator's own link (for example into a dotfiles checkout) and is followed; the skill entry itself is never followed.
|
|
35
|
+
- `--customize-skill` writes only below the override directory, never overwrites an existing override and never edits an operator's file. It moves the recorded base only on an explicit `--apply`, which acknowledges a reviewed change to the shipped skill. `--apply` runs under an exclusive kernel lock on `<override dir>/.pi-session-mcp-bases.lock` and replaces the bases file atomically, so concurrent runs cannot lose a base; the dry-run takes no lock and writes nothing.
|
|
36
|
+
- Worker skills are not installed into clients. Reports name the skill and a stable code, never a path or content.
|
|
29
37
|
- **False verification:** Verify combines Doctor and exact registration
|
|
30
38
|
equality with a bounded direct MCP initialize, `tools/list`, and
|
|
31
39
|
`pi_capabilities_get({})` call. It never starts a session or invokes
|
|
@@ -68,7 +76,7 @@ Pi Session MCP trusts the local process that launches and speaks MCP over inheri
|
|
|
68
76
|
- **Thinking-level clamping:** SDK capability handling can alter a requested level. The adapter compares the effective `session.thinkingLevel` after creation and disposes on a mismatch.
|
|
69
77
|
- **Orphaned SDK session:** a post-creation mismatch or later registry failure could otherwise leave a live Pi handle. The adapter holds it locally until all postconditions pass, best-effort disposes on each later failure, and the registry admits only verified handles.
|
|
70
78
|
- **Excess capability:** the execution profile selects a permission-derived tool allowlist. Read-only permits only `read`, `grep`, `find`, and `ls`; coding remains high impact.
|
|
71
|
-
- **Project resource code execution:** Pi resource loading disables extension discovery,
|
|
79
|
+
- **Project resource code execution:** Pi resource loading disables extension discovery, default skill directories, prompts, and themes; only a profile's allowlisted extensions and its explicitly selected catalog skills load (see below). A skill, prompt template or theme that an extension package ships is not made available by the allowlist. Non-executable `AGENTS.md` context remains untrusted instruction content, never authorization.
|
|
72
80
|
- **Concurrent state corruption:** a per-session queue serializes prompt admission and close; concurrent abort callers share one attempt for the active turn. Closing is terminal, settles an active turn, and disposes once.
|
|
73
81
|
- **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.
|
|
74
82
|
- **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.
|
|
@@ -80,6 +88,15 @@ Pi Session MCP trusts the local process that launches and speaks MCP over inheri
|
|
|
80
88
|
- `read-only` profiles never activate extension tools. At session start, after load and again after binding, no extension tool may shadow a built-in or granted tool; later registrations are covered in the residual risks.
|
|
81
89
|
- Client prompts never dispatch extension commands, but extension input hooks can still see, rewrite or consume a prompt. They receive it with `source: "rpc"`, Pi's marker for input from a program, so a hook that reads the source sees that no human typed it. A hook that ignores the source treats it like any other input.
|
|
82
90
|
- Each extension session gets its own model runtime, and close emits `session_shutdown`.
|
|
91
|
+
- **Skills as prompt content:** a profile's `skills` select files from the operator's `skillCatalog`. The MCP client cannot name a skill, a path or a catalog entry; `pi_session_start` and `pi_session_prompt` take no skill input. Mitigations:
|
|
92
|
+
- Catalog values are single local `SKILL.md` files: no directories, globs, URLs, scheme-prefixed sources, `~` or backslashes. The one accepted scheme is `builtin:<name>`, which resolves to the operator's override next to the configuration file or else to the skill shipped in the package, and to no other place. Relative paths resolve against the configuration file's directory, never against a workspace.
|
|
93
|
+
- The server loads exactly the selected files with no default directories, validates them at session start and rejects oversized (over 256 KiB), duplicate, invalid and explicit-only skills with `skill_load_failed`. Its message and diagnostics never contain a path, skill name or SDK text.
|
|
94
|
+
- Selection limits the regular skill catalog only. An allowlisted extension stays trusted executable code and can still read files or inject prompt text.
|
|
95
|
+
- Skills are operator-managed prompt content. In `coding` profiles a skill's instructions run with the profile's tools, so a skill grants no rights but can direct everything the profile may do. Review skills like code.
|
|
96
|
+
- Content is not snapshotted: the SDK keeps file paths, so a changed skill or companion file can reach a running session. Operators must not change them during active sessions. The configuration fingerprint covers configuration bytes, not skill contents.
|
|
97
|
+
- A `coding` session can write any file in its workspace, including a catalog file that lies inside it, and so change the instructions of other sessions and profiles. Operators keep catalog files outside every configured workspace; nothing enforces this.
|
|
98
|
+
- Whether the model reads a listed skill is the model's decision; configured, available and actually read are different states.
|
|
99
|
+
- Pi lists each available skill to the model with the absolute path of its `SKILL.md`, so the model knows that path and can repeat it in `assistantText`. Capabilities, errors and diagnostics stay path-free; completed `assistantText` is model output and not sanitized.
|
|
83
100
|
- **stdout corruption:** every write through `process.stdout` or `console.log`, `console.info` and `console.debug` other than the MCP transport's is dropped. The stdout guard intercepts `process.stdout.write`, `process.stdout.end` and `console.log`, `console.info` and `console.debug`, which covers output from extensions and the SDK in the server process. stderr gets only `foreign_stdout_suppressed` with byte and write counts, never the content. Anything that writes file descriptor 1 directly is not covered; see the residual risks.
|
|
84
101
|
- **Misleading annotations:** annotations are client hints only and never grant access.
|
|
85
102
|
- **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.
|
|
@@ -104,7 +121,7 @@ sanitizing catch. A foreign transport exception with identical text remains
|
|
|
104
121
|
generic. This does not raise the limit, permit additional remote error codes or
|
|
105
122
|
change public terminal errors; cancellation and close still take precedence.
|
|
106
123
|
|
|
107
|
-
Aliases
|
|
124
|
+
Aliases, profile definitions, skill catalog entries and the skill override directory are trusted administrator configuration, not a filesystem or provider-security sandbox. A locally available model may later be unreachable; no live provider request is made during selection. Symlinks and Pi tools can reach resources permitted to the OS identity. `AGENTS.md` can influence model behavior. The number of active sessions and the duration of an already accepted turn remain unbounded. Stdio peer authentication, quotas, persistent recovery, provider hard-kill capability, dependency integrity policy, and OS/filesystem isolation remain outside the verified boundary. Coding-profile acceptance checks behavior in a selected fixture; it does not prove OS-level isolation.
|
|
108
125
|
The trusted same-UID operator can unlink or replace the setup lock path between
|
|
109
126
|
checks and must not mutate the ownership directory during a transaction.
|
|
110
127
|
|
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.
|
|
25
|
+
"server": { "name": "pi-session-mcp", "version": "0.8.1" },
|
|
26
26
|
"configuration": {
|
|
27
27
|
"fingerprint": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
|
28
28
|
"reloadPolicy": "restart-required"
|
|
@@ -35,12 +35,13 @@ There are exactly eight tools. No `pi_turn_wait` tool or live provider/model inv
|
|
|
35
35
|
"provider": "configured-provider",
|
|
36
36
|
"model": "configured-model",
|
|
37
37
|
"thinkingLevel": "medium",
|
|
38
|
-
"extensions": []
|
|
38
|
+
"extensions": [],
|
|
39
|
+
"skills": []
|
|
39
40
|
}]
|
|
40
41
|
}
|
|
41
42
|
```
|
|
42
43
|
|
|
43
|
-
The server sorts both arrays by alias with a deterministic code-point comparison. It copies only loaded configuration fingerprint/reload policy, configured aliases, and the
|
|
44
|
+
The server sorts both arrays by alias with a deterministic code-point comparison. It copies only loaded configuration fingerprint/reload policy, configured aliases, and the eight documented profile fields. `extensions` lists the configured extension specs (`npm:<name>@<version>`), empty when a profile loads none; it makes no claim that the package is installed. `skills` lists the skill-catalog aliases that the profile selects, in configured order, `[]` when it selects none. It contains no paths, file names, contents or SDK diagnostics, and it is configuration intent only: it makes no claim that a skill file exists, loads, or will be read by the model. See [Pi skills](skills.md). It never copies the configuration path or contents, workspace paths, authentication state, SDK data, session/turn data, prompts, transcripts, or tool arguments/results. The handler reads the in-memory loaded snapshot only and does not call the registry, Pi adapter, provider, filesystem, or network. The fingerprint identifies the exact loaded bytes, not current-file freshness; provider/model fields describe configured intent and make no availability claim.
|
|
44
45
|
|
|
45
46
|
Annotations are `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`, and `openWorldHint: false`. Clients may use them for presentation, but the strict input schema and server-owned projection enforce the contract.
|
|
46
47
|
|
|
@@ -52,6 +53,8 @@ The former `profile` input is rejected; it is not reinterpreted as an execution-
|
|
|
52
53
|
|
|
53
54
|
Successful session metadata is a whitelist: `id`, `workspace`, `executionProfile`, `profile`, `provider`, `model`, `thinkingLevel`, `state`, `createdAt`, and `updatedAt`. `profile` remains derived permission metadata (`read-only` or `coding`) for compatibility; it is not client-selectable. Provider, model, and thinking level are projected only after SDK post-verification.
|
|
54
55
|
|
|
56
|
+
The selected skills of an execution profile are never an input. A session loads exactly the skills that the profile selects from the operator's skill catalog, validated at start; a failure is `skill_load_failed`. A catalog value is the path of one `SKILL.md` or `builtin:<name>`, which names a skill of the skill library: the operator's override next to the configuration file if it exists, else the skill shipped in the package. It is resolved when the server loads the configuration, and the value never appears in tool output. See [Pi skills](skills.md).
|
|
57
|
+
|
|
55
58
|
## Deterministic MCP errors
|
|
56
59
|
|
|
57
60
|
Public MCP errors are stable and sanitized. Their messages do not include inputs, auth details, provider responses, filesystem paths, or secrets.
|
|
@@ -72,6 +75,7 @@ Public MCP errors are stable and sanitized. Their messages do not include inputs
|
|
|
72
75
|
| `extension_version_mismatch` | Pi's installed extension package has another version than the configured one. |
|
|
73
76
|
| `extension_load_failed` | A configured extension has an invalid manifest, failed to load or failed to bind. |
|
|
74
77
|
| `extension_tool_conflict` | An extension tool name collides with a built-in, MCP or other extension tool, or is unsafe: not 1 to 64 letters, digits, `_` or `-` (not starting with `-`), or reserved for MCP (`mcp__` prefix, `list_mcp_resources`, `list_mcp_resource_templates`, `read_mcp_resource`). |
|
|
78
|
+
| `skill_load_failed` | A skill that the profile selects could not be loaded: a missing (also a `builtin:` name that matches no override and no shipped skill), unreadable or oversized (over 256 KiB) file, an invalid skill, two selected files with the same Pi skill name, two aliases on the same canonical file, or a skill with `disable-model-invocation: true`. The message is the fixed `Configured Pi skill could not be loaded`; it never contains a path, skill name or SDK text. |
|
|
75
79
|
| `pi_session_creation_failed` | Pi session construction failed without a more specific safe classification. |
|
|
76
80
|
| `server_stopping` | Shutdown has begun, so a new session cannot be admitted. |
|
|
77
81
|
|
|
@@ -81,12 +85,12 @@ Invalid execution-profile configuration prevents startup, so it cannot be an MCP
|
|
|
81
85
|
|
|
82
86
|
| Startup diagnostic code | Meaning |
|
|
83
87
|
| --- | --- |
|
|
84
|
-
| `invalid_execution_profile_config` | The execution-profile configuration violates its invariants or strict shape. |
|
|
88
|
+
| `invalid_execution_profile_config` | The execution-profile configuration violates its invariants or strict shape, including an unknown or duplicate selected skill alias, two selected skill aliases with the same path, or an invalid `skillCatalog` entry (including a malformed `builtin:` name). |
|
|
85
89
|
| `invalid_thinking_level` | A configured thinking level is outside the supported enum. |
|
|
86
90
|
|
|
87
91
|
`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.
|
|
88
92
|
|
|
89
|
-
While a turn runs, `updatedAt` is the
|
|
93
|
+
While a turn runs, `updatedAt` is the time of the last observed public SDK activity of that turn: assistant message start, streaming updates and end, and tool execution start, update and end. It freezes at the terminal transition. The `updatedAt` of the session does not follow this activity: it moves when a turn starts and at its terminal transition. It is a liveness lower bound only. Streaming is activity, not evidence of finished or useful work. Work without a public event, such as the internal steps of an extension's own agent loop or a long tool call without updates, stays invisible, so a stamp that has not moved can still be a working turn (a long model response, thinking, a first token, or a long tool call) and never justifies a claim that a turn is hung. The stamp is a wall-clock ISO-8601 millisecond value for ordering, not a progress count, duration, or step total, and activity within one millisecond simply reuses the stamp. Only the type of an event and the role of its message are inspected: no delta, thinking block, tool argument, or partial result is stored or projected, and the answer still comes only from the final assistant message.
|
|
90
94
|
|
|
91
95
|
Context usage stays out of the boundary: no token, usage, context-window, or cost figure is projected for a running or terminal turn, so approaching context exhaustion remains invisible in the turn view and in `pi_session_get`. This change adds no progress counters, tool names, arguments, results, or transcripts; see *Failure causes* below for failure-cause classification, which is not part of the turn view and is decided in *Failure causes* below.
|
|
92
96
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-session-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Local stdio MCP server for controlled Pi coding-agent sessions",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
".pi-session-mcp-cli/",
|
|
30
30
|
"scripts/doctor.mjs",
|
|
31
31
|
"pi-session-mcp.example.json",
|
|
32
|
+
"skills/",
|
|
32
33
|
"docs/",
|
|
33
34
|
"!docs/superpowers/",
|
|
34
35
|
"CHANGELOG.md",
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"workspaces": {
|
|
3
|
-
"project": "
|
|
3
|
+
"project": "/absolute/path/to/project"
|
|
4
|
+
},
|
|
5
|
+
"skillCatalog": {
|
|
6
|
+
"pi-session-implementation": "builtin:pi-session-implementation",
|
|
7
|
+
"pi-session-review": "builtin:pi-session-review"
|
|
4
8
|
},
|
|
5
9
|
"executionProfiles": {
|
|
6
10
|
"safe-readonly": {
|
|
@@ -8,14 +12,16 @@
|
|
|
8
12
|
"permissionProfile": "read-only",
|
|
9
13
|
"provider": "example-provider",
|
|
10
14
|
"model": "example-model",
|
|
11
|
-
"thinkingLevel": "medium"
|
|
15
|
+
"thinkingLevel": "medium",
|
|
16
|
+
"skills": ["pi-session-review"]
|
|
12
17
|
},
|
|
13
18
|
"coding-example": {
|
|
14
19
|
"default": false,
|
|
15
20
|
"permissionProfile": "coding",
|
|
16
21
|
"provider": "another-example-provider",
|
|
17
22
|
"model": "another-example-model",
|
|
18
|
-
"thinkingLevel": "high"
|
|
23
|
+
"thinkingLevel": "high",
|
|
24
|
+
"skills": ["pi-session-implementation"]
|
|
19
25
|
}
|
|
20
26
|
}
|
|
21
27
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-session-implementation
|
|
3
|
+
description: Use when you are a Pi worker session that was given exactly one implementation task by a controlling agent, to change code in your workspace. Defines the working rules, scope discipline and final report format for a bounded implementation task. Do not use for review-only tasks or when no concrete task was assigned.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Implementing one bounded task
|
|
7
|
+
|
|
8
|
+
You are a worker. A controlling agent gave you one task. Do that task and report back.
|
|
9
|
+
|
|
10
|
+
## Before you change anything
|
|
11
|
+
|
|
12
|
+
- Identify the one problem you must solve. If the task bundles several problems, do the first and name the rest in your report. If the task is unclear, say what is unclear in your report instead of guessing.
|
|
13
|
+
- Confirm your starting point: the base commit or branch you were given. Check that the workspace matches it. If it does not, stop and report the mismatch.
|
|
14
|
+
- Confirm the agreed change area (files or directories). Stay inside it. If the task needs a change outside it, report that as an open point; do not make the change.
|
|
15
|
+
- Read the code around the change and follow its style, naming and comment density.
|
|
16
|
+
|
|
17
|
+
## While you work
|
|
18
|
+
|
|
19
|
+
- Make small changes that can be traced to the task. No unrelated cleanups, renames or formatting sweeps.
|
|
20
|
+
- Do not add dependencies unless the task says so.
|
|
21
|
+
- Write or update tests for the behavior you change. Run the targeted tests for that area, not the whole suite unless the task asks for it.
|
|
22
|
+
- Never integrate, merge or copy in other workers' changes. Other workers may be changing other parts of the project at the same time. Work only from your starting point.
|
|
23
|
+
- Never expose secrets, tokens or credentials in files, commits or your report.
|
|
24
|
+
- This skill grants no rights. Your tools define what you can do. If a tool you need is missing, or a command is denied, do not work around it. Report the blocker and what you would have done.
|
|
25
|
+
|
|
26
|
+
## Commit
|
|
27
|
+
|
|
28
|
+
- If your profile can commit and the task asks for it, commit your change with a clear message that refers to the task or issue. Make one commit per issue.
|
|
29
|
+
- If you cannot commit, leave the changes in the workspace and say so.
|
|
30
|
+
- Do not push, open pull requests or change branches unless the task says so.
|
|
31
|
+
|
|
32
|
+
## Final report
|
|
33
|
+
|
|
34
|
+
End with a report that has these parts:
|
|
35
|
+
|
|
36
|
+
1. Result: done, partly done or blocked, in one sentence.
|
|
37
|
+
2. Commit: the hash and branch, or "not committed" and why.
|
|
38
|
+
3. Changed files: repository-relative paths, one line each on what changed.
|
|
39
|
+
4. Checks run: each command and its result (pass, fail, number of tests). Say which checks you did not run and why.
|
|
40
|
+
5. Open points: blockers, assumptions, work outside your change area, anything the controlling agent must verify.
|
|
41
|
+
|
|
42
|
+
Report facts you observed. Do not claim a check passed unless you ran it and saw it pass.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-session-orchestration
|
|
3
|
+
description: Use when you, as the controlling agent (Claude Code or Codex), delegate work to Pi worker sessions through the pi-session-mcp MCP tools (pi_capabilities_get, pi_session_start, pi_session_prompt, pi_turn_get, pi_session_abort, pi_session_close). Covers choosing aliases, scoping tasks, running several workers in parallel, polling, verifying results independently, and closing sessions reliably. Do not use inside a Pi worker session.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Orchestrating Pi worker sessions
|
|
7
|
+
|
|
8
|
+
You control Pi worker sessions through the pi-session-mcp tools. You choose only configured workspace and profile aliases. Workers do the work; you scope, monitor, verify and close.
|
|
9
|
+
|
|
10
|
+
## 1. Discover first
|
|
11
|
+
|
|
12
|
+
- Call `pi_capabilities_get` before anything else in a run. Use only the workspace and profile aliases it lists. Never invent an alias or pass a path.
|
|
13
|
+
- Each profile lists `permissionProfile` (`read-only` or `coding`), `extensions` and `skills`. `skills` names the configured skill aliases. That is configuration intent only. It does not prove that a session loaded the skill or that the model will read it.
|
|
14
|
+
- Capabilities do not prove that a provider or model is reachable. A successful `pi_session_start` shows that the session was created with the selected provider, model and thinking level, and that local authentication, the extensions, external MCP servers and selected skills passed their start checks. It does not prove that the provider accepts requests: credentials, quota and network show only when a turn runs.
|
|
15
|
+
|
|
16
|
+
## 2. Scope each task
|
|
17
|
+
|
|
18
|
+
Write down before you start a worker:
|
|
19
|
+
|
|
20
|
+
- goal and the single bounded problem,
|
|
21
|
+
- issue or reference, if any,
|
|
22
|
+
- base commit or branch the worker starts from,
|
|
23
|
+
- dependencies on other tasks,
|
|
24
|
+
- workspace alias,
|
|
25
|
+
- the change area (files or directories) the worker may touch,
|
|
26
|
+
- the checks you expect it to run.
|
|
27
|
+
|
|
28
|
+
Split work so tasks do not overlap. If two tasks need the same files, run them one after the other.
|
|
29
|
+
|
|
30
|
+
## 3. Pick workspace and profile
|
|
31
|
+
|
|
32
|
+
- Use a `read-only` profile for review, analysis and questions. Use a `coding` profile only when files must change.
|
|
33
|
+
- Pick a profile whose listed `skills`, `extensions` and model fit the task, for example a profile that lists `pi-session-implementation` for implementation work or `pi-session-review` for review work.
|
|
34
|
+
- A listed skill is something the worker can use, not a task. Do not tell a worker to follow a skill, and never widen a task, just because its profile lists that skill. Name a skill in the prompt only when the task itself needs it.
|
|
35
|
+
- Every concurrently writing worker needs its own prepared worktree workspace alias on the base commit you specified. Never let two writers share an alias. Read-only workers may share one.
|
|
36
|
+
- A session's workspace and profile are fixed at start. Never try to switch them; start a new session instead.
|
|
37
|
+
- The profile's tools set the limit. A skill grants no rights. If no listed profile can do the task, stop and report that instead of picking a more powerful one than needed.
|
|
38
|
+
|
|
39
|
+
## 4. Keep a ledger
|
|
40
|
+
|
|
41
|
+
Keep an internal ledger with one row per task: task, workspace alias, profile alias, `sessionId`, `turnId`, start time and time budget, status. Update it after every tool call. Decide the time budget per task when you start it. A cap on concurrent sessions and per-task budgets are your own policy for this run; the server enforces neither. Two concurrent workers is the first tested scope, not a limit of the server; choose a cap you can supervise.
|
|
42
|
+
|
|
43
|
+
## 5. Start in parallel, wait on the first
|
|
44
|
+
|
|
45
|
+
- Start all independent tasks (`pi_session_start`, then `pi_session_prompt`) before you wait on any of them.
|
|
46
|
+
- A prompt call returns a running turn at once. Do not block on one task while others sit unstarted.
|
|
47
|
+
- A session accepts one running turn. A second prompt on a running session fails with `session_running`.
|
|
48
|
+
- Put the full task in the prompt: goal, base commit, change area, checks, expected report. Add nothing the task does not ask for. The worker cannot see your conversation.
|
|
49
|
+
|
|
50
|
+
## 6. Poll with pauses
|
|
51
|
+
|
|
52
|
+
- Poll `pi_turn_get` with `sessionId` and `turnId`. There is no wait tool.
|
|
53
|
+
- Pause between polls (several seconds, longer for long tasks). Do not hammer.
|
|
54
|
+
- Cycle over all running tasks in the ledger. Handle whichever finishes first, then continue.
|
|
55
|
+
- Stop waiting on a task when its time budget is spent. Then abort it (see section 9).
|
|
56
|
+
|
|
57
|
+
## 7. Interpret progress and results
|
|
58
|
+
|
|
59
|
+
- `updatedAt` on a running turn is the time of the last observed public SDK activity: assistant message start, streaming updates and end, and tool execution start, update and end. Streaming is activity, not evidence of finished or useful work. Work without a public event stays invisible, for example inside an extension's own agent loop or in a long tool call without updates. A stamp that has not moved is therefore no proof of a hang. Judge by your time budget and by the workspace.
|
|
60
|
+
- `completed` is a technical state: the turn ended and returned text. It does not mean the task succeeded. Read `assistantText` and check `truncated`.
|
|
61
|
+
- Never accept a worker report as proof. A worker saying the tests pass is a claim, not evidence.
|
|
62
|
+
|
|
63
|
+
## 8. Take over and verify
|
|
64
|
+
|
|
65
|
+
Before you close a task or integrate anything:
|
|
66
|
+
|
|
67
|
+
- inspect the actual files and diff in the worker's workspace, and stay within the paths you were given: do not search the machine for other files to confirm a result,
|
|
68
|
+
- run the relevant tests and checks yourself,
|
|
69
|
+
- compare the result with the scope you wrote down,
|
|
70
|
+
- reject or send back work that is outside the change area or unverified.
|
|
71
|
+
|
|
72
|
+
You integrate. Workers never integrate each other's changes. Resolve conflicts between workers yourself.
|
|
73
|
+
|
|
74
|
+
## 9. Follow-ups, failures and aborts
|
|
75
|
+
|
|
76
|
+
- Send a follow-up prompt in the same session only when the existing context fits the next step: same task, same workspace, same base. For an unrelated task, start a fresh session.
|
|
77
|
+
- `failed` means `turn_failed`. The error carries no cause. Check the result in the workspace, then retry once in a fresh session with a narrower prompt, or take the task over yourself.
|
|
78
|
+
- `aborted` means the turn stopped. Look at what the workspace contains before reusing it.
|
|
79
|
+
- `pi_session_abort` returns `abort_failed` if the abort was rejected. The turn may still be running. Poll it.
|
|
80
|
+
- `abort_timeout` is not a successful abort. The turn may still be running or may finish normally. Decide an observation and cleanup budget before you abort, for example a fixed number of polling rounds within a few minutes. Poll `pi_turn_get` until the turn is terminal or the budget is spent, then close the session with `pi_session_close`. If the close fails or does not finish, stop using that workspace, treat it as unverified and report it. Never wait without a bound.
|
|
81
|
+
- On `pi_session_start` errors, do not retry blindly and do not change the profile. These codes need the operator; a retry cannot fix them: `unknown_execution_profile`, `unknown_workspace`, `skill_load_failed`, `extension_not_installed`, `extension_version_mismatch`, `extension_tool_conflict`, `external_mcp_no_tools`, `external_mcp_grant_tool_missing` and `external_mcp_activation_mismatch`.
|
|
82
|
+
- `external_mcp_unavailable` (an external MCP server that cannot connect, times out or breaks the protocol) and `extension_load_failed` (an invalid package, but also a start timeout) can be transient. Retry at most once after a pause, then report.
|
|
83
|
+
|
|
84
|
+
## 10. Close every session
|
|
85
|
+
|
|
86
|
+
- Call `pi_session_close` for every session you started, when its task is done, aborted, failed or abandoned. Closing is idempotent.
|
|
87
|
+
- Close on every error path, too. Before you end the run, check the ledger: no session may remain open.
|
|
88
|
+
- A session that is idle is still open. Closing releases its resources.
|
|
89
|
+
|
|
90
|
+
## Limits to remember
|
|
91
|
+
|
|
92
|
+
- Each client process has its own server process and its own in-memory sessions. Separate Claude Code and Codex processes do not share sessions.
|
|
93
|
+
- Sessions disappear when the server process ends. Do not rely on them across restarts.
|
|
94
|
+
- A `coding` profile limits Pi's tools. It is not an operating-system sandbox.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-session-review
|
|
3
|
+
description: Use when you are a Pi worker session asked to review a fixed target such as a diff, commit range, branch or set of files, and to report findings. Defines the review priorities, finding format and evidence rules. Do not use for implementing changes.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Reviewing a fixed target
|
|
7
|
+
|
|
8
|
+
You are a reviewer. A controlling agent gave you a fixed review target. Review it and report findings.
|
|
9
|
+
|
|
10
|
+
## Fix the target
|
|
11
|
+
|
|
12
|
+
- State the target at the start: commit range, branch, diff or file list, as given. Review exactly that.
|
|
13
|
+
- If the target is missing or ambiguous, say so in your report instead of choosing one.
|
|
14
|
+
- Read the code around the change, not only the diff lines. Check callers and tests that the change affects.
|
|
15
|
+
|
|
16
|
+
## Priorities
|
|
17
|
+
|
|
18
|
+
Review in this order:
|
|
19
|
+
|
|
20
|
+
1. Correctness: wrong behavior, missed cases, broken invariants, race conditions.
|
|
21
|
+
2. Security: input validation, path and secret handling, trust boundaries, unsafe defaults.
|
|
22
|
+
3. Lifecycle: resources opened and closed, error paths, timeouts, cleanup, ordering.
|
|
23
|
+
4. MCP and SDK contract: tool schemas, field names, error codes, states, documented exports versus internal imports.
|
|
24
|
+
5. Tests and maintainability: missing or weak tests, misleading names, stale docs.
|
|
25
|
+
|
|
26
|
+
Skip style nitpicks unless they hide a defect.
|
|
27
|
+
|
|
28
|
+
## Findings
|
|
29
|
+
|
|
30
|
+
Report each finding with:
|
|
31
|
+
|
|
32
|
+
- Severity: critical, high, medium or low.
|
|
33
|
+
- Location: repository-relative `path:line`. Give concrete lines, not only a file.
|
|
34
|
+
- Cause: what is wrong and why.
|
|
35
|
+
- Impact: what can break and for whom.
|
|
36
|
+
- Fix: a concrete, verifiable change, and how to check it.
|
|
37
|
+
|
|
38
|
+
Separate two groups in your report:
|
|
39
|
+
|
|
40
|
+
- Verified findings: you read the code or ran a check and saw the problem.
|
|
41
|
+
- Risks and hypotheses: plausible but not confirmed. Say what would confirm them.
|
|
42
|
+
|
|
43
|
+
Order findings by severity. If you find nothing, say what you checked and what you did not.
|
|
44
|
+
|
|
45
|
+
## Evidence rules
|
|
46
|
+
|
|
47
|
+
- Never approve because CI is green, a worker report says the work is done, or tests pass. Those do not replace your own reading.
|
|
48
|
+
- Run the checks that matter if your tools allow it, and report each result. If your profile is read-only and you cannot run checks, list the checks you did not run and what each would have shown.
|
|
49
|
+
- This skill grants no rights. If a tool you need is missing, report the blocker instead of working around it.
|
|
50
|
+
- Do not change files. Report the fix instead.
|
|
51
|
+
|
|
52
|
+
## Final report
|
|
53
|
+
|
|
54
|
+
1. Target reviewed.
|
|
55
|
+
2. Verdict: blocking findings exist, only non-blocking findings, or no findings. Base it on your evidence.
|
|
56
|
+
3. Verified findings.
|
|
57
|
+
4. Risks and hypotheses.
|
|
58
|
+
5. Checks run and checks not run.
|