From 3a632bc33d932f35d645da1da0dfa943200e32bc Mon Sep 17 00:00:00 2001 From: Matthew Breedlove Date: Fri, 8 Aug 2025 19:42:04 -0400 Subject: [PATCH] Adding version widget --- package.json | 2 +- src/ccstatusline.ts | 11 ++++++++++- src/config.ts | 2 +- src/tui.tsx | 19 ++++++++++++++----- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 9b7e0a1..9692c06 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ccstatusline", - "version": "1.0.8", + "version": "1.0.9", "description": "A customizable status line formatter for Claude Code CLI", "module": "src/ccstatusline.ts", "type": "module", diff --git a/src/ccstatusline.ts b/src/ccstatusline.ts index 83ed40b..904af0f 100644 --- a/src/ccstatusline.ts +++ b/src/ccstatusline.ts @@ -24,6 +24,7 @@ interface StatusJSON { current_dir: string; project_dir: string; }; + version?: string; } interface TokenUsage { @@ -399,13 +400,21 @@ function renderSingleLine(items: StatusItem[], settings: any, data: StatusJSON, } break; + case 'version': + const versionString = data.version || 'Unknown'; + const versionColor = (chalk as any)[item.color || 'green'] || chalk.green; + elements.push({ content: versionColor(`Version: ${versionString}`), type: 'version' }); + break; + case 'separator': // Only add separator if there are already elements and the last one isn't a separator const lastElement = elements[elements.length - 1]; if (elements.length > 0 && lastElement && lastElement.type !== 'separator') { const sepColor = (chalk as any)[settings.colors.separator] || chalk.dim; const sepChar = item.character || '|'; - elements.push({ content: sepColor(` ${sepChar} `), type: 'separator' }); + // Don't add space before comma + const sepContent = sepChar === ',' ? sepColor(`${sepChar} `) : sepColor(` ${sepChar} `); + elements.push({ content: sepContent, type: 'separator' }); } break; diff --git a/src/config.ts b/src/config.ts index 1bc8a1a..f479a3e 100644 --- a/src/config.ts +++ b/src/config.ts @@ -9,7 +9,7 @@ const writeFile = fs.promises?.writeFile || promisify(fs.writeFile); const mkdir = fs.promises?.mkdir || promisify(fs.mkdir); export type StatusItemType = 'model' | 'git-branch' | 'git-changes' | 'separator' | 'flex-separator' | - 'tokens-input' | 'tokens-output' | 'tokens-cached' | 'tokens-total' | 'context-length' | 'context-percentage' | 'terminal-width' | 'session-clock'; + 'tokens-input' | 'tokens-output' | 'tokens-cached' | 'tokens-total' | 'context-length' | 'context-percentage' | 'terminal-width' | 'session-clock' | 'version'; export interface StatusItem { id: string; diff --git a/src/tui.tsx b/src/tui.tsx index 56f0785..b7d1d29 100644 --- a/src/tui.tsx +++ b/src/tui.tsx @@ -103,6 +103,10 @@ const renderSingleLine = (items: StatusItem[], terminalWidth: number, widthDetec const sessionColor = (chalk as any)[item.color || 'blue'] || chalk.blue; elements.push(sessionColor('Session: 2hr 15m')); break; + case 'version': + const versionColor = (chalk as any)[item.color || 'green'] || chalk.green; + elements.push(versionColor('Version: 1.0.72')); + break; case 'terminal-width': const termColor = (chalk as any)[item.color || 'dim'] || chalk.dim; const detectedWidth = canDetectTerminalWidth() ? terminalWidth : '??'; @@ -110,7 +114,9 @@ const renderSingleLine = (items: StatusItem[], terminalWidth: number, widthDetec break; case 'separator': const sepChar = item.character || '|'; - elements.push(chalk.dim(` ${sepChar} `)); + // Don't add space before comma + const sepContent = sepChar === ',' ? chalk.dim(`${sepChar} `) : chalk.dim(` ${sepChar} `); + elements.push(sepContent); break; case 'flex-separator': elements.push('FLEX'); @@ -308,7 +314,7 @@ interface ItemsEditorProps { const ItemsEditor: React.FC = ({ items, onUpdate, onBack, lineNumber }) => { const [selectedIndex, setSelectedIndex] = useState(0); const [moveMode, setMoveMode] = useState(false); - const separatorChars = ['|', '-', ' ']; + const separatorChars = ['|', '-', ',', ' ']; useInput((input, key) => { if (moveMode) { @@ -345,7 +351,7 @@ const ItemsEditor: React.FC = ({ items, onUpdate, onBack, line // Toggle item type backwards const types: StatusItemType[] = ['model', 'git-branch', 'git-changes', 'separator', 'tokens-input', 'tokens-output', 'tokens-cached', 'tokens-total', 'context-length', 'context-percentage', - 'session-clock', 'terminal-width', 'flex-separator']; + 'session-clock', 'terminal-width', 'version', 'flex-separator']; const currentItem = items[selectedIndex]; if (currentItem) { const currentType = currentItem.type; @@ -362,7 +368,7 @@ const ItemsEditor: React.FC = ({ items, onUpdate, onBack, line // Toggle item type forwards const types: StatusItemType[] = ['model', 'git-branch', 'git-changes', 'separator', 'tokens-input', 'tokens-output', 'tokens-cached', 'tokens-total', 'context-length', 'context-percentage', - 'session-clock', 'terminal-width', 'flex-separator']; + 'session-clock', 'terminal-width', 'version', 'flex-separator']; const currentItem = items[selectedIndex]; if (currentItem) { const currentType = currentItem.type; @@ -456,6 +462,8 @@ const ItemsEditor: React.FC = ({ items, onUpdate, onBack, line return chalk.blue('Session Clock'); case 'terminal-width': return chalk.dim('Terminal Width'); + case 'version': + return chalk.green('Version'); } }; @@ -505,7 +513,7 @@ interface ColorMenuProps { const ColorMenu: React.FC = ({ items, onUpdate, onBack }) => { const colorableItems = items.filter(item => - ['model', 'git-branch', 'tokens-input', 'tokens-output', 'tokens-cached', 'tokens-total', 'context-length', 'context-percentage', 'session-clock'].includes(item.type) + ['model', 'git-branch', 'tokens-input', 'tokens-output', 'tokens-cached', 'tokens-total', 'context-length', 'context-percentage', 'session-clock', 'version'].includes(item.type) ); const [selectedIndex, setSelectedIndex] = useState(0); @@ -544,6 +552,7 @@ const ColorMenu: React.FC = ({ items, onUpdate, onBack }) => { case 'context-length': return 'Context Length'; case 'context-percentage': return 'Context Percentage'; case 'session-clock': return 'Session Clock'; + case 'version': return 'Version'; default: return item.type; } };