lumira 1.1.2 → 1.2.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.
@@ -0,0 +1,82 @@
1
+ import type { AgentEntry } from '../types.js';
2
+ export declare const GENERIC_AGENT_TYPES: ReadonlySet<string>;
3
+ /**
4
+ * Returns true when `type` identifies a *named* subagent — i.e. one defined
5
+ * by the user (e.g. `pepito`, `feature-dev:code-reviewer`) rather than an
6
+ * anonymous dispatch via the generic Agent tool. Render layers use this to
7
+ * decide whether to surface the type in the cubes-icon widget.
8
+ */
9
+ export declare function isNamedAgentType(type: string | undefined | null): boolean;
10
+ /**
11
+ * Per-file metadata captured by `scanSubagentsDir`. Phase 1 of the parse:
12
+ * a stat-only summary the cache uses for fingerprinting and that the full
13
+ * parse re-uses to avoid re-running readdir/stat on miss.
14
+ */
15
+ export interface AgentCandidate {
16
+ id: string;
17
+ jsonlFile: string;
18
+ metaFile: string;
19
+ mtimeMs: number;
20
+ size: number;
21
+ }
22
+ export declare function deriveSubagentsDir(jsonlPath: string): string;
23
+ /**
24
+ * Cheap filesystem fingerprint of a session's subagents dir, suitable for
25
+ * folding into a transcript-level cache key. Captures (a) the number of
26
+ * matching agent files, (b) the most recent file mtime in the dir, and
27
+ * (c) the aggregate file size. A change to any agent file flips at least
28
+ * one of these — `maxMtimeMs` is monotonic across writes (every new write
29
+ * either bumps mtime or leaves it unchanged on the same-second case where
30
+ * the size delta still fires), and `totalSize` catches in-place edits that
31
+ * happen at exactly the same mtime tick.
32
+ *
33
+ * Intentionally O(N) on dir size: the dir is small (≤ MAX_AGENTS handful)
34
+ * and `stat` is fast. Returns null when the dir doesn't exist or isn't
35
+ * accessible — the caller should treat that as "no fingerprint, no cached
36
+ * subagent state".
37
+ */
38
+ export interface SubagentsDirState {
39
+ count: number;
40
+ maxMtimeMs: number;
41
+ totalSize: number;
42
+ }
43
+ /**
44
+ * Unified scan: walks the subagents/ dir once, gathering both the cache
45
+ * fingerprint AND the per-file stat metadata needed for the full parse.
46
+ * Callers that only need the fingerprint can ignore `candidates`; callers
47
+ * doing a full parse can hand the candidates to `readSubagentDetails`
48
+ * without re-running readdir/stat.
49
+ */
50
+ export declare function scanSubagentsDir(rawJsonlPath: string): Promise<{
51
+ state: SubagentsDirState | null;
52
+ candidates: AgentCandidate[];
53
+ }>;
54
+ export declare function getSubagentsDirState(jsonlPath: string): Promise<SubagentsDirState | null>;
55
+ export declare function subagentsDirStateEqual(a: SubagentsDirState | null, b: SubagentsDirState | null): boolean;
56
+ /**
57
+ * Phase 2 of the parse — reads JSONL bodies + meta sidecars only for the
58
+ * MAX_AGENTS most recent files in `candidates`. Sorts oldest → newest by
59
+ * file mtime; the survivors of `slice(-MAX_AGENTS)` are read.
60
+ *
61
+ * `mtime` is the on-disk last-write timestamp, not the agent's logical
62
+ * "last activity". The two usually coincide, but on a slow filesystem an
63
+ * agent dispatched recently may have a stale mtime (its first write
64
+ * hasn't been journaled yet) while an older agent's file gets touched by
65
+ * an unrelated journal flush. The downstream `startTime` is read from
66
+ * the JSONL line's embedded `timestamp` field — so the sort order may
67
+ * not match `startTime` order exactly. Acceptable for the statusline's
68
+ * "newest N" picker; flagged here so a future caller doesn't assume the
69
+ * two orderings are identical.
70
+ *
71
+ * Exported so callers that already ran `scanSubagentsDir` (e.g. the
72
+ * transcript parser, which uses the same scan to build its cache key) can
73
+ * skip a second readdir+stat pass.
74
+ */
75
+ export declare function readSubagentDetails(candidates: AgentCandidate[]): Promise<AgentEntry[]>;
76
+ /**
77
+ * Convenience wrapper: full scan + full parse. Equivalent to
78
+ * `(await scanSubagentsDir(p)).candidates → readSubagentDetails`.
79
+ * Callers that need the cache fingerprint *and* the agents in the same
80
+ * tick should call `scanSubagentsDir` directly to avoid a second scan.
81
+ */
82
+ export declare function parseSubagentsDir(jsonlPath: string): Promise<AgentEntry[]>;
@@ -0,0 +1,366 @@
1
+ // Mixed sync/async fs imports are deliberate: `stat` and `readFile` are async
2
+ // I/O on the hot path; the only sync call is the canonicalisation helper from
3
+ // `utils/path.ts`. We do not gate any I/O behind `existsSync` here — the
4
+ // async readdir/stat calls have try/catch fallbacks, which avoids the
5
+ // existsSync→readdir TOCTOU window.
6
+ import { open, readdir, readFile, stat } from 'node:fs/promises';
7
+ import { join, dirname, basename, resolve } from 'node:path';
8
+ import { isUnderAllowedRoot, LUMIRA_ALLOWED_ROOTS } from '../utils/path.js';
9
+ import { sanitizeTermString } from '../normalize.js';
10
+ import { debug } from '../utils/debug.js';
11
+ const log = debug('subagents');
12
+ // Claude Code stores per-subagent transcripts at
13
+ // ~/.claude/projects/<slug>/<session-id>/subagents/agent-<id>.jsonl
14
+ // alongside an agent-<id>.meta.json sidecar carrying {agentType, description}.
15
+ // This is an undocumented implementation detail of Claude Code (verified
16
+ // against 2.1.x). When the layout changes, this module degrades to an empty
17
+ // result and the main-JSONL parser remains the source of truth.
18
+ const AGENT_FILE_RE = /^agent-([A-Za-z0-9_-]+)\.jsonl$/;
19
+ // Long-running sessions accumulate dozens of agent files; the statusline only
20
+ // surfaces a handful. Match the cap used by the main-JSONL agent slice (in
21
+ // `transcript.ts: agentMap.values()).slice(-10)`).
22
+ const MAX_AGENTS = 10;
23
+ // Generic dispatch types Claude Code attaches to anonymous Agent calls. The
24
+ // list is hard-coded today; extend it when Claude Code adds new generic
25
+ // types so the statusline doesn't accidentally surface their names as if
26
+ // they were user-named subagents. Exported as part of the public API;
27
+ // callers should prefer `isNamedAgentType` for membership checks rather
28
+ // than reaching into the set directly.
29
+ export const GENERIC_AGENT_TYPES = new Set(['general-purpose', 'unknown']);
30
+ /**
31
+ * Returns true when `type` identifies a *named* subagent — i.e. one defined
32
+ * by the user (e.g. `pepito`, `feature-dev:code-reviewer`) rather than an
33
+ * anonymous dispatch via the generic Agent tool. Render layers use this to
34
+ * decide whether to surface the type in the cubes-icon widget.
35
+ */
36
+ export function isNamedAgentType(type) {
37
+ return typeof type === 'string' && type.length > 0 && !GENERIC_AGENT_TYPES.has(type);
38
+ }
39
+ export function deriveSubagentsDir(jsonlPath) {
40
+ const dir = dirname(jsonlPath);
41
+ const base = basename(jsonlPath).replace(/\.jsonl$/i, '');
42
+ return join(dir, base, 'subagents');
43
+ }
44
+ /**
45
+ * Unified scan: walks the subagents/ dir once, gathering both the cache
46
+ * fingerprint AND the per-file stat metadata needed for the full parse.
47
+ * Callers that only need the fingerprint can ignore `candidates`; callers
48
+ * doing a full parse can hand the candidates to `readSubagentDetails`
49
+ * without re-running readdir/stat.
50
+ */
51
+ export async function scanSubagentsDir(rawJsonlPath) {
52
+ if (!rawJsonlPath)
53
+ return { state: null, candidates: [] };
54
+ // Canonicalise the input path here so public callers (relative paths,
55
+ // `..` segments) and internal callers (`transcript.ts` already passes a
56
+ // resolved absolute path) get identical results. `deriveSubagentsDir`
57
+ // remains a pure string operation; this is the single point of resolution.
58
+ const jsonlPath = resolve(rawJsonlPath);
59
+ const resolved = deriveSubagentsDir(jsonlPath);
60
+ if (!isUnderAllowedRoot(resolved, LUMIRA_ALLOWED_ROOTS)) {
61
+ log('skip — subagents dir outside allowed roots:', resolved);
62
+ return { state: null, candidates: [] };
63
+ }
64
+ let entries;
65
+ try {
66
+ entries = await readdir(resolved);
67
+ }
68
+ catch (err) {
69
+ log('readdir failed:', resolved, err);
70
+ return { state: null, candidates: [] };
71
+ }
72
+ let count = 0;
73
+ let maxMtimeMs = 0;
74
+ let totalSize = 0;
75
+ const candidates = [];
76
+ for (const file of entries) {
77
+ const m = file.match(AGENT_FILE_RE);
78
+ if (!m)
79
+ continue;
80
+ try {
81
+ const jsonlFile = join(resolved, file);
82
+ const st = await stat(jsonlFile);
83
+ if (!st.isFile())
84
+ continue;
85
+ count += 1;
86
+ if (st.mtimeMs > maxMtimeMs)
87
+ maxMtimeMs = st.mtimeMs;
88
+ totalSize += st.size;
89
+ candidates.push({
90
+ id: m[1],
91
+ jsonlFile,
92
+ metaFile: join(resolved, `agent-${m[1]}.meta.json`),
93
+ mtimeMs: st.mtimeMs,
94
+ size: st.size,
95
+ });
96
+ }
97
+ catch { /* file disappeared mid-scan — skip */ }
98
+ }
99
+ return { state: { count, maxMtimeMs, totalSize }, candidates };
100
+ }
101
+ // Thin wrapper retained for callers that only want the cache fingerprint.
102
+ // Internally re-uses `scanSubagentsDir` so the two paths can never drift.
103
+ export async function getSubagentsDirState(jsonlPath) {
104
+ return (await scanSubagentsDir(jsonlPath)).state;
105
+ }
106
+ export function subagentsDirStateEqual(a, b) {
107
+ if (a === b)
108
+ return true;
109
+ if (!a || !b)
110
+ return false;
111
+ return a.count === b.count && a.maxMtimeMs === b.maxMtimeMs && a.totalSize === b.totalSize;
112
+ }
113
+ async function readMeta(metaPath) {
114
+ try {
115
+ const raw = await readFile(metaPath, 'utf8');
116
+ const parsed = JSON.parse(raw);
117
+ if (parsed && typeof parsed === 'object')
118
+ return parsed;
119
+ }
120
+ catch { /* meta is best-effort */ }
121
+ return null;
122
+ }
123
+ // Files larger than this threshold are read via head/tail chunks rather
124
+ // than slurped whole. Subagent transcripts can grow into the megabytes
125
+ // when the agent runs many tool calls — buffering all of them on every
126
+ // cache miss caused real memory pressure in the wild.
127
+ const LARGE_FILE_THRESHOLD = 256 * 1024;
128
+ // Window we read at each end of a large file. 64 KB is comfortably bigger
129
+ // than any single JSONL line we've observed in the wild (an Opus reviewer's
130
+ // multi-thousand-word closing message clocked at ~18 KB; we leave headroom
131
+ // for unusually large summaries). Small enough to keep a 10-agent miss
132
+ // under ~1.3 MB peak buffer use.
133
+ const BOUNDARY_CHUNK_SIZE = 64 * 1024;
134
+ // Extracts both the first and last well-formed JSON objects from a JSONL
135
+ // file. We need the first line's timestamp for `startTime` (file mtime
136
+ // drifts to the *last* write) and the last line for completion markers.
137
+ //
138
+ // For files at or below `LARGE_FILE_THRESHOLD` we slurp via `readFile`
139
+ // (one syscall, no chunking). For larger files we open the fd and read
140
+ // only the head and tail windows — bounding peak memory regardless of
141
+ // transcript size.
142
+ async function readBoundaryJsonLines(filePath, fileSize) {
143
+ if (fileSize <= LARGE_FILE_THRESHOLD) {
144
+ try {
145
+ const raw = await readFile(filePath, 'utf8');
146
+ return { first: parseFirstJson(raw), last: parseLastJson(raw) };
147
+ }
148
+ catch {
149
+ return { first: null, last: null };
150
+ }
151
+ }
152
+ let fd;
153
+ try {
154
+ fd = await open(filePath, 'r');
155
+ }
156
+ catch {
157
+ return { first: null, last: null };
158
+ }
159
+ try {
160
+ // We're on the chunked path, so fileSize > LARGE_FILE_THRESHOLD >
161
+ // BOUNDARY_CHUNK_SIZE — head and tail windows are always exactly
162
+ // BOUNDARY_CHUNK_SIZE bytes, never clamped by file size.
163
+ const chunkSize = BOUNDARY_CHUNK_SIZE;
164
+ const headBuf = Buffer.alloc(chunkSize);
165
+ await fd.read(headBuf, 0, chunkSize, 0);
166
+ const head = headBuf.toString('utf8');
167
+ const tailBuf = Buffer.alloc(chunkSize);
168
+ await fd.read(tailBuf, 0, chunkSize, fileSize - chunkSize);
169
+ const tail = tailBuf.toString('utf8');
170
+ // The tail window starts at an arbitrary byte offset; if that byte
171
+ // happens to be inside a JSON line, the leading fragment is malformed
172
+ // and we discard everything up to the first newline. If the offset
173
+ // lands cleanly on a line boundary the slice still drops only the
174
+ // single leading newline byte (harmless), so the same logic covers
175
+ // both cases without an extra branch.
176
+ const tailFromBoundary = tail.includes('\n') ? tail.slice(tail.indexOf('\n') + 1) : tail;
177
+ const first = parseFirstJson(head);
178
+ const last = parseLastJson(tailFromBoundary);
179
+ if (log.enabled) {
180
+ // When a single first/last line is bigger than the chunk window,
181
+ // JSON.parse fails on every fragment we see and we fall back to
182
+ // mtime / "running". A fully corrupt file produces the same
183
+ // signal — the suffix "(no valid JSON in head/tail window)"
184
+ // covers both interpretations without overcommitting to either.
185
+ if (first === null)
186
+ log('warn — first-line parse missed (no valid JSON in head window):', filePath);
187
+ if (last === null)
188
+ log('warn — last-line parse missed (no valid JSON in tail window):', filePath);
189
+ }
190
+ return { first, last };
191
+ }
192
+ catch {
193
+ return { first: null, last: null };
194
+ }
195
+ finally {
196
+ await fd.close().catch(() => undefined);
197
+ }
198
+ }
199
+ function parseFirstJson(raw) {
200
+ for (const l of raw.split('\n')) {
201
+ const t = l.trim();
202
+ if (!t)
203
+ continue;
204
+ try {
205
+ return JSON.parse(t);
206
+ }
207
+ catch { /* try next line */ }
208
+ }
209
+ return null;
210
+ }
211
+ function parseLastJson(raw) {
212
+ const lines = raw.split('\n');
213
+ for (let i = lines.length - 1; i >= 0; i--) {
214
+ const t = lines[i].trim();
215
+ if (!t)
216
+ continue;
217
+ try {
218
+ return JSON.parse(t);
219
+ }
220
+ catch { /* try previous line */ }
221
+ }
222
+ return null;
223
+ }
224
+ function extractStopReason(lastLine) {
225
+ if (!lastLine || typeof lastLine !== 'object')
226
+ return null;
227
+ const msg = lastLine.message;
228
+ if (!msg || typeof msg !== 'object')
229
+ return null;
230
+ const sr = msg.stop_reason;
231
+ return typeof sr === 'string' ? sr : null;
232
+ }
233
+ // Claude Code occasionally finalises a subagent's JSONL with `stop_reason:
234
+ // null` (or absent) on the closing assistant message even though the agent
235
+ // has clearly finished — observed for short reviewer subagents that returned
236
+ // their full response inline. The reliable on-disk tell-apart from a "still
237
+ // waiting on a tool" line is whether the assistant's content includes a
238
+ // `tool_use` block: a running agent's last assistant message always carries
239
+ // the tool_use it's waiting on; a finished agent's last message is text-only.
240
+ function isFinalAssistantTextOnly(lastLine) {
241
+ if (!lastLine || typeof lastLine !== 'object')
242
+ return false;
243
+ const d = lastLine;
244
+ if (d.type !== 'assistant')
245
+ return false;
246
+ const content = d.message?.content;
247
+ if (!Array.isArray(content) || content.length === 0)
248
+ return false;
249
+ for (const block of content) {
250
+ if (block && typeof block === 'object') {
251
+ const t = block.type;
252
+ if (t !== 'text')
253
+ return false;
254
+ }
255
+ }
256
+ return true;
257
+ }
258
+ // JSONL lines carry an ISO `timestamp` field. Prefer it for endTime over the
259
+ // file's mtime: mtime can drift due to OS-level flush buffering, especially
260
+ // for short-lived agents that finish faster than the journal commit window.
261
+ function extractTimestamp(lastLine) {
262
+ if (!lastLine || typeof lastLine !== 'object')
263
+ return null;
264
+ const ts = lastLine.timestamp;
265
+ if (typeof ts !== 'string')
266
+ return null;
267
+ const d = new Date(ts);
268
+ return Number.isFinite(d.getTime()) ? d : null;
269
+ }
270
+ // When the user stops a running subagent, Claude Code appends a synthetic
271
+ // user-role message whose text is bracket-wrapped, e.g.
272
+ // "[Request interrupted by user for tool use]". That's the only on-disk
273
+ // signal of a kill — the assistant message that preceded it never gets its
274
+ // closing stop_reason rewritten. Matching is anchored on both ends to avoid
275
+ // false positives if Claude Code ever ships an unrelated message that
276
+ // starts with the same prefix.
277
+ // `[^[]*` rather than `[^\]]*` so a hypothetical future variant whose
278
+ // reason text contains a `]` (but no `[`) would still match.
279
+ const INTERRUPT_MARKER_RE = /^\[Request interrupted by user[^[]*\]$/;
280
+ function wasInterruptedByUser(lastLine) {
281
+ if (!lastLine || typeof lastLine !== 'object')
282
+ return false;
283
+ const d = lastLine;
284
+ if (d.type !== 'user')
285
+ return false;
286
+ const content = d.message?.content;
287
+ if (!Array.isArray(content))
288
+ return false;
289
+ for (const block of content) {
290
+ if (block && typeof block === 'object') {
291
+ const text = block.text;
292
+ if (typeof text === 'string' && INTERRUPT_MARKER_RE.test(text.trim()))
293
+ return true;
294
+ }
295
+ }
296
+ return false;
297
+ }
298
+ async function readAgentDetails(c) {
299
+ const { first, last } = await readBoundaryJsonLines(c.jsonlFile, c.size);
300
+ const stopReason = extractStopReason(last);
301
+ const interrupted = wasInterruptedByUser(last);
302
+ const finalTextOnly = isFinalAssistantTextOnly(last);
303
+ const meta = await readMeta(c.metaFile);
304
+ const agentType = sanitizeTermString(typeof meta?.agentType === 'string' ? meta.agentType : 'unknown');
305
+ const description = typeof meta?.description === 'string' ? sanitizeTermString(meta.description) : undefined;
306
+ const status = (stopReason === 'end_turn' || interrupted || finalTextOnly) ? 'completed' : 'running';
307
+ // startTime: prefer the first JSONL line's embedded ISO timestamp (the
308
+ // dispatch moment) over the file mtime. mtime tracks the *last* write,
309
+ // which for a long-running agent is the close-out — using it as
310
+ // startTime would make duration calculations meaningless. birthtimeMs
311
+ // is unreliable across filesystems (often 0/unset, can't be updated by
312
+ // utimes() so tests can't simulate it), hence we don't try it.
313
+ const startTime = extractTimestamp(first) ?? new Date(c.mtimeMs);
314
+ const agent = {
315
+ id: c.id,
316
+ type: agentType,
317
+ status,
318
+ startTime,
319
+ };
320
+ if (description)
321
+ agent.description = description;
322
+ if (status === 'completed') {
323
+ const tsFromLine = extractTimestamp(last);
324
+ agent.endTime = tsFromLine ?? new Date(c.mtimeMs);
325
+ }
326
+ return agent;
327
+ }
328
+ /**
329
+ * Phase 2 of the parse — reads JSONL bodies + meta sidecars only for the
330
+ * MAX_AGENTS most recent files in `candidates`. Sorts oldest → newest by
331
+ * file mtime; the survivors of `slice(-MAX_AGENTS)` are read.
332
+ *
333
+ * `mtime` is the on-disk last-write timestamp, not the agent's logical
334
+ * "last activity". The two usually coincide, but on a slow filesystem an
335
+ * agent dispatched recently may have a stale mtime (its first write
336
+ * hasn't been journaled yet) while an older agent's file gets touched by
337
+ * an unrelated journal flush. The downstream `startTime` is read from
338
+ * the JSONL line's embedded `timestamp` field — so the sort order may
339
+ * not match `startTime` order exactly. Acceptable for the statusline's
340
+ * "newest N" picker; flagged here so a future caller doesn't assume the
341
+ * two orderings are identical.
342
+ *
343
+ * Exported so callers that already ran `scanSubagentsDir` (e.g. the
344
+ * transcript parser, which uses the same scan to build its cache key) can
345
+ * skip a second readdir+stat pass.
346
+ */
347
+ export async function readSubagentDetails(candidates) {
348
+ const sorted = candidates.slice().sort((a, b) => a.mtimeMs - b.mtimeMs);
349
+ const top = sorted.slice(-MAX_AGENTS);
350
+ const agents = [];
351
+ for (const c of top) {
352
+ agents.push(await readAgentDetails(c));
353
+ }
354
+ return agents;
355
+ }
356
+ /**
357
+ * Convenience wrapper: full scan + full parse. Equivalent to
358
+ * `(await scanSubagentsDir(p)).candidates → readSubagentDetails`.
359
+ * Callers that need the cache fingerprint *and* the agents in the same
360
+ * tick should call `scanSubagentsDir` directly to avoid a second scan.
361
+ */
362
+ export async function parseSubagentsDir(jsonlPath) {
363
+ const { candidates } = await scanSubagentsDir(jsonlPath);
364
+ return readSubagentDetails(candidates);
365
+ }
366
+ //# sourceMappingURL=subagents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagents.js","sourceRoot":"","sources":["../../src/parsers/subagents.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
1
- import { createReadStream, existsSync, realpathSync } from 'node:fs';
1
+ import { createReadStream, existsSync } from 'node:fs';
2
2
  import { createInterface } from 'node:readline';
3
3
  import { resolve } from 'node:path';
4
- import { homedir, tmpdir } from 'node:os';
5
4
  import { EMPTY_TRANSCRIPT } from '../types.js';
6
5
  import { isMtimeFresh, getMtimeState } from '../utils/cache.js';
7
6
  import { sanitizeTermString } from '../normalize.js';
8
- import { isUnderAllowedRoot } from '../utils/path.js';
7
+ import { isUnderAllowedRoot, LUMIRA_ALLOWED_ROOTS } from '../utils/path.js';
9
8
  import { debug } from '../utils/debug.js';
9
+ import { scanSubagentsDir, readSubagentDetails, subagentsDirStateEqual } from './subagents.js';
10
10
  const log = debug('transcript');
11
11
  // Full re-parse on cache miss is intentional. Incremental byte-offset parsing
12
12
  // was evaluated and rejected (see #43): real transcripts are low-thousands of
@@ -119,22 +119,10 @@ export function extractToolTarget(toolName, input) {
119
119
  // under an allowed root pointing at /etc/passwd) is tracked separately;
120
120
  // the threat is narrow because `transcript_path` arrives from Claude Code
121
121
  // itself, not arbitrary external input.
122
- function realpathSafe(p) {
123
- try {
124
- return realpathSync(p);
125
- }
126
- catch {
127
- return resolve(p);
128
- }
129
- }
130
- const ALLOWED_ROOTS = [
131
- ...new Set([
132
- resolve(homedir()),
133
- resolve(tmpdir()),
134
- realpathSafe(homedir()),
135
- realpathSafe(tmpdir()),
136
- ]),
137
- ];
122
+ // `realpathSafe` and `LUMIRA_ALLOWED_ROOTS` previously lived here; both are
123
+ // now in `src/utils/path.ts` so other parsers (e.g. `subagents.ts`) share the
124
+ // same canonicalisation and allow-list semantics. See `path.ts` for caveats
125
+ // about the string-level (non-symlink-following) nature of the check.
138
126
  export async function parseTranscript(transcriptPath) {
139
127
  const result = { ...EMPTY_TRANSCRIPT, tools: [], agents: [], todos: [] };
140
128
  if (!transcriptPath || !existsSync(transcriptPath)) {
@@ -146,15 +134,27 @@ export async function parseTranscript(transcriptPath) {
146
134
  transcriptCache.delete(resolve(transcriptPath));
147
135
  return result;
148
136
  }
137
+ // path.resolve, NOT realpathSafe — symlink resolution is deliberately not
138
+ // done here (and not in subagents.ts either). See `src/utils/path.ts`
139
+ // header for the string-level threat model rationale.
149
140
  const resolved = resolve(transcriptPath);
150
- if (!isUnderAllowedRoot(resolved, ALLOWED_ROOTS)) {
141
+ if (!isUnderAllowedRoot(resolved, LUMIRA_ALLOWED_ROOTS)) {
151
142
  log('skip — path outside allowed roots:', resolved);
152
143
  transcriptCache.delete(resolved);
153
144
  return result;
154
145
  }
155
146
  const currentMtime = getMtimeState(resolved);
147
+ // The subagents/ dir lives outside the main JSONL's stat scope, so a quiet
148
+ // subagent's progress (or a `stop_reason: end_turn` flush) wouldn't change
149
+ // anything the cache can see. A single `scanSubagentsDir` produces both
150
+ // the cache fingerprint AND the per-file candidates we'll feed to
151
+ // `readSubagentDetails` on a miss — eliminates the double readdir+stat
152
+ // pass that an independent fingerprint call would force.
153
+ const subagentsScan = await scanSubagentsDir(resolved);
154
+ const currentSubagentsState = subagentsScan.state;
156
155
  const cached = transcriptCache.get(resolved);
157
- if (currentMtime && cached && isMtimeFresh(resolved, cached.mtime)) {
156
+ if (currentMtime && cached && isMtimeFresh(resolved, cached.mtime)
157
+ && subagentsDirStateEqual(cached.subagentsDir, currentSubagentsState)) {
158
158
  log('cache hit:', resolved);
159
159
  touchCache(resolved, cached);
160
160
  return cloneShallow(cached.result);
@@ -200,17 +200,31 @@ export async function parseTranscript(transcriptPath) {
200
200
  continue;
201
201
  for (const block of content) {
202
202
  if (block.type === 'tool_use' && block.id && block.name) {
203
- toolMap.set(block.id, { id: block.id, name: sanitizeTermString(block.name), target: extractToolTarget(block.name, block.input), status: 'running', startTime: timestamp });
204
- if (block.name === 'Task') {
205
- const inp = block.input || {};
206
- agentMap.set(block.id, {
207
- id: block.id,
208
- type: sanitizeTermString(inp.subagent_type || 'unknown'),
209
- model: typeof inp.model === 'string' ? sanitizeTermString(inp.model) : inp.model,
210
- description: typeof inp.description === 'string' ? sanitizeTermString(inp.description) : inp.description,
211
- status: 'running',
212
- startTime: timestamp,
213
- });
203
+ // Claude Code occasionally re-emits a tool_use after its tool_result
204
+ // has already landed (observed when a subagent dispatch fails with
205
+ // "Agent type not found"). Treat the first completion as final —
206
+ // never downgrade completed/error back to running on re-registration.
207
+ const existingTool = toolMap.get(block.id);
208
+ if (!existingTool || existingTool.status === 'running') {
209
+ toolMap.set(block.id, { id: block.id, name: sanitizeTermString(block.name), target: extractToolTarget(block.name, block.input), status: 'running', startTime: timestamp });
210
+ }
211
+ // Claude Code ≥ 2.1.x renamed the subagent dispatch tool from
212
+ // `Task` to `Agent`. Both shapes carry the same fields
213
+ // (subagent_type, description, model, prompt). Accept either so the
214
+ // live agent count widget works on both versions.
215
+ if (block.name === 'Task' || block.name === 'Agent') {
216
+ const existingAgent = agentMap.get(block.id);
217
+ if (!existingAgent || existingAgent.status === 'running') {
218
+ const inp = block.input || {};
219
+ agentMap.set(block.id, {
220
+ id: block.id,
221
+ type: sanitizeTermString(inp.subagent_type || 'unknown'),
222
+ model: typeof inp.model === 'string' ? sanitizeTermString(inp.model) : inp.model,
223
+ description: typeof inp.description === 'string' ? sanitizeTermString(inp.description) : inp.description,
224
+ status: 'running',
225
+ startTime: timestamp,
226
+ });
227
+ }
214
228
  }
215
229
  if (block.name === 'TodoWrite' && block.input?.todos && Array.isArray(block.input.todos)) {
216
230
  const existingById = new Map(todos.map(t => [t.id || t.content, t]));
@@ -282,8 +296,21 @@ export async function parseTranscript(transcriptPath) {
282
296
  result.agents = Array.from(agentMap.values()).slice(-10);
283
297
  result.todos = todos;
284
298
  result.thinkingEffort = thinkingEffort;
299
+ // The subagents/ dir alongside the main JSONL is Claude Code's own
300
+ // per-subagent transcript store. It records every agent that ran in this
301
+ // session — including quiet/background ones whose tool_use entry stays
302
+ // buffered in the parent JSONL — and exposes a definitive completion
303
+ // marker via stop_reason. When present, prefer it over the main-JSONL
304
+ // pairing heuristic. When absent (older Claude Code, layout change), fall
305
+ // back to whatever main-JSONL parsing produced.
306
+ const subagentDirAgents = await readSubagentDetails(subagentsScan.candidates);
307
+ if (subagentDirAgents.length > 0) {
308
+ if (log.enabled)
309
+ log('subagents-dir override:', subagentDirAgents.length, 'agents replace', result.agents.length, 'from main JSONL');
310
+ result.agents = subagentDirAgents;
311
+ }
285
312
  if (currentMtime) {
286
- touchCache(resolved, { result, mtime: currentMtime });
313
+ touchCache(resolved, { result, mtime: currentMtime, subagentsDir: currentSubagentsState });
287
314
  }
288
315
  if (log.enabled) {
289
316
  log('parsed', resolved, {
@@ -1 +1 @@
1
- {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/parsers/transcript.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/parsers/transcript.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { fitSegments, truncField } from './text.js';
4
4
  import { formatGitChanges, getActiveTodo, SEP } from './shared.js';
5
5
  import { hyperlink } from './hyperlink.js';
6
6
  import { formatDuration } from '../utils/format.js';
7
+ import { isNamedAgentType } from '../parsers/subagents.js';
7
8
  export function renderLine1(ctx, c) {
8
9
  const { input, git, transcript, config: { display }, cols, icons, memory, tokenSpeed } = ctx;
9
10
  const left = [];
@@ -71,8 +72,22 @@ export function renderLine1(ctx, c) {
71
72
  if (display.worktree && input.worktreeName) {
72
73
  right.push(c.gray(`${icons.tree} ${truncField(input.worktreeName, 15)}`));
73
74
  }
74
- if (display.agent && input.agentName) {
75
- right.push(c.gray(`${icons.cubes} ${truncField(input.agentName, 15)}`));
75
+ if (display.agent) {
76
+ // Show the cubes-icon agent name when:
77
+ // 1) the statusline is rendering inside a subagent session (input.agentName
78
+ // comes from Claude Code's stdin payload), or
79
+ // 2) the parent session has exactly one *named* subagent currently
80
+ // running. Anonymous (general-purpose / unknown) agents stay collapsed
81
+ // under the live ⚡N agents widget on line 3 to avoid noise.
82
+ let agentName = input.agentName;
83
+ if (!agentName) {
84
+ const named = transcript.agents.filter(a => a.status === 'running' && isNamedAgentType(a.type));
85
+ if (named.length === 1)
86
+ agentName = named[0].type;
87
+ }
88
+ if (agentName) {
89
+ right.push(c.gray(`${icons.cubes} ${truncField(agentName, 15)}`));
90
+ }
76
91
  }
77
92
  if (display.sessionName && input.sessionName) {
78
93
  right.push(c.dim(truncField(input.sessionName, 20)));
@@ -1 +1 @@
1
- {"version":3,"file":"line1.js","sourceRoot":"","sources":["../../src/render/line1.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"line1.js","sourceRoot":"","sources":["../../src/render/line1.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,21 @@
1
+ /**
2
+ * Resolves a path through symlinks, falling back to plain `resolve()` if the
3
+ * path doesn't exist or canonicalisation fails. Used to harden allow-list
4
+ * checks across modules that read user-controlled paths.
5
+ */
6
+ export declare function realpathSafe(p: string): string;
7
+ /**
8
+ * The default set of root directories Lumira parsers are allowed to read from.
9
+ * Includes both the canonical and the symlink-resolved forms of $HOME and
10
+ * $TMPDIR so paths under either spelling are accepted.
11
+ *
12
+ * IMPORTANT: this allow-list is a *string-level* defence. `isUnderAllowedRoot`
13
+ * does not follow symlinks at check time — callers protecting against symlink
14
+ * traversal should canonicalise the candidate path with `realpathSafe` before
15
+ * the comparison, or accept that a symlink whose target lies outside the
16
+ * allow-list is treated as legal as long as its own *path* sits under one.
17
+ */
18
+ export declare const LUMIRA_ALLOWED_ROOTS: readonly string[];
1
19
  /**
2
20
  * Returns true if `candidate` is the same as, or a descendant of, any of the
3
21
  * `roots`. Uses `path.relative` to avoid the classic `startsWith` bypass where
@@ -1,4 +1,33 @@
1
+ import { realpathSync } from 'node:fs';
2
+ import { homedir, tmpdir } from 'node:os';
1
3
  import { resolve, relative, isAbsolute } from 'node:path';
4
+ /**
5
+ * Resolves a path through symlinks, falling back to plain `resolve()` if the
6
+ * path doesn't exist or canonicalisation fails. Used to harden allow-list
7
+ * checks across modules that read user-controlled paths.
8
+ */
9
+ export function realpathSafe(p) {
10
+ try {
11
+ return realpathSync(p);
12
+ }
13
+ catch {
14
+ return resolve(p);
15
+ }
16
+ }
17
+ /**
18
+ * The default set of root directories Lumira parsers are allowed to read from.
19
+ * Includes both the canonical and the symlink-resolved forms of $HOME and
20
+ * $TMPDIR so paths under either spelling are accepted.
21
+ *
22
+ * IMPORTANT: this allow-list is a *string-level* defence. `isUnderAllowedRoot`
23
+ * does not follow symlinks at check time — callers protecting against symlink
24
+ * traversal should canonicalise the candidate path with `realpathSafe` before
25
+ * the comparison, or accept that a symlink whose target lies outside the
26
+ * allow-list is treated as legal as long as its own *path* sits under one.
27
+ */
28
+ export const LUMIRA_ALLOWED_ROOTS = [
29
+ ...new Set([resolve(homedir()), resolve(tmpdir()), realpathSafe(homedir()), realpathSafe(tmpdir())]),
30
+ ];
2
31
  /**
3
32
  * Returns true if `candidate` is the same as, or a descendant of, any of the
4
33
  * `roots`. Uses `path.relative` to avoid the classic `startsWith` bypass where
@@ -1 +1 @@
1
- {"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,KAAwB;IAC5E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,MAAM,mBAAmB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,mBAAmB,KAAK,cAAc;YAAE,OAAO,IAAI,CAAC;QACxD,MAAM,GAAG,GAAG,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;QAC1D,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IACpE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE1D;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,IAAI,CAAC;QAAC,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAsB;IACrD,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CACrG,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,KAAwB;IAC5E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,MAAM,mBAAmB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,mBAAmB,KAAK,cAAc;YAAE,OAAO,IAAI,CAAC;QACxD,MAAM,GAAG,GAAG,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;QAC1D,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IACpE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lumira",
3
- "version": "1.1.2",
3
+ "version": "1.2.1",
4
4
  "description": "Real-time statusline HUD for Claude Code and Qwen Code — context bar, burn rate, themes, powerline, zero deps.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",