@cryptiklemur/lattice 1.24.6 → 1.25.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.
|
@@ -2,7 +2,7 @@ import { Store } from "@tanstack/react-store";
|
|
|
2
2
|
import type { ProjectSettingsSection } from "@lattice/shared";
|
|
3
3
|
import { encodeWorkspaceUrl, decodeWorkspaceUrl, isLegacySessionUrl, shortSessionId } from "../lib/workspace-url";
|
|
4
4
|
import type { DecodedWorkspace } from "../lib/workspace-url";
|
|
5
|
-
import { getWorkspaceStore, restoreWorkspace, setUrlSyncCallback } from "./workspace";
|
|
5
|
+
import { getWorkspaceStore, restoreWorkspace, setUrlSyncCallback, switchProjectWorkspace, setCurrentProjectKey } from "./workspace";
|
|
6
6
|
|
|
7
7
|
export type { ProjectSettingsSection };
|
|
8
8
|
|
|
@@ -106,6 +106,7 @@ function parseInitialUrl(): ParsedUrl {
|
|
|
106
106
|
|
|
107
107
|
const initialUrl = parseInitialUrl();
|
|
108
108
|
|
|
109
|
+
setCurrentProjectKey(initialUrl.settingsSection ? null : initialUrl.projectSlug);
|
|
109
110
|
if (initialUrl.decodedWorkspace) {
|
|
110
111
|
restoreWorkspace(initialUrl.decodedWorkspace);
|
|
111
112
|
}
|
|
@@ -196,6 +197,7 @@ export function getSidebarStore(): Store<SidebarState> {
|
|
|
196
197
|
}
|
|
197
198
|
|
|
198
199
|
export function setActiveProjectSlug(slug: string | null): void {
|
|
200
|
+
let prevSlug = sidebarStore.state.activeProjectSlug;
|
|
199
201
|
sidebarStore.setState(function (state) {
|
|
200
202
|
return {
|
|
201
203
|
...state,
|
|
@@ -215,6 +217,8 @@ export function setActiveProjectSlug(slug: string | null): void {
|
|
|
215
217
|
window.history.pushState(null, "", path);
|
|
216
218
|
}
|
|
217
219
|
lastEncodedUrl = "";
|
|
220
|
+
// Switch workspace AFTER sidebar state is set so React sees both in same render
|
|
221
|
+
switchProjectWorkspace(prevSlug, slug);
|
|
218
222
|
}
|
|
219
223
|
|
|
220
224
|
export function setActiveSessionId(sessionId: string | null): void {
|
|
@@ -340,6 +344,7 @@ export function goToProjectDashboard(): void {
|
|
|
340
344
|
}
|
|
341
345
|
|
|
342
346
|
export function goToDashboard(): void {
|
|
347
|
+
let prevSlug = sidebarStore.state.activeProjectSlug;
|
|
343
348
|
sidebarStore.setState(function (state) {
|
|
344
349
|
return {
|
|
345
350
|
...state,
|
|
@@ -354,6 +359,7 @@ export function goToDashboard(): void {
|
|
|
354
359
|
if (window.location.pathname + window.location.search !== "/") {
|
|
355
360
|
window.history.pushState(null, "", "/");
|
|
356
361
|
}
|
|
362
|
+
switchProjectWorkspace(prevSlug, null);
|
|
357
363
|
lastEncodedUrl = "";
|
|
358
364
|
}
|
|
359
365
|
|
|
@@ -416,6 +416,82 @@ export function restoreWorkspace(data: DecodedWorkspace): void {
|
|
|
416
416
|
urlSyncSuppressed = false;
|
|
417
417
|
}
|
|
418
418
|
|
|
419
|
+
var currentProjectKey: string = "__global__";
|
|
420
|
+
|
|
421
|
+
export function setCurrentProjectKey(slug: string | null): void {
|
|
422
|
+
currentProjectKey = slug || "__global__";
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function storageKey(projectSlug: string | null): string {
|
|
426
|
+
return "lattice:workspace:" + (projectSlug || "__global__");
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
export function saveWorkspaceForProject(projectSlug: string | null): void {
|
|
430
|
+
let key = storageKey(projectSlug);
|
|
431
|
+
let state = workspaceStore.state;
|
|
432
|
+
try {
|
|
433
|
+
localStorage.setItem(key, JSON.stringify({
|
|
434
|
+
tabs: state.tabs,
|
|
435
|
+
panes: state.panes,
|
|
436
|
+
activePaneId: state.activePaneId,
|
|
437
|
+
splitDirection: state.splitDirection,
|
|
438
|
+
splitRatio: state.splitRatio,
|
|
439
|
+
}));
|
|
440
|
+
} catch {}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
export function loadWorkspaceForProject(projectSlug: string | null): void {
|
|
444
|
+
let key = storageKey(projectSlug);
|
|
445
|
+
currentProjectKey = projectSlug || "__global__";
|
|
446
|
+
|
|
447
|
+
try {
|
|
448
|
+
let raw = localStorage.getItem(key);
|
|
449
|
+
if (raw) {
|
|
450
|
+
let saved = JSON.parse(raw) as WorkspaceState;
|
|
451
|
+
if (saved.tabs && saved.panes && saved.tabs.length > 0 && saved.panes.length > 0) {
|
|
452
|
+
urlSyncSuppressed = true;
|
|
453
|
+
workspaceStore.setState(function () {
|
|
454
|
+
return {
|
|
455
|
+
tabs: saved.tabs,
|
|
456
|
+
panes: saved.panes,
|
|
457
|
+
activePaneId: saved.activePaneId || saved.panes[0].id,
|
|
458
|
+
splitDirection: saved.splitDirection || null,
|
|
459
|
+
splitRatio: saved.splitRatio || 0.5,
|
|
460
|
+
};
|
|
461
|
+
});
|
|
462
|
+
urlSyncSuppressed = false;
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
} catch {}
|
|
467
|
+
|
|
468
|
+
urlSyncSuppressed = true;
|
|
469
|
+
workspaceStore.setState(function () {
|
|
470
|
+
return {
|
|
471
|
+
tabs: [{ id: "chat", type: "chat" as TabType, label: "Chat", closeable: false }],
|
|
472
|
+
panes: [{ id: "pane-1", tabIds: ["chat"], activeTabId: "chat" }],
|
|
473
|
+
activePaneId: "pane-1",
|
|
474
|
+
splitDirection: null,
|
|
475
|
+
splitRatio: 0.5,
|
|
476
|
+
};
|
|
477
|
+
});
|
|
478
|
+
urlSyncSuppressed = false;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
var saveSuppressed = false;
|
|
482
|
+
|
|
483
|
+
export function switchProjectWorkspace(fromSlug: string | null, toSlug: string | null): void {
|
|
484
|
+
saveSuppressed = true;
|
|
485
|
+
saveWorkspaceForProject(fromSlug);
|
|
486
|
+
loadWorkspaceForProject(toSlug);
|
|
487
|
+
saveSuppressed = false;
|
|
488
|
+
}
|
|
489
|
+
|
|
419
490
|
workspaceStore.subscribe(function () {
|
|
420
491
|
notifyUrlSync();
|
|
492
|
+
if (!saveSuppressed) {
|
|
493
|
+
try {
|
|
494
|
+
saveWorkspaceForProject(currentProjectKey === "__global__" ? null : currentProjectKey);
|
|
495
|
+
} catch {}
|
|
496
|
+
}
|
|
421
497
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cryptiklemur/lattice",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.1",
|
|
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>",
|