@alyibrahim/claude-statusline 1.6.0 → 1.6.1

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
@@ -34,7 +34,7 @@ Done. The statusline configures itself automatically. Restart Claude Code to see
34
34
 
35
35
  > If auto-setup didn't run: `claude-statusline setup`
36
36
 
37
- **Plugin install (Claude Code marketplace):** Search for `claude-statusline` in the Claude Code plugin browser. The plugin auto-configures on first session start. To get the native Rust binary after a plugin install, run:
37
+ **Plugin install (Claude Code marketplace):** Search for `claude-statusline` in the Claude Code plugin browser. The plugin auto-configures during installation. To get the native Rust binary after a plugin install, run:
38
38
 
39
39
  ```bash
40
40
  claude-statusline download-binary
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alyibrahim/claude-statusline",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "Rich statusline for Claude Code — model, context bar, real-time token tracking, git branch, rate limits, and session stats. Rust binary, ~5ms startup.",
5
5
  "keywords": [
6
6
  "claude",
@@ -58,11 +58,11 @@
58
58
  "open": "^10.1.0"
59
59
  },
60
60
  "optionalDependencies": {
61
- "@alyibrahim/claude-statusline-linux-x64": "1.5.4",
62
- "@alyibrahim/claude-statusline-linux-arm64": "1.5.4",
63
- "@alyibrahim/claude-statusline-darwin-x64": "1.5.4",
64
- "@alyibrahim/claude-statusline-darwin-arm64": "1.5.4",
65
- "@alyibrahim/claude-statusline-win32-x64": "1.5.4"
61
+ "@alyibrahim/claude-statusline-linux-x64": "1.6.1",
62
+ "@alyibrahim/claude-statusline-linux-arm64": "1.6.1",
63
+ "@alyibrahim/claude-statusline-darwin-x64": "1.6.1",
64
+ "@alyibrahim/claude-statusline-darwin-arm64": "1.6.1",
65
+ "@alyibrahim/claude-statusline-win32-x64": "1.6.1"
66
66
  },
67
67
  "devDependencies": {
68
68
  "jest": "^29.0.0"
@@ -15,7 +15,7 @@ function readCargoVersion(cargoTomlPath) {
15
15
  }
16
16
 
17
17
  function main() {
18
- const root = path.resolve(__dirname, '..');
18
+ const root = process.env.CHECK_VERSIONS_ROOT || path.resolve(__dirname, '..');
19
19
  const packageJsonPath = path.join(root, 'package.json');
20
20
  const packageLockPath = path.join(root, 'package-lock.json');
21
21
  const cargoTomlPath = path.join(root, 'Cargo.toml');
@@ -56,6 +56,11 @@ function main() {
56
56
  }
57
57
 
58
58
  for (const [name, version] of Object.entries(optionalDeps)) {
59
+ // Each platform package must be pinned to the root version — they are published together.
60
+ if (version !== expected) {
61
+ errors.push(`optionalDependencies[${name}] is pinned to ${version}, expected root version ${expected}`);
62
+ }
63
+
59
64
  const lockRootVersion = lock.packages && lock.packages[''] && lock.packages[''].optionalDependencies
60
65
  ? lock.packages[''].optionalDependencies[name]
61
66
  : undefined;
@@ -2,7 +2,6 @@
2
2
  const fs = require('fs');
3
3
  const path = require('path');
4
4
  const os = require('os');
5
- const open = require('open');
6
5
  const { normalizeProjectSlug } = require('./slug-utils');
7
6
 
8
7
  const JSONL_PATH = path.join(
@@ -165,6 +164,7 @@ async function handleHistory() {
165
164
  const tempPath = path.join(os.tmpdir(), 'claude-statusline-dashboard.html');
166
165
  fs.writeFileSync(tempPath, html);
167
166
  try {
167
+ const open = require('open');
168
168
  await open.default(tempPath);
169
169
  console.log(`Dashboard opened: ${tempPath}`);
170
170
  } catch (e) {
@@ -2,34 +2,49 @@
2
2
  const fs = require('fs');
3
3
  const path = require('path');
4
4
  const os = require('os');
5
- const { atomicWrite } = require('./config');
5
+ const { atomicWrite, resolveBinary } = require('./config');
6
6
 
7
- // Only meaningful in plugin context — exit silently otherwise
8
- const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT;
9
- if (!pluginRoot) process.exit(0);
7
+ function pluginAutoSetup(pluginRoot = process.env.CLAUDE_PLUGIN_ROOT) {
8
+ // Only meaningful in plugin context.
9
+ if (!pluginRoot) return { ok: true, configured: false };
10
10
 
11
- const configDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');
12
- const settingsPath = path.join(configDir, 'settings.json');
11
+ const configDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');
12
+ const settingsPath = path.join(configDir, 'settings.json');
13
13
 
14
- let settings = {};
15
- try {
16
- settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
17
- } catch (e) {}
14
+ let settings = {};
15
+ try {
16
+ settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
17
+ } catch (e) {}
18
18
 
19
- // Already configured nothing to do
20
- if (settings.statusLine) process.exit(0);
19
+ // Already configured; leave user config untouched.
20
+ if (settings.statusLine) return { ok: true, configured: false };
21
21
 
22
- const script = path.join(pluginRoot, 'statusline.js');
23
- if (!fs.existsSync(script)) process.exit(0);
22
+ const script = path.join(pluginRoot, 'statusline.js');
23
+ const binaryPath = resolveBinary();
24
+ if (!binaryPath && !fs.existsSync(script)) return { ok: true, configured: false };
24
25
 
25
- settings.statusLine = {
26
- type: 'command',
27
- command: `"${process.execPath}" "${script}"`,
28
- };
26
+ const command = binaryPath
27
+ ? `"${binaryPath}"`
28
+ : `"${process.execPath}" "${script}"`;
29
29
 
30
- try {
31
- fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
32
- atomicWrite(settingsPath, settings);
33
- } catch (e) {
34
- process.exit(0); // Non-fatal — user can run /claude-statusline:setup manually
30
+ settings.statusLine = {
31
+ type: 'command',
32
+ command,
33
+ };
34
+
35
+ try {
36
+ fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
37
+ atomicWrite(settingsPath, settings);
38
+ } catch (e) {
39
+ return { ok: true, configured: false }; // Non-fatal.
40
+ }
41
+
42
+ return { ok: true, configured: true };
43
+ }
44
+
45
+ module.exports = { pluginAutoSetup };
46
+
47
+ if (require.main === module) {
48
+ pluginAutoSetup();
49
+ process.exit(0); // never fail plugin startup
35
50
  }
@@ -3,8 +3,19 @@
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
5
  const { setup } = require('./setup');
6
+ const { pluginAutoSetup } = require('./plugin-autosetup');
6
7
  const config = require('./config');
7
8
  try {
9
+ // Plugin installs run npm scripts in plugin context; configure statusLine once at install time.
10
+ if (process.env.CLAUDE_PLUGIN_ROOT) {
11
+ pluginAutoSetup(process.env.CLAUDE_PLUGIN_ROOT);
12
+ const pluginBinaryPath = config.resolveBinary();
13
+ if (pluginBinaryPath && process.platform !== 'win32') {
14
+ try { fs.chmodSync(pluginBinaryPath, 0o755); } catch (e) {}
15
+ }
16
+ process.exit(0);
17
+ }
18
+
8
19
  const result = setup({ force: false });
9
20
  if (result.settingsPath === null) process.exit(0); // non-global install, skip silently
10
21
 
package/scripts/setup.js CHANGED
@@ -59,6 +59,9 @@ function setup({ force = false } = {}) {
59
59
  } catch (e) {
60
60
  return { ok: false, error: 'settings.json contains invalid JSON — fix manually then re-run.' };
61
61
  }
62
+ if (!settings || typeof settings !== 'object' || Array.isArray(settings)) {
63
+ return { ok: false, error: 'settings.json does not contain a JSON object — fix manually then re-run.' };
64
+ }
62
65
  }
63
66
 
64
67
  const binaryPath = config.resolveBinary();
@@ -180,6 +183,9 @@ function toggleHistory(enable) {
180
183
  } catch (e) {
181
184
  return { ok: false, error: 'settings.json contains invalid JSON — fix manually then re-run.' };
182
185
  }
186
+ if (!settings || typeof settings !== 'object' || Array.isArray(settings)) {
187
+ return { ok: false, error: 'settings.json does not contain a JSON object — fix manually then re-run.' };
188
+ }
183
189
  }
184
190
 
185
191
  try {
@@ -209,6 +215,9 @@ function getDashboardMode() {
209
215
  } catch (e) {
210
216
  return { ok: false, error: 'settings.json contains invalid JSON - fix manually then re-run.' };
211
217
  }
218
+ if (!settings || typeof settings !== 'object' || Array.isArray(settings)) {
219
+ return { ok: false, error: 'settings.json does not contain a JSON object - fix manually then re-run.' };
220
+ }
212
221
 
213
222
  const mode = settings.dashboardMode === 'terminal' ? 'terminal' : 'web';
214
223
  return { ok: true, settingsPath, mode };
@@ -227,6 +236,9 @@ function setDashboardMode(mode) {
227
236
  } catch (e) {
228
237
  return { ok: false, error: 'settings.json contains invalid JSON - fix manually then re-run.' };
229
238
  }
239
+ if (!settings || typeof settings !== 'object' || Array.isArray(settings)) {
240
+ return { ok: false, error: 'settings.json does not contain a JSON object - fix manually then re-run.' };
241
+ }
230
242
  }
231
243
 
232
244
  settings.dashboardMode = mode;
@@ -12,6 +12,9 @@ function uninstall() {
12
12
  } catch (e) {
13
13
  return { ok: false, error: 'settings.json contains invalid JSON — cannot safely modify.' };
14
14
  }
15
+ if (!settings || typeof settings !== 'object' || Array.isArray(settings)) {
16
+ return { ok: false, error: 'settings.json does not contain a JSON object — cannot safely modify.' };
17
+ }
15
18
 
16
19
  if (settings.statusLine) {
17
20
  delete settings.statusLine;