#2352: feat(cli): CLI feature parity phase 2 - usage tracking and streaming (AI-assisted)
app: web-ui
gateway
agents
size: XL
Cluster:
Session Management and Fixes
## Summary
This PR continues CLI backend improvements from #1921, adding accurate token usage tracking and real-time streaming support.
### Concurrency Hardening
Fixes race conditions in CLI transcript writes:
- Uses `{ flag: 'wx' }` for atomic file creation (TOCTOU fix)
- Adds session-level locking for concurrent-safe writes
- New async API: `appendMessageToTranscriptAsync`, `appendAssistantMessageToTranscriptAsync`
- Tests for partial failure (orphaned user message) and concurrent writes
### Token Usage Tracking
> ⚠️ **WIP:** Token display is improved but not fully resolved - some edge cases remain
Fixes incorrect token display in UI (showed 558k/200k when actual was ~120k):
- Adds `usage` parameter to `appendMessageToTranscript` functions
- Passes `result.meta.agentMeta?.usage` when persisting assistant messages
- Creates `CliSessionManager` class with SDK-aligned API for future use
- Transcript entries now contain actual input/output/cache token counts
### Configurable Usage Fields
Enables per-backend token field parsing:
- Adds `usageFields` config to `CliBackendConfig`
- Handles different API response formats (Anthropic vs OpenAI field names)
- Correctly parses `cache_creation_input_tokens` (previously missed)
- Maintains backwards compatibility via fallback defaults
### Streaming NDJSON Support
> ⚠️ **TODO:** Non-streaming path (`streaming: false`) is currently broken - needs fix before merge
Adds real-time output for CLI backends:
- New `cli-runner/streaming.ts` module with readline-based NDJSON parsing
- Emits events as they arrive instead of waiting for full response
- Config options: `streaming?: boolean`, `streamingEventTypes?: string[]`
- Event mapping for Claude CLI (`text`, `tool_use`, `result`) and Codex CLI (`item.*`, `turn.*`)
- Debug logging throughout pipeline for production diagnostics
### Reply Directives for Streaming
Matches embedded flow's text processing:
- Applies `parseReplyDirectives` to streaming text events
- Extracts media URLs, cleans directives, computes delta from cleaned text
## Test plan
- [x] Unit tests for CliSessionManager (17 tests)
- [x] Unit tests for session-utils.fs usage parameter
- [x] Unit tests for CLI streaming module
- [x] Unit tests for agent-runner-execution CLI persistence
- [x] Tested locally with claude-cli backend - tokens display improved
- [x] Verified streaming events emit in real-time
- [ ] **TODO:** Fix and test non-streaming path
- [ ] **TODO:** Verify token display edge cases resolved
## AI-assisted
This PR was developed with AI assistance (Claude). The code has been tested locally with a live Clawdbot instance. I understand what all the code does.
Most Similar PRs
#23720: Feat/cli backend runtime tuning
by wanmorebot · 2026-02-22
74.5%
#11996: fix: CLI backend JSON array parsing and clearEnv merge
by shanemmattner · 2026-02-08
72.6%
#23700: feat: Claude CLI personal-use auth (no API key required) + native A...
by 88plug · 2026-02-22
72.3%
#18670: feat: add first-class Claude Code CLI auth path + CLI model UX hard...
by SmithLabsLLC · 2026-02-16
71.9%
#14483: fix(cli-runner): map Anthropic cache_creation_input_tokens
by AlexAnys · 2026-02-12
68.7%
#23175: feat(security): runtime safety — transcript retention, tool call bu...
by ihsanmokhlisse · 2026-02-22
68.2%
#12384: feat(cli): add --stream-json flag for live NDJSON streaming
by kumarabhirup · 2026-02-09
67.6%
#6611: fix(webchat): persist assistant messages for CLI backends
by JorgeAlan · 2026-02-01
67.4%
#16099: feat: add opencode-cli as CLI backend provider
by imwxc · 2026-02-14
67.2%
#19136: feat(claude-code): implement spawn mode for Claude Code sub-agents
by botverse · 2026-02-17
67.0%