claude-usage-dashboard 1.3.7 → 1.3.9
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/bin/cli.sh +11 -0
- package/package.json +2 -2
- package/server/credentials.js +28 -3
- package/server/index.js +0 -1
package/bin/cli.sh
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Resolve symlinks to find the real script location
|
|
3
|
+
SCRIPT="$0"
|
|
4
|
+
while [ -L "$SCRIPT" ]; do
|
|
5
|
+
DIR="$(cd -P "$(dirname "$SCRIPT")" && pwd)"
|
|
6
|
+
SCRIPT="$(readlink "$SCRIPT")"
|
|
7
|
+
case "$SCRIPT" in /*) ;; *) SCRIPT="$DIR/$SCRIPT" ;; esac
|
|
8
|
+
done
|
|
9
|
+
DIR="$(cd -P "$(dirname "$SCRIPT")" && pwd)"
|
|
10
|
+
|
|
11
|
+
exec node "$DIR/../server/index.js" "$@"
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-usage-dashboard",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.9",
|
|
4
4
|
"description": "Dashboard that visualizes Claude Code usage from local session logs",
|
|
5
5
|
"main": "server/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"claude-usage-dashboard": "
|
|
7
|
+
"claude-usage-dashboard": "bin/cli.sh"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"bin/",
|
package/server/credentials.js
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import os from 'os';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
4
5
|
|
|
5
6
|
const CREDENTIALS_PATH = path.join(os.homedir(), '.claude', '.credentials.json');
|
|
7
|
+
const KEYCHAIN_SERVICE = 'Claude Code-credentials';
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
function readFromKeychain() {
|
|
10
|
+
if (process.platform !== 'darwin') return null;
|
|
11
|
+
try {
|
|
12
|
+
const raw = execSync(
|
|
13
|
+
`security find-generic-password -s "${KEYCHAIN_SERVICE}" -w`,
|
|
14
|
+
{ encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }
|
|
15
|
+
).trim();
|
|
16
|
+
const data = JSON.parse(raw);
|
|
17
|
+
return data.claudeAiOauth || null;
|
|
18
|
+
} catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function readFromFile(credentialsPath) {
|
|
8
24
|
try {
|
|
9
25
|
const raw = fs.readFileSync(credentialsPath, 'utf-8');
|
|
10
26
|
const data = JSON.parse(raw);
|
|
@@ -14,7 +30,16 @@ export function readCredentials(credentialsPath = CREDENTIALS_PATH) {
|
|
|
14
30
|
}
|
|
15
31
|
}
|
|
16
32
|
|
|
17
|
-
export function
|
|
33
|
+
export function readCredentials(credentialsPath) {
|
|
34
|
+
if (credentialsPath) {
|
|
35
|
+
// Explicit path provided (e.g. tests) — skip Keychain
|
|
36
|
+
return readFromFile(credentialsPath);
|
|
37
|
+
}
|
|
38
|
+
// Try macOS Keychain first, then fall back to default file
|
|
39
|
+
return readFromKeychain() || readFromFile(CREDENTIALS_PATH);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function getSubscriptionInfo(credentialsPath) {
|
|
18
43
|
const creds = readCredentials(credentialsPath);
|
|
19
44
|
if (!creds) return null;
|
|
20
45
|
|
|
@@ -29,7 +54,7 @@ export function getSubscriptionInfo(credentialsPath = CREDENTIALS_PATH) {
|
|
|
29
54
|
return { subscriptionType: subscriptionType || null, rateLimitTier: rateLimitTier || null, plan };
|
|
30
55
|
}
|
|
31
56
|
|
|
32
|
-
export function getAccessToken(credentialsPath
|
|
57
|
+
export function getAccessToken(credentialsPath) {
|
|
33
58
|
const creds = readCredentials(credentialsPath);
|
|
34
59
|
if (!creds || !creds.accessToken) return null;
|
|
35
60
|
if (creds.expiresAt && creds.expiresAt < Date.now()) return null;
|
package/server/index.js
CHANGED