Expand description
Cost/token usage ingestion for interactive claude-code sessions.
Ninox launches the real claude CLI interactively inside a tmux pane
(see harness::HarnessRegistry::interactive_cmd/worker_cmd) rather than driving it
through a scripted API, so there is no request/response boundary Ninox
controls where a cost or token count could be captured directly. What
does exist is the CLI’s own on-disk transcript: every turn is appended
as a JSON line to
~/.claude/projects/<escaped-workspace-path>/<claude-session-uuid>.jsonlwhere the directory name is the session’s working directory with every
non-alphanumeric character replaced by -, and each assistant-type
line carries a message.usage object (input_tokens, output_tokens,
cache_creation_input_tokens, cache_read_input_tokens) plus
message.model. Since each Ninox session (orchestrator subdirectory,
standalone worktree, or CLI worker worktree) runs in its own dedicated
workspace directory, that directory is a reliable 1:1 key back to the
session — no ATHENE_SESSION-style attribution needed for this part.
There is no on-disk USD figure to read, so cost is estimated from token counts against a small built-in pricing table. These are rough priors, not live pricing — good enough to answer “is this session burning money” and to seed the spawn-modal’s data-driven estimate, not to reconcile an invoice.
Structs§
- Usage
Snapshot - A snapshot of a workspace’s accumulated
claudeusage, computed by summing every turn recorded in its transcript(s).
Functions§
- claude_
project_ slug - The directory-name
claudederives from a working-directory path: every byte that isn’t an ASCII letter or digit becomes-. - claude_
projects_ dir - Directory Ninox expects
claude’s own per-project transcripts to live under. HonorsNINOX_CLAUDE_PROJECTS_DIRas a test/override seam (mirrorsAppConfig::resolved_brain_path’sNINOX_BRAINpattern); otherwise~/.claude/projects. - ingest_
usage_ for_ workspace - Compute the current usage snapshot for a session’s workspace directory,
by locating and summing
claude’s own transcript(s) for that directory. ReturnsNonewhen no transcripts exist yet (e.g. the agent hasn’t sent its first turn) or the workspace can’t be resolved.