Repository navigation
claudestream rewritten in Go: a library of typed Claude Code events with sessions started through claudewheel profile exec, strict TOML agent definitions, and a command line installed with go install or from the release archives. The Python package is no longer published; PyPI and npm keep 0.15.3.
Context
The stricttools projects are moving to Go; the Python and npm releases stop at 0.15.3.
Breaking
- claudestream is now a Go module. The Python package is gone: install the command with
go install github.com/stricttools/claudestream/cmd/claudestream@v0(or from the Linux and macOS archives on each GitHub Release) and the library withgo get github.com/stricttools/claudestream@v0. Nothing newer than 0.15.3 is published to PyPI or npm, and 0.15.3 stays there; Python programs that import claudestream stay on it. - Sessions start Claude Code through claudewheel. Claude Code runs as
claudewheel profile exec --name <profile> -- <claude> ..., so a session needs a claudewheel with theprofile execcommand, and the profile's environment reaches Claude Code from claudewheel rather than from the calling process. The library takes absolute paths of both binaries and never searchesPATH;ResolveOnPathfinds one for a caller that wants that. - The session config is explicit.
Configrequires the model, the profile, both binaries, and the session to use (NewSession,ResumeSession, orContinueLastSession), andConfig.Validaterefuses anything missing or contradictory instead of filling in a default. Tools areToolvalues with an explicit JSON Schema and a handler, replacing the@tooldecorator, its schemas from type hints, and handler injection. The sandbox dropsbare(which passed--bareand disabled token login) andlog_violations; the hooks, the cost log, the tool context, and the poll, join, and stuck timeouts are gone. - One session type, read turn by turn.
Startreturns aSession;Sendreturns aTurnwhoseNextyields typed events untilio.EOF, replacing the async and sync sessions,ask, andprint_prompt. Callbacks and lifecycle hooks are gone, and a session no longer restarts Claude Code when it goes quiet: a wedged turn waits until its context ends, and an authentication failure, a process exit, or a cancelled turn makes the session unusable. - Agent definitions are strict TOML. An agent is
.claudestream/agents/<name>.agent.tomlwithformat_version = 2;.agent.jsonfiles are refused, naming the steps to convert one by hand (keys one to one,format_version = 2, deletebareandlog_violations, give every tool aserver, rename the file). Unknown keys are refused,[sandbox]requiresskip_permissions, and agents are found only in the agents directory of the working directory. - The command line asks for everything it acts on.
ask,stream,send,events, andagent runtake the prompt as--promptor--prompt-from-stdin, and require--profile, one of--new-session,--resume <id>, or--continue-session, and one of--skip-permissionsor--no-skip-permissions.replandconfigare removed (config --profileprinted the profile's token), as aresend --rawand--json-output;agent run --modelis required when the definition declares no model and refused when it declares one, and agents that declare tools are refused.
Features
- Command line additions.
ask --jsonputs the reply and its metadata, including the session ID to resume, in the document's payload;doctor --profilestarts Claude Code through the profile once;--claude-binaryand--claudewheel-binarychoose the programs;--color/--no-colorand--footer/--no-footercontrol the rendering; andsendmarks error tool results, permission decisions, tool calls the session served, and unrecognized frames.
Fixes
- Claude Code never waits for an answer that does not come. A control request the session does not handle, and an MCP message for an unknown server or method, are answered with an error and reported as events; a permission request a sandbox decides is answered and reported as
PermissionDecidedrather than also yielded as a request; and the SDK MCPinitializeanswers with the protocol version Claude Code proposed when it is one claudestream supports. - Every line Claude Code writes reaches the consumer. Non-JSON lines, frames that do not decode, and unknown content blocks become events instead of log warnings;
FileWriteandFileEditfollow a successful tool result rather than the request; the permission mode, MCP server statuses, and authentication failures are read from the keys Claude Code sends; and rate limits are read from both of their shapes. - List options repeat their flag. Several MCP config files, added directories, files, plugin directories or URLs, betas, and allowed tools each get their own flag (
--mcp-config a --mcp-config b) instead of one comma-joined value, which broke a session given more than one MCP config file. - A failed turn fails the command. Every session command exits 1, with the result text on stderr, when Claude Code ends the turn with an error.