zozul-cli 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +81 -135
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,185 +1,131 @@
1
- # zozul-cli
1
+ # zozul
2
2
 
3
- Observability for [Claude Code](https://code.claude.com/) track token usage, costs, turns, and full conversation history. No external services, no Docker, no cloud.
3
+ Observability for [Claude Code](https://code.claude.com/). Track costs, sessions, and conversations across projects.
4
4
 
5
- ## What it does
6
-
7
- zozul is a single local process that captures everything Claude Code does. Data flows in from three complementary sources and lands in a SQLite database at `~/.zozul/zozul.db`. A built-in web dashboard and JSON API sit on top of that.
8
-
9
- | Source | What it provides |
10
- |---|---|
11
- | **OTEL receiver** | Token counts, cost (USD), active time, API events, user prompts — streamed from Claude Code every ~60s |
12
- | **Hooks** | Real-time session lifecycle, tool calls, user prompts — fired synchronously as events happen |
13
- | **JSONL watcher** | Full turn content, assistant responses, per-turn token detail — read directly from Claude Code's transcript files |
14
-
15
- Each source has different strengths. OTEL is the authoritative source for **cost and duration**. JSONL is the only source for **full conversation text**. Hooks provide **real-time signals** and trigger transcript ingestion on session end. The `sessions` table is kept in sync from all three.
5
+ Works locally out of the box. Optionally syncs to a remote backend for persistent storage and team visibility.
16
6
 
17
7
  ## Quick start
18
8
 
19
9
  ```bash
20
- # Install globally from npm
21
10
  npm install -g zozul-cli
22
11
 
23
- # Configure Claude Code and install as a background service (recommended)
12
+ # Configure Claude Code and run as a background service
24
13
  zozul install --service
25
14
 
26
15
  # Open the dashboard
27
16
  open http://localhost:7890/dashboard
28
-
29
- # Use Claude Code normally — data appears automatically
30
- claude
31
- ```
32
-
33
- Or if you'd rather manage the process yourself:
34
-
35
- ```bash
36
- zozul install # Configure Claude Code hooks + OTEL
37
- zozul serve # Start the server
38
- open http://localhost:7890/dashboard
39
17
  ```
40
18
 
41
- ## Dashboard
19
+ That's it. Use Claude Code normally — data appears automatically.
42
20
 
43
- `http://localhost:7890/dashboard`
21
+ ## What you get
44
22
 
45
- Four views, all with time window filtering (7d / 30d / All):
23
+ A single local process that captures everything Claude Code does via three sources:
46
24
 
47
- - **Summary** — total cost, sessions, and tasks at a glance; 30-day cost chart; cost breakdown by project
48
- - **Tasks** — groups turns by tag combination (e.g. `[API] [Backend] [DB]`), shows process time, cost, and human interventions per group; click to drill into individual turns
49
- - **Tags** — per-tag stats with drill-down into paginated turns and per-prompt cost
50
- - **Sessions** — sortable, filterable, paginated session table; click any session for the full conversation with per-turn token counts and expandable tool call inputs/outputs
25
+ - **OTEL** — cost, tokens, active time. Streamed every ~60s. The authoritative source for spend.
26
+ - **Hooks** — session lifecycle, tool calls, user prompts. Real-time.
27
+ - **JSONL** — full conversation text, assistant responses. Read from Claude Code's transcript files.
51
28
 
52
- The dashboard auto-detects whether a remote backend is available (via health check) and falls back to the local API transparently. A badge in the header shows "Remote" or "Local".
29
+ All data lands in SQLite at `~/.zozul/zozul.db`. A web dashboard and JSON API sit on top.
53
30
 
54
- Auto-refresh polls every 10s on the active view.
31
+ ## Dashboard
55
32
 
56
- ## Commands
33
+ `http://localhost:7890/dashboard`
57
34
 
58
- | Command | Description |
35
+ | View | What it answers |
59
36
  |---|---|
60
- | `zozul serve` | Start the server (dashboard, hooks, OTEL receiver, API) on port 7890 |
61
- | `zozul install` | Configure Claude Code hooks and OTEL in `~/.claude/settings.json` |
62
- | `zozul install --service` | Configure Claude Code **and** install zozul as a login service (auto-starts) |
63
- | `zozul install --status` | Show whether the background service is installed and running |
64
- | `zozul install --restart` | Restart the background service (picks up new builds) |
65
- | `zozul install --dry-run` | Preview the config that would be installed |
66
- | `zozul uninstall` | Remove zozul hooks, OTEL config, git hook, and background service |
67
- | `zozul context <tags...>` | Set active task tags for tagging turns (e.g. `zozul context "UI" "Feature"`) |
68
- | `zozul context --list` | List all tasks that have been used |
69
- | `zozul context --clear` | Clear the active task context |
70
- | `zozul sync` | Sync local data to the remote zozul backend |
71
- | `zozul sync --dry-run` | Show what would be synced without sending data |
72
-
73
- ## Architecture
37
+ | **Summary** | How much have I spent? Cost chart, project breakdown, totals. |
38
+ | **Tasks** | What did I work on? Groups turns by tag combination, shows cost and time per task. |
39
+ | **Tags** | How much per category? Per-tag stats with drill-down into individual prompts. |
40
+ | **Sessions** | Raw session list. Sortable, filterable, click to see full conversation. |
74
41
 
75
- ```
76
- Claude Code
77
- |
78
- +-------------+-------------+
79
- | | |
80
- OTEL export Hook POSTs ~/.claude/projects/
81
- (every ~60s) (real-time) <project>/<uuid>.jsonl
82
- | | |
83
- v v v
84
- /v1/metrics /hook/* fs.watch (live)
85
- /v1/logs | zozul ingest (manual)
86
- | | |
87
- | updateSessionFromOtel |
88
- | | persistSession
89
- +------+------+------+------+
90
- |
91
- SQLite (WAL)
92
- ~/.zozul/zozul.db
93
- |
94
- +------+------+
95
- | |
96
- /dashboard /api/*
97
- (browser) (JSON)
98
- ```
42
+ All views support time filtering (7d / 30d / All). Auto-refreshes every 10s.
99
43
 
100
- Everything runs in a single process on port 7890.
44
+ When a remote backend is configured, the dashboard auto-detects it via health check and uses it as the data source. Falls back to local if unavailable.
101
45
 
102
- ### Data sources and ownership
46
+ ## Task tagging
103
47
 
104
- Each field in the `sessions` table has a designated owner:
105
-
106
- | Field | Owner | Notes |
107
- |---|---|---|
108
- | `id`, `started_at`, `project_path`, `model` | JSONL | Set from transcript filename and content |
109
- | `total_turns` | JSONL | Count of turns parsed from transcript |
110
- | `total_cost_usd` | OTEL | JSONL transcripts do not include cost data |
111
- | `total_duration_ms` | OTEL | Accumulated from `claude_code.active_time.total` |
112
- | `total_*_tokens` (session level) | OTEL (preferred) | JSONL provides seeds; OTEL accumulates via `MAX()` |
113
- | `ended_at` | Both | OTEL keeps it current as batches arrive; JSONL sets it at ingest |
48
+ Tag your work so costs are attributed to what you're building:
114
49
 
115
- The `sessions` upsert uses `MAX()` for all metric fields so OTEL-accumulated values are never clobbered by a JSONL re-ingest that may have lower (or zero) values.
50
+ ```bash
51
+ zozul context "auth" "backend" # Set active tags
52
+ # ... use Claude Code ...
53
+ git commit # Tags auto-clear on commit
54
+ ```
116
55
 
117
- ### JSONL watcher
56
+ Tags appear in the Tasks and Tags views. Turns are grouped by their tag combination.
118
57
 
119
- When `zozul serve` starts it:
58
+ ## Remote sync
120
59
 
121
- 1. Performs a catch-up pass ingests all JSONL files found under `~/.claude/projects/`
122
- 2. Watches that directory for changes via `fs.watch` (recursive, FSEvents on macOS)
123
- 3. Debounces per-file at 500ms and calls `ingestSessionFile` on each change
60
+ Optionally push data to a remote backend:
124
61
 
125
- This means starting zozul after Claude Code is already running is fine — all existing turns are recovered immediately and new turns appear within ~500ms of being written.
62
+ ```bash
63
+ # Set in .env or environment
64
+ ZOZUL_API_URL=https://your-backend.example.com
65
+ ZOZUL_API_KEY=your-key
126
66
 
127
- ### OTEL metrics
67
+ zozul sync
68
+ ```
128
69
 
129
- Claude Code exports OTLP JSON to `http://localhost:7890` on a 60s interval (metrics) and 5s interval (logs). Each batch contains **delta values** for the export window — not cumulative totals. zozul accumulates these into the `sessions` table via `updateSessionFromOtel` on every batch received.
70
+ Sync is incremental (watermark-based) and also runs automatically on session end when the service is running. The dashboard switches to the remote API when available.
130
71
 
131
- Raw metric rows are also stored in `otel_metrics` and `otel_events` for dashboard charts and event replay.
72
+ ## Commands
132
73
 
133
- ## Background service
74
+ | Command | Description |
75
+ |---|---|
76
+ | `zozul serve` | Start the server on port 7890 |
77
+ | `zozul install` | Configure Claude Code hooks and OTEL |
78
+ | `zozul install --service` | Also install as a background service (auto-starts on login) |
79
+ | `zozul install --status` | Check if the service is running |
80
+ | `zozul install --restart` | Restart the service after code changes |
81
+ | `zozul uninstall` | Remove all hooks, config, and service |
82
+ | `zozul context <tags...>` | Set active task tags |
83
+ | `zozul context --clear` | Clear tags |
84
+ | `zozul sync` | Push local data to remote backend |
85
+
86
+ ## How it works
134
87
 
135
- `zozul install --service` installs zozul as a persistent background service:
88
+ ```
89
+ Claude Code
90
+ |
91
+ +--- OTEL export (every ~60s) ---> /v1/metrics, /v1/logs
92
+ +--- Hook POSTs (real-time) -----> /hook/*
93
+ +--- JSONL transcripts ----------> fs.watch
94
+ |
95
+ v
96
+ SQLite (~/.zozul/zozul.db)
97
+ |
98
+ +--- /dashboard (browser)
99
+ +--- /api/* (JSON)
100
+ +--- zozul sync --> remote backend (optional)
101
+ ```
136
102
 
137
- - **macOS**: writes `~/Library/LaunchAgents/com.zozul.serve.plist` and loads it via `launchctl`. Starts on login, restarts on crash.
138
- - **Linux**: writes `~/.config/systemd/user/zozul.service` and enables it with `systemctl --user`.
103
+ Single process on port 7890. macOS uses launchd, Linux uses systemd.
139
104
 
140
- The service bakes in the exact node binary path (nvm-safe) and the script path at install time, so it doesn't depend on shell PATH.
105
+ ### Data ownership
141
106
 
142
- Logs write to `~/.zozul/zozul.log`.
107
+ | What | Source | Notes |
108
+ |---|---|---|
109
+ | Cost | OTEL | JSONL doesn't include cost |
110
+ | Duration | OTEL | Accumulated from active time metrics |
111
+ | Tokens | OTEL (preferred) | JSONL provides initial values, OTEL accumulates |
112
+ | Conversation text | JSONL | Full turns, tool calls, assistant responses |
113
+ | Session events | Hooks | Start, end, stop, tool use |
143
114
 
144
115
  ## Configuration
145
116
 
146
- Settings via `.env` in the working directory (see `.env.example`) or environment variables:
117
+ Via `.env` or environment variables:
147
118
 
148
119
  ```bash
149
- ZOZUL_PORT=7890 # Server port (default: 7890)
150
- ZOZUL_DB_PATH=~/.zozul/zozul.db # Database path
151
- ZOZUL_VERBOSE=1 # Log every event to stderr
152
- OTEL_ENDPOINT=http://localhost:7890 # Where Claude Code sends OTEL
153
- OTEL_PROTOCOL=http/json # Must be http/json
154
- OTEL_LOG_USER_PROMPTS=1 # Include prompt text in OTEL events
155
- OTEL_LOG_TOOL_DETAILS=1 # Include tool names in OTEL events
120
+ ZOZUL_PORT=7890 # Default: 7890
121
+ ZOZUL_DB_PATH=~/.zozul/zozul.db # Default: ~/.zozul/zozul.db
122
+ ZOZUL_VERBOSE=1 # Log all events
123
+ ZOZUL_API_URL=https://... # Remote backend URL (optional)
124
+ ZOZUL_API_KEY=... # Remote backend API key (optional)
156
125
  ```
157
126
 
158
- CLI flags override `.env` values.
159
-
160
- ## Data captured
161
-
162
- | Data point | Source | Granularity |
163
- |---|---|---|
164
- | Token usage (input/output/cache/creation) | OTEL + JSONL | Per-session and per-turn |
165
- | Cost (USD) | OTEL | Per-session, per-model |
166
- | Active time | OTEL | Per-session |
167
- | Turns / API calls | JSONL | Full content and metadata |
168
- | User prompts | Hooks (`UserPromptSubmit`) + JSONL | Count (aggregate) + full text (per-turn) |
169
- | Interruptions | Hooks (`Stop`) | Count (aggregate) |
170
- | Model responses | JSONL only | Full text |
171
- | Tool calls and results | Hooks + JSONL | Name, input, output |
172
- | Session lifecycle | Hooks | Start, end, stop events |
173
-
174
127
  ## Requirements
175
128
 
176
129
  - Node.js 18+
177
- - npm
178
- - Claude Code installed (`claude --version`)
130
+ - Claude Code (`claude --version`)
179
131
  - Claude Pro, Max, Teams, Enterprise, or API key
180
-
181
- ## Updating
182
-
183
- ```bash
184
- npm install -g zozul-cli
185
- ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zozul-cli",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Observability for Claude Code — track token usage, costs, turns, and conversation history",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",