stashes 0.1.35 → 0.1.37
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
CHANGED
|
@@ -851,8 +851,14 @@ ${truncatedDiff}`;
|
|
|
851
851
|
}
|
|
852
852
|
function buildScreenshotPrompt(port, diff, screenshotDir, stashId) {
|
|
853
853
|
return [
|
|
854
|
-
"You are a screenshot assistant.
|
|
855
|
-
"
|
|
854
|
+
"You are a screenshot assistant. Your ONLY job is to take screenshots of a running web app using Playwright MCP tools.",
|
|
855
|
+
"",
|
|
856
|
+
"IMPORTANT RULES:",
|
|
857
|
+
"- ONLY use these Playwright MCP tools: mcp__playwright__browser_navigate, mcp__playwright__browser_take_screenshot, mcp__playwright__browser_click, mcp__playwright__browser_snapshot",
|
|
858
|
+
"- Do NOT use any other tools (no Bash, Read, Grep, Agent, ToolSearch, etc.)",
|
|
859
|
+
"- Do NOT start any sessions or call useai tools",
|
|
860
|
+
"- Do NOT read or analyze code files \u2014 the diff below tells you everything",
|
|
861
|
+
"- Be fast \u2014 you have a strict time limit",
|
|
856
862
|
"",
|
|
857
863
|
`## The app is running at: http://localhost:${port}`,
|
|
858
864
|
"",
|
|
@@ -861,22 +867,18 @@ function buildScreenshotPrompt(port, diff, screenshotDir, stashId) {
|
|
|
861
867
|
diff,
|
|
862
868
|
"```",
|
|
863
869
|
"",
|
|
864
|
-
"##
|
|
865
|
-
|
|
866
|
-
"2.
|
|
867
|
-
"3.
|
|
868
|
-
"
|
|
869
|
-
|
|
870
|
-
"
|
|
871
|
-
" - Take a screenshot using browser_take_screenshot",
|
|
872
|
-
"4. Decide which screenshot shows the MOST visually significant change \u2014 mark it as primary",
|
|
870
|
+
"## Steps:",
|
|
871
|
+
`1. Call mcp__playwright__browser_navigate with url "http://localhost:${port}" to open the app`,
|
|
872
|
+
"2. From the diff, determine which page/route shows the changed components",
|
|
873
|
+
"3. If the change is on a different route, navigate to it",
|
|
874
|
+
"4. If the change is behind an interaction (tab click, modal open), perform it with mcp__playwright__browser_click",
|
|
875
|
+
`5. Call mcp__playwright__browser_take_screenshot to capture the page`,
|
|
876
|
+
"6. Respond with the JSON below",
|
|
873
877
|
"",
|
|
874
|
-
`## Screenshot save
|
|
875
|
-
|
|
876
|
-
`- Additional: ${join6(screenshotDir, `${stashId}-1.png`)}, ${join6(screenshotDir, `${stashId}-2.png`)}, etc.`,
|
|
878
|
+
`## Screenshot save directory: ${screenshotDir}`,
|
|
879
|
+
`Use filename "${stashId}.png" for the primary screenshot.`,
|
|
877
880
|
"",
|
|
878
|
-
"##
|
|
879
|
-
"Respond with ONLY this JSON (no markdown fences):",
|
|
881
|
+
"## After taking screenshots, respond with ONLY this JSON:",
|
|
880
882
|
"{",
|
|
881
883
|
' "screenshots": [',
|
|
882
884
|
" {",
|
|
@@ -1113,9 +1115,9 @@ async function generate(opts) {
|
|
|
1113
1115
|
await wtGit.commit(`stashes: stash ${stashId}`);
|
|
1114
1116
|
} catch {}
|
|
1115
1117
|
await worktreeManager.removeGeneration(stashId);
|
|
1116
|
-
const
|
|
1117
|
-
completedStashes.push(
|
|
1118
|
-
persistence.saveStash(
|
|
1118
|
+
const generatedStash = { ...stash, status: "screenshotting" };
|
|
1119
|
+
completedStashes.push(generatedStash);
|
|
1120
|
+
persistence.saveStash(generatedStash);
|
|
1119
1121
|
} catch (error) {
|
|
1120
1122
|
const errorMsg = error instanceof Error ? error.message : "Unknown error";
|
|
1121
1123
|
persistence.saveStash({ ...stash, status: "error", error: errorMsg });
|
|
@@ -1155,7 +1157,7 @@ async function generate(opts) {
|
|
|
1155
1157
|
model: opts.screenshotModel,
|
|
1156
1158
|
timeout: opts.screenshotTimeout
|
|
1157
1159
|
});
|
|
1158
|
-
const updatedStash = { ...stash, screenshotUrl: primary, screenshots };
|
|
1160
|
+
const updatedStash = { ...stash, status: "ready", screenshotUrl: primary, screenshots };
|
|
1159
1161
|
persistence.saveStash(updatedStash);
|
|
1160
1162
|
const idx = completedStashes.indexOf(stash);
|
|
1161
1163
|
completedStashes[idx] = updatedStash;
|
|
@@ -1168,6 +1170,7 @@ async function generate(opts) {
|
|
|
1168
1170
|
logger.error("generation", `screenshot failed for ${stash.id}`, {
|
|
1169
1171
|
error: err instanceof Error ? err.message : String(err)
|
|
1170
1172
|
});
|
|
1173
|
+
persistence.saveStash({ ...stash, status: "ready" });
|
|
1171
1174
|
emit(onProgress, { type: "ready", stashId: stash.id, screenshotPath: "" });
|
|
1172
1175
|
}
|
|
1173
1176
|
}
|
|
@@ -1259,6 +1262,7 @@ async function vary(opts) {
|
|
|
1259
1262
|
await wtGit.commit(`stashes: vary ${stashId} from ${sourceStashId}`);
|
|
1260
1263
|
} catch {}
|
|
1261
1264
|
await worktreeManager.removeGeneration(stashId);
|
|
1265
|
+
persistence.saveStash({ ...stash, status: "screenshotting" });
|
|
1262
1266
|
emit2(onProgress, { type: "screenshotting", stashId });
|
|
1263
1267
|
let screenshotPath = "";
|
|
1264
1268
|
let screenshots = [];
|
|
@@ -2008,7 +2012,8 @@ function createWebSocketHandler(projectPath, userDevPort, appProxyPort) {
|
|
|
2008
2012
|
case "select_component":
|
|
2009
2013
|
stashService.setSelectedComponent(event.component);
|
|
2010
2014
|
break;
|
|
2011
|
-
case "message":
|
|
2015
|
+
case "message": {
|
|
2016
|
+
const isFirstMessage = persistence.getChatMessages(event.projectId, event.chatId).length === 0;
|
|
2012
2017
|
persistence.saveChatMessage(event.projectId, event.chatId, {
|
|
2013
2018
|
id: crypto.randomUUID(),
|
|
2014
2019
|
role: "user",
|
|
@@ -2018,8 +2023,16 @@ function createWebSocketHandler(projectPath, userDevPort, appProxyPort) {
|
|
|
2018
2023
|
referenceStashIds: event.referenceStashIds,
|
|
2019
2024
|
componentContext: event.componentContext
|
|
2020
2025
|
});
|
|
2026
|
+
if (isFirstMessage) {
|
|
2027
|
+
const chat = persistence.getChat(event.projectId, event.chatId);
|
|
2028
|
+
if (chat) {
|
|
2029
|
+
const title = event.message.length > 80 ? event.message.substring(0, 80).trimEnd() + "\u2026" : event.message;
|
|
2030
|
+
persistence.saveChat({ ...chat, title });
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2021
2033
|
await stashService.message(event.projectId, event.chatId, event.message, event.referenceStashIds, event.componentContext);
|
|
2022
2034
|
break;
|
|
2035
|
+
}
|
|
2023
2036
|
case "interact":
|
|
2024
2037
|
await stashService.switchPreview(event.stashId, event.sortedStashIds);
|
|
2025
2038
|
break;
|
package/dist/mcp.js
CHANGED
|
@@ -733,8 +733,14 @@ ${truncatedDiff}`;
|
|
|
733
733
|
}
|
|
734
734
|
function buildScreenshotPrompt(port, diff, screenshotDir, stashId) {
|
|
735
735
|
return [
|
|
736
|
-
"You are a screenshot assistant.
|
|
737
|
-
"
|
|
736
|
+
"You are a screenshot assistant. Your ONLY job is to take screenshots of a running web app using Playwright MCP tools.",
|
|
737
|
+
"",
|
|
738
|
+
"IMPORTANT RULES:",
|
|
739
|
+
"- ONLY use these Playwright MCP tools: mcp__playwright__browser_navigate, mcp__playwright__browser_take_screenshot, mcp__playwright__browser_click, mcp__playwright__browser_snapshot",
|
|
740
|
+
"- Do NOT use any other tools (no Bash, Read, Grep, Agent, ToolSearch, etc.)",
|
|
741
|
+
"- Do NOT start any sessions or call useai tools",
|
|
742
|
+
"- Do NOT read or analyze code files \u2014 the diff below tells you everything",
|
|
743
|
+
"- Be fast \u2014 you have a strict time limit",
|
|
738
744
|
"",
|
|
739
745
|
`## The app is running at: http://localhost:${port}`,
|
|
740
746
|
"",
|
|
@@ -743,22 +749,18 @@ function buildScreenshotPrompt(port, diff, screenshotDir, stashId) {
|
|
|
743
749
|
diff,
|
|
744
750
|
"```",
|
|
745
751
|
"",
|
|
746
|
-
"##
|
|
747
|
-
|
|
748
|
-
"2.
|
|
749
|
-
"3.
|
|
750
|
-
"
|
|
751
|
-
|
|
752
|
-
"
|
|
753
|
-
" - Take a screenshot using browser_take_screenshot",
|
|
754
|
-
"4. Decide which screenshot shows the MOST visually significant change \u2014 mark it as primary",
|
|
752
|
+
"## Steps:",
|
|
753
|
+
`1. Call mcp__playwright__browser_navigate with url "http://localhost:${port}" to open the app`,
|
|
754
|
+
"2. From the diff, determine which page/route shows the changed components",
|
|
755
|
+
"3. If the change is on a different route, navigate to it",
|
|
756
|
+
"4. If the change is behind an interaction (tab click, modal open), perform it with mcp__playwright__browser_click",
|
|
757
|
+
`5. Call mcp__playwright__browser_take_screenshot to capture the page`,
|
|
758
|
+
"6. Respond with the JSON below",
|
|
755
759
|
"",
|
|
756
|
-
`## Screenshot save
|
|
757
|
-
|
|
758
|
-
`- Additional: ${join5(screenshotDir, `${stashId}-1.png`)}, ${join5(screenshotDir, `${stashId}-2.png`)}, etc.`,
|
|
760
|
+
`## Screenshot save directory: ${screenshotDir}`,
|
|
761
|
+
`Use filename "${stashId}.png" for the primary screenshot.`,
|
|
759
762
|
"",
|
|
760
|
-
"##
|
|
761
|
-
"Respond with ONLY this JSON (no markdown fences):",
|
|
763
|
+
"## After taking screenshots, respond with ONLY this JSON:",
|
|
762
764
|
"{",
|
|
763
765
|
' "screenshots": [',
|
|
764
766
|
" {",
|
|
@@ -995,9 +997,9 @@ async function generate(opts) {
|
|
|
995
997
|
await wtGit.commit(`stashes: stash ${stashId}`);
|
|
996
998
|
} catch {}
|
|
997
999
|
await worktreeManager.removeGeneration(stashId);
|
|
998
|
-
const
|
|
999
|
-
completedStashes.push(
|
|
1000
|
-
persistence.saveStash(
|
|
1000
|
+
const generatedStash = { ...stash, status: "screenshotting" };
|
|
1001
|
+
completedStashes.push(generatedStash);
|
|
1002
|
+
persistence.saveStash(generatedStash);
|
|
1001
1003
|
} catch (error) {
|
|
1002
1004
|
const errorMsg = error instanceof Error ? error.message : "Unknown error";
|
|
1003
1005
|
persistence.saveStash({ ...stash, status: "error", error: errorMsg });
|
|
@@ -1037,7 +1039,7 @@ async function generate(opts) {
|
|
|
1037
1039
|
model: opts.screenshotModel,
|
|
1038
1040
|
timeout: opts.screenshotTimeout
|
|
1039
1041
|
});
|
|
1040
|
-
const updatedStash = { ...stash, screenshotUrl: primary, screenshots };
|
|
1042
|
+
const updatedStash = { ...stash, status: "ready", screenshotUrl: primary, screenshots };
|
|
1041
1043
|
persistence.saveStash(updatedStash);
|
|
1042
1044
|
const idx = completedStashes.indexOf(stash);
|
|
1043
1045
|
completedStashes[idx] = updatedStash;
|
|
@@ -1050,6 +1052,7 @@ async function generate(opts) {
|
|
|
1050
1052
|
logger.error("generation", `screenshot failed for ${stash.id}`, {
|
|
1051
1053
|
error: err instanceof Error ? err.message : String(err)
|
|
1052
1054
|
});
|
|
1055
|
+
persistence.saveStash({ ...stash, status: "ready" });
|
|
1053
1056
|
emit(onProgress, { type: "ready", stashId: stash.id, screenshotPath: "" });
|
|
1054
1057
|
}
|
|
1055
1058
|
}
|
|
@@ -1141,6 +1144,7 @@ async function vary(opts) {
|
|
|
1141
1144
|
await wtGit.commit(`stashes: vary ${stashId} from ${sourceStashId}`);
|
|
1142
1145
|
} catch {}
|
|
1143
1146
|
await worktreeManager.removeGeneration(stashId);
|
|
1147
|
+
persistence.saveStash({ ...stash, status: "screenshotting" });
|
|
1144
1148
|
emit2(onProgress, { type: "screenshotting", stashId });
|
|
1145
1149
|
let screenshotPath = "";
|
|
1146
1150
|
let screenshots = [];
|
|
@@ -2204,7 +2208,8 @@ function createWebSocketHandler(projectPath, userDevPort, appProxyPort) {
|
|
|
2204
2208
|
case "select_component":
|
|
2205
2209
|
stashService.setSelectedComponent(event.component);
|
|
2206
2210
|
break;
|
|
2207
|
-
case "message":
|
|
2211
|
+
case "message": {
|
|
2212
|
+
const isFirstMessage = persistence.getChatMessages(event.projectId, event.chatId).length === 0;
|
|
2208
2213
|
persistence.saveChatMessage(event.projectId, event.chatId, {
|
|
2209
2214
|
id: crypto.randomUUID(),
|
|
2210
2215
|
role: "user",
|
|
@@ -2214,8 +2219,16 @@ function createWebSocketHandler(projectPath, userDevPort, appProxyPort) {
|
|
|
2214
2219
|
referenceStashIds: event.referenceStashIds,
|
|
2215
2220
|
componentContext: event.componentContext
|
|
2216
2221
|
});
|
|
2222
|
+
if (isFirstMessage) {
|
|
2223
|
+
const chat = persistence.getChat(event.projectId, event.chatId);
|
|
2224
|
+
if (chat) {
|
|
2225
|
+
const title = event.message.length > 80 ? event.message.substring(0, 80).trimEnd() + "\u2026" : event.message;
|
|
2226
|
+
persistence.saveChat({ ...chat, title });
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2217
2229
|
await stashService.message(event.projectId, event.chatId, event.message, event.referenceStashIds, event.componentContext);
|
|
2218
2230
|
break;
|
|
2231
|
+
}
|
|
2219
2232
|
case "interact":
|
|
2220
2233
|
await stashService.switchPreview(event.stashId, event.sortedStashIds);
|
|
2221
2234
|
break;
|