lumira 1.9.1 → 1.10.0

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.
@@ -5,14 +5,14 @@
5
5
  },
6
6
  "metadata": {
7
7
  "description": "Real-time statusline HUD for Claude Code and Qwen Code — analytics, quota projection, themes, powerline",
8
- "version": "1.9.0"
8
+ "version": "1.10.0"
9
9
  },
10
10
  "plugins": [
11
11
  {
12
12
  "name": "lumira",
13
13
  "source": "./",
14
14
  "description": "Real-time statusline HUD for Claude Code and Qwen Code. Session analytics, API latency widget, 7-day quota projection, auto-compact warnings, 7 themes, powerline support. Zero runtime dependencies. Run /lumira:setup after install to activate.",
15
- "version": "1.9.0",
15
+ "version": "1.10.0",
16
16
  "author": {
17
17
  "name": "Carlos Cativo"
18
18
  },
@@ -32,5 +32,5 @@
32
32
  ]
33
33
  }
34
34
  ],
35
- "version": "1.9.0"
35
+ "version": "1.10.0"
36
36
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lumira",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "Real-time statusline HUD for Claude Code and Qwen Code — session analytics, API latency, 7-day quota projection, auto-compact warnings, 7 themes, powerline. Zero runtime deps.",
5
5
  "author": {
6
6
  "name": "Carlos Cativo"
package/README.md CHANGED
@@ -40,6 +40,7 @@ Interactive wizard — preset, theme, icons — previewed live before write.
40
40
  ## Table of contents
41
41
 
42
42
  - [Why lumira?](#why-lumira)
43
+ - [How lumira compares](#how-lumira-compares)
43
44
  - [Requirements](#requirements)
44
45
  - [Features](#features)
45
46
  - [Install](#install)
@@ -63,7 +64,25 @@ Claude Code's default statusline shows the model name and current directory. Tha
63
64
  - **Active tools, agents, and todo progress** — parsed from the live transcript, updated every render.
64
65
  - **Cross-platform** — same config drives Claude Code and Qwen Code; Qwen sessions auto-collapse to single-line.
65
66
 
66
- Inspired by [claude-hud](https://github.com/jarrodwatts/claude-hud); takes a different stance on opt-in powerline rendering, theme contrast guarantees, and Qwen Code compatibility.
67
+ Inspired by [GSD's](https://github.com/open-gsd/gsd-core) statusline; takes its own stance on opt-in powerline rendering, theme contrast guarantees, and Qwen Code compatibility.
68
+
69
+ ## How lumira compares
70
+
71
+ The Claude Code statusline space has several good tools. Here's an honest head-to-head on **features** against the other true statuslines (feature claims checked against each tool's current README, 2026-06-14):
72
+
73
+ | Tool | Runtime / deps | Distribution | Platforms | Config UX | Powerline + themes | Session-intel widgets |
74
+ |---|---|---|---|---|---|---|
75
+ | **lumira** | TS / **0 runtime deps** | npm + npx + plugin (+ Qwen skill) | **Claude Code + Qwen Code** | Wizard + JSON + CLI flags | Yes (7 styles) + 7 themes, **WCAG-AA guard** | **Quota projection, pace delta, API-latency, auto-compact glyph + counter, cache, agents, MCP, todos, tools** + `stats` CLI |
76
+ | ccstatusline | TS / bundled | npm + npx | Claude Code | **Ink TUI** (live preview) | Yes + themes | Context, cost, usage %, block timer, compaction count, git; no quota/pace/latency |
77
+ | claude-hud | JS / Node 18+ | Plugin marketplace | Claude Code (v1.0.80+) | Guided `/configure` + JSON | No / no themes | Context, 5h/7d usage, cost, git, tools, agents, todos, cache TTL; no quota ETA/pace/latency |
78
+ | CCometixLine | Rust binary | npm + binary + source | Claude Code | TUI (TOML) | Yes + themes | Model, dir, git, context %, usage, cost, time, output-style |
79
+ | claude-pace | Bash + jq | curl + plugin + npx | Claude Code 2.1.80+ | JSON block | No / no | 5h+7d %, pace delta, reset countdown, git diff; ~10ms (lightest) |
80
+ | cship | Rust binary | binary / script / cargo | Claude Code | TOML (Starship-style) | Yes (Starship) + themes | Cost, context bar, usage limits, model, effort, agent, session, peak-time |
81
+ | starship-claude | Shell / needs Starship | Plugin + manual | Claude Code (no tmux) | Wizard + TOML | Via Starship + palettes | Context bar, model, session |
82
+
83
+ **Where lumira leads:** breadth of session-intelligence widgets — sole owner of an API-latency widget, a 7-day quota *projection ETA*, an MCP-server count, and a bundled `stats` analytics CLI, on top of the full pace / agents / todos / cache set. Plus zero runtime deps, dual-platform (Claude Code **and** Qwen Code), and WCAG-AA contrast enforced in CI on every theme. **Where it doesn't:** no Ink-style interactive widget builder — config is a wizard + JSON, not a live drag-and-drop TUI.
84
+
85
+ See [`docs/competitive-comparison.md`](docs/competitive-comparison.md) for the full per-widget matrix, config-UX detail, and distribution breakdown across every tool.
67
86
 
68
87
  ## Requirements
69
88
 
@@ -83,6 +83,22 @@ export function parseStateMd(content) {
83
83
  state.phaseTotal = phaseMatch[2];
84
84
  state.phaseName = phaseMatch[3];
85
85
  }
86
+ // Plan progress within the current phase (gsd-core ≥ 1.4.x). Accepts both the
87
+ // compound "X of Y in current phase" and the bare "X of Y" forms. A "Plan: —"
88
+ // (not started) line has no digits and is correctly skipped.
89
+ const planMatch = content.match(/^Plan:\s*(\d+)\s+of\s+(\d+)/m);
90
+ if (planMatch) {
91
+ state.planNum = planMatch[1];
92
+ state.planTotal = planMatch[2];
93
+ }
94
+ // Resume point (gsd-core ≥ 1.4.x). "Resume file: None" means no active resume
95
+ // point and is treated as absent.
96
+ const resumeMatch = content.match(/^Resume file:\s*(.+)/m);
97
+ if (resumeMatch) {
98
+ const path = resumeMatch[1].trim();
99
+ if (path && path.toLowerCase() !== 'none')
100
+ state.resumeFile = path;
101
+ }
86
102
  if (!state.status) {
87
103
  // Fallback: parse body Status line when frontmatter status is missing
88
104
  const bodyStatus = content.match(/^Status:\s*(.+)/m);
@@ -145,9 +161,13 @@ function formatState(s) {
145
161
  }
146
162
  // Scene selection: activePhase → nextAction → milestone-complete → default
147
163
  const phasesStr = s.nextPhases?.length ? s.nextPhases.join('/') : null;
164
+ // Plan progress within the phase (gsd-core ≥ 1.4.x), appended to the phase
165
+ // descriptor in the active/default scenes — e.g. "auth (3/5) p2/9".
166
+ const planSuffix = s.planNum && s.planTotal ? ` p${s.planNum}/${s.planTotal}` : '';
148
167
  if (s.activePhase) {
149
168
  // Scene 1: activePhase (with optional status)
150
- parts.push(s.status ? `Phase ${s.activePhase} ${s.status}` : `Phase ${s.activePhase}`);
169
+ const phase = s.status ? `Phase ${s.activePhase} ${s.status}` : `Phase ${s.activePhase}`;
170
+ parts.push(`${phase}${planSuffix}`);
151
171
  }
152
172
  else if (s.nextAction && phasesStr) {
153
173
  // Scene 2: nextAction + phases when idle
@@ -163,7 +183,7 @@ function formatState(s) {
163
183
  parts.push(s.status);
164
184
  if (s.phaseNum && s.phaseTotal) {
165
185
  const phase = s.phaseName ? `${s.phaseName} (${s.phaseNum}/${s.phaseTotal})` : `ph ${s.phaseNum}/${s.phaseTotal}`;
166
- parts.push(phase);
186
+ parts.push(`${phase}${planSuffix}`);
167
187
  }
168
188
  }
169
189
  return parts.join(' · ');
@@ -234,11 +254,13 @@ export function getGsdInfo(cwd, opts = {}) {
234
254
  const legacyCacheFile = join(claudeDir, 'cache', 'gsd-update-check.json');
235
255
  const cacheData = readUpdateCache(openGsdCacheFile, sharedCacheFile, legacyCacheFile);
236
256
  let currentTask;
257
+ let hasResume = false;
237
258
  const stateFile = findStateMd(cwd || process.cwd());
238
259
  if (stateFile) {
239
260
  log('STATE.md found:', stateFile);
240
261
  try {
241
262
  const state = parseStateMd(readFileSync(stateFile, 'utf8'));
263
+ hasResume = state.resumeFile !== undefined;
242
264
  const formatted = formatState(state);
243
265
  if (formatted) {
244
266
  currentTask = sanitizeTermString(formatted);
@@ -261,6 +283,7 @@ export function getGsdInfo(cwd, opts = {}) {
261
283
  staleHooks: cacheData.staleHooks || undefined,
262
284
  devInstall: cacheData.devInstall || undefined,
263
285
  currentTask,
286
+ hasResume: hasResume || undefined,
264
287
  };
265
288
  }
266
289
  //# sourceMappingURL=gsd.js.map
@@ -13,6 +13,12 @@ export function renderLine4(ctx, c) {
13
13
  if (gsd.currentTask) {
14
14
  parts.push(c.bold(`${icons.hammer} ${truncField(gsd.currentTask, 60)}`));
15
15
  }
16
+ // Resume-point indicator (gsd-core ≥ 1.4.x). A ↩ glyph signals STATE.md has
17
+ // an active `.continue-here`/spec resume file — a cue that work can be picked
18
+ // up where it left off. Cyan: informational, distinct from update/stale warns.
19
+ if (gsd.hasResume) {
20
+ parts.push(c.cyan('↩'));
21
+ }
16
22
  if (gsd.updateAvailable) {
17
23
  parts.push(c.yellow('⬆ /gsd:update'));
18
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lumira",
3
- "version": "1.9.1",
3
+ "version": "1.10.0",
4
4
  "description": "Real-time statusline HUD for Claude Code and Qwen Code. Includes session analytics CLI, API latency overhead widget, 7d quota projection, auto-compact proximity warnings, themes, and powerline. Zero deps.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",