# Sage Pi Adapter Integration Skill

Use this skill when a repository uses `@earendil-works/pi-coding-agent`
(formerly `@mariozechner/pi-coding-agent`) and needs Sage integrated into its
session bootstrap or Pi extension layer.

## Preflight

1. Verify npm package availability: `npm view @sage-protocol/pi-adapter version`.
2. Confirm whether the target uses the installed Pi CLI extension or owns a
   harness bootstrap containing `createAgentSession`.
3. If source integration is requested but the workspace has no harness source,
   stop and ask for the harness repo path instead of editing unrelated files.

> **Pi upstream:** [earendil-works/pi](https://github.com/earendil-works/pi)
>
> **Sage upstream:** [sage-protocol/sage](https://github.com/sage-protocol/sage)

## Integration Contract

Sage 0.4 uses Pi-native skill ownership:

- Pi discovers skills from `<available_skills>`.
- Pi loads a selected procedure through `/skill:<name>` or a complete
  `SKILL.md` read.
- The adapter does not call `sage suggest hook skill` for each prompt, inject
  `sage-suggested-skills`, or infer use from a suggestion.
- Manual `sage suggest skill "<task>"` remains an explicit CLI ranking tool; it
  is not automatic Pi injection.
- The adapter keeps SessionStart Sage context, MCP tools, behaviors, security
  hooks, prompt/response capture, and explicit subagent resolution.
- The packaged Pi extension observes truthful complete native loads, writes
  source- and session-qualified load receipts, and exposes
  `sage_mark_guided_use` to bind actually applied loaded skills to the exact
  prompt capture through Sage's native-use daemon path.
- Pi has no suggestion auto-skip, auto-reject, or suggestion-quality widget
  lifecycle.

## Integration Modes

### Pi CLI Extension

```bash
pi install npm:@sage-protocol/pi-adapter
pi list
```

Restart Pi and verify that `sage_status` is callable. Pi's native skill catalog
and `/skill:<name>` command own skill discovery and loading.

### Source-Owned Harness

```ts
import {
  createAgentSession,
  createCodingTools,
  type ToolDefinition as PiToolDefinition,
} from '@earendil-works/pi-coding-agent';
import {
  createSageSessionConfig,
  type ToolDefinition as SageToolDefinition,
} from '@sage-protocol/pi-adapter';

function asPiCustomTools(tools: SageToolDefinition[]): PiToolDefinition[] {
  // Type-shape compatibility across supported Pi minors; no runtime conversion.
  return tools as unknown as PiToolDefinition[];
}

const sage = await createSageSessionConfig({
  source: 'pi-agent-core',
  enableSecurityHooks: true,
  enableRlmFeedback: true,
});
const cwd = process.cwd();
const securedTools = sage.wrapToolsWithSecurity(createCodingTools(cwd));
const { session } = await createAgentSession({
  ...existingConfig,
  cwd,
  noTools: 'builtin',
  customTools: asPiCustomTools([...securedTools, ...sage.customTools]),
});

const disposeSageHooks = sage.setupHooks(session);
```

Current Pi treats `tools` as a string allowlist. Definitions belong in
`customTools`, and `noTools: 'builtin'` avoids registering an unwrapped built-in
set as well. Keep the one cast isolated at the supported Pi peer-version type
boundary; it is not a runtime conversion.

Wire teardown to `disposeSageHooks()` and, when the harness owns bridge
lifecycle, `await sage.mcpBridge.stop()`.

The packaged extension owns Pi event-level full-load observation and
`sage_mark_guided_use` registration. A custom SDK host that bypasses it must add
equivalent Pi event wiring if those extension features are required.

## Native Skill Use Contract

When a skill applies:

1. Select it from Pi's native `<available_skills>` catalog.
2. Load its complete procedure with `/skill:<name>` or a full `SKILL.md` read.
3. Follow the procedure.
4. Call `sage_mark_guided_use({ skills: ["<loaded-key>"] })` in the same turn
   only if at least one instruction, constraint, or output structure guided the
   work.

The declaration is additive for multiple loaded skills. Loading alone is not
use. Partial reads do not establish a load. Unloaded keys, ambiguous bare
names, a missing current capture, or a failed daemon write fail closed. The
adapter attaches the exact Pi session and active prompt capture; agents should
not invent or copy correlation identifiers. Compaction and session
replacement clear load eligibility.

There is no automatic suggestion settlement in Pi. Do not add skip/reject
bookkeeping, suggestion-quality annotations, or a suggestion widget.

Captures and native-use feedback stay in Sage's local capture/RLM stores.
Never copy raw session text directly into a `SKILL.md`; examples must be
reviewed and sanitized through the capture/example workflow.

## SessionStart, Tools, and Behaviors

Keep these surfaces intact:

- SessionStart output from `sage skill context --format pi`
- `hub_list_servers`, `hub_status`, `hub_session_list`,
  `hub_start_server`, and `hub_stop_server`
- `sage_search`, `sage_execute`, and `sage_status`
- `sage_behavior` controller plans
- pre/post-tool security hooks
- explicit subagent skill resolution for subagents that do not inherit Pi's
  native skill catalog

Bridge health must use low-level MCP probes, not recursively call the
adapter-level `sage_status` tool. Recovery wording should point to the Sage MCP
bridge unless the daemon itself is the failing component.

## Project-Local Pi Skills

For monorepo development, keep Pi thin and use the curated Pi export surface:

```json
{
  "packages": [
    "../packages/sage-pi-adapter",
    {
      "source": "../packages/sage-pi-export",
      "skills": ["skills/*/SKILL.md"],
      "extensions": [],
      "prompts": [],
      "themes": []
    }
  ],
  "enableSkillCommands": true
}
```

Author real skills under `packages/sage/skills/`, declare Pi-visible entries in
`packages/sage/pi-export.manifest.json`, and materialize the curated surface
with `node scripts/util/sync-sage-pi-export.mjs`. Do not point Pi at broad Sage
runtime roots containing backups, snapshots, and third-party installs.

## Deprecated Compatibility

Do not use `sageInjectSuggestion(...)`; version 0.4 retains it only as a no-op.
`suggestLimit`, `suggestDebounceMs`, and `enableProvision` remain exported for
low-level legacy compatibility but are ignored by the default Pi path and
should not appear in new examples.

## Where to Patch

```bash
rg "createAgentSession|createCodingTools|customTools|tools:" src packages/coding-agent
rg "dispose|shutdown|teardown|cleanup" src packages/coding-agent
```

Put setup in the bootstrap/plugin path, call it once per session, preserve
existing model/provider behavior, and do not remove existing tools.

## Verification Checklist

- Pi native `<available_skills>` and `/skill:<name>` remain enabled.
- No per-prompt `sage suggest hook skill` call or `sage-suggested-skills`
  injection exists.
- SessionStart context, MCP tools, behavior plans, security hooks, capture, and
  explicit subagent resolution remain available.
- Complete native loads produce source/session-qualified receipts.
- `sage_mark_guided_use` accepts only actually loaded procedures and uses the
  exact prompt capture.
- No suggestion auto-skip/reject or quality widget exists.
- Teardown disposes hooks and owned bridge lifecycle.
- Build and tests pass.

## Source of Truth

See `packages/sage-pi-adapter/README.md` and `USAGE.md` for the current
contract and examples.
