ccstatusline 1.0.2 → 1.0.4

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/README.md CHANGED
@@ -45,10 +45,13 @@ Once configured, ccstatusline automatically formats your Claude Code status line
45
45
 
46
46
  - **Model Name** - Shows the current Claude model (e.g., "Claude 3.5 Sonnet")
47
47
  - **Git Branch** - Displays current git branch name
48
- - **Token Usage** - Shows input/output/total tokens used
49
- - **Time** - Current time in HH:MM:SS format
50
- - **Custom Text** - Add your own static text
51
- - **Separator** - Visual divider between items
48
+ - **Tokens Input** - Shows input tokens used
49
+ - **Tokens Output** - Shows output tokens used
50
+ - **Tokens Cached** - Shows cached tokens used
51
+ - **Tokens Total** - Shows total tokens used
52
+ - **Context Length** - Shows current context length in tokens
53
+ - **Context Percentage** - Shows percentage of context limit used
54
+ - **Separator** - Visual divider between items (|)
52
55
  - **Flex Separator** - Expands to fill available space
53
56
 
54
57
  ## Configuration File
@@ -64,29 +67,26 @@ The configuration file at `~/.config/ccstatusline/settings.json` looks like:
64
67
  },
65
68
  {
66
69
  "type": "separator",
67
- "text": " │ ",
68
70
  "color": "gray"
69
71
  },
70
72
  {
71
- "type": "git_branch",
73
+ "type": "git-branch",
72
74
  "color": "green"
73
75
  },
74
76
  {
75
77
  "type": "separator",
76
- "text": " │ ",
77
78
  "color": "gray"
78
79
  },
79
80
  {
80
- "type": "tokens",
81
+ "type": "tokens-total",
81
82
  "color": "yellow"
82
83
  },
83
84
  {
84
- "type": "flex_separator",
85
- "text": "─",
85
+ "type": "flex-separator",
86
86
  "color": "gray"
87
87
  },
88
88
  {
89
- "type": "time",
89
+ "type": "context-percentage",
90
90
  "color": "blue"
91
91
  }
92
92
  ]
