claudeline 1.2.0 → 1.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.
- package/dist/index.js +121 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -259,6 +259,11 @@ function listComponents() {
|
|
|
259
259
|
"elapsed"
|
|
260
260
|
]
|
|
261
261
|
},
|
|
262
|
+
{
|
|
263
|
+
name: "Account",
|
|
264
|
+
prefix: "account",
|
|
265
|
+
items: ["email", "name", "display-name", "org", "plan", "tier"]
|
|
266
|
+
},
|
|
262
267
|
{
|
|
263
268
|
name: "Usage/Limits",
|
|
264
269
|
prefix: "usage",
|
|
@@ -490,11 +495,14 @@ function listThemes() {
|
|
|
490
495
|
import * as fs from "fs";
|
|
491
496
|
import * as path from "path";
|
|
492
497
|
import * as os from "os";
|
|
498
|
+
function getClaudeConfigDir() {
|
|
499
|
+
return process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude");
|
|
500
|
+
}
|
|
493
501
|
function getClaudeDir(project) {
|
|
494
502
|
if (project) {
|
|
495
503
|
return path.join(process.cwd(), ".claude");
|
|
496
504
|
}
|
|
497
|
-
return
|
|
505
|
+
return getClaudeConfigDir();
|
|
498
506
|
}
|
|
499
507
|
function escapeForShell(str) {
|
|
500
508
|
return str.replace(/'/g, "'\\''");
|
|
@@ -625,7 +633,7 @@ function getSampleDataJson() {
|
|
|
625
633
|
|
|
626
634
|
// src/runtime.ts
|
|
627
635
|
import * as path3 from "path";
|
|
628
|
-
import * as
|
|
636
|
+
import * as os2 from "os";
|
|
629
637
|
import * as fs3 from "fs";
|
|
630
638
|
import { execSync as execSync2 } from "child_process";
|
|
631
639
|
|
|
@@ -727,13 +735,24 @@ function getEmoji(name) {
|
|
|
727
735
|
// src/usage.ts
|
|
728
736
|
import * as fs2 from "fs";
|
|
729
737
|
import * as path2 from "path";
|
|
730
|
-
import * as
|
|
738
|
+
import * as crypto from "crypto";
|
|
731
739
|
import { execSync } from "child_process";
|
|
732
740
|
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
733
|
-
var
|
|
734
|
-
function
|
|
741
|
+
var PROFILE_CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
742
|
+
function tokenHash(token) {
|
|
743
|
+
return crypto.createHash("sha256").update(token).digest("hex").slice(0, 12);
|
|
744
|
+
}
|
|
745
|
+
function getCacheFile(token, type) {
|
|
746
|
+
const dir = path2.join(getClaudeConfigDir(), "cache");
|
|
747
|
+
try {
|
|
748
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
749
|
+
} catch {
|
|
750
|
+
}
|
|
751
|
+
return path2.join(dir, `claudeline-${type}-${tokenHash(token)}.json`);
|
|
752
|
+
}
|
|
753
|
+
function readCache(cacheFile) {
|
|
735
754
|
try {
|
|
736
|
-
const raw = fs2.readFileSync(
|
|
755
|
+
const raw = fs2.readFileSync(cacheFile, "utf8");
|
|
737
756
|
const cached = JSON.parse(raw);
|
|
738
757
|
if (Date.now() - cached.fetched_at < CACHE_TTL_MS) {
|
|
739
758
|
return cached;
|
|
@@ -742,16 +761,25 @@ function readCache() {
|
|
|
742
761
|
}
|
|
743
762
|
return null;
|
|
744
763
|
}
|
|
745
|
-
function writeCache(data) {
|
|
764
|
+
function writeCache(cacheFile, data) {
|
|
746
765
|
try {
|
|
747
|
-
fs2.writeFileSync(
|
|
766
|
+
fs2.writeFileSync(cacheFile, JSON.stringify({ data, fetched_at: Date.now() }));
|
|
748
767
|
} catch {
|
|
749
768
|
}
|
|
750
769
|
}
|
|
770
|
+
function getKeychainService() {
|
|
771
|
+
const configDir = process.env.CLAUDE_CONFIG_DIR;
|
|
772
|
+
if (configDir) {
|
|
773
|
+
const suffix = crypto.createHash("sha256").update(configDir).digest("hex").slice(0, 8);
|
|
774
|
+
return `Claude Code-credentials-${suffix}`;
|
|
775
|
+
}
|
|
776
|
+
return "Claude Code-credentials";
|
|
777
|
+
}
|
|
751
778
|
function getOAuthToken() {
|
|
752
779
|
try {
|
|
780
|
+
const service = getKeychainService();
|
|
753
781
|
const raw = execSync(
|
|
754
|
-
|
|
782
|
+
`security find-generic-password -s "${service}" -w 2>/dev/null`,
|
|
755
783
|
{ encoding: "utf8" }
|
|
756
784
|
).trim();
|
|
757
785
|
const parsed = JSON.parse(raw);
|
|
@@ -764,9 +792,7 @@ function getOAuthToken() {
|
|
|
764
792
|
return null;
|
|
765
793
|
}
|
|
766
794
|
}
|
|
767
|
-
function fetchUsage() {
|
|
768
|
-
const token = getOAuthToken();
|
|
769
|
-
if (!token) return null;
|
|
795
|
+
function fetchUsage(token) {
|
|
770
796
|
try {
|
|
771
797
|
const result = execSync(
|
|
772
798
|
`curl -s --max-time 5 -H "Authorization: Bearer ${token}" -H "anthropic-beta: oauth-2025-04-20" "https://api.anthropic.com/api/oauth/usage"`,
|
|
@@ -782,11 +808,14 @@ function fetchUsage() {
|
|
|
782
808
|
}
|
|
783
809
|
}
|
|
784
810
|
function getUsageData() {
|
|
785
|
-
const
|
|
811
|
+
const token = getOAuthToken();
|
|
812
|
+
if (!token) return null;
|
|
813
|
+
const cacheFile = getCacheFile(token, "usage");
|
|
814
|
+
const cached = readCache(cacheFile);
|
|
786
815
|
if (cached) return cached.data;
|
|
787
|
-
const data = fetchUsage();
|
|
816
|
+
const data = fetchUsage(token);
|
|
788
817
|
if (data) {
|
|
789
|
-
writeCache(data);
|
|
818
|
+
writeCache(cacheFile, data);
|
|
790
819
|
}
|
|
791
820
|
return data;
|
|
792
821
|
}
|
|
@@ -809,6 +838,70 @@ function makeBar(pct, width, label) {
|
|
|
809
838
|
const bar = "\u25B0".repeat(filled) + "\u25B1".repeat(width - filled);
|
|
810
839
|
return label ? label + bar : bar;
|
|
811
840
|
}
|
|
841
|
+
function readProfileCache(cacheFile) {
|
|
842
|
+
try {
|
|
843
|
+
const raw = fs2.readFileSync(cacheFile, "utf8");
|
|
844
|
+
const cached = JSON.parse(raw);
|
|
845
|
+
if (Date.now() - cached.fetched_at < PROFILE_CACHE_TTL_MS) {
|
|
846
|
+
return cached;
|
|
847
|
+
}
|
|
848
|
+
} catch {
|
|
849
|
+
}
|
|
850
|
+
return null;
|
|
851
|
+
}
|
|
852
|
+
function writeProfileCache(cacheFile, data) {
|
|
853
|
+
try {
|
|
854
|
+
fs2.writeFileSync(cacheFile, JSON.stringify({ data, fetched_at: Date.now() }));
|
|
855
|
+
} catch {
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
function fetchProfile(token) {
|
|
859
|
+
try {
|
|
860
|
+
const result = execSync(
|
|
861
|
+
`curl -s --max-time 5 -H "Authorization: Bearer ${token}" -H "anthropic-beta: oauth-2025-04-20" "https://api.anthropic.com/api/oauth/profile"`,
|
|
862
|
+
{ encoding: "utf8" }
|
|
863
|
+
).trim();
|
|
864
|
+
const data = JSON.parse(result);
|
|
865
|
+
if (data.account?.email) {
|
|
866
|
+
return data;
|
|
867
|
+
}
|
|
868
|
+
return null;
|
|
869
|
+
} catch {
|
|
870
|
+
return null;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
function getProfileData() {
|
|
874
|
+
const token = getOAuthToken();
|
|
875
|
+
if (!token) return null;
|
|
876
|
+
const cacheFile = getCacheFile(token, "profile");
|
|
877
|
+
const cached = readProfileCache(cacheFile);
|
|
878
|
+
if (cached) return cached.data;
|
|
879
|
+
const data = fetchProfile(token);
|
|
880
|
+
if (data) {
|
|
881
|
+
writeProfileCache(cacheFile, data);
|
|
882
|
+
}
|
|
883
|
+
return data;
|
|
884
|
+
}
|
|
885
|
+
function evaluateAccountComponent(key) {
|
|
886
|
+
const data = getProfileData();
|
|
887
|
+
if (!data) return "";
|
|
888
|
+
switch (key) {
|
|
889
|
+
case "email":
|
|
890
|
+
return data.account.email;
|
|
891
|
+
case "name":
|
|
892
|
+
return data.account.full_name;
|
|
893
|
+
case "display-name":
|
|
894
|
+
return data.account.display_name;
|
|
895
|
+
case "org":
|
|
896
|
+
return data.organization.name;
|
|
897
|
+
case "plan":
|
|
898
|
+
return data.organization.organization_type;
|
|
899
|
+
case "tier":
|
|
900
|
+
return data.organization.rate_limit_tier;
|
|
901
|
+
default:
|
|
902
|
+
return "";
|
|
903
|
+
}
|
|
904
|
+
}
|
|
812
905
|
function evaluateUsageComponent(key, args) {
|
|
813
906
|
const data = getUsageData();
|
|
814
907
|
if (!data) return "";
|
|
@@ -999,7 +1092,7 @@ function evaluateFsComponent(key, data) {
|
|
|
999
1092
|
case "project-path":
|
|
1000
1093
|
return data.workspace?.project_dir || "";
|
|
1001
1094
|
case "home":
|
|
1002
|
-
return (data.workspace?.current_dir || data.cwd || "").replace(
|
|
1095
|
+
return (data.workspace?.current_dir || data.cwd || "").replace(os2.homedir(), "~");
|
|
1003
1096
|
case "cwd":
|
|
1004
1097
|
return data.cwd || "";
|
|
1005
1098
|
case "relative": {
|
|
@@ -1216,11 +1309,11 @@ function evaluateEnvComponent(key) {
|
|
|
1216
1309
|
return match?.[1] || "";
|
|
1217
1310
|
}
|
|
1218
1311
|
case "user":
|
|
1219
|
-
return
|
|
1312
|
+
return os2.userInfo().username;
|
|
1220
1313
|
case "hostname":
|
|
1221
|
-
return
|
|
1314
|
+
return os2.hostname();
|
|
1222
1315
|
case "hostname-short":
|
|
1223
|
-
return
|
|
1316
|
+
return os2.hostname().split(".")[0];
|
|
1224
1317
|
case "shell":
|
|
1225
1318
|
return path3.basename(process.env.SHELL || "");
|
|
1226
1319
|
case "term":
|
|
@@ -1230,11 +1323,11 @@ function evaluateEnvComponent(key) {
|
|
|
1230
1323
|
case "arch":
|
|
1231
1324
|
return process.arch;
|
|
1232
1325
|
case "os-release":
|
|
1233
|
-
return
|
|
1326
|
+
return os2.release();
|
|
1234
1327
|
case "cpus":
|
|
1235
|
-
return
|
|
1328
|
+
return os2.cpus().length.toString();
|
|
1236
1329
|
case "memory":
|
|
1237
|
-
return Math.round(
|
|
1330
|
+
return Math.round(os2.totalmem() / 1024 / 1024 / 1024) + "GB";
|
|
1238
1331
|
default:
|
|
1239
1332
|
return "";
|
|
1240
1333
|
}
|
|
@@ -1345,6 +1438,9 @@ function evaluateComponent(comp, data, options) {
|
|
|
1345
1438
|
case "usage":
|
|
1346
1439
|
result = evaluateUsageComponent(comp.key, comp.args);
|
|
1347
1440
|
break;
|
|
1441
|
+
case "account":
|
|
1442
|
+
result = evaluateAccountComponent(comp.key);
|
|
1443
|
+
break;
|
|
1348
1444
|
case "time":
|
|
1349
1445
|
result = evaluateTimeComponent(comp.key, data);
|
|
1350
1446
|
break;
|
|
@@ -1404,11 +1500,12 @@ function evaluateFormat(format, data, options = {}) {
|
|
|
1404
1500
|
noColor: options.noColor ?? false
|
|
1405
1501
|
};
|
|
1406
1502
|
const components = parseFormat(format);
|
|
1407
|
-
|
|
1503
|
+
const result = evaluateComponents(components, data, opts);
|
|
1504
|
+
return opts.noColor ? result : result + `\x1B[0m`;
|
|
1408
1505
|
}
|
|
1409
1506
|
|
|
1410
1507
|
// src/index.ts
|
|
1411
|
-
var VERSION = "1.1
|
|
1508
|
+
var VERSION = "1.3.1";
|
|
1412
1509
|
async function readStdin() {
|
|
1413
1510
|
return new Promise((resolve, reject) => {
|
|
1414
1511
|
let input = "";
|