claudeline 1.7.0 → 1.8.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/dist/index.js +197 -30
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -598,7 +598,7 @@ function getSampleDataJson() {
|
|
|
598
598
|
import * as path3 from "path";
|
|
599
599
|
import * as os3 from "os";
|
|
600
600
|
import * as fs3 from "fs";
|
|
601
|
-
import { execSync } from "child_process";
|
|
601
|
+
import { execSync as execSync2 } from "child_process";
|
|
602
602
|
|
|
603
603
|
// src/separators.ts
|
|
604
604
|
var SEPARATORS = {
|
|
@@ -639,6 +639,8 @@ function getSeparator(name) {
|
|
|
639
639
|
import * as fs2 from "fs";
|
|
640
640
|
import * as path2 from "path";
|
|
641
641
|
import * as os2 from "os";
|
|
642
|
+
import * as crypto from "crypto";
|
|
643
|
+
import { execSync } from "child_process";
|
|
642
644
|
var CLUSAGE_API_FILE = path2.join(os2.homedir(), ".claude", "clusage-api.json");
|
|
643
645
|
var CLUSAGE_STALE_MS = 10 * 60 * 1e3;
|
|
644
646
|
var _clusageCache = null;
|
|
@@ -660,24 +662,162 @@ function getClusageAccount() {
|
|
|
660
662
|
if (!payload || payload.accounts.length === 0) return null;
|
|
661
663
|
return payload.accounts[0];
|
|
662
664
|
}
|
|
665
|
+
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
666
|
+
var PROFILE_CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
667
|
+
var ANTHROPIC_BETA_HEADER = "oauth-2025-04-20";
|
|
668
|
+
function tokenHash(token) {
|
|
669
|
+
return crypto.createHash("sha256").update(token).digest("hex").slice(0, 12);
|
|
670
|
+
}
|
|
671
|
+
function getCacheFile(token, type) {
|
|
672
|
+
const dir = path2.join(getClaudeConfigDir(), "cache");
|
|
673
|
+
try {
|
|
674
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
675
|
+
} catch {
|
|
676
|
+
}
|
|
677
|
+
return path2.join(dir, `claudeline-${type}-${tokenHash(token)}.json`);
|
|
678
|
+
}
|
|
679
|
+
function readCache(cacheFile, ttlMs) {
|
|
680
|
+
try {
|
|
681
|
+
const raw = fs2.readFileSync(cacheFile, "utf8");
|
|
682
|
+
const cached = JSON.parse(raw);
|
|
683
|
+
if (Date.now() - cached.fetched_at < ttlMs) {
|
|
684
|
+
return cached.data;
|
|
685
|
+
}
|
|
686
|
+
} catch {
|
|
687
|
+
}
|
|
688
|
+
return null;
|
|
689
|
+
}
|
|
690
|
+
function writeCache(cacheFile, data) {
|
|
691
|
+
try {
|
|
692
|
+
fs2.writeFileSync(cacheFile, JSON.stringify({ data, fetched_at: Date.now() }));
|
|
693
|
+
} catch {
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
function extractToken(raw) {
|
|
697
|
+
try {
|
|
698
|
+
const parsed = JSON.parse(raw);
|
|
699
|
+
if (typeof parsed === "string") return parsed;
|
|
700
|
+
if (parsed.claudeAiOauth?.accessToken) return parsed.claudeAiOauth.accessToken;
|
|
701
|
+
if (parsed.accessToken) return parsed.accessToken;
|
|
702
|
+
if (parsed.access_token) return parsed.access_token;
|
|
703
|
+
} catch {
|
|
704
|
+
}
|
|
705
|
+
return null;
|
|
706
|
+
}
|
|
707
|
+
function getKeychainService() {
|
|
708
|
+
const configDir = process.env.CLAUDE_CONFIG_DIR;
|
|
709
|
+
if (configDir) {
|
|
710
|
+
const suffix = crypto.createHash("sha256").update(configDir).digest("hex").slice(0, 8);
|
|
711
|
+
return `Claude Code-credentials-${suffix}`;
|
|
712
|
+
}
|
|
713
|
+
return "Claude Code-credentials";
|
|
714
|
+
}
|
|
715
|
+
function getOAuthTokenMacOS() {
|
|
716
|
+
try {
|
|
717
|
+
const service = getKeychainService();
|
|
718
|
+
const raw = execSync(
|
|
719
|
+
`security find-generic-password -s "${service}" -w 2>/dev/null`,
|
|
720
|
+
{ encoding: "utf8" }
|
|
721
|
+
).trim();
|
|
722
|
+
return extractToken(raw);
|
|
723
|
+
} catch {
|
|
724
|
+
return null;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
function getOAuthTokenLinux() {
|
|
728
|
+
try {
|
|
729
|
+
const configDir = process.env.CLAUDE_CONFIG_DIR || path2.join(os2.homedir(), ".claude");
|
|
730
|
+
const credPath = path2.join(configDir, ".credentials.json");
|
|
731
|
+
const raw = fs2.readFileSync(credPath, "utf8").trim();
|
|
732
|
+
return extractToken(raw);
|
|
733
|
+
} catch {
|
|
734
|
+
return null;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
function getOAuthToken() {
|
|
738
|
+
switch (process.platform) {
|
|
739
|
+
case "darwin":
|
|
740
|
+
return getOAuthTokenMacOS();
|
|
741
|
+
case "linux":
|
|
742
|
+
return getOAuthTokenLinux();
|
|
743
|
+
default:
|
|
744
|
+
return null;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
function apiGet(token, urlPath) {
|
|
748
|
+
try {
|
|
749
|
+
return execSync(
|
|
750
|
+
`curl -s --max-time 5 -H "Content-Type: application/json" -H "User-Agent: claude-code/2.1.69" -H "Authorization: Bearer $__CLAUDE_TOKEN" -H "anthropic-beta: ${ANTHROPIC_BETA_HEADER}" "https://api.anthropic.com${urlPath}"`,
|
|
751
|
+
{ encoding: "utf8", env: { ...process.env, __CLAUDE_TOKEN: token } }
|
|
752
|
+
).trim();
|
|
753
|
+
} catch {
|
|
754
|
+
return null;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
function fetchUsageDirect(token) {
|
|
758
|
+
try {
|
|
759
|
+
const result = apiGet(token, "/api/oauth/usage");
|
|
760
|
+
if (!result) return null;
|
|
761
|
+
const data = JSON.parse(result);
|
|
762
|
+
if (data.five_hour && data.seven_day) return data;
|
|
763
|
+
return null;
|
|
764
|
+
} catch {
|
|
765
|
+
return null;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
function fetchProfileDirect(token) {
|
|
769
|
+
try {
|
|
770
|
+
const result = apiGet(token, "/api/oauth/profile");
|
|
771
|
+
if (!result) return null;
|
|
772
|
+
const data = JSON.parse(result);
|
|
773
|
+
if (data.account?.email) return { email: data.account.email };
|
|
774
|
+
return null;
|
|
775
|
+
} catch {
|
|
776
|
+
return null;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
function getUsageDataDirect() {
|
|
780
|
+
const token = getOAuthToken();
|
|
781
|
+
if (!token) return null;
|
|
782
|
+
const cacheFile = getCacheFile(token, "usage");
|
|
783
|
+
const cached = readCache(cacheFile, CACHE_TTL_MS);
|
|
784
|
+
if (cached) return cached;
|
|
785
|
+
const data = fetchUsageDirect(token);
|
|
786
|
+
if (data) writeCache(cacheFile, data);
|
|
787
|
+
return data;
|
|
788
|
+
}
|
|
789
|
+
function getProfileDataDirect() {
|
|
790
|
+
const token = getOAuthToken();
|
|
791
|
+
if (!token) return null;
|
|
792
|
+
const cacheFile = getCacheFile(token, "profile");
|
|
793
|
+
const cached = readCache(cacheFile, PROFILE_CACHE_TTL_MS);
|
|
794
|
+
if (cached) return cached;
|
|
795
|
+
const data = fetchProfileDirect(token);
|
|
796
|
+
if (data) writeCache(cacheFile, data);
|
|
797
|
+
return data;
|
|
798
|
+
}
|
|
663
799
|
function getUsageData() {
|
|
664
800
|
const account = getClusageAccount();
|
|
665
|
-
if (
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
801
|
+
if (account) {
|
|
802
|
+
return {
|
|
803
|
+
five_hour: {
|
|
804
|
+
utilization: account.fiveHour.utilization,
|
|
805
|
+
resets_at: account.fiveHour.resetsAt
|
|
806
|
+
},
|
|
807
|
+
seven_day: {
|
|
808
|
+
utilization: account.sevenDay.utilization,
|
|
809
|
+
resets_at: account.sevenDay.resetsAt
|
|
810
|
+
}
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
return getUsageDataDirect();
|
|
676
814
|
}
|
|
677
815
|
function getProfileData() {
|
|
678
816
|
const account = getClusageAccount();
|
|
679
|
-
if (
|
|
680
|
-
|
|
817
|
+
if (account?.profile) {
|
|
818
|
+
return { email: account.profile.email };
|
|
819
|
+
}
|
|
820
|
+
return getProfileDataDirect();
|
|
681
821
|
}
|
|
682
822
|
function formatTimeUntil(isoDate) {
|
|
683
823
|
const reset = new Date(isoDate).getTime();
|
|
@@ -804,7 +944,7 @@ function evaluateUsageComponent(key, args, noColor = false) {
|
|
|
804
944
|
const { delta } = calculatePace(data.seven_day, SEVEN_DAY_MS);
|
|
805
945
|
return formatPaceIcon(delta, noColor);
|
|
806
946
|
}
|
|
807
|
-
// Clusage momentum/projection data
|
|
947
|
+
// Clusage-only momentum/projection data (no direct API fallback)
|
|
808
948
|
case "velocity": {
|
|
809
949
|
const m = getClusageAccount()?.momentum;
|
|
810
950
|
return m ? m.velocity.toFixed(1) + " pp/hr" : "";
|
|
@@ -986,7 +1126,7 @@ function formatDuration(ms) {
|
|
|
986
1126
|
}
|
|
987
1127
|
function execCommand(cmd) {
|
|
988
1128
|
try {
|
|
989
|
-
return
|
|
1129
|
+
return execSync2(cmd, { encoding: "utf8" }).trim();
|
|
990
1130
|
} catch {
|
|
991
1131
|
return "";
|
|
992
1132
|
}
|
|
@@ -1101,7 +1241,7 @@ function evaluateGitComponent(key, noColor = false, noIcons = false) {
|
|
|
1101
1241
|
return execCommand("git branch --show-current 2>/dev/null");
|
|
1102
1242
|
case "status":
|
|
1103
1243
|
try {
|
|
1104
|
-
|
|
1244
|
+
execSync2("git diff --quiet 2>/dev/null");
|
|
1105
1245
|
return "\u2713";
|
|
1106
1246
|
} catch {
|
|
1107
1247
|
return "*";
|
|
@@ -1109,14 +1249,14 @@ function evaluateGitComponent(key, noColor = false, noIcons = false) {
|
|
|
1109
1249
|
case "status-icon":
|
|
1110
1250
|
if (noIcons) return "";
|
|
1111
1251
|
try {
|
|
1112
|
-
|
|
1252
|
+
execSync2("git diff --quiet 2>/dev/null");
|
|
1113
1253
|
return getNerdIcon("sparkle");
|
|
1114
1254
|
} catch {
|
|
1115
1255
|
return getNerdIcon("commit");
|
|
1116
1256
|
}
|
|
1117
1257
|
case "status-word":
|
|
1118
1258
|
try {
|
|
1119
|
-
|
|
1259
|
+
execSync2("git diff --quiet 2>/dev/null");
|
|
1120
1260
|
return "clean";
|
|
1121
1261
|
} catch {
|
|
1122
1262
|
return "dirty";
|
|
@@ -1370,21 +1510,21 @@ function evaluateCondition(condition, data) {
|
|
|
1370
1510
|
switch (condition) {
|
|
1371
1511
|
case "git":
|
|
1372
1512
|
try {
|
|
1373
|
-
|
|
1513
|
+
execSync2("git rev-parse --git-dir 2>/dev/null");
|
|
1374
1514
|
return true;
|
|
1375
1515
|
} catch {
|
|
1376
1516
|
return false;
|
|
1377
1517
|
}
|
|
1378
1518
|
case "dirty":
|
|
1379
1519
|
try {
|
|
1380
|
-
|
|
1520
|
+
execSync2("git diff --quiet 2>/dev/null");
|
|
1381
1521
|
return false;
|
|
1382
1522
|
} catch {
|
|
1383
1523
|
return true;
|
|
1384
1524
|
}
|
|
1385
1525
|
case "clean":
|
|
1386
1526
|
try {
|
|
1387
|
-
|
|
1527
|
+
execSync2("git diff --quiet 2>/dev/null");
|
|
1388
1528
|
return true;
|
|
1389
1529
|
} catch {
|
|
1390
1530
|
return false;
|
|
@@ -1484,16 +1624,43 @@ function evaluateComponent(comp, data, options) {
|
|
|
1484
1624
|
return applyStyles(result, comp.styles, options.noColor);
|
|
1485
1625
|
}
|
|
1486
1626
|
function evaluateComponents(components, data, options) {
|
|
1627
|
+
const evaluated = components.map((comp) => ({
|
|
1628
|
+
type: comp.type,
|
|
1629
|
+
value: evaluateComponent(comp, data, options)
|
|
1630
|
+
}));
|
|
1631
|
+
const filtered = [];
|
|
1632
|
+
for (let i = 0; i < evaluated.length; i++) {
|
|
1633
|
+
const entry = evaluated[i];
|
|
1634
|
+
if (entry.type === "sep") {
|
|
1635
|
+
let hasBefore = false;
|
|
1636
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
1637
|
+
if (evaluated[j].type === "sep") continue;
|
|
1638
|
+
if (evaluated[j].value) {
|
|
1639
|
+
hasBefore = true;
|
|
1640
|
+
}
|
|
1641
|
+
break;
|
|
1642
|
+
}
|
|
1643
|
+
let hasAfter = false;
|
|
1644
|
+
for (let j = i + 1; j < evaluated.length; j++) {
|
|
1645
|
+
if (evaluated[j].type === "sep") continue;
|
|
1646
|
+
if (evaluated[j].value) {
|
|
1647
|
+
hasAfter = true;
|
|
1648
|
+
}
|
|
1649
|
+
break;
|
|
1650
|
+
}
|
|
1651
|
+
if (!hasBefore || !hasAfter) continue;
|
|
1652
|
+
}
|
|
1653
|
+
filtered.push(entry);
|
|
1654
|
+
}
|
|
1487
1655
|
const parts = [];
|
|
1488
|
-
for (let i = 0; i <
|
|
1489
|
-
const
|
|
1490
|
-
const prev =
|
|
1491
|
-
|
|
1492
|
-
if (i > 0 && comp.type !== "sep" && comp.type !== "conditional" && prev?.type !== "sep" && value) {
|
|
1656
|
+
for (let i = 0; i < filtered.length; i++) {
|
|
1657
|
+
const entry = filtered[i];
|
|
1658
|
+
const prev = filtered[i - 1];
|
|
1659
|
+
if (i > 0 && entry.type !== "sep" && entry.type !== "conditional" && prev?.type !== "sep" && entry.value) {
|
|
1493
1660
|
parts.push(" ");
|
|
1494
1661
|
}
|
|
1495
|
-
if (value) {
|
|
1496
|
-
parts.push(value);
|
|
1662
|
+
if (entry.value) {
|
|
1663
|
+
parts.push(entry.value);
|
|
1497
1664
|
}
|
|
1498
1665
|
}
|
|
1499
1666
|
return parts.join("");
|
|
@@ -1509,7 +1676,7 @@ function evaluateFormat(format, data, options = {}) {
|
|
|
1509
1676
|
}
|
|
1510
1677
|
|
|
1511
1678
|
// src/index.ts
|
|
1512
|
-
var VERSION = "1.
|
|
1679
|
+
var VERSION = "1.8.0";
|
|
1513
1680
|
async function readStdin() {
|
|
1514
1681
|
return new Promise((resolve, reject) => {
|
|
1515
1682
|
let input = "";
|