# Usage Guide

## Requirements

- Node project using `@earendil-works/pi-coding-agent`
- Sage CLI installed and on `PATH` (`sage`)
- See [earendil-works/pi](https://github.com/earendil-works/pi) and [sage-protocol/sage](https://github.com/sage-protocol/sage)

## Integration Modes

1. **Pi CLI extension** — `pi install npm:@sage-protocol/pi-adapter` (no source changes)
2. **SDK embedding** — `createSageSessionConfig(...)` for harness source owners

## Pi CLI Mode

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

Restart Pi and use it normally. The packaged extension provides:

- SessionStart Sage context, loaded inventory, MCP tools, and behaviors
- Pi-native skill discovery through `<available_skills>` and `/skill:<name>`
- prompt/response capture through `sage capture hook prompt/response`
- observation of complete native `SKILL.md` reads and full `skills.get` loads
- source- and session-qualified load receipts
- `sage_mark_guided_use` for binding applied loaded skills to the exact prompt capture
- optional pre/post-tool security scanning
- explicit skill resolution for subagents that do not inherit Pi's native skill catalog

The extension does not run `sage suggest hook skill` per prompt and does not
inject `sage-suggested-skills`. It also has no suggestion auto-skip,
auto-reject, or suggestion-quality widget lifecycle.

## Native Skill Workflow

1. Choose from Pi's native `<available_skills>` catalog.
2. Load the selected skill with `/skill:<name>` or a complete `SKILL.md` read.
3. Follow the loaded procedure.
4. If at least one instruction, constraint, or output structure from it guided
   the current turn, call:

   ```text
   sage_mark_guided_use({ skills: ["<loaded-key>"] })
   ```

The adapter observes successful complete loads, writes a load receipt qualified
by Sage source and Pi session, and lets the daemon bind guided use to the exact
active prompt capture. Partial reads, unloaded keys, ambiguous bare names,
missing captures, and failed receipt/feedback writes fail closed. Loading a
procedure without applying it is not use. Compaction and session replacement
clear load eligibility.

Manual ranking is still available when explicitly requested:

```bash
sage suggest skill "review this smart contract" --format json
```

That command does not inject a skill into Pi. Load the chosen full procedure
through Pi's native flow before using it.

## SDK Integration

```typescript
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({
  sageBin: 'sage',
  source: 'pi-agent-core',
  enableRlmFeedback: true,
  enableSecurityHooks: true,
});
const cwd = process.cwd();
const securedTools = sage.wrapToolsWithSecurity(createCodingTools(cwd));
const { session } = await createAgentSession({
  cwd,
  model,
  noTools: 'builtin',
  customTools: asPiCustomTools([...securedTools, ...sage.customTools]),
});

const disposeSageHooks = sage.setupHooks(session);
// on teardown: disposeSageHooks(); await sage.mcpBridge.stop();
```

Pi's `tools` option is a string allowlist, not a tool-definition array. The
helper isolates the only compatibility cast between the adapter's tool shape,
which spans supported Pi minors, and Pi's generic `ToolDefinition`; it performs
no runtime conversion.

The packaged Pi extension contains the Pi event-level native-load observer and
`sage_mark_guided_use` registration. A custom SDK host that bypasses the
extension must provide equivalent Pi event wiring if it wants those extension
features; `createSageSessionConfig` still supplies bridge, SessionStart,
capture, and security integration.

## Plugin Pattern

```typescript
export async function setupSagePlugin(runtime) {
  const sage = await createSageSessionConfig({ source: 'pi-agent-core' });
  const cwd = process.cwd();
  const securedTools = sage.wrapToolsWithSecurity(runtime.createCodingTools(cwd));

  // Pseudo host API: register definitions as custom tools before session creation.
  runtime.registerCustomTools([...securedTools, ...sage.customTools]);
  const { session } = await runtime.makeSession({
    cwd,
    model: runtime.model,
    noTools: 'builtin',
  });
  const dispose = sage.setupHooks(session);
  return {
    session,
    dispose: async () => { dispose(); await sage.mcpBridge.stop(); },
  };
}
```

A plugin host may name `registerCustomTools` differently; use its own custom-tool
registration API. Do not put definitions in a `tools` option.

## Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `SAGE_BIN` | `sage` | Path to Sage CLI |
| `SAGE_PROFILE` | — | Sage config profile (for example `testnet`) |
| `SAGE_SECURITY_HOOKS` | `1` | Enable pre/post-tool security scanning |
| `SAGE_RLM_FEEDBACK` | `1` | Enable prompt/response capture and native-use receipts |
| `SAGE_SHOW_HOOK_MESSAGES` | `0` | Display SessionStart hook messages in the chat UI |
| `SAGE_ALLOW_BASH_CLI` | `1` | Allow direct `sage ...` bash calls |
| `SAGE_AUTO_RESOLVE_SKILLS` | `1` | Resolve skills explicitly named in subagent tasks |
| `SAGE_INJECT_TOOL_DOCS` | `1` | Add compact Sage tool guardrails each turn |

### Deprecated Low-Level Compatibility

`suggestLimit`, `suggestDebounceMs`, and `enableProvision` remain exported in
`SageP2Config` for low-level legacy callers. The default Pi path ignores them;
do not use them in new configuration. `sageInjectSuggestion(...)` is likewise
a deprecated no-op in 0.4.

## Project Config

For monorepo development, keep Pi thin and point it at the curated Sage Pi
export surface:

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