stashes 0.1.11 → 0.1.13
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/dist/cli.js +213 -46
- package/dist/mcp.js +212 -45
- package/dist/web/assets/index-7ZfF6u6K.js +96 -0
- package/dist/web/assets/index-CGKcu-ru.css +1 -0
- package/dist/web/index.html +3 -3
- package/package.json +1 -1
- package/dist/web/assets/index-CGt4isEz.js +0 -62
- package/dist/web/assets/index-YiFrDapH.css +0 -1
package/dist/cli.js
CHANGED
|
@@ -52,7 +52,7 @@ var DEFAULT_DIRECTIVES = [
|
|
|
52
52
|
];
|
|
53
53
|
// ../server/dist/routes/api.js
|
|
54
54
|
import { Hono } from "hono";
|
|
55
|
-
import { join } from "path";
|
|
55
|
+
import { join, basename } from "path";
|
|
56
56
|
import { existsSync, readFileSync } from "fs";
|
|
57
57
|
var app = new Hono;
|
|
58
58
|
app.get("/health", (c) => c.json({ status: "ok", service: "stashes" }));
|
|
@@ -84,14 +84,54 @@ app.get("/projects/:id", (c) => {
|
|
|
84
84
|
if (!project)
|
|
85
85
|
return c.json({ error: "Project not found" }, 404);
|
|
86
86
|
const stashes = persistence.listStashes(project.id);
|
|
87
|
-
const
|
|
88
|
-
return c.json({ data: { ...project, stashes,
|
|
87
|
+
const chats = persistence.listChats(project.id);
|
|
88
|
+
return c.json({ data: { ...project, stashes, chats } });
|
|
89
89
|
});
|
|
90
90
|
app.delete("/projects/:id", (c) => {
|
|
91
91
|
const id = c.req.param("id");
|
|
92
92
|
getPersistence().deleteProject(id);
|
|
93
93
|
return c.json({ data: { deleted: id } });
|
|
94
94
|
});
|
|
95
|
+
app.get("/chats", (c) => {
|
|
96
|
+
const persistence = getPersistence();
|
|
97
|
+
const project = ensureProject(persistence);
|
|
98
|
+
const chats = persistence.listChats(project.id);
|
|
99
|
+
const stashes = persistence.listStashes(project.id);
|
|
100
|
+
return c.json({ data: { project, chats, stashCount: stashes.length } });
|
|
101
|
+
});
|
|
102
|
+
app.post("/chats", async (c) => {
|
|
103
|
+
const persistence = getPersistence();
|
|
104
|
+
const project = ensureProject(persistence);
|
|
105
|
+
const { title } = await c.req.json();
|
|
106
|
+
const chatCount = persistence.listChats(project.id).length;
|
|
107
|
+
const chat = {
|
|
108
|
+
id: `chat_${crypto.randomUUID().substring(0, 8)}`,
|
|
109
|
+
projectId: project.id,
|
|
110
|
+
title: title?.trim() || `Chat ${chatCount + 1}`,
|
|
111
|
+
createdAt: new Date().toISOString(),
|
|
112
|
+
updatedAt: new Date().toISOString()
|
|
113
|
+
};
|
|
114
|
+
persistence.saveChat(chat);
|
|
115
|
+
return c.json({ data: chat }, 201);
|
|
116
|
+
});
|
|
117
|
+
app.get("/chats/:chatId", (c) => {
|
|
118
|
+
const persistence = getPersistence();
|
|
119
|
+
const project = ensureProject(persistence);
|
|
120
|
+
const chatId = c.req.param("chatId");
|
|
121
|
+
const chat = persistence.getChat(project.id, chatId);
|
|
122
|
+
if (!chat)
|
|
123
|
+
return c.json({ error: "Chat not found" }, 404);
|
|
124
|
+
const messages = persistence.getChatMessages(project.id, chatId);
|
|
125
|
+
const stashes = persistence.listStashes(project.id).filter((s) => s.originChatId === chatId);
|
|
126
|
+
return c.json({ data: { ...chat, messages, stashes } });
|
|
127
|
+
});
|
|
128
|
+
app.delete("/chats/:chatId", (c) => {
|
|
129
|
+
const persistence = getPersistence();
|
|
130
|
+
const project = ensureProject(persistence);
|
|
131
|
+
const chatId = c.req.param("chatId");
|
|
132
|
+
persistence.deleteChat(project.id, chatId);
|
|
133
|
+
return c.json({ data: { deleted: chatId } });
|
|
134
|
+
});
|
|
95
135
|
app.get("/screenshots/:filename", (c) => {
|
|
96
136
|
const filename = c.req.param("filename");
|
|
97
137
|
const filePath = join(serverState.projectPath, ".stashes", "screenshots", filename);
|
|
@@ -102,6 +142,20 @@ app.get("/screenshots/:filename", (c) => {
|
|
|
102
142
|
headers: { "content-type": "image/png", "cache-control": "no-cache" }
|
|
103
143
|
});
|
|
104
144
|
});
|
|
145
|
+
function ensureProject(persistence) {
|
|
146
|
+
const projects = persistence.listProjects();
|
|
147
|
+
if (projects.length > 0)
|
|
148
|
+
return projects[0];
|
|
149
|
+
const project = {
|
|
150
|
+
id: `proj_${crypto.randomUUID().substring(0, 8)}`,
|
|
151
|
+
name: basename(serverState.projectPath),
|
|
152
|
+
createdAt: new Date().toISOString(),
|
|
153
|
+
updatedAt: new Date().toISOString()
|
|
154
|
+
};
|
|
155
|
+
persistence.saveProject(project);
|
|
156
|
+
persistence.migrateOldChat(project.id);
|
|
157
|
+
return project;
|
|
158
|
+
}
|
|
105
159
|
var apiRoutes = app;
|
|
106
160
|
|
|
107
161
|
// ../core/dist/generation.js
|
|
@@ -411,7 +465,7 @@ class WorktreeManager {
|
|
|
411
465
|
}
|
|
412
466
|
|
|
413
467
|
// ../core/dist/persistence.js
|
|
414
|
-
import { readFileSync as readFileSync2, writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync4, rmSync as rmSync2 } from "fs";
|
|
468
|
+
import { readFileSync as readFileSync2, writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync4, rmSync as rmSync2, readdirSync } from "fs";
|
|
415
469
|
import { join as join4, dirname } from "path";
|
|
416
470
|
var STASHES_DIR = ".stashes";
|
|
417
471
|
function ensureDir(dirPath) {
|
|
@@ -488,14 +542,64 @@ class PersistenceService {
|
|
|
488
542
|
const filePath = join4(this.basePath, "projects", projectId, "stashes.json");
|
|
489
543
|
writeJson(filePath, stashes);
|
|
490
544
|
}
|
|
491
|
-
|
|
492
|
-
const
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
545
|
+
listChats(projectId) {
|
|
546
|
+
const dir = join4(this.basePath, "projects", projectId, "chats");
|
|
547
|
+
if (!existsSync4(dir))
|
|
548
|
+
return [];
|
|
549
|
+
const files = readdirSync(dir).filter((f) => f.endsWith(".json"));
|
|
550
|
+
return files.map((f) => {
|
|
551
|
+
const data = readJson(join4(dir, f), null);
|
|
552
|
+
return data?.chat;
|
|
553
|
+
}).filter(Boolean).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
554
|
+
}
|
|
555
|
+
getChat(projectId, chatId) {
|
|
556
|
+
const filePath = join4(this.basePath, "projects", projectId, "chats", `${chatId}.json`);
|
|
557
|
+
const data = readJson(filePath, null);
|
|
558
|
+
return data?.chat;
|
|
559
|
+
}
|
|
560
|
+
saveChat(chat) {
|
|
561
|
+
const filePath = join4(this.basePath, "projects", chat.projectId, "chats", `${chat.id}.json`);
|
|
562
|
+
const existing = readJson(filePath, { chat, messages: [] });
|
|
563
|
+
writeJson(filePath, { ...existing, chat });
|
|
564
|
+
}
|
|
565
|
+
deleteChat(projectId, chatId) {
|
|
566
|
+
const filePath = join4(this.basePath, "projects", projectId, "chats", `${chatId}.json`);
|
|
567
|
+
if (existsSync4(filePath)) {
|
|
568
|
+
rmSync2(filePath);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
getChatMessages(projectId, chatId) {
|
|
572
|
+
const filePath = join4(this.basePath, "projects", projectId, "chats", `${chatId}.json`);
|
|
573
|
+
const data = readJson(filePath, { messages: [] });
|
|
574
|
+
return data.messages;
|
|
575
|
+
}
|
|
576
|
+
saveChatMessage(projectId, chatId, message) {
|
|
577
|
+
const filePath = join4(this.basePath, "projects", projectId, "chats", `${chatId}.json`);
|
|
578
|
+
const data = readJson(filePath, { chat: this.getChat(projectId, chatId), messages: [] });
|
|
579
|
+
writeJson(filePath, { ...data, messages: [...data.messages, message] });
|
|
580
|
+
}
|
|
581
|
+
migrateOldChat(projectId) {
|
|
582
|
+
const oldPath = join4(this.basePath, "projects", projectId, "chat.json");
|
|
583
|
+
if (!existsSync4(oldPath))
|
|
584
|
+
return null;
|
|
585
|
+
const messages = readJson(oldPath, []);
|
|
586
|
+
if (messages.length === 0) {
|
|
587
|
+
rmSync2(oldPath);
|
|
588
|
+
return null;
|
|
589
|
+
}
|
|
590
|
+
const chatId = `chat_${crypto.randomUUID().substring(0, 8)}`;
|
|
591
|
+
const chat = {
|
|
592
|
+
id: chatId,
|
|
593
|
+
projectId,
|
|
594
|
+
title: "Initial conversation",
|
|
595
|
+
createdAt: messages[0].createdAt,
|
|
596
|
+
updatedAt: messages[messages.length - 1].createdAt
|
|
597
|
+
};
|
|
598
|
+
const filePath = join4(this.basePath, "projects", projectId, "chats", `${chatId}.json`);
|
|
599
|
+
writeJson(filePath, { chat, messages });
|
|
600
|
+
rmSync2(oldPath);
|
|
601
|
+
logger.info("persistence", `migrated old chat.json \u2192 ${chatId}`);
|
|
602
|
+
return chatId;
|
|
499
603
|
}
|
|
500
604
|
ensureGitignore(projectPath) {
|
|
501
605
|
const gitignorePath = join4(projectPath, ".gitignore");
|
|
@@ -721,7 +825,7 @@ async function allocatePort() {
|
|
|
721
825
|
throw new Error("No available ports in range 4010-4030");
|
|
722
826
|
}
|
|
723
827
|
async function generate(opts) {
|
|
724
|
-
const { projectPath, projectId, prompt, component, count = DEFAULT_STASH_COUNT, directives = DEFAULT_DIRECTIVES, onProgress } = opts;
|
|
828
|
+
const { projectPath, projectId, chatId, prompt, component, count = DEFAULT_STASH_COUNT, directives = DEFAULT_DIRECTIVES, onProgress } = opts;
|
|
725
829
|
const worktreeManager = new WorktreeManager(projectPath);
|
|
726
830
|
const persistence = new PersistenceService(projectPath);
|
|
727
831
|
const selectedDirectives = directives.slice(0, count);
|
|
@@ -733,12 +837,17 @@ async function generate(opts) {
|
|
|
733
837
|
}
|
|
734
838
|
}
|
|
735
839
|
const completedStashes = [];
|
|
736
|
-
const
|
|
840
|
+
const existingStashes = persistence.listStashes(projectId);
|
|
841
|
+
const maxNumber = existingStashes.reduce((max, s) => Math.max(max, s.number ?? 0), 0);
|
|
842
|
+
const stashPromises = selectedDirectives.map(async (directive, idx) => {
|
|
737
843
|
const stashId = `stash_${crypto.randomUUID().substring(0, 8)}`;
|
|
844
|
+
const stashNumber = maxNumber + idx + 1;
|
|
738
845
|
const worktree = await worktreeManager.createForGeneration(stashId);
|
|
739
846
|
const stash = {
|
|
740
847
|
id: stashId,
|
|
848
|
+
number: stashNumber,
|
|
741
849
|
projectId,
|
|
850
|
+
originChatId: chatId,
|
|
742
851
|
prompt,
|
|
743
852
|
componentPath: component?.filePath,
|
|
744
853
|
branch: worktree.branch,
|
|
@@ -751,7 +860,7 @@ async function generate(opts) {
|
|
|
751
860
|
createdAt: new Date().toISOString()
|
|
752
861
|
};
|
|
753
862
|
persistence.saveStash(stash);
|
|
754
|
-
emit(onProgress, { type: "generating", stashId });
|
|
863
|
+
emit(onProgress, { type: "generating", stashId, number: stashNumber });
|
|
755
864
|
let stashPrompt;
|
|
756
865
|
if (component?.filePath) {
|
|
757
866
|
stashPrompt = buildStashPrompt({ name: component.exportName || component.filePath, filePath: component.filePath, domSelector: "" }, sourceCode, prompt, directive);
|
|
@@ -840,7 +949,7 @@ async function allocatePort2() {
|
|
|
840
949
|
throw new Error("No available ports in range 4010-4030");
|
|
841
950
|
}
|
|
842
951
|
async function vary(opts) {
|
|
843
|
-
const { projectPath, sourceStashId, prompt, onProgress } = opts;
|
|
952
|
+
const { projectPath, sourceStashId, chatId, prompt, onProgress } = opts;
|
|
844
953
|
const persistence = new PersistenceService(projectPath);
|
|
845
954
|
const worktreeManager = new WorktreeManager(projectPath);
|
|
846
955
|
let sourceStash;
|
|
@@ -856,10 +965,14 @@ async function vary(opts) {
|
|
|
856
965
|
if (!sourceStash)
|
|
857
966
|
throw new Error(`Source stash ${sourceStashId} not found`);
|
|
858
967
|
const stashId = `stash_${crypto.randomUUID().substring(0, 8)}`;
|
|
968
|
+
const existingStashes = persistence.listStashes(projectId);
|
|
969
|
+
const stashNumber = existingStashes.reduce((max, s) => Math.max(max, s.number ?? 0), 0) + 1;
|
|
859
970
|
const worktree = await worktreeManager.createForVary(stashId, sourceStash.branch);
|
|
860
971
|
const stash = {
|
|
861
972
|
id: stashId,
|
|
973
|
+
number: stashNumber,
|
|
862
974
|
projectId,
|
|
975
|
+
originChatId: chatId,
|
|
863
976
|
prompt,
|
|
864
977
|
componentPath: sourceStash.componentPath,
|
|
865
978
|
branch: worktree.branch,
|
|
@@ -872,7 +985,7 @@ async function vary(opts) {
|
|
|
872
985
|
createdAt: new Date().toISOString()
|
|
873
986
|
};
|
|
874
987
|
persistence.saveStash(stash);
|
|
875
|
-
emit2(onProgress, { type: "generating", stashId });
|
|
988
|
+
emit2(onProgress, { type: "generating", stashId, number: stashNumber });
|
|
876
989
|
const varyPrompt = `The user wants to vary the current UI. Apply this change: ${prompt}`;
|
|
877
990
|
const aiProcess = startAiProcess(stashId, varyPrompt, worktree.path);
|
|
878
991
|
try {
|
|
@@ -1217,8 +1330,8 @@ class StashService {
|
|
|
1217
1330
|
});
|
|
1218
1331
|
}
|
|
1219
1332
|
}
|
|
1220
|
-
async
|
|
1221
|
-
const component = this.selectedComponent;
|
|
1333
|
+
async message(projectId, chatId, message, referenceStashIds, componentContext) {
|
|
1334
|
+
const component = componentContext ? { name: componentContext.name, filePath: this.selectedComponent?.filePath || "" } : this.selectedComponent;
|
|
1222
1335
|
let sourceCode = "";
|
|
1223
1336
|
const filePath = component?.filePath || "";
|
|
1224
1337
|
if (filePath && filePath !== "auto-detect") {
|
|
@@ -1238,8 +1351,11 @@ ${refs.join(`
|
|
|
1238
1351
|
}
|
|
1239
1352
|
}
|
|
1240
1353
|
const chatPrompt = [
|
|
1241
|
-
"
|
|
1242
|
-
"
|
|
1354
|
+
"You are helping the user explore UI design variations for their project.",
|
|
1355
|
+
"You have access to stashes MCP tools to generate, list, browse, vary, and apply stashes.",
|
|
1356
|
+
"If the user asks you to generate, create, or make variations, use the stashes_generate tool.",
|
|
1357
|
+
"If the user asks to vary an existing stash, use the stashes_vary tool.",
|
|
1358
|
+
"Otherwise, respond conversationally about their project and stashes.",
|
|
1243
1359
|
"",
|
|
1244
1360
|
component ? `Component: ${component.name}` : "",
|
|
1245
1361
|
filePath !== "auto-detect" ? `File: ${filePath}` : "",
|
|
@@ -1250,7 +1366,7 @@ ${sourceCode.substring(0, 3000)}
|
|
|
1250
1366
|
\`\`\`` : "",
|
|
1251
1367
|
stashContext,
|
|
1252
1368
|
"",
|
|
1253
|
-
`User
|
|
1369
|
+
`User: ${message}`
|
|
1254
1370
|
].filter(Boolean).join(`
|
|
1255
1371
|
`);
|
|
1256
1372
|
const aiProcess = startAiProcess("chat", chatPrompt, this.projectPath);
|
|
@@ -1259,12 +1375,60 @@ ${sourceCode.substring(0, 3000)}
|
|
|
1259
1375
|
for await (const chunk of parseClaudeStream(aiProcess.process)) {
|
|
1260
1376
|
if (chunk.type === "text") {
|
|
1261
1377
|
fullResponse += chunk.content;
|
|
1262
|
-
this.broadcast({
|
|
1378
|
+
this.broadcast({
|
|
1379
|
+
type: "ai_stream",
|
|
1380
|
+
content: chunk.content,
|
|
1381
|
+
streamType: "text",
|
|
1382
|
+
source: "chat"
|
|
1383
|
+
});
|
|
1384
|
+
} else if (chunk.type === "thinking") {
|
|
1385
|
+
this.broadcast({
|
|
1386
|
+
type: "ai_stream",
|
|
1387
|
+
content: chunk.content,
|
|
1388
|
+
streamType: "thinking",
|
|
1389
|
+
source: "chat"
|
|
1390
|
+
});
|
|
1391
|
+
} else if (chunk.type === "tool_use") {
|
|
1392
|
+
let toolName = "unknown";
|
|
1393
|
+
let toolParams = {};
|
|
1394
|
+
try {
|
|
1395
|
+
const parsed = JSON.parse(chunk.content);
|
|
1396
|
+
toolName = parsed.tool || parsed.name || "unknown";
|
|
1397
|
+
toolParams = parsed.input || parsed.params || {};
|
|
1398
|
+
} catch {}
|
|
1399
|
+
this.broadcast({
|
|
1400
|
+
type: "ai_stream",
|
|
1401
|
+
content: chunk.content,
|
|
1402
|
+
streamType: "tool_start",
|
|
1403
|
+
source: "chat",
|
|
1404
|
+
toolName,
|
|
1405
|
+
toolParams,
|
|
1406
|
+
toolStatus: "running"
|
|
1407
|
+
});
|
|
1408
|
+
} else if (chunk.type === "tool_result") {
|
|
1409
|
+
let toolName = "unknown";
|
|
1410
|
+
let toolResult = "";
|
|
1411
|
+
try {
|
|
1412
|
+
const parsed = JSON.parse(chunk.content);
|
|
1413
|
+
toolName = parsed.tool || parsed.name || "unknown";
|
|
1414
|
+
toolResult = typeof parsed.result === "string" ? parsed.result.substring(0, 200) : JSON.stringify(parsed.result).substring(0, 200);
|
|
1415
|
+
} catch {
|
|
1416
|
+
toolResult = chunk.content.substring(0, 200);
|
|
1417
|
+
}
|
|
1418
|
+
this.broadcast({
|
|
1419
|
+
type: "ai_stream",
|
|
1420
|
+
content: chunk.content,
|
|
1421
|
+
streamType: "tool_end",
|
|
1422
|
+
source: "chat",
|
|
1423
|
+
toolName,
|
|
1424
|
+
toolStatus: "completed",
|
|
1425
|
+
toolResult
|
|
1426
|
+
});
|
|
1263
1427
|
}
|
|
1264
1428
|
}
|
|
1265
1429
|
await aiProcess.process.exited;
|
|
1266
1430
|
if (fullResponse) {
|
|
1267
|
-
this.persistence.saveChatMessage(projectId, {
|
|
1431
|
+
this.persistence.saveChatMessage(projectId, chatId, {
|
|
1268
1432
|
id: crypto.randomUUID(),
|
|
1269
1433
|
role: "assistant",
|
|
1270
1434
|
content: fullResponse,
|
|
@@ -1275,7 +1439,7 @@ ${sourceCode.substring(0, 3000)}
|
|
|
1275
1439
|
} catch (err) {
|
|
1276
1440
|
this.broadcast({
|
|
1277
1441
|
type: "ai_stream",
|
|
1278
|
-
content: `
|
|
1442
|
+
content: `Error: ${err instanceof Error ? err.message : String(err)}`,
|
|
1279
1443
|
streamType: "text",
|
|
1280
1444
|
source: "chat"
|
|
1281
1445
|
});
|
|
@@ -1288,7 +1452,12 @@ ${sourceCode.substring(0, 3000)}
|
|
|
1288
1452
|
case "generating":
|
|
1289
1453
|
case "screenshotting":
|
|
1290
1454
|
case "ready":
|
|
1291
|
-
this.broadcast({
|
|
1455
|
+
this.broadcast({
|
|
1456
|
+
type: "stash:status",
|
|
1457
|
+
stashId: event.stashId,
|
|
1458
|
+
status: event.type === "ready" ? "ready" : event.type,
|
|
1459
|
+
..."number" in event ? { number: event.number } : {}
|
|
1460
|
+
});
|
|
1292
1461
|
if (event.type === "ready" && "screenshotPath" in event && event.screenshotPath) {
|
|
1293
1462
|
this.broadcast({ type: "stash:screenshot", stashId: event.stashId, url: event.screenshotPath });
|
|
1294
1463
|
}
|
|
@@ -1296,9 +1465,11 @@ ${sourceCode.substring(0, 3000)}
|
|
|
1296
1465
|
case "error":
|
|
1297
1466
|
this.broadcast({ type: "stash:error", stashId: event.stashId, error: event.error });
|
|
1298
1467
|
break;
|
|
1299
|
-
case "ai_stream":
|
|
1300
|
-
|
|
1468
|
+
case "ai_stream": {
|
|
1469
|
+
const streamType = event.streamType === "tool_use" ? "tool_start" : event.streamType;
|
|
1470
|
+
this.broadcast({ type: "ai_stream", content: event.content, streamType });
|
|
1301
1471
|
break;
|
|
1472
|
+
}
|
|
1302
1473
|
}
|
|
1303
1474
|
}
|
|
1304
1475
|
async generate(projectId, prompt, stashCount = DEFAULT_STASH_COUNT, referenceStashIds) {
|
|
@@ -1373,7 +1544,14 @@ function createWebSocketHandler(projectPath, userDevPort, appProxyPort) {
|
|
|
1373
1544
|
open(ws) {
|
|
1374
1545
|
clients.add(ws);
|
|
1375
1546
|
logger.info("ws", "client connected", { total: clients.size });
|
|
1376
|
-
|
|
1547
|
+
const project = ensureProject(persistence);
|
|
1548
|
+
ws.send(JSON.stringify({
|
|
1549
|
+
type: "server_ready",
|
|
1550
|
+
port: userDevPort,
|
|
1551
|
+
appProxyPort,
|
|
1552
|
+
projectId: project.id,
|
|
1553
|
+
projectName: project.name
|
|
1554
|
+
}));
|
|
1377
1555
|
},
|
|
1378
1556
|
async message(ws, message) {
|
|
1379
1557
|
const raw = typeof message === "string" ? message : new TextDecoder().decode(message);
|
|
@@ -1392,28 +1570,17 @@ function createWebSocketHandler(projectPath, userDevPort, appProxyPort) {
|
|
|
1392
1570
|
case "select_component":
|
|
1393
1571
|
stashService.setSelectedComponent(event.component);
|
|
1394
1572
|
break;
|
|
1395
|
-
case "
|
|
1396
|
-
persistence.saveChatMessage(event.projectId, {
|
|
1573
|
+
case "message":
|
|
1574
|
+
persistence.saveChatMessage(event.projectId, event.chatId, {
|
|
1397
1575
|
id: crypto.randomUUID(),
|
|
1398
1576
|
role: "user",
|
|
1399
1577
|
content: event.message,
|
|
1400
1578
|
type: "text",
|
|
1401
|
-
createdAt: new Date().toISOString()
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
break;
|
|
1405
|
-
case "generate":
|
|
1406
|
-
persistence.saveChatMessage(event.projectId, {
|
|
1407
|
-
id: crypto.randomUUID(),
|
|
1408
|
-
role: "user",
|
|
1409
|
-
content: event.prompt,
|
|
1410
|
-
type: "text",
|
|
1411
|
-
createdAt: new Date().toISOString()
|
|
1579
|
+
createdAt: new Date().toISOString(),
|
|
1580
|
+
referenceStashIds: event.referenceStashIds,
|
|
1581
|
+
componentContext: event.componentContext
|
|
1412
1582
|
});
|
|
1413
|
-
await stashService.
|
|
1414
|
-
break;
|
|
1415
|
-
case "vary":
|
|
1416
|
-
await stashService.vary(event.sourceStashId, event.prompt);
|
|
1583
|
+
await stashService.message(event.projectId, event.chatId, event.message, event.referenceStashIds, event.componentContext);
|
|
1417
1584
|
break;
|
|
1418
1585
|
case "interact":
|
|
1419
1586
|
await stashService.switchPreview(event.stashId, event.sortedStashIds);
|