# Extension Development Template

Use this template for small repo-local extensions before adding packaging,
dependencies, or distribution metadata.

## Directory Layout

```text
~/.sf/agent/extensions/my-extension/
├── index.ts
├── extension-manifest.json
└── README.md
```

For source-tree development inside this repository, place bundled extensions
under `src/resources/extensions/<extension-id>/` and keep tests next to the
extension's existing test conventions.

## `extension-manifest.json`

```json
{
	"id": "my-extension",
	"name": "My Extension",
	"version": "0.1.0",
	"description": "Adds one focused command or tool.",
	"tier": "project",
	"entry": "index.ts",
	"provides": {
		"tools": ["my_tool"],
		"commands": ["/my-command"],
		"hooks": []
	},
	"dependencies": {
		"extensions": [],
		"runtime": []
	}
}
```

## `index.ts`

```ts
import { Type } from "@sinclair/typebox";
import type {
	ExtensionAPI,
	ExtensionContext,
} from "@mariozechner/pi-coding-agent";

/**
 * Register the extension's command and tool.
 *
 * Purpose: expose one project-specific operation through a typed tool and a
 * human-triggered command.
 *
 * Consumer: SF runtime extension loader.
 */
export default function activate(pi: ExtensionAPI, ctx: ExtensionContext) {
	pi.registerTool({
		name: "my_tool",
		description: "Return a concise project-specific status.",
		parameters: Type.Object({
			label: Type.String({ description: "Status label to display." }),
		}),
		async execute({ label }) {
			return { ok: true, label };
		},
	});

	pi.registerCommand("my-command", {
		description: "Show the current extension status.",
		async run() {
			ctx.ui.notify("My extension is loaded.", "info");
		},
	});
}
```

## Review Checklist

- The extension has one clear purpose and a named production consumer.
- Every tool parameter has a TypeBox schema.
- Persistent state is written under the project `.sf/` tree or the managed
  agent directory, not arbitrary home-directory paths.
- Commands and tools degrade with useful messages when dependencies are missing.
- Tests cover the behavior contract, not only mocks or call counts.
- User-facing environment variables are added to `src/env.ts` and
  `docs/user-docs/configuration.md`.
