테마 전환

확장(extension)은 Pi의 동작을 확장하는 TypeScript 모듈입니다. 라이프사이클 이벤트를 구독하고, LLM이 호출할 수 있는 커스텀 도구를 등록하고, 명령을 추가하는 등의 일을 합니다. Pi는 "확장은 Pi가 직접 만들 수 있다"고 안내합니다 — 사용 사례에 맞는 확장을 Pi에게 직접 시켜도 됩니다.
확장은 Pi 프로세스 안에서, 같은 OS 권한으로 실행됩니다. 프롬프트, 도구 호출, 파일, 자격 증명, 세션 기록을 들여다볼 수 있으므로 신뢰할 수 있는 출처의 것만 로드해야 합니다.
빠른 시작
~/.pi/agent/extensions/my-extension.ts를 만듭니다.
typescript
import { type ExtensionAPI, isToolCallEventType } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";
export default function (pi: ExtensionAPI) {
// 이벤트 수신
pi.on("session_start", async (_event, ctx) => {
ctx.ui.notify("Extension loaded!", "info");
});
// 도구 호출 가로채기: 위험 명령 확인
pi.on("tool_call", async (event, ctx) => {
if (isToolCallEventType("bash", event) && event.input.command.includes("rm -rf")) {
const ok = await ctx.ui.confirm("Dangerous!", "Allow rm -rf?");
if (!ok) return { block: true, reason: "Blocked by user" };
}
});
// 커스텀 도구 등록
pi.registerTool({
name: "greet",
label: "Greet",
description: "Greet someone by name",
parameters: Type.Object({
name: Type.String({ description: "Name to greet" }),
}),
async execute(toolCallId, params, signal, onUpdate, ctx) {
return {
content: [{ type: "text", text: `Hello, ${params.name}!` }],
details: {},
};
},
});
// 명령 등록
pi.registerCommand("hello", {
description: "Say hello",
handler: async (args, ctx) => {
ctx.ui.notify(`Hello ${args || "world"}!`, "info");
},
});
}-e 플래그로 빠르게 시험할 수 있습니다. 정식 배치는 자동 탐색 위치, 즉 전역은 ~/.pi/agent/extensions/, 프로젝트는 .pi/extensions/에 두고 /reload로 핫 리로드하는 방식입니다.
bash
pi -e ./my-extension.ts확장으로 할 수 있는 것
공식 문서가 나열하는 주요 능력입니다.
| 능력 | 설명 |
|---|---|
| 커스텀 도구 | pi.registerTool()로 LLM이 호출하는 도구 등록 |
| 이벤트 가로채기 | 도구 호출 차단·수정, 컨텍스트 주입, 압축 커스터마이징 |
| 사용자 상호작용 | ctx.ui의 select·confirm·input·notify |
| 커스텀 UI | ctx.ui.custom()으로 키보드 입력을 받는 TUI 컴포넌트 |
| 커스텀 명령 | pi.registerCommand()로 /mycommand 등록 |
| 세션 영속 상태 | pi.appendEntry()로 재시작을 버티는 상태 저장 |
| 커스텀 렌더링 | 도구 호출·결과·메시지의 터미널 표시 제어 |
| 제공자·MCP | 모델 제공자, 가상 모델, MCP 서버 등록 |
문서가 제시하는 활용 예시도 눈여겨볼 만합니다: rm -rf 같은 위험 명령 사전 확인(권한 게이트), 턴마다 stash하는 git 체크포인트, .env·node_modules/ 쓰기 차단(경로 보호), 나만의 방식의 대화 요약 압축, 질문 마법사·다이얼로그 같은 대화형 도구, todo 리스트처럼 상태를 기억하는 도구, 파일 watcher·웹훅 연동, 심지어 기다리는 동안 하는 게임(snake 예시)까지 있습니다.
저장소의 예제 확장
레포의 packages/coding-agent/examples/extensions/에는 동작하는 구현체가 모여 있습니다. 일부만 옮겨 보면:
| 예제 | 내용 |
|---|---|
permission-gate.ts | 도구 호출 확인 게이트 |
protected-paths.ts | 특정 경로 쓰기 차단 |
git-checkpoint.ts | 턴별 git 체크포인트 |
auto-commit-on-exit.ts | 종료 시 자동 커밋 |
custom-footer.ts, custom-header.ts | 커스텀 헤더·푸터 UI |
custom-compaction.ts | 커스텀 압축 |
dynamic-tools.ts | 동적 도구 로딩 |
file-trigger.ts | 파일 변경 트리거 |
project-trust.ts | 프로젝트 신뢰 판정 처리 |
confirm-destructive.ts | 파괴적 작업 확인 |
custom-provider-anthropic/ | 커스텀 제공자 구현 |
예제들은 라이프사이클 이벤트 핸들러, 커스텀 도구, 명령과 단축키, 커스텀 UI, git 연동, 시스템 프롬프트 수정, 외부 연동, 커스텀 제공자 등 주요 주제를 망라합니다.
어디에 두고 어떻게 로드하나
| 위치 | 범위 |
|---|---|
~/.pi/agent/extensions/ | 사용자 전역 |
.pi/extensions/ | 프로젝트(신뢰 허용 후 로드) |
settings의 extensions 배열, Pi 패키지 | 설정으로 지정 |
pi -e ./path.ts | 한 번의 실행(신속한 시험용) |
설정이나 -e로 지정한 확장도 /reload로 다시 읽힙니다. 확장 내부에서 사용할 수 있는 import(@earendil-works/pi-coding-agent의 타입과 헬퍼, typebox 등)와 이벤트 라이프사이클, ExtensionContext와 ExtensionAPI의 전체 메서드, 도구 노출 제어, 에러 처리, 모드별 동작 차이는 공식 Extensions 문서가 레퍼런스입니다. Pi에게 확장 작성을 시킬 때는 이 문서 경로를 함께 알려 주면 좋습니다.