@scrylog/cli 0.2.0 → 0.3.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.
Files changed (171) hide show
  1. package/README.md +46 -7
  2. package/dist/assets/highlights-eq9cgrbb.scm +604 -0
  3. package/dist/assets/highlights-ghv9g403.scm +205 -0
  4. package/dist/assets/highlights-hk7bwhj4.scm +284 -0
  5. package/dist/assets/highlights-r812a2qc.scm +150 -0
  6. package/dist/assets/highlights-x6tmsnaa.scm +115 -0
  7. package/dist/assets/injections-73j83es3.scm +27 -0
  8. package/dist/assets/parser.worker-xyhf83rf.js +4563 -0
  9. package/dist/assets/tree-sitter-3jzf13jk.wasm +0 -0
  10. package/dist/assets/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  11. package/dist/assets/tree-sitter-markdown-411r6y9b.wasm +0 -0
  12. package/dist/assets/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  13. package/dist/assets/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  14. package/dist/assets/tree-sitter-zig-e78zbjpm.wasm +0 -0
  15. package/dist/cli/assets/providers/SOURCES.md +21 -0
  16. package/dist/cli/assets/providers/claude-terminal.png +0 -0
  17. package/dist/cli/assets/providers/claude-terminal.svg +62 -0
  18. package/dist/cli/assets/providers/claude.png +0 -0
  19. package/dist/cli/assets/providers/copilot.png +0 -0
  20. package/dist/cli/assets/providers/copilot.svg +44 -0
  21. package/dist/cli/assets/providers/openai-terminal.png +0 -0
  22. package/dist/cli/assets/providers/openai-terminal.svg +62 -0
  23. package/dist/cli/assets/providers/openai.png +0 -0
  24. package/dist/cli/assets/providers/opencode-terminal.png +0 -0
  25. package/dist/cli/assets/providers/opencode-terminal.svg +62 -0
  26. package/dist/cli/assets/providers/opencode.png +0 -0
  27. package/dist/cli/assets/providers/shell.png +0 -0
  28. package/dist/cli/assets/providers/shell.svg +23 -0
  29. package/dist/cli/assets/providers/unknown.png +0 -0
  30. package/dist/cli/assets/providers/unknown.svg +23 -0
  31. package/dist/cli/index.js +499 -0
  32. package/dist/cli/index.js.map +61 -0
  33. package/dist/daemon/index.js +670 -0
  34. package/dist/daemon/index.js.map +1475 -0
  35. package/dist/hooks/claude.js +6 -0
  36. package/dist/hooks/claude.js.map +11 -0
  37. package/dist/hooks/codex.js +10 -0
  38. package/dist/hooks/codex.js.map +11 -0
  39. package/dist/mcp/index.js +100 -0
  40. package/dist/mcp/index.js.map +231 -0
  41. package/dist/oc/index.js +21 -0
  42. package/dist/oc/index.js.map +10 -0
  43. package/package.json +26 -20
  44. package/src/postinstall.cjs +11 -0
  45. package/src/api/docs/sessions.keys.ts +0 -6
  46. package/src/api/docs/sessions.ts +0 -81
  47. package/src/api/docs/system.keys.ts +0 -5
  48. package/src/api/docs/system.ts +0 -66
  49. package/src/api/docs/usage.keys.ts +0 -3
  50. package/src/api/docs/usage.ts +0 -24
  51. package/src/api/docs/webhooks.keys.ts +0 -5
  52. package/src/api/docs/webhooks.ts +0 -78
  53. package/src/api/index.ts +0 -18
  54. package/src/api/lib/auth.ts +0 -43
  55. package/src/api/lib/errors.ts +0 -28
  56. package/src/api/lib/route.ts +0 -18
  57. package/src/api/models/claude.ts +0 -4
  58. package/src/api/models/codex.ts +0 -4
  59. package/src/api/models/opencode.ts +0 -11
  60. package/src/api/routes/sessions.ts +0 -47
  61. package/src/api/routes/system.ts +0 -103
  62. package/src/api/routes/usage.ts +0 -15
  63. package/src/api/routes/webhooks/claude.ts +0 -141
  64. package/src/api/routes/webhooks/codex.ts +0 -175
  65. package/src/api/routes/webhooks/opencode.ts +0 -111
  66. package/src/api/routes.ts +0 -93
  67. package/src/api/schemas/common.ts +0 -21
  68. package/src/api/schemas/sessions.ts +0 -72
  69. package/src/api/schemas/usage.ts +0 -50
  70. package/src/api/schemas/webhooks/claude.ts +0 -32
  71. package/src/api/schemas/webhooks/codex.ts +0 -34
  72. package/src/api/schemas/webhooks/opencode.ts +0 -29
  73. package/src/api/services/claude-session.ts +0 -9
  74. package/src/api/services/codex-session.ts +0 -8
  75. package/src/api/services/opencode-session.ts +0 -73
  76. package/src/classifier.ts +0 -206
  77. package/src/cli/commands.ts +0 -632
  78. package/src/cli/prompt.ts +0 -44
  79. package/src/daemon/cli.ts +0 -27
  80. package/src/daemon/collectors/claude/README.md +0 -108
  81. package/src/daemon/collectors/claude/collector.ts +0 -423
  82. package/src/daemon/collectors/claude/discovery.ts +0 -148
  83. package/src/daemon/collectors/claude/hooks.ts +0 -181
  84. package/src/daemon/collectors/claude/index.ts +0 -8
  85. package/src/daemon/collectors/claude/jsonl.ts +0 -85
  86. package/src/daemon/collectors/claude/transcript.ts +0 -246
  87. package/src/daemon/collectors/codex/README.md +0 -147
  88. package/src/daemon/collectors/codex/collector.ts +0 -661
  89. package/src/daemon/collectors/codex/discovery.ts +0 -104
  90. package/src/daemon/collectors/codex/hooks.ts +0 -179
  91. package/src/daemon/collectors/codex/index.ts +0 -7
  92. package/src/daemon/collectors/codex/jsonl.ts +0 -108
  93. package/src/daemon/collectors/codex/transcript.ts +0 -299
  94. package/src/daemon/collectors/git.ts +0 -295
  95. package/src/daemon/collectors/opencode/README.md +0 -106
  96. package/src/daemon/collectors/opencode/collector.ts +0 -545
  97. package/src/daemon/collectors/opencode/discovery.ts +0 -257
  98. package/src/daemon/collectors/opencode/index.ts +0 -5
  99. package/src/daemon/collectors/opencode/session-builder.ts +0 -59
  100. package/src/daemon/collectors/opencode-db.ts +0 -282
  101. package/src/daemon/collectors/process.ts +0 -201
  102. package/src/daemon/collectors/tmux/README.md +0 -128
  103. package/src/daemon/collectors/tmux/collector.ts +0 -472
  104. package/src/daemon/collectors/tmux/enrichment.ts +0 -241
  105. package/src/daemon/collectors/tmux/index.ts +0 -4
  106. package/src/daemon/collectors/tmux/parse.ts +0 -128
  107. package/src/daemon/collectors/usage.ts +0 -193
  108. package/src/daemon/index.ts +0 -207
  109. package/src/daemon/scheduler.ts +0 -86
  110. package/src/daemon/store.ts +0 -588
  111. package/src/detect.ts +0 -143
  112. package/src/hooks/claude.ts +0 -596
  113. package/src/hooks/codex.ts +0 -517
  114. package/src/legacy/classifier.ts +0 -215
  115. package/src/legacy/detect.ts +0 -143
  116. package/src/mcp/client-server.ts +0 -21
  117. package/src/mcp/http-handler.ts +0 -126
  118. package/src/mcp/index.ts +0 -61
  119. package/src/mcp/resources/config-current.ts +0 -19
  120. package/src/mcp/resources/index.ts +0 -11
  121. package/src/mcp/resources/sessions-active.ts +0 -19
  122. package/src/mcp/resources/sessions-all.ts +0 -19
  123. package/src/mcp/schemas/sessions.ts +0 -3
  124. package/src/mcp/server.ts +0 -17
  125. package/src/mcp/services/api-adapter.ts +0 -48
  126. package/src/mcp/services/data-source.ts +0 -22
  127. package/src/mcp/services/store-adapter.ts +0 -40
  128. package/src/mcp/tools/get-active-sessions.ts +0 -16
  129. package/src/mcp/tools/get-session-children.ts +0 -24
  130. package/src/mcp/tools/get-session-messages.ts +0 -24
  131. package/src/mcp/tools/get-session.ts +0 -23
  132. package/src/mcp/tools/index.ts +0 -15
  133. package/src/mcp/tools/list-sessions.ts +0 -16
  134. package/src/neo-blessed.d.ts +0 -4
  135. package/src/oc/index.ts +0 -302
  136. package/src/service/manager.ts +0 -284
  137. package/src/shared/config.ts +0 -478
  138. package/src/shared/ipc.ts +0 -80
  139. package/src/shared/logger.ts +0 -248
  140. package/src/shared/paths.ts +0 -73
  141. package/src/shared/platform.ts +0 -110
  142. package/src/shared/session-view.ts +0 -241
  143. package/src/shared/types.ts +0 -299
  144. package/src/shared/utils.ts +0 -339
  145. package/src/tui/app.ts +0 -920
  146. package/src/tui/client.ts +0 -149
  147. package/src/tui/index.ts +0 -217
  148. package/src/types.ts +0 -113
  149. package/src/usage/README.md +0 -323
  150. package/src/usage/api.ts +0 -99
  151. package/src/usage/client.ts +0 -3
  152. package/src/usage/clients/anthropic-oauth-usage.ts +0 -178
  153. package/src/usage/clients/anthropic-web-usage.ts +0 -245
  154. package/src/usage/clients/claude-cli-probe.ts +0 -187
  155. package/src/usage/clients/codex-oauth-usage.ts +0 -113
  156. package/src/usage/clients/opencode-go-usage.ts +0 -441
  157. package/src/usage/index.ts +0 -20
  158. package/src/usage/mappers.ts +0 -273
  159. package/src/usage/planner.ts +0 -54
  160. package/src/usage/providers/claude.ts +0 -113
  161. package/src/usage/providers/codex.ts +0 -34
  162. package/src/usage/providers/opencode-go.ts +0 -37
  163. package/src/usage/resolver.ts +0 -4
  164. package/src/usage/resolvers/browser-cookies.ts +0 -470
  165. package/src/usage/resolvers/claude-auth.ts +0 -108
  166. package/src/usage/resolvers/claude-cli.ts +0 -24
  167. package/src/usage/resolvers/claude-desktop-auth.ts +0 -160
  168. package/src/usage/resolvers/claude-web.ts +0 -16
  169. package/src/usage/resolvers/codex-auth.ts +0 -117
  170. package/src/usage/resolvers/opencode-go-web.ts +0 -14
  171. package/src/usage/types.ts +0 -190
