@scrylog/cli 0.1.4 → 0.3.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 (97) hide show
  1. package/README.md +46 -7
  2. package/package.json +13 -10
  3. package/src/api/docs/sessions.ts +3 -2
  4. package/src/api/docs/system.ts +3 -0
  5. package/src/api/docs/usage.ts +2 -2
  6. package/src/api/routes/sessions.ts +6 -2
  7. package/src/api/routes/system.ts +4 -1
  8. package/src/api/routes/webhooks/claude.ts +9 -21
  9. package/src/api/routes/webhooks/opencode.ts +6 -1
  10. package/src/api/routes.ts +1 -1
  11. package/src/api/schemas/common.ts +8 -0
  12. package/src/api/schemas/sessions.ts +15 -1
  13. package/src/api/schemas/usage.ts +1 -0
  14. package/src/cli/commands.ts +170 -26
  15. package/src/cli/index.ts +18 -0
  16. package/src/cli/program.ts +175 -0
  17. package/src/daemon/collectors/claude/collector.ts +11 -1
  18. package/src/daemon/collectors/claude/discovery.ts +2 -23
  19. package/src/daemon/collectors/codex/collector.ts +3 -3
  20. package/src/daemon/collectors/git.ts +60 -2
  21. package/src/daemon/collectors/herdr/collector.ts +128 -0
  22. package/src/daemon/collectors/herdr/index.ts +2 -0
  23. package/src/daemon/collectors/herdr/normalization.ts +111 -0
  24. package/src/daemon/collectors/opencode/collector.ts +4 -2
  25. package/src/daemon/collectors/opencode-db.ts +17 -5
  26. package/src/daemon/collectors/tmux/collector.ts +21 -1
  27. package/src/daemon/collectors/tmux/enrichment.ts +1 -0
  28. package/src/daemon/collectors/usage.ts +115 -49
  29. package/src/daemon/index.ts +2 -0
  30. package/src/daemon/store.ts +109 -14
  31. package/src/postinstall.cjs +11 -0
  32. package/src/shared/config.ts +33 -0
  33. package/src/shared/session-exclusions.ts +5 -0
  34. package/src/shared/session-view.ts +67 -6
  35. package/src/shared/terminal-capabilities.ts +130 -0
  36. package/src/shared/types.ts +33 -2
  37. package/src/shared/version.ts +44 -0
  38. package/src/tui/App.tsx +240 -0
  39. package/src/tui/assets/providers/SOURCES.md +21 -0
  40. package/src/tui/assets/providers/claude-terminal.png +0 -0
  41. package/src/tui/assets/providers/claude-terminal.svg +62 -0
  42. package/src/tui/assets/providers/claude.png +0 -0
  43. package/src/tui/assets/providers/copilot.png +0 -0
  44. package/src/tui/assets/providers/copilot.svg +44 -0
  45. package/src/tui/assets/providers/openai-terminal.png +0 -0
  46. package/src/tui/assets/providers/openai-terminal.svg +62 -0
  47. package/src/tui/assets/providers/openai.png +0 -0
  48. package/src/tui/assets/providers/opencode-terminal.png +0 -0
  49. package/src/tui/assets/providers/opencode-terminal.svg +62 -0
  50. package/src/tui/assets/providers/opencode.png +0 -0
  51. package/src/tui/assets/providers/shell.png +0 -0
  52. package/src/tui/assets/providers/shell.svg +23 -0
  53. package/src/tui/assets/providers/unknown.png +0 -0
  54. package/src/tui/assets/providers/unknown.svg +23 -0
  55. package/src/tui/client.ts +22 -8
  56. package/src/tui/components/BindingsModal.tsx +82 -0
  57. package/src/tui/components/DashboardHeader.tsx +256 -0
  58. package/src/tui/components/KeyBar.tsx +67 -0
  59. package/src/tui/components/SessionDetailModal.tsx +169 -0
  60. package/src/tui/components/SessionsView.tsx +184 -0
  61. package/src/tui/components/TabBar.tsx +40 -0
  62. package/src/tui/components/UsageSummaryPane.tsx +272 -0
  63. package/src/tui/components/UsageView.tsx +242 -0
  64. package/src/tui/components/tool-icons.ts +24 -0
  65. package/src/tui/index.tsx +106 -0
  66. package/src/tui/keybindings.ts +49 -0
  67. package/src/tui/model.ts +295 -0
  68. package/src/tui/state.ts +77 -0
  69. package/src/tui/theme.ts +110 -0
  70. package/src/usage/README.md +3 -3
  71. package/src/usage/clients/anthropic-oauth-usage.ts +100 -20
  72. package/src/usage/clients/anthropic-web-usage.ts +133 -49
  73. package/src/usage/clients/claude-cli-probe.ts +458 -132
  74. package/src/usage/clients/codex-app-server.ts +354 -0
  75. package/src/usage/clients/codex-oauth-usage.ts +143 -16
  76. package/src/usage/clients/opencode-go-api.ts +100 -0
  77. package/src/usage/clients/opencode-go-usage.ts +163 -27
  78. package/src/usage/errors.ts +33 -0
  79. package/src/usage/index.ts +2 -1
  80. package/src/usage/local/opencode-go-local.ts +194 -0
  81. package/src/usage/mappers.ts +24 -15
  82. package/src/usage/planner.ts +89 -25
  83. package/src/usage/providers/claude.ts +203 -83
  84. package/src/usage/providers/codex.ts +92 -11
  85. package/src/usage/providers/opencode-go.ts +94 -16
  86. package/src/usage/resolvers/browser-cookies.ts +679 -69
  87. package/src/usage/resolvers/claude-auth.ts +150 -41
  88. package/src/usage/resolvers/claude-desktop-auth.ts +170 -0
  89. package/src/usage/resolvers/claude-web.ts +72 -6
  90. package/src/usage/resolvers/codex-auth.ts +74 -17
  91. package/src/usage/resolvers/keychain-coordinator.ts +397 -0
  92. package/src/usage/resolvers/opencode-go-web.ts +47 -6
  93. package/src/usage/types.ts +37 -2
  94. package/src/usage/web-session-cache.ts +37 -0
  95. package/src/neo-blessed.d.ts +0 -4
  96. package/src/tui/app.ts +0 -920
  97. package/src/tui/index.ts +0 -193
