claudemon 0.2.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/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kumar Anirudha
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # claudemon
2
+
3
+ Claude Usage Monitor TUI - monitor your Claude Pro/Max plan quota in real-time.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/claudemon)](https://www.npmjs.com/package/claudemon)
6
+ [![npm downloads](https://img.shields.io/npm/dm/claudemon)](https://www.npmjs.com/package/claudemon)
7
+ [![Open Source](https://img.shields.io/badge/open-source-brightgreen)](https://github.com/anistark/claudemon)
8
+ ![maintenance-status](https://img.shields.io/badge/maintenance-actively--developed-brightgreen.svg)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
10
+
11
+ ## Install
12
+
13
+ ```sh
14
+ # Run without installing
15
+ npx claudemon
16
+
17
+ # Or install globally
18
+ npm i -g claudemon
19
+ pnpm add -g claudemon
20
+ ```
21
+
22
+ Requires Node.js 18+.
23
+
24
+ ## Setup
25
+
26
+ ```sh
27
+ claudemon setup
28
+ ```
29
+
30
+ This detects your Claude Code OAuth credentials automatically. If you haven't logged in to Claude Code yet, it will guide you through the process.
31
+
32
+ ## Usage
33
+
34
+ ```sh
35
+ # Launch the TUI dashboard
36
+ claudemon
37
+ ```
38
+
39
+ ### Keybindings
40
+
41
+ | Key | Action |
42
+ |-----|--------|
43
+ | `q` | Quit |
44
+ | `r` | Force refresh |
45
+ | `?` | Show help |
46
+
47
+ ## Development
48
+
49
+ ```sh
50
+ # Install dependencies
51
+ pnpm install
52
+
53
+ # Build and run with args
54
+ just run
55
+ just run setup
56
+ just run --help
57
+
58
+ # Build
59
+ just build
60
+
61
+ # Watch mode
62
+ just dev
63
+
64
+ # Type check
65
+ just lint
66
+ ```
package/dist/api.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * API client for Claude OAuth usage endpoint.
3
+ */
4
+ import { type QuotaData } from "./models.js";
5
+ export declare const OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
6
+ export declare const OAUTH_BETA_HEADER = "oauth-2025-04-20";
7
+ export declare class QuotaFetchError extends Error {
8
+ constructor(message: string);
9
+ }
10
+ export declare class AuthenticationError extends QuotaFetchError {
11
+ constructor(message: string);
12
+ }
13
+ export declare function fetchQuota(oauthToken: string): Promise<QuotaData>;
14
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAmB,KAAK,SAAS,EAAmB,MAAM,aAAa,CAAC;AAE/E,eAAO,MAAM,eAAe,8CAA8C,CAAC;AAC3E,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAEpD,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,mBAAoB,SAAQ,eAAe;gBAC1C,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAmCvE"}
package/dist/api.js ADDED
@@ -0,0 +1,92 @@
1
+ /**
2
+ * API client for Claude OAuth usage endpoint.
3
+ */
4
+ import { createQuotaData } from "./models.js";
5
+ export const OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
6
+ export const OAUTH_BETA_HEADER = "oauth-2025-04-20";
7
+ export class QuotaFetchError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "QuotaFetchError";
11
+ }
12
+ }
13
+ export class AuthenticationError extends QuotaFetchError {
14
+ constructor(message) {
15
+ super(message);
16
+ this.name = "AuthenticationError";
17
+ }
18
+ }
19
+ export async function fetchQuota(oauthToken) {
20
+ const headers = {
21
+ Authorization: `Bearer ${oauthToken}`,
22
+ "anthropic-beta": OAUTH_BETA_HEADER,
23
+ };
24
+ let resp;
25
+ try {
26
+ resp = await fetch(OAUTH_USAGE_URL, {
27
+ headers,
28
+ signal: AbortSignal.timeout(15000),
29
+ });
30
+ }
31
+ catch (e) {
32
+ throw new QuotaFetchError(`Network error: ${e}`);
33
+ }
34
+ if (resp.status === 401) {
35
+ throw new AuthenticationError("OAuth token is invalid or expired. Run 'claudemon setup' to re-authenticate.");
36
+ }
37
+ if (resp.status === 403) {
38
+ throw new AuthenticationError("Access denied. Your token may lack the required permissions.");
39
+ }
40
+ if (resp.status !== 200) {
41
+ const text = await resp.text();
42
+ throw new QuotaFetchError(`API returned status ${resp.status}: ${text}`);
43
+ }
44
+ const data = (await resp.json());
45
+ return parseQuotaResponse(data);
46
+ }
47
+ function parseQuotaResponse(data) {
48
+ const quota = createQuotaData();
49
+ // Parse 5-hour window
50
+ const fiveHour = (data["five_hour"] ?? data["fiveHour"] ?? {});
51
+ if (fiveHour) {
52
+ quota.fiveHourUsagePct =
53
+ fiveHour["utilization"] ??
54
+ fiveHour["usage_pct"] ??
55
+ 0;
56
+ const resetAt = fiveHour["resets_at"] ??
57
+ fiveHour["reset_at"] ??
58
+ fiveHour["resetAt"];
59
+ if (resetAt) {
60
+ quota.fiveHourResetTime = parseISOTime(resetAt);
61
+ }
62
+ }
63
+ // Parse 7-day window
64
+ const sevenDay = (data["seven_day"] ?? data["sevenDay"] ?? {});
65
+ if (sevenDay) {
66
+ quota.sevenDayUsagePct =
67
+ sevenDay["utilization"] ??
68
+ sevenDay["usage_pct"] ??
69
+ 0;
70
+ const resetAt = sevenDay["resets_at"] ??
71
+ sevenDay["reset_at"] ??
72
+ sevenDay["resetAt"];
73
+ if (resetAt) {
74
+ quota.sevenDayResetTime = parseISOTime(resetAt);
75
+ }
76
+ }
77
+ // Parse model-specific quotas
78
+ const models = (data["models"] ?? data["model_quotas"] ?? []);
79
+ for (const m of models) {
80
+ const name = m["model"] ?? m["name"] ?? "unknown";
81
+ const usage = m["utilization"] ?? m["usage_pct"] ?? 0;
82
+ quota.modelQuotas.push({ modelName: name, usagePct: usage });
83
+ }
84
+ // Plan type
85
+ quota.planType =
86
+ data["plan_type"] ?? data["planType"] ?? "pro";
87
+ return quota;
88
+ }
89
+ function parseISOTime(timeStr) {
90
+ return new Date(timeStr.replace("Z", "+00:00").endsWith("+00:00") ? timeStr : timeStr);
91
+ }
92
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/app.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Main Ink application component for claudemon.
3
+ */
4
+ import React from "react";
5
+ interface AppProps {
6
+ version?: string;
7
+ }
8
+ export declare function App({ version }: AppProps): React.ReactElement;
9
+ export {};
10
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAaxE,UAAU,QAAQ;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,GAAG,CAAC,EAAE,OAAY,EAAE,EAAE,QAAQ,GAAG,KAAK,CAAC,YAAY,CA6KlE"}
package/dist/app.js ADDED
@@ -0,0 +1,108 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Main Ink application component for claudemon.
4
+ */
5
+ import { useCallback, useEffect, useRef, useState } from "react";
6
+ import { Box, Text, useApp, useInput, useStdout } from "ink";
7
+ import { fetchQuota, AuthenticationError, QuotaFetchError } from "./api.js";
8
+ import { getOAuthToken, isAuthenticated } from "./auth.js";
9
+ import { loadConfig } from "./config.js";
10
+ import { HeaderBar } from "./components/HeaderBar.js";
11
+ import { PieChart } from "./components/PieChart.js";
12
+ const WEEKLY_REFRESH_INTERVAL = 300; // 5 minutes in seconds
13
+ export function App({ version = "" }) {
14
+ const { exit } = useApp();
15
+ const config = useRef(loadConfig());
16
+ const refreshInterval = Number(config.current["refresh_interval"] ?? 5);
17
+ const [quotaData, setQuotaData] = useState(null);
18
+ const [planType, setPlanType] = useState(String(config.current["plan_type"] ?? "pro"));
19
+ const [lastRefreshAgo, setLastRefreshAgo] = useState(0);
20
+ const [isLoading, setIsLoading] = useState(true);
21
+ const [errorMessage, setErrorMessage] = useState("");
22
+ const [showHelp, setShowHelp] = useState(false);
23
+ const lastRefreshTime = useRef(0);
24
+ const authenticated = useRef(isAuthenticated());
25
+ const { stdout } = useStdout();
26
+ const [termRows, setTermRows] = useState(stdout.rows ?? 24);
27
+ useEffect(() => {
28
+ const onResize = () => setTermRows(stdout.rows ?? 24);
29
+ stdout.on("resize", onResize);
30
+ return () => { stdout.off("resize", onResize); };
31
+ }, [stdout]);
32
+ const doRefresh = useCallback(async (weekly = false) => {
33
+ setIsLoading(true);
34
+ setErrorMessage("");
35
+ try {
36
+ const token = getOAuthToken();
37
+ if (!token)
38
+ return;
39
+ const quota = await fetchQuota(token);
40
+ setQuotaData(quota);
41
+ setPlanType(quota.planType || String(config.current["plan_type"] ?? "pro"));
42
+ lastRefreshTime.current = Date.now();
43
+ setLastRefreshAgo(0);
44
+ setIsLoading(false);
45
+ }
46
+ catch (e) {
47
+ setIsLoading(false);
48
+ if (e instanceof AuthenticationError) {
49
+ setErrorMessage(e.message);
50
+ }
51
+ else if (e instanceof QuotaFetchError) {
52
+ setErrorMessage(`Fetch error: ${e.message}`);
53
+ }
54
+ else {
55
+ setErrorMessage(`Error: ${e}`);
56
+ }
57
+ }
58
+ }, []);
59
+ // Initial fetch
60
+ useEffect(() => {
61
+ if (authenticated.current) {
62
+ doRefresh();
63
+ }
64
+ }, [doRefresh]);
65
+ // Session refresh interval
66
+ useEffect(() => {
67
+ if (!authenticated.current)
68
+ return;
69
+ const id = setInterval(() => doRefresh(), refreshInterval * 1000);
70
+ return () => clearInterval(id);
71
+ }, [doRefresh, refreshInterval]);
72
+ // Weekly refresh interval
73
+ useEffect(() => {
74
+ if (!authenticated.current)
75
+ return;
76
+ const id = setInterval(() => doRefresh(true), WEEKLY_REFRESH_INTERVAL * 1000);
77
+ return () => clearInterval(id);
78
+ }, [doRefresh]);
79
+ // Tick refresh counter every second
80
+ useEffect(() => {
81
+ const id = setInterval(() => {
82
+ if (lastRefreshTime.current > 0) {
83
+ setLastRefreshAgo(Math.floor((Date.now() - lastRefreshTime.current) / 1000));
84
+ }
85
+ }, 1000);
86
+ return () => clearInterval(id);
87
+ }, []);
88
+ // Keybindings
89
+ useInput((input, key) => {
90
+ if (input === "q") {
91
+ exit();
92
+ }
93
+ else if (input === "r") {
94
+ doRefresh();
95
+ }
96
+ else if (input === "?") {
97
+ setShowHelp((prev) => !prev);
98
+ }
99
+ });
100
+ if (!authenticated.current) {
101
+ return (_jsx(Box, { marginTop: 1, children: _jsxs(Box, { flexDirection: "column", borderStyle: "round", width: "100%", height: termRows - 1, children: [_jsx(HeaderBar, { planType: planType, lastRefreshAgo: 0, isLoading: false, errorMessage: "" }), _jsx(Box, { flexGrow: 1, paddingX: 4, paddingY: 2, justifyContent: "center", alignItems: "center", children: _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "yellow", children: "Not authenticated" }), "\n\n", "Run ", _jsx(Text, { bold: true, children: "claudemon setup" }), " to authenticate", "\n", "and start monitoring your Claude quota."] }) }), _jsxs(Box, { width: "100%", paddingX: 2, justifyContent: "space-between", borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, children: [_jsx(Text, { dimColor: true, children: "q: Quit | r: Refresh | ?: Help" }), version && _jsxs(Text, { dimColor: true, children: ["v", version] })] })] }) }));
102
+ }
103
+ if (showHelp) {
104
+ return (_jsx(Box, { marginTop: 1, children: _jsxs(Box, { flexDirection: "column", borderStyle: "round", width: "100%", height: termRows - 1, children: [_jsx(HeaderBar, { planType: planType, lastRefreshAgo: lastRefreshAgo, isLoading: isLoading, errorMessage: errorMessage }), _jsxs(Box, { flexGrow: 1, paddingX: 4, paddingY: 2, flexDirection: "column", justifyContent: "center", children: [_jsx(Text, { bold: true, children: "Keybindings" }), _jsx(Text, { children: " q \u2014 Quit" }), _jsx(Text, { children: " r \u2014 Force refresh" }), _jsx(Text, { children: " ? \u2014 Toggle help" })] }), _jsxs(Box, { width: "100%", paddingX: 2, justifyContent: "space-between", borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, children: [_jsx(Text, { dimColor: true, children: "q: Quit | r: Refresh | ?: Help" }), version && _jsxs(Text, { dimColor: true, children: ["v", version] })] })] }) }));
105
+ }
106
+ return (_jsx(Box, { marginTop: 1, children: _jsxs(Box, { flexDirection: "column", borderStyle: "round", width: "100%", height: termRows - 1, children: [_jsx(HeaderBar, { planType: planType, lastRefreshAgo: lastRefreshAgo, isLoading: isLoading, errorMessage: errorMessage }), _jsxs(Box, { flexGrow: 1, flexDirection: "row", justifyContent: "center", alignItems: "center", paddingX: 2, gap: 4, children: [_jsx(PieChart, { usagePct: quotaData?.fiveHourUsagePct ?? 0, label: "5-Hour Quota", resetTime: quotaData?.fiveHourResetTime ?? null }), _jsx(PieChart, { usagePct: quotaData?.sevenDayUsagePct ?? 0, label: "Weekly Quota", resetTime: quotaData?.sevenDayResetTime ?? null })] }), _jsxs(Box, { width: "100%", paddingX: 2, justifyContent: "space-between", borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, children: [_jsx(Text, { dimColor: true, children: "q: Quit | r: Refresh | ?: Help" }), version && _jsxs(Text, { dimColor: true, children: ["v", version] })] })] }) }));
107
+ }
108
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"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"}
package/dist/auth.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * OAuth authentication and token management for claudemon.
3
+ *
4
+ * Reads Claude Code's OAuth credentials from:
5
+ * 1. macOS Keychain ("Claude Code-credentials")
6
+ * 2. ~/.claude/.credentials.json (Linux / older versions)
7
+ */
8
+ export declare function storeToken(tokenData: Record<string, unknown>): void;
9
+ export declare function loadToken(): Record<string, unknown> | null;
10
+ export declare function getOAuthToken(): string | null;
11
+ export declare function getSubscriptionType(): string | null;
12
+ export declare function isAuthenticated(): boolean;
13
+ export declare function clearToken(): void;
14
+ export declare function openBrowser(url: string): boolean;
15
+ export declare function detectPlanType(): string;
16
+ export declare function interactiveSetup(): Promise<void>;
17
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA4EH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAInE;AAED,wBAAgB,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAU1D;AAED,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAS7C;AAED,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAGnD;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAMD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAoBhD;AAYD,wBAAgB,cAAc,IAAI,MAAM,CAUvC;AAMD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiGtD"}
package/dist/auth.js ADDED
@@ -0,0 +1,234 @@
1
+ /**
2
+ * OAuth authentication and token management for claudemon.
3
+ *
4
+ * Reads Claude Code's OAuth credentials from:
5
+ * 1. macOS Keychain ("Claude Code-credentials")
6
+ * 2. ~/.claude/.credentials.json (Linux / older versions)
7
+ */
8
+ import { execFileSync, spawn } from "node:child_process";
9
+ import { chmodSync, existsSync, readFileSync, unlinkSync, writeFileSync, } from "node:fs";
10
+ import { homedir, platform } from "node:os";
11
+ import { join } from "node:path";
12
+ import { createInterface } from "node:readline/promises";
13
+ import { stdin, stdout } from "node:process";
14
+ import { CONFIG_DIR, ensureConfigDir, loadConfig, saveConfig } from "./config.js";
15
+ const TOKEN_FILE = join(CONFIG_DIR, "token.json");
16
+ const CLAUDE_CREDENTIALS_FILE = join(homedir(), ".claude", ".credentials.json");
17
+ function readKeychainCredentials() {
18
+ if (platform() !== "darwin")
19
+ return null;
20
+ try {
21
+ const raw = execFileSync("/usr/bin/security", [
22
+ "find-generic-password",
23
+ "-s",
24
+ "Claude Code-credentials",
25
+ "-w",
26
+ ], { timeout: 5000, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
27
+ if (!raw.trim())
28
+ return null;
29
+ return JSON.parse(raw.trim());
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ function readFileCredentials() {
36
+ if (!existsSync(CLAUDE_CREDENTIALS_FILE))
37
+ return null;
38
+ try {
39
+ const raw = readFileSync(CLAUDE_CREDENTIALS_FILE, "utf-8");
40
+ return JSON.parse(raw);
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ function getClaudeCodeCredentials() {
47
+ for (const reader of [readKeychainCredentials, readFileCredentials]) {
48
+ const data = reader();
49
+ if (data) {
50
+ const oauth = data["claudeAiOauth"];
51
+ if (oauth?.accessToken)
52
+ return oauth;
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+ // ---------------------------------------------------------------------------
58
+ // Token storage (claudemon's own cache)
59
+ // ---------------------------------------------------------------------------
60
+ export function storeToken(tokenData) {
61
+ ensureConfigDir();
62
+ writeFileSync(TOKEN_FILE, JSON.stringify(tokenData, null, 2));
63
+ chmodSync(TOKEN_FILE, 0o600);
64
+ }
65
+ export function loadToken() {
66
+ if (!existsSync(TOKEN_FILE))
67
+ return null;
68
+ try {
69
+ return JSON.parse(readFileSync(TOKEN_FILE, "utf-8"));
70
+ }
71
+ catch {
72
+ return null;
73
+ }
74
+ }
75
+ export function getOAuthToken() {
76
+ // Prefer Claude Code's live credentials (always fresh)
77
+ const creds = getClaudeCodeCredentials();
78
+ if (creds?.accessToken)
79
+ return creds.accessToken;
80
+ // Fallback to manually stored token
81
+ const tokenData = loadToken();
82
+ if (!tokenData)
83
+ return null;
84
+ return tokenData["oauth_token"] ?? null;
85
+ }
86
+ export function getSubscriptionType() {
87
+ const creds = getClaudeCodeCredentials();
88
+ return creds?.subscriptionType ?? null;
89
+ }
90
+ export function isAuthenticated() {
91
+ return getOAuthToken() !== null;
92
+ }
93
+ export function clearToken() {
94
+ if (existsSync(TOKEN_FILE))
95
+ unlinkSync(TOKEN_FILE);
96
+ }
97
+ // ---------------------------------------------------------------------------
98
+ // Browser helper
99
+ // ---------------------------------------------------------------------------
100
+ export function openBrowser(url) {
101
+ try {
102
+ const sys = platform().toLowerCase();
103
+ if (sys === "darwin") {
104
+ spawn("open", [url], { stdio: "ignore", detached: true }).unref();
105
+ return true;
106
+ }
107
+ else if (sys === "linux") {
108
+ spawn("xdg-open", [url], { stdio: "ignore", detached: true }).unref();
109
+ return true;
110
+ }
111
+ else if (sys === "win32") {
112
+ spawn("cmd", ["/c", "start", url], {
113
+ stdio: "ignore",
114
+ detached: true,
115
+ }).unref();
116
+ return true;
117
+ }
118
+ return false;
119
+ }
120
+ catch {
121
+ return false;
122
+ }
123
+ }
124
+ // ---------------------------------------------------------------------------
125
+ // Plan type detection
126
+ // ---------------------------------------------------------------------------
127
+ const PLAN_NAMES = {
128
+ default_claude_pro: "pro",
129
+ default_claude_max_5x: "max",
130
+ default_claude_max_20x: "max",
131
+ };
132
+ export function detectPlanType() {
133
+ const subType = getSubscriptionType();
134
+ if (subType) {
135
+ const plan = PLAN_NAMES[subType];
136
+ if (plan)
137
+ return plan;
138
+ const lower = subType.toLowerCase();
139
+ if (lower.includes("max"))
140
+ return "max";
141
+ if (lower.includes("pro"))
142
+ return "pro";
143
+ }
144
+ return "pro";
145
+ }
146
+ // ---------------------------------------------------------------------------
147
+ // Interactive setup
148
+ // ---------------------------------------------------------------------------
149
+ export async function interactiveSetup() {
150
+ const config = loadConfig();
151
+ console.log("=".repeat(50));
152
+ console.log(" Claudemon Setup — OAuth Authentication");
153
+ console.log("=".repeat(50));
154
+ console.log();
155
+ // Check if Claude Code credentials already exist
156
+ const creds = getClaudeCodeCredentials();
157
+ if (creds) {
158
+ console.log("Found existing Claude Code credentials.");
159
+ const token = creds.accessToken ?? "";
160
+ if (token.length > 16) {
161
+ console.log(` Token: ${token.slice(0, 12)}...${token.slice(-4)}`);
162
+ }
163
+ else {
164
+ console.log(" Token found");
165
+ }
166
+ const subType = creds.subscriptionType ?? "";
167
+ const plan = PLAN_NAMES[subType] ?? subType;
168
+ if (plan) {
169
+ config["plan_type"] = plan === "pro" || plan === "max" ? plan : "pro";
170
+ console.log(` Plan: ${plan.toUpperCase()}`);
171
+ }
172
+ saveConfig(config);
173
+ console.log();
174
+ console.log("Setup complete! Run 'claudemon' to launch the dashboard.");
175
+ return;
176
+ }
177
+ // No Claude Code credentials — guide user through login
178
+ console.log("Claudemon reads your Claude Code OAuth token to");
179
+ console.log("monitor quota usage. You need to be logged in to");
180
+ console.log("Claude Code first.");
181
+ console.log();
182
+ console.log("Run the following command to log in:");
183
+ console.log(" claude /login");
184
+ console.log();
185
+ const rl = createInterface({ input: stdin, output: stdout });
186
+ const answer = await rl.question("Open Claude Code login in browser? [Y/n]: ");
187
+ if (["", "y", "yes"].includes(answer.trim().toLowerCase())) {
188
+ openBrowser("https://claude.ai/login");
189
+ console.log();
190
+ console.log("Complete the login in your browser, then run:");
191
+ console.log(" claude /login");
192
+ console.log();
193
+ }
194
+ await rl.question("Press Enter after you've logged in to Claude Code...");
195
+ console.log();
196
+ // Re-check credentials
197
+ const newCreds = getClaudeCodeCredentials();
198
+ if (newCreds) {
199
+ console.log("Credentials found!");
200
+ const subType = newCreds.subscriptionType ?? "";
201
+ const plan = PLAN_NAMES[subType] ?? subType;
202
+ if (plan) {
203
+ config["plan_type"] = plan === "pro" || plan === "max" ? plan : "pro";
204
+ console.log(` Plan: ${plan.toUpperCase()}`);
205
+ }
206
+ saveConfig(config);
207
+ console.log();
208
+ console.log("Setup complete! Run 'claudemon' to launch the dashboard.");
209
+ }
210
+ else {
211
+ console.log("Could not find Claude Code credentials.");
212
+ console.log("Make sure Claude Code is installed and you've run:");
213
+ console.log(" claude /login");
214
+ console.log();
215
+ console.log("You can also paste your OAuth token manually.");
216
+ const token = await rl.question("OAuth token (or Enter to skip): ");
217
+ if (token.trim()) {
218
+ storeToken({ oauth_token: token.trim() });
219
+ console.log("Token saved.");
220
+ console.log("Detecting plan type...");
221
+ const detectedPlan = detectPlanType();
222
+ config["plan_type"] = detectedPlan;
223
+ console.log(` Plan: ${detectedPlan.toUpperCase()}`);
224
+ saveConfig(config);
225
+ console.log();
226
+ console.log("Setup complete! Run 'claudemon' to launch the dashboard.");
227
+ }
228
+ else {
229
+ console.log("Setup incomplete. Run 'claudemon setup' again after logging in.");
230
+ }
231
+ }
232
+ rl.close();
233
+ }
234
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Header bar component showing title, plan type, and refresh status.
3
+ */
4
+ import React from "react";
5
+ interface HeaderBarProps {
6
+ planType: string;
7
+ lastRefreshAgo: number;
8
+ isLoading: boolean;
9
+ errorMessage: string;
10
+ }
11
+ export declare function HeaderBar({ planType, lastRefreshAgo, isLoading, errorMessage, }: HeaderBarProps): React.ReactElement;
12
+ export {};
13
+ //# sourceMappingURL=HeaderBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeaderBar.d.ts","sourceRoot":"","sources":["../../src/components/HeaderBar.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,cAAc;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,SAAS,CAAC,EACtB,QAAQ,EACR,cAAc,EACd,SAAS,EACT,YAAY,GACf,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,CAgCrC"}
@@ -0,0 +1,21 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import chalk from "chalk";
4
+ export function HeaderBar({ planType, lastRefreshAgo, isLoading, errorMessage, }) {
5
+ const planBadge = chalk.bold.cyan(`[${planType.toUpperCase()}]`);
6
+ let status;
7
+ if (errorMessage) {
8
+ status = chalk.bold.red(`! ${errorMessage}`);
9
+ }
10
+ else if (isLoading) {
11
+ status = chalk.dim("⟳ loading...");
12
+ }
13
+ else if (lastRefreshAgo === 0) {
14
+ status = chalk.green("⟳ just now");
15
+ }
16
+ else {
17
+ status = chalk.dim(`⟳ ${lastRefreshAgo}s ago`);
18
+ }
19
+ return (_jsxs(Box, { width: "100%", paddingX: 2, justifyContent: "space-between", alignItems: "center", borderStyle: "single", borderBottom: true, borderTop: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { children: [chalk.bold("✨ Claude Usage Monitor"), " ", planBadge] }), _jsx(Text, { children: status })] }));
20
+ }
21
+ //# sourceMappingURL=HeaderBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeaderBar.js","sourceRoot":"","sources":["../../src/components/HeaderBar.tsx"],"names":[],"mappings":";AAKA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,MAAM,UAAU,SAAS,CAAC,EACtB,QAAQ,EACR,cAAc,EACd,SAAS,EACT,YAAY,GACC;IACb,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IAEjE,IAAI,MAAc,CAAC;IACnB,IAAI,YAAY,EAAE,CAAC;QACf,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,YAAY,EAAE,CAAC,CAAC;IACjD,CAAC;SAAM,IAAI,SAAS,EAAE,CAAC;QACnB,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACvC,CAAC;SAAM,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACvC,CAAC;SAAM,CAAC;QACJ,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,cAAc,OAAO,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,CACH,MAAC,GAAG,IACA,KAAK,EAAC,MAAM,EACZ,QAAQ,EAAE,CAAC,EACX,cAAc,EAAC,eAAe,EAC9B,UAAU,EAAC,QAAQ,EACnB,WAAW,EAAC,QAAQ,EACpB,YAAY,QACZ,SAAS,EAAE,KAAK,EAChB,UAAU,EAAE,KAAK,EACjB,WAAW,EAAE,KAAK,aAElB,MAAC,IAAI,eACA,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,OAAG,SAAS,IAC9C,EACP,KAAC,IAAI,cAAE,MAAM,GAAQ,IACnB,CACT,CAAC;AACN,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Donut/ring chart component showing quota usage.
3
+ */
4
+ import React from "react";
5
+ interface PieChartProps {
6
+ usagePct: number;
7
+ label: string;
8
+ resetTime: Date | null;
9
+ }
10
+ export declare function PieChart({ usagePct, label, resetTime, }: PieChartProps): React.ReactElement;
11
+ export {};
12
+ //# sourceMappingURL=PieChart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PieChart.d.ts","sourceRoot":"","sources":["../../src/components/PieChart.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,aAAa;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAqDD,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,KAAK,EACL,SAAS,GACV,EAAE,aAAa,GAAG,KAAK,CAAC,YAAY,CAuFpC"}
@@ -0,0 +1,116 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import chalk from "chalk";
4
+ function getColor(pct) {
5
+ if (pct < 50)
6
+ return chalk.green;
7
+ if (pct < 80)
8
+ return chalk.yellow;
9
+ return chalk.red;
10
+ }
11
+ function getBoldColor(pct) {
12
+ if (pct < 50)
13
+ return chalk.bold.green;
14
+ if (pct < 80)
15
+ return chalk.bold.yellow;
16
+ return chalk.bold.red;
17
+ }
18
+ function formatResetTime(reset) {
19
+ const now = new Date();
20
+ const resetLocal = reset;
21
+ const nowDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
22
+ const resetDate = new Date(resetLocal.getFullYear(), resetLocal.getMonth(), resetLocal.getDate());
23
+ const fmt = (d) => {
24
+ let hours = d.getHours();
25
+ const minutes = d.getMinutes();
26
+ const ampm = hours >= 12 ? "pm" : "am";
27
+ hours = hours % 12 || 12;
28
+ return `${hours}:${minutes.toString().padStart(2, "0")}${ampm}`;
29
+ };
30
+ // Same day
31
+ if (nowDate.getTime() === resetDate.getTime()) {
32
+ return fmt(resetLocal);
33
+ }
34
+ // Tomorrow
35
+ const tomorrow = new Date(nowDate);
36
+ tomorrow.setDate(tomorrow.getDate() + 1);
37
+ if (tomorrow.getTime() === resetDate.getTime()) {
38
+ return `tomorrow at ${fmt(resetLocal)}`;
39
+ }
40
+ // Other
41
+ const months = [
42
+ "jan", "feb", "mar", "apr", "may", "jun",
43
+ "jul", "aug", "sep", "oct", "nov", "dec",
44
+ ];
45
+ return `${months[resetLocal.getMonth()]} ${resetLocal.getDate()} at ${fmt(resetLocal)}`;
46
+ }
47
+ export function PieChart({ usagePct, label, resetTime, }) {
48
+ const pct = Math.max(0, Math.min(100, usagePct));
49
+ const color = getColor(pct);
50
+ const boldColor = getBoldColor(pct);
51
+ // Donut dimensions
52
+ const outerR = 6.5;
53
+ const innerR = 5.0;
54
+ const rows = Math.floor(outerR * 2) + 1;
55
+ const cols = Math.floor(outerR * 4) + 1;
56
+ // Usage fills clockwise from top
57
+ const usedAngle = 2 * Math.PI * (pct / 100);
58
+ const centerY = outerR;
59
+ const centerX = outerR * 2;
60
+ const grid = [];
61
+ for (let row = 0; row < rows; row++) {
62
+ const line = [];
63
+ for (let col = 0; col < cols; col++) {
64
+ const dy = row - centerY;
65
+ const dx = (col - centerX) / 2.0;
66
+ const dist = Math.sqrt(dx * dx + dy * dy);
67
+ if (innerR <= dist && dist <= outerR) {
68
+ let angle = Math.atan2(dx, -dy);
69
+ if (angle < 0)
70
+ angle += 2 * Math.PI;
71
+ if (angle <= usedAngle) {
72
+ line.push({ char: "█", style: color });
73
+ }
74
+ else {
75
+ line.push({ char: "░", style: chalk.gray });
76
+ }
77
+ }
78
+ else {
79
+ line.push({ char: " ", style: null });
80
+ }
81
+ }
82
+ grid.push(line);
83
+ }
84
+ // Place percentage text in center
85
+ const pctStr = `${Math.round(pct)}%`;
86
+ const centerRow = Math.floor(rows / 2);
87
+ const startCol = Math.floor(centerX - pctStr.length / 2);
88
+ for (let i = 0; i < pctStr.length; i++) {
89
+ const colIdx = startCol + i;
90
+ if (colIdx >= 0 && colIdx < cols) {
91
+ grid[centerRow][colIdx] = { char: pctStr[i], style: boldColor };
92
+ }
93
+ }
94
+ // Place label below percentage
95
+ const labelRow = centerRow + 1;
96
+ const labelStart = Math.floor(centerX - label.length / 2);
97
+ if (labelRow < rows) {
98
+ for (let i = 0; i < label.length; i++) {
99
+ const colIdx = labelStart + i;
100
+ if (colIdx >= 0 && colIdx < cols) {
101
+ grid[labelRow][colIdx] = { char: label[i], style: chalk.dim };
102
+ }
103
+ }
104
+ }
105
+ // Render to lines
106
+ const lines = [];
107
+ for (const row of grid) {
108
+ let line = "";
109
+ for (const cell of row) {
110
+ line += cell.style ? cell.style(cell.char) : cell.char;
111
+ }
112
+ lines.push(line);
113
+ }
114
+ return (_jsxs(Box, { flexDirection: "column", alignItems: "center", paddingY: 0, children: [lines.map((line, i) => (_jsx(Text, { children: line }, i))), resetTime && (_jsxs(Text, { dimColor: true, children: ["Resets ", formatResetTime(resetTime)] }))] }));
115
+ }
116
+ //# sourceMappingURL=PieChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PieChart.js","sourceRoot":"","sources":["../../src/components/PieChart.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Stats panel component showing quota details.
3
+ */
4
+ import React from "react";
5
+ import { type QuotaData } from "../models.js";
6
+ interface StatsPanelProps {
7
+ quotaData: QuotaData | null;
8
+ }
9
+ export declare function StatsPanel({ quotaData, }: StatsPanelProps): React.ReactElement;
10
+ export {};
11
+ //# sourceMappingURL=StatsPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatsPanel.d.ts","sourceRoot":"","sources":["../../src/components/StatsPanel.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,cAAc,CAAC;AAEtB,UAAU,eAAe;IACvB,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;CAC7B;AAcD,wBAAgB,UAAU,CAAC,EACzB,SAAS,GACV,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CA8CtC"}
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import chalk from "chalk";
4
+ import { fiveHourRemainingSeconds, sevenDayRemainingSeconds, formatCountdown, } from "../models.js";
5
+ function usageColor(pct) {
6
+ if (pct < 50)
7
+ return chalk.green;
8
+ if (pct < 80)
9
+ return chalk.yellow;
10
+ return chalk.red;
11
+ }
12
+ function estimateMessages(usagePct) {
13
+ const totalEst = 45;
14
+ const usedEst = Math.round(totalEst * usagePct / 100);
15
+ return `${usedEst} / ~${totalEst}`;
16
+ }
17
+ export function StatsPanel({ quotaData, }) {
18
+ if (!quotaData) {
19
+ return (_jsx(Box, { paddingX: 2, paddingY: 1, children: _jsx(Text, { dimColor: true, children: "Waiting for data..." }) }));
20
+ }
21
+ const q = quotaData;
22
+ const lines = [];
23
+ // 5-hour window
24
+ const fiveColor = usageColor(q.fiveHourUsagePct);
25
+ lines.push(chalk.bold("5-Hour Window"));
26
+ lines.push(` ├ Used: ${fiveColor(`${Math.round(q.fiveHourUsagePct)}%`)}`);
27
+ lines.push(` ├ Resets: ${formatCountdown(fiveHourRemainingSeconds(q))}`);
28
+ lines.push(` └ Messages: ~${estimateMessages(q.fiveHourUsagePct)}`);
29
+ lines.push("");
30
+ // 7-day window
31
+ const sevenColor = usageColor(q.sevenDayUsagePct);
32
+ lines.push(chalk.bold("7-Day Window"));
33
+ lines.push(` ├ Used: ${sevenColor(`${Math.round(q.sevenDayUsagePct)}%`)}`);
34
+ lines.push(` └ Resets: ${formatCountdown(sevenDayRemainingSeconds(q))}`);
35
+ lines.push("");
36
+ // Model quotas
37
+ if (q.modelQuotas.length > 0) {
38
+ lines.push(chalk.bold("Model Quotas"));
39
+ for (let i = 0; i < q.modelQuotas.length; i++) {
40
+ const mq = q.modelQuotas[i];
41
+ const prefix = i === q.modelQuotas.length - 1 ? " └" : " ├";
42
+ const mColor = usageColor(mq.usagePct);
43
+ lines.push(`${prefix} ${mq.modelName}: ${mColor(`${Math.round(mq.usagePct)}%`)}`);
44
+ }
45
+ lines.push("");
46
+ }
47
+ return (_jsx(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: lines.map((line, i) => (_jsx(Text, { children: line }, i))) }));
48
+ }
49
+ //# sourceMappingURL=StatsPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatsPanel.js","sourceRoot":"","sources":["../../src/components/StatsPanel.tsx"],"names":[],"mappings":";AAKA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAEL,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,GAChB,MAAM,cAAc,CAAC;AAMtB,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC;IACjC,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC,MAAM,CAAC;IAClC,OAAO,KAAK,CAAC,GAAG,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB;IACxC,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,GAAG,GAAG,CAAC,CAAC;IACtD,OAAO,GAAG,OAAO,OAAO,QAAQ,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EACzB,SAAS,GACO;IAChB,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CACL,KAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,YAC3B,KAAC,IAAI,IAAC,QAAQ,0CAA2B,GACrC,CACP,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,GAAG,SAAS,CAAC;IACpB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,gBAAgB;IAChB,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACjD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IACxC,KAAK,CAAC,IAAI,CAAC,iBAAiB,SAAS,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,iBAAiB,eAAe,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5E,KAAK,CAAC,IAAI,CAAC,kBAAkB,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACrE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,eAAe;IACf,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,iBAAiB,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChF,KAAK,CAAC,IAAI,CAAC,iBAAiB,eAAe,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,eAAe;IACf,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;YAC9D,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,EAAE,CAAC,SAAS,KAAK,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,YACjD,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CACtB,KAAC,IAAI,cAAU,IAAI,IAAR,CAAC,CAAe,CAC5B,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Configuration management for claudemon.
3
+ */
4
+ export declare const CONFIG_DIR: string;
5
+ export declare const CONFIG_FILE: string;
6
+ export declare function ensureConfigDir(): void;
7
+ export declare function loadConfig(): Record<string, string | number | boolean>;
8
+ export declare function saveConfig(config: Record<string, string | number | boolean>): void;
9
+ export declare function getConfigValue(key: string): string | number | boolean | undefined;
10
+ export declare function setConfigValue(key: string, value: string | number | boolean): void;
11
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,eAAO,MAAM,UAAU,QAA0C,CAAC;AAClE,eAAO,MAAM,WAAW,QAAkC,CAAC;AAO3D,wBAAgB,eAAe,IAAI,IAAI,CAItC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAWtE;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAChD,IAAI,CAaN;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAGvC;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAC/B,IAAI,CAIN"}
package/dist/config.js ADDED
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Configuration management for claudemon.
3
+ */
4
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
+ import { homedir } from "node:os";
6
+ import { join } from "node:path";
7
+ import { parse as parseTOML } from "smol-toml";
8
+ export const CONFIG_DIR = join(homedir(), ".config", "claudemon");
9
+ export const CONFIG_FILE = join(CONFIG_DIR, "config.toml");
10
+ const DEFAULT_CONFIG = {
11
+ plan_type: "pro",
12
+ refresh_interval: 5,
13
+ };
14
+ export function ensureConfigDir() {
15
+ if (!existsSync(CONFIG_DIR)) {
16
+ mkdirSync(CONFIG_DIR, { recursive: true });
17
+ }
18
+ }
19
+ export function loadConfig() {
20
+ if (!existsSync(CONFIG_FILE)) {
21
+ return { ...DEFAULT_CONFIG };
22
+ }
23
+ try {
24
+ const raw = readFileSync(CONFIG_FILE, "utf-8");
25
+ const config = parseTOML(raw);
26
+ return { ...DEFAULT_CONFIG, ...config };
27
+ }
28
+ catch {
29
+ return { ...DEFAULT_CONFIG };
30
+ }
31
+ }
32
+ export function saveConfig(config) {
33
+ ensureConfigDir();
34
+ const lines = [];
35
+ for (const [key, value] of Object.entries(config)) {
36
+ if (typeof value === "string") {
37
+ lines.push(`${key} = "${value}"`);
38
+ }
39
+ else if (typeof value === "boolean") {
40
+ lines.push(`${key} = ${value ? "true" : "false"}`);
41
+ }
42
+ else {
43
+ lines.push(`${key} = ${value}`);
44
+ }
45
+ }
46
+ writeFileSync(CONFIG_FILE, lines.join("\n") + "\n");
47
+ }
48
+ export function getConfigValue(key) {
49
+ const config = loadConfig();
50
+ return config[key];
51
+ }
52
+ export function setConfigValue(key, value) {
53
+ const config = loadConfig();
54
+ config[key] = value;
55
+ saveConfig(config);
56
+ }
57
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AAClE,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAE3D,MAAM,cAAc,GAA8C;IAChE,SAAS,EAAE,KAAK;IAChB,gBAAgB,EAAE,CAAC;CACpB,CAAC;AAEF,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAA8C,CAAC;QAC3E,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,MAAiD;IAEjD,eAAe,EAAE,CAAC;IAClB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,OAAO,KAAK,GAAG,CAAC,CAAC;QACpC,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,aAAa,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,GAAW;IAEX,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,GAAW,EACX,KAAgC;IAEhC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACpB,UAAU,CAAC,MAAM,CAAC,CAAC;AACrB,CAAC"}
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point for claudemon.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":";AAEA;;GAEG"}
package/dist/index.js ADDED
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * CLI entry point for claudemon.
5
+ */
6
+ import { createRequire } from "node:module";
7
+ import { render } from "ink";
8
+ import { App } from "./app.js";
9
+ const require = createRequire(import.meta.url);
10
+ const { version: VERSION } = require("../package.json");
11
+ function main() {
12
+ const args = process.argv.slice(2);
13
+ if (args.includes("--help") || args.includes("-h")) {
14
+ printHelp();
15
+ return;
16
+ }
17
+ if (args.includes("--version")) {
18
+ console.log(`claudemon ${VERSION}`);
19
+ return;
20
+ }
21
+ if (args[0] === "setup") {
22
+ runSetup();
23
+ return;
24
+ }
25
+ // Launch TUI (full-screen alternate screen)
26
+ process.stdout.write("\x1b[?1049h"); // enter alternate screen
27
+ process.stdout.write("\x1b[2J\x1b[H"); // clear + home
28
+ const instance = render(_jsx(App, { version: VERSION }));
29
+ instance.waitUntilExit().then(() => {
30
+ process.stdout.write("\x1b[?1049l"); // restore main screen
31
+ });
32
+ }
33
+ async function runSetup() {
34
+ const { interactiveSetup } = await import("./auth.js");
35
+ await interactiveSetup();
36
+ }
37
+ function printHelp() {
38
+ console.log(`claudemon — Claude Usage Monitor TUI
39
+
40
+ Usage:
41
+ claudemon Launch the TUI dashboard
42
+ claudemon setup Interactive OAuth setup
43
+
44
+ Options:
45
+ --help, -h Show this help message
46
+ --version Show version
47
+
48
+ Keybindings (in TUI):
49
+ q Quit
50
+ r Force refresh
51
+ ? Show help`);
52
+ }
53
+ main();
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":";;AAEA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAExD,SAAS,IAAI;IACX,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,EAAE,CAAC,CAAC;QACpC,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QACxB,QAAQ,EAAE,CAAC;QACX,OAAO;IACT,CAAC;IAED,4CAA4C;IAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,yBAAyB;IAC9D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAC,GAAG,IAAC,OAAO,EAAE,OAAO,GAAI,CAAC,CAAC;IACnD,QAAQ,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,sBAAsB;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,QAAQ;IACrB,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,gBAAgB,EAAE,CAAC;AAC3B,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;iBAaG,CAAC,CAAC;AACnB,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Data models for claudemon.
3
+ */
4
+ export interface ModelQuota {
5
+ modelName: string;
6
+ usagePct: number;
7
+ }
8
+ export interface QuotaData {
9
+ fiveHourUsagePct: number;
10
+ fiveHourResetTime: Date | null;
11
+ sevenDayUsagePct: number;
12
+ sevenDayResetTime: Date | null;
13
+ modelQuotas: ModelQuota[];
14
+ planType: string;
15
+ }
16
+ export interface TokenData {
17
+ inputTokens: number;
18
+ outputTokens: number;
19
+ cacheRead: number;
20
+ cacheWrite: number;
21
+ }
22
+ export interface ApiUsageData {
23
+ tokenCounts: TokenData;
24
+ costsUsd: number;
25
+ }
26
+ export declare function createQuotaData(partial?: Partial<QuotaData>): QuotaData;
27
+ export declare function createTokenData(partial?: Partial<TokenData>): TokenData;
28
+ export declare function tokenTotal(t: TokenData): number;
29
+ export declare function fiveHourRemainingSeconds(q: QuotaData): number;
30
+ export declare function sevenDayRemainingSeconds(q: QuotaData): number;
31
+ export declare function formatTokens(count: number): string;
32
+ export declare function formatCountdown(totalSeconds: number): string;
33
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,IAAI,GAAG,IAAI,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,IAAI,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,SAAS,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAUvE;AAED,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAQvE;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAE/C;AAED,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAI7D;AAED,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAI7D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAQ5D"}
package/dist/models.js ADDED
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Data models for claudemon.
3
+ */
4
+ export function createQuotaData(partial) {
5
+ return {
6
+ fiveHourUsagePct: 0,
7
+ fiveHourResetTime: null,
8
+ sevenDayUsagePct: 0,
9
+ sevenDayResetTime: null,
10
+ modelQuotas: [],
11
+ planType: "pro",
12
+ ...partial,
13
+ };
14
+ }
15
+ export function createTokenData(partial) {
16
+ return {
17
+ inputTokens: 0,
18
+ outputTokens: 0,
19
+ cacheRead: 0,
20
+ cacheWrite: 0,
21
+ ...partial,
22
+ };
23
+ }
24
+ export function tokenTotal(t) {
25
+ return t.inputTokens + t.outputTokens + t.cacheRead + t.cacheWrite;
26
+ }
27
+ export function fiveHourRemainingSeconds(q) {
28
+ if (!q.fiveHourResetTime)
29
+ return 0;
30
+ const delta = q.fiveHourResetTime.getTime() - Date.now();
31
+ return Math.max(0, Math.floor(delta / 1000));
32
+ }
33
+ export function sevenDayRemainingSeconds(q) {
34
+ if (!q.sevenDayResetTime)
35
+ return 0;
36
+ const delta = q.sevenDayResetTime.getTime() - Date.now();
37
+ return Math.max(0, Math.floor(delta / 1000));
38
+ }
39
+ export function formatTokens(count) {
40
+ if (count >= 1_000_000) {
41
+ return `${(count / 1_000_000).toFixed(1)}M`;
42
+ }
43
+ else if (count >= 1_000) {
44
+ return `${Math.round(count / 1_000)}K`;
45
+ }
46
+ return String(count);
47
+ }
48
+ export function formatCountdown(totalSeconds) {
49
+ if (totalSeconds <= 0)
50
+ return "now";
51
+ const days = Math.floor(totalSeconds / 86400);
52
+ const hours = Math.floor((totalSeconds % 86400) / 3600);
53
+ const minutes = Math.floor((totalSeconds % 3600) / 60);
54
+ if (days > 0)
55
+ return `${days}d ${hours}h`;
56
+ if (hours > 0)
57
+ return `${hours}h ${minutes}m`;
58
+ return `${minutes}m`;
59
+ }
60
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4BH,MAAM,UAAU,eAAe,CAAC,OAA4B;IAC1D,OAAO;QACL,gBAAgB,EAAE,CAAC;QACnB,iBAAiB,EAAE,IAAI;QACvB,gBAAgB,EAAE,CAAC;QACnB,iBAAiB,EAAE,IAAI;QACvB,WAAW,EAAE,EAAE;QACf,QAAQ,EAAE,KAAK;QACf,GAAG,OAAO;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAA4B;IAC1D,OAAO;QACL,WAAW,EAAE,CAAC;QACd,YAAY,EAAE,CAAC;QACf,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,CAAC;QACb,GAAG,OAAO;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAY;IACrC,OAAO,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,UAAU,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,CAAY;IACnD,IAAI,CAAC,CAAC,CAAC,iBAAiB;QAAE,OAAO,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,CAAY;IACnD,IAAI,CAAC,CAAC,CAAC,iBAAiB;QAAE,OAAO,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAC9C,CAAC;SAAM,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC;IACzC,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,YAAoB;IAClD,IAAI,YAAY,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC;IAC1C,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,GAAG,KAAK,KAAK,OAAO,GAAG,CAAC;IAC9C,OAAO,GAAG,OAAO,GAAG,CAAC;AACvB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "claudemon",
3
+ "version": "0.2.0",
4
+ "description": "Claude Usage Monitor TUI - monitor your Claude usage in real-time",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "claudemon": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "keywords": [
14
+ "claude",
15
+ "anthropic",
16
+ "quota",
17
+ "tui",
18
+ "cli"
19
+ ],
20
+ "license": "MIT",
21
+ "dependencies": {
22
+ "chalk": "^5.3.0",
23
+ "ink": "^5.1.0",
24
+ "react": "^18.3.1",
25
+ "smol-toml": "^1.3.1"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^25.2.3",
29
+ "@types/react": "^18.3.12",
30
+ "typescript": "^5.7.0"
31
+ },
32
+ "scripts": {
33
+ "build": "tsc",
34
+ "dev": "tsc --watch",
35
+ "start": "node dist/index.js",
36
+ "lint": "tsc --noEmit"
37
+ }
38
+ }