@@ -1,207 +0,0 @@
1
- #!/usr/bin/env bun
2
- import { unlinkSync, existsSync } from "node:fs";
3
- import { loadConfig } from "../shared/config";
4
- import { getSocketPath } from "../shared/ipc";
5
- import { IS_WINDOWS } from "../shared/platform";
6
- import { DaemonStore } from "./store";
7
- import { Scheduler } from "./scheduler";
8
- import { TmuxCollector } from "./collectors/tmux";
9
- import { ProcessCollector } from "./collectors/process";
10
- import { GitCollector } from "./collectors/git";
11
- import { OpenCodeCollector } from "./collectors/opencode";
12
- import { ClaudeCollector } from "./collectors/claude";
13
- import { CodexCollector } from "./collectors/codex";
14
- import { OpenCodeDbCollector } from "./collectors/opencode-db";
15
- import { UsageCollector } from "./collectors/usage";
16
- import { createApiHandler } from "../api/index";
17
- import { createMcpHttpHandler } from "../mcp/http-handler";
18
- import { createLogger, parseLogFormat, parseLogLevel } from "../shared/logger";
19
- import { parseDaemonArgs } from "./cli";
20
-
21
- function printHelp() {
22
- process.stdout.write(`scrylogd
23
-
24
- Usage:
25
- scrylogd [options]
26
-
27
- Options:
28
- --config <path> Load config from an explicit path
29
- --log-level <level> Override daemon log level
30
- --log-format <format> Override stderr log format (pretty|json)
31
- --no-log-file Disable daemon JSONL file logging for this process
32
- -h, --help Show this help text
33
-
34
- Notes:
35
- Starts the scrylog daemon, HTTP API, and MCP HTTP listener.
36
- `);
37
- }
38
-
39
- // ── Parse CLI args ────────────────────────────────────────────────────────────
40
-
41
- const args = process.argv.slice(2);
42
- let cliOptions: ReturnType<typeof parseDaemonArgs>;
43
- try {
44
- cliOptions = parseDaemonArgs(args);
45
- } catch (error) {
46
- process.stderr.write(`scrylogd: ${error instanceof Error ? error.message : String(error)}\n`);
47
- process.exit(1);
48
- }
49
-
50
- if (cliOptions.help) {
51
- printHelp();
52
- process.exit(0);
53
- }
54
- const configPath = cliOptions.configPath;
55
- const logLevelArg = cliOptions.logLevel;
56
- const logFormatArg = cliOptions.logFormat;
57
-
58
- // ── Bootstrap ─────────────────────────────────────────────────────────────────
59
-
60
- const config = loadConfig(configPath);
61
- const logLevel = parseLogLevel(logLevelArg, config.daemon.logLevel);
62
- const logFormat = parseLogFormat(logFormatArg, config.daemon.logFormat);
63
- const logger = createLogger({
64
- level: logLevel,
65
- format: logFormat,
66
- file: {
67
- enabled: config.daemon.logFileEnabled && cliOptions.logFileEnabled,
68
- path: config.daemon.logFilePath,
69
- maxBytes: config.daemon.logFileMaxBytes,
70
- maxFiles: config.daemon.logFileMaxFiles,
71
- },
72
- });
73
- const store = new DaemonStore(logger);
74
- const scheduler = new Scheduler(store, config, logger);
75
- const processCollector = new ProcessCollector();
76
- const gitCollector = new GitCollector();
77
-
78
- scheduler.register(processCollector);
79
- scheduler.register(gitCollector);
80
- scheduler.register(new TmuxCollector(processCollector, gitCollector));
81
- if (config.opencode.mode === "sse") {
82
- scheduler.register(new OpenCodeCollector(gitCollector));
83
- }
84
- scheduler.register(new ClaudeCollector(gitCollector));
85
- scheduler.register(new CodexCollector(gitCollector));
86
- scheduler.register(new OpenCodeDbCollector(gitCollector));
87
- if (config.usage.enabled) {
88
- scheduler.register(new UsageCollector());
89
- }
90
-
91
- // ── Duplicate-instance detection ──────────────────────────────────────────────
92
-
93
- const socketPath = getSocketPath(config.daemon.socketPath);
94
- const apiTcpEnabled = IS_WINDOWS || config.api.tcpEnabled;
95
-
96
- if (IS_WINDOWS) {
97
- if (!config.api.tcpEnabled) {
98
- logger.warn("daemon", "Windows requires TCP for duplicate detection and API access. Using TCP regardless of config.api.tcpEnabled.", { event: "daemon.tcp_required", platform: "windows" });
99
- }
100
-
101
- // Try connecting to an existing daemon via TCP; if it responds, exit
102
- try {
103
- const probeHeaders: Record<string, string> = config.api.bearerToken
104
- ? { Authorization: `Bearer ${config.api.bearerToken}` }
105
- : {};
106
- const probeUrl = `http://localhost:${config.api.port}/api/health`;
107
- const probe = await fetch(probeUrl, { headers: probeHeaders, signal: AbortSignal.timeout(config.daemon.networkTimeoutMs) });
108
- if (probe.ok) {
109
- logger.info("daemon", "Another daemon is already running. Exiting.", { event: "daemon.duplicate_detected", listener: "tcp", url: probeUrl });
110
- process.exit(0);
111
- }
112
- } catch {
113
- // No running daemon — continue
114
- }
115
- } else {
116
- // Try connecting to an existing daemon; if it responds, exit
117
- try {
118
- const probeHeaders: Record<string, string> = config.api.bearerToken
119
- ? { Authorization: `Bearer ${config.api.bearerToken}` }
120
- : {};
121
- // @ts-ignore -- Bun-specific unix option
122
- const probe = await fetch("http://localhost/api/health", { unix: socketPath, headers: probeHeaders, signal: AbortSignal.timeout(config.daemon.networkTimeoutMs) });
123
- if (probe.ok) {
124
- logger.info("daemon", "Another daemon is already running. Exiting.", { event: "daemon.duplicate_detected", socketPath });
125
- process.exit(0);
126
- }
127
- } catch {
128
- // No running daemon — clean up stale socket and continue
129
- if (existsSync(socketPath)) {
130
- try {
131
- unlinkSync(socketPath);
132
- } catch {
133
- // Ignore cleanup errors
134
- }
135
- }
136
- }
137
- }
138
-
139
- // ── Start collectors ──────────────────────────────────────────────────────────
140
-
141
- await scheduler.start();
142
-
143
- // ── HTTP API handler (shared across Unix socket and TCP) ──────────────────────
144
-
145
- const apiHandler = createApiHandler(store, config, logger, gitCollector);
146
-
147
- // ── Unix socket listener (macOS/Linux) ────────────────────────────────────────
148
-
149
- if (!IS_WINDOWS) {
150
- // idleTimeout is not typed on the unix socket variant but is supported at runtime
151
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
152
- Bun.serve({
153
- unix: socketPath,
154
- fetch: apiHandler,
155
- idleTimeout: 0, // SSE connections must not be dropped on idle
156
- } as any);
157
- logger.info("daemon", "Unix socket listener started", { event: "daemon.listener_started", listener: "unix", socketPath });
158
- }
159
-
160
- // ── TCP listener ──────────────────────────────────────────────────────────────
161
-
162
- if (apiTcpEnabled) {
163
- Bun.serve({
164
- port: config.api.port,
165
- hostname: config.api.host,
166
- fetch: apiHandler,
167
- idleTimeout: 0, // SSE connections must not be dropped on idle
168
- });
169
- logger.info("daemon", "HTTP API listener started", { event: "daemon.listener_started", listener: "api", url: `http://${config.api.host}:${config.api.port}` });
170
- } else {
171
- logger.info("daemon", "HTTP API TCP listener disabled", { event: "daemon.listener_disabled", listener: "api" });
172
- }
173
-
174
- // ── MCP HTTP listener (in-daemon) ─────────────────────────────────────────────
175
-
176
- const mcpHandler = createMcpHttpHandler(store, config);
177
- if (mcpHandler) {
178
- Bun.serve({
179
- port: config.mcp.port,
180
- hostname: config.mcp.host,
181
- fetch: mcpHandler,
182
- idleTimeout: 0, // long-lived MCP connections
183
- });
184
- logger.info("daemon", "MCP HTTP listener started", { event: "daemon.listener_started", listener: "mcp", url: `http://${config.mcp.host}:${config.mcp.port}` });
185
- } else {
186
- logger.info("daemon", "MCP HTTP listener disabled", { event: "daemon.listener_disabled", listener: "mcp" });
187
- }
188
-
189
- // ── Signal handling ───────────────────────────────────────────────────────────
190
-
191
- async function shutdown(signal: string): Promise<void> {
192
- logger.info("daemon", "Received signal. Shutting down", { event: "daemon.shutdown", signal });
193
- await scheduler.stop();
194
- if (!IS_WINDOWS && existsSync(socketPath)) {
195
- try {
196
- unlinkSync(socketPath);
197
- } catch {
198
- // Ignore
199
- }
200
- }
201
- process.exit(0);
202
- }
203
-
204
- process.on("SIGTERM", () => void shutdown("SIGTERM"));
205
- process.on("SIGINT", () => void shutdown("SIGINT"));
206
-
207
- logger.info("daemon", "Started", { event: "daemon.started" });
@@ -1,86 +0,0 @@
1
- import type { ScrylogConfig } from "../shared/config";
2
- import type { Logger } from "../shared/logger";
3
- import type { DaemonStore } from "./store";
4
- import type { ProcessCollector } from "./collectors/process";
5
-
6
- export interface Collector {
7
- name: string;
8
- /** Called once to start periodic/event-driven collection */
9
- start(store: DaemonStore, config: ScrylogConfig, logger: Logger): void | Promise<void>;
10
- /** Called on daemon shutdown */
11
- stop(): void | Promise<void>;
12
- }
13
-
14
- /**
15
- * Orchestrates all collectors.
16
- * Handles lifecycle start/stop and periodic polling intervals.
17
- */
18
- export class Scheduler {
19
- private collectors: Collector[] = [];
20
- private running = false;
21
- private retentionTimer?: ReturnType<typeof setInterval>;
22
-
23
- constructor(
24
- private readonly store: DaemonStore,
25
- private readonly config: ScrylogConfig,
26
- private readonly logger: Logger,
27
- ) {}
28
-
29
- register(collector: Collector): void {
30
- this.collectors.push(collector);
31
- if (collector.name === "process" && "processes" in collector) {
32
- this.store.registerProcessCollector(collector as unknown as ProcessCollector);
33
- }
34
- }
35
-
36
- async start(): Promise<void> {
37
- if (this.running) {
38
- return;
39
- }
40
-
41
- this.running = true;
42
- this.logger.info("scheduler", "Starting all collectors", { event: "scheduler.collectors_starting", count: this.collectors.length });
43
-
44
- for (const collector of this.collectors) {
45
- try {
46
- this.store.setCollectorStatus(collector.name, { running: true, lastRunAt: Date.now() });
47
- this.logger.debug("scheduler", "Starting collector", { event: "collector.starting", collector: collector.name });
48
- await collector.start(this.store, this.config, this.logger);
49
- } catch (error) {
50
- const message = error instanceof Error ? error.message : String(error);
51
- this.logger.warn("scheduler", "Collector failed to start", { event: "collector.start_failed", collector: collector.name, errorMessage: message });
52
- this.store.setCollectorStatus(collector.name, { running: false, lastError: message });
53
- this.store.reportError(collector.name, message);
54
- }
55
- }
56
-
57
- this.store.applyRetention(this.config.retention);
58
- this.retentionTimer = setInterval(() => {
59
- this.store.applyRetention(this.config.retention);
60
- }, Math.max(this.config.daemon.pollIntervalMs, 60_000));
61
- }
62
-
63
- async stop(): Promise<void> {
64
- if (!this.running) {
65
- return;
66
- }
67
-
68
- this.running = false;
69
- this.logger.info("scheduler", "Stopping all collectors", { event: "scheduler.collectors_stopping" });
70
- if (this.retentionTimer) {
71
- clearInterval(this.retentionTimer);
72
- this.retentionTimer = undefined;
73
- }
74
-
75
- for (const collector of this.collectors) {
76
- try {
77
- await collector.stop();
78
- this.store.setCollectorStatus(collector.name, { running: false });
79
- this.logger.debug("scheduler", "Stopped collector", { event: "collector.stopped", collector: collector.name });
80
- } catch (error) {
81
- const message = error instanceof Error ? error.message : String(error);
82
- this.logger.warn("scheduler", "Collector failed to stop", { event: "collector.stop_failed", collector: collector.name, errorMessage: message });
83
- }
84
- }
85
- }
86
- }