@cryptiklemur/lattice 0.0.0 → 1.2.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.
Files changed (53) hide show
  1. package/.github/workflows/release.yml +4 -4
  2. package/.releaserc.json +2 -1
  3. package/client/src/components/auth/PassphrasePrompt.tsx +70 -70
  4. package/client/src/components/mesh/NodeBadge.tsx +24 -24
  5. package/client/src/components/mesh/PairingDialog.tsx +281 -281
  6. package/client/src/components/panels/FileBrowser.tsx +241 -241
  7. package/client/src/components/panels/StickyNotes.tsx +187 -187
  8. package/client/src/components/project-settings/ProjectMemory.tsx +471 -0
  9. package/client/src/components/project-settings/ProjectSettingsView.tsx +6 -0
  10. package/client/src/components/settings/Appearance.tsx +151 -151
  11. package/client/src/components/settings/MeshStatus.tsx +145 -145
  12. package/client/src/components/settings/SettingsView.tsx +57 -57
  13. package/client/src/components/setup/SetupWizard.tsx +750 -750
  14. package/client/src/components/sidebar/AddProjectModal.tsx +432 -0
  15. package/client/src/components/sidebar/ProjectRail.tsx +8 -4
  16. package/client/src/components/sidebar/SettingsSidebar.tsx +2 -1
  17. package/client/src/components/ui/ErrorBoundary.tsx +56 -56
  18. package/client/src/hooks/useSidebar.ts +16 -0
  19. package/client/src/router.tsx +453 -391
  20. package/client/src/stores/sidebar.ts +28 -0
  21. package/client/vite.config.ts +20 -20
  22. package/package.json +1 -1
  23. package/server/src/daemon.ts +1 -0
  24. package/server/src/handlers/chat.ts +194 -194
  25. package/server/src/handlers/fs.ts +159 -0
  26. package/server/src/handlers/memory.ts +179 -0
  27. package/server/src/handlers/settings.ts +114 -109
  28. package/shared/src/messages.ts +97 -2
  29. package/shared/src/project-settings.ts +1 -1
  30. package/themes/amoled.json +20 -20
  31. package/themes/ayu-light.json +9 -9
  32. package/themes/catppuccin-latte.json +9 -9
  33. package/themes/catppuccin-mocha.json +9 -9
  34. package/themes/clay-light.json +10 -10
  35. package/themes/clay.json +10 -10
  36. package/themes/dracula.json +9 -9
  37. package/themes/everforest-light.json +9 -9
  38. package/themes/everforest.json +9 -9
  39. package/themes/github-light.json +9 -9
  40. package/themes/gruvbox-dark.json +9 -9
  41. package/themes/gruvbox-light.json +9 -9
  42. package/themes/monokai.json +9 -9
  43. package/themes/nord-light.json +9 -9
  44. package/themes/nord.json +9 -9
  45. package/themes/one-dark.json +9 -9
  46. package/themes/one-light.json +9 -9
  47. package/themes/rose-pine-dawn.json +9 -9
  48. package/themes/rose-pine.json +9 -9
  49. package/themes/solarized-dark.json +9 -9
  50. package/themes/solarized-light.json +9 -9
  51. package/themes/tokyo-night-light.json +9 -9
  52. package/themes/tokyo-night.json +9 -9
  53. package/.serena/project.yml +0 -138
