@mindstudio-ai/remy 0.1.64 → 0.1.65

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/headless.js CHANGED
@@ -574,7 +574,7 @@ async function* streamChat(params) {
574
574
  var MAX_RETRIES = 3;
575
575
  var INITIAL_BACKOFF_MS = 1e3;
576
576
  function isRetryableError(error) {
577
- return /Network error/i.test(error) || /HTTP 5\d\d/i.test(error) || /Stream stalled/i.test(error);
577
+ return /Network error/i.test(error) || /HTTP 5\d\d/i.test(error) || /Stream stalled/i.test(error) || /overloaded/i.test(error);
578
578
  }
579
579
  function sleep(ms) {
580
580
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -1892,7 +1892,7 @@ function formatOccurrenceError(count, lines, filePath) {
1892
1892
  var editFileTool = {
1893
1893
  definition: {
1894
1894
  name: "editFile",
1895
- description: "Replace a string in a file. old_string must appear exactly once (minor indentation differences are handled automatically). Set replace_all to true to replace every occurrence at once. For bulk mechanical substitutions (renaming a variable, swapping colors), prefer replace_all. Always read the file first so you know the exact text to match.",
1895
+ description: "Replace a string in a file. old_string must appear exactly once (minor indentation differences are handled automatically). Set replace_all to true to replace every occurrence at once. For bulk mechanical substitutions (renaming a variable, swapping colors), prefer replace_all. Always read the file first so you know the exact text to match. When editing nested structures (objects, function bodies, arrays, template literals), always include the full enclosing structure in old_string rather than just an inner fragment. Replacing a partial slice from the middle of nested code is the most common source of syntax errors.",
1896
1896
  inputSchema: {
1897
1897
  type: "object",
1898
1898
  properties: {
@@ -3345,11 +3345,37 @@ var definition5 = {
3345
3345
  path: {
3346
3346
  type: "string",
3347
3347
  description: 'Navigate to this path before capturing (e.g. "/settings"). If omitted, screenshots the current page.'
3348
+ },
3349
+ instructions: {
3350
+ type: "string",
3351
+ description: "If the screenshot you need requires interaction first (dismissing a modal, clicking a tab, filling out a form, navigating a flow), describe the steps to get there. A browser automation agent will follow these instructions before capturing the screenshot."
3348
3352
  }
3349
3353
  }
3350
3354
  }
3351
3355
  };
3352
- async function execute5(input, onLog) {
3356
+ async function execute5(input, onLog, context) {
3357
+ if (input.instructions && context) {
3358
+ try {
3359
+ const task = input.path ? `Navigate to "${input.path}", then: ${input.instructions}. After completing these steps, take a full-page screenshot.` : `${input.instructions}. After completing these steps, take a full-page screenshot.`;
3360
+ const result = await browserAutomationTool.execute({ task }, context);
3361
+ const urlMatch = result.match(
3362
+ /https:\/\/[^\s"')]+\.(?:png|jpg|jpeg|webp)/i
3363
+ );
3364
+ if (!urlMatch) {
3365
+ return `Error: browser navigation completed but no screenshot URL was returned. Agent output: ${result}`;
3366
+ }
3367
+ const url = urlMatch[0];
3368
+ const analysisPrompt = input.prompt || SCREENSHOT_ANALYSIS_PROMPT;
3369
+ const analysis = await analyzeImage({
3370
+ prompt: analysisPrompt,
3371
+ imageUrl: url,
3372
+ onLog
3373
+ });
3374
+ return JSON.stringify({ url, analysis });
3375
+ } catch (err) {
3376
+ return `Error taking interactive screenshot: ${err.message}`;
3377
+ }
3378
+ }
3353
3379
  try {
3354
3380
  return await captureAndAnalyzeScreenshot({
3355
3381
  prompt: input.prompt,
@@ -3618,7 +3644,7 @@ async function executeDesignExpertTool(name, input, context, toolCallId, onLog)
3618
3644
  if (!tool) {
3619
3645
  return `Error: unknown tool "${name}"`;
3620
3646
  }
3621
- return tool.execute(input, onLog);
3647
+ return tool.execute(input, onLog, context);
3622
3648
  }
3623
3649
 
3624
3650
  // src/subagents/designExpert/prompt.ts
package/dist/index.js CHANGED
@@ -221,7 +221,7 @@ async function* streamChat(params) {
221
221
  }
222
222
  }
223
223
  function isRetryableError(error) {
224
- return /Network error/i.test(error) || /HTTP 5\d\d/i.test(error) || /Stream stalled/i.test(error);
224
+ return /Network error/i.test(error) || /HTTP 5\d\d/i.test(error) || /Stream stalled/i.test(error) || /overloaded/i.test(error);
225
225
  }
226
226
  function sleep(ms) {
227
227
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -1477,7 +1477,7 @@ var init_editFile = __esm({
1477
1477
  editFileTool = {
1478
1478
  definition: {
1479
1479
  name: "editFile",
1480
- description: "Replace a string in a file. old_string must appear exactly once (minor indentation differences are handled automatically). Set replace_all to true to replace every occurrence at once. For bulk mechanical substitutions (renaming a variable, swapping colors), prefer replace_all. Always read the file first so you know the exact text to match.",
1480
+ description: "Replace a string in a file. old_string must appear exactly once (minor indentation differences are handled automatically). Set replace_all to true to replace every occurrence at once. For bulk mechanical substitutions (renaming a variable, swapping colors), prefer replace_all. Always read the file first so you know the exact text to match. When editing nested structures (objects, function bodies, arrays, template literals), always include the full enclosing structure in old_string rather than just an inner fragment. Replacing a partial slice from the middle of nested code is the most common source of syntax errors.",
1481
1481
  inputSchema: {
1482
1482
  type: "object",
1483
1483
  properties: {
@@ -3172,7 +3172,29 @@ __export(screenshot_exports, {
3172
3172
  definition: () => definition5,
3173
3173
  execute: () => execute5
3174
3174
  });
3175
- async function execute5(input, onLog) {
3175
+ async function execute5(input, onLog, context) {
3176
+ if (input.instructions && context) {
3177
+ try {
3178
+ const task = input.path ? `Navigate to "${input.path}", then: ${input.instructions}. After completing these steps, take a full-page screenshot.` : `${input.instructions}. After completing these steps, take a full-page screenshot.`;
3179
+ const result = await browserAutomationTool.execute({ task }, context);
3180
+ const urlMatch = result.match(
3181
+ /https:\/\/[^\s"')]+\.(?:png|jpg|jpeg|webp)/i
3182
+ );
3183
+ if (!urlMatch) {
3184
+ return `Error: browser navigation completed but no screenshot URL was returned. Agent output: ${result}`;
3185
+ }
3186
+ const url = urlMatch[0];
3187
+ const analysisPrompt = input.prompt || SCREENSHOT_ANALYSIS_PROMPT;
3188
+ const analysis = await analyzeImage({
3189
+ prompt: analysisPrompt,
3190
+ imageUrl: url,
3191
+ onLog
3192
+ });
3193
+ return JSON.stringify({ url, analysis });
3194
+ } catch (err) {
3195
+ return `Error taking interactive screenshot: ${err.message}`;
3196
+ }
3197
+ }
3176
3198
  try {
3177
3199
  return await captureAndAnalyzeScreenshot({
3178
3200
  prompt: input.prompt,
@@ -3188,6 +3210,8 @@ var init_screenshot3 = __esm({
3188
3210
  "src/subagents/designExpert/tools/screenshot.ts"() {
3189
3211
  "use strict";
3190
3212
  init_screenshot();
3213
+ init_analyzeImage();
3214
+ init_browserAutomation();
3191
3215
  definition5 = {
3192
3216
  name: "screenshot",
3193
3217
  description: "Capture a full-height screenshot of the current app preview. Returns a CDN URL along with visual analysis. Use to review the current state of the UI being built. Remember, the screenshot analysis is not overly precise - for example, it cannot reliably identify specific fonts by name \u2014 it can only describe what letterforms look like.",
@@ -3201,6 +3225,10 @@ var init_screenshot3 = __esm({
3201
3225
  path: {
3202
3226
  type: "string",
3203
3227
  description: 'Navigate to this path before capturing (e.g. "/settings"). If omitted, screenshots the current page.'
3228
+ },
3229
+ instructions: {
3230
+ type: "string",
3231
+ description: "If the screenshot you need requires interaction first (dismissing a modal, clicking a tab, filling out a form, navigating a flow), describe the steps to get there. A browser automation agent will follow these instructions before capturing the screenshot."
3204
3232
  }
3205
3233
  }
3206
3234
  }
@@ -3482,7 +3510,7 @@ async function executeDesignExpertTool(name, input, context, toolCallId, onLog)
3482
3510
  if (!tool) {
3483
3511
  return `Error: unknown tool "${name}"`;
3484
3512
  }
3485
- return tool.execute(input, onLog);
3513
+ return tool.execute(input, onLog, context);
3486
3514
  }
3487
3515
  var tools, DESIGN_EXPERT_TOOLS;
3488
3516
  var init_tools2 = __esm({
@@ -38,7 +38,7 @@ Always consult the code sanity check before writing code in initialCodegen with
38
38
 
39
39
  ### QA (`runAutomatedBrowserTest`)
40
40
 
41
- For verifying complex stateful interactions: multi-step form submissions, auth flows, real-time updates, flows that require specific data/role setup. This spins up a full chrome browser automation — it's heavyweight. Do not use it for basic rendering or navigation checks. If you can verify something with a screenshot or by reading the code, do that instead. Run a scenario first to seed test data and set user roles. The user is able to watch QA work on their screen via a live browser preview - the cursor will move, type, etc - so you can also use this to demo functionality to the user and help them understand how to use their app.
41
+ For verifying complex stateful interactions: multi-step form submissions, auth flows, real-time updates, flows that require specific data/role setup. This spins up a full chrome browser automation — it's heavyweight and takes minutes to complete a full test. Do not use it for basic rendering or navigation checks. If you can verify something with a screenshot or by reading the code, do that instead. Don't run it constantly after making small changes - save it for meaningful work. Run a scenario first to seed test data and set user roles. The user is able to watch QA work on their screen via a live browser preview - the cursor will move, type, etc - so you can also use this to demo functionality to the user and help them understand how to use their app.
42
42
 
43
43
  The QA agent can see the screen. Describe what to test, not how — it will figure out what to click, what to check, and what values to use.
44
44
 
@@ -1,5 +1,8 @@
1
1
  You are a browser smoke test agent. You verify that features work end to end by interacting with the live preview. Focus on outcomes: does the feature work? Did the expected content appear? Just do the thing and see if it worked.
2
2
 
3
+ ## Rules to Remember
4
+ - Don't overthink the tests - the goal is to generally make sure things work as expected, not to provide detailed QA. If something seems mostly okay, note it and move on. Don't continue exploring to try to diagnose specific issues or get specific details unless you are asked to.
5
+
3
6
  ## Tester Persona
4
7
  The user is watching the automation happen on their screen in real-time. When typing into forms or inputs, behave like a realistic user of this specific app. Use the app context (if provided) to understand the audience and tone. Type the way that audience would actually type — not formal, not robotic. The app developer's name is Remy, so use that and the email remy@mindstudio.ai as the basis for any testing that requires a persona.
5
8
 
@@ -10,6 +10,7 @@ Then, think about the layout and UI patterns - these are the core of the user's
10
10
 
11
11
  ## Tool Usage
12
12
  - When multiple tool calls are independent, make them all in a single turn. Searching for three different products, or fetching two reference sites: batch them instead of doing one per turn.
13
+ - The screenshot tool supports an `instructions` parameter for taking screenshots that require interaction first. If you need to screenshot a state that's behind a modal, a specific tab, or a multi-step flow, pass `instructions` describing how to get there (e.g., "dismiss the welcome modal, then click XYZ"). A browser automation agent will follow your instructions and capture the screenshot for you.
13
14
 
14
15
  ## Voice
15
16
  - No emoji, no filler.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/remy",
3
- "version": "0.1.64",
3
+ "version": "0.1.65",
4
4
  "description": "MindStudio coding agent",
5
5
  "repository": {
6
6
  "type": "git",