@fml-inc/panopticon 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.
Files changed (124) hide show
  1. package/.claude-plugin/plugin.json +10 -0
  2. package/LICENSE +5 -0
  3. package/README.md +363 -0
  4. package/bin/hook-handler +3 -0
  5. package/bin/mcp-server +3 -0
  6. package/bin/panopticon +3 -0
  7. package/bin/proxy +3 -0
  8. package/bin/server +3 -0
  9. package/dist/api/client.d.ts +67 -0
  10. package/dist/api/client.js +48 -0
  11. package/dist/api/client.js.map +1 -0
  12. package/dist/chunk-3BUJ7URA.js +387 -0
  13. package/dist/chunk-3BUJ7URA.js.map +1 -0
  14. package/dist/chunk-3TZAKV3M.js +158 -0
  15. package/dist/chunk-3TZAKV3M.js.map +1 -0
  16. package/dist/chunk-4SM2H22C.js +169 -0
  17. package/dist/chunk-4SM2H22C.js.map +1 -0
  18. package/dist/chunk-7Q3BJMLG.js +62 -0
  19. package/dist/chunk-7Q3BJMLG.js.map +1 -0
  20. package/dist/chunk-BVOE7A2Z.js +412 -0
  21. package/dist/chunk-BVOE7A2Z.js.map +1 -0
  22. package/dist/chunk-CF4GPWLI.js +170 -0
  23. package/dist/chunk-CF4GPWLI.js.map +1 -0
  24. package/dist/chunk-DZ5HJFB4.js +467 -0
  25. package/dist/chunk-DZ5HJFB4.js.map +1 -0
  26. package/dist/chunk-HQCY722C.js +428 -0
  27. package/dist/chunk-HQCY722C.js.map +1 -0
  28. package/dist/chunk-HRCEIYKU.js +134 -0
  29. package/dist/chunk-HRCEIYKU.js.map +1 -0
  30. package/dist/chunk-K7YUPLES.js +76 -0
  31. package/dist/chunk-K7YUPLES.js.map +1 -0
  32. package/dist/chunk-L7G27XWF.js +130 -0
  33. package/dist/chunk-L7G27XWF.js.map +1 -0
  34. package/dist/chunk-LWXF7YRG.js +626 -0
  35. package/dist/chunk-LWXF7YRG.js.map +1 -0
  36. package/dist/chunk-NXH7AONS.js +1120 -0
  37. package/dist/chunk-NXH7AONS.js.map +1 -0
  38. package/dist/chunk-QK5442ZP.js +55 -0
  39. package/dist/chunk-QK5442ZP.js.map +1 -0
  40. package/dist/chunk-QVK6VGCV.js +1703 -0
  41. package/dist/chunk-QVK6VGCV.js.map +1 -0
  42. package/dist/chunk-RX2RXHBH.js +1699 -0
  43. package/dist/chunk-RX2RXHBH.js.map +1 -0
  44. package/dist/chunk-SEXU2WYG.js +788 -0
  45. package/dist/chunk-SEXU2WYG.js.map +1 -0
  46. package/dist/chunk-SUGSQ4YI.js +264 -0
  47. package/dist/chunk-SUGSQ4YI.js.map +1 -0
  48. package/dist/chunk-TGXFVAID.js +138 -0
  49. package/dist/chunk-TGXFVAID.js.map +1 -0
  50. package/dist/chunk-WLBNFVIG.js +447 -0
  51. package/dist/chunk-WLBNFVIG.js.map +1 -0
  52. package/dist/chunk-XLTCUH5A.js +1072 -0
  53. package/dist/chunk-XLTCUH5A.js.map +1 -0
  54. package/dist/chunk-YVRWVDIA.js +146 -0
  55. package/dist/chunk-YVRWVDIA.js.map +1 -0
  56. package/dist/chunk-ZEC4LRKS.js +176 -0
  57. package/dist/chunk-ZEC4LRKS.js.map +1 -0
  58. package/dist/cli.d.ts +1 -0
  59. package/dist/cli.js +1084 -0
  60. package/dist/cli.js.map +1 -0
  61. package/dist/config-NwoZC-GM.d.ts +20 -0
  62. package/dist/db.d.ts +46 -0
  63. package/dist/db.js +15 -0
  64. package/dist/db.js.map +1 -0
  65. package/dist/doctor.d.ts +37 -0
  66. package/dist/doctor.js +14 -0
  67. package/dist/doctor.js.map +1 -0
  68. package/dist/hooks/handler.d.ts +23 -0
  69. package/dist/hooks/handler.js +295 -0
  70. package/dist/hooks/handler.js.map +1 -0
  71. package/dist/index.d.ts +57 -0
  72. package/dist/index.js +101 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/mcp/server.d.ts +1 -0
  75. package/dist/mcp/server.js +243 -0
  76. package/dist/mcp/server.js.map +1 -0
  77. package/dist/otlp/server.d.ts +7 -0
  78. package/dist/otlp/server.js +17 -0
  79. package/dist/otlp/server.js.map +1 -0
  80. package/dist/permissions.d.ts +33 -0
  81. package/dist/permissions.js +14 -0
  82. package/dist/permissions.js.map +1 -0
  83. package/dist/pricing.d.ts +29 -0
  84. package/dist/pricing.js +13 -0
  85. package/dist/pricing.js.map +1 -0
  86. package/dist/proxy/server.d.ts +10 -0
  87. package/dist/proxy/server.js +20 -0
  88. package/dist/proxy/server.js.map +1 -0
  89. package/dist/prune.d.ts +18 -0
  90. package/dist/prune.js +13 -0
  91. package/dist/prune.js.map +1 -0
  92. package/dist/query.d.ts +56 -0
  93. package/dist/query.js +27 -0
  94. package/dist/query.js.map +1 -0
  95. package/dist/reparse-636YZCE3.js +14 -0
  96. package/dist/reparse-636YZCE3.js.map +1 -0
  97. package/dist/repo.d.ts +17 -0
  98. package/dist/repo.js +9 -0
  99. package/dist/repo.js.map +1 -0
  100. package/dist/scanner.d.ts +73 -0
  101. package/dist/scanner.js +15 -0
  102. package/dist/scanner.js.map +1 -0
  103. package/dist/sdk.d.ts +82 -0
  104. package/dist/sdk.js +208 -0
  105. package/dist/sdk.js.map +1 -0
  106. package/dist/server.d.ts +5 -0
  107. package/dist/server.js +25 -0
  108. package/dist/server.js.map +1 -0
  109. package/dist/setup.d.ts +35 -0
  110. package/dist/setup.js +19 -0
  111. package/dist/setup.js.map +1 -0
  112. package/dist/sync/index.d.ts +29 -0
  113. package/dist/sync/index.js +32 -0
  114. package/dist/sync/index.js.map +1 -0
  115. package/dist/targets.d.ts +279 -0
  116. package/dist/targets.js +20 -0
  117. package/dist/targets.js.map +1 -0
  118. package/dist/types-D-MYCBol.d.ts +128 -0
  119. package/dist/types.d.ts +164 -0
  120. package/dist/types.js +1 -0
  121. package/dist/types.js.map +1 -0
  122. package/hooks/hooks.json +274 -0
  123. package/package.json +124 -0
  124. package/skills/panopticon-optimize/SKILL.md +222 -0
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "panopticon",
3
+ "description": "Observability for Claude Code — captures OTel signals and hook events, queryable via MCP",
4
+ "mcpServers": {
5
+ "panopticon": {
6
+ "command": "node",
7
+ "args": ["${CLAUDE_PLUGIN_ROOT}/bin/mcp-server"]
8
+ }
9
+ }
10
+ }
package/LICENSE ADDED
@@ -0,0 +1,5 @@
1
+ Copyright (c) 2025 FML Labs Inc. All rights reserved.
2
+
3
+ This software is proprietary and confidential. No part of this software may be
4
+ reproduced, distributed, or transmitted in any form or by any means without the
5
+ prior written permission of the copyright holder.
package/README.md ADDED
@@ -0,0 +1,363 @@
1
+ # Panopticon
2
+
3
+ <div align="center">
4
+ <img src="panopticon.jpg" alt="Panopticon — Willey Reveley, 1791" width="480">
5
+ <br>
6
+ <em>Elevation and plan of Jeremy Bentham's Panopticon, drawn by Willey Reveley in 1791</em>
7
+ </div>
8
+
9
+ <br>
10
+
11
+ Self-contained observability for AI coding tools. Captures OpenTelemetry signals, hook events, API traffic, and local session files from Claude Code, Gemini CLI, and Codex CLI — stored in SQLite, queryable via MCP.
12
+
13
+ No Docker, no external services. Just Node.js.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm install -g @fml-inc/panopticon
19
+ panopticon install
20
+ ```
21
+
22
+ This initializes the database, registers hooks and MCP servers in each detected tool, and configures OTel environment variables in your shell. Start a new session to activate.
23
+
24
+ To install for a specific tool only:
25
+
26
+ ```bash
27
+ panopticon install --target claude
28
+ panopticon install --target gemini
29
+ panopticon install --target codex
30
+ panopticon install --target claude-desktop
31
+ ```
32
+
33
+ Options:
34
+
35
+ | Flag | Description |
36
+ |------|-------------|
37
+ | `--target <t>` | Target: `claude`, `gemini`, `codex`, `claude-desktop`, or `all` (default: `all`) |
38
+ | `--proxy` | Route API traffic through the panopticon proxy |
39
+ | `--force` | Overwrite customized env vars with defaults |
40
+
41
+ ### From source
42
+
43
+ ```bash
44
+ git clone https://github.com/fml-inc/panopticon.git && cd panopticon
45
+ pnpm install && pnpm build
46
+ npm pack
47
+ npm install -g ./fml-inc-panopticon-*.tgz
48
+ panopticon install
49
+ ```
50
+
51
+ ## How it works
52
+
53
+ ```
54
+ ┌──────────────────────────────────────────────────────────────┐
55
+ │ Claude Code / Gemini CLI / Codex CLI │
56
+ │ │
57
+ │ ┌──────────┐ ┌──────────────┐ ┌───────────┐ ┌────────┐ │
58
+ │ │ OTel SDK │ │ Plugin Hooks │ │ Session │ │ API │ │
59
+ │ │ │ │ │ │ Files │ │ Proxy │ │
60
+ │ └────┬─────┘ └──────┬───────┘ └─────┬─────┘ └───┬────┘ │
61
+ └───────┼───────────────┼───────────────┼──────────────┼───────┘
62
+ │ │ │ │
63
+ ▼ ▼ │ ▼
64
+ ┌───────────────────────────────────────┼──────────────────────┐
65
+ │ Unified Panopticon Server (:4318) │
66
+ │ │ │
67
+ │ /v1/logs, /v1/metrics /hooks │ /proxy/anthropic │
68
+ │ (OTLP ingest) (hook JSON) │ /proxy/openai │
69
+ │ │ /proxy/google │
70
+ └──────────────────────┬────────────────┼──────────────────────┘
71
+ │ │
72
+ ▼ ▼
73
+ ┌─────────────────────────────────────┐
74
+ │ SQLite (WAL mode) │
75
+ │ │
76
+ │ sessions (unified, all sources) │
77
+ │ hook_events / otel_logs / metrics │
78
+ │ scanner_turns / scanner_events │
79
+ └──┬──────────┬──────────────┬────────┘
80
+ │ │ │
81
+ ▼ ▼ ▼
82
+ ┌──────────┐ ┌──────────┐ ┌───────────┐
83
+ │ MCP │ │ Sync │ │ Scanner │
84
+ │ Server │ │ Loop │ │ Loop │
85
+ │ (stdio) │ │ (OTLP) │ │ (60s poll)│
86
+ └──────────┘ └──────────┘ └───────────┘
87
+ ```
88
+
89
+ **Five data pipelines feed one database:**
90
+
91
+ 1. **Hook events** — Plugin hooks capture SessionStart, tool use (pre/post), prompts, and session end. Rich payloads including tool inputs and outputs.
92
+
93
+ 2. **OTel logs** — Native telemetry events: API requests/responses, tool calls, user prompts, config, model routing. Includes cost, token counts, durations, model info.
94
+
95
+ 3. **OTel metrics** — Time series: `token.usage`, `cost.usage`, `session.count`, `active_time.total`, `lines_of_code.count`, `commit.count`, `pull_request.count`.
96
+
97
+ 4. **Session file scanner** — Reads local JSONL/JSON session files written by each CLI. Extracts per-turn token usage (input, output, cache read, cache creation, reasoning), tool calls, API errors, agent reasoning, and file snapshots. More complete than OTel for token data (captures ~2x the turns) and provides historical backfill for sessions before panopticon was installed.
98
+
99
+ 5. **API proxy** — Transparent HTTP proxy for Anthropic, OpenAI, and Google AI APIs. Captures request/response pairs and emits them as hook events and OTel data. Enable with `panopticon install --proxy`.
100
+
101
+ All pipelines feed a **unified sessions table** — each session accumulates data from whichever sources are active, in any order, via COALESCE upserts.
102
+
103
+ **Sync** (optional) — OTLP export that tails the local SQLite and POSTs merged events to a remote OTLP receiver. Useful for forwarding to Grafana, Honeycomb, Datadog, etc.
104
+
105
+ **Scanner** — Polls local CLI session files every 60 seconds. Extracts per-turn token usage and events that OTel misses (reasoning tokens, cache breakdowns, tool calls with arguments/output, API errors with retry metadata). Backfills historical sessions from before panopticon was installed.
106
+
107
+ ## Supported tools
108
+
109
+ | Tool | Hooks | OTel | Scanner | Proxy | Notes |
110
+ |------|-------|------|---------|-------|-------|
111
+ | Claude Code | Plugin marketplace | Native OTel SDK | `~/.claude/projects/` JSONL | Anthropic API | Full coverage; scanner captures API errors, file snapshots |
112
+ | Gemini CLI | `settings.json` hooks | Native OTel SDK (HTTP) | `~/.gemini/tmp/` JSON | Google AI API | Scanner captures tool calls, reasoning thoughts |
113
+ | Codex CLI | `hooks.json` | Native OTel SDK (HTTP) | `~/.codex/sessions/` JSONL | OpenAI API | Scanner captures tool calls, reasoning tokens, agent messages |
114
+ | Claude Desktop | MCP server | — | — | — | MCP query tools only |
115
+
116
+ Each tool is implemented as a **target adapter** in `src/targets/`. To add support for a new tool, create a single adapter file that declares config paths, hook events, shell env vars, event normalization, detection logic, and proxy routing — then register it in `src/targets/index.ts`.
117
+
118
+ ## MCP tools
119
+
120
+ Once installed, these tools are available to the AI coding tool via MCP:
121
+
122
+ | Tool | Description |
123
+ |------|-------------|
124
+ | `panopticon_sessions` | List recent sessions with stats (event count, tools used, cost) |
125
+ | `panopticon_session_timeline` | Chronological events for a session (hooks + OTel merged) |
126
+ | `panopticon_tool_stats` | Per-tool aggregates: call count, success/failure |
127
+ | `panopticon_costs` | Token/cost breakdowns by session, model, or day |
128
+ | `panopticon_summary` | Activity summary for a time window (sessions, prompts, tools, files, costs) |
129
+ | `panopticon_plans` | Plans created via ExitPlanMode with full markdown content |
130
+ | `panopticon_search` | Full-text search across hook payloads (FTS5) and OTel log bodies |
131
+ | `panopticon_get_event` | Fetch full untruncated details for a specific event by source and ID |
132
+ | `panopticon_query` | Raw read-only SQL against the database |
133
+ | `panopticon_status` | Database row counts |
134
+ | `panopticon_permissions_show` | Show current permission approvals and allowed tools/commands |
135
+ | `panopticon_permissions_apply` | Apply permission rules (allowed tools/commands via PreToolUse hook) |
136
+
137
+ ## CLI
138
+
139
+ ```
140
+ panopticon install Register hooks, init DB, configure shell
141
+ --target <t> Target: claude, gemini, codex, claude-desktop, all (default: all)
142
+ --proxy Route API traffic through the panopticon proxy
143
+ --force Overwrite customized env vars with defaults
144
+
145
+ panopticon uninstall Remove hooks, shell config, and optionally all data
146
+ --target <t> Uninstall from a specific target only
147
+ --purge Also remove database and all data
148
+
149
+ panopticon update Show instructions to update via npm
150
+
151
+ panopticon start Start the server (background)
152
+ panopticon stop Stop the server
153
+ panopticon status Show server status and database stats
154
+ panopticon doctor Check system health, server, database, and configuration
155
+
156
+ panopticon logs [daemon] View daemon logs (server, otlp, mcp, proxy)
157
+ -f, --follow Follow log output (like tail -f)
158
+ -n <lines> Number of lines to show (default 50)
159
+
160
+ panopticon sessions List recent sessions with stats
161
+ --limit <n> Max sessions to return (default 20)
162
+ --since <duration> Time filter (e.g. "24h", "7d")
163
+ panopticon timeline <id> Chronological events for a session
164
+ panopticon tools Per-tool usage aggregates
165
+ panopticon costs Token usage and cost breakdowns
166
+ --group-by <g> Group by session, model, or day
167
+ panopticon summary Activity summary
168
+ panopticon plans List plans from ExitPlanMode events
169
+ panopticon search <query> Full-text search across all events
170
+ panopticon event <src> <id> Get full details for a specific event
171
+ panopticon query <sql> Raw read-only SQL query
172
+ panopticon db-stats Show database row counts
173
+
174
+ panopticon scan Scan local session files (incremental)
175
+ panopticon scan reset Reset scanner and re-scan from scratch
176
+ [source] Optionally reset only: claude, codex, gemini
177
+ panopticon scan compare Compare scanner data against hooks/OTLP data
178
+
179
+ panopticon prune Delete old data from the database
180
+ --older-than 30d Max age (default: 30d)
181
+ --dry-run Show estimate without deleting
182
+ --vacuum Reclaim disk space after pruning
183
+ --yes Skip confirmation prompt
184
+
185
+ panopticon refresh-pricing Fetch latest model pricing from OpenRouter
186
+ panopticon permissions show Show current approval rules
187
+ panopticon permissions apply Apply permission rules (JSON from stdin)
188
+ ```
189
+
190
+ The server auto-starts on `SessionStart` via hook, so manual start/stop is rarely needed.
191
+
192
+ ## Logs
193
+
194
+ Daemon stdout/stderr is written to platform-specific log directories:
195
+
196
+ | Platform | Path |
197
+ |----------|------|
198
+ | macOS | `~/Library/Logs/panopticon/` |
199
+ | Linux | `~/.local/state/panopticon/logs/` |
200
+ | Windows | `%LOCALAPPDATA%/panopticon/logs/` |
201
+
202
+ Log files: `server.log`, `mcp-server.log`, `hook-handler.log`, `proxy.log`.
203
+
204
+ ## Configuration
205
+
206
+ **Environment variables** set by `panopticon install` in your shell profile:
207
+
208
+ ```bash
209
+ # Shared OTel (always set)
210
+ OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
211
+ OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
212
+ OTEL_METRICS_EXPORTER=otlp
213
+ OTEL_LOGS_EXPORTER=otlp
214
+ OTEL_LOG_TOOL_DETAILS=1
215
+ OTEL_LOG_USER_PROMPTS=1
216
+ OTEL_METRIC_EXPORT_INTERVAL=10000
217
+
218
+ # Target-specific (set per --target)
219
+ CLAUDE_CODE_ENABLE_TELEMETRY=1 # Claude Code
220
+ ANTHROPIC_BASE_URL=http://localhost:4318/proxy/anthropic # Claude Code (--proxy only)
221
+ GEMINI_TELEMETRY_ENABLED=true # Gemini CLI
222
+ GEMINI_TELEMETRY_TARGET=local # Gemini CLI
223
+ GEMINI_TELEMETRY_OTLP_ENDPOINT=http://localhost:4318 # Gemini CLI
224
+ GEMINI_TELEMETRY_OTLP_PROTOCOL=http # Gemini CLI
225
+ GEMINI_TELEMETRY_LOG_PROMPTS=true # Gemini CLI
226
+ ```
227
+
228
+ Target-specific env vars are declared by each target adapter in `src/targets/`.
229
+
230
+ **Server configuration:**
231
+
232
+ | Env var | Default | Description |
233
+ |---|---|---|
234
+ | `PANOPTICON_DATA_DIR` | Platform-specific (see below) | Data directory |
235
+ | `PANOPTICON_PORT` | `4318` | Unified server port |
236
+ | `PANOPTICON_HOST` | `127.0.0.1` | Server bind address |
237
+
238
+ Data directory defaults:
239
+
240
+ | Platform | Path |
241
+ |----------|------|
242
+ | macOS | `~/Library/Application Support/panopticon/` |
243
+ | Linux | `~/.local/share/panopticon/` |
244
+ | Windows | `%APPDATA%/panopticon/` |
245
+
246
+ ## Database
247
+
248
+ SQLite with WAL mode. Location depends on platform (see data directory above).
249
+
250
+ | Table | Description |
251
+ |-------|-------------|
252
+ | `sessions` | Unified session metadata — aggregated from hooks, OTel, and scanner |
253
+ | `otel_logs` | OTel log records (api_request, tool_result, user_prompt, etc.) |
254
+ | `otel_metrics` | OTel metric data points (token usage, cost, active time, etc.) |
255
+ | `hook_events` | Plugin hook events with full payloads (tool inputs/outputs, tool results) |
256
+ | `hook_events_fts` | FTS5 full-text search index on hook payloads |
257
+ | `scanner_turns` | Per-turn token usage from session files (input, output, cache, reasoning) |
258
+ | `scanner_events` | Tool calls, errors, reasoning, file snapshots from session files |
259
+ | `scanner_file_watermarks` | Byte offsets for incremental session file parsing |
260
+ | `session_repositories` | Maps sessions to GitHub repositories |
261
+ | `session_cwds` | Maps sessions to working directories |
262
+ | `model_pricing` | Cached model pricing from OpenRouter |
263
+ | `schema_meta` | Internal schema version tracking |
264
+
265
+ Query directly with `panopticon query` or via the `panopticon_query` MCP tool.
266
+
267
+ ## Development
268
+
269
+ ```bash
270
+ pnpm install # Install dependencies
271
+ pnpm dev # Watch mode (tsup)
272
+ pnpm check # Lint (Biome)
273
+ pnpm typecheck # Type check
274
+ pnpm test # Run tests (Vitest)
275
+ ```
276
+
277
+ To test the full install flow:
278
+
279
+ ```bash
280
+ pnpm build && npm pack
281
+ npm install -g ./fml-inc-panopticon-*.tgz
282
+ panopticon install --target claude
283
+ ```
284
+
285
+ ## Architecture
286
+
287
+ ```
288
+ src/
289
+ ├── cli.ts CLI entry point (install, uninstall, start/stop, query commands)
290
+ ├── server.ts Unified HTTP server (hooks, OTLP, proxy — single port)
291
+ ├── sdk.ts SDK shim (observe() wrapper)
292
+ ├── config.ts Panopticon paths, ports, defaults
293
+ ├── log.ts Log file paths (macOS/Linux/Windows)
294
+ ├── repo.ts Git repository detection
295
+ ├── toml.ts TOML read/write (for Codex config)
296
+ ├── targets/
297
+ │ ├── types.ts TargetAdapter interface (config, hooks, events, detect, proxy)
298
+ │ ├── registry.ts Map-based target registry (register, get, all)
299
+ │ ├── index.ts Barrel — re-exports + registers all built-in targets
300
+ │ ├── claude.ts Claude Code adapter
301
+ │ ├── claude-desktop.ts Claude Desktop adapter
302
+ │ ├── gemini.ts Gemini CLI adapter
303
+ │ └── codex.ts Codex CLI adapter
304
+ ├── db/
305
+ │ ├── schema.ts SQLite schema, migrations, WAL + auto-vacuum
306
+ │ ├── query.ts Query helpers for MCP tools and CLI
307
+ │ ├── store.ts Data storage (insert hooks, OTel, upsert sessions)
308
+ │ ├── prune.ts Data retention / pruning
309
+ │ └── pricing.ts Model pricing cache (OpenRouter)
310
+ ├── scanner/
311
+ │ ├── index.ts Public API (createScannerLoop, scanOnce)
312
+ │ ├── loop.ts Poll loop — discovers files via target adapters, incremental parse
313
+ │ ├── reader.ts Byte-offset file reader (only reads new lines)
314
+ │ ├── store.ts Scanner DB operations (turns, events, watermarks, session upsert)
315
+ │ ├── reconcile.ts Compare scanner vs hooks/OTLP token data per session
316
+ │ └── types.ts ScannerHandle, ScannerOptions
317
+ ├── hooks/
318
+ │ ├── handler.ts Hook event handler (stdin JSON → server)
319
+ │ ├── ingest.ts Hook processing — uses target adapters for normalization
320
+ │ └── permissions.ts PreToolUse permission enforcement
321
+ ├── mcp/
322
+ │ ├── server.ts MCP server with query tools
323
+ │ └── permissions.ts Permission management MCP tools
324
+ ├── otlp/
325
+ │ ├── server.ts HTTP OTLP receiver (protobuf + JSON)
326
+ │ ├── decode-logs.ts OTel log record decoding
327
+ │ ├── decode-metrics.ts OTel metric decoding
328
+ │ └── proto.ts Protocol buffer definitions
329
+ ├── sync/
330
+ │ ├── index.ts Public API (createSyncLoop, resetWatermarks)
331
+ │ ├── types.ts Interfaces (SyncTarget, SyncOptions, MergedEvent, OTLP types)
332
+ │ ├── loop.ts Poll loop with debounced scheduling
333
+ │ ├── reader.ts Batch reads from SQLite + hook/OTLP dedup
334
+ │ ├── serialize.ts Convert rows → OTLP JSON (resourceLogs, resourceMetrics)
335
+ │ ├── watermark.ts Watermark persistence (sync-watermarks.db)
336
+ │ └── post.ts HTTP POST with retry + exponential backoff
337
+ └── proxy/
338
+ ├── server.ts API proxy — routes built from target registry
339
+ ├── emit.ts Event emission from proxy captures
340
+ ├── streaming.ts SSE stream accumulation (Anthropic + OpenAI)
341
+ ├── sessions.ts Proxy session tracking
342
+ └── formats/
343
+ ├── types.ts Format parser interface
344
+ ├── anthropic.ts Anthropic Messages API parser
345
+ ├── openai.ts OpenAI Chat Completions parser
346
+ └── openai-responses.ts OpenAI Responses API parser
347
+ ```
348
+
349
+ ### Target adapters
350
+
351
+ Each supported coding tool is a self-contained adapter in `src/targets/`. An adapter declares:
352
+
353
+ | Concern | What it specifies |
354
+ |---------|-------------------|
355
+ | **Config** | Directory, config file path, format (JSON/TOML) |
356
+ | **Hooks** | Event names, install-time config merge, uninstall cleanup |
357
+ | **Shell env** | Target-specific env vars for the shell profile |
358
+ | **Events** | Event name mapping to canonical types, payload normalization, permission response format |
359
+ | **Detection** | Display name, `isInstalled()`, `isConfigured()` for doctor |
360
+ | **Proxy** | Upstream host (static or dynamic), path rewriting, accumulator type |
361
+ | **Scanner** | `discover()` finds session files on disk, `parseFile()` extracts turns + events |
362
+
363
+ To add a new target, create `src/targets/<name>.ts`, implement `TargetAdapter`, call `registerTarget()`, and add the import to `src/targets/index.ts`. All consumers (install, uninstall, doctor, hooks, proxy, shell env, scanner) pick it up automatically.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import("../dist/hooks/handler.js");
package/bin/mcp-server ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import("../dist/mcp/server.js");
package/bin/panopticon ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import("../dist/cli.js");
package/bin/proxy ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import("../dist/proxy/server.js");
package/bin/server ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import("../dist/server.js");
@@ -0,0 +1,67 @@
1
+ import { ActivitySummaryResult, SpendingResult, SessionListResult, SearchResult, SessionTimelineResult } from '../types.js';
2
+
3
+ declare function callTool(name: string, params?: Record<string, unknown>): Promise<unknown>;
4
+ declare function listSessions(opts?: {
5
+ limit?: number;
6
+ since?: string;
7
+ }): Promise<SessionListResult>;
8
+ declare function sessionTimeline(opts: {
9
+ sessionId: string;
10
+ limit?: number;
11
+ offset?: number;
12
+ fullPayloads?: boolean;
13
+ }): Promise<SessionTimelineResult>;
14
+ declare function costBreakdown(opts?: {
15
+ since?: string;
16
+ groupBy?: "session" | "model" | "day";
17
+ }): Promise<SpendingResult>;
18
+ declare function activitySummary(opts?: {
19
+ since?: string;
20
+ }): Promise<ActivitySummaryResult>;
21
+ declare function listPlans(opts?: {
22
+ session_id?: string;
23
+ since?: string;
24
+ limit?: number;
25
+ }): Promise<unknown>;
26
+ declare function search(opts: {
27
+ query: string;
28
+ eventTypes?: string[];
29
+ since?: string;
30
+ limit?: number;
31
+ offset?: number;
32
+ fullPayloads?: boolean;
33
+ }): Promise<SearchResult>;
34
+ declare function print(opts: {
35
+ source: "hook" | "otel" | "message";
36
+ id: number;
37
+ }): Promise<unknown>;
38
+ declare function rawQuery(sql: string): Promise<unknown>;
39
+ declare function dbStats(): Promise<unknown>;
40
+ declare function callExec(command: string, params?: Record<string, unknown>): Promise<unknown>;
41
+ declare function pruneEstimate(cutoffMs: number): Promise<unknown>;
42
+ declare function pruneExecute(cutoffMs: number, opts?: {
43
+ vacuum?: boolean;
44
+ }): Promise<unknown>;
45
+ declare function refreshPricing(): Promise<unknown>;
46
+ declare function syncReset(target?: string): Promise<unknown>;
47
+ declare function syncWatermarkGet(target: string, table?: string): Promise<unknown>;
48
+ declare function syncWatermarkSet(target: string, table: string, value: number): Promise<unknown>;
49
+ declare function syncPending(target: string): Promise<{
50
+ target: string;
51
+ totalPending: number;
52
+ tables: Record<string, {
53
+ maxId: number;
54
+ watermark: number;
55
+ pending: number;
56
+ }>;
57
+ }>;
58
+ declare function syncTargetList(): Promise<unknown>;
59
+ declare function syncTargetAdd(target: {
60
+ name: string;
61
+ url: string;
62
+ token?: string;
63
+ tokenCommand?: string;
64
+ }): Promise<unknown>;
65
+ declare function syncTargetRemove(name: string): Promise<unknown>;
66
+
67
+ export { activitySummary, callExec, callTool, costBreakdown, dbStats, listPlans, listSessions, print, pruneEstimate, pruneExecute, rawQuery, refreshPricing, search, sessionTimeline, syncPending, syncReset, syncTargetAdd, syncTargetList, syncTargetRemove, syncWatermarkGet, syncWatermarkSet };
@@ -0,0 +1,48 @@
1
+ import {
2
+ activitySummary,
3
+ callExec,
4
+ callTool,
5
+ costBreakdown,
6
+ dbStats,
7
+ listPlans,
8
+ listSessions,
9
+ print,
10
+ pruneEstimate,
11
+ pruneExecute,
12
+ rawQuery,
13
+ refreshPricing,
14
+ search,
15
+ sessionTimeline,
16
+ syncPending,
17
+ syncReset,
18
+ syncTargetAdd,
19
+ syncTargetList,
20
+ syncTargetRemove,
21
+ syncWatermarkGet,
22
+ syncWatermarkSet
23
+ } from "../chunk-4SM2H22C.js";
24
+ import "../chunk-K7YUPLES.js";
25
+ export {
26
+ activitySummary,
27
+ callExec,
28
+ callTool,
29
+ costBreakdown,
30
+ dbStats,
31
+ listPlans,
32
+ listSessions,
33
+ print,
34
+ pruneEstimate,
35
+ pruneExecute,
36
+ rawQuery,
37
+ refreshPricing,
38
+ search,
39
+ sessionTimeline,
40
+ syncPending,
41
+ syncReset,
42
+ syncTargetAdd,
43
+ syncTargetList,
44
+ syncTargetRemove,
45
+ syncWatermarkGet,
46
+ syncWatermarkSet
47
+ };
48
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}