Skip to content

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)

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().
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.

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-mode is 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.