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 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
- "## CRITICAL: You are an automated screenshot subprocess. Follow these rules exactly.",
775
+ "## You are a screenshot agent. Your goal: capture a screenshot showing the UI changes described in the diff below.",
776
776
  "",
777
- "FORBIDDEN \u2014 do NOT call any of these tools:",
778
- "- ToolSearch, Skill, Agent, TodoWrite, TaskCreate, TaskUpdate, TaskList",
779
- "- mcp__UseAI__useai_start, mcp__UseAI__useai_end, mcp__UseAI__useai_heartbeat",
780
- "- mcp__stashes__*, mcp__plugin_drills__*, mcp__plugin_coverit__*",
781
- "- EnterPlanMode, ExitPlanMode, WebSearch, WebFetch, LSP",
782
- "- Read, Write, Edit, Glob, Grep (you do NOT need to read code)",
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
- "YOUR ONLY JOB: navigate to the app and take a screenshot using Playwright.",
784
+ `## App: http://localhost:${port}`,
785
+ componentPath ? `## Target component file: ${componentPath}` : "",
785
786
  "",
786
- `## App URL: http://localhost:${port}`,
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
- "## Steps (do these in order, nothing else):",
794
- `1. Navigate: call mcp__plugin_playwright_playwright__browser_navigate with url "http://localhost:${port}"`,
795
- "2. Wait 3 seconds for the page to render",
796
- "3. If the diff shows changes below the fold, scroll down using mcp__plugin_playwright_playwright__browser_evaluate",
797
- `4. Take screenshot: call mcp__plugin_playwright_playwright__browser_take_screenshot with type "png"`,
798
- ` The screenshot will be saved automatically.`,
799
- "5. Output ONLY this JSON (replace the screenshot path with the actual path returned):",
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": "Description of what is shown",',
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
- "## CRITICAL: You are an automated screenshot subprocess. Follow these rules exactly.",
760
+ "## You are a screenshot agent. Your goal: capture a screenshot showing the UI changes described in the diff below.",
761
761
  "",
762
- "FORBIDDEN \u2014 do NOT call any of these tools:",
763
- "- ToolSearch, Skill, Agent, TodoWrite, TaskCreate, TaskUpdate, TaskList",
764
- "- mcp__UseAI__useai_start, mcp__UseAI__useai_end, mcp__UseAI__useai_heartbeat",
765
- "- mcp__stashes__*, mcp__plugin_drills__*, mcp__plugin_coverit__*",
766
- "- EnterPlanMode, ExitPlanMode, WebSearch, WebFetch, LSP",
767
- "- Read, Write, Edit, Glob, Grep (you do NOT need to read code)",
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
- "YOUR ONLY JOB: navigate to the app and take a screenshot using Playwright.",
769
+ `## App: http://localhost:${port}`,
770
+ componentPath ? `## Target component file: ${componentPath}` : "",
770
771
  "",
771
- `## App URL: http://localhost:${port}`,
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
- "## Steps (do these in order, nothing else):",
779
- `1. Navigate: call mcp__plugin_playwright_playwright__browser_navigate with url "http://localhost:${port}"`,
780
- "2. Wait 3 seconds for the page to render",
781
- "3. If the diff shows changes below the fold, scroll down using mcp__plugin_playwright_playwright__browser_evaluate",
782
- `4. Take screenshot: call mcp__plugin_playwright_playwright__browser_take_screenshot with type "png"`,
783
- ` The screenshot will be saved automatically.`,
784
- "5. Output ONLY this JSON (replace the screenshot path with the actual path returned):",
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": "Description of what is shown",',
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];