Nothing runs until send()
This is the arrangement borrowed from ActiveRecord, and the reason the rest of the API can be as plain as it is.
const command = Command.open(Claude, { workingDir: '/proj' });
command.setModel('opus').setPermissions('plan').setMessage('Plan the migration');
command.toArgv();// ['-p', '--output-format', 'stream-json', '--input-format', 'stream-json',// '--verbose', '--include-partial-messages', '--permission-prompt-tool', 'stdio',// '--session-id', '…', '--permission-mode', 'plan', '--model', 'opus']
command.toPayload();// { type: 'user', message: { role: 'user', content: 'Plan the migration' } }
console.log(command.inspect());// provider: claude// command: claude -p --output-format stream-json …// stdin: {"type":"user","message":{"role":"user","content":"Plan the migration"}}// model: opus// permissions: plan// attachments: 0// workingDir: /proj// session: 3f2a… (not started)Setting things: two ways, on purpose
Section titled “Setting things: two ways, on purpose”Every property has both an assignment and a set-prefixed method. The setter returns this, so intent can be chained; the assignment is there for when chaining would only add noise.
command.model = 'opus';command.setModel('opus').setPermissions('ask-before-edit').setMessage('…');| Property | Setter | Notes |
|---|---|---|
message |
setMessage(text) |
The turn that will be sent next. |
model |
setModel(name | null) |
null leaves the CLI’s own choice alone. |
permissions |
setPermissions(mode | name | null) |
An unknown name throws rather than being ignored. |
provider |
setProvider(provider) |
Takes effect at the next send(). |
attachments |
setAttachment(one) / setAttachments(many) |
Singular replaces; cleared after send(). |
Switching provider mid-conversation
Section titled “Switching provider mid-conversation”command.provider = Codex; // takes effect at the next send()A CLI process cannot become another one, so switching means replacing the process. There is no reason to pay for that until there is something to run — which is exactly why saying it costs nothing.
When send() spawns again
Section titled “When send() spawns again”send() reuses the running process wherever it can. A new one is spawned only when something changed that a running CLI cannot be talked out of:
- a different provider — a process cannot become another program;
- a different permission mode —
--permission-modeis a spawn-time flag with no documented way to change it in place.
Everything else — a new model, a new message, new attachments — travels over the existing process.
Where to go next
Section titled “Where to go next”- Permission modes — why a mode change is a respawn.
- Attachments — what
send()clears, and why. - Reference: Command — every property and method in one place.