@@ -24,7 +24,9 @@ var DEFAULT_SETTINGS = {
24
24
  items: [
25
25
  { id: "1", type: "model", color: "cyan" },
26
26
  { id: "2", type: "separator" },
27
- { id: "3", type: "git-branch", color: "magenta" }
27
+ { id: "3", type: "git-branch", color: "magenta" },
28
+ { id: "4", type: "separator" },
29
+ { id: "5", type: "git-changes", color: "yellow" }
28
30
  ],
29
31
  colors: {
30
32
  model: "cyan",
@@ -142,6 +144,10 @@ var StatusLinePreview = ({ items, terminalWidth }) => {
142
144
  const branchColor = chalk[item.color || "magenta"] || chalk.magenta;
143
145
  elements.push(branchColor("⎇ main"));
144
146
  break;
147
+ case "git-changes":
148
+ const changesColor = chalk[item.color || "yellow"] || chalk.yellow;
149
+ elements.push(changesColor("(+42,-10)"));
150
+ break;
145
151
  case "tokens-input":
146
152
  const inputColor = chalk[item.color || "yellow"] || chalk.yellow;
147
153
  elements.push(inputColor("In: 15.2k"));
@@ -320,6 +326,7 @@ var ItemsEditor = ({ items, onUpdate, onBack }) => {
320
326
  const types = [
321
327
  "model",
322
328
  "git-branch",
329
+ "git-changes",
323
330
  "separator",
324
331
  "flex-separator",
325
332
  "tokens-input",
@@ -345,6 +352,7 @@ var ItemsEditor = ({ items, onUpdate, onBack }) => {
345
352
  const types = [
346
353
  "model",
347
354
  "git-branch",
355
+ "git-changes",
348
356
  "separator",
349
357
  "flex-separator",
350
358
  "tokens-input",
@@ -400,6 +408,8 @@ var ItemsEditor = ({ items, onUpdate, onBack }) => {
400
408
  return chalk.cyan("Model");
401
409
  case "git-branch":
402
410
  return chalk.magenta("Git Branch");
411
+ case "git-changes":
412
+ return chalk.yellow("Git Changes");
403
413
  case "separator":
404
414
  return chalk.dim("Separator |");
405
415
  case "flex-separator":
@@ -507,6 +517,8 @@ var ColorMenu = ({ items, onUpdate, onBack }) => {
507
517
  return "Model";
508
518
  case "git-branch":
509
519
  return "Git Branch";
520
+ case "git-changes":
521
+ return "Git Changes";
510
522
  case "tokens-input":
511
523
  return "Tokens Input";
512
524
  case "tokens-output":
@@ -813,6 +825,38 @@ function getGitBranch() {
813
825
  return null;
814
826
  }
815
827
  }
828
+ function getGitChanges() {
829
+ try {
830
+ let totalInsertions = 0;
831
+ let totalDeletions = 0;
832
+ const unstagedStat = execSync("git diff --shortstat 2>/dev/null", {
833
+ encoding: "utf8",
834
+ stdio: ["pipe", "pipe", "ignore"]
835
+ }).trim();
836
+ const stagedStat = execSync("git diff --cached --shortstat 2>/dev/null", {
837
+ encoding: "utf8",
838
+ stdio: ["pipe", "pipe", "ignore"]
839
+ }).trim();
840
+ if (unstagedStat) {
841
+ const insertMatch = unstagedStat.match(/(\d+) insertion/);
842
+ const deleteMatch = unstagedStat.match(/(\d+) deletion/);
843
+ totalInsertions += insertMatch?.[1] ? parseInt(insertMatch[1], 10) : 0;
844
+ totalDeletions += deleteMatch?.[1] ? parseInt(deleteMatch[1], 10) : 0;
845
+ }
846
+ if (stagedStat) {
847
+ const insertMatch = stagedStat.match(/(\d+) insertion/);
848
+ const deleteMatch = stagedStat.match(/(\d+) deletion/);
849
+ totalInsertions += insertMatch?.[1] ? parseInt(insertMatch[1], 10) : 0;
850
+ totalDeletions += deleteMatch?.[1] ? parseInt(deleteMatch[1], 10) : 0;
851
+ }
852
+ if (totalInsertions === 0 && totalDeletions === 0) {
853
+ return null;
854
+ }
855
+ return { insertions: totalInsertions, deletions: totalDeletions };
856
+ } catch {
857
+ return null;
858
+ }
859
+ }
816
860
  async function getTokenMetrics(transcriptPath) {
817
861
  try {
818
862
  if (!fs3.existsSync(transcriptPath)) {
@@ -824,6 +868,8 @@ async function getTokenMetrics(transcriptPath) {
824
868
  let inputTokens = 0;
825
869
  let outputTokens = 0;
826
870
  let cachedTokens = 0;
871
+ let contextLength = 0;
872
+ let lastMessageWithUsage = null;
827
873
  for (const line of lines) {
828
874
  try {
829
875
  const data = JSON.parse(line);
@@ -832,11 +878,15 @@ async function getTokenMetrics(transcriptPath) {
832
878
  outputTokens += data.message.usage.output_tokens || 0;
833
879
  cachedTokens += data.message.usage.cache_read_input_tokens || 0;
834
880
  cachedTokens += data.message.usage.cache_creation_input_tokens || 0;
881
+ lastMessageWithUsage = data;
835
882
  }
836
883
  } catch {}
837
884
  }
885
+ if (lastMessageWithUsage?.message?.usage) {
886
+ const usage = lastMessageWithUsage.message.usage;
887
+ contextLength = (usage.input_tokens || 0) + (usage.cache_read_input_tokens || 0) + (usage.cache_creation_input_tokens || 0);
888
+ }
838
889
  const totalTokens = inputTokens + outputTokens + cachedTokens;
839
- const contextLength = inputTokens + outputTokens;
840
890
  return { inputTokens, outputTokens, cachedTokens, totalTokens, contextLength };
841
891
  } catch {
842
892
  return { inputTokens: 0, outputTokens: 0, cachedTokens: 0, totalTokens: 0, contextLength: 0 };
@@ -874,6 +924,14 @@ async function renderStatusLine(data) {
874
924
  elements.push({ content: color(`⎇ ${branch}`), type: "git-branch" });
875
925
  }
876
926
  break;
927
+ case "git-changes":
928
+ const changes = getGitChanges();
929
+ if (changes !== null) {
930
+ const color = chalk2[item.color || "yellow"] || chalk2.yellow;
931
+ const changeStr = `(+${changes.insertions},-${changes.deletions})`;
932
+ elements.push({ content: color(changeStr), type: "git-changes" });
933
+ }
934
+ break;
877
935
  case "tokens-input":
878
936
  if (tokenMetrics) {
879
937
  const color = chalk2[item.color || "yellow"] || chalk2.yellow;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",