@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.
- package/README.md +46 -7
- package/package.json +13 -10
- package/src/api/docs/sessions.ts +3 -2
- package/src/api/docs/system.ts +3 -0
- package/src/api/docs/usage.ts +2 -2
- package/src/api/routes/sessions.ts +6 -2
- package/src/api/routes/system.ts +4 -1
- package/src/api/routes/webhooks/claude.ts +9 -21
- package/src/api/routes/webhooks/opencode.ts +6 -1
- package/src/api/routes.ts +1 -1
- package/src/api/schemas/common.ts +8 -0
- package/src/api/schemas/sessions.ts +15 -1
- package/src/api/schemas/usage.ts +1 -0
- package/src/cli/commands.ts +170 -26
- package/src/cli/index.ts +18 -0
- package/src/cli/program.ts +175 -0
- package/src/daemon/collectors/claude/collector.ts +11 -1
- package/src/daemon/collectors/claude/discovery.ts +2 -23
- package/src/daemon/collectors/codex/collector.ts +3 -3
- package/src/daemon/collectors/git.ts +60 -2
- package/src/daemon/collectors/herdr/collector.ts +128 -0
- package/src/daemon/collectors/herdr/index.ts +2 -0
- package/src/daemon/collectors/herdr/normalization.ts +111 -0
- package/src/daemon/collectors/opencode/collector.ts +4 -2
- package/src/daemon/collectors/opencode-db.ts +17 -5
- package/src/daemon/collectors/tmux/collector.ts +21 -1
- package/src/daemon/collectors/tmux/enrichment.ts +1 -0
- package/src/daemon/collectors/usage.ts +115 -49
- package/src/daemon/index.ts +2 -0
- package/src/daemon/store.ts +109 -14
- package/src/postinstall.cjs +11 -0
- package/src/shared/config.ts +33 -0
- package/src/shared/session-exclusions.ts +5 -0
- package/src/shared/session-view.ts +67 -6
- package/src/shared/terminal-capabilities.ts +130 -0
- package/src/shared/types.ts +33 -2
- package/src/shared/version.ts +44 -0
- package/src/tui/App.tsx +240 -0
- package/src/tui/assets/providers/SOURCES.md +21 -0
- package/src/tui/assets/providers/claude-terminal.png +0 -0
- package/src/tui/assets/providers/claude-terminal.svg +62 -0
- package/src/tui/assets/providers/claude.png +0 -0
- package/src/tui/assets/providers/copilot.png +0 -0
- package/src/tui/assets/providers/copilot.svg +44 -0
- package/src/tui/assets/providers/openai-terminal.png +0 -0
- package/src/tui/assets/providers/openai-terminal.svg +62 -0
- package/src/tui/assets/providers/openai.png +0 -0
- package/src/tui/assets/providers/opencode-terminal.png +0 -0
- package/src/tui/assets/providers/opencode-terminal.svg +62 -0
- package/src/tui/assets/providers/opencode.png +0 -0
- package/src/tui/assets/providers/shell.png +0 -0
- package/src/tui/assets/providers/shell.svg +23 -0
- package/src/tui/assets/providers/unknown.png +0 -0
- package/src/tui/assets/providers/unknown.svg +23 -0
- package/src/tui/client.ts +22 -8
- package/src/tui/components/BindingsModal.tsx +82 -0
- package/src/tui/components/DashboardHeader.tsx +256 -0
- package/src/tui/components/KeyBar.tsx +67 -0
- package/src/tui/components/SessionDetailModal.tsx +169 -0
- package/src/tui/components/SessionsView.tsx +184 -0
- package/src/tui/components/TabBar.tsx +40 -0
- package/src/tui/components/UsageSummaryPane.tsx +272 -0
- package/src/tui/components/UsageView.tsx +242 -0
- package/src/tui/components/tool-icons.ts +24 -0
- package/src/tui/index.tsx +106 -0
- package/src/tui/keybindings.ts +49 -0
- package/src/tui/model.ts +295 -0
- package/src/tui/state.ts +77 -0
- package/src/tui/theme.ts +110 -0
- package/src/usage/README.md +3 -3
- package/src/usage/clients/anthropic-oauth-usage.ts +100 -20
- package/src/usage/clients/anthropic-web-usage.ts +133 -49
- package/src/usage/clients/claude-cli-probe.ts +458 -132
- package/src/usage/clients/codex-app-server.ts +354 -0
- package/src/usage/clients/codex-oauth-usage.ts +143 -16
- package/src/usage/clients/opencode-go-api.ts +100 -0
- package/src/usage/clients/opencode-go-usage.ts +163 -27
- package/src/usage/errors.ts +33 -0
- package/src/usage/index.ts +2 -1
- package/src/usage/local/opencode-go-local.ts +194 -0
- package/src/usage/mappers.ts +24 -15
- package/src/usage/planner.ts +89 -25
- package/src/usage/providers/claude.ts +203 -83
- package/src/usage/providers/codex.ts +92 -11
- package/src/usage/providers/opencode-go.ts +94 -16
- package/src/usage/resolvers/browser-cookies.ts +679 -69
- package/src/usage/resolvers/claude-auth.ts +150 -41
- package/src/usage/resolvers/claude-desktop-auth.ts +170 -0
- package/src/usage/resolvers/claude-web.ts +72 -6
- package/src/usage/resolvers/codex-auth.ts +74 -17
- package/src/usage/resolvers/keychain-coordinator.ts +397 -0
- package/src/usage/resolvers/opencode-go-web.ts +47 -6
- package/src/usage/types.ts +37 -2
- package/src/usage/web-session-cache.ts +37 -0
- package/src/neo-blessed.d.ts +0 -4
- package/src/tui/app.ts +0 -920
- 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
|
-
}
|