ccstatusline 2.0.3 → 2.0.5
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/ccstatusline.js +86 -47
- package/package.json +5 -7
package/dist/ccstatusline.js
CHANGED
|
@@ -51035,7 +51035,7 @@ import { execSync as execSync3 } from "child_process";
|
|
|
51035
51035
|
import * as fs5 from "fs";
|
|
51036
51036
|
import * as path4 from "path";
|
|
51037
51037
|
var __dirname = "/Users/sirmalloc/Projects/Personal/ccstatusline/src/utils";
|
|
51038
|
-
var PACKAGE_VERSION = "2.0.
|
|
51038
|
+
var PACKAGE_VERSION = "2.0.5";
|
|
51039
51039
|
function getPackageVersion() {
|
|
51040
51040
|
if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
|
|
51041
51041
|
return PACKAGE_VERSION;
|
|
@@ -51949,7 +51949,7 @@ class GitBranchWidget {
|
|
|
51949
51949
|
}
|
|
51950
51950
|
getGitBranch() {
|
|
51951
51951
|
try {
|
|
51952
|
-
const branch = execSync4("git branch --show-current
|
|
51952
|
+
const branch = execSync4("git branch --show-current", {
|
|
51953
51953
|
encoding: "utf8",
|
|
51954
51954
|
stdio: ["pipe", "pipe", "ignore"]
|
|
51955
51955
|
}).trim();
|
|
@@ -51995,11 +51995,11 @@ class GitChangesWidget {
|
|
|
51995
51995
|
try {
|
|
51996
51996
|
let totalInsertions = 0;
|
|
51997
51997
|
let totalDeletions = 0;
|
|
51998
|
-
const unstagedStat = execSync5("git diff --shortstat
|
|
51998
|
+
const unstagedStat = execSync5("git diff --shortstat", {
|
|
51999
51999
|
encoding: "utf8",
|
|
52000
52000
|
stdio: ["pipe", "pipe", "ignore"]
|
|
52001
52001
|
}).trim();
|
|
52002
|
-
const stagedStat = execSync5("git diff --cached --shortstat
|
|
52002
|
+
const stagedStat = execSync5("git diff --cached --shortstat", {
|
|
52003
52003
|
encoding: "utf8",
|
|
52004
52004
|
stdio: ["pipe", "pipe", "ignore"]
|
|
52005
52005
|
}).trim();
|
|
@@ -53243,20 +53243,27 @@ class BlockTimerWidget {
|
|
|
53243
53243
|
render(item, context, settings) {
|
|
53244
53244
|
const displayMode = item.metadata?.display ?? "time";
|
|
53245
53245
|
if (context.isPreview) {
|
|
53246
|
+
const prefix = item.rawValue ? "" : "Block ";
|
|
53246
53247
|
if (displayMode === "progress") {
|
|
53247
|
-
return
|
|
53248
|
+
return `${prefix}[██████████████████████░░░░░░░░] 73.9%`;
|
|
53248
53249
|
} else if (displayMode === "progress-short") {
|
|
53249
|
-
return
|
|
53250
|
+
return `${prefix}[███████░░░░░░░░] 73.9%`;
|
|
53250
53251
|
}
|
|
53251
53252
|
return item.rawValue ? "3hr 45m" : "Block: 3hr 45m";
|
|
53252
53253
|
}
|
|
53253
|
-
const
|
|
53254
|
-
if (!
|
|
53255
|
-
|
|
53254
|
+
const blockMetrics = context.blockMetrics;
|
|
53255
|
+
if (!blockMetrics) {
|
|
53256
|
+
if (displayMode === "progress" || displayMode === "progress-short") {
|
|
53257
|
+
const barWidth = displayMode === "progress" ? 32 : 16;
|
|
53258
|
+
const emptyBar = "░".repeat(barWidth);
|
|
53259
|
+
return item.rawValue ? `[${emptyBar}] 0%` : `Block [${emptyBar}] 0%`;
|
|
53260
|
+
} else {
|
|
53261
|
+
return item.rawValue ? "0hr 0m" : "Block: 0hr 0m";
|
|
53262
|
+
}
|
|
53256
53263
|
}
|
|
53257
53264
|
try {
|
|
53258
53265
|
const now = new Date;
|
|
53259
|
-
const elapsedMs = now.getTime() -
|
|
53266
|
+
const elapsedMs = now.getTime() - blockMetrics.startTime.getTime();
|
|
53260
53267
|
const sessionDurationMs = 5 * 60 * 60 * 1000;
|
|
53261
53268
|
const progress = Math.min(elapsedMs / sessionDurationMs, 1);
|
|
53262
53269
|
const percentage = (progress * 100).toFixed(1);
|
|
@@ -56945,13 +56952,15 @@ Continue?`;
|
|
|
56945
56952
|
},
|
|
56946
56953
|
onInstallFonts: () => {
|
|
56947
56954
|
setInstallingFonts(true);
|
|
56948
|
-
|
|
56949
|
-
|
|
56950
|
-
|
|
56951
|
-
|
|
56952
|
-
|
|
56955
|
+
setTimeout(() => {
|
|
56956
|
+
installPowerlineFonts().then((result) => {
|
|
56957
|
+
setInstallingFonts(false);
|
|
56958
|
+
setFontInstallMessage(result.message);
|
|
56959
|
+
checkPowerlineFontsAsync().then((asyncStatus) => {
|
|
56960
|
+
setPowerlineFontStatus(asyncStatus);
|
|
56961
|
+
});
|
|
56953
56962
|
});
|
|
56954
|
-
});
|
|
56963
|
+
}, 50);
|
|
56955
56964
|
},
|
|
56956
56965
|
installingFonts,
|
|
56957
56966
|
fontInstallMessage,
|
|
@@ -57887,9 +57896,8 @@ function getBlockMetrics(transcriptPath) {
|
|
|
57887
57896
|
}
|
|
57888
57897
|
currentPath = path6.dirname(currentPath);
|
|
57889
57898
|
}
|
|
57890
|
-
if (!claudePath)
|
|
57899
|
+
if (!claudePath)
|
|
57891
57900
|
return null;
|
|
57892
|
-
}
|
|
57893
57901
|
try {
|
|
57894
57902
|
return findMostRecentBlockStartTime(claudePath);
|
|
57895
57903
|
} catch {
|
|
@@ -57901,47 +57909,73 @@ function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
|
|
|
57901
57909
|
const now = new Date;
|
|
57902
57910
|
const pattern = path6.join(rootDir, "projects", "**", "*.jsonl").replace(/\\/g, "/");
|
|
57903
57911
|
const files = globSync([pattern]);
|
|
57904
|
-
if (files.length === 0)
|
|
57912
|
+
if (files.length === 0)
|
|
57905
57913
|
return null;
|
|
57906
|
-
}
|
|
57907
57914
|
const filesWithStats = files.map((file2) => {
|
|
57908
57915
|
const stats = statSync3(file2);
|
|
57909
57916
|
return { file: file2, mtime: stats.mtime };
|
|
57910
57917
|
});
|
|
57911
57918
|
filesWithStats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
57912
|
-
const
|
|
57913
|
-
|
|
57914
|
-
|
|
57915
|
-
|
|
57916
|
-
|
|
57919
|
+
const lookbackChunks = [
|
|
57920
|
+
10,
|
|
57921
|
+
20,
|
|
57922
|
+
48
|
|
57923
|
+
];
|
|
57924
|
+
let timestamps = [];
|
|
57925
|
+
let mostRecentTimestamp = null;
|
|
57926
|
+
let continuousWorkStart = null;
|
|
57927
|
+
let foundSessionGap = false;
|
|
57928
|
+
for (const lookbackHours of lookbackChunks) {
|
|
57929
|
+
const cutoffTime = new Date(now.getTime() - lookbackHours * 60 * 60 * 1000);
|
|
57930
|
+
timestamps = [];
|
|
57931
|
+
for (const { file: file2, mtime } of filesWithStats) {
|
|
57932
|
+
if (mtime.getTime() < cutoffTime.getTime()) {
|
|
57933
|
+
break;
|
|
57934
|
+
}
|
|
57935
|
+
const fileTimestamps = getAllTimestampsFromFile(file2);
|
|
57936
|
+
timestamps.push(...fileTimestamps);
|
|
57917
57937
|
}
|
|
57918
|
-
|
|
57919
|
-
timestamps.push(...fileTimestamps);
|
|
57920
|
-
}
|
|
57921
|
-
if (timestamps.length === 0) {
|
|
57922
|
-
return null;
|
|
57923
|
-
}
|
|
57924
|
-
timestamps.sort((a, b) => b.getTime() - a.getTime());
|
|
57925
|
-
const mostRecentTimestamp = timestamps[0];
|
|
57926
|
-
if (!mostRecentTimestamp) {
|
|
57927
|
-
return null;
|
|
57928
|
-
}
|
|
57929
|
-
let actualStartTimestamp = mostRecentTimestamp;
|
|
57930
|
-
for (let i = 1;i < timestamps.length; i++) {
|
|
57931
|
-
const currentTimestamp = timestamps[i];
|
|
57932
|
-
const previousTimestamp = timestamps[i - 1];
|
|
57933
|
-
if (!currentTimestamp || !previousTimestamp) {
|
|
57938
|
+
if (timestamps.length === 0) {
|
|
57934
57939
|
continue;
|
|
57935
57940
|
}
|
|
57936
|
-
|
|
57937
|
-
if (
|
|
57941
|
+
timestamps.sort((a, b) => b.getTime() - a.getTime());
|
|
57942
|
+
if (!mostRecentTimestamp && timestamps[0]) {
|
|
57943
|
+
mostRecentTimestamp = timestamps[0];
|
|
57944
|
+
const timeSinceLastActivity = now.getTime() - mostRecentTimestamp.getTime();
|
|
57945
|
+
if (timeSinceLastActivity > sessionDurationMs) {
|
|
57946
|
+
return null;
|
|
57947
|
+
}
|
|
57948
|
+
}
|
|
57949
|
+
continuousWorkStart = mostRecentTimestamp;
|
|
57950
|
+
for (let i = 1;i < timestamps.length; i++) {
|
|
57951
|
+
const currentTimestamp = timestamps[i];
|
|
57952
|
+
const previousTimestamp = timestamps[i - 1];
|
|
57953
|
+
if (!currentTimestamp || !previousTimestamp)
|
|
57954
|
+
continue;
|
|
57955
|
+
const gap = previousTimestamp.getTime() - currentTimestamp.getTime();
|
|
57956
|
+
if (gap >= sessionDurationMs) {
|
|
57957
|
+
foundSessionGap = true;
|
|
57958
|
+
break;
|
|
57959
|
+
}
|
|
57960
|
+
continuousWorkStart = currentTimestamp;
|
|
57961
|
+
}
|
|
57962
|
+
if (foundSessionGap) {
|
|
57963
|
+
break;
|
|
57964
|
+
}
|
|
57965
|
+
if (lookbackHours === lookbackChunks[lookbackChunks.length - 1]) {
|
|
57938
57966
|
break;
|
|
57939
57967
|
}
|
|
57940
|
-
actualStartTimestamp = currentTimestamp;
|
|
57941
57968
|
}
|
|
57942
|
-
|
|
57943
|
-
|
|
57944
|
-
|
|
57969
|
+
if (!mostRecentTimestamp || !continuousWorkStart) {
|
|
57970
|
+
return null;
|
|
57971
|
+
}
|
|
57972
|
+
const flooredWorkStart = floorToHour(continuousWorkStart);
|
|
57973
|
+
const totalWorkTime = now.getTime() - flooredWorkStart.getTime();
|
|
57974
|
+
let blockStart = flooredWorkStart;
|
|
57975
|
+
if (totalWorkTime > sessionDurationMs) {
|
|
57976
|
+
const completedBlocks = Math.floor(totalWorkTime / sessionDurationMs);
|
|
57977
|
+
blockStart = new Date(flooredWorkStart.getTime() + completedBlocks * sessionDurationMs);
|
|
57978
|
+
}
|
|
57945
57979
|
const timeSinceActivity = now.getTime() - mostRecentTimestamp.getTime();
|
|
57946
57980
|
const blockEnd = new Date(blockStart.getTime() + sessionDurationMs);
|
|
57947
57981
|
const isActive = timeSinceActivity < sessionDurationMs && now < blockEnd;
|
|
@@ -57975,6 +58009,11 @@ function getAllTimestampsFromFile(filePath) {
|
|
|
57975
58009
|
return [];
|
|
57976
58010
|
}
|
|
57977
58011
|
}
|
|
58012
|
+
function floorToHour(timestamp) {
|
|
58013
|
+
const floored = new Date(timestamp);
|
|
58014
|
+
floored.setUTCMinutes(0, 0, 0);
|
|
58015
|
+
return floored;
|
|
58016
|
+
}
|
|
57978
58017
|
|
|
57979
58018
|
// src/ccstatusline.ts
|
|
57980
58019
|
async function readStdin() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccstatusline",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "A customizable status line formatter for Claude Code CLI",
|
|
5
5
|
"module": "src/ccstatusline.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -37,9 +37,11 @@
|
|
|
37
37
|
"patch-package": "^8.0.0",
|
|
38
38
|
"react": "^19.1.1",
|
|
39
39
|
"react-devtools-core": "^6.1.5",
|
|
40
|
+
"strip-ansi": "^7.1.0",
|
|
40
41
|
"tinyglobby": "^0.2.14",
|
|
41
42
|
"typescript": "^5.9.2",
|
|
42
|
-
"typescript-eslint": "^8.39.1"
|
|
43
|
+
"typescript-eslint": "^8.39.1",
|
|
44
|
+
"zod": "^4.0.17"
|
|
43
45
|
},
|
|
44
46
|
"keywords": [
|
|
45
47
|
"claude",
|
|
@@ -59,9 +61,5 @@
|
|
|
59
61
|
},
|
|
60
62
|
"trustedDependencies": [
|
|
61
63
|
"unrs-resolver"
|
|
62
|
-
]
|
|
63
|
-
"dependencies": {
|
|
64
|
-
"strip-ansi": "^7.1.0",
|
|
65
|
-
"zod": "^4.0.17"
|
|
66
|
-
}
|
|
64
|
+
]
|
|
67
65
|
}
|