@cryptiklemur/lattice 5.4.3 → 5.5.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.
- package/README.md +114 -0
- package/dist/client/assets/{angular-html-BMCIs4B9.js → angular-html-Bmjy4gNc.js} +1 -1
- package/dist/client/assets/{angular-ts-Dl9U67Xi.js → angular-ts-10l13C4C.js} +1 -1
- package/dist/client/assets/{apl-Dc2Jp1EP.js → apl--Bn7yH0T.js} +1 -1
- package/dist/client/assets/{astro-KOvSEh6g.js → astro-C8P9TQkP.js} +1 -1
- package/dist/client/assets/{blade-Bp9mbJ5K.js → blade-DQiHYnIS.js} +1 -1
- package/dist/client/assets/{c-C0ETB1bm.js → c-BFny-WnE.js} +1 -1
- package/dist/client/assets/{cobol-DE5VmQJX.js → cobol-hGEexMYH.js} +1 -1
- package/dist/client/assets/{coffee-COzJhfRU.js → coffee-j3W4ZALV.js} +1 -1
- package/dist/client/assets/{cpp-jzhs79Ii.js → cpp-DquWJNps.js} +1 -1
- package/dist/client/assets/{crystal-Czf3Etrk.js → crystal-CWL31dIV.js} +1 -1
- package/dist/client/assets/{css-Cf45eU4M.js → css-Di4GSq8V.js} +1 -1
- package/dist/client/assets/{dist-Bk-EVR9B.js → dist-CaJdL3Va.js} +2 -2
- package/dist/client/assets/{edge-BmKSsYuX.js → edge-rK4d050l.js} +1 -1
- package/dist/client/assets/{elixir-Ds7FEpTU.js → elixir-BMFKKu5z.js} +1 -1
- package/dist/client/assets/{elm-C_AmF7eK.js → elm-B0QVlW3-.js} +1 -1
- package/dist/client/assets/{erb-DevlC2ei.js → erb-C9w9QbhL.js} +1 -1
- package/dist/client/assets/{git-rebase-CpJCeeHA.js → git-rebase-FaylS7Vl.js} +1 -1
- package/dist/client/assets/{glimmer-js-CFH-Kzxa.js → glimmer-js-Bi2XnbHi.js} +1 -1
- package/dist/client/assets/{glimmer-ts-BkiQ1tjj.js → glimmer-ts-DOdxK6E6.js} +1 -1
- package/dist/client/assets/{glsl-DLuvkGQM.js → glsl-BiGDIGbZ.js} +1 -1
- package/dist/client/assets/{graphql-CYjDXA-l.js → graphql-CZJB8KIP.js} +1 -1
- package/dist/client/assets/{hack-CDfrJ_Sc.js → hack-CNGYBFqH.js} +1 -1
- package/dist/client/assets/{haml-C4YjrCNF.js → haml-pf3Zh5MH.js} +1 -1
- package/dist/client/assets/{handlebars-WIT13u08.js → handlebars-BsQwsvPC.js} +1 -1
- package/dist/client/assets/{html-ntqTOVvn.js → html-Dj4Hvv69.js} +1 -1
- package/dist/client/assets/{html-derivative-B3rc20Rp.js → html-derivative-CE7dQ_mI.js} +1 -1
- package/dist/client/assets/{http-jTU2ko3B.js → http-DjOuMI1u.js} +1 -1
- package/dist/client/assets/{hurl-D2HM7b2B.js → hurl-BH_MQrQo.js} +1 -1
- package/dist/client/assets/{index-CZNra7P3.js → index-DA8ZBSYW.js} +321 -88
- package/dist/client/assets/{index-DCKRhnC1.css → index-DcwXjiH0.css} +1 -1
- package/dist/client/assets/{java-BofMW2-d.js → java-CnpykAva.js} +1 -1
- package/dist/client/assets/{javascript-DHlF2jGd.js → javascript-BbqQ1sQM.js} +1 -1
- package/dist/client/assets/{jinja-BXkUuA_p.js → jinja-DddpvWwk.js} +1 -1
- package/dist/client/assets/{jison-CYSiwIU-.js → jison-Bd3G2n4x.js} +1 -1
- package/dist/client/assets/{json-5cpQWmWq.js → json-F0eTFQKP.js} +1 -1
- package/dist/client/assets/{jsx-D8kfeKVb.js → jsx-B-wB5nUs.js} +1 -1
- package/dist/client/assets/{julia-BkW_r2Xd.js → julia-9Lfz4b5s.js} +1 -1
- package/dist/client/assets/{just-Dz61xACw.js → just-BVE1sBJx.js} +1 -1
- package/dist/client/assets/{latex-gqtZNh_M.js → latex-SF3xMSWG.js} +1 -1
- package/dist/client/assets/{liquid-KcpeevnQ.js → liquid-CLkbZ0ZV.js} +1 -1
- package/dist/client/assets/{lua-C3Vw3Kyi.js → lua-DNph6TL8.js} +1 -1
- package/dist/client/assets/{marko-DVaxNS7b.js → marko-CGqdEtbF.js} +1 -1
- package/dist/client/assets/{mdc-DRm1pTBY.js → mdc-BLpzcq82.js} +1 -1
- package/dist/client/assets/{nginx-DYudX1m0.js → nginx-s7ciyZD1.js} +1 -1
- package/dist/client/assets/{nim-DejMEf9z.js → nim-C4FeZI3R.js} +1 -1
- package/dist/client/assets/{perl-D09qXnjW.js → perl-GDfD5AIi.js} +1 -1
- package/dist/client/assets/{php-BrfQzrDQ.js → php-CusAuy6y.js} +1 -1
- package/dist/client/assets/{pug-DPbk8XD2.js → pug-DCKuXO7x.js} +1 -1
- package/dist/client/assets/{qml-BCh8MHc-.js → qml-rp1ZHoeo.js} +1 -1
- package/dist/client/assets/{r-DCcyjvCV.js → r-CwNbYaVb.js} +1 -1
- package/dist/client/assets/{razor-CHeljxcn.js → razor-CinY5yf4.js} +1 -1
- package/dist/client/assets/{regexp-DpLv_uhV.js → regexp-CxVI4rKV.js} +1 -1
- package/dist/client/assets/{rst-BmAGX4li.js → rst-BrBmBgUr.js} +1 -1
- package/dist/client/assets/{ruby-C28IDakj.js → ruby-BzNCpRio.js} +1 -1
- package/dist/client/assets/{sas-Dq78Tt13.js → sas-B4IAap7m.js} +1 -1
- package/dist/client/assets/{scss-CCq8md_z.js → scss-eNAsUEA1.js} +1 -1
- package/dist/client/assets/{shellscript-Cl_slHLv.js → shellscript-BwH0aChW.js} +1 -1
- package/dist/client/assets/{shellsession-D50FTgCo.js → shellsession-B5ibJBbh.js} +1 -1
- package/dist/client/assets/{soy-Da12pRro.js → soy-BrqReQP3.js} +1 -1
- package/dist/client/assets/{sql-DRKhJcrs.js → sql-KIDgTieS.js} +1 -1
- package/dist/client/assets/{stata-E06HAz87.js → stata-D6yim7Rr.js} +1 -1
- package/dist/client/assets/{surrealql-CTaVrdiv.js → surrealql-C51iMPEA.js} +1 -1
- package/dist/client/assets/{svelte-j0H5d0BS.js → svelte-DYs5QSVt.js} +1 -1
- package/dist/client/assets/{templ-BXfOHYWo.js → templ-CLDdaEXl.js} +1 -1
- package/dist/client/assets/{tex-CGBWhBxV.js → tex-D16HBCoj.js} +1 -1
- package/dist/client/assets/{ts-tags-C-diQc0f.js → ts-tags-DTcB2bBd.js} +1 -1
- package/dist/client/assets/{tsx-CUBPow91.js → tsx-BxGfVt8a.js} +1 -1
- package/dist/client/assets/{twig-BYoQufij.js → twig-BUC08jwe.js} +1 -1
- package/dist/client/assets/{typescript-CAiUPCi4.js → typescript-CuPGT2MR.js} +1 -1
- package/dist/client/assets/{vue-CEKqQRtx.js → vue-_ip8-SIk.js} +1 -1
- package/dist/client/assets/{vue-html-DSRnbzbs.js → vue-html-D-I9-U-x.js} +1 -1
- package/dist/client/assets/{vue-vine-PFaCZbOl.js → vue-vine-7AONB1tt.js} +1 -1
- package/dist/client/assets/{xml-CpFeNxWK.js → xml-D2ZUDsPU.js} +1 -1
- package/dist/client/assets/{xsl-DOlnqqgg.js → xsl-GlFKKlLy.js} +1 -1
- package/dist/client/assets/{yaml-Bv-3IQB_.js → yaml-BnuTxWck.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/sw.js +1 -1
- package/dist/server/daemon.js +16 -0
- package/dist/server/features/brainstorm.js +267 -0
- package/dist/server/handlers/brainstorm.js +33 -0
- package/dist/server/handlers/fs.js +3 -0
- package/dist/server/handlers/session.js +13 -5
- package/dist/server/project/session.js +92 -11
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { registerHandler } from "../ws/router.js";
|
|
2
|
-
import { sendTo } from "../ws/broadcast.js";
|
|
2
|
+
import { sendTo, broadcast } from "../ws/broadcast.js";
|
|
3
3
|
import { loadConfig } from "../config.js";
|
|
4
|
-
import { createSession, deleteSession, findProjectSlugForSession, getSessionPreview, getSessionTitle, getSessionUsage, listSessions, invalidateSessionCache, invalidateHistoryCache, getSessionHistoryPage, loadSessionHistory, renameSession, getSessionFileSizeBytes, } from "../project/session.js";
|
|
4
|
+
import { createSession, deleteSession, findProjectSlugForSession, getSessionPreview, getSessionTitle, getSessionUsage, listSessions, invalidateSessionCache, invalidateHistoryCache, getSessionHistoryPage, loadSessionHistory, renameSession, getSessionFileSizeBytes, updateSessionInIndex, removeSessionFromIndex, } from "../project/session.js";
|
|
5
5
|
import { getContextBreakdown } from "../project/context-breakdown.js";
|
|
6
6
|
import { setActiveSession, getActiveSession } from "./chat.js";
|
|
7
7
|
import { setActiveProject } from "./fs.js";
|
|
@@ -71,7 +71,15 @@ registerHandler("session", function (clientId, message) {
|
|
|
71
71
|
if (message.type === "session:create") {
|
|
72
72
|
var createMsg = message;
|
|
73
73
|
var session = createSession(createMsg.projectSlug);
|
|
74
|
+
updateSessionInIndex(createMsg.projectSlug, session);
|
|
74
75
|
sendTo(clientId, { type: "session:created", session });
|
|
76
|
+
broadcast({
|
|
77
|
+
type: "session:list",
|
|
78
|
+
projectSlug: createMsg.projectSlug,
|
|
79
|
+
sessions: [session],
|
|
80
|
+
totalCount: undefined,
|
|
81
|
+
offset: 0,
|
|
82
|
+
});
|
|
75
83
|
return;
|
|
76
84
|
}
|
|
77
85
|
if (message.type === "session:activate") {
|
|
@@ -160,7 +168,7 @@ registerHandler("session", function (clientId, message) {
|
|
|
160
168
|
void renameSession(projectSlug, renameMsg.sessionId, renameMsg.title).then(function () {
|
|
161
169
|
invalidateSessionCache(projectSlug);
|
|
162
170
|
void listSessions(projectSlug, { limit: 40 }).then(function (result) {
|
|
163
|
-
|
|
171
|
+
broadcast({
|
|
164
172
|
type: "session:list",
|
|
165
173
|
projectSlug,
|
|
166
174
|
sessions: result.sessions,
|
|
@@ -179,9 +187,9 @@ registerHandler("session", function (clientId, message) {
|
|
|
179
187
|
return;
|
|
180
188
|
}
|
|
181
189
|
void deleteSession(deleteProjectSlug, deleteMsg.sessionId).then(function () {
|
|
182
|
-
|
|
190
|
+
removeSessionFromIndex(deleteProjectSlug, deleteMsg.sessionId);
|
|
183
191
|
void listSessions(deleteProjectSlug, { limit: 40 }).then(function (result) {
|
|
184
|
-
|
|
192
|
+
broadcast({
|
|
185
193
|
type: "session:list",
|
|
186
194
|
projectSlug: deleteProjectSlug,
|
|
187
195
|
sessions: result.sessions,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { listSessions as sdkListSessions, getSessionInfo, getSessionMessages, renameSession as sdkRenameSession, } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
-
import { existsSync, unlinkSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { existsSync, unlinkSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
3
3
|
import * as fsPromises from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
|
-
import { loadConfig } from "../config.js";
|
|
7
|
+
import { loadConfig, getLatticeHome } from "../config.js";
|
|
8
8
|
import { log } from "../logger.js";
|
|
9
9
|
function getProjectPath(projectSlug) {
|
|
10
10
|
var config = loadConfig();
|
|
@@ -428,7 +428,81 @@ export async function getSessionPreview(projectSlug, sessionId) {
|
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
430
|
var sessionListCache = new Map();
|
|
431
|
-
var SESSION_CACHE_TTL =
|
|
431
|
+
var SESSION_CACHE_TTL = 60000;
|
|
432
|
+
var RECONCILE_INTERVAL = 5 * 60 * 1000;
|
|
433
|
+
var lastReconcile = new Map();
|
|
434
|
+
function getIndexPath() {
|
|
435
|
+
return join(getLatticeHome(), "session-index.json");
|
|
436
|
+
}
|
|
437
|
+
function loadSessionIndex() {
|
|
438
|
+
var indexPath = getIndexPath();
|
|
439
|
+
if (!existsSync(indexPath))
|
|
440
|
+
return {};
|
|
441
|
+
try {
|
|
442
|
+
return JSON.parse(readFileSync(indexPath, "utf-8"));
|
|
443
|
+
}
|
|
444
|
+
catch {
|
|
445
|
+
return {};
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
function saveSessionIndex(index) {
|
|
449
|
+
try {
|
|
450
|
+
writeFileSync(getIndexPath(), JSON.stringify(index), "utf-8");
|
|
451
|
+
}
|
|
452
|
+
catch (err) {
|
|
453
|
+
log.session("Failed to save session index: %O", err);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
export function updateSessionInIndex(projectSlug, session) {
|
|
457
|
+
var index = loadSessionIndex();
|
|
458
|
+
var sessions = index[projectSlug] || [];
|
|
459
|
+
var existing = -1;
|
|
460
|
+
for (var i = 0; i < sessions.length; i++) {
|
|
461
|
+
if (sessions[i].id === session.id) {
|
|
462
|
+
existing = i;
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (existing >= 0) {
|
|
467
|
+
sessions[existing] = session;
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
sessions.push(session);
|
|
471
|
+
}
|
|
472
|
+
sessions.sort(function (a, b) { return b.updatedAt - a.updatedAt; });
|
|
473
|
+
index[projectSlug] = sessions;
|
|
474
|
+
saveSessionIndex(index);
|
|
475
|
+
sessionListCache.set(projectSlug, { sessions, time: Date.now() });
|
|
476
|
+
}
|
|
477
|
+
export function removeSessionFromIndex(projectSlug, sessionId) {
|
|
478
|
+
var index = loadSessionIndex();
|
|
479
|
+
var sessions = index[projectSlug] || [];
|
|
480
|
+
index[projectSlug] = sessions.filter(function (s) { return s.id !== sessionId; });
|
|
481
|
+
saveSessionIndex(index);
|
|
482
|
+
sessionListCache.set(projectSlug, { sessions: index[projectSlug], time: Date.now() });
|
|
483
|
+
}
|
|
484
|
+
async function reconcileWithSDK(projectSlug) {
|
|
485
|
+
var projectPath = getProjectPath(projectSlug);
|
|
486
|
+
if (!projectPath)
|
|
487
|
+
return [];
|
|
488
|
+
var sdkT0 = Date.now();
|
|
489
|
+
var sdkSessions = await sdkListSessions({ dir: projectPath });
|
|
490
|
+
log.session("sdkListSessions for %s: %dms (%d sessions)", projectSlug, Date.now() - sdkT0, sdkSessions.length);
|
|
491
|
+
var summaries = sdkSessions.map(function (s) { return mapSDKSession(s, projectSlug); });
|
|
492
|
+
summaries.sort(function (a, b) { return b.updatedAt - a.updatedAt; });
|
|
493
|
+
var index = loadSessionIndex();
|
|
494
|
+
index[projectSlug] = summaries;
|
|
495
|
+
saveSessionIndex(index);
|
|
496
|
+
sessionListCache.set(projectSlug, { sessions: summaries, time: Date.now() });
|
|
497
|
+
lastReconcile.set(projectSlug, Date.now());
|
|
498
|
+
return summaries;
|
|
499
|
+
}
|
|
500
|
+
function needsReconcile(projectSlug) {
|
|
501
|
+
var last = lastReconcile.get(projectSlug);
|
|
502
|
+
if (!last)
|
|
503
|
+
return true;
|
|
504
|
+
return Date.now() - last > RECONCILE_INTERVAL;
|
|
505
|
+
}
|
|
432
506
|
export async function listSessions(projectSlug, options) {
|
|
433
507
|
var projectPath = getProjectPath(projectSlug);
|
|
434
508
|
if (!projectPath) {
|
|
@@ -441,15 +515,22 @@ export async function listSessions(projectSlug, options) {
|
|
|
441
515
|
var sliced = limit > 0 ? cached.sessions.slice(offset, offset + limit) : cached.sessions;
|
|
442
516
|
return { sessions: sliced, totalCount: cached.sessions.length };
|
|
443
517
|
}
|
|
518
|
+
var index = loadSessionIndex();
|
|
519
|
+
var indexed = index[projectSlug];
|
|
520
|
+
if (indexed && indexed.length > 0) {
|
|
521
|
+
sessionListCache.set(projectSlug, { sessions: indexed, time: Date.now() });
|
|
522
|
+
if (needsReconcile(projectSlug)) {
|
|
523
|
+
reconcileWithSDK(projectSlug).catch(function (err) {
|
|
524
|
+
log.session("Background reconcile failed: %O", err);
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
var offset3 = options?.offset ?? 0;
|
|
528
|
+
var limit3 = options?.limit ?? 0;
|
|
529
|
+
var sliced3 = limit3 > 0 ? indexed.slice(offset3, offset3 + limit3) : indexed;
|
|
530
|
+
return { sessions: sliced3, totalCount: indexed.length };
|
|
531
|
+
}
|
|
444
532
|
try {
|
|
445
|
-
var
|
|
446
|
-
var sdkSessions = await sdkListSessions({ dir: projectPath });
|
|
447
|
-
log.session("sdkListSessions for %s: %dms (%d sessions)", projectSlug, Date.now() - sdkT0, sdkSessions.length);
|
|
448
|
-
var summaries = sdkSessions.map(function (s) {
|
|
449
|
-
return mapSDKSession(s, projectSlug);
|
|
450
|
-
});
|
|
451
|
-
summaries.sort(function (a, b) { return b.updatedAt - a.updatedAt; });
|
|
452
|
-
sessionListCache.set(projectSlug, { sessions: summaries, time: Date.now() });
|
|
533
|
+
var summaries = await reconcileWithSDK(projectSlug);
|
|
453
534
|
var offset2 = options?.offset ?? 0;
|
|
454
535
|
var limit2 = options?.limit ?? 0;
|
|
455
536
|
var sliced2 = limit2 > 0 ? summaries.slice(offset2, offset2 + limit2) : summaries;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cryptiklemur/lattice",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
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>",
|