@scrylog/cli 0.4.2 → 0.5.1
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/README.md +175 -97
- package/dist/cli/assets/providers/SOURCES.md +9 -9
- package/dist/cli/index.js +349 -220
- package/dist/cli/index.js.map +43 -38
- package/dist/daemon/index.js +580 -517
- package/dist/daemon/index.js.map +144 -220
- package/dist/hooks/claude.js +3 -3
- package/dist/hooks/claude.js.map +4 -4
- package/dist/hooks/codex.js +6 -6
- package/dist/hooks/codex.js.map +4 -4
- package/dist/mcp/index.js +39 -39
- package/dist/mcp/index.js.map +23 -22
- package/dist/oc/index.js +3 -3
- package/dist/oc/index.js.map +3 -3
- package/package.json +49 -36
- package/src/postinstall.cjs +8 -8
package/README.md
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
# scrylog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**scrylog** monitors AI coding sessions from Claude Code, Codex, and OpenCode in one terminal dashboard: session states, required attention, provider usage limits, and optional Telegram notifications, with REST/SSE and MCP access for integrations.
|
|
4
|
+
|
|
5
|
+
Sessions are discovered as standalone processes or through `tmux` and herdr. `tmux` is optional — every collector degrades gracefully when its source is absent.
|
|
4
6
|
|
|
5
7
|
It ships four commands:
|
|
6
8
|
|
|
7
|
-
| Command
|
|
8
|
-
|
|
|
9
|
-
| `scrylog`
|
|
10
|
-
| `scrylogd`
|
|
9
|
+
| Command | Purpose |
|
|
10
|
+
| ------------- | ----------------------------------------- |
|
|
11
|
+
| `scrylog` | TUI dashboard and operator CLI |
|
|
12
|
+
| `scrylogd` | Foreground daemon process |
|
|
11
13
|
| `scrylog-mcp` | stdio MCP server that proxies daemon data |
|
|
12
|
-
| `oc`
|
|
14
|
+
| `oc` | OpenCode launcher and attach helper |
|
|
13
15
|
|
|
14
16
|
## Features
|
|
15
17
|
|
|
18
|
+
- Claude Code session monitoring via transcript collection
|
|
19
|
+
- Codex session monitoring via transcript collection and hook-based state tracking
|
|
20
|
+
- OpenCode integration in `hooks` or `sse` mode, with SQLite-based session enrichment
|
|
21
|
+
- Session states (`working`, `idle`, `waiting-input`, `error`) and permission/question attention visibility
|
|
22
|
+
- Provider usage and subscription limits for Claude, Codex, and OpenCode Go, on the dashboard and `GET /api/usage`
|
|
23
|
+
- Telegram notifications for session events and usage alerts, including `user-idle` delivery gating
|
|
16
24
|
- `tmux` monitoring for OpenCode, Codex, Copilot, and shell panes
|
|
17
25
|
- herdr default-session monitoring through its structured agent and pane API
|
|
18
|
-
- OpenCode integration in `hooks` or `sse` mode
|
|
19
|
-
- Claude transcript collection
|
|
20
|
-
- Codex transcript collection and hook-based state tracking
|
|
21
26
|
- Local daemon with Unix socket IPC on macOS and Linux, TCP fallback on Windows
|
|
22
27
|
- Optional TCP REST API exposure (enabled by default on Windows)
|
|
23
28
|
- Optional MCP HTTP exposure with bearer token support
|
|
@@ -27,6 +32,8 @@ It ships four commands:
|
|
|
27
32
|
|
|
28
33
|
## Requirements
|
|
29
34
|
|
|
35
|
+
Only [Bun](https://bun.sh) is required. The rest are optional per data source, and their absence is handled automatically:
|
|
36
|
+
|
|
30
37
|
- [Bun](https://bun.sh) `>= 1.3.0`
|
|
31
38
|
- `tmux` if you want `tmux` monitoring
|
|
32
39
|
- [herdr](https://herdr.dev) if you want herdr monitoring; absence is handled automatically
|
|
@@ -35,41 +42,106 @@ It ships four commands:
|
|
|
35
42
|
|
|
36
43
|
## Platform Support
|
|
37
44
|
|
|
38
|
-
| Tier
|
|
39
|
-
|
|
|
40
|
-
| Tier 1 | macOS
|
|
41
|
-
| Tier 2 | Linux / WSL 2
|
|
45
|
+
| Tier | Platform | Status | Notes |
|
|
46
|
+
| ------ | ---------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
47
|
+
| Tier 1 | macOS | Tested daily | Full feature set including Keychain OAuth and Safari cookies |
|
|
48
|
+
| Tier 2 | Linux / WSL 2 | Compatible | Claude OAuth via `~/.claude/.credentials.json`, Chrome/Chromium cookies, systemd service when available |
|
|
42
49
|
| Tier 3 | Windows (native) | Experimental / not recommended | TCP IPC, `wmic` process scan, degraded service status. Chrome cookie decryption not available (DPAPI not implemented). Primary use is ad-hoc debugging, not daily monitoring. |
|
|
43
50
|
|
|
44
51
|
## Terminal Icon Rendering
|
|
45
52
|
|
|
46
53
|
The Usage view renders provider icons with one of these values for `tui.providerIcons`:
|
|
47
54
|
|
|
48
|
-
| Mode
|
|
49
|
-
|
|
|
50
|
-
| `blocks` (default) | Bundled pixel-art PNGs rendered with Unicode half-blocks on the Usage cards. Works in any terminal, including multiplexers.
|
|
51
|
-
| `graphics`
|
|
52
|
-
| `kitty` / `sixel`
|
|
53
|
-
| `text`
|
|
55
|
+
| Mode | Behavior |
|
|
56
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
57
|
+
| `blocks` (default) | Bundled pixel-art PNGs rendered with Unicode half-blocks on the Usage cards. Works in any terminal, including multiplexers. |
|
|
58
|
+
| `graphics` | Full artwork. Probes the terminal (`XTVERSION`, kitty graphics query, Sixel support) and falls back to `blocks` when nothing is confirmed. |
|
|
59
|
+
| `kitty` / `sixel` | Force a specific image protocol even when detection does not confirm it (useful for terminals whose detection response is ambiguous). |
|
|
60
|
+
| `text` | Two-letter provider monogram on Usage cards. Never uses images. |
|
|
54
61
|
|
|
55
62
|
In the sessions list the Tool column also depends on the mode: image modes render 2x1-cell mini icons, `blocks` shows the colored brand monogram (`CL`, `CX`, `OC`, ...) plus child-session badges, and `text` keeps the full tool name. Press `?` in the dashboard to see a legend mapping each icon or monogram to its tool name (legend shown only when an image mode is active).
|
|
56
63
|
|
|
57
64
|
Compatibility of `graphics` by environment:
|
|
58
65
|
|
|
59
|
-
| Environment
|
|
60
|
-
|
|
|
61
|
-
| Ghostty
|
|
62
|
-
| Kitty
|
|
63
|
-
| WezTerm
|
|
64
|
-
| iTerm2
|
|
65
|
-
| Konsole, Foot
|
|
66
|
-
| Direct SSH (no multiplexer)
|
|
67
|
-
| tmux / herdr
|
|
68
|
-
| Alacritty, Terminal.app, GNOME Terminal | No
|
|
69
|
-
| Windows native (Tier 3)
|
|
66
|
+
| Environment | Works | Detail |
|
|
67
|
+
| --------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
68
|
+
| Ghostty | Yes | Kitty graphics protocol (`TERM=xterm-ghostty`) |
|
|
69
|
+
| Kitty | Yes | Kitty graphics protocol (reference implementation) |
|
|
70
|
+
| WezTerm | Yes | Kitty graphics and Sixel |
|
|
71
|
+
| iTerm2 | Yes | Inline images and Sixel |
|
|
72
|
+
| Konsole, Foot | Yes | Sixel, requires pixel-resolution detection to confirm |
|
|
73
|
+
| Direct SSH (no multiplexer) | Yes | Inherits the local terminal's protocol support |
|
|
74
|
+
| tmux / herdr | Forced `blocks` | The multiplexer sits between the client and the terminal; passthrough is not reliable, so rendering degrades to `blocks` |
|
|
75
|
+
| Alacritty, Terminal.app, GNOME Terminal | No | No image protocol; falls back to `blocks` |
|
|
76
|
+
| Windows native (Tier 3) | No | Sixel support is partial/experimental; falls back to `blocks` |
|
|
70
77
|
|
|
71
78
|
Run `scrylog doctor` for a "Terminal graphics" section with detected capabilities and the recommended value for the current terminal.
|
|
72
79
|
|
|
80
|
+
## Notification Activity Sources
|
|
81
|
+
|
|
82
|
+
`user-idle` delivery modes gate notifications on user inactivity. scrylog supports two sources that answer "how long has the user been away?":
|
|
83
|
+
|
|
84
|
+
| Source (`notifications.activity.source`) | Signal | When to use |
|
|
85
|
+
| ---------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| `system` (default) | OS idle time (keyboard **and mouse movement**) | Normal desktops |
|
|
87
|
+
| `keyboard-clicks` | Key presses and mouse button press/release only | Machines where a utility or device jitters the mouse cursor to keep Slack/Teams presence "active" |
|
|
88
|
+
|
|
89
|
+
**Why the second source exists:** some users run a driver-level tool that moves the cursor a few pixels on a cycle so messaging apps never show "away". That synthetic movement is indistinguishable from real input and resets OS-wide idle time, so with the default `system` source the idle threshold is never reached and `user-idle` notifications never fire. The `keyboard-clicks` source ignores cursor movement and wheel events entirely; only key presses and mouse button clicks signal activity.
|
|
90
|
+
|
|
91
|
+
Enable it in the config:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"notifications": {
|
|
96
|
+
"enabled": true,
|
|
97
|
+
"activity": { "source": "keyboard-clicks" }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Backends per platform:
|
|
103
|
+
|
|
104
|
+
| Platform | Backend | Notes |
|
|
105
|
+
| ----------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
106
|
+
| macOS | `CGEventSource` query (poll-on-demand, via `bun:ffi`) | No helper process. Idle includes history before the daemon started. |
|
|
107
|
+
| Windows native | Resident PowerShell helper with low-level input hooks | One extra PowerShell process exists while the source is on; it exits when the daemon stops. |
|
|
108
|
+
| WSL 2 | Same PowerShell helper, running on the Windows host via interop | `powershell.exe` must be reachable from WSL (PATH or `/mnt/c/...`). |
|
|
109
|
+
| Linux (X11 and Wayland) | Read-only `evdev` drains of `/dev/input/event*` | Works under both X11 and Wayland compositors; requires the daemon user to be able to read input devices (usually the `input` group). |
|
|
110
|
+
|
|
111
|
+
Known limitations (they are the deliberate trade-off of ignoring cursor movement):
|
|
112
|
+
|
|
113
|
+
- Reading documentation, watching a presentation, or working with no keyboard presses or mouse clicks counts as idle under this source: expect a notification while you are still at the machine if you are not touching input.
|
|
114
|
+
- Media keys and special hardware buttons may not be reported by the OS as key presses; the idle clock stays valid but such events do not reset it.
|
|
115
|
+
- On Windows and Linux the activity clock starts when the daemon starts (observation begins with the notification service, before the first notification); input before that moment is unrecoverable, so an idle-before-start machine behaves as "unknown" and follows the channel's `onUnknown` policy. Backends keep running across the whole daemon lifetime once started, and a bounded heartbeat on Linux keeps the input queues healthy.
|
|
116
|
+
- `scrylog doctor` shows the configured source, the resolved backend, and any availability reason when `keyboard-clicks` is selected. On WSL, `powershell-hook (windows host, ready)` means a PowerShell candidate is reachable through interop; it does not verify that the running daemon's input hooks are installed or receiving events.
|
|
117
|
+
|
|
118
|
+
### Observed WSL behavior with an automatic mouse mover
|
|
119
|
+
|
|
120
|
+
In a user-reported manual test on WSL, the daemon was restarted after changing the activity source. The following notification behavior was observed:
|
|
121
|
+
|
|
122
|
+
| Activity source | Input during the test | Observed result |
|
|
123
|
+
| ----------------- | ------------------------------------------------------- | -------------------------- |
|
|
124
|
+
| `system` | Only movement from the automatic mouse-mover device | Notification was not sent. |
|
|
125
|
+
| `keyboard-clicks` | Only movement from the automatic mouse-mover device | Notification was sent. |
|
|
126
|
+
| `keyboard-clicks` | Manual mouse movement, without clicks or keyboard input | Notification was not sent. |
|
|
127
|
+
|
|
128
|
+
This was useful in the tested environment: automatic movement allowed notifications during the user's absence, while manual mouse use blocked them.
|
|
129
|
+
|
|
130
|
+
The distinction between manual and automatic movement is an observation, not an explicit capability of the implemented filter. The filter ignores mouse-movement and wheel events and observes key presses and mouse button events. The cause of the observed difference has not been determined, and this result has not been validated with other devices or platforms. Windows version, WSL version, device model, and input-event traces were not captured for this report.
|
|
131
|
+
|
|
132
|
+
### Verifying activity detection
|
|
133
|
+
|
|
134
|
+
To confirm the source is actually working, set `daemon.logLevel: "debug"` (with `daemon.logFileEnabled: true`) and watch the daemon log (`scrylog logs`) for these events — none of them ever log key content, coordinates, or event history:
|
|
135
|
+
|
|
136
|
+
| Event | Meaning |
|
|
137
|
+
| ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
138
|
+
| `notify.activity_observing` | Observation started; names the resolved backend |
|
|
139
|
+
| `notify.activity_first_input` | First key press or button click observed by the watcher (once per backend lifetime) |
|
|
140
|
+
| `notify.activity_gate` | A delivery gate decision: `idleMs`, `idleThresholdMs`, `activitySource`, event `kind`, and `outcome` (`send`, `defer`, `suppress`) |
|
|
141
|
+
| `notify.activity_backend_restarting` / `notify.activity_backend_failed` | The resident helper died and is restarting / exhausted its restart budget |
|
|
142
|
+
|
|
143
|
+
Expected trace for the artificial-cursor-movement case: a starting `notify.activity_observing`, then `notify.activity_first_input` when you next touch the keyboard or a button, `notify.activity_gate ... outcome: suppress` while only cursor moves happen, and `outcome: send` once real inactivity (movement ignored) reaches the threshold. If you only ever see `notify.activity_unknown`, the backend cannot observe input on your machine — the log reason and `scrylog doctor` will name what is missing.
|
|
144
|
+
|
|
73
145
|
## WSL 2 Notes
|
|
74
146
|
|
|
75
147
|
- The daemon runs as a Linux process and uses the same paths as native Linux.
|
|
@@ -169,28 +241,28 @@ By default, sessions whose tool could not be identified (`tool: "unknown"`) are
|
|
|
169
241
|
|
|
170
242
|
The dashboard header layout is configurable through `tui.headerLayout`, and the setup wizard prompts for the same preference:
|
|
171
243
|
|
|
172
|
-
| Value
|
|
173
|
-
|
|
|
174
|
-
| `auto`
|
|
175
|
-
| `horizontal` | Always keeps the header above Sessions and Usage.
|
|
176
|
-
| `vertical`
|
|
244
|
+
| Value | Behavior |
|
|
245
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
246
|
+
| `auto` | Uses a right or left sidebar below 33 rows when the terminal is at least 64 columns wide; otherwise uses the horizontal header. |
|
|
247
|
+
| `horizontal` | Always keeps the header above Sessions and Usage. |
|
|
248
|
+
| `vertical` | Always uses the 15-column sidebar, even below 64 columns. |
|
|
177
249
|
|
|
178
250
|
Set `tui.headerSide` to `left` or `right` to place the vertical header. The value is retained but ignored while the resolved layout is horizontal. While the sidebar is active, the tab row displays a compact colored `scrylog` label opposite Sessions and Usage. A forced vertical layout can significantly reduce or clip session content on narrow terminals.
|
|
179
251
|
|
|
180
252
|
Keyboard shortcuts:
|
|
181
253
|
|
|
182
|
-
| Key
|
|
183
|
-
|
|
|
184
|
-
| `↑` / `k`
|
|
185
|
-
| `↓` / `j`
|
|
186
|
-
| `Enter`
|
|
187
|
-
| `t`
|
|
188
|
-
| `/`
|
|
189
|
-
| `f`
|
|
190
|
-
| `a`
|
|
191
|
-
| `r`
|
|
192
|
-
| `Esc`
|
|
193
|
-
| `q` / `Ctrl+C` | Quit
|
|
254
|
+
| Key | Action |
|
|
255
|
+
| -------------- | ------------------------------------------ |
|
|
256
|
+
| `↑` / `k` | Move selection up |
|
|
257
|
+
| `↓` / `j` | Move selection down |
|
|
258
|
+
| `Enter` | Open session detail |
|
|
259
|
+
| `t` | Attach to selected `tmux` or herdr session |
|
|
260
|
+
| `/` | Search |
|
|
261
|
+
| `f` | Cycle filters |
|
|
262
|
+
| `a` | Show actionable sessions only |
|
|
263
|
+
| `r` | Refresh now |
|
|
264
|
+
| `Esc` | Close detail |
|
|
265
|
+
| `q` / `Ctrl+C` | Quit |
|
|
194
266
|
|
|
195
267
|
### Setup
|
|
196
268
|
|
|
@@ -273,11 +345,11 @@ Use the foreground daemon mainly for:
|
|
|
273
345
|
|
|
274
346
|
Logging options:
|
|
275
347
|
|
|
276
|
-
| Flag
|
|
277
|
-
|
|
|
278
|
-
| `--log-level debug|info|warn|error` | Override the configured minimum log level |
|
|
279
|
-
| `--log-format pretty|json`
|
|
280
|
-
| `--no-log-file`
|
|
348
|
+
| Flag | Purpose |
|
|
349
|
+
| -------------------- | -------------------------------------------------- | ---------------------------------------------- | ------ | ----------------------------------------- |
|
|
350
|
+
| `--log-level debug | info | warn | error` | Override the configured minimum log level |
|
|
351
|
+
| `--log-format pretty | json` | Override stderr output format for this process |
|
|
352
|
+
| `--no-log-file` | Disable daemon JSONL file logging for this process |
|
|
281
353
|
|
|
282
354
|
For normal daily use on macOS and Linux, prefer `scrylog daemon install` so the daemon starts automatically with your user session.
|
|
283
355
|
|
|
@@ -305,12 +377,12 @@ Example config:
|
|
|
305
377
|
"logFileEnabled": true,
|
|
306
378
|
"logFilePath": "~/.scrylog/logs/scrylogd.log",
|
|
307
379
|
"logFileMaxBytes": 5242880,
|
|
308
|
-
"logFileMaxFiles": 3
|
|
380
|
+
"logFileMaxFiles": 3,
|
|
309
381
|
},
|
|
310
382
|
"api": {
|
|
311
383
|
"tcpEnabled": false,
|
|
312
384
|
"host": "127.0.0.1",
|
|
313
|
-
"port": 7788
|
|
385
|
+
"port": 7788,
|
|
314
386
|
},
|
|
315
387
|
"cors": {
|
|
316
388
|
"enabled": false,
|
|
@@ -319,26 +391,26 @@ Example config:
|
|
|
319
391
|
"allowedHeaders": ["Content-Type", "Authorization"],
|
|
320
392
|
"exposedHeaders": [],
|
|
321
393
|
"credentials": false,
|
|
322
|
-
"maxAge": 600
|
|
394
|
+
"maxAge": 600,
|
|
323
395
|
},
|
|
324
396
|
"opencode": {
|
|
325
397
|
"mode": "hooks",
|
|
326
398
|
"instances": [],
|
|
327
|
-
"autoDiscover": true
|
|
399
|
+
"autoDiscover": true,
|
|
328
400
|
},
|
|
329
401
|
"claude": {
|
|
330
402
|
"claudeDir": "/Users/you/.claude",
|
|
331
403
|
"hooksEnabled": false,
|
|
332
|
-
"hooksDir": "/tmp/scrylog-claude-hooks"
|
|
404
|
+
"hooksDir": "/tmp/scrylog-claude-hooks",
|
|
333
405
|
},
|
|
334
406
|
"codex": {
|
|
335
407
|
"codexDir": "/Users/you/.codex",
|
|
336
408
|
"hooksEnabled": false,
|
|
337
|
-
"hooksDir": "/tmp/scrylog-codex-hooks"
|
|
409
|
+
"hooksDir": "/tmp/scrylog-codex-hooks",
|
|
338
410
|
},
|
|
339
411
|
"tmux": {
|
|
340
412
|
"previewLines": 50,
|
|
341
|
-
"detailLines": 200
|
|
413
|
+
"detailLines": 200,
|
|
342
414
|
},
|
|
343
415
|
"tui": {
|
|
344
416
|
"refreshMs": 5000,
|
|
@@ -348,27 +420,27 @@ Example config:
|
|
|
348
420
|
"pushDebounceMs": 120,
|
|
349
421
|
"headerLayout": "auto",
|
|
350
422
|
"headerSide": "left",
|
|
351
|
-
"providerIcons": "blocks"
|
|
423
|
+
"providerIcons": "blocks",
|
|
352
424
|
},
|
|
353
425
|
"mcp": {
|
|
354
426
|
"stdioEnabled": true,
|
|
355
427
|
"httpEnabled": false,
|
|
356
428
|
"host": "127.0.0.1",
|
|
357
429
|
"port": 7789,
|
|
358
|
-
"bearerToken": null
|
|
430
|
+
"bearerToken": null,
|
|
359
431
|
},
|
|
360
432
|
"usage": {
|
|
361
433
|
"enabled": true,
|
|
362
434
|
"pollIntervalMs": 300000,
|
|
363
|
-
"providers": ["claude", "opencode-go", "codex"]
|
|
435
|
+
"providers": ["claude", "opencode-go", "codex"],
|
|
364
436
|
},
|
|
365
437
|
"retention": {
|
|
366
438
|
"maxSessions": 500,
|
|
367
439
|
"standaloneMaxAgeHours": 168,
|
|
368
440
|
"localCommandTtlHours": 72,
|
|
369
441
|
"cacheMaxEntries": 1000,
|
|
370
|
-
"transcriptMaxBytes": 10485760
|
|
371
|
-
}
|
|
442
|
+
"transcriptMaxBytes": 10485760,
|
|
443
|
+
},
|
|
372
444
|
}
|
|
373
445
|
```
|
|
374
446
|
|
|
@@ -398,21 +470,21 @@ Notes:
|
|
|
398
470
|
|
|
399
471
|
`scrylogd` is a monitor for active and recent sessions, not a permanent historical archive. Defaults are tuned for unattended daemon usage:
|
|
400
472
|
|
|
401
|
-
| Setting
|
|
402
|
-
|
|
|
403
|
-
| `retention.maxSessions`
|
|
404
|
-
| `retention.standaloneMaxAgeHours` |
|
|
405
|
-
| `retention.cacheMaxEntries`
|
|
406
|
-
| `retention.transcriptMaxBytes`
|
|
407
|
-
| `daemon.commandTimeoutMs`
|
|
473
|
+
| Setting | Default | Effect |
|
|
474
|
+
| --------------------------------- | ---------: | ------------------------------------------------------------------------------------------------------------ |
|
|
475
|
+
| `retention.maxSessions` | `500` | Prunes oldest inactive identified standalone sessions above this count (tmux/herdr/unknown rows never count) |
|
|
476
|
+
| `retention.standaloneMaxAgeHours` | `168` | Prunes inactive standalone sessions older than 7 days |
|
|
477
|
+
| `retention.cacheMaxEntries` | `1000` | Bounds internal path/project caches |
|
|
478
|
+
| `retention.transcriptMaxBytes` | `10485760` | Parses only a bounded tail for very large Claude transcripts |
|
|
479
|
+
| `daemon.commandTimeoutMs` | `5000` | Prevents external commands from blocking indefinitely |
|
|
408
480
|
|
|
409
481
|
Expected daemon RSS depends on active sessions and transcript size:
|
|
410
482
|
|
|
411
|
-
| Scenario
|
|
412
|
-
|
|
|
413
|
-
| No active sessions
|
|
414
|
-
| Normal local usage
|
|
415
|
-
| Heavy tmux/Claude/OpenCode usage |
|
|
483
|
+
| Scenario | Expected RSS |
|
|
484
|
+
| -------------------------------- | -----------: |
|
|
485
|
+
| No active sessions | 35-70 MB |
|
|
486
|
+
| Normal local usage | 50-120 MB |
|
|
487
|
+
| Heavy tmux/Claude/OpenCode usage | 100-250 MB |
|
|
416
488
|
|
|
417
489
|
If you want longer history, increase `retention.maxSessions` or `retention.standaloneMaxAgeHours`. Setting age to `0` disables age-based pruning, but count-based pruning can still apply.
|
|
418
490
|
|
|
@@ -436,16 +508,22 @@ The file format is JSONL for bug reports and tooling. Terminal stderr output def
|
|
|
436
508
|
|
|
437
509
|
Default file rotation keeps three files total:
|
|
438
510
|
|
|
439
|
-
| File
|
|
440
|
-
|
|
|
441
|
-
| `scrylogd.log`
|
|
511
|
+
| File | Purpose |
|
|
512
|
+
| ---------------- | -------------------- |
|
|
513
|
+
| `scrylogd.log` | Active log file |
|
|
442
514
|
| `scrylogd.1.log` | Previous active file |
|
|
443
515
|
| `scrylogd.2.log` | Oldest retained file |
|
|
444
516
|
|
|
445
517
|
Example JSONL entry:
|
|
446
518
|
|
|
447
519
|
```json
|
|
448
|
-
{
|
|
520
|
+
{
|
|
521
|
+
"ts": "2026-05-05T18:42:31.123Z",
|
|
522
|
+
"level": "info",
|
|
523
|
+
"source": "daemon",
|
|
524
|
+
"event": "daemon.started",
|
|
525
|
+
"msg": "Started"
|
|
526
|
+
}
|
|
449
527
|
```
|
|
450
528
|
|
|
451
529
|
Logs sanitize home-directory paths, bearer tokens, authorization values, and URL query strings before writing.
|
|
@@ -513,7 +591,7 @@ scrylog setup
|
|
|
513
591
|
scrylog opencode hooks install
|
|
514
592
|
```
|
|
515
593
|
|
|
516
|
-
|
|
594
|
+
Alternatively, add the plugin to `~/.config/opencode/opencode.json` manually:
|
|
517
595
|
|
|
518
596
|
```json
|
|
519
597
|
{
|
|
@@ -595,10 +673,10 @@ How it works:
|
|
|
595
673
|
|
|
596
674
|
Environment variables:
|
|
597
675
|
|
|
598
|
-
| Variable
|
|
599
|
-
|
|
|
600
|
-
| `OPENCODE_LOCAL_PORT` | `4096`
|
|
601
|
-
| `OPENCODE_HOST`
|
|
676
|
+
| Variable | Default | Purpose |
|
|
677
|
+
| --------------------- | ----------- | --------------------- |
|
|
678
|
+
| `OPENCODE_LOCAL_PORT` | `4096` | Force a specific port |
|
|
679
|
+
| `OPENCODE_HOST` | `127.0.0.1` | Force a specific host |
|
|
602
680
|
|
|
603
681
|
## HTTP API
|
|
604
682
|
|
|
@@ -618,17 +696,17 @@ Enable it with:
|
|
|
618
696
|
|
|
619
697
|
Endpoints:
|
|
620
698
|
|
|
621
|
-
| Method | Path
|
|
622
|
-
|
|
|
623
|
-
| `GET`
|
|
624
|
-
| `GET`
|
|
625
|
-
| `GET`
|
|
626
|
-
| `GET`
|
|
627
|
-
| `GET`
|
|
628
|
-
| `GET`
|
|
629
|
-
| `GET`
|
|
630
|
-
| `GET`
|
|
631
|
-
| `POST` | `/api/webhook/opencode`
|
|
699
|
+
| Method | Path | Returns |
|
|
700
|
+
| ------ | ---------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
701
|
+
| `GET` | `/api/health` | daemon health, timestamps, collector status |
|
|
702
|
+
| `GET` | `/api/status` | visible counts, collector status, generated timestamp (`?includeUnknown=true` opts in) |
|
|
703
|
+
| `GET` | `/api/sessions` | visible session tree plus counts (`?includeUnknown=true` opts in; unknown-tool rows hidden by default) |
|
|
704
|
+
| `GET` | `/api/sessions/:id` | full session detail |
|
|
705
|
+
| `GET` | `/api/sessions/:id/children` | visible child sessions |
|
|
706
|
+
| `GET` | `/api/sessions/:id/messages` | recent messages when available |
|
|
707
|
+
| `GET` | `/api/config` | active config with sensitive fields redacted |
|
|
708
|
+
| `GET` | `/api/events` | SSE stream of store events |
|
|
709
|
+
| `POST` | `/api/webhook/opencode` | OpenCode plugin webhook |
|
|
632
710
|
|
|
633
711
|
All error responses follow a consistent format:
|
|
634
712
|
|
|
@@ -864,7 +942,7 @@ For OpenCode local plugin testing, create or update:
|
|
|
864
942
|
with:
|
|
865
943
|
|
|
866
944
|
```ts
|
|
867
|
-
export { server } from
|
|
945
|
+
export { server } from 'file:///Volumes/Files/Workspace/Projects/other/scrylog/packages/opencode-plugin/src/index.ts';
|
|
868
946
|
```
|
|
869
947
|
|
|
870
948
|
For package usage, prefer the published plugin configuration:
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Retrieved from official provider properties. The images are bundled so the dashboard never fetches artwork at runtime.
|
|
4
4
|
|
|
5
|
-
| File
|
|
6
|
-
|
|
|
7
|
-
| `claude.png`
|
|
8
|
-
| `opencode.png` | `https://opencode.ai/apple-touch-icon-v3.png`
|
|
9
|
-
| `openai.png`
|
|
5
|
+
| File | Official source |
|
|
6
|
+
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
7
|
+
| `claude.png` | `https://assets-proxy.anthropic.com/claude-ai/v2/assets/v1/c129d018a-0ZbJsTbu.png` |
|
|
8
|
+
| `opencode.png` | `https://opencode.ai/apple-touch-icon-v3.png` |
|
|
9
|
+
| `openai.png` | OpenAI official app icon (`https://cdn.oaistatic.com/assets/apple-touch-icon-mz9nytnj.webp`, white tile with black Blossom from the official brand guidelines); the standalone mono Blossom SVG (`File:OpenAI_logo_2025_(symbol).svg`, Wikimedia Commons, PD-textlogo) served as design reference. Formerly `codex.png` (OpenAI Codex app art). |
|
|
10
10
|
|
|
11
11
|
The `*-terminal.svg` files are editable 8x8, square integer-grid adaptations of those marks. Their generated `*-terminal.png` counterparts map directly to a compact 8x4-cell block target with square half-block pixels (2 pixel rows per cell), avoiding destructive downsampling and aspect distortion. Hand-drawn tool glyphs (no official small-mark equivalent; used for the 2x1-cell mini column icon in image-capable modes, replaced by a brand monogram in blocks mode):
|
|
12
12
|
|
|
13
|
-
| File
|
|
14
|
-
|
|
|
13
|
+
| File | Source |
|
|
14
|
+
| ----------------------------- | ------------------------------------------------------------------- |
|
|
15
15
|
| `copilot.svg` / `copilot.png` | Original 8x8 grid drawing modelled on GitHub Copilot's goggles mark |
|
|
16
|
-
| `shell.svg` / `shell.png`
|
|
17
|
-
| `unknown.svg` / `unknown.png` | Original 8x8 grid drawing of a `?` marker
|
|
16
|
+
| `shell.svg` / `shell.png` | Original 8x8 grid drawing of a `>_` prompt glyph |
|
|
17
|
+
| `unknown.svg` / `unknown.png` | Original 8x8 grid drawing of a `?` marker |
|
|
18
18
|
|
|
19
19
|
They deliberately avoid gradients and antialiasing so Claude's inverted cream spark on an orange tile, OpenCode's light "O" plate, and OpenAI's black Blossom on a white tile remain identifiable after character-cell rendering. Square official artwork uses a separate 6x3-cell fitted target.
|
|
20
20
|
|