zozul-cli 0.1.0
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.
- package/.env.example +44 -0
- package/.github/workflows/publish.yml +26 -0
- package/DEVELOPMENT.md +288 -0
- package/LICENSE +201 -0
- package/README.md +178 -0
- package/dist/cli/commands.d.ts +3 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +307 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/format.d.ts +5 -0
- package/dist/cli/format.d.ts.map +1 -0
- package/dist/cli/format.js +115 -0
- package/dist/cli/format.js.map +1 -0
- package/dist/context/index.d.ts +8 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +37 -0
- package/dist/context/index.js.map +1 -0
- package/dist/dashboard/html.d.ts +17 -0
- package/dist/dashboard/html.d.ts.map +1 -0
- package/dist/dashboard/html.js +79 -0
- package/dist/dashboard/html.js.map +1 -0
- package/dist/dashboard/index.html +1245 -0
- package/dist/hooks/config.d.ts +19 -0
- package/dist/hooks/config.d.ts.map +1 -0
- package/dist/hooks/config.js +106 -0
- package/dist/hooks/config.js.map +1 -0
- package/dist/hooks/git.d.ts +6 -0
- package/dist/hooks/git.d.ts.map +1 -0
- package/dist/hooks/git.js +73 -0
- package/dist/hooks/git.js.map +1 -0
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +3 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/server.d.ts +16 -0
- package/dist/hooks/server.d.ts.map +1 -0
- package/dist/hooks/server.js +349 -0
- package/dist/hooks/server.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/otel/config.d.ts +36 -0
- package/dist/otel/config.d.ts.map +1 -0
- package/dist/otel/config.js +109 -0
- package/dist/otel/config.js.map +1 -0
- package/dist/otel/index.d.ts +4 -0
- package/dist/otel/index.d.ts.map +1 -0
- package/dist/otel/index.js +3 -0
- package/dist/otel/index.js.map +1 -0
- package/dist/otel/receiver.d.ts +10 -0
- package/dist/otel/receiver.d.ts.map +1 -0
- package/dist/otel/receiver.js +155 -0
- package/dist/otel/receiver.js.map +1 -0
- package/dist/parser/index.d.ts +4 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +3 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/ingest.d.ts +20 -0
- package/dist/parser/ingest.d.ts.map +1 -0
- package/dist/parser/ingest.js +98 -0
- package/dist/parser/ingest.js.map +1 -0
- package/dist/parser/jsonl.d.ts +14 -0
- package/dist/parser/jsonl.d.ts.map +1 -0
- package/dist/parser/jsonl.js +202 -0
- package/dist/parser/jsonl.js.map +1 -0
- package/dist/parser/types.d.ts +81 -0
- package/dist/parser/types.d.ts.map +1 -0
- package/dist/parser/types.js +9 -0
- package/dist/parser/types.js.map +1 -0
- package/dist/parser/watcher.d.ts +16 -0
- package/dist/parser/watcher.d.ts.map +1 -0
- package/dist/parser/watcher.js +103 -0
- package/dist/parser/watcher.js.map +1 -0
- package/dist/pricing/index.d.ts +2 -0
- package/dist/pricing/index.d.ts.map +1 -0
- package/dist/pricing/index.js +37 -0
- package/dist/pricing/index.js.map +1 -0
- package/dist/service/index.d.ts +31 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/service/index.js +252 -0
- package/dist/service/index.js.map +1 -0
- package/dist/storage/db.d.ts +75 -0
- package/dist/storage/db.d.ts.map +1 -0
- package/dist/storage/db.js +117 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +3 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/repo.d.ts +162 -0
- package/dist/storage/repo.d.ts.map +1 -0
- package/dist/storage/repo.js +472 -0
- package/dist/storage/repo.js.map +1 -0
- package/dist/sync/client.d.ts +24 -0
- package/dist/sync/client.d.ts.map +1 -0
- package/dist/sync/client.js +41 -0
- package/dist/sync/client.js.map +1 -0
- package/dist/sync/index.d.ts +18 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +135 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/sync.test.d.ts +2 -0
- package/dist/sync/sync.test.d.ts.map +1 -0
- package/dist/sync/sync.test.js +412 -0
- package/dist/sync/sync.test.js.map +1 -0
- package/dist/sync/transform.d.ts +80 -0
- package/dist/sync/transform.d.ts.map +1 -0
- package/dist/sync/transform.js +90 -0
- package/dist/sync/transform.js.map +1 -0
- package/package.json +50 -0
- package/src/cli/commands.ts +332 -0
- package/src/cli/format.ts +133 -0
- package/src/context/index.ts +42 -0
- package/src/dashboard/html.ts +97 -0
- package/src/dashboard/index.html +1245 -0
- package/src/hooks/config.ts +119 -0
- package/src/hooks/git.ts +77 -0
- package/src/hooks/index.ts +7 -0
- package/src/hooks/server.ts +397 -0
- package/src/index.ts +6 -0
- package/src/otel/config.ts +141 -0
- package/src/otel/index.ts +8 -0
- package/src/otel/receiver.ts +183 -0
- package/src/parser/index.ts +3 -0
- package/src/parser/ingest.ts +119 -0
- package/src/parser/jsonl.ts +241 -0
- package/src/parser/types.ts +89 -0
- package/src/parser/watcher.ts +116 -0
- package/src/pricing/index.ts +51 -0
- package/src/service/index.ts +272 -0
- package/src/storage/db.ts +198 -0
- package/src/storage/index.ts +3 -0
- package/src/storage/repo.ts +601 -0
- package/src/sync/client.ts +63 -0
- package/src/sync/index.ts +207 -0
- package/src/sync/sync.test.ts +447 -0
- package/src/sync/transform.ts +184 -0
- package/tsconfig.json +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# zozul-cli
|
|
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.
|
|
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.
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Install and build
|
|
21
|
+
npm install && npm link
|
|
22
|
+
|
|
23
|
+
# Configure Claude Code and install as a background service (recommended)
|
|
24
|
+
zozul install --service
|
|
25
|
+
|
|
26
|
+
# Open the dashboard
|
|
27
|
+
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
|
+
```
|
|
40
|
+
|
|
41
|
+
## Dashboard
|
|
42
|
+
|
|
43
|
+
`http://localhost:7890/dashboard`
|
|
44
|
+
|
|
45
|
+
- **Stats bar** — sessions, user prompts, interruptions, tokens, and cost at a glance
|
|
46
|
+
- **Token usage chart** — daily input/output/cache token trends with time range controls
|
|
47
|
+
- **Cost chart** — daily spend
|
|
48
|
+
- **Tool usage** — which tools Claude uses most
|
|
49
|
+
- **Model breakdown** — cost and tokens per model
|
|
50
|
+
- **Sessions table** — paginated (Load More), filterable; click any session for the full conversation with per-turn token counts, expandable tool call inputs/outputs
|
|
51
|
+
- **Auto-refresh** — dashboard polls every 10s automatically; click the Auto button to refresh immediately
|
|
52
|
+
|
|
53
|
+
## Commands
|
|
54
|
+
|
|
55
|
+
| Command | Description |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `zozul serve` | Start the server (dashboard, hooks, OTEL receiver, API) on port 7890 |
|
|
58
|
+
| `zozul install` | Configure Claude Code hooks and OTEL in `~/.claude/settings.json` |
|
|
59
|
+
| `zozul install --service` | Configure Claude Code **and** install zozul as a login service (auto-starts) |
|
|
60
|
+
| `zozul uninstall` | Remove zozul config from Claude Code settings |
|
|
61
|
+
| `zozul uninstall --service` | Also stop and remove the background service |
|
|
62
|
+
| `zozul restart` | Restart the background service (picks up new builds) |
|
|
63
|
+
| `zozul service-status` | Show whether the background service is installed and running |
|
|
64
|
+
| `zozul ingest` | Parse all Claude Code session JSONL files into the database |
|
|
65
|
+
| `zozul ingest --force` | Re-ingest sessions that already exist (picks up new turns) |
|
|
66
|
+
| `zozul sessions` | List recorded sessions with token/cost summaries |
|
|
67
|
+
| `zozul session <id>` | Show full details and conversation for a session |
|
|
68
|
+
| `zozul stats` | Show aggregate statistics across all sessions |
|
|
69
|
+
| `zozul db-clean` | Remove rows with invalid timestamps from the database |
|
|
70
|
+
| `zozul db-clean --session <id>` | Remove all data for a specific session |
|
|
71
|
+
| `zozul show-config` | Preview the Claude Code config that would be installed |
|
|
72
|
+
|
|
73
|
+
## Architecture
|
|
74
|
+
|
|
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
|
+
```
|
|
99
|
+
|
|
100
|
+
Everything runs in a single process on port 7890.
|
|
101
|
+
|
|
102
|
+
### Data sources and ownership
|
|
103
|
+
|
|
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 |
|
|
114
|
+
|
|
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.
|
|
116
|
+
|
|
117
|
+
### JSONL watcher
|
|
118
|
+
|
|
119
|
+
When `zozul serve` starts it:
|
|
120
|
+
|
|
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
|
|
124
|
+
|
|
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.
|
|
126
|
+
|
|
127
|
+
### OTEL metrics
|
|
128
|
+
|
|
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.
|
|
130
|
+
|
|
131
|
+
Raw metric rows are also stored in `otel_metrics` and `otel_events` for dashboard charts and event replay.
|
|
132
|
+
|
|
133
|
+
## Background service
|
|
134
|
+
|
|
135
|
+
`zozul install --service` installs zozul as a persistent background service:
|
|
136
|
+
|
|
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`.
|
|
139
|
+
|
|
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.
|
|
141
|
+
|
|
142
|
+
Logs write to `~/.zozul/zozul.log`.
|
|
143
|
+
|
|
144
|
+
## Configuration
|
|
145
|
+
|
|
146
|
+
Settings via `.env` in the working directory (see `.env.example`) or environment variables:
|
|
147
|
+
|
|
148
|
+
```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
|
|
156
|
+
```
|
|
157
|
+
|
|
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
|
+
## Requirements
|
|
175
|
+
|
|
176
|
+
- Node.js 18+
|
|
177
|
+
- Claude Code installed (`claude --version`)
|
|
178
|
+
- Claude Pro, Max, Teams, Enterprise, or API key
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BpC,wBAAgB,QAAQ,IAAI,OAAO,CA6SlC"}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { getDb } from "../storage/db.js";
|
|
3
|
+
import { SessionRepo } from "../storage/repo.js";
|
|
4
|
+
import { createHookServer } from "../hooks/server.js";
|
|
5
|
+
import { installHooksToSettings, uninstallHooksFromSettings, generateHooksConfig } from "../hooks/config.js";
|
|
6
|
+
import { installOtelToSettings, uninstallOtelFromSettings, generateOtelShellExports } from "../otel/config.js";
|
|
7
|
+
import { ingestAllSessions } from "../parser/ingest.js";
|
|
8
|
+
import { watchSessionFiles } from "../parser/watcher.js";
|
|
9
|
+
import { installService, uninstallService, serviceStatus, restartService } from "../service/index.js";
|
|
10
|
+
import { getActiveContext, setActiveContext, clearActiveContext } from "../context/index.js";
|
|
11
|
+
import { installGitHook, uninstallGitHook } from "../hooks/git.js";
|
|
12
|
+
import { runSync } from "../sync/index.js";
|
|
13
|
+
import { ZozulApiClient } from "../sync/client.js";
|
|
14
|
+
function envPort() {
|
|
15
|
+
return process.env.ZOZUL_PORT ?? "7890";
|
|
16
|
+
}
|
|
17
|
+
function envOtelEndpoint() {
|
|
18
|
+
return process.env.OTEL_ENDPOINT ?? "http://localhost:7890";
|
|
19
|
+
}
|
|
20
|
+
function envOtelProtocol() {
|
|
21
|
+
return process.env.OTEL_PROTOCOL ?? "http/json";
|
|
22
|
+
}
|
|
23
|
+
function envVerbose() {
|
|
24
|
+
return process.env.ZOZUL_VERBOSE === "true" || process.env.ZOZUL_VERBOSE === "1";
|
|
25
|
+
}
|
|
26
|
+
function envDbPath() {
|
|
27
|
+
return process.env.ZOZUL_DB_PATH || undefined;
|
|
28
|
+
}
|
|
29
|
+
export function buildCli() {
|
|
30
|
+
const program = new Command();
|
|
31
|
+
program
|
|
32
|
+
.name("zozul")
|
|
33
|
+
.description("Observability for Claude Code — track tokens, costs, turns, and conversations")
|
|
34
|
+
.version("0.1.0");
|
|
35
|
+
program
|
|
36
|
+
.command("serve")
|
|
37
|
+
.description("Start the hooks HTTP server to receive real-time events from Claude Code")
|
|
38
|
+
.option("-p, --port <port>", "Port to listen on", envPort())
|
|
39
|
+
.option("-v, --verbose", "Print events to stderr as they arrive")
|
|
40
|
+
.action(async (opts) => {
|
|
41
|
+
const port = parseInt(opts.port, 10);
|
|
42
|
+
const verbose = opts.verbose || envVerbose();
|
|
43
|
+
const db = getDb(envDbPath());
|
|
44
|
+
const repo = new SessionRepo(db);
|
|
45
|
+
const server = createHookServer({ port, repo, verbose });
|
|
46
|
+
server.on("error", (err) => {
|
|
47
|
+
if (err.code === "EADDRINUSE") {
|
|
48
|
+
console.error(`Port ${port} is already in use. Is zozul already running?`);
|
|
49
|
+
console.error(" Check with: lsof -ti :" + port);
|
|
50
|
+
db.close();
|
|
51
|
+
process.exit(0); // clean exit so launchd/systemd won't respawn
|
|
52
|
+
}
|
|
53
|
+
throw err;
|
|
54
|
+
});
|
|
55
|
+
server.listen(port, async () => {
|
|
56
|
+
console.log(`zozul listening on http://localhost:${port}`);
|
|
57
|
+
console.log(` Dashboard: http://localhost:${port}/dashboard`);
|
|
58
|
+
console.log(` Hooks: http://localhost:${port}/hook/<event>`);
|
|
59
|
+
console.log(` OTLP receiver: http://localhost:${port}/v1/metrics & /v1/logs`);
|
|
60
|
+
console.log(` API: http://localhost:${port}/api/*`);
|
|
61
|
+
console.log("\nPress Ctrl+C to stop.\n");
|
|
62
|
+
const stopWatcher = await watchSessionFiles({ repo, verbose, catchUp: true });
|
|
63
|
+
process.on("SIGINT", () => {
|
|
64
|
+
stopWatcher();
|
|
65
|
+
server.close();
|
|
66
|
+
db.close();
|
|
67
|
+
process.exit(0);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
program
|
|
72
|
+
.command("install")
|
|
73
|
+
.description("Install hooks, OTEL config, and optionally the background service")
|
|
74
|
+
.option("-p, --port <port>", "Hook server port", envPort())
|
|
75
|
+
.option("--otel-endpoint <endpoint>", "OTLP endpoint", envOtelEndpoint())
|
|
76
|
+
.option("--otel-protocol <protocol>", "OTLP protocol", envOtelProtocol())
|
|
77
|
+
.option("--no-otel", "Skip OTEL configuration")
|
|
78
|
+
.option("--no-hooks", "Skip hooks configuration")
|
|
79
|
+
.option("--service", "Also install zozul as a background service (starts on login)")
|
|
80
|
+
.option("--status", "Show background service status")
|
|
81
|
+
.option("--restart", "Restart the background service")
|
|
82
|
+
.option("--dry-run", "Print the config that would be installed without writing")
|
|
83
|
+
.action((opts) => {
|
|
84
|
+
if (opts.status) {
|
|
85
|
+
console.log(`Service status: ${serviceStatus()}`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (opts.restart) {
|
|
89
|
+
try {
|
|
90
|
+
restartService();
|
|
91
|
+
console.log("Service restarted.");
|
|
92
|
+
console.log(` Status: ${serviceStatus()}`);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
console.error(`Restart failed: ${err instanceof Error ? err.message : err}`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const port = parseInt(opts.port, 10);
|
|
101
|
+
if (opts.dryRun) {
|
|
102
|
+
console.log("── Hooks Config (for ~/.claude/settings.json) ──\n");
|
|
103
|
+
console.log(JSON.stringify(generateHooksConfig({ port }), null, 2));
|
|
104
|
+
console.log("\n── OTEL Environment Variables ──\n");
|
|
105
|
+
console.log(generateOtelShellExports({ endpoint: opts.otelEndpoint }));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (opts.hooks !== false) {
|
|
109
|
+
const result = installHooksToSettings({ port });
|
|
110
|
+
console.log(`Hooks installed to ${result.path}`);
|
|
111
|
+
if (result.merged)
|
|
112
|
+
console.log(" (merged with existing hooks)");
|
|
113
|
+
}
|
|
114
|
+
if (opts.otel !== false) {
|
|
115
|
+
const result = installOtelToSettings({
|
|
116
|
+
endpoint: opts.otelEndpoint,
|
|
117
|
+
protocol: opts.otelProtocol,
|
|
118
|
+
});
|
|
119
|
+
console.log(`OTEL config installed to ${result.path}`);
|
|
120
|
+
}
|
|
121
|
+
if (opts.service) {
|
|
122
|
+
try {
|
|
123
|
+
const result = installService({ port, dbPath: envDbPath() });
|
|
124
|
+
console.log(`Service installed: ${result.servicePath}`);
|
|
125
|
+
console.log(" zozul is now running in the background and will start automatically on login.");
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
console.error(`Service install failed: ${err instanceof Error ? err.message : err}`);
|
|
129
|
+
console.error(" Run 'zozul serve' manually as a fallback.");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
console.log("\nDone. Start the server with: zozul serve");
|
|
134
|
+
console.log("Or install as a background service with: zozul install --service");
|
|
135
|
+
}
|
|
136
|
+
const gitResult = installGitHook();
|
|
137
|
+
if (gitResult) {
|
|
138
|
+
if (gitResult.created) {
|
|
139
|
+
console.log(`Git post-commit hook installed: ${gitResult.path}`);
|
|
140
|
+
console.log(" (auto-clears task context on commit)");
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
console.log("Git post-commit hook already installed.");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
console.log("Launch Claude Code normally with: claude");
|
|
147
|
+
});
|
|
148
|
+
program
|
|
149
|
+
.command("uninstall")
|
|
150
|
+
.description("Remove zozul hooks, OTEL config, and background service")
|
|
151
|
+
.option("-p, --port <port>", "Hook server port (to match installed hooks)", envPort())
|
|
152
|
+
.action((opts) => {
|
|
153
|
+
const port = parseInt(opts.port, 10);
|
|
154
|
+
const hooksRemoved = uninstallHooksFromSettings({ port });
|
|
155
|
+
const otelRemoved = uninstallOtelFromSettings();
|
|
156
|
+
const gitRemoved = uninstallGitHook();
|
|
157
|
+
if (hooksRemoved)
|
|
158
|
+
console.log("Hooks removed from Claude Code settings.");
|
|
159
|
+
if (otelRemoved)
|
|
160
|
+
console.log("OTEL config removed from Claude Code settings.");
|
|
161
|
+
if (gitRemoved)
|
|
162
|
+
console.log("Git post-commit hook removed.");
|
|
163
|
+
const serviceResult = uninstallService();
|
|
164
|
+
if (serviceResult.removed) {
|
|
165
|
+
console.log("Background service stopped and removed.");
|
|
166
|
+
}
|
|
167
|
+
if (!hooksRemoved && !otelRemoved && !gitRemoved && !serviceResult.removed) {
|
|
168
|
+
console.log("Nothing to remove.");
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
program
|
|
172
|
+
.command("context [tags...]")
|
|
173
|
+
.description("Set, view, or clear the active task tags for tagging turns")
|
|
174
|
+
.option("--clear", "Clear the active task context")
|
|
175
|
+
.option("--list", "List all tasks that have been used")
|
|
176
|
+
.action((tags, opts) => {
|
|
177
|
+
if (opts.clear) {
|
|
178
|
+
clearActiveContext();
|
|
179
|
+
console.log("Task context cleared.");
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (opts.list) {
|
|
183
|
+
const db = getDb(envDbPath());
|
|
184
|
+
const repo = new SessionRepo(db);
|
|
185
|
+
const tasks = repo.listTasks();
|
|
186
|
+
if (tasks.length === 0) {
|
|
187
|
+
console.log("No tasks found.");
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
for (const t of tasks) {
|
|
191
|
+
console.log(` ${t.task} (${t.turn_count} turns, last tagged: ${t.last_tagged})`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
db.close();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (tags.length > 0) {
|
|
198
|
+
const ctx = setActiveContext(tags);
|
|
199
|
+
console.log(`Active tags: ${ctx.active.join(", ")}`);
|
|
200
|
+
console.log(` Set at: ${ctx.set_at}`);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
// No arguments: show current context
|
|
204
|
+
const ctx = getActiveContext();
|
|
205
|
+
if (ctx?.active && ctx.active.length > 0) {
|
|
206
|
+
console.log(`Active tags: ${ctx.active.join(", ")}`);
|
|
207
|
+
console.log(` Set at: ${ctx.set_at}`);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
console.log("No active task context.");
|
|
211
|
+
console.log('Set one with: zozul context "UI" "Feature"');
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
program
|
|
215
|
+
.command("sync")
|
|
216
|
+
.description("Sync local data to the remote zozul backend")
|
|
217
|
+
.option("--dry-run", "Show what would be synced without sending data")
|
|
218
|
+
.option("-v, --verbose", "Print detailed progress")
|
|
219
|
+
.action(async (opts) => {
|
|
220
|
+
const apiUrl = process.env.ZOZUL_API_URL;
|
|
221
|
+
const apiKey = process.env.ZOZUL_API_KEY;
|
|
222
|
+
if (!apiUrl || !apiKey) {
|
|
223
|
+
console.error("Missing required environment variables:");
|
|
224
|
+
if (!apiUrl)
|
|
225
|
+
console.error(" ZOZUL_API_URL — base URL of the zozul backend");
|
|
226
|
+
if (!apiKey)
|
|
227
|
+
console.error(" ZOZUL_API_KEY — API key for authentication");
|
|
228
|
+
console.error("\nSet them in .env or export them in your shell.");
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
const db = getDb(envDbPath());
|
|
232
|
+
const repo = new SessionRepo(db);
|
|
233
|
+
const client = new ZozulApiClient({ apiUrl, apiKey });
|
|
234
|
+
if (opts.dryRun) {
|
|
235
|
+
console.log(`Dry run — checking what would sync to ${apiUrl}...\n`);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
console.log(`Syncing to ${apiUrl}...\n`);
|
|
239
|
+
}
|
|
240
|
+
const result = await runSync(repo, client, {
|
|
241
|
+
verbose: opts.verbose || envVerbose(),
|
|
242
|
+
dryRun: opts.dryRun,
|
|
243
|
+
});
|
|
244
|
+
console.log("── Sync Summary ──");
|
|
245
|
+
const label = opts.dryRun ? "pending" : "synced";
|
|
246
|
+
for (const [table, counts] of Object.entries(result)) {
|
|
247
|
+
const status = counts.failed > 0 ? "PARTIAL" : "OK";
|
|
248
|
+
console.log(` ${table.padEnd(15)} ${counts.synced} ${label}, ${counts.failed} failed [${status}]`);
|
|
249
|
+
}
|
|
250
|
+
const totalFailed = Object.values(result).reduce((s, c) => s + c.failed, 0);
|
|
251
|
+
if (totalFailed > 0) {
|
|
252
|
+
console.error(`\n${totalFailed} items failed to sync. Re-run 'zozul sync' to retry.`);
|
|
253
|
+
db.close();
|
|
254
|
+
process.exit(1);
|
|
255
|
+
}
|
|
256
|
+
db.close();
|
|
257
|
+
});
|
|
258
|
+
// ── Hidden maintenance commands ──
|
|
259
|
+
program
|
|
260
|
+
.command("ingest", { hidden: true })
|
|
261
|
+
.description("Re-ingest all Claude Code session files (backfill)")
|
|
262
|
+
.option("-f, --force", "Re-ingest sessions that already exist in the database")
|
|
263
|
+
.option("--no-tag", "Skip tagging turns with the active task context")
|
|
264
|
+
.action(async (opts) => {
|
|
265
|
+
const db = getDb(envDbPath());
|
|
266
|
+
const repo = new SessionRepo(db);
|
|
267
|
+
console.log("Scanning for Claude Code session files...");
|
|
268
|
+
const result = await ingestAllSessions(repo, { force: opts.force, noTag: opts.tag === false });
|
|
269
|
+
console.log(`Ingested: ${result.ingested} Skipped: ${result.skipped}`);
|
|
270
|
+
db.close();
|
|
271
|
+
});
|
|
272
|
+
program
|
|
273
|
+
.command("db-clean", { hidden: true })
|
|
274
|
+
.description("Remove invalid/test rows from the database")
|
|
275
|
+
.option("--session <id>", "Remove all data for a specific session ID")
|
|
276
|
+
.action((opts) => {
|
|
277
|
+
const db = getDb(envDbPath());
|
|
278
|
+
if (opts.session) {
|
|
279
|
+
const id = opts.session;
|
|
280
|
+
db.transaction(() => {
|
|
281
|
+
db.prepare(`DELETE FROM task_tags WHERE turn_id IN (SELECT id FROM turns WHERE session_id = ?)`).run(id);
|
|
282
|
+
for (const table of ["otel_metrics", "otel_events", "hook_events", "tool_uses", "turns"]) {
|
|
283
|
+
db.prepare(`DELETE FROM ${table} WHERE session_id = ?`).run(id);
|
|
284
|
+
}
|
|
285
|
+
db.prepare(`DELETE FROM sessions WHERE id = ?`).run(id);
|
|
286
|
+
})();
|
|
287
|
+
console.log(`Removed all data for session: ${id}`);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
const minDate = "2025-01-01";
|
|
291
|
+
const result = db.prepare(`
|
|
292
|
+
SELECT COUNT(*) as n FROM otel_metrics WHERE timestamp < ?
|
|
293
|
+
`).get(minDate);
|
|
294
|
+
if (result.n === 0) {
|
|
295
|
+
console.log("Nothing to clean.");
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
db.prepare(`DELETE FROM otel_metrics WHERE timestamp < ?`).run(minDate);
|
|
299
|
+
db.prepare(`DELETE FROM otel_events WHERE timestamp < ?`).run(minDate);
|
|
300
|
+
console.log(`Removed ${result.n} row(s) with timestamps before ${minDate}.`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
db.close();
|
|
304
|
+
});
|
|
305
|
+
return program;
|
|
306
|
+
}
|
|
307
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SessionRow, TurnRow } from "../storage/db.js";
|
|
2
|
+
export declare function formatSessionList(sessions: SessionRow[]): string;
|
|
3
|
+
export declare function formatSessionDetail(session: SessionRow, turns: TurnRow[]): string;
|
|
4
|
+
export declare function formatStats(stats: Record<string, unknown>): string;
|
|
5
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE5D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,CA+BhE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAwDjF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAWlE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export function formatSessionList(sessions) {
|
|
2
|
+
if (sessions.length === 0)
|
|
3
|
+
return "No sessions found.";
|
|
4
|
+
const lines = [];
|
|
5
|
+
lines.push(pad("SESSION ID", 40) +
|
|
6
|
+
pad("STARTED", 22) +
|
|
7
|
+
pad("TURNS", 7) +
|
|
8
|
+
pad("TOKENS (in/out)", 20) +
|
|
9
|
+
pad("COST", 10) +
|
|
10
|
+
"MODEL");
|
|
11
|
+
lines.push("─".repeat(120));
|
|
12
|
+
for (const s of sessions) {
|
|
13
|
+
const started = formatTimestamp(s.started_at);
|
|
14
|
+
const tokens = `${fmtNum(s.total_input_tokens)}/${fmtNum(s.total_output_tokens)}`;
|
|
15
|
+
const cost = `$${s.total_cost_usd.toFixed(4)}`;
|
|
16
|
+
const id = s.id.length > 36 ? s.id.slice(0, 36) + "…" : s.id;
|
|
17
|
+
lines.push(pad(id, 40) +
|
|
18
|
+
pad(started, 22) +
|
|
19
|
+
pad(String(s.total_turns), 7) +
|
|
20
|
+
pad(tokens, 20) +
|
|
21
|
+
pad(cost, 10) +
|
|
22
|
+
(s.model ?? "—"));
|
|
23
|
+
}
|
|
24
|
+
return lines.join("\n");
|
|
25
|
+
}
|
|
26
|
+
export function formatSessionDetail(session, turns) {
|
|
27
|
+
const lines = [];
|
|
28
|
+
lines.push(`Session: ${session.id}`);
|
|
29
|
+
lines.push(`Project: ${session.project_path ?? "—"}`);
|
|
30
|
+
lines.push(`Started: ${formatTimestamp(session.started_at)}`);
|
|
31
|
+
lines.push(`Ended: ${session.ended_at ? formatTimestamp(session.ended_at) : "—"}`);
|
|
32
|
+
lines.push(`Model: ${session.model ?? "—"}`);
|
|
33
|
+
lines.push("");
|
|
34
|
+
lines.push("── Token Usage ──");
|
|
35
|
+
lines.push(` Input tokens: ${fmtNum(session.total_input_tokens)}`);
|
|
36
|
+
lines.push(` Output tokens: ${fmtNum(session.total_output_tokens)}`);
|
|
37
|
+
lines.push(` Cache read tokens: ${fmtNum(session.total_cache_read_tokens)}`);
|
|
38
|
+
lines.push(` Cache creation tokens: ${fmtNum(session.total_cache_creation_tokens)}`);
|
|
39
|
+
lines.push(` Total cost: $${session.total_cost_usd.toFixed(4)}`);
|
|
40
|
+
lines.push(` Total turns: ${session.total_turns}`);
|
|
41
|
+
lines.push(` Total duration: ${formatDuration(session.total_duration_ms)}`);
|
|
42
|
+
if (turns.length > 0) {
|
|
43
|
+
lines.push("");
|
|
44
|
+
lines.push("── Conversation ──");
|
|
45
|
+
for (const turn of turns) {
|
|
46
|
+
const role = turn.role === "assistant" ? "🤖 Assistant" : "👤 User";
|
|
47
|
+
lines.push("");
|
|
48
|
+
lines.push(`[${turn.turn_index}] ${role} (${formatTimestamp(turn.timestamp)})`);
|
|
49
|
+
if (turn.input_tokens > 0 || turn.output_tokens > 0) {
|
|
50
|
+
lines.push(` tokens: ${fmtNum(turn.input_tokens)} in / ${fmtNum(turn.output_tokens)} out` +
|
|
51
|
+
(turn.cost_usd > 0 ? ` | cost: $${turn.cost_usd.toFixed(4)}` : "") +
|
|
52
|
+
(turn.model ? ` | model: ${turn.model}` : ""));
|
|
53
|
+
}
|
|
54
|
+
if (turn.content_text) {
|
|
55
|
+
const preview = turn.content_text.length > 500
|
|
56
|
+
? turn.content_text.slice(0, 500) + "…"
|
|
57
|
+
: turn.content_text;
|
|
58
|
+
lines.push(` ${preview.replace(/\n/g, "\n ")}`);
|
|
59
|
+
}
|
|
60
|
+
if (turn.tool_calls) {
|
|
61
|
+
try {
|
|
62
|
+
const calls = JSON.parse(turn.tool_calls);
|
|
63
|
+
for (const call of calls) {
|
|
64
|
+
lines.push(` 🔧 ${call.toolName}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// skip
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return lines.join("\n");
|
|
74
|
+
}
|
|
75
|
+
export function formatStats(stats) {
|
|
76
|
+
const lines = [];
|
|
77
|
+
lines.push("── Aggregate Statistics ──");
|
|
78
|
+
lines.push(` Total sessions: ${stats.total_sessions ?? 0}`);
|
|
79
|
+
lines.push(` Total input tokens: ${fmtNum(Number(stats.total_input_tokens ?? 0))}`);
|
|
80
|
+
lines.push(` Total output tokens: ${fmtNum(Number(stats.total_output_tokens ?? 0))}`);
|
|
81
|
+
lines.push(` Total cache read: ${fmtNum(Number(stats.total_cache_read_tokens ?? 0))}`);
|
|
82
|
+
lines.push(` Total cost: $${Number(stats.total_cost_usd ?? 0).toFixed(4)}`);
|
|
83
|
+
lines.push(` Total turns: ${stats.total_turns ?? 0}`);
|
|
84
|
+
lines.push(` Total active time: ${formatDuration(Number(stats.total_duration_ms ?? 0))}`);
|
|
85
|
+
return lines.join("\n");
|
|
86
|
+
}
|
|
87
|
+
function pad(str, len) {
|
|
88
|
+
return str.padEnd(len);
|
|
89
|
+
}
|
|
90
|
+
function fmtNum(n) {
|
|
91
|
+
return n.toLocaleString("en-US");
|
|
92
|
+
}
|
|
93
|
+
function formatTimestamp(ts) {
|
|
94
|
+
try {
|
|
95
|
+
return new Date(ts).toLocaleString();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return ts;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function formatDuration(ms) {
|
|
102
|
+
if (ms < 1000)
|
|
103
|
+
return `${ms}ms`;
|
|
104
|
+
const seconds = Math.floor(ms / 1000);
|
|
105
|
+
if (seconds < 60)
|
|
106
|
+
return `${seconds}s`;
|
|
107
|
+
const minutes = Math.floor(seconds / 60);
|
|
108
|
+
const remainingSeconds = seconds % 60;
|
|
109
|
+
if (minutes < 60)
|
|
110
|
+
return `${minutes}m ${remainingSeconds}s`;
|
|
111
|
+
const hours = Math.floor(minutes / 60);
|
|
112
|
+
const remainingMinutes = minutes % 60;
|
|
113
|
+
return `${hours}h ${remainingMinutes}m`;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"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"}
|