Pi 코딩 에이전트 (coding agent)를 위한 확장 기능으로, Pi가 관찰 가능한 TUI (Text User Interface) 오버레이에서 대화형 CLI (Command Line Interface)를 자율적으로 실행할 수 있게 해줍니다. 사용자가 지켜보는 동안 Pi가 서브프로세스 (subprocess)를 제어하며, 사용자는 언제든 제어권을 가져올 수 있습니다.
pi-interactive-shell-extension.mp4
interactive_shell({ command: 'vim config.yaml' })
중요: 이 README에 포함된 interactive_shell({...}) 스니펫 (snippets)은 Pi(또는 확장 기능/프롬프트 작성자)가 수행하는 도구 호출 (tool calls)입니다. 최종 사용자가 이를 채팅창에 직접 입력하지 않습니다. 사용자는 Pi에게 무언가를 실행하도록 요청하거나 (예: "dispatch 모드로 실행해줘"), /spawn, /attach, /dismiss 명령어를 사용하십시오.
일부 작업에는 에디터 (editors), REPL (Read-Eval-Print Loop), 데이터베이스 쉘 (database shells), 장시간 실행되는 프로세스 (long-running processes)와 같은 대화형 CLI가 필요합니다. Pi는 다음과 같은 오버레이에서 이를 실행할 수 있습니다:
사용자 관찰 (User watches) - 실시간으로 정확히 무엇이 일어나고 있는지 확인
사용자 제어 (User takes over) - 무엇이든 입력하여 제어권을 획득
에이전트 모니터링 (Agent monitors) - 상태를 쿼리 (query)하고, 입력을 보내며, 종료 시점을 결정
다음과 같은 모든 CLI와 함께 작동합니다: vim, htop, psql, ssh, docker logs -f, npm run dev, git rebase -i 등.
pi install npm:pi-interactive-shell
interactive-shell 기술 (skill)은 자동으로 ~/.pi/agent/skills/interactive-shell/에 심볼릭 링크 (symlinked)됩니다.
요구 사항: Node.js. PTY (Pseudo-Terminal) 지원은 zigpty 사전 빌드된 바이너리 (prebuilt binaries)를 사용합니다 (지원되는 플랫폼에서는 node-gyp 툴체인 (toolchain)이 필요하지 않음).
| 모드 (Mode) | 에이전트 대기 여부? | 출력이 에이전트에 도달하는 방식 | 적합한 용도 |
|---|
| Interactive (기본값) | 예 — 종료될 때까지 차단 (blocks) | 도구 반환 값 (Tool return value) | 에디터, REPL, SSH — 즉시 결과가 필요한 경우 |
| Hands-free | 아니요 | sessionId로 폴링 (Poll) | 개발 서버, 빌드 — 진행 상황을 지켜보고 후속 명령을 보내고 싶은 경우 |
| Dispatch | 아니요 | triggerTurn을 통한 완료 알림 | 서브에이전트 (subagents)에게 작업 위임 — 실행 후 망각 (fire and forget) |
| Monitor | 아니요 | 구조화된 모니터 트리거 이벤트에 대한 알림 | 와처 (Watchers), 로그, 테스트 및 상태 확인 — 특정 상황이 발생했을 때만 깨어남 |
Interactive — 오버레이가 열리고, 사용자가 세션을 제어하며, 에이전트는 세션이 닫힐 때까지 기다립니다. 에디터(vim) 등에 사용하십시오.
), 데이터베이스 쉘 (psql)
), 또는 에이전트가 최종 결과를 즉시 받아야 하는 모든 작업에 적합합니다.
Hands-free — 오버레이가 열리지만 즉시 닫힙니다. 에이전트는 sessionId를 사용하여 주기적으로 폴링 (polling)하며 상태를 확인하고 새로운 출력을 가져옵니다. 실행 도중 반응(입력 전송, 로그 확인, 완료 시 종료 등)이 필요한 장시간 실행되는 빌드 또는 개발 서버에 유용합니다.
Dispatch — 즉시 반환됩니다. 폴링 (polling)은 없습니다. 에이전트는 세션이 완료될 때(자연 종료, 타임아웃, 정적 상태 감지 또는 사용자 종료)에만 triggerTurn을 통해 깨어납니다. 알림에는 출력의 마지막 부분(tail)이 포함됩니다. 이는 서브 에이전트 (subagents)에게 작업을 위임할 때 사용하는 기본값입니다. 오버레이를 완전히 건너뛰려면 background: true를 추가하십시오.
Monitor — 즉시 반환됩니다. 폴링 (polling)도, 완료 알림도 없습니다. 에이전트는 설정된 모니터 트리거 (monitor trigger)가 이벤트를 발생시킬 때 깨어납니다. 스트림 트리거 (stream triggers), 폴링 차이 체크 (poll-diff checks), 퍼스트 클래스 파일 와칭 (first-class file watching), 선택적 쿨다운 (cooldowns), 지속성 제어 (persistence controls), 탐지 명령 (detector commands) 및 이벤트 이력 쿼리 (event history queries)를 지원합니다. 헤드리스 (headless)로 실행되며, 필요한 경우 검사를 위해 연결(attach)할 수 있습니다.
아래 예시는 에이전트 측의 도구 호출 (tool calls)을 보여줍니다. 이는 최종 사용자를 위한 채팅 명령이 아닙니다.
Pi, Codex, Claude 및 Cursor의 경우, 에이전트는 명령 문자열을 수동으로 만드는 대신 구조화된 스폰 파라미터 (structured spawn params)를 사용할 수 있습니다:
// 사용자: "파일을 대화형으로 편집할 수 있도록 pi를 스폰(spawn)해줘"
interactive_shell({ spawn: { agent: "pi" }, mode: "interactive" })
// 사용자: "이 리팩토링 작업을 codex에게 위임하고 완료되면 알려줘"
...
구조화된 spawn은 사용자용 /spawn 명령과 동일한 리졸버 (resolver) 및 설정 기본값을 사용합니다. 임의의 CLI 및 사용자 정의 실행 문자열을 위해 원시 command 방식도 여전히 지원됩니다.
Codex의 이미지 또는 디자인 작업의 경우, Codex는 프롬프트에서 직접 gpt-image-2를 호출할 수 있습니다. 일반적으로 자연어만으로도 충분하며, 필요한 경우 $imagegen을 사용하여 이미지 생성 도구를 강제할 수 있습니다. 편집 및 반복 작업을 위해 -i를 사용하여 참조를 첨부하십시오. 번들로 포함된 codex-cli를 참조하십시오.
구체적인 예시를 위한 skill입니다. Cursor CLI 전용 명령 참조를 보려면 선택 사항인 examples/skills/cursor-cli skill을 확인하십시오. Cursor의 structured spawn은 --model composer-2-fast를 기본값으로 설정하며, 이는 Cursor의 Composer 2 Fast 모델을 명시적으로 선택합니다.
// 사용자가 말함: "vim으로 package.json을 여세요"
interactive_shell({ command: 'vim package.json' })
// 사용자가 말함: "postgres 데이터베이스에 연결하세요"
...
오버레이(overlay)가 닫힐 때까지 에이전트(agent)의 턴은 차단됩니다. 사용자가 세션을 직접 제어합니다.
// 장기 실행 프로세스 시작
interactive_shell({
command: 'npm run dev',
...
사용자가 지켜볼 수 있도록 오버레이가 열립니다. 에이전트는 주기적으로 체크인(check in)합니다. 사용자는 무엇이든 입력하여 제어권을 가져올 수 있습니다. 모니터링 중인 hands-free 또는 dispatch 세션의 제어권을 가져온 후에는 Ctrl+G를 눌러 에이전트에게 제어권을 돌려주십시오.
// 사용자가 말함: "auth 모듈 리팩토링을 pi에게 위임하고 완료되면 나에게 알려줘"
interactive_shell({
command: 'pi "Refactor the auth module"',
...
세션이 완료되면 에이전트는 새로운 턴에서 간결한 알림을 받습니다:
Session calm-reef completed successfully (5m 23s). 847 lines of output.
Step 9 of 10
Step 10 of 10
...
알림에는 짧은 꼬리 부분(마지막 5줄)과 재연결(reattach) 지침이 포함됩니다. PTY는 5분 동안 보존되므로 에이전트가 전체 스크롤백(scrollback)을 검토하기 위해 연결할 수 있습니다.
Dispatch는 autoExitOnQuiet: true를 기본값으로 사용합니다. 즉, 세션에 15초의 시작 유예 기간(startup grace period)이 주어지며, 그 후 출력이 조용해지면(기본값 8초) 종료됩니다. 이는 작업 지향적 서브 에이전트(subagents)에게 완료 신호를 보냅니다. handsFree: { gracePeriod: 60000 }를 사용하여 유예 기간을 조정하거나, handsFree: { autoExitOnQuiet: false }를 사용하여 이 기능을 완전히 제외할 수 있습니다.
오버레이는 여전히 사용자에게 표시되며, 사용자는 Ctrl+T로 출력을 전송하거나, Ctrl+B로 백그라운드로 보내거나, 직접 타이핑하여 제어권을 가져오거나, Ctrl+Q로 더 많은 옵션을 선택할 수 있습니다. Ctrl+G는 사용자가 모니터링 중인 hands-free 또는 dispatch 세션의 제어권을 가져온 후에만 의미가 있습니다.
// 오버레이 없음 — 완전히 보이지 않게 실행됨
interactive_shell({
command: 'pi "Fix all lint errors"',
...
단일 인터랙티브 오버레이 (interactive overlay)와 함께 여러 개의 헤드리스 디스패치 (headless dispatches)를 동시에 실행할 수 있습니다. 이것이 서브에이전트 (subagent) 작업을 병렬화하는 방법입니다. 즉, 세 개의 백그라운드 디스패치를 실행하고 각 완료 알림 (completion notification)이 도착할 때마다 결과를 처리하는 방식입니다.
이 예시들은 **에이전트 도구 호출 (agent tool calls)**입니다. 최종 사용자는 자연어(예: "내 테스트를 감시하고 실패 시 알려줘")로 요청해야 하며, Pi는 모니터 설정 (monitor config)과 함께 interactive_shell을 호출해야 합니다.
모니터 트리거 (monitor triggers)가 이벤트를 방출할 때 에이전트를 깨우십시오. 폴링 (polling)이나 프로세스 완료를 기다릴 필요가 없습니다.
// 사용자가 말함: "내 테스트를 감시하고 실패나 에러가 발생하면 알려줘"
interactive_shell({
command: 'npm test --watch',
...
모니터 모드 (Monitor mode)는 구조화된 페이로드 (structured payloads) (sessionId, eventId, timestamp, strategy, triggerId, matchedText, lineOrDiff, stream)를 방출하며, 이제 모니터가 중단될 때 (스트림 종료, 스크립트 실패, 중단 또는 타임아웃) 라이프사이클 알림 (lifecycle notifications)도 방출합니다. 구조화된 monitor 객체를 사용하는 방향으로 개선되면서 monitorFilter는 제거되었습니다.
interactive_shell({ monitorStatus: true, monitorSessionId: "calm-reef" })
interactive_shell({ monitorEvents: true, monitorSessionId: "calm-reef" })
interactive_shell({ monitorEvents: true, monitorSessionId: "calm-reef", monitorSinceEventId: 42 })
...
모니터 세션 (Monitor sessions)은 헤드리스 (headless)로 실행되며 다른 백그라운드 세션(listBackground, /attach, dismissBackground)과 같이 관리할 수 있습니다.
깔끔하게 종료되지 않는 TUI 앱의 출력을 캡처하십시오:
interactive_shell({
command: "htop",
mode: "hands-free",
...
실행 후 잊어버리는 방식 (fire-and-forget)의 단일 작업 위임의 경우, 출력이 8초 동안 없을 때 세션을 종료하도록 자동 종료 (auto-exit)를 활성화하십시오:
interactive_shell({
command: 'pi "Fix the bug in auth.ts"',
mode: "hands-free",
...
15초의 시작 유예 기간 (startup grace period)은 서브프로세스 (subprocess)가 출력을 생성할 시간을 갖기 전에 세션이 종료되는 것을 방지합니다. gracePeriod를 통해 호출마다 이를 커스텀할 수 있습니다.
:
interactive_shell({
command: 'pi "Run the full test suite"',
mode: "hands-free",
...
기본 유예 기간은 설정 파일의 autoExitGracePeriod를 통해 전역적으로도 구성할 수 있습니다.
상호 주고받는 상호작용이 필요한 멀티 턴 (multi-turn) 세션의 경우, 이를 비활성화된 상태(기본값)로 두고 작업이 완료되었을 때 kill: true를 사용하세요.
// 텍스트 전용 (텍스트를 입력하지만 제출하지는 않음)
interactive_shell({ sessionId: "calm-reef", input: "SELECT * FROM users;" })
// 텍스트를 입력하고 Enter를 누름
...
pi와 같은 에디터 기반 TUI (Text User Interface)의 경우, 원시 input은 텍스트만 입력합니다. 프롬프트를 제출하지는 않습니다. \n에 의존하는 대신 submit: true 또는 inputKeys: ["enter"]를 사용하는 것을 권장합니다.
// 기본값: 20줄, 5KB
interactive_shell({ sessionId: "calm-reef" })
// 더 많은 줄 (최대: 200줄)
...
서브에이전트 (subagent)가 작업을 마치면, Ctrl+T를 눌러 해당 출력을 캡처하고 메인 에이전트 (main agent)로 직접 전송할 수 있습니다:
[서브에이전트 작업 완료]
↓
[Ctrl+T 누름]
...
그러면 메인 에이전트는 컨텍스트 (context) 내에 서브에이전트의 응답을 갖게 되며, 해당 정보를 바탕으로 작업을 계속할 수 있습니다.
설정 (Configuration):
transferLines: 캡처할 최대 줄 수 (기본값: 200)
transferMaxChars: 최대 글자 수 (기본값: 20KB)
세션은 사용자에 의해 (Ctrl+B, 또는 Ctrl+Q → "Run in background") 또는 에이전트에 의해 백그라운드로 전환될 수 있습니다:
// 에이전트가 활성 세션을 백그라운드로 전환
interactive_shell({ sessionId: "calm-reef", background: true })
// → 오버레이가 닫히고 프로세스는 계속 실행됨
...
모니터 세션 (Monitor sessions)도 동일하게 작동합니다. 이들은 완료 시점이 아닌 모니터 이벤트 발생 시 깨어나는 헤드리스 (headless) 백그라운드 세션입니다.
사용자는 또한 /spawn을 통해 설정된 기본 스폰 에이전트 (default spawn agent)를 실행하거나, /spawn codex, /spawn cursor, /spawn claude, /spawn pi, /spawn fork, 또는 /spawn pi fork를 실행할 수 있습니다. --worktree를 추가하세요.
별도의 git worktree에서 스폰하려면, 예를 들어 /spawn cursor --worktree, /spawn codex --worktree, 또는 /spawn pi fork --worktree를 실행할 수 있습니다. 일반적인 /spawn cursor는 정상적인 대화형 오버레이 (interactive overlay) 상태를 유지합니다. fork는 Pi 전용입니다. Worktree는 그대로 유지되며, 오버레이가 생성된 위치를 알려줍니다. /attach 또는 /attach <id>를 사용하면 다시 연결 (reattach)할 수 있고, /dismiss 또는 /dismiss <id>를 사용하면 채팅에서 정리합니다. 키보드 스폰 단축키는 /spawn과 별개이며 spawn.shortcut을 사용합니다.
따옴표로 묶인 프롬프트 텍스트에 --hands-free 또는 --dispatch를 추가하면, /spawn은 단순한 대화형 오버레이 대신 모니터링되는 위임 실행 (monitored delegated run)으로 전환됩니다. 이는 구조화된 interactive_shell({ spawn: ... })와 동일한 리졸버 (resolver) 및 기본값을 공유합니다. 일반적인 /spawn은 대화형 (interactive) 상태를 유지합니다. Ctrl+G는 이러한 모니터링 세션 중 하나를 사용자가 제어하기 시작한 후에만 적용됩니다.
/spawn cursor "review the diffs" --dispatch
/spawn claude "review the diffs" --dispatch
/spawn codex "fix the failing tests" --hands-free
...
| 키 | 동작 |
|---|
| Ctrl+T | 전송 및 종료 (Transfer & close) - 출력을 캡처하여 메인 에이전트 (main agent)로 전송 |
| ... | |
설정 파일 (프로젝트 설정이 전역 설정을 덮어씁니다):
전역 (Global): ~/.pi/agent/interactive-shell.json
프로젝트 (Project): .pi/interactive-shell.json
단축키 설정은 시작 시 고정됩니다. focusShortcut 또는 spawn.shortcut을 변경한 경우, 이를 적용하려면 Pi를 다시 로드하거나 재시작하십시오.
{
"overlayWidthPercent": 95,
"overlayHeightPercent": 60,
...
}