@cryptiklemur/lattice 1.24.5 → 1.25.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.
|
@@ -419,7 +419,7 @@ export function ChatView({ sessionId: tabSessionId, projectSlug: tabProjectSlug
|
|
|
419
419
|
return (
|
|
420
420
|
<div className="flex flex-col h-full w-full bg-base-100 overflow-hidden relative">
|
|
421
421
|
<div className="bg-base-100 border-b border-base-300 flex-shrink-0 px-2 sm:px-4">
|
|
422
|
-
<div className="flex items-center
|
|
422
|
+
<div className="flex items-center h-11 gap-1.5">
|
|
423
423
|
<button
|
|
424
424
|
className="btn btn-ghost btn-sm btn-square lg:hidden"
|
|
425
425
|
aria-label="Toggle sidebar"
|
|
@@ -90,7 +90,7 @@ export function SettingsSidebar({ projectName, onBack }: SettingsSidebarProps) {
|
|
|
90
90
|
|
|
91
91
|
return (
|
|
92
92
|
<div className="flex flex-col h-full w-full overflow-hidden bg-base-200">
|
|
93
|
-
<div className="px-4
|
|
93
|
+
<div className="px-4 h-11 border-b border-base-300 flex-shrink-0 flex items-center">
|
|
94
94
|
<span className="text-[13px] font-mono font-bold text-base-content">{headerLabel}</span>
|
|
95
95
|
</div>
|
|
96
96
|
|
|
@@ -327,7 +327,7 @@ export function Sidebar({ onSessionSelect }: { onSessionSelect?: () => void }) {
|
|
|
327
327
|
onClick={sidebar.toggleProjectDropdown}
|
|
328
328
|
aria-label="Switch project"
|
|
329
329
|
aria-expanded={sidebar.projectDropdownOpen}
|
|
330
|
-
className="w-full px-4
|
|
330
|
+
className="w-full px-4 h-11 border-b border-base-300 flex-shrink-0 flex items-center justify-between cursor-pointer hover:bg-base-300/30 transition-colors text-left"
|
|
331
331
|
>
|
|
332
332
|
<span className="text-[13px] font-mono font-bold text-base-content/90">
|
|
333
333
|
{activeProject?.title ?? "No Project"}
|
|
@@ -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,8 @@ export function getSidebarStore(): Store<SidebarState> {
|
|
|
196
197
|
}
|
|
197
198
|
|
|
198
199
|
export function setActiveProjectSlug(slug: string | null): void {
|
|
200
|
+
let prevSlug = sidebarStore.state.activeProjectSlug;
|
|
201
|
+
switchProjectWorkspace(prevSlug, slug);
|
|
199
202
|
sidebarStore.setState(function (state) {
|
|
200
203
|
return {
|
|
201
204
|
...state,
|
|
@@ -416,6 +416,77 @@ 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
|
+
export function switchProjectWorkspace(fromSlug: string | null, toSlug: string | null): void {
|
|
482
|
+
saveWorkspaceForProject(fromSlug);
|
|
483
|
+
loadWorkspaceForProject(toSlug);
|
|
484
|
+
}
|
|
485
|
+
|
|
419
486
|
workspaceStore.subscribe(function () {
|
|
420
487
|
notifyUrlSync();
|
|
488
|
+
// Auto-save on every state change
|
|
489
|
+
try {
|
|
490
|
+
saveWorkspaceForProject(currentProjectKey === "__global__" ? null : currentProjectKey);
|
|
491
|
+
} catch {}
|
|
421
492
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cryptiklemur/lattice",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.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>",
|