diff --git a/README.md b/README.md
index 8dd7604..799c5c1 100644
--- a/README.md
+++ b/README.md
@@ -200,7 +200,7 @@ Execute shell commands and display their output dynamically:
### 🔗 Integration Example: ccusage
-[ccusage](https://github.com/samuelint/ccusage) is a tool that tracks and displays Claude Code usage metrics. You can integrate it directly into your status line:
+[ccusage](https://github.com/ryoppippi/ccusage) is a tool that tracks and displays Claude Code usage metrics. You can integrate it directly into your status line:
1. Add a Custom Command widget
2. Set command: `npx -y ccusage statusline`
@@ -325,6 +325,16 @@ Contributions are welcome! Please feel free to submit a Pull Request.
---
+## Star History
+
+
+
+
+
+
+
+
+
### 🌟 Show Your Support
diff --git a/package.json b/package.json
index 9124387..430ae93 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ccstatusline",
- "version": "2.0.0",
+ "version": "2.0.1",
"description": "A customizable status line formatter for Claude Code CLI",
"module": "src/ccstatusline.ts",
"type": "module",
@@ -13,6 +13,7 @@
"statusline": "bun run src/ccstatusline.ts",
"patch": "patch-package",
"build": "bun run patch && rm -rf dist/* && bun build src/ccstatusline.ts --target=node --outfile=dist/ccstatusline.js --target-version=14",
+ "postbuild": "bun run scripts/replace-version.ts",
"prepublishOnly": "bun run build",
"lint": "bun tsc --noEmit; eslint . --config eslint.config.js --max-warnings=999999 --fix"
},
diff --git a/scripts/replace-version.ts b/scripts/replace-version.ts
new file mode 100755
index 0000000..d28a25b
--- /dev/null
+++ b/scripts/replace-version.ts
@@ -0,0 +1,28 @@
+#!/usr/bin/env bun
+
+import {
+ readFileSync,
+ writeFileSync
+} from 'fs';
+import { join } from 'path';
+
+interface PackageJson {
+ version: string;
+ [key: string]: unknown;
+}
+
+// Read package.json to get version
+const packageJson = JSON.parse(readFileSync('package.json', 'utf-8')) as PackageJson;
+const version = packageJson.version;
+
+// Read the bundled file
+const bundledFilePath = join('dist', 'ccstatusline.js');
+let bundledContent = readFileSync(bundledFilePath, 'utf-8');
+
+// Replace the placeholder with the actual version
+bundledContent = bundledContent.replace(/__PACKAGE_VERSION__/g, version);
+
+// Write back the modified content
+writeFileSync(bundledFilePath, bundledContent);
+
+console.log(`✓ Replaced version placeholder with ${version}`);
\ No newline at end of file
diff --git a/src/tui/components/ItemsEditor.tsx b/src/tui/components/ItemsEditor.tsx
index 31fbfcd..aa5ae9d 100644
--- a/src/tui/components/ItemsEditor.tsx
+++ b/src/tui/components/ItemsEditor.tsx
@@ -372,8 +372,8 @@ export const ItemsEditor: React.FC = ({ widgets, onUpdate, onB
{' '}
{lineNumber}
{' '}
- {moveMode && [MOVE MODE]}
+ {moveMode && [MOVE MODE]}
{(settings.powerline.enabled || Boolean(settings.defaultSeparator)) && (
@@ -412,7 +412,7 @@ export const ItemsEditor: React.FC = ({ widgets, onUpdate, onB
return (
-
+
{isSelected ? (moveMode ? '◆ ' : '▶ ') : ' '}
{` ${index + 1}. ${displayText || getWidgetDisplay(widget)}`}
diff --git a/src/tui/components/MainMenu.tsx b/src/tui/components/MainMenu.tsx
index dca985a..5fe8cf0 100644
--- a/src/tui/components/MainMenu.tsx
+++ b/src/tui/components/MainMenu.tsx
@@ -30,7 +30,7 @@ export const MainMenu: React.FC = ({ onSelect, isClaudeInstalled,
{ label: '💻 Terminal Options', value: 'terminalConfig', selectable: true },
{ label: '🌐 Global Overrides', value: 'globalOverrides', selectable: true },
{ label: '', value: '_gap2', selectable: false }, // Visual gap
- { label: isClaudeInstalled ? '🗑️ Uninstall from Claude Code' : '📦 Install to Claude Code', value: 'install', selectable: true }
+ { label: isClaudeInstalled ? '🔌 Uninstall from Claude Code' : '📦 Install to Claude Code', value: 'install', selectable: true }
];
if (hasChanges) {
diff --git a/src/utils/terminal.ts b/src/utils/terminal.ts
index 140dab1..394f5e3 100644
--- a/src/utils/terminal.ts
+++ b/src/utils/terminal.ts
@@ -3,14 +3,33 @@ import * as fs from 'fs';
import * as path from 'path';
// Get package version
+// __PACKAGE_VERSION__ will be replaced at build time
+const PACKAGE_VERSION = '__PACKAGE_VERSION__';
+
export function getPackageVersion(): string {
- try {
- const packageJsonPath = path.join(__dirname, '..', '..', 'package.json');
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')) as { version?: string };
- return packageJson.version ?? '';
- } catch {
- return '';
+ // If we have the build-time replaced version, use it (check if it looks like a version)
+ if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
+ return PACKAGE_VERSION;
}
+
+ // Fallback for development mode
+ const possiblePaths = [
+ path.join(__dirname, '..', '..', 'package.json'), // Development: dist/utils/ -> root
+ path.join(__dirname, '..', 'package.json') // Production: dist/ -> root (bundled)
+ ];
+
+ for (const packageJsonPath of possiblePaths) {
+ try {
+ if (fs.existsSync(packageJsonPath)) {
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')) as { version?: string };
+ return packageJson.version ?? '';
+ }
+ } catch {
+ // Continue to next path
+ }
+ }
+
+ return '';
}
// Get terminal width
diff --git a/src/widgets/CustomCommand.tsx b/src/widgets/CustomCommand.tsx
index a31d018..3dc88e0 100644
--- a/src/widgets/CustomCommand.tsx
+++ b/src/widgets/CustomCommand.tsx
@@ -60,7 +60,8 @@ export class CustomCommandWidget implements Widget {
encoding: 'utf8',
input: jsonInput,
timeout: timeout,
- stdio: ['pipe', 'pipe', 'ignore']
+ stdio: ['pipe', 'pipe', 'ignore'],
+ env: process.env
}).trim();
// Strip ANSI codes if preserveColors is false
@@ -74,7 +75,26 @@ export class CustomCommandWidget implements Widget {
}
return output || null;
- } catch {
+ } catch (error) {
+ // Provide more specific error messages
+ if (error instanceof Error) {
+ const execError = error as Error & {
+ code?: string;
+ signal?: string;
+ status?: number;
+ };
+ if (execError.code === 'ENOENT') {
+ return '[Cmd not found]';
+ } else if (execError.code === 'ETIMEDOUT') {
+ return '[Timeout]';
+ } else if (execError.code === 'EACCES') {
+ return '[Permission denied]';
+ } else if (execError.signal) {
+ return `[Signal: ${execError.signal}]`;
+ } else if (execError.status !== undefined) {
+ return `[Exit: ${execError.status}]`;
+ }
+ }
return '[Error]';
}
}