package/src/tui/index.ts DELETED
@@ -1,193 +0,0 @@
1
- #!/usr/bin/env bun
2
- import { loadConfig } from "../shared/config";
3
- import type { ScrylogConfig } from "../shared/config";
4
- import { DaemonClient } from "./client";
5
- import { DashboardApp } from "./app";
6
- import { getServiceManagerOrThrow } from "../service/manager";
7
- import type { ServiceStatus } from "../service/manager";
8
- import {
9
- runClaudeHooksInstall,
10
- runCodexHooksInstall,
11
- runOpenCodeHooksInstall,
12
- runConfigCommand,
13
- runDaemonCommand,
14
- runDoctor,
15
- runLogsCommand,
16
- runSetupWizard,
17
- runTokenCommand,
18
- } from "../cli/commands";
19
-
20
- function printHelp() {
21
- process.stdout.write(`scrylog
22
-
23
- Usage:
24
- scrylog [--config <path>]
25
- scrylog setup [--config <path>]
26
- scrylog doctor [--config <path>]
27
- scrylog daemon <install|uninstall|start|stop|restart|status> [--config <path>]
28
- scrylog config <show|path> [--config <path>]
29
- scrylog token <mcp|api|both> <generate|rotate|clear> [--config <path>]
30
- scrylog claude hooks install [--config <path>]
31
- scrylog codex hooks install [--config <path>]
32
- scrylog opencode hooks install [--config <path>]
33
- scrylog logs
34
-
35
- Options:
36
- --config <path> Load config from an explicit path
37
- -h, --help Show this help text
38
-
39
- Notes:
40
- Running scrylog with no subcommand launches the TUI dashboard.
41
- 'scrylog claude hooks install' configures Claude Code to emit lifecycle
42
- hooks that scrylog uses for real-time session state tracking.
43
- 'scrylog codex hooks install' configures Codex CLI to emit lifecycle
44
- hooks that scrylog uses for real-time session state tracking.
45
- 'scrylog opencode hooks install' registers the scrylog plugin in
46
- OpenCode configuration for real-time session state tracking.
47
- `);
48
- }
49
-
50
- function extractGlobalOptions(argv: string[]) {
51
- const args = [...argv];
52
- let configPath: string | undefined;
53
- const configFlagIndex = args.indexOf("--config");
54
- if (configFlagIndex >= 0) {
55
- configPath = args[configFlagIndex + 1];
56
- args.splice(configFlagIndex, configPath ? 2 : 1);
57
- }
58
- return { args, options: { configPath } };
59
- }
60
-
61
- async function launchTui(configPath?: string): Promise<void> {
62
- const config = loadConfig(configPath);
63
-
64
- const client = new DaemonClient(config);
65
- if (!(await client.isHealthy())) {
66
- printDaemonNotRunning(config, getServiceManagerOrThrow().platform);
67
- process.exit(1);
68
- }
69
-
70
- const app = new DashboardApp(client, {
71
- refreshMs: config.tui.refreshMs,
72
- showStandalone: config.tui.showStandalone,
73
- }, config);
74
-
75
- app.start();
76
- }
77
-
78
- /**
79
- * Print a platform-aware error explaining that the daemon is not running and
80
- * listing the commands to verify, start, and inspect it. Exported for testing.
81
- */
82
- export function printDaemonNotRunning(config: ScrylogConfig, platform: ServiceStatus["platform"]): void {
83
- const logPath = config.daemon.logFilePath;
84
- const hasService = platform === "macos" || platform === "linux";
85
-
86
- process.stderr.write("scrylog: daemon is not running.\n\n");
87
- process.stderr.write("Verify:\n");
88
- process.stderr.write(" scrylog daemon status\n");
89
- process.stderr.write(" scrylog doctor\n\n");
90
- process.stderr.write("Start it (pick one):\n");
91
- if (hasService) {
92
- process.stderr.write(" scrylog daemon start # user service\n");
93
- process.stderr.write(" scrylog daemon install # if the service is not installed yet\n");
94
- }
95
- process.stderr.write(" scrylogd # foreground\n\n");
96
- process.stderr.write(`Logs:\n scrylog logs\n ${logPath}\n`);
97
-
98
- if (!hasService) {
99
- const note =
100
- platform === "wsl"
101
- ? "Service management is unavailable (WSL without systemd). Run scrylogd directly or enable systemd in /etc/wsl.conf."
102
- : platform === "linux-no-systemd"
103
- ? "Service management is unavailable (no systemd user session). Run scrylogd directly."
104
- : "Service management is unavailable on this platform. Run scrylogd directly or use Task Scheduler.";
105
- process.stderr.write(`\n${note}\n`);
106
- }
107
- }
108
-
109
- async function main(): Promise<void> {
110
- const { args, options } = extractGlobalOptions(process.argv.slice(2));
111
- if (args.includes("--help") || args.includes("-h")) {
112
- printHelp();
113
- process.exit(0);
114
- }
115
-
116
- const [command, subcommand] = args;
117
- if (!command) {
118
- await launchTui(options.configPath ?? process.env.SCRYLOG_CONFIG);
119
- return;
120
- }
121
-
122
- if (command === "setup") {
123
- await runSetupWizard(options);
124
- return;
125
- }
126
-
127
- if (command === "doctor") {
128
- await runDoctor(options);
129
- return;
130
- }
131
-
132
- if (command === "daemon") {
133
- if (!subcommand) throw new Error("Missing daemon action");
134
- await runDaemonCommand(subcommand, options);
135
- return;
136
- }
137
-
138
- if (command === "config") {
139
- if (!subcommand) throw new Error("Missing config action");
140
- runConfigCommand(subcommand, options);
141
- return;
142
- }
143
-
144
- if (command === "token") {
145
- if (!subcommand) throw new Error("Missing token target (mcp, api, or both)");
146
- const action = args[2];
147
- if (!action) throw new Error("Missing token action (generate, rotate, or clear)");
148
- const target = subcommand;
149
- if (target !== "mcp" && target !== "api" && target !== "both") {
150
- throw new Error(`Invalid token target: ${target}. Must be mcp, api, or both.`);
151
- }
152
- runTokenCommand(target as "mcp" | "api" | "both", action, options);
153
- return;
154
- }
155
-
156
- if (command === "logs") {
157
- await runLogsCommand();
158
- return;
159
- }
160
-
161
- if (command === "claude") {
162
- if (subcommand === "hooks" && args[2] === "install") {
163
- await runClaudeHooksInstall(options);
164
- return;
165
- }
166
- throw new Error(`Unknown claude subcommand: ${subcommand ?? "(none)"}`);
167
- }
168
-
169
- if (command === "codex") {
170
- if (subcommand === "hooks" && args[2] === "install") {
171
- await runCodexHooksInstall(options);
172
- return;
173
- }
174
- throw new Error(`Unknown codex subcommand: ${subcommand ?? "(none)"}`);
175
- }
176
-
177
- if (command === "opencode") {
178
- if (subcommand === "hooks" && args[2] === "install") {
179
- await runOpenCodeHooksInstall(options);
180
- return;
181
- }
182
- throw new Error(`Unknown opencode subcommand: ${subcommand ?? "(none)"}`);
183
- }
184
-
185
- throw new Error(`Unknown command: ${command}`);
186
- }
187
-
188
- if (import.meta.main) {
189
- main().catch((err) => {
190
- process.stderr.write(`scrylog: fatal: ${err instanceof Error ? err.message : String(err)}\n`);
191
- process.exit(1);
192
- });
193
- }