@@ -0,0 +1,179 @@
1
+ import { existsSync, readFileSync, writeFileSync, readdirSync, unlinkSync, mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import type { ClientMessage } from "@lattice/shared";
5
+ import { registerHandler } from "../ws/router";
6
+ import { sendTo } from "../ws/broadcast";
7
+ import { loadConfig } from "../config";
8
+
9
+ function getMemoryDir(projectSlug: string): string | null {
10
+ var config = loadConfig();
11
+ var project = config.projects.find(function (p) { return p.slug === projectSlug; });
12
+ if (!project) return null;
13
+ var hash = "-" + project.path.replace(/\//g, "-").replace(/^-/, "");
14
+ return join(homedir(), ".claude", "projects", hash, "memory");
15
+ }
16
+
17
+ function parseFrontmatter(content: string): { name: string; description: string; type: string } {
18
+ var match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
19
+ if (!match) return { name: "", description: "", type: "" };
20
+ var yaml = match[1];
21
+ var name = "";
22
+ var description = "";
23
+ var type = "";
24
+ var lines = yaml.split(/\r?\n/);
25
+ for (var i = 0; i < lines.length; i++) {
26
+ var line = lines[i];
27
+ var nameMatch = line.match(/^name:\s*(.+)/);
28
+ if (nameMatch) name = nameMatch[1].trim().replace(/^["']|["']$/g, "");
29
+ var descMatch = line.match(/^description:\s*(.+)/);
30
+ if (descMatch) description = descMatch[1].trim().replace(/^["']|["']$/g, "");
31
+ var typeMatch = line.match(/^type:\s*(.+)/);
32
+ if (typeMatch) type = typeMatch[1].trim().replace(/^["']|["']$/g, "");
33
+ }
34
+ return { name, description, type };
35
+ }
36
+
37
+ function regenerateIndex(memoryDir: string): void {
38
+ if (!existsSync(memoryDir)) return;
39
+ var files = readdirSync(memoryDir).filter(function (f) {
40
+ return f.endsWith(".md") && f !== "MEMORY.md";
41
+ });
42
+
43
+ var grouped: Record<string, Array<{ filename: string; name: string; description: string }>> = {};
44
+
45
+ for (var i = 0; i < files.length; i++) {
46
+ try {
47
+ var content = readFileSync(join(memoryDir, files[i]), "utf-8");
48
+ var meta = parseFrontmatter(content);
49
+ var type = meta.type || "other";
50
+ if (!grouped[type]) grouped[type] = [];
51
+ grouped[type].push({ filename: files[i], name: meta.name || files[i], description: meta.description || "" });
52
+ } catch {}
53
+ }
54
+
55
+ var lines: string[] = ["# Memory Index", ""];
56
+ var types = Object.keys(grouped).sort();
57
+ for (var t = 0; t < types.length; t++) {
58
+ lines.push("## " + types[t].charAt(0).toUpperCase() + types[t].slice(1));
59
+ var entries = grouped[types[t]];
60
+ for (var e = 0; e < entries.length; e++) {
61
+ var desc = entries[e].description ? " — " + entries[e].description : "";
62
+ lines.push("- [" + entries[e].filename + "](" + entries[e].filename + ")" + desc);
63
+ }
64
+ lines.push("");
65
+ }
66
+
67
+ writeFileSync(join(memoryDir, "MEMORY.md"), lines.join("\n"), "utf-8");
68
+ }
69
+
70
+ registerHandler("memory", function (clientId: string, message: ClientMessage) {
71
+ if (message.type === "memory:list") {
72
+ var listMsg = message as { type: "memory:list"; projectSlug: string };
73
+ var memDir = getMemoryDir(listMsg.projectSlug);
74
+ if (!memDir || !existsSync(memDir)) {
75
+ sendTo(clientId, { type: "memory:list_result", projectSlug: listMsg.projectSlug, memories: [] });
76
+ return;
77
+ }
78
+
79
+ var files = readdirSync(memDir).filter(function (f) {
80
+ return f.endsWith(".md") && f !== "MEMORY.md";
81
+ });
82
+
83
+ var memories: Array<{ filename: string; name: string; description: string; type: string }> = [];
84
+ for (var i = 0; i < files.length; i++) {
85
+ try {
86
+ var content = readFileSync(join(memDir, files[i]), "utf-8");
87
+ var meta = parseFrontmatter(content);
88
+ memories.push({
89
+ filename: files[i],
90
+ name: meta.name || files[i].replace(/\.md$/, ""),
91
+ description: meta.description,
92
+ type: meta.type || "other",
93
+ });
94
+ } catch {}
95
+ }
96
+
97
+ memories.sort(function (a, b) { return a.name.localeCompare(b.name); });
98
+ sendTo(clientId, { type: "memory:list_result", projectSlug: listMsg.projectSlug, memories: memories });
99
+ return;
100
+ }
101
+
102
+ if (message.type === "memory:view") {
103
+ var viewMsg = message as { type: "memory:view"; projectSlug: string; filename: string };
104
+ var viewDir = getMemoryDir(viewMsg.projectSlug);
105
+ if (!viewDir) {
106
+ sendTo(clientId, { type: "memory:view_result", filename: viewMsg.filename, content: "Project not found." });
107
+ return;
108
+ }
109
+ try {
110
+ var viewContent = readFileSync(join(viewDir, viewMsg.filename), "utf-8");
111
+ sendTo(clientId, { type: "memory:view_result", filename: viewMsg.filename, content: viewContent });
112
+ } catch {
113
+ sendTo(clientId, { type: "memory:view_result", filename: viewMsg.filename, content: "File not found." });
114
+ }
115
+ return;
116
+ }
117
+
118
+ if (message.type === "memory:save") {
119
+ var saveMsg = message as { type: "memory:save"; projectSlug: string; filename: string; content: string };
120
+ var saveDir = getMemoryDir(saveMsg.projectSlug);
121
+ if (!saveDir) {
122
+ sendTo(clientId, { type: "memory:save_result", success: false, message: "Project not found." });
123
+ return;
124
+ }
125
+ try {
126
+ mkdirSync(saveDir, { recursive: true });
127
+ writeFileSync(join(saveDir, saveMsg.filename), saveMsg.content, "utf-8");
128
+ regenerateIndex(saveDir);
129
+ sendTo(clientId, { type: "memory:save_result", success: true });
130
+ var updatedFiles = readdirSync(saveDir).filter(function (f) { return f.endsWith(".md") && f !== "MEMORY.md"; });
131
+ var updatedMemories: Array<{ filename: string; name: string; description: string; type: string }> = [];
132
+ for (var j = 0; j < updatedFiles.length; j++) {
133
+ try {
134
+ var c = readFileSync(join(saveDir, updatedFiles[j]), "utf-8");
135
+ var m = parseFrontmatter(c);
136
+ updatedMemories.push({ filename: updatedFiles[j], name: m.name || updatedFiles[j].replace(/\.md$/, ""), description: m.description, type: m.type || "other" });
137
+ } catch {}
138
+ }
139
+ updatedMemories.sort(function (a, b) { return a.name.localeCompare(b.name); });
140
+ sendTo(clientId, { type: "memory:list_result", projectSlug: saveMsg.projectSlug, memories: updatedMemories });
141
+ } catch (err) {
142
+ sendTo(clientId, { type: "memory:save_result", success: false, message: "Failed to save: " + String(err) });
143
+ }
144
+ return;
145
+ }
146
+
147
+ if (message.type === "memory:delete") {
148
+ var delMsg = message as { type: "memory:delete"; projectSlug: string; filename: string };
149
+ var delDir = getMemoryDir(delMsg.projectSlug);
150
+ if (!delDir) {
151
+ sendTo(clientId, { type: "memory:delete_result", success: false, message: "Project not found." });
152
+ return;
153
+ }
154
+ try {
155
+ var filePath = join(delDir, delMsg.filename);
156
+ if (!existsSync(filePath)) {
157
+ sendTo(clientId, { type: "memory:delete_result", success: false, message: "Memory not found." });
158
+ return;
159
+ }
160
+ unlinkSync(filePath);
161
+ regenerateIndex(delDir);
162
+ sendTo(clientId, { type: "memory:delete_result", success: true });
163
+ var remainingFiles = readdirSync(delDir).filter(function (f) { return f.endsWith(".md") && f !== "MEMORY.md"; });
164
+ var remainingMemories: Array<{ filename: string; name: string; description: string; type: string }> = [];
165
+ for (var k = 0; k < remainingFiles.length; k++) {
166
+ try {
167
+ var rc = readFileSync(join(delDir, remainingFiles[k]), "utf-8");
168
+ var rm = parseFrontmatter(rc);
169
+ remainingMemories.push({ filename: remainingFiles[k], name: rm.name || remainingFiles[k].replace(/\.md$/, ""), description: rm.description, type: rm.type || "other" });
170
+ } catch {}
171
+ }
172
+ remainingMemories.sort(function (a, b) { return a.name.localeCompare(b.name); });
173
+ sendTo(clientId, { type: "memory:list_result", projectSlug: delMsg.projectSlug, memories: remainingMemories });
174
+ } catch (err) {
175
+ sendTo(clientId, { type: "memory:delete_result", success: false, message: "Failed to delete: " + String(err) });
176
+ }
177
+ return;
178
+ }
179
+ });
@@ -1,109 +1,114 @@
1
- import type { ClientMessage, SettingsGetMessage, SettingsUpdateMessage } from "@lattice/shared";
2
- import { registerHandler } from "../ws/router";
3
- import { sendTo, broadcast } from "../ws/broadcast";
4
- import { loadConfig, saveConfig } from "../config";
5
- import { addProject } from "../project/registry";
6
- import type { LatticeConfig } from "@lattice/shared";
7
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
8
- import { join } from "node:path";
9
- import { homedir } from "node:os";
10
- import { readGlobalMcpServers, writeGlobalMcpServers, readGlobalSkills } from "../project/project-files";
11
- import { loadOrCreateIdentity } from "../identity";
12
-
13
- function loadGlobalClaudeMd(): string {
14
- var mdPath = join(homedir(), ".claude", "CLAUDE.md");
15
- if (existsSync(mdPath)) {
16
- try {
17
- return readFileSync(mdPath, "utf-8");
18
- } catch {}
19
- }
20
- return "";
21
- }
22
-
23
- function saveGlobalClaudeMd(content: string): void {
24
- var claudeDir = join(homedir(), ".claude");
25
- if (!existsSync(claudeDir)) {
26
- mkdirSync(claudeDir, { recursive: true });
27
- }
28
- writeFileSync(join(claudeDir, "CLAUDE.md"), content, "utf-8");
29
- }
30
-
31
- registerHandler("settings", function (clientId: string, message: ClientMessage) {
32
- if (message.type === "settings:get") {
33
- var config = loadConfig();
34
- var identity = loadOrCreateIdentity();
35
- var configWithClaudeMd = { ...config, claudeMd: loadGlobalClaudeMd() };
36
- sendTo(clientId, {
37
- type: "settings:data",
38
- config: configWithClaudeMd,
39
- mcpServers: readGlobalMcpServers() as Record<string, import("@lattice/shared").McpServerConfig>,
40
- globalSkills: readGlobalSkills(),
41
- });
42
- sendTo(clientId, {
43
- type: "projects:list",
44
- projects: config.projects.map(function (p) {
45
- return { slug: p.slug, path: p.path, title: p.title, nodeId: identity.id, nodeName: config.name, isRemote: false };
46
- }),
47
- });
48
- return;
49
- }
50
-
51
- if (message.type === "settings:update") {
52
- var updateMsg = message as SettingsUpdateMessage;
53
- var current = loadConfig();
54
-
55
- var incoming = updateMsg.settings as Record<string, unknown>;
56
- if (typeof incoming.claudeMd === "string") {
57
- saveGlobalClaudeMd(incoming.claudeMd);
58
- delete incoming.claudeMd;
59
- }
60
-
61
- if (incoming.mcpServers != null) {
62
- writeGlobalMcpServers(incoming.mcpServers as Record<string, unknown>);
63
- delete incoming.mcpServers;
64
- }
65
-
66
- var incomingProjects = incoming.projects as Array<{ path: string; slug?: string; title: string; env?: Record<string, string> }> | undefined;
67
- if (incomingProjects && incomingProjects.length > 0) {
68
- for (var i = 0; i < incomingProjects.length; i++) {
69
- var proj = incomingProjects[i];
70
- addProject(proj.path, proj.title);
71
- }
72
- }
73
-
74
- var refreshed = loadConfig();
75
- var updated: LatticeConfig = {
76
- ...refreshed,
77
- ...(incoming as Partial<LatticeConfig>),
78
- globalEnv: {
79
- ...refreshed.globalEnv,
80
- ...((incoming.globalEnv as Record<string, string>) ?? {}),
81
- },
82
- projects: refreshed.projects,
83
- };
84
- saveConfig(updated);
85
- var updatedWithClaudeMd = { ...updated, claudeMd: loadGlobalClaudeMd() };
86
- sendTo(clientId, {
87
- type: "settings:data",
88
- config: updatedWithClaudeMd,
89
- mcpServers: readGlobalMcpServers() as Record<string, import("@lattice/shared").McpServerConfig>,
90
- globalSkills: readGlobalSkills(),
91
- });
92
- var updatedIdentity = loadOrCreateIdentity();
93
- broadcast({
94
- type: "projects:list",
95
- projects: updated.projects.map(function (p) {
96
- return { slug: p.slug, path: p.path, title: p.title, nodeId: updatedIdentity.id, nodeName: updated.name, isRemote: false };
97
- }),
98
- });
99
- return;
100
- }
101
-
102
- if (message.type === "settings:restart") {
103
- console.log("[lattice] Restart requested by client");
104
- setTimeout(function () {
105
- process.exit(0);
106
- }, 200);
107
- return;
108
- }
109
- });
1
+ import type { ClientMessage, SettingsGetMessage, SettingsUpdateMessage } from "@lattice/shared";
2
+ import { registerHandler } from "../ws/router";
3
+ import { sendTo, broadcast } from "../ws/broadcast";
4
+ import { loadConfig, saveConfig } from "../config";
5
+ import { addProject, removeProject } from "../project/registry";
6
+ import type { LatticeConfig } from "@lattice/shared";
7
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { homedir } from "node:os";
10
+ import { readGlobalMcpServers, writeGlobalMcpServers, readGlobalSkills } from "../project/project-files";
11
+ import { loadOrCreateIdentity } from "../identity";
12
+
13
+ function loadGlobalClaudeMd(): string {
14
+ var mdPath = join(homedir(), ".claude", "CLAUDE.md");
15
+ if (existsSync(mdPath)) {
16
+ try {
17
+ return readFileSync(mdPath, "utf-8");
18
+ } catch {}
19
+ }
20
+ return "";
21
+ }
22
+
23
+ function saveGlobalClaudeMd(content: string): void {
24
+ var claudeDir = join(homedir(), ".claude");
25
+ if (!existsSync(claudeDir)) {
26
+ mkdirSync(claudeDir, { recursive: true });
27
+ }
28
+ writeFileSync(join(claudeDir, "CLAUDE.md"), content, "utf-8");
29
+ }
30
+
31
+ registerHandler("settings", function (clientId: string, message: ClientMessage) {
32
+ if (message.type === "settings:get") {
33
+ var config = loadConfig();
34
+ var identity = loadOrCreateIdentity();
35
+ var configWithClaudeMd = { ...config, claudeMd: loadGlobalClaudeMd() };
36
+ sendTo(clientId, {
37
+ type: "settings:data",
38
+ config: configWithClaudeMd,
39
+ mcpServers: readGlobalMcpServers() as Record<string, import("@lattice/shared").McpServerConfig>,
40
+ globalSkills: readGlobalSkills(),
41
+ });
42
+ sendTo(clientId, {
43
+ type: "projects:list",
44
+ projects: config.projects.map(function (p) {
45
+ return { slug: p.slug, path: p.path, title: p.title, nodeId: identity.id, nodeName: config.name, isRemote: false };
46
+ }),
47
+ });
48
+ return;
49
+ }
50
+
51
+ if (message.type === "settings:update") {
52
+ var updateMsg = message as SettingsUpdateMessage;
53
+ var current = loadConfig();
54
+
55
+ var incoming = updateMsg.settings as Record<string, unknown>;
56
+ if (typeof incoming.claudeMd === "string") {
57
+ saveGlobalClaudeMd(incoming.claudeMd);
58
+ delete incoming.claudeMd;
59
+ }
60
+
61
+ if (incoming.mcpServers != null) {
62
+ writeGlobalMcpServers(incoming.mcpServers as Record<string, unknown>);
63
+ delete incoming.mcpServers;
64
+ }
65
+
66
+ if (typeof incoming.removeProject === "string") {
67
+ removeProject(incoming.removeProject as string);
68
+ delete incoming.removeProject;
69
+ }
70
+
71
+ var incomingProjects = incoming.projects as Array<{ path: string; slug?: string; title: string; env?: Record<string, string> }> | undefined;
72
+ if (incomingProjects && incomingProjects.length > 0) {
73
+ for (var i = 0; i < incomingProjects.length; i++) {
74
+ var proj = incomingProjects[i];
75
+ addProject(proj.path, proj.title);
76
+ }
77
+ }
78
+
79
+ var refreshed = loadConfig();
80
+ var updated: LatticeConfig = {
81
+ ...refreshed,
82
+ ...(incoming as Partial<LatticeConfig>),
83
+ globalEnv: {
84
+ ...refreshed.globalEnv,
85
+ ...((incoming.globalEnv as Record<string, string>) ?? {}),
86
+ },
87
+ projects: refreshed.projects,
88
+ };
89
+ saveConfig(updated);
90
+ var updatedWithClaudeMd = { ...updated, claudeMd: loadGlobalClaudeMd() };
91
+ sendTo(clientId, {
92
+ type: "settings:data",
93
+ config: updatedWithClaudeMd,
94
+ mcpServers: readGlobalMcpServers() as Record<string, import("@lattice/shared").McpServerConfig>,
95
+ globalSkills: readGlobalSkills(),
96
+ });
97
+ var updatedIdentity = loadOrCreateIdentity();
98
+ broadcast({
99
+ type: "projects:list",
100
+ projects: updated.projects.map(function (p) {
101
+ return { slug: p.slug, path: p.path, title: p.title, nodeId: updatedIdentity.id, nodeName: updated.name, isRemote: false };
102
+ }),
103
+ });
104
+ return;
105
+ }
106
+
107
+ if (message.type === "settings:restart") {
108
+ console.log("[lattice] Restart requested by client");
109
+ setTimeout(function () {
110
+ process.exit(0);
111
+ }, 200);
112
+ return;
113
+ }
114
+ });
@@ -223,6 +223,39 @@ export interface SkillsUpdateMessage {
223
223
  source: string;
224
224
  }
225
225
 
226
+ export interface BrowseListMessage {
227
+ type: "browse:list";
228
+ path: string;
229
+ }
230
+
231
+ export interface MemoryListMessage {
232
+ type: "memory:list";
233
+ projectSlug: string;
234
+ }
235
+
236
+ export interface MemoryViewMessage {
237
+ type: "memory:view";
238
+ projectSlug: string;
239
+ filename: string;
240
+ }
241
+
242
+ export interface MemorySaveMessage {
243
+ type: "memory:save";
244
+ projectSlug: string;
245
+ filename: string;
246
+ content: string;
247
+ }
248
+
249
+ export interface MemoryDeleteMessage {
250
+ type: "memory:delete";
251
+ projectSlug: string;
252
+ filename: string;
253
+ }
254
+
255
+ export interface BrowseSuggestionsMessage {
256
+ type: "browse:suggestions";
257
+ }
258
+
226
259
  export interface ProjectSettingsGetMessage {
227
260
  type: "project-settings:get";
228
261
  projectSlug: string;
@@ -289,7 +322,13 @@ export type ClientMessage =
289
322
  | SkillsInstallMessage
290
323
  | SkillsViewMessage
291
324
  | SkillsDeleteMessage
292
- | SkillsUpdateMessage;
325
+ | SkillsUpdateMessage
326
+ | BrowseListMessage
327
+ | MemoryListMessage
328
+ | MemoryViewMessage
329
+ | MemorySaveMessage
330
+ | MemoryDeleteMessage
331
+ | BrowseSuggestionsMessage;
293
332
 
294
333
  export interface SessionListMessage {
295
334
  type: "session:list";
@@ -548,6 +587,56 @@ export interface SkillsDeleteResultMessage {
548
587
  message?: string;
549
588
  }
550
589
 
590
+ export interface BrowseListResultMessage {
591
+ type: "browse:list_result";
592
+ path: string;
593
+ homedir: string;
594
+ entries: Array<{
595
+ name: string;
596
+ path: string;
597
+ hasClaudeMd: boolean;
598
+ projectName: string | null;
599
+ }>;
600
+ }
601
+
602
+ export interface MemoryListResultMessage {
603
+ type: "memory:list_result";
604
+ projectSlug: string;
605
+ memories: Array<{
606
+ filename: string;
607
+ name: string;
608
+ description: string;
609
+ type: string;
610
+ }>;
611
+ }
612
+
613
+ export interface MemoryViewResultMessage {
614
+ type: "memory:view_result";
615
+ filename: string;
616
+ content: string;
617
+ }
618
+
619
+ export interface MemorySaveResultMessage {
620
+ type: "memory:save_result";
621
+ success: boolean;
622
+ message?: string;
623
+ }
624
+
625
+ export interface MemoryDeleteResultMessage {
626
+ type: "memory:delete_result";
627
+ success: boolean;
628
+ message?: string;
629
+ }
630
+
631
+ export interface BrowseSuggestionsResultMessage {
632
+ type: "browse:suggestions_result";
633
+ suggestions: Array<{
634
+ path: string;
635
+ name: string;
636
+ hasClaudeMd: boolean;
637
+ }>;
638
+ }
639
+
551
640
  export type ServerMessage =
552
641
  | SessionListMessage
553
642
  | SessionCreatedMessage
@@ -592,7 +681,13 @@ export type ServerMessage =
592
681
  | SkillsSearchResultsMessage
593
682
  | SkillsInstallResultMessage
594
683
  | SkillsViewResultMessage
595
- | SkillsDeleteResultMessage;
684
+ | SkillsDeleteResultMessage
685
+ | BrowseListResultMessage
686
+ | MemoryListResultMessage
687
+ | MemoryViewResultMessage
688
+ | MemorySaveResultMessage
689
+ | MemoryDeleteResultMessage
690
+ | BrowseSuggestionsResultMessage;
596
691
 
597
692
  export interface MeshHelloMessage {
598
693
  type: "mesh:hello";
@@ -15,7 +15,7 @@ export type McpServerConfig =
15
15
  | { type: "sse"; url: string; headers?: Record<string, string> };
16
16
 
17
17
  export type ProjectSettingsSection =
18
- | "general" | "claude" | "environment" | "mcp" | "skills" | "rules" | "permissions";
18
+ | "general" | "claude" | "environment" | "mcp" | "skills" | "rules" | "permissions" | "memory";
19
19
 
20
20
  export interface ProjectSettings {
21
21
  title: string;
@@ -1,20 +1,20 @@
1
- {
2
- "name": "AMOLED Dark",
3
- "variant": "dark",
4
- "base00": "000000",
5
- "base01": "0a0a0a",
6
- "base02": "1a1a1a",
7
- "base03": "555555",
8
- "base04": "999999",
9
- "base05": "e0e0e0",
10
- "base06": "f5f5f5",
11
- "base07": "ffffff",
12
- "base08": "ff6b6b",
13
- "base09": "ffa94d",
14
- "base0A": "ffd93d",
15
- "base0B": "6bcf7f",
16
- "base0C": "4ecdc4",
17
- "base0D": "74b7ff",
18
- "base0E": "ff6ef7",
19
- "base0F": "c8a2ff"
20
- }
1
+ {
2
+ "name": "AMOLED Dark",
3
+ "variant": "dark",
4
+ "base00": "000000",
5
+ "base01": "0a0a0a",
6
+ "base02": "1a1a1a",
7
+ "base03": "555555",
8
+ "base04": "999999",
9
+ "base05": "e0e0e0",
10
+ "base06": "f5f5f5",
11
+ "base07": "ffffff",
12
+ "base08": "ff6b6b",
13
+ "base09": "ffa94d",
14
+ "base0A": "ffd93d",
15
+ "base0B": "6bcf7f",
16
+ "base0C": "4ecdc4",
17
+ "base0D": "74b7ff",
18
+ "base0E": "ff6ef7",
19
+ "base0F": "c8a2ff"
20
+ }
@@ -1,9 +1,9 @@
1
- {
2
- "name": "Ayu Light",
3
- "author": "Ike Ku",
4
- "variant": "light",
5
- "base00": "FAFAFA", "base01": "EDEFF1", "base02": "D2D4D8", "base03": "A0A6AC",
6
- "base04": "8A9199", "base05": "5C6166", "base06": "4E5257", "base07": "404447",
7
- "base08": "F07171", "base09": "FA8D3E", "base0A": "F2AE49", "base0B": "6CBF49",
8
- "base0C": "4CBF99", "base0D": "399EE6", "base0E": "A37ACC", "base0F": "E6BA7E"
9
- }
1
+ {
2
+ "name": "Ayu Light",
3
+ "author": "Ike Ku",
4
+ "variant": "light",
5
+ "base00": "FAFAFA", "base01": "EDEFF1", "base02": "D2D4D8", "base03": "A0A6AC",
6
+ "base04": "8A9199", "base05": "5C6166", "base06": "4E5257", "base07": "404447",
7
+ "base08": "F07171", "base09": "FA8D3E", "base0A": "F2AE49", "base0B": "6CBF49",
8
+ "base0C": "4CBF99", "base0D": "399EE6", "base0E": "A37ACC", "base0F": "E6BA7E"
9
+ }
@@ -1,9 +1,9 @@
1
- {
2
- "name": "Catppuccin Latte",
3
- "author": "catppuccin",
4
- "variant": "light",
5
- "base00": "eff1f5", "base01": "e6e9ef", "base02": "ccd0da", "base03": "9ca0b0",
6
- "base04": "8c8fa1", "base05": "5c5f77", "base06": "4c4f69", "base07": "303446",
7
- "base08": "d20f39", "base09": "fe640b", "base0A": "df8e1d", "base0B": "40a02b",
8
- "base0C": "179299", "base0D": "1e66f5", "base0E": "8839ef", "base0F": "dd7878"
9
- }
1
+ {
2
+ "name": "Catppuccin Latte",
3
+ "author": "catppuccin",
4
+ "variant": "light",
5
+ "base00": "eff1f5", "base01": "e6e9ef", "base02": "ccd0da", "base03": "9ca0b0",
6
+ "base04": "8c8fa1", "base05": "5c5f77", "base06": "4c4f69", "base07": "303446",
7
+ "base08": "d20f39", "base09": "fe640b", "base0A": "df8e1d", "base0B": "40a02b",
8
+ "base0C": "179299", "base0D": "1e66f5", "base0E": "8839ef", "base0F": "dd7878"
9
+ }
@@ -1,9 +1,9 @@
1
- {
2
- "name": "Catppuccin Mocha",
3
- "author": "catppuccin",
4
- "variant": "dark",
5
- "base00": "1e1e2e", "base01": "181825", "base02": "313244", "base03": "45475a",
6
- "base04": "585b70", "base05": "cdd6f4", "base06": "f5e0dc", "base07": "b4befe",
7
- "base08": "f38ba8", "base09": "fab387", "base0A": "f9e2af", "base0B": "a6e3a1",
8
- "base0C": "94e2d5", "base0D": "89b4fa", "base0E": "cba6f7", "base0F": "f2cdcd"
9
- }
1
+ {
2
+ "name": "Catppuccin Mocha",
3
+ "author": "catppuccin",
4
+ "variant": "dark",
5
+ "base00": "1e1e2e", "base01": "181825", "base02": "313244", "base03": "45475a",
6
+ "base04": "585b70", "base05": "cdd6f4", "base06": "f5e0dc", "base07": "b4befe",
7
+ "base08": "f38ba8", "base09": "fab387", "base0A": "f9e2af", "base0B": "a6e3a1",
8
+ "base0C": "94e2d5", "base0D": "89b4fa", "base0E": "cba6f7", "base0F": "f2cdcd"
9
+ }
@@ -1,10 +1,10 @@
1
- {
2
- "name": "Clay Light",
3
- "author": "Clay",
4
- "variant": "light",
5
- "base00": "F3EBE7", "base01": "EBE1DC", "base02": "D8CCC6", "base03": "A09590",
6
- "base04": "786D67", "base05": "504541", "base06": "332925", "base07": "1A1412",
7
- "base08": "C83520", "base09": "F74728", "base0A": "C08520", "base0B": "008F6B",
8
- "base0C": "1C8575", "base0D": "3560B0", "base0E": "8C4E8E", "base0F": "A57C45",
9
- "accent2": "2A26E5"
10
- }
1
+ {
2
+ "name": "Clay Light",
3
+ "author": "Clay",
4
+ "variant": "light",
5
+ "base00": "F3EBE7", "base01": "EBE1DC", "base02": "D8CCC6", "base03": "A09590",
6
+ "base04": "786D67", "base05": "504541", "base06": "332925", "base07": "1A1412",
7
+ "base08": "C83520", "base09": "F74728", "base0A": "C08520", "base0B": "008F6B",
8
+ "base0C": "1C8575", "base0D": "3560B0", "base0E": "8C4E8E", "base0F": "A57C45",
9
+ "accent2": "2A26E5"
10
+ }