On this page
#Changelog
#0.14.2
Ships the second machine-local path fix: probe_user_dialogs.py now requires --captures-dir instead of defaulting to an operator scratchpad path.
Context
0.14.1 fixed a cassette privacy leak and added a repo-wide hygiene guard. That guard immediately found a second leak of the same class: scripts/probe_user_dialogs.py hardcoded an absolute operator scratchpad path (including a session UUID) as the default for its captures directory. The fix landed right after 0.14.1 was cut, so the offending path still ships in the 0.14.1 sdist. 0.14.2 exists to get the fixed artifact published.
#Fixes
- A second machine-local path is gone from the published sdist.
scripts/probe_user_dialogs.pydefaulted its capture directory to an absolute path naming the author's account; it is now a required--captures-dirargument. The hygiene guardrail was extended from the recorded cassettes to every git-tracked text file, which is what found it.
#0.14.1
Privacy fix: the published sdist no longer carries the recording machine's paths or private tool inventory.
Context
An audit of the 0.14.0 test infrastructure found that the VCR recorder's scrubber emptied only list-valued inventory keys. memory_paths arrives from the CLI as a dict, so it was copied verbatim and a real /tmp/.../-home-
Scrubbing is now type-agnostic (dict, list, str) rather than list-shaped, the tools inventory is filtered to a public-tool allowlist, and both cassettes were re-recorded through the credential-less free lane (total_cost_usd 0, zero API spend). tests/test_cassette_hygiene.py is the backstop that does not need to know the schema: it greps every committed cassette for home directories, temp directories, $HOME, the operator username as a path segment and absolute-path shapes, so the next unknown protocol key cannot leak silently.
The same audit found the spend guard weaker than advertised, all fixed here and pinned by tests: tests/test_integration.py hardcoded an absolute path to the real binary (the poisoned PATH only intercepts name lookups, so 19 tests were outside the guard); the guard hooks lived in tests/conftest.py, so pytest scripts/ ran unguarded; the opt-in assertion checked only a skip count, which a broken local profile reproduces; and two spend-capable operator scripts in scripts/ were named test_*.py, so pytest collected them.
#Fixes
- Fixed a privacy defect in the published sdist. The 0.14.0 tarball's test cassettes carried the recording machine's filesystem paths and private tool inventory: the recorder scrubbed only list-valued inventory keys, and
memory_pathsarrives as a dict. Scrubbing is now type-agnostic, thetoolsinventory is filtered to a public-tool allowlist, both cassettes were re-recorded, and a hygiene test greps every committed cassette for machine-local shapes.
#0.14.0
Agent definitions are schema-validated at load, the CLI runs on strictcli 0.36, and the test suite can no longer spend money.
Context
This release carries the strictspec at-rest gate for .agent.json documents (a breaking change: an integer format_version is now required), the strictcli 0.36 command-classification migration and its dependency floor, two new documentation guides, and a fix that makes agent discovery report the deprecated budget fields as helpfully as load_agent already did.
Behind that, the test suite changed shape. Integration tests used to drive the real claude binary against a real profile on every full-suite run, so the release gate itself billed a real account. They are now opt-in behind CLAUDESTREAM_INTEGRATION=1, backed by a poisoned PATH shim so nothing else can reach a real binary either, and a recorded-replay (VCR) lane covers the wire protocol -- real subprocess, real pipes, real control round-trips -- from committed cassettes at zero cost.
#Breaking
- Agent definitions are now schema-validated at load.
.agent.jsondocuments loaded viaload_agent/discover_agents/theagentCLI are validated against a strictspec schema before decoding: they now REQUIRE an integerformat_version(currently1), and unknown keys (with did-you-mean hints) or wrong-typed fields are rejected with hardAgentValidationErrors. Stamp existing agent files with"format_version": 1one time.
#Features
- Architecture and agents guides. The documentation site gains a guide to claudestream's four layers and a guide to agent definitions, plus a generated table of every stream event type.
- Fuller CLI help text. Every command and flag description was expanded, so
claudestream <command> --helpexplains what a command does and when to reach for it.
#Fixes
- The CLI works again on strictcli 0.36.0. strictcli made per-command effect classification mandatory, which hard-errored claudestream's command registration --
claudestream --help, every subcommand and any import ofclaudestream._clifailed. All 11 commands are now classified: the six that spawn a Claude Code subprocess aremutating, the five inspection commands areread_only. No command prompts for confirmation. - Agent discovery now explains the deprecated budget fields. A
.agent.jsonstill usingmax_cost_usd,max_turnsormax_tokensreported a generic unknown-key error when found bydiscover_agents(orclaudestream agent list) whileload_agentgave the migration hint. Both paths now name the replacement threshold fields. - Installs can no longer resolve a strictcli too old to run claudestream. The manifest now declares
strictcli>=0.36.0; below that, command registration fails and every CLI invocation errors on import.
#0.13.1
Real-CLI integration tests now skip gracefully when the claude binary or a claudewheel profile is unavailable, so CI and credential-less environments no longer fail the suite.
Context
The 0.13.0 release tagged and pushed successfully but its PyPI and npm publish was blocked because the CI test suite failed on the GitHub runner: the newly scaffolded full-suite CI ran the real-CLI integration tests in a credential-less environment with no claude binary and no claudewheel profiles, and claudewheel 0.22's resolve_profile raises instead of failing soft, turning what should be skips into 20 hard errors. This hotfix adds a shared skip guard so those tests skip gracefully when their external prerequisites are absent, unblocking the publish that the 0.13.0 CI gate held back. bump = hotfix because the change is test-infrastructure only (no user-facing changelog entries).
#Infrastructure
- Real-CLI integration tests now skip gracefully when the claude binary or a claudewheel profile is unavailable, so CI and credential-less environments no longer fail the suite.
#0.13.0
Control-protocol extensions for interactive clients: interrupt, live model and permission-mode switching, context usage, user dialogs, enriched permission prompts, and renderer observability.
Context
These additions power alternative frontends that drive the claude CLI directly. AskUserQuestion is answered by feeding the choice back through a permission updatedInput, so interactive tools resolve without a separate answer channel. A correlation registry tracks pending control requests with restart-safe hard failures, so a dropped or restarted session surfaces an explicit error rather than a silently unresolved future.
#Breaking
- Breaking. Renamed
--no-colorflag to--color(default: true) across all commands. Use--no-colorto disable color output.
#Features
- New feature. Added
__version__attribute to theclaudestreampackage. - Control-request wire structs. New
ControlRequestmessage struct and aControlResponse.errorfield expose the CLI control protocol for interrupt, model, and mode requests. - Control-request correlation. Sessions can issue correlated control requests with pending-future tracking, turn-loop and between-turns response resolution, timeouts, and restart/close safety.
- Interactive session controls.
interrupt(),set_permission_mode(),set_model(), andget_context_usage()are now available on bothAsyncSessionandSyncSession, andSessionConfig.permission_modesets the initial permission mode via--permission-mode. - Dialog and enriched-permission responses. New
DialogCompletedandDialogCancelledmessages answer user dialogs,AllowPermissionacceptsupdated_permissionsto apply permission-rule updates on allow, andInitializeRequestcan declaresupported_dialog_kinds. - Tool-permission prompts now decode correctly. The current Claude CLI sends permission prompts as
can_use_tool; these now surface asPermissionRequest(with new fields likepermission_suggestions,display_name, andrequires_user_interaction) instead of being missed. A newUserDialogRequestevent carries CLI-driven user dialogs. - User-dialog handling on sessions.
respond_dialog()andrespond_dialog_cancelled()answer dialog requests,respond_allow()acceptsupdated_permissions, andSessionConfig.supported_dialog_kindsdeclares which dialogs the consumer can render (forcing the initialize handshake). Available on bothAsyncSessionandSyncSession. - Renderer observability.
ToolResultnow carriestool_name(correlated from the matchingToolUse), andResultexposes per-modelmodel_usagefrom the CLI'smodelUsagepayload. - Permission interception. New
SessionConfig.intercept_permissionsroutes permission prompts and interactive tools like AskUserQuestion to the consumer as PermissionRequest events. - Tool error signal.
ToolResultandToolResultBlocknow exposeis_error, so consumers can distinguish failed tool executions from successful ones.
#Fixes
- Fix.
ToolSchemafieldsdescription,input_schema, andserverare now optional, supporting name-only tool entries.
#0.12.2
Fix liveness probe to use event-based timeout instead of CPU-based polling
#Fixes
- Fix. Liveness probe now uses event-based timeout instead of CPU monitoring, correctly detecting I/O-bound subprocess hangs.
#0.12.1
Fix uv.lock local paths and Usage struct documentation
#Fixes
- Fix. Regenerated uv.lock to resolve dependencies from PyPI instead of local editable paths, fixing CI test failures.
- Fix. Clarified Usage struct docstring to explain context-dependent semantics (per-call vs cumulative).
#0.12.0
Observe-not-limit budget redesign
Context
Budget fields replaced with threshold-based observation. Budget no longer kills sessions -- it emits BudgetThreshold events.
#Breaking
- Breaking. Budget fields
max_cost_usd,max_turns,max_tokensreplaced with threshold-based observation:cost_thresholds,turn_thresholds,token_thresholds. Budget no longer kills sessions — it emitsBudgetThresholdevents when thresholds are crossed.
#Features
- New.
session.total_cost_usdproperty for cumulative session cost tracking. - New.
SessionConfig.cost_log_pathenables per-turn JSONL cost logging with session metadata. - New.
SyncSession.total_cost_usdproperty.
#Fixes
- Fix. Token accumulation no longer double-counts —
usagefields are session-cumulative, not per-turn. - Fix. Pass all
SessionConfigfields through agent invocation merge.
#0.11.0
Transparent subprocess retry and structured logging
Context
Adds automatic subprocess retry on stuck detection and structured logging for liveness probe events.
#Features
- New. Transparent subprocess retry when stuck detection triggers, preventing session hangs.
- New. Structured logging for liveness probe events, subprocess retry, restart, and session start.
#0.10.0
Liveness probe, MCP multi-server handshake fix
#Features
- Liveness check. Subprocess CPU monitoring via psutil detects stuck Claude CLI processes. When the subprocess is alive but at 0% CPU (idle), it is killed and a clear error is raised instead of hanging forever.
#Fixes
- MCP multi-server handshake. Sessions with tools from multiple MCP servers no longer hang. The handshake now waits for all servers to complete tools/list before proceeding.
#0.9.0
#Features
- SyncSession now exposes all 19 AsyncSession properties including turn_count, total_tokens, sandbox, and config.
- SDK-registered MCP tools are now immediately visible to the model without requiring a ToolSearch call.
- Expanded CLI help descriptions for agent subcommands.
#Fixes
- invoke_agent now correctly passes tool_context and inject metadata to MCP tools.
#0.8.0
#Features
- Documentation. README.md and CLAUDE.md are now auto-generated from selfdoc templates with comprehensive examples, architecture narrative, and API reference tables.
#Fixes
- Bug fix. Custom tools registered via
@toolare now visible to the model. The SDK MCP handshake was incomplete -- claudestream now sendsmcp_set_serversafter initialization and handles the full MCP protocol negotiation (initialize, notifications/initialized, tools/list). - Bug fix. MCP handshake unit and integration tests verifying tool registration end-to-end.
#0.7.7
#Features
- **
--from-prCLI flag.** All commands (send, stream, events, repl, ask) now accept--from-prto resume from a PR-linked session.
#0.7.6
#Fixes
- Fixed MCP tool visibility. Tools registered via
@toolare now visible to the Claude Code model. The--permission-prompt-tool stdioflag was missing when MCP tools were registered without sandbox restrictions.
#0.7.5
#Features
- npm package.
npx claudestreamnow works. The npm package is a thin CLI wrapper that shells out to the Pythonclaudestreamcommand.
#0.7.4
#Fixes
- Fixed prompt template false positives.
resolve_prompt()no longer flags{word}patterns that were introduced by variable substitution itself.
#0.7.3
#Features
- Agent discovery from custom paths and packages.
discover_agents()now acceptspaths=for custom directories andpackages=for Python package resources viaimportlib.resources. Deduplicates by name with warnings on conflicts.load_agent()gains acwdparameter for consistent bare name resolution.
#0.7.2
#Features
- Tool context injection.
@tool("server", inject=["ctx"])explicitly declares parameters injected fromSessionConfig.tool_context. Injected params are hidden from the model's schema. Hard error when context is required but missing.
#0.7.1
#Features
- File write tracking. New
FileWriteandFileEditderived events emitted when Claude writes or edits files.session.files_modifiedaccumulates all modified paths with absolute path resolution. - Lifecycle hooks.
on_turn_complete,on_error,on_closehooks for post-turn cleanup, error handling, and session teardown. Supports both sync and async hooks.
#Fixes
- Removed CLI output truncation. Tool results and thinking content are now printed in full, never truncated.
- Editable install version freshness. CLI version now read from
pyproject.tomlat runtime, eliminating stale version after editable install bumps.
#0.7.0
#Breaking
- SessionConfig. Sessions,
print_prompt, andinvoke_agentnow accept a singleSessionConfigstruct instead of individual parameters. - Required fields.
Tool.server,ToolSchema.server, andAgentDefinition.versionno longer have defaults — callers must specify them explicitly. - **Removed
SandboxConfig.**AgentDefinition.sandboxnow usesSandboxdirectly. JSON agent definitions with partial sandbox fields decode correctly.
#Features
- Declarative flag registry. All ~45 Claude CLI flags are now typed ProcessConfig fields with a declarative registry in
build_argv().--verboseand--include-partial-messagesare now configurable. - Expanded exports. Message types, protocol functions, option structs,
BUILTIN_TOOLS,ProcessConfig, andProcessManagernow exported from the top-level package. - **Agent definitions gain
mcpandstreamfields.**AgentDefinitionnow acceptsMcpOptionsandStreamOptionsfor MCP server config and stream behavior. - Budget enforcement.
Budget.max_cost_usdwired to--max-budget-usd. Runtime enforcement ofmax_turnsandmax_tokenswithClaudeStreamErroron exceeded limits. - **Enriched
AskResult.** Now includesnum_turns,duration_api_ms,stop_reason,result,api_error_status, andsubtypefrom the Result event. - Session observability. New properties:
sandbox,user_tools,is_alive,active_turn,cancelled,process_pid,cwd,mcp_servers,permission_mode,config,turn_count,total_tokens.SyncSession.stderr_linesnow available. - Tool decorator expansion.
@toolnow handlesOptional,Literal,Enum,list[dict],dict[str,T], default values, and docstring-based parameter descriptions. Tool results are JSON-serialized for dict/list returns. Newcollect_tools(module)utility. - **Multimodal
send().**send()andask()now acceptstr | listfor content, enabling image blocks and structured content. - **SDK hooks and
HookEvent.** Newhooksparameter onSessionConfigwired toInitializeRequest.HookEventtype for lifecycle events. - Agent discovery.
.claudestream/agents/convention with bare name resolution. Newdiscover_agents()function. CLI commands:agent list,agent info,agent validate. - Configurable constants.
ProcessLimitscontrols buffer size, shutdown timeout, version check timeout, and health timeout.EventPrintertruncation lengths configurable.SyncSessionpoll and join timeouts configurable. - New CLI commands.
claudestream ask(one-shot),claudestream doctor(health check),claudestream config(show resolved config).
#0.6.2
#Fixes
- Stricter agent validation. CLI
agent runnow fails early with a clear message when no model is specified.invoke_agentraisesValueErrorlisting any tools missing handlers.
#0.6.1
#Features
- Session resumption. New
resume_session_idparameter and--resumeCLI flag to continue a previous Claude Code session.
#0.6.0
#Breaking
- Sandbox system. Replaced the Policy system with a unified
SandboxAPI combining tool allow-lists,--baremode, and filesystem write-path scoping.
#Features
- Migrated to msgspec. All event, message, and content block types converted from dataclasses to msgspec Structs for faster parsing and better type validation.
- SDK MCP tool registration. Register custom host-handled tools via
@tooldecorator or explicit schema. Full lifecycle: initialize handshake,tools/list,tools/callwith async/sync handler support. - **
ask()convenience method.** Send a prompt and get back anAskResultwith text, usage, cost, and duration — no manual event collection needed. - Agent definition toolkit. Declarative
AgentDefinitionwith prompt templates, tool schemas, sandbox config, and budget constraints. Load from.agent.jsonfiles. Newclaudestream agent runCLI command.
#0.5.1
#Fixes
- Fix.
--system-promptno longer adds--bare, which was blocking OAuth authentication. Uses--append-system-promptinstead.
#0.5.0
#Breaking
- Breaking.
modelandprofileare now required parameters in the library API (AsyncSession,SyncSession,print_prompt).
#Features
- New feature. SyncSession no longer uses a threading lock. Queue reads have a timeout to prevent infinite blocking. Thread startup uses
threading.Eventinstead of busy-wait. - New feature. All events are now yielded to consumers, including
SystemInitand auto-handledPermissionRequest. No more silent event filtering. - New feature.
session.cancel(force=False)method on bothAsyncSessionandSyncSession. Graceful mode closes stdin; force mode sends SIGTERM. - New feature. All CLI commands now handle every event type.
RateLimit,ApiRetry,Thinking, andPermissionRequestprint to stderr instead of being silently dropped. - New feature.
--system-prompt/-sflag on all CLI commands. - New feature.
--stdinflag onsend,stream, andeventscommands for piped input. - New feature. ANSI color output with TTY auto-detection,
--no-colorflag, andNO_COLORenv var support.
#Fixes
- Fix. Removed unused imports, fixed inconsistent ToolResult truncation, fixed ellipsis always showing on short thinking blocks, added warning for unknown content block types.
#0.4.0
#Breaking
- Breaking.
--profileand--modelare now required flags on all commands. No implicit defaults.
#Features
- New feature.
--footer/--no-footerflag on all commands. Cost and timing metadata now goes to stderr. - New feature. REPL shows actual model name after first response instead of \default\.
#Fixes
- Fix. All CLI commands now handle errors gracefully instead of showing Python tracebacks.
- Fix. Commands no longer silently swallow responses when streaming is unavailable (e.g., authentication errors).
- Fix. Authentication failures now produce an actionable error message instead of silent empty output.
- Fix. Subcommand parse errors now suggest the correct subcommand help (requires strictcli >= 0.8.6).
#0.3.0
#Features
- New feature. Per-event INFO logging for all event types (Thinking, ToolUse, ToolResult, Result, ApiRetry, RateLimit) and a startup health probe that warns after 30s with no events.
#Fixes
- Fix. Drain subprocess stderr to prevent pipe buffer deadlock that caused sessions to hang indefinitely.
- Fix. Parse
rate_limit_eventtype and systemrate_limitsubtype correctly — rate limit events were silently dropped as UnknownEvent.
#0.2.1
#Fixes
- Fix.
sendcommand no longer prints response text twice.
#0.2.0
#Features
- New feature.
--profileflag for claudewheel profile selection — setsCLAUDE_CONFIG_DIRand OAuth token for the Claude subprocess.
#0.1.1
#Fixes
- Fix. Session no longer hangs during initialization -- SystemInit is now captured lazily on first send().
- Fix. Extended thinking responses no longer crash -- increased subprocess readline buffer to 16MB.
#0.1.0
#Features
- Async and sync session APIs (
AsyncSession,SyncSession) for multi-turn conversations with Claude Code - Configurable permission policy system (allow_all, deny_all, allow_builtins, allow_list, custom callbacks)
- CLI with 4 commands:
send,stream,events,repl - Subprocess lifecycle management with graceful shutdown
- One-shot
print_prompt()convenience function for simple use cases - Typed event models for all Claude Code stream-json event types
- Real-time streaming token support via
StreamDeltaevents