@cryptiklemur/lattice 0.0.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/.editorconfig +12 -0
- package/.github/workflows/release.yml +44 -0
- package/.impeccable.md +66 -0
- package/.releaserc.json +32 -0
- package/.serena/project.yml +138 -0
- package/CLAUDE.md +35 -0
- package/CONTRIBUTING.md +93 -0
- package/LICENSE +21 -0
- package/README.md +83 -0
- package/bun.lock +1459 -0
- package/bunfig.toml +2 -0
- package/client/index.html +32 -0
- package/client/package.json +37 -0
- package/client/public/icons/icon-192.svg +11 -0
- package/client/public/icons/icon-512.svg +11 -0
- package/client/public/manifest.json +24 -0
- package/client/public/sw.js +61 -0
- package/client/src/App.tsx +28 -0
- package/client/src/components/auth/PassphrasePrompt.tsx +70 -0
- package/client/src/components/chat/ChatInput.tsx +241 -0
- package/client/src/components/chat/ChatView.tsx +727 -0
- package/client/src/components/chat/Message.tsx +362 -0
- package/client/src/components/chat/ModelSelector.tsx +87 -0
- package/client/src/components/chat/PermissionModeSelector.tsx +41 -0
- package/client/src/components/chat/StatusBar.tsx +50 -0
- package/client/src/components/chat/ToolGroup.tsx +129 -0
- package/client/src/components/chat/ToolResultRenderer.tsx +343 -0
- package/client/src/components/chat/toolSummary.ts +41 -0
- package/client/src/components/dashboard/DashboardView.tsx +219 -0
- package/client/src/components/dashboard/ProjectDashboardView.tsx +168 -0
- package/client/src/components/mesh/NodeBadge.tsx +24 -0
- package/client/src/components/mesh/PairingDialog.tsx +281 -0
- package/client/src/components/panels/FileBrowser.tsx +241 -0
- package/client/src/components/panels/StickyNotes.tsx +187 -0
- package/client/src/components/panels/Terminal.tsx +128 -0
- package/client/src/components/project-settings/ProjectClaude.tsx +304 -0
- package/client/src/components/project-settings/ProjectEnvironment.tsx +235 -0
- package/client/src/components/project-settings/ProjectGeneral.tsx +76 -0
- package/client/src/components/project-settings/ProjectMcp.tsx +232 -0
- package/client/src/components/project-settings/ProjectPermissions.tsx +209 -0
- package/client/src/components/project-settings/ProjectRules.tsx +277 -0
- package/client/src/components/project-settings/ProjectSettingsView.tsx +99 -0
- package/client/src/components/project-settings/ProjectSkills.tsx +91 -0
- package/client/src/components/settings/Appearance.tsx +151 -0
- package/client/src/components/settings/ClaudeSettings.tsx +151 -0
- package/client/src/components/settings/Environment.tsx +185 -0
- package/client/src/components/settings/GlobalMcp.tsx +207 -0
- package/client/src/components/settings/GlobalSkills.tsx +125 -0
- package/client/src/components/settings/MeshStatus.tsx +145 -0
- package/client/src/components/settings/SettingsView.tsx +57 -0
- package/client/src/components/settings/SkillMarketplace.tsx +175 -0
- package/client/src/components/settings/mcp-shared.tsx +194 -0
- package/client/src/components/settings/skill-shared.tsx +177 -0
- package/client/src/components/setup/SetupWizard.tsx +750 -0
- package/client/src/components/sidebar/NodeSettingsModal.tsx +180 -0
- package/client/src/components/sidebar/ProjectDropdown.tsx +43 -0
- package/client/src/components/sidebar/ProjectRail.tsx +291 -0
- package/client/src/components/sidebar/SearchFilter.tsx +52 -0
- package/client/src/components/sidebar/SessionList.tsx +384 -0
- package/client/src/components/sidebar/SettingsSidebar.tsx +128 -0
- package/client/src/components/sidebar/Sidebar.tsx +209 -0
- package/client/src/components/sidebar/UserIsland.tsx +59 -0
- package/client/src/components/sidebar/UserMenu.tsx +101 -0
- package/client/src/components/ui/CommandPalette.tsx +321 -0
- package/client/src/components/ui/ErrorBoundary.tsx +56 -0
- package/client/src/components/ui/IconPicker.tsx +209 -0
- package/client/src/components/ui/LatticeLogomark.tsx +19 -0
- package/client/src/components/ui/PopupMenu.tsx +98 -0
- package/client/src/components/ui/SaveFooter.tsx +38 -0
- package/client/src/components/ui/Toast.tsx +112 -0
- package/client/src/hooks/useMesh.ts +89 -0
- package/client/src/hooks/useProjectSettings.ts +56 -0
- package/client/src/hooks/useProjects.ts +66 -0
- package/client/src/hooks/useSaveState.ts +59 -0
- package/client/src/hooks/useSession.ts +317 -0
- package/client/src/hooks/useSidebar.ts +74 -0
- package/client/src/hooks/useSkills.ts +30 -0
- package/client/src/hooks/useTheme.ts +114 -0
- package/client/src/hooks/useWebSocket.ts +26 -0
- package/client/src/main.tsx +10 -0
- package/client/src/providers/WebSocketProvider.tsx +146 -0
- package/client/src/router.tsx +391 -0
- package/client/src/stores/mesh.ts +78 -0
- package/client/src/stores/session.ts +322 -0
- package/client/src/stores/sidebar.ts +336 -0
- package/client/src/stores/theme.ts +44 -0
- package/client/src/styles/global.css +167 -0
- package/client/src/styles/theme-vars.css +18 -0
- package/client/src/themes/index.ts +79 -0
- package/client/src/utils/findDuplicateKeys.ts +12 -0
- package/client/tsconfig.json +14 -0
- package/client/vite.config.ts +20 -0
- package/package.json +46 -0
- package/server/package.json +22 -0
- package/server/src/auth/passphrase.ts +48 -0
- package/server/src/config.ts +55 -0
- package/server/src/daemon.ts +338 -0
- package/server/src/features/ralph-loop.ts +173 -0
- package/server/src/features/scheduler.ts +281 -0
- package/server/src/features/sticky-notes.ts +102 -0
- package/server/src/handlers/chat.ts +194 -0
- package/server/src/handlers/fs.ts +84 -0
- package/server/src/handlers/loop.ts +37 -0
- package/server/src/handlers/mesh.ts +125 -0
- package/server/src/handlers/notes.ts +45 -0
- package/server/src/handlers/project-settings.ts +174 -0
- package/server/src/handlers/scheduler.ts +47 -0
- package/server/src/handlers/session.ts +159 -0
- package/server/src/handlers/settings.ts +109 -0
- package/server/src/handlers/skills.ts +380 -0
- package/server/src/handlers/terminal.ts +70 -0
- package/server/src/identity.ts +26 -0
- package/server/src/index.ts +190 -0
- package/server/src/mesh/connector.ts +209 -0
- package/server/src/mesh/discovery.ts +123 -0
- package/server/src/mesh/pairing.ts +94 -0
- package/server/src/mesh/peers.ts +52 -0
- package/server/src/mesh/proxy.ts +103 -0
- package/server/src/mesh/session-sync.ts +107 -0
- package/server/src/project/context-breakdown.ts +289 -0
- package/server/src/project/file-browser.ts +106 -0
- package/server/src/project/project-files.ts +267 -0
- package/server/src/project/registry.ts +57 -0
- package/server/src/project/sdk-bridge.ts +566 -0
- package/server/src/project/session.ts +432 -0
- package/server/src/project/terminal.ts +69 -0
- package/server/src/tls.ts +51 -0
- package/server/src/ws/broadcast.ts +31 -0
- package/server/src/ws/router.ts +104 -0
- package/server/src/ws/server.ts +2 -0
- package/server/tsconfig.json +16 -0
- package/shared/package.json +11 -0
- package/shared/src/constants.ts +7 -0
- package/shared/src/index.ts +4 -0
- package/shared/src/messages.ts +638 -0
- package/shared/src/models.ts +136 -0
- package/shared/src/project-settings.ts +45 -0
- package/shared/tsconfig.json +11 -0
- package/themes/amoled.json +20 -0
- package/themes/ayu-light.json +9 -0
- package/themes/catppuccin-latte.json +9 -0
- package/themes/catppuccin-mocha.json +9 -0
- package/themes/clay-light.json +10 -0
- package/themes/clay.json +10 -0
- package/themes/dracula.json +9 -0
- package/themes/everforest-light.json +9 -0
- package/themes/everforest.json +9 -0
- package/themes/github-light.json +9 -0
- package/themes/gruvbox-dark.json +9 -0
- package/themes/gruvbox-light.json +9 -0
- package/themes/monokai.json +9 -0
- package/themes/nord-light.json +9 -0
- package/themes/nord.json +9 -0
- package/themes/one-dark.json +9 -0
- package/themes/one-light.json +9 -0
- package/themes/rose-pine-dawn.json +9 -0
- package/themes/rose-pine.json +9 -0
- package/themes/solarized-dark.json +9 -0
- package/themes/solarized-light.json +9 -0
- package/themes/tokyo-night-light.json +9 -0
- package/themes/tokyo-night.json +9 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { Trash2, RefreshCw, X, Loader2, FileText } from "lucide-react";
|
|
3
|
+
import Markdown from "react-markdown";
|
|
4
|
+
import type { SkillInfo } from "@lattice/shared";
|
|
5
|
+
|
|
6
|
+
function parseFrontmatter(content: string): { meta: Record<string, string>; body: string } {
|
|
7
|
+
var match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\s*\r?\n?([\s\S]*)$/);
|
|
8
|
+
if (!match) return { meta: {}, body: content };
|
|
9
|
+
var meta: Record<string, string> = {};
|
|
10
|
+
var lines = match[1].split(/\r?\n/);
|
|
11
|
+
for (var i = 0; i < lines.length; i++) {
|
|
12
|
+
var colonIdx = lines[i].indexOf(":");
|
|
13
|
+
if (colonIdx > 0) {
|
|
14
|
+
var key = lines[i].slice(0, colonIdx).trim();
|
|
15
|
+
var value = lines[i].slice(colonIdx + 1).trim().replace(/^["']|["']$/g, "");
|
|
16
|
+
meta[key] = value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return { meta, body: match[2] };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function SkillItem({
|
|
23
|
+
skill,
|
|
24
|
+
badge,
|
|
25
|
+
onClick,
|
|
26
|
+
actions,
|
|
27
|
+
}: {
|
|
28
|
+
skill: SkillInfo;
|
|
29
|
+
badge?: string;
|
|
30
|
+
onClick?: () => void;
|
|
31
|
+
actions?: React.ReactNode;
|
|
32
|
+
}) {
|
|
33
|
+
return (
|
|
34
|
+
<div
|
|
35
|
+
onClick={onClick}
|
|
36
|
+
className={
|
|
37
|
+
"flex items-start gap-3 px-3 py-2.5 bg-base-300 border border-base-content/15 rounded-xl transition-colors duration-[120ms]" +
|
|
38
|
+
(onClick ? " cursor-pointer hover:border-base-content/30 hover:bg-base-300/80" : "")
|
|
39
|
+
}
|
|
40
|
+
role={onClick ? "button" : undefined}
|
|
41
|
+
tabIndex={onClick ? 0 : undefined}
|
|
42
|
+
onKeyDown={onClick ? function (e) { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onClick(); } } : undefined}
|
|
43
|
+
>
|
|
44
|
+
<FileText size={14} className="text-base-content/25 mt-0.5 flex-shrink-0" />
|
|
45
|
+
<div className="flex-1 min-w-0">
|
|
46
|
+
<div className="flex items-center gap-2">
|
|
47
|
+
<span className="text-[13px] font-bold text-base-content truncate">{skill.name}</span>
|
|
48
|
+
{badge && (
|
|
49
|
+
<span className="shrink-0 text-[10px] font-mono px-1.5 py-0.5 rounded-md bg-base-content/8 text-base-content/40">
|
|
50
|
+
{badge}
|
|
51
|
+
</span>
|
|
52
|
+
)}
|
|
53
|
+
</div>
|
|
54
|
+
{skill.description && (
|
|
55
|
+
<div className="text-[12px] text-base-content/40 mt-0.5 line-clamp-2">{skill.description}</div>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
{actions && (
|
|
59
|
+
<div className="flex gap-1 flex-shrink-0 mt-0.5" onClick={function (e) { e.stopPropagation(); }}>
|
|
60
|
+
{actions}
|
|
61
|
+
</div>
|
|
62
|
+
)}
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function SkillActions({
|
|
68
|
+
skill,
|
|
69
|
+
onDelete,
|
|
70
|
+
onUpdate,
|
|
71
|
+
isDeleting,
|
|
72
|
+
isUpdating,
|
|
73
|
+
}: {
|
|
74
|
+
skill: SkillInfo;
|
|
75
|
+
onDelete: () => void;
|
|
76
|
+
onUpdate: () => void;
|
|
77
|
+
isDeleting: boolean;
|
|
78
|
+
isUpdating: boolean;
|
|
79
|
+
}) {
|
|
80
|
+
var [confirmDelete, setConfirmDelete] = useState(false);
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<>
|
|
84
|
+
{isUpdating ? (
|
|
85
|
+
<Loader2 size={12} className="text-primary animate-spin mt-1 mx-1" />
|
|
86
|
+
) : (
|
|
87
|
+
<button
|
|
88
|
+
onClick={onUpdate}
|
|
89
|
+
aria-label={"Update " + skill.name}
|
|
90
|
+
className="btn btn-ghost btn-xs btn-square text-base-content/30 hover:text-info focus-visible:ring-2 focus-visible:ring-primary"
|
|
91
|
+
>
|
|
92
|
+
<RefreshCw size={12} />
|
|
93
|
+
</button>
|
|
94
|
+
)}
|
|
95
|
+
{confirmDelete ? (
|
|
96
|
+
<div className="flex gap-1">
|
|
97
|
+
<button
|
|
98
|
+
onClick={function () { onDelete(); setConfirmDelete(false); }}
|
|
99
|
+
className="btn btn-error btn-xs"
|
|
100
|
+
disabled={isDeleting}
|
|
101
|
+
>
|
|
102
|
+
{isDeleting ? <Loader2 size={10} className="animate-spin" /> : "Delete"}
|
|
103
|
+
</button>
|
|
104
|
+
<button
|
|
105
|
+
onClick={function () { setConfirmDelete(false); }}
|
|
106
|
+
className="btn btn-ghost btn-xs"
|
|
107
|
+
>
|
|
108
|
+
Cancel
|
|
109
|
+
</button>
|
|
110
|
+
</div>
|
|
111
|
+
) : (
|
|
112
|
+
<button
|
|
113
|
+
onClick={function () { setConfirmDelete(true); }}
|
|
114
|
+
aria-label={"Delete " + skill.name}
|
|
115
|
+
className="btn btn-ghost btn-xs btn-square text-base-content/30 hover:text-error focus-visible:ring-2 focus-visible:ring-primary"
|
|
116
|
+
>
|
|
117
|
+
<Trash2 size={12} />
|
|
118
|
+
</button>
|
|
119
|
+
)}
|
|
120
|
+
</>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function SkillViewModal({ path, content, onClose }: { path: string; content: string; onClose: () => void }) {
|
|
125
|
+
var parsed = parseFrontmatter(content);
|
|
126
|
+
var hasMeta = Object.keys(parsed.meta).length > 0;
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
|
130
|
+
<div className="absolute inset-0 bg-black/50" onClick={onClose} />
|
|
131
|
+
<div className="relative bg-base-200 border border-base-content/15 rounded-2xl shadow-2xl w-full max-w-2xl mx-4 max-h-[80vh] flex flex-col overflow-hidden">
|
|
132
|
+
<div className="flex items-center justify-between px-5 py-4 border-b border-base-content/15 flex-shrink-0">
|
|
133
|
+
<div className="flex items-center gap-2 min-w-0">
|
|
134
|
+
<FileText size={16} className="text-primary flex-shrink-0" />
|
|
135
|
+
<h2 className="text-[15px] font-mono font-bold text-base-content truncate">
|
|
136
|
+
{parsed.meta.name || path.split("/").pop() || path}
|
|
137
|
+
</h2>
|
|
138
|
+
</div>
|
|
139
|
+
<button
|
|
140
|
+
onClick={onClose}
|
|
141
|
+
aria-label="Close"
|
|
142
|
+
className="btn btn-ghost btn-xs btn-square text-base-content/40 hover:text-base-content"
|
|
143
|
+
>
|
|
144
|
+
<X size={16} />
|
|
145
|
+
</button>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<div className="overflow-y-auto flex-1">
|
|
149
|
+
{hasMeta && (
|
|
150
|
+
<div className="px-5 py-3 border-b border-base-content/10 bg-base-300/30">
|
|
151
|
+
<div className="flex flex-wrap gap-x-6 gap-y-1.5">
|
|
152
|
+
{Object.entries(parsed.meta).map(function ([key, value]) {
|
|
153
|
+
return (
|
|
154
|
+
<div key={key} className="flex items-baseline gap-1.5">
|
|
155
|
+
<span className="text-[11px] font-mono text-base-content/35 uppercase tracking-wider">{key}</span>
|
|
156
|
+
<span className="text-[12px] text-base-content/70">{value}</span>
|
|
157
|
+
</div>
|
|
158
|
+
);
|
|
159
|
+
})}
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
)}
|
|
163
|
+
|
|
164
|
+
<div className="px-5 py-4">
|
|
165
|
+
<div className="prose prose-sm max-w-none prose-headings:text-base-content prose-headings:font-mono prose-p:text-base-content/70 prose-strong:text-base-content prose-code:text-base-content/60 prose-code:bg-base-100/50 prose-code:px-1 prose-code:py-0.5 prose-code:rounded prose-code:text-[11px] prose-pre:bg-base-100 prose-pre:text-base-content/70 prose-pre:text-[11px] prose-a:text-primary prose-li:text-base-content/70 prose-li:marker:text-base-content/30 [&>*:first-child]:mt-0 [&>*:last-child]:mb-0">
|
|
166
|
+
<Markdown>{parsed.body}</Markdown>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<div className="px-5 py-3 border-t border-base-content/15 flex-shrink-0">
|
|
172
|
+
<div className="text-[11px] font-mono text-base-content/30 truncate">{path}</div>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
);
|
|
177
|
+
}
|