stashes 0.1.57 → 0.1.58
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 +42 -29
- package/dist/mcp.js +42 -29
- package/dist/web/assets/index-WpgHkzXv.js +97 -0
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
- package/dist/web/assets/index-DLRxgF4c.js +0 -97
package/dist/cli.js
CHANGED
|
@@ -769,50 +769,61 @@ ${truncatedDiff}`;
|
|
|
769
769
|
return "";
|
|
770
770
|
}
|
|
771
771
|
}
|
|
772
|
-
function buildScreenshotPrompt(port, diff, screenshotDir, stashId) {
|
|
772
|
+
function buildScreenshotPrompt(port, diff, screenshotDir, stashId, componentPath) {
|
|
773
773
|
const outputPath = join5(screenshotDir, `${stashId}.png`);
|
|
774
774
|
return [
|
|
775
|
-
"##
|
|
775
|
+
"## You are a screenshot agent. Your goal: capture a screenshot showing the UI changes described in the diff below.",
|
|
776
776
|
"",
|
|
777
|
-
"
|
|
778
|
-
"-
|
|
779
|
-
"-
|
|
780
|
-
"
|
|
781
|
-
"
|
|
782
|
-
"-
|
|
777
|
+
"## RULES",
|
|
778
|
+
"- ONLY use Playwright MCP tools (prefixed with mcp__plugin_playwright_playwright__)",
|
|
779
|
+
"- Do NOT call: ToolSearch, Skill, Agent, TodoWrite, TaskCreate, TaskUpdate,",
|
|
780
|
+
" mcp__UseAI__*, mcp__stashes__*, mcp__plugin_drills__*, mcp__plugin_coverit__*,",
|
|
781
|
+
" EnterPlanMode, ExitPlanMode, WebSearch, WebFetch, LSP, Read, Write, Edit, Glob, Grep",
|
|
782
|
+
"- You have a strict time budget. Be fast and decisive.",
|
|
783
783
|
"",
|
|
784
|
-
|
|
784
|
+
`## App: http://localhost:${port}`,
|
|
785
|
+
componentPath ? `## Target component file: ${componentPath}` : "",
|
|
785
786
|
"",
|
|
786
|
-
|
|
787
|
-
"",
|
|
788
|
-
"## Git diff (shows what changed \u2014 use this to decide where to navigate):",
|
|
787
|
+
"## Git diff of changes:",
|
|
789
788
|
"```",
|
|
790
789
|
diff,
|
|
791
790
|
"```",
|
|
792
791
|
"",
|
|
793
|
-
"##
|
|
794
|
-
|
|
795
|
-
"
|
|
796
|
-
"
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
"
|
|
792
|
+
"## Your task",
|
|
793
|
+
"Study the diff above to understand:",
|
|
794
|
+
"1. WHAT changed (component, styles, layout, content)",
|
|
795
|
+
"2. WHERE it lives in the app (which route? which section of the page? is it behind a tab/modal/click?)",
|
|
796
|
+
"3. WHAT STATE is needed to see it (does a button need to be clicked? a tab selected? a form filled?)",
|
|
797
|
+
"",
|
|
798
|
+
"Then use Playwright tools to navigate there and capture it:",
|
|
799
|
+
"",
|
|
800
|
+
"**Available Playwright tools:**",
|
|
801
|
+
"- `mcp__plugin_playwright_playwright__browser_navigate` \u2014 go to a URL",
|
|
802
|
+
"- `mcp__plugin_playwright_playwright__browser_snapshot` \u2014 get the page accessibility tree (use this to find elements)",
|
|
803
|
+
"- `mcp__plugin_playwright_playwright__browser_click` \u2014 click an element (use ref from snapshot)",
|
|
804
|
+
"- `mcp__plugin_playwright_playwright__browser_hover` \u2014 hover over an element",
|
|
805
|
+
"- `mcp__plugin_playwright_playwright__browser_evaluate` \u2014 run JS on the page (e.g. scroll, trigger state)",
|
|
806
|
+
"- `mcp__plugin_playwright_playwright__browser_take_screenshot` \u2014 capture the screenshot",
|
|
800
807
|
"",
|
|
808
|
+
"**Typical flow:**",
|
|
809
|
+
`1. Navigate to http://localhost:${port} (or a sub-route if the diff indicates one)`,
|
|
810
|
+
"2. Take a snapshot to understand the page layout",
|
|
811
|
+
"3. If the changed component is not visible: scroll to it, click a tab, open a modal \u2014 whatever is needed",
|
|
812
|
+
"4. Take the screenshot once the changed component is visible",
|
|
813
|
+
"",
|
|
814
|
+
`## Output \u2014 after taking the screenshot, respond with ONLY this JSON:`,
|
|
801
815
|
"```json",
|
|
802
816
|
"{",
|
|
803
817
|
' "screenshots": [',
|
|
804
818
|
" {",
|
|
805
819
|
` "path": "${outputPath}",`,
|
|
806
|
-
' "label": "
|
|
807
|
-
' "route": "/",',
|
|
820
|
+
' "label": "Brief description of what the screenshot shows",',
|
|
821
|
+
' "route": "/the-route-you-navigated-to",',
|
|
808
822
|
' "isPrimary": true',
|
|
809
823
|
" }",
|
|
810
824
|
" ]",
|
|
811
825
|
"}",
|
|
812
|
-
"```"
|
|
813
|
-
"",
|
|
814
|
-
"REMEMBER: Do NOT call ToolSearch, Skill, UseAI, Read, or any tool not listed above.",
|
|
815
|
-
"You have a strict time limit. Just navigate, screenshot, output JSON, done."
|
|
826
|
+
"```"
|
|
816
827
|
].join(`
|
|
817
828
|
`);
|
|
818
829
|
}
|
|
@@ -846,7 +857,7 @@ async function fallbackScreenshot(port, projectPath, stashId) {
|
|
|
846
857
|
}
|
|
847
858
|
}
|
|
848
859
|
async function captureSmartScreenshots(opts) {
|
|
849
|
-
const { projectPath, stashId, stashBranch, parentBranch, worktreePath, port, model = "sonnet", timeout = DEFAULT_TIMEOUT } = opts;
|
|
860
|
+
const { projectPath, stashId, stashBranch, parentBranch, worktreePath, port, model = "sonnet", timeout = DEFAULT_TIMEOUT, componentPath } = opts;
|
|
850
861
|
const screenshotDir = join5(projectPath, SCREENSHOTS_DIR2);
|
|
851
862
|
if (!existsSync5(screenshotDir)) {
|
|
852
863
|
mkdirSync4(screenshotDir, { recursive: true });
|
|
@@ -857,7 +868,7 @@ async function captureSmartScreenshots(opts) {
|
|
|
857
868
|
return fallbackScreenshot(port, projectPath, stashId);
|
|
858
869
|
}
|
|
859
870
|
const processId = `screenshot-ai-${stashId}`;
|
|
860
|
-
const prompt = buildScreenshotPrompt(port, diff, screenshotDir, stashId);
|
|
871
|
+
const prompt = buildScreenshotPrompt(port, diff, screenshotDir, stashId, componentPath);
|
|
861
872
|
const modelFlag = model === "sonnet" ? "sonnet" : "haiku";
|
|
862
873
|
const aiProcess = startAiProcess({
|
|
863
874
|
id: processId,
|
|
@@ -1129,7 +1140,8 @@ async function generate(opts) {
|
|
|
1129
1140
|
worktreePath: screenshotWorktree.path,
|
|
1130
1141
|
port,
|
|
1131
1142
|
model: opts.screenshotModel,
|
|
1132
|
-
timeout: opts.screenshotTimeout
|
|
1143
|
+
timeout: opts.screenshotTimeout,
|
|
1144
|
+
componentPath: stash.componentPath ?? undefined
|
|
1133
1145
|
});
|
|
1134
1146
|
const readyStash = { ...generatedStash, status: "ready", screenshotUrl: primary, screenshots };
|
|
1135
1147
|
completedStashes.push(readyStash);
|
|
@@ -1295,7 +1307,8 @@ async function vary(opts) {
|
|
|
1295
1307
|
worktreePath: screenshotWorktree.path,
|
|
1296
1308
|
port,
|
|
1297
1309
|
model: opts.screenshotModel,
|
|
1298
|
-
timeout: opts.screenshotTimeout
|
|
1310
|
+
timeout: opts.screenshotTimeout,
|
|
1311
|
+
componentPath: stash.componentPath ?? undefined
|
|
1299
1312
|
});
|
|
1300
1313
|
screenshotPath = result.primary;
|
|
1301
1314
|
screenshots = [...result.screenshots];
|
package/dist/mcp.js
CHANGED
|
@@ -754,50 +754,61 @@ ${truncatedDiff}`;
|
|
|
754
754
|
return "";
|
|
755
755
|
}
|
|
756
756
|
}
|
|
757
|
-
function buildScreenshotPrompt(port, diff, screenshotDir, stashId) {
|
|
757
|
+
function buildScreenshotPrompt(port, diff, screenshotDir, stashId, componentPath) {
|
|
758
758
|
const outputPath = join5(screenshotDir, `${stashId}.png`);
|
|
759
759
|
return [
|
|
760
|
-
"##
|
|
760
|
+
"## You are a screenshot agent. Your goal: capture a screenshot showing the UI changes described in the diff below.",
|
|
761
761
|
"",
|
|
762
|
-
"
|
|
763
|
-
"-
|
|
764
|
-
"-
|
|
765
|
-
"
|
|
766
|
-
"
|
|
767
|
-
"-
|
|
762
|
+
"## RULES",
|
|
763
|
+
"- ONLY use Playwright MCP tools (prefixed with mcp__plugin_playwright_playwright__)",
|
|
764
|
+
"- Do NOT call: ToolSearch, Skill, Agent, TodoWrite, TaskCreate, TaskUpdate,",
|
|
765
|
+
" mcp__UseAI__*, mcp__stashes__*, mcp__plugin_drills__*, mcp__plugin_coverit__*,",
|
|
766
|
+
" EnterPlanMode, ExitPlanMode, WebSearch, WebFetch, LSP, Read, Write, Edit, Glob, Grep",
|
|
767
|
+
"- You have a strict time budget. Be fast and decisive.",
|
|
768
768
|
"",
|
|
769
|
-
|
|
769
|
+
`## App: http://localhost:${port}`,
|
|
770
|
+
componentPath ? `## Target component file: ${componentPath}` : "",
|
|
770
771
|
"",
|
|
771
|
-
|
|
772
|
-
"",
|
|
773
|
-
"## Git diff (shows what changed \u2014 use this to decide where to navigate):",
|
|
772
|
+
"## Git diff of changes:",
|
|
774
773
|
"```",
|
|
775
774
|
diff,
|
|
776
775
|
"```",
|
|
777
776
|
"",
|
|
778
|
-
"##
|
|
779
|
-
|
|
780
|
-
"
|
|
781
|
-
"
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
"
|
|
777
|
+
"## Your task",
|
|
778
|
+
"Study the diff above to understand:",
|
|
779
|
+
"1. WHAT changed (component, styles, layout, content)",
|
|
780
|
+
"2. WHERE it lives in the app (which route? which section of the page? is it behind a tab/modal/click?)",
|
|
781
|
+
"3. WHAT STATE is needed to see it (does a button need to be clicked? a tab selected? a form filled?)",
|
|
782
|
+
"",
|
|
783
|
+
"Then use Playwright tools to navigate there and capture it:",
|
|
784
|
+
"",
|
|
785
|
+
"**Available Playwright tools:**",
|
|
786
|
+
"- `mcp__plugin_playwright_playwright__browser_navigate` \u2014 go to a URL",
|
|
787
|
+
"- `mcp__plugin_playwright_playwright__browser_snapshot` \u2014 get the page accessibility tree (use this to find elements)",
|
|
788
|
+
"- `mcp__plugin_playwright_playwright__browser_click` \u2014 click an element (use ref from snapshot)",
|
|
789
|
+
"- `mcp__plugin_playwright_playwright__browser_hover` \u2014 hover over an element",
|
|
790
|
+
"- `mcp__plugin_playwright_playwright__browser_evaluate` \u2014 run JS on the page (e.g. scroll, trigger state)",
|
|
791
|
+
"- `mcp__plugin_playwright_playwright__browser_take_screenshot` \u2014 capture the screenshot",
|
|
785
792
|
"",
|
|
793
|
+
"**Typical flow:**",
|
|
794
|
+
`1. Navigate to http://localhost:${port} (or a sub-route if the diff indicates one)`,
|
|
795
|
+
"2. Take a snapshot to understand the page layout",
|
|
796
|
+
"3. If the changed component is not visible: scroll to it, click a tab, open a modal \u2014 whatever is needed",
|
|
797
|
+
"4. Take the screenshot once the changed component is visible",
|
|
798
|
+
"",
|
|
799
|
+
`## Output \u2014 after taking the screenshot, respond with ONLY this JSON:`,
|
|
786
800
|
"```json",
|
|
787
801
|
"{",
|
|
788
802
|
' "screenshots": [',
|
|
789
803
|
" {",
|
|
790
804
|
` "path": "${outputPath}",`,
|
|
791
|
-
' "label": "
|
|
792
|
-
' "route": "/",',
|
|
805
|
+
' "label": "Brief description of what the screenshot shows",',
|
|
806
|
+
' "route": "/the-route-you-navigated-to",',
|
|
793
807
|
' "isPrimary": true',
|
|
794
808
|
" }",
|
|
795
809
|
" ]",
|
|
796
810
|
"}",
|
|
797
|
-
"```"
|
|
798
|
-
"",
|
|
799
|
-
"REMEMBER: Do NOT call ToolSearch, Skill, UseAI, Read, or any tool not listed above.",
|
|
800
|
-
"You have a strict time limit. Just navigate, screenshot, output JSON, done."
|
|
811
|
+
"```"
|
|
801
812
|
].join(`
|
|
802
813
|
`);
|
|
803
814
|
}
|
|
@@ -831,7 +842,7 @@ async function fallbackScreenshot(port, projectPath, stashId) {
|
|
|
831
842
|
}
|
|
832
843
|
}
|
|
833
844
|
async function captureSmartScreenshots(opts) {
|
|
834
|
-
const { projectPath, stashId, stashBranch, parentBranch, worktreePath, port, model = "sonnet", timeout = DEFAULT_TIMEOUT } = opts;
|
|
845
|
+
const { projectPath, stashId, stashBranch, parentBranch, worktreePath, port, model = "sonnet", timeout = DEFAULT_TIMEOUT, componentPath } = opts;
|
|
835
846
|
const screenshotDir = join5(projectPath, SCREENSHOTS_DIR2);
|
|
836
847
|
if (!existsSync5(screenshotDir)) {
|
|
837
848
|
mkdirSync4(screenshotDir, { recursive: true });
|
|
@@ -842,7 +853,7 @@ async function captureSmartScreenshots(opts) {
|
|
|
842
853
|
return fallbackScreenshot(port, projectPath, stashId);
|
|
843
854
|
}
|
|
844
855
|
const processId = `screenshot-ai-${stashId}`;
|
|
845
|
-
const prompt = buildScreenshotPrompt(port, diff, screenshotDir, stashId);
|
|
856
|
+
const prompt = buildScreenshotPrompt(port, diff, screenshotDir, stashId, componentPath);
|
|
846
857
|
const modelFlag = model === "sonnet" ? "sonnet" : "haiku";
|
|
847
858
|
const aiProcess = startAiProcess({
|
|
848
859
|
id: processId,
|
|
@@ -1114,7 +1125,8 @@ async function generate(opts) {
|
|
|
1114
1125
|
worktreePath: screenshotWorktree.path,
|
|
1115
1126
|
port,
|
|
1116
1127
|
model: opts.screenshotModel,
|
|
1117
|
-
timeout: opts.screenshotTimeout
|
|
1128
|
+
timeout: opts.screenshotTimeout,
|
|
1129
|
+
componentPath: stash.componentPath ?? undefined
|
|
1118
1130
|
});
|
|
1119
1131
|
const readyStash = { ...generatedStash, status: "ready", screenshotUrl: primary, screenshots };
|
|
1120
1132
|
completedStashes.push(readyStash);
|
|
@@ -1280,7 +1292,8 @@ async function vary(opts) {
|
|
|
1280
1292
|
worktreePath: screenshotWorktree.path,
|
|
1281
1293
|
port,
|
|
1282
1294
|
model: opts.screenshotModel,
|
|
1283
|
-
timeout: opts.screenshotTimeout
|
|
1295
|
+
timeout: opts.screenshotTimeout,
|
|
1296
|
+
componentPath: stash.componentPath ?? undefined
|
|
1284
1297
|
});
|
|
1285
1298
|
screenshotPath = result.primary;
|
|
1286
1299
|
screenshots = [...result.screenshots];
|