@cryptiklemur/lattice 1.42.1 → 1.42.2
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/client/src/components/analytics/QuickStats.tsx +5 -5
- package/client/src/components/chat/ChatView.tsx +9 -9
- package/client/src/components/settings/GlobalPlugins.tsx +3 -2
- package/client/src/components/settings/GlobalSkills.tsx +3 -2
- package/client/src/components/settings/MeshStatus.tsx +5 -4
- package/client/src/components/settings/SettingsView.tsx +1 -1
- package/client/src/components/sidebar/ProjectRail.tsx +23 -19
- package/client/src/components/sidebar/SessionList.tsx +9 -2
- package/client/src/components/sidebar/SettingsSidebar.tsx +25 -28
- package/client/src/components/sidebar/Sidebar.tsx +14 -14
- package/client/src/components/sidebar/UserIsland.tsx +2 -2
- package/package.json +1 -1
|
@@ -38,7 +38,7 @@ export function QuickStats() {
|
|
|
38
38
|
<div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
|
|
39
39
|
{[0, 1, 2, 3].map(function (i) {
|
|
40
40
|
return (
|
|
41
|
-
<div key={i} className="bg-base-content/[0.03]
|
|
41
|
+
<div key={i} className="bg-base-content/[0.03] rounded-xl p-3.5 animate-pulse">
|
|
42
42
|
<div className="h-2.5 w-16 bg-base-content/10 rounded mb-3" />
|
|
43
43
|
<div className="h-6 w-12 bg-base-content/10 rounded" />
|
|
44
44
|
</div>
|
|
@@ -60,7 +60,7 @@ export function QuickStats() {
|
|
|
60
60
|
|
|
61
61
|
return (
|
|
62
62
|
<div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
|
|
63
|
-
<div className="bg-base-content/[0.03]
|
|
63
|
+
<div className="bg-base-content/[0.03] rounded-xl p-3.5">
|
|
64
64
|
<div className="flex items-center justify-between mb-1">
|
|
65
65
|
<span className="text-[10px] font-mono font-bold uppercase tracking-wider text-base-content/40">Total Spend</span>
|
|
66
66
|
{costSparkData.length > 1 && (
|
|
@@ -72,7 +72,7 @@ export function QuickStats() {
|
|
|
72
72
|
<div className="text-[20px] font-mono text-base-content">${d.totalCost.toFixed(2)}</div>
|
|
73
73
|
</div>
|
|
74
74
|
|
|
75
|
-
<div className="bg-base-content/[0.03]
|
|
75
|
+
<div className="bg-base-content/[0.03] rounded-xl p-3.5">
|
|
76
76
|
<div className="flex items-center justify-between mb-1">
|
|
77
77
|
<span className="text-[10px] font-mono font-bold uppercase tracking-wider text-base-content/40">Sessions</span>
|
|
78
78
|
{sessionsSparkData.length > 1 && (
|
|
@@ -84,7 +84,7 @@ export function QuickStats() {
|
|
|
84
84
|
<div className="text-[20px] font-mono text-base-content">{d.totalSessions}</div>
|
|
85
85
|
</div>
|
|
86
86
|
|
|
87
|
-
<div className="bg-base-content/[0.03]
|
|
87
|
+
<div className="bg-base-content/[0.03] rounded-xl p-3.5">
|
|
88
88
|
<div className="flex items-center justify-between mb-1">
|
|
89
89
|
<span className="text-[10px] font-mono font-bold uppercase tracking-wider text-base-content/40">Total Tokens</span>
|
|
90
90
|
{tokensSparkData.length > 1 && (
|
|
@@ -96,7 +96,7 @@ export function QuickStats() {
|
|
|
96
96
|
<div className="text-[20px] font-mono text-base-content">{formatTokens(totalTokens)}</div>
|
|
97
97
|
</div>
|
|
98
98
|
|
|
99
|
-
<div className="bg-base-content/[0.03]
|
|
99
|
+
<div className="bg-base-content/[0.03] rounded-xl p-3.5">
|
|
100
100
|
<div className="mb-1">
|
|
101
101
|
<span className="text-[10px] font-mono font-bold uppercase tracking-wider text-base-content/40">Cache Rate</span>
|
|
102
102
|
</div>
|
|
@@ -755,22 +755,22 @@ export function ChatView({ sessionId: tabSessionId, projectSlug: tabProjectSlug
|
|
|
755
755
|
) : messages.length === 0 ? (
|
|
756
756
|
<div className="flex items-center justify-center p-10 h-full">
|
|
757
757
|
<div className="text-center max-w-[360px]">
|
|
758
|
-
<div className="text-
|
|
759
|
-
<LatticeLogomark size={
|
|
758
|
+
<div className="text-base-content/10 mb-4 flex justify-center">
|
|
759
|
+
<LatticeLogomark size={40} />
|
|
760
760
|
</div>
|
|
761
|
-
<p className="text-[
|
|
761
|
+
<p className="text-[15px] font-mono font-semibold text-base-content/60 mb-1.5">
|
|
762
762
|
{activeSessionId
|
|
763
|
-
? "
|
|
763
|
+
? "What are you working on?"
|
|
764
764
|
: activeProject
|
|
765
|
-
? "
|
|
765
|
+
? "Ready when you are"
|
|
766
766
|
: "Select a project"}
|
|
767
767
|
</p>
|
|
768
|
-
<p className="text-[
|
|
768
|
+
<p className="text-[12px] text-base-content/30 leading-relaxed">
|
|
769
769
|
{activeSessionId
|
|
770
|
-
? "Type a message below
|
|
770
|
+
? "Type a message below or press / for commands."
|
|
771
771
|
: activeProject
|
|
772
|
-
? "
|
|
773
|
-
: "Choose a project from the
|
|
772
|
+
? "Start a new session from the sidebar to chat with Claude."
|
|
773
|
+
: "Choose a project from the rail to get started."}
|
|
774
774
|
</p>
|
|
775
775
|
</div>
|
|
776
776
|
</div>
|
|
@@ -251,8 +251,9 @@ function InstalledPlugins({
|
|
|
251
251
|
<div>
|
|
252
252
|
<div className="text-[12px] font-semibold text-base-content/40 mb-2">Installed Plugins</div>
|
|
253
253
|
{plugins.length === 0 ? (
|
|
254
|
-
<div className="py-6 text-center
|
|
255
|
-
No plugins installed
|
|
254
|
+
<div className="py-6 text-center">
|
|
255
|
+
<div className="text-[12px] text-base-content/30 mb-0.5">No plugins installed</div>
|
|
256
|
+
<div className="text-[11px] text-base-content/20">Browse the marketplace or search below to add plugins.</div>
|
|
256
257
|
</div>
|
|
257
258
|
) : (
|
|
258
259
|
<div className="space-y-2">
|
|
@@ -94,8 +94,9 @@ export function GlobalSkills() {
|
|
|
94
94
|
<div>
|
|
95
95
|
<div className="text-[12px] font-semibold text-base-content/40 mb-2">Installed Skills</div>
|
|
96
96
|
{skills.length === 0 ? (
|
|
97
|
-
<div className="py-4 text-center
|
|
98
|
-
No
|
|
97
|
+
<div className="py-4 text-center">
|
|
98
|
+
<div className="text-[12px] text-base-content/30 mb-0.5">No skills installed</div>
|
|
99
|
+
<div className="text-[11px] text-base-content/20">Search the marketplace below to add skills.</div>
|
|
99
100
|
</div>
|
|
100
101
|
) : (
|
|
101
102
|
<div className="space-y-2">
|
|
@@ -135,8 +135,8 @@ export function MeshStatus() {
|
|
|
135
135
|
{localNode ? (
|
|
136
136
|
<NodeRow node={localNode} onUnpair={handleUnpair} onReconnect={handleReconnect} />
|
|
137
137
|
) : (
|
|
138
|
-
<div className="text-[12px] text-base-content/
|
|
139
|
-
|
|
138
|
+
<div className="text-[12px] text-base-content/30">
|
|
139
|
+
Loading node information...
|
|
140
140
|
</div>
|
|
141
141
|
)}
|
|
142
142
|
</div>
|
|
@@ -156,8 +156,9 @@ export function MeshStatus() {
|
|
|
156
156
|
</div>
|
|
157
157
|
|
|
158
158
|
{remoteNodes.length === 0 ? (
|
|
159
|
-
<div className="p-4 rounded-lg border border-dashed border-base-content/
|
|
160
|
-
No paired nodes
|
|
159
|
+
<div className="p-4 rounded-lg border border-dashed border-base-content/10 text-center">
|
|
160
|
+
<div className="text-[12px] text-base-content/30 mb-0.5">No paired nodes</div>
|
|
161
|
+
<div className="text-[11px] text-base-content/20">Connect another machine to view its projects and sessions here.</div>
|
|
161
162
|
</div>
|
|
162
163
|
) : (
|
|
163
164
|
remoteNodes.map(function (node) {
|
|
@@ -17,7 +17,7 @@ import type { SettingsSection } from "../../stores/sidebar";
|
|
|
17
17
|
var SECTION_CONFIG: Record<string, { title: string }> = {
|
|
18
18
|
appearance: { title: "Appearance" },
|
|
19
19
|
notifications: { title: "Notifications" },
|
|
20
|
-
claude: { title: "Claude
|
|
20
|
+
claude: { title: "Claude" },
|
|
21
21
|
budget: { title: "Budget" },
|
|
22
22
|
environment: { title: "Environment" },
|
|
23
23
|
mcp: { title: "MCP Servers" },
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useState, useEffect, useRef } from "react";
|
|
2
|
+
import { createPortal } from "react-dom";
|
|
2
3
|
import { Plus } from "lucide-react";
|
|
3
4
|
import type { ProjectInfo, NodeInfo } from "@lattice/shared";
|
|
4
5
|
import { LatticeLogomark } from "../ui/LatticeLogomark";
|
|
@@ -88,17 +89,17 @@ function ProjectButton(props: ProjectButtonProps) {
|
|
|
88
89
|
className={
|
|
89
90
|
"w-[42px] h-[42px] flex items-center justify-center text-[11px] font-bold tracking-[0.03em] cursor-pointer transition-all duration-[120ms] flex-shrink-0 " +
|
|
90
91
|
(props.isActive
|
|
91
|
-
? "rounded-xl bg-
|
|
92
|
+
? "rounded-xl bg-base-content/10 text-base-content ring-1 ring-base-content/20"
|
|
92
93
|
: hovered
|
|
93
94
|
? "rounded-xl bg-base-200 text-base-content/60"
|
|
94
|
-
: "rounded-full bg-base-200 text-base-content/
|
|
95
|
+
: "rounded-full bg-base-200 text-base-content/40")
|
|
95
96
|
}
|
|
96
97
|
>
|
|
97
98
|
{initials}
|
|
98
99
|
</button>
|
|
99
100
|
|
|
100
101
|
{props.group.activeSessions > 0 && (
|
|
101
|
-
<div className="absolute -top-
|
|
102
|
+
<div className="absolute -top-0.5 -right-0.5 min-w-[14px] h-[14px] rounded-full bg-success/80 text-success-content text-[8px] font-bold flex items-center justify-center pointer-events-none px-0.5">
|
|
102
103
|
{props.group.activeSessions}
|
|
103
104
|
</div>
|
|
104
105
|
)}
|
|
@@ -109,17 +110,17 @@ function ProjectButton(props: ProjectButtonProps) {
|
|
|
109
110
|
<div
|
|
110
111
|
key={n.nodeId}
|
|
111
112
|
className={
|
|
112
|
-
"w-[
|
|
113
|
-
(n.online ? "bg-success" : "bg-
|
|
113
|
+
"w-[8px] h-[8px] rounded-full border border-base-100 " +
|
|
114
|
+
(n.online ? "bg-success/70" : "bg-base-content/20")
|
|
114
115
|
}
|
|
115
116
|
/>
|
|
116
117
|
);
|
|
117
118
|
})}
|
|
118
119
|
</div>
|
|
119
120
|
|
|
120
|
-
{hovered && (
|
|
121
|
+
{hovered && createPortal(
|
|
121
122
|
<div
|
|
122
|
-
className="pointer-events-none z-[
|
|
123
|
+
className="pointer-events-none z-[99999] bg-base-300 border border-base-content/20 rounded-lg px-2.5 py-1.5 shadow-xl"
|
|
123
124
|
style={{
|
|
124
125
|
position: "fixed",
|
|
125
126
|
left: "calc(64px + 8px)",
|
|
@@ -139,7 +140,8 @@ function ProjectButton(props: ProjectButtonProps) {
|
|
|
139
140
|
</div>
|
|
140
141
|
);
|
|
141
142
|
})}
|
|
142
|
-
</div
|
|
143
|
+
</div>,
|
|
144
|
+
document.body
|
|
143
145
|
)}
|
|
144
146
|
</div>
|
|
145
147
|
);
|
|
@@ -162,17 +164,17 @@ function NodeIndicator({ node }: { node: NodeInfo }) {
|
|
|
162
164
|
}}
|
|
163
165
|
onMouseLeave={function () { setHovered(false); }}
|
|
164
166
|
className={
|
|
165
|
-
"w-[
|
|
167
|
+
"w-[26px] h-[26px] flex items-center justify-center text-[9px] font-semibold rounded-full cursor-pointer transition-all duration-[120ms] flex-shrink-0 border " +
|
|
166
168
|
(node.online
|
|
167
|
-
? "border-success/
|
|
168
|
-
: "border-
|
|
169
|
+
? "border-success/30 bg-base-200/60 text-base-content/40 hover:bg-base-200"
|
|
170
|
+
: "border-base-content/10 bg-base-200/30 text-base-content/20 hover:bg-base-200/40")
|
|
169
171
|
}
|
|
170
172
|
>
|
|
171
173
|
{initial}
|
|
172
174
|
</button>
|
|
173
|
-
{hovered && (
|
|
175
|
+
{hovered && createPortal(
|
|
174
176
|
<div
|
|
175
|
-
className="pointer-events-none z-[
|
|
177
|
+
className="pointer-events-none z-[99999] bg-base-300 border border-base-content/20 rounded-lg px-2.5 py-1.5 shadow-xl"
|
|
176
178
|
style={{
|
|
177
179
|
position: "fixed",
|
|
178
180
|
left: "calc(64px + 8px)",
|
|
@@ -192,7 +194,8 @@ function NodeIndicator({ node }: { node: NodeInfo }) {
|
|
|
192
194
|
<div className="text-[10px] text-base-content/30 mt-0.5">
|
|
193
195
|
{node.projects.length} project{node.projects.length !== 1 ? "s" : ""}
|
|
194
196
|
</div>
|
|
195
|
-
</div
|
|
197
|
+
</div>,
|
|
198
|
+
document.body
|
|
196
199
|
)}
|
|
197
200
|
</div>
|
|
198
201
|
);
|
|
@@ -283,8 +286,8 @@ export function ProjectRail(props: ProjectRailProps) {
|
|
|
283
286
|
className={
|
|
284
287
|
"relative w-[42px] h-[42px] flex items-center justify-center cursor-pointer transition-all duration-[120ms] flex-shrink-0 " +
|
|
285
288
|
(props.isDashboardActive
|
|
286
|
-
? "rounded-xl bg-
|
|
287
|
-
: "rounded-full bg-base-200 text-base-content/
|
|
289
|
+
? "rounded-xl bg-base-content/10 text-base-content ring-1 ring-base-content/20"
|
|
290
|
+
: "rounded-full bg-base-200 text-base-content/40 hover:rounded-xl hover:bg-base-200 hover:text-base-content/60")
|
|
288
291
|
}
|
|
289
292
|
title="Lattice Dashboard"
|
|
290
293
|
>
|
|
@@ -339,13 +342,13 @@ export function ProjectRail(props: ProjectRailProps) {
|
|
|
339
342
|
|
|
340
343
|
<div className="flex-1" />
|
|
341
344
|
|
|
342
|
-
{contextMenu.visible && (
|
|
345
|
+
{contextMenu.visible && createPortal(
|
|
343
346
|
<div
|
|
344
347
|
ref={menuRef}
|
|
345
348
|
role="menu"
|
|
346
349
|
aria-label="Project actions"
|
|
347
350
|
onClick={function (e) { e.stopPropagation(); }}
|
|
348
|
-
className="fixed z-[
|
|
351
|
+
className="fixed z-[99999] bg-base-300 border border-base-content/20 rounded-lg shadow-2xl py-1 min-w-[160px]"
|
|
349
352
|
style={{ left: contextMenu.x + "px", top: contextMenu.y + "px" }}
|
|
350
353
|
>
|
|
351
354
|
<button
|
|
@@ -387,7 +390,8 @@ export function ProjectRail(props: ProjectRailProps) {
|
|
|
387
390
|
>
|
|
388
391
|
Remove Project
|
|
389
392
|
</button>
|
|
390
|
-
</div
|
|
393
|
+
</div>,
|
|
394
|
+
document.body
|
|
391
395
|
)}
|
|
392
396
|
|
|
393
397
|
</div>
|
|
@@ -475,8 +475,15 @@ export function SessionList(props: SessionListProps) {
|
|
|
475
475
|
<div className="flex flex-col flex-1 overflow-hidden min-h-0">
|
|
476
476
|
<div ref={scrollContainerRef} className="flex-1 overflow-y-auto overflow-x-hidden scrollbar-hidden py-0.5 pb-16">
|
|
477
477
|
{grouped.length === 0 ? (
|
|
478
|
-
<div className="px-
|
|
479
|
-
{props.filter ?
|
|
478
|
+
<div className="px-4 py-6 text-center">
|
|
479
|
+
{props.filter ? (
|
|
480
|
+
<div className="text-[12px] text-base-content/30">No sessions match your search</div>
|
|
481
|
+
) : (
|
|
482
|
+
<>
|
|
483
|
+
<div className="text-[12px] text-base-content/30 mb-1">No sessions yet</div>
|
|
484
|
+
<div className="text-[11px] text-base-content/20">Click + above to start a conversation with Claude</div>
|
|
485
|
+
</>
|
|
486
|
+
)}
|
|
480
487
|
</div>
|
|
481
488
|
) : (
|
|
482
489
|
grouped.map(function (group) {
|
|
@@ -9,29 +9,29 @@ interface SettingsSidebarProps {
|
|
|
9
9
|
|
|
10
10
|
var SETTINGS_NAV = [
|
|
11
11
|
{
|
|
12
|
-
group: "
|
|
12
|
+
group: "",
|
|
13
13
|
items: [
|
|
14
14
|
{ id: "appearance" as SettingsSection, label: "Appearance", icon: <Palette size={14} /> },
|
|
15
15
|
{ id: "notifications" as SettingsSection, label: "Notifications", icon: <Bell size={14} /> },
|
|
16
|
-
{ id: "claude" as SettingsSection, label: "Claude Settings", icon: <FileText size={14} /> },
|
|
17
|
-
{ id: "budget" as SettingsSection, label: "Budget", icon: <Wallet size={14} /> },
|
|
18
|
-
{ id: "environment" as SettingsSection, label: "Environment", icon: <Terminal size={14} /> },
|
|
19
|
-
{ id: "editor" as SettingsSection, label: "Editor", icon: <MonitorCog size={14} /> },
|
|
20
16
|
],
|
|
21
17
|
},
|
|
22
18
|
{
|
|
23
|
-
group: "
|
|
19
|
+
group: "CLAUDE",
|
|
24
20
|
items: [
|
|
25
|
-
{ id: "
|
|
26
|
-
{ id: "
|
|
21
|
+
{ id: "claude" as SettingsSection, label: "Model & Prompts", icon: <FileText size={14} /> },
|
|
22
|
+
{ id: "budget" as SettingsSection, label: "Budget", icon: <Wallet size={14} /> },
|
|
23
|
+
{ id: "environment" as SettingsSection, label: "Environment", icon: <Terminal size={14} /> },
|
|
24
|
+
{ id: "editor" as SettingsSection, label: "Editor", icon: <MonitorCog size={14} /> },
|
|
27
25
|
],
|
|
28
26
|
},
|
|
29
27
|
{
|
|
30
|
-
group: "
|
|
28
|
+
group: "EXTENSIONS",
|
|
31
29
|
items: [
|
|
32
|
-
{ id: "mcp" as SettingsSection, label: "MCP Servers", icon: <Plug size={14} /> },
|
|
33
|
-
{ id: "skills" as SettingsSection, label: "Skills", icon: <Puzzle size={14} /> },
|
|
34
30
|
{ id: "plugins" as SettingsSection, label: "Plugins", icon: <Blocks size={14} /> },
|
|
31
|
+
{ id: "skills" as SettingsSection, label: "Skills", icon: <Puzzle size={14} /> },
|
|
32
|
+
{ id: "mcp" as SettingsSection, label: "MCP Servers", icon: <Plug size={14} /> },
|
|
33
|
+
{ id: "rules" as SettingsSection, label: "Rules", icon: <ScrollText size={14} /> },
|
|
34
|
+
{ id: "memory" as SettingsSection, label: "Memory", icon: <Brain size={14} /> },
|
|
35
35
|
],
|
|
36
36
|
},
|
|
37
37
|
{
|
|
@@ -44,7 +44,7 @@ var SETTINGS_NAV = [
|
|
|
44
44
|
|
|
45
45
|
var PROJECT_SETTINGS_NAV = [
|
|
46
46
|
{
|
|
47
|
-
group: "
|
|
47
|
+
group: "",
|
|
48
48
|
items: [
|
|
49
49
|
{ id: "general" as ProjectSettingsSection, label: "General", icon: <Settings size={14} /> },
|
|
50
50
|
{ id: "notifications" as ProjectSettingsSection, label: "Notifications", icon: <Bell size={14} /> },
|
|
@@ -53,16 +53,11 @@ var PROJECT_SETTINGS_NAV = [
|
|
|
53
53
|
],
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
|
-
group: "
|
|
56
|
+
group: "EXTENSIONS",
|
|
57
57
|
items: [
|
|
58
|
-
{ id: "mcp" as ProjectSettingsSection, label: "MCP Servers", icon: <Plug size={14} /> },
|
|
59
|
-
{ id: "skills" as ProjectSettingsSection, label: "Skills", icon: <Puzzle size={14} /> },
|
|
60
58
|
{ id: "plugins" as ProjectSettingsSection, label: "Plugins", icon: <Blocks size={14} /> },
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
{
|
|
64
|
-
group: "CONFIGURATION",
|
|
65
|
-
items: [
|
|
59
|
+
{ id: "skills" as ProjectSettingsSection, label: "Skills", icon: <Puzzle size={14} /> },
|
|
60
|
+
{ id: "mcp" as ProjectSettingsSection, label: "MCP Servers", icon: <Plug size={14} /> },
|
|
66
61
|
{ id: "rules" as ProjectSettingsSection, label: "Rules", icon: <ScrollText size={14} /> },
|
|
67
62
|
{ id: "permissions" as ProjectSettingsSection, label: "Permissions", icon: <Shield size={14} /> },
|
|
68
63
|
{ id: "memory" as ProjectSettingsSection, label: "Memory", icon: <Brain size={14} /> },
|
|
@@ -92,19 +87,21 @@ export function SettingsSidebar({ projectName, onBack }: SettingsSidebarProps) {
|
|
|
92
87
|
|
|
93
88
|
return (
|
|
94
89
|
<div className="flex flex-col h-full w-full overflow-hidden bg-base-200">
|
|
95
|
-
<div className="px-4 h-
|
|
90
|
+
<div className="px-4 h-12 border-b border-base-300 flex-shrink-0 flex items-center">
|
|
96
91
|
<span className="text-[13px] font-mono font-bold text-base-content">{headerLabel}</span>
|
|
97
92
|
</div>
|
|
98
93
|
|
|
99
94
|
<div className="flex flex-col flex-1 overflow-y-auto min-h-0 py-2 pb-16">
|
|
100
95
|
{nav.map(function (group) {
|
|
101
96
|
return (
|
|
102
|
-
<div key={group.group} className="mb-2">
|
|
103
|
-
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
97
|
+
<div key={group.group || "ungrouped"} className="mb-2">
|
|
98
|
+
{group.group && (
|
|
99
|
+
<div className="px-4 pt-3 pb-1">
|
|
100
|
+
<span className="text-[10px] font-bold tracking-wider uppercase text-base-content/40">
|
|
101
|
+
{group.group}
|
|
102
|
+
</span>
|
|
103
|
+
</div>
|
|
104
|
+
)}
|
|
108
105
|
{group.items.map(function (item) {
|
|
109
106
|
var isActive = activeSection === item.id;
|
|
110
107
|
return (
|
|
@@ -114,7 +111,7 @@ export function SettingsSidebar({ projectName, onBack }: SettingsSidebarProps) {
|
|
|
114
111
|
className={
|
|
115
112
|
"w-full flex items-center gap-2.5 px-4 py-2.5 sm:py-1.5 text-[13px] transition-colors duration-[100ms] text-left " +
|
|
116
113
|
(isActive
|
|
117
|
-
? "bg-
|
|
114
|
+
? "bg-base-content/8 text-base-content font-medium"
|
|
118
115
|
: "text-base-content/55 hover:bg-base-content/5 hover:text-base-content")
|
|
119
116
|
}
|
|
120
117
|
>
|
|
@@ -261,7 +261,7 @@ export function Sidebar({ onSessionSelect }: { onSessionSelect?: () => void }) {
|
|
|
261
261
|
<>
|
|
262
262
|
{sidebar.activeView.type === "dashboard" ? (
|
|
263
263
|
<>
|
|
264
|
-
<div className="px-4 h-
|
|
264
|
+
<div className="px-4 h-12 border-b border-base-300 flex-shrink-0 flex items-center gap-2">
|
|
265
265
|
<LatticeLogomark size={18} />
|
|
266
266
|
<span className="text-[13px] font-mono font-bold text-base-content/90">
|
|
267
267
|
Lattice
|
|
@@ -315,12 +315,12 @@ export function Sidebar({ onSessionSelect }: { onSessionSelect?: () => void }) {
|
|
|
315
315
|
</div>
|
|
316
316
|
<SectionLabel label="Projects" />
|
|
317
317
|
{projects.length === 0 && nodes.some(function (n) { return !n.isLocal && n.online; }) ? (
|
|
318
|
-
<div className="flex items-center gap-2 text-[12px] text-base-content/
|
|
319
|
-
<span className="w-
|
|
320
|
-
|
|
318
|
+
<div className="flex items-center gap-2 text-[12px] text-base-content/25 px-4">
|
|
319
|
+
<span className="w-1.5 h-1.5 rounded-full bg-base-content/30 animate-pulse flex-shrink-0" />
|
|
320
|
+
Syncing remote projects...
|
|
321
321
|
</div>
|
|
322
322
|
) : (
|
|
323
|
-
<div className="text-[12px] text-base-content/
|
|
323
|
+
<div className="text-[12px] text-base-content/25 px-4">
|
|
324
324
|
Select a project from the rail to view sessions.
|
|
325
325
|
</div>
|
|
326
326
|
)}
|
|
@@ -334,17 +334,19 @@ export function Sidebar({ onSessionSelect }: { onSessionSelect?: () => void }) {
|
|
|
334
334
|
onClick={sidebar.toggleProjectDropdown}
|
|
335
335
|
aria-label="Switch project"
|
|
336
336
|
aria-expanded={sidebar.projectDropdownOpen}
|
|
337
|
-
className="w-full px-4
|
|
337
|
+
className={"w-full px-4 border-b border-base-300 flex-shrink-0 flex items-center justify-between cursor-pointer hover:bg-base-300/30 transition-colors text-left " + (activeProject?.isRemote ? "h-14 py-2" : "h-12 py-2.5")}
|
|
338
338
|
>
|
|
339
|
-
<
|
|
340
|
-
|
|
339
|
+
<div className="min-w-0">
|
|
340
|
+
<div className="text-[13px] font-mono font-bold text-base-content/90 truncate">
|
|
341
|
+
{activeProject?.title ?? (projects.length === 0 ? "Loading..." : "No Project")}
|
|
342
|
+
</div>
|
|
341
343
|
{activeProject?.isRemote && (
|
|
342
|
-
<
|
|
344
|
+
<div className="text-[10px] text-base-content/30 font-mono">
|
|
343
345
|
on {activeProject.nodeName}
|
|
344
|
-
</
|
|
346
|
+
</div>
|
|
345
347
|
)}
|
|
346
|
-
</
|
|
347
|
-
<ChevronDown size={14} className="text-base-content/30" />
|
|
348
|
+
</div>
|
|
349
|
+
<ChevronDown size={14} className="text-base-content/30 flex-shrink-0" />
|
|
348
350
|
</button>
|
|
349
351
|
|
|
350
352
|
<button
|
|
@@ -361,8 +363,6 @@ export function Sidebar({ onSessionSelect }: { onSessionSelect?: () => void }) {
|
|
|
361
363
|
{ type: "files" as const, icon: FolderOpen, label: "Files", localOnly: true },
|
|
362
364
|
{ type: "terminal" as const, icon: TerminalSquare, label: "Terminal", localOnly: true },
|
|
363
365
|
{ type: "notes" as const, icon: StickyNote, label: "Notes", localOnly: false },
|
|
364
|
-
{ type: "tasks" as const, icon: Calendar, label: "Tasks", localOnly: false },
|
|
365
|
-
{ type: "bookmarks" as const, icon: Bookmark, label: "Bookmarks", localOnly: false },
|
|
366
366
|
].map(function (item) {
|
|
367
367
|
var isDisabled = item.localOnly && activeProject?.isRemote;
|
|
368
368
|
return (
|
|
@@ -86,7 +86,7 @@ export function UserIsland(props: UserIslandProps) {
|
|
|
86
86
|
className="flex items-center gap-2 flex-1 min-w-0 rounded-lg px-1 py-1 -mx-1 hover:bg-base-content/5 transition-colors duration-[120ms] cursor-pointer"
|
|
87
87
|
aria-label="Node info"
|
|
88
88
|
>
|
|
89
|
-
<div className="w-7 h-7 rounded-full bg-
|
|
89
|
+
<div className="w-7 h-7 rounded-full bg-base-content/10 text-base-content/50 text-[12px] font-bold flex items-center justify-center flex-shrink-0">
|
|
90
90
|
{initial}
|
|
91
91
|
</div>
|
|
92
92
|
<div className="flex-1 min-w-0 text-left">
|
|
@@ -96,7 +96,7 @@ export function UserIsland(props: UserIslandProps) {
|
|
|
96
96
|
<div className="text-[10px] font-mono flex items-center gap-1">
|
|
97
97
|
<span className="text-base-content/30">{"v" + currentVersion}</span>
|
|
98
98
|
{updateAvailable && latestVersion && (
|
|
99
|
-
<span className="flex items-center gap-0.5 text-
|
|
99
|
+
<span className="flex items-center gap-0.5 text-base-content/30">
|
|
100
100
|
<ArrowUpCircle size={9} />
|
|
101
101
|
{latestVersion}
|
|
102
102
|
</span>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cryptiklemur/lattice",
|
|
3
|
-
"version": "1.42.
|
|
3
|
+
"version": "1.42.2",
|
|
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>",
|