@cryptiklemur/lattice 1.43.3 → 1.43.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cryptiklemur/lattice",
3
- "version": "1.43.3",
3
+ "version": "1.43.4",
4
4
  "description": "Multi-machine agentic dashboard for Claude Code. Monitor sessions, manage MCP servers and skills, orchestrate across mesh-networked nodes.",
5
5
  "license": "MIT",
6
6
  "author": "Aaron Scherer <me@aaronscherer.me>",
@@ -34,7 +34,9 @@ registerHandler("session", function (clientId: string, message: ClientMessage) {
34
34
  var listReqMsg = message as SessionListRequestMessage;
35
35
  var offset = listReqMsg.offset || 0;
36
36
  var limit = listReqMsg.limit || 0;
37
+ var t0 = Date.now();
37
38
  void listSessions(listReqMsg.projectSlug, { offset, limit }).then(function (result) {
39
+ log.session("session:list_request for %s took %dms (%d sessions)", listReqMsg.projectSlug, Date.now() - t0, result.sessions.length);
38
40
  sendTo(clientId, {
39
41
  type: "session:list",
40
42
  projectSlug: listReqMsg.projectSlug,
@@ -221,7 +221,7 @@ export function getActiveSessionCountForProject(projectPath: string): number {
221
221
  if (existsSync(join(dir, sessionId + ".jsonl"))) count++;
222
222
  }
223
223
 
224
- if (cliSessionsByProject.get(projectPath) !== null && cliSessionsByProject.get(projectPath) !== undefined) count++;
224
+ if (cliActiveProjects.has(projectPath)) count++;
225
225
 
226
226
  return count;
227
227
  }
@@ -241,32 +241,15 @@ export function isSessionBusy(sessionId: string): boolean {
241
241
  * The SDK spawns child processes (e.g. claude-agent-sdk/cli.js) that hold
242
242
  * lock files — those are NOT external.
243
243
  */
244
- var cliSessionsByProject = new Map<string, string | null>();
245
- var sessionNameCache = new Map<string, string>();
244
+ var cliActiveProjects = new Set<string>();
246
245
 
247
246
  function refreshCliDetection(): void {
248
- var config = loadConfig();
247
+ var newActive = new Set<string>();
249
248
  var cliPids = getClaudeCliPidsAsync();
250
- for (var i = 0; i < config.projects.length; i++) {
251
- var projectPath = config.projects[i].path;
252
- var found: string | null = null;
253
- for (var j = 0; j < cliPids.length; j++) {
254
- if (cliPids[j].cwd !== projectPath) continue;
255
- var cmdline = cliPids[j].cmdline;
256
- var resumeIdx = cmdline.indexOf("--resume");
257
- if (resumeIdx !== -1 && resumeIdx + 1 < cmdline.length) {
258
- var sessionName = cmdline[resumeIdx + 1];
259
- found = resolveSessionName(projectPath, sessionName);
260
- if (!found) {
261
- resolveSessionNameAsync(projectPath, sessionName);
262
- }
263
- } else {
264
- found = findMostRecentSession(projectPath);
265
- }
266
- break;
267
- }
268
- cliSessionsByProject.set(projectPath, found);
249
+ for (var i = 0; i < cliPids.length; i++) {
250
+ newActive.add(cliPids[i].cwd);
269
251
  }
252
+ cliActiveProjects = newActive;
270
253
  }
271
254
 
272
255
  function getClaudeCliPidsAsync(): Array<{ pid: number; cwd: string; cmdline: string[] }> {
@@ -288,8 +271,7 @@ function getClaudeCliPidsAsync(): Array<{ pid: number; cwd: string; cmdline: str
288
271
  return results;
289
272
  }
290
273
 
291
- setInterval(refreshCliDetection, 5000);
292
- setTimeout(refreshCliDetection, 1000);
274
+ setInterval(refreshCliDetection, 10000);
293
275
 
294
276
  function getProjectPathForSession(sessionId: string): string | null {
295
277
  var config = loadConfig();
@@ -302,72 +284,11 @@ function getProjectPathForSession(sessionId: string): string | null {
302
284
  }
303
285
 
304
286
 
305
- function resolveSessionName(projectPath: string, name: string): string | null {
306
- var cacheKey = projectPath + ":" + name;
307
- var cached = sessionNameCache.get(cacheKey);
308
- if (cached) return cached;
309
-
310
- if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(name)) {
311
- var hash = projectPath.replace(/\//g, "-");
312
- if (existsSync(join(homedir(), ".claude", "projects", hash, name + ".jsonl"))) {
313
- sessionNameCache.set(cacheKey, name);
314
- return name;
315
- }
316
- }
317
-
318
- return null;
319
- }
320
-
321
- function resolveSessionNameAsync(projectPath: string, name: string): void {
322
- var cacheKey = projectPath + ":" + name;
323
- if (sessionNameCache.has(cacheKey)) return;
324
-
325
- var hash = projectPath.replace(/\//g, "-");
326
- var dir = join(homedir(), ".claude", "projects", hash);
327
- if (!existsSync(dir)) return;
328
-
329
- var proc = Bun.spawn(["grep", "-rl", "--include=*.jsonl", "-m", "1", name, dir], {
330
- stdout: "pipe", stderr: "ignore",
331
- });
332
- void proc.exited.then(function () {
333
- var output = new Response(proc.stdout).text();
334
- return output;
335
- }).then(function (text) {
336
- var files = text.trim().split("\n").filter(Boolean);
337
- if (files.length > 0) {
338
- var match = files[0].match(/([0-9a-f-]{36})\.jsonl$/);
339
- if (match) {
340
- sessionNameCache.set(cacheKey, match[1]);
341
- }
342
- }
343
- }).catch(function () {});
344
- }
345
-
346
- function findMostRecentSession(projectPath: string): string | null {
347
- var hash = projectPath.replace(/\//g, "-");
348
- var dir = join(homedir(), ".claude", "projects", hash);
349
- if (!existsSync(dir)) return null;
350
-
351
- var entries = readdirSync(dir).filter(function (f) { return f.endsWith(".jsonl"); });
352
- var latest: { id: string; mtime: number } | null = null;
353
- for (var e = 0; e < entries.length; e++) {
354
- try {
355
- var s = statSync(join(dir, entries[e]));
356
- if (!latest || s.mtimeMs > latest.mtime) {
357
- latest = { id: entries[e].replace(".jsonl", ""), mtime: s.mtimeMs };
358
- }
359
- } catch {}
360
- }
361
- if (latest && Date.now() - latest.mtime < 60000) return latest.id;
362
- return null;
363
- }
364
-
365
-
366
287
  function isSessionLockedByExternal(sessionId: string): boolean {
367
288
  if (activeStreams.has(sessionId)) return false;
368
289
  var projectPath = getProjectPathForSession(sessionId);
369
290
  if (!projectPath) return false;
370
- return cliSessionsByProject.get(projectPath) === sessionId;
291
+ return cliActiveProjects.has(projectPath);
371
292
  }
372
293
 
373
294
  export function stopExternalSession(sessionId: string): boolean {