Prompt handoff
botctl supports both direct TUI prompt execution and SQLite-backed prompt handoff through Claude's external-editor flow.
Prompt paths
There are four supported paths:
-
TUI-backed one-shot execution
promptlaunches Claude in a new detached tmux session, waits forChatReady, pastes the resolved prompt into the interactive TUI through tmux, waits for the reply, and prints only assistant text to stdout. Pass--verbosefor launch/wait progress on stderr. Arguments after--pass through to Claude.- Small inputs are pasted directly; inputs larger than
--large-prompt-thresholdare written to a state-dir instruction file and Claude receives a short prompt pointing at that file.
-
Manual staging
prepare-promptwrites the prompt text to a workspace-scoped placeholder instance in the state database.editor-helperreads that pending prompt from SQLite and writes it into the editor target path that Claude requested.
-
One-shot submission to an existing pane
submit-prompt --text ...orsubmit-prompt --source ...resolves the prompt text itself, stages it in the state database, and submits it.
-
Loop submission
keep-goinguses the built-in audit loop prompt by default.keep-going --source ...orkeep-going --text ...stages a custom loop prompt in SQLite instead.
State directory
The default state root is $XDG_STATE_HOME/botctl when XDG_STATE_HOME is set and non-empty. Otherwise, botctl uses ~/.local/state/botctl.
--state-dir PATH overrides that root for commands that support it.
Relevant stateful commands now bootstrap <state-dir>/state.db, run any supported schema migrations, and ensure the workspace, instance, and prompt-handoff tables used for staged prompts exist.
Prompt handoff now uses the pending_prompts table inside <state-dir>/state.db, keyed by botctl instance identity. Manual prompt prep creates a placeholder instance for the selected workspace and session name, and one-shot submission promotes or attaches the prompt to the live pane instance.
Commands that support --workspace PATH|UUID accept either a botctl workspace id or a path. Path values may be absolute or relative; Git-backed paths collapse to the canonical worktree root, while non-Git paths use the resolved path itself as the workspace root.
The external editor target that Claude requests is still a regular file, but the staged prompt itself is no longer stored under a separate prompt path.
prompt
prompt accepts repeated --source, one --text, explicit --stdin, implicit piped stdin, and repeated --append-system-prompt. It combines those inputs before launching Claude so input and filesystem errors fail early.
For large combined prompts, it creates <state-dir>/prompt-runs/.../instructions.md and pastes a short file-pointer prompt into Claude. Unless --keep-temp is set, the temp instruction file is removed after a successful response; with --keep-temp, the path is reported on stderr for debugging.
prepare-prompt
prepare-prompt accepts either --text or --source and writes the resolved content to the selected workspace/session placeholder instance.
Use this when you want to stage content before the editor handoff begins.
editor-helper
editor-helper is the bridge from staged prompt to Claude's editor target.
- with
--source, it writes that source text directly to the target file - without
--source, it copies the pending prompt for the selected workspace/session into the target file - by default it consumes the pending prompt record after copying
--keep-pendingleaves the staged prompt record in place
submit-prompt
submit-prompt ultimately submits from ChatReady, but it can auto-dismiss SurveyPrompt first as a preflight recovery step.
It will:
- validate the target pane is Claude-owned
- optionally run a preflight recovery workflow when Claude is sitting in a supported intermediate state such as
SurveyPrompt - stage the prompt in the instance-backed state database
- send the submit sequence from the user's keybindings
- verify that the pane actually transitioned after submission
If the pane does not show a prompt-submission transition, the command fails rather than assuming success.