첫 대화
두 번째 턴이 필요하거나, 스트리밍이 필요하거나, 권한을 직접 처리해야 한다면 Command를 열어 들고 있으면 됩니다.
import { Claude, Command, AssistantEvent } from 'activecli';
const command = Command.open(Claude, { workingDir: '/proj' });
command.subscribe((event) => { if (event instanceof AssistantEvent) process.stdout.write(event.text);});command.onPermission((request) => request.approve());
await command.setMessage('Find the bug').send();await command.setMessage('Now fix it').send();
command.close();네 가지 일이 일어납니다
섹션 제목: “네 가지 일이 일어납니다”여기서 일어나는 일 중 이름을 붙여둘 만한 것이 넷 있습니다.
| 호출 | 하는 일 |
|---|---|
Command.open(Claude, …) |
세션 id를 발급하고 의도를 기술합니다. 프로세스는 시작되지 않습니다. |
subscribe / onPermission |
아무것도 실행되기 전에 등록되므로, 첫 이벤트를 놓칠 수 없습니다. |
setMessage(…) |
축적합니다. this를 반환하므로 체이닝됩니다. |
send() |
필요하면 spawn한 뒤 턴을 씁니다. 무언가가 CLI에 닿는 유일한 지점입니다. |
두 번째 send()는 프로세스를 재사용합니다
섹션 제목: “두 번째 send()는 프로세스를 재사용합니다”두 번째 send()는 실행 중인 프로세스를 재사용합니다. 새로 spawn되는 경우는, 실행 중인 CLI를 설득해서는 바꿀 수 없는 무언가가 바뀌었을 때뿐입니다 — 다른 provider이거나, spawn 시점 플래그인 permission mode입니다.
전체를 합치면
섹션 제목: “전체를 합치면”import { Claude, Command, AssistantEvent, ResultEvent } from 'activecli';
const command = Command.open(Claude, { workingDir: process.cwd(), permissions: 'ask-before-edit', model: 'opus',});
command.subscribe((event) => { if (event instanceof AssistantEvent && event.hasText()) { process.stdout.write(event.text); } if (event instanceof ResultEvent && event.raw['subtype'] !== 'success') { console.error('turn did not finish cleanly:', command.session?.diagnostics); }});
command.onPermission((request) => request.subtype === 'can_use_tool' ? request.approve() : request.deny('not allowed here'),);
await command.setMessage('Summarise this repository').send();await command.setAttachment('src/index.ts').setMessage('Now explain this file').send();
const sessionId = command.sessionId; // 나중에 Command.resume(sessionId, Claude)로 이어감command.close();다음으로 볼 것
섹션 제목: “다음으로 볼 것”- 권한 요청에 답하기 —
onPermission이 실제로 결정하는 것. - 첨부 —
setAttachment가 메시지에 무엇을 하는지. - 세션 생명주기 — 재개, 인터럽트, 종료.