@mindstudio-ai/remy 0.1.230 → 0.1.231

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
@@ -5122,6 +5122,50 @@ ${summaryText}
5122
5122
  var DESCRIPTION = `
5123
5123
  Visual design expert. Describe the situation and what you need \u2014 the agent decides what to deliver. It reads the spec files automatically. Include relevant user requirements and context it can't get from the spec, but do not list specific deliverables or tell it how to do its job. Do not suggest implementation details or ideas - only relay what is needed.
5124
5124
  `.trim();
5125
+ var RENDER_WRITE_TOOL_NAMES = /* @__PURE__ */ new Set(["writeFile", "editFile"]);
5126
+ var DESIGN_EXPERT_RENDER_TOOLS = [
5127
+ ...DESIGN_EXPERT_TOOLS,
5128
+ writeFileTool.definition,
5129
+ editFileTool.definition
5130
+ ];
5131
+ async function runDesignExpert(opts, context) {
5132
+ const history = context.conversationMessages ? getSubAgentHistory(context.conversationMessages, "visualDesignExpert") : [];
5133
+ return runSubAgent({
5134
+ system: getDesignExpertPrompt(context.onboardingState),
5135
+ task: opts.task,
5136
+ history: history.length > 0 ? history : void 0,
5137
+ tools: opts.enableWrite ? DESIGN_EXPERT_RENDER_TOOLS : DESIGN_EXPERT_TOOLS,
5138
+ externalTools: /* @__PURE__ */ new Set(),
5139
+ executeTool: (name, input, toolCallId, onLog, sams) => {
5140
+ const childCtx = toolCallId ? { ...deriveContext(context, toolCallId), subAgentMessages: sams } : { ...context, subAgentMessages: sams };
5141
+ if (COMMON_READ_TOOL_NAMES.has(name)) {
5142
+ return executeTool(name, input, childCtx);
5143
+ }
5144
+ if (opts.enableWrite && RENDER_WRITE_TOOL_NAMES.has(name)) {
5145
+ return executeTool(name, input, childCtx);
5146
+ }
5147
+ return executeDesignExpertTool(name, input, childCtx, toolCallId, onLog);
5148
+ },
5149
+ apiConfig: context.apiConfig,
5150
+ model: resolveModel("visualDesignExpert", context.models, context.model),
5151
+ subAgentId: "visualDesignExpert",
5152
+ signal: context.signal,
5153
+ parentToolId: context.toolCallId,
5154
+ requestId: context.requestId,
5155
+ onEvent: context.onEvent,
5156
+ resolveExternalTool: context.resolveExternalTool,
5157
+ toolRegistry: context.toolRegistry,
5158
+ background: opts.background,
5159
+ onBackgroundComplete: opts.background ? (bgResult) => {
5160
+ context.onBackgroundComplete?.(
5161
+ context.toolCallId,
5162
+ opts.reportingName ?? "visualDesignExpert",
5163
+ bgResult.text,
5164
+ bgResult.messages
5165
+ );
5166
+ } : void 0
5167
+ });
5168
+ }
5125
5169
  var designExpertTool = {
5126
5170
  clearable: false,
5127
5171
  definition: {
@@ -5146,49 +5190,20 @@ var designExpertTool = {
5146
5190
  if (!context) {
5147
5191
  return "Error: visual design expert requires execution context";
5148
5192
  }
5149
- const history = context.conversationMessages ? getSubAgentHistory(context.conversationMessages, "visualDesignExpert") : [];
5150
- const result = await runSubAgent({
5151
- system: getDesignExpertPrompt(context.onboardingState),
5152
- task: input.task,
5153
- history: history.length > 0 ? history : void 0,
5154
- tools: DESIGN_EXPERT_TOOLS,
5155
- externalTools: /* @__PURE__ */ new Set(),
5156
- executeTool: (name, input2, toolCallId, onLog, sams) => {
5157
- const childCtx = toolCallId ? { ...deriveContext(context, toolCallId), subAgentMessages: sams } : { ...context, subAgentMessages: sams };
5158
- if (COMMON_READ_TOOL_NAMES.has(name)) {
5159
- return executeTool(name, input2, childCtx);
5160
- }
5161
- return executeDesignExpertTool(
5162
- name,
5163
- input2,
5164
- childCtx,
5165
- toolCallId,
5166
- onLog
5167
- );
5193
+ const result = await runDesignExpert(
5194
+ {
5195
+ task: input.task,
5196
+ background: input.background
5168
5197
  },
5169
- apiConfig: context.apiConfig,
5170
- model: resolveModel("visualDesignExpert", context.models, context.model),
5171
- subAgentId: "visualDesignExpert",
5172
- signal: context.signal,
5173
- parentToolId: context.toolCallId,
5174
- requestId: context.requestId,
5175
- onEvent: context.onEvent,
5176
- resolveExternalTool: context.resolveExternalTool,
5177
- toolRegistry: context.toolRegistry,
5178
- background: input.background,
5179
- onBackgroundComplete: input.background ? (bgResult) => {
5180
- context.onBackgroundComplete?.(
5181
- context.toolCallId,
5182
- "visualDesignExpert",
5183
- bgResult.text,
5184
- bgResult.messages
5185
- );
5186
- } : void 0
5187
- });
5198
+ context
5199
+ );
5188
5200
  context.subAgentMessages?.set(context.toolCallId, result.messages);
5189
5201
  return result.text;
5190
5202
  }
5191
5203
  };
5204
+ async function runDesignExpertRender(opts, context) {
5205
+ return runDesignExpert({ ...opts, enableWrite: true }, context);
5206
+ }
5192
5207
 
5193
5208
  // src/subagents/productVision/tools.ts
5194
5209
  var VISION_TOOLS = [
@@ -5293,16 +5308,25 @@ ${unifiedDiff(filePath, oldContent, "")}`;
5293
5308
  const filePath = resolve("pitch.html");
5294
5309
  try {
5295
5310
  fs19.mkdirSync(ROADMAP_DIR, { recursive: true });
5296
- const existing = fs19.existsSync(filePath) ? fs19.readFileSync(filePath, "utf-8").trim() : "";
5297
- const currentDeck = existing || PITCH_DECK_SHELL;
5311
+ const exists = fs19.existsSync(filePath);
5312
+ const before = exists ? fs19.statSync(filePath).mtimeMs : null;
5313
+ const delivery = exists ? `### Your deliverable
5314
+ The pitch deck already exists at \`${filePath}\`. Read it, then update it for the new <pitch_content>, keeping the presentation scaffolding intact \u2014 change only what needs to change.
5315
+
5316
+ Reply with a one-line summary of what you changed \u2014 not the HTML.` : `### Your deliverable
5317
+ Write the complete pitch deck to \`${filePath}\`. It does not exist yet \u2014 start from this scaffold, keeping its progress bar, chevron navigation, keyboard navigation, and transition mechanics intact:
5318
+
5319
+ <pitch_deck_shell>
5320
+ ${PITCH_DECK_SHELL}
5321
+ </pitch_deck_shell>
5322
+
5323
+ Reply with a one-line summary of what you wrote \u2014 not the HTML.`;
5298
5324
  const task = `
5299
5325
  <pitch_content>${input.task}</pitch_content>
5300
5326
 
5301
- <current_deck>${currentDeck}</current_deck>
5302
-
5303
5327
  We are building the pitch deck for the app. Using the provided <pitch_content>, as well as the app's spec data, think about what would make a compelling, interactive, self-contained horizontally-scrolling HTML slide deck for this product. Keep it simple, clean, powerful. Giant text, large logo, big, bold stats and claims. Edit the content as necessary to create the most impactful, bold, and beautiful slides. This should not feel like an essay, and it should not feel like a landing page \u2014 it should feel like a modern interactive presentation that leaves the user wowed by the product and excited about its future.
5304
5328
 
5305
- Use <current_deck> as your starting point and replace or update the content as needed, maintaining the bones of the presentation scaffolding. Always keep the progress bar, chevron navigation, and keyboard navigation - they are part of the scaffold.
5329
+ Maintain the bones of the presentation scaffolding. Always keep the progress bar, chevron navigation, and keyboard navigation - they are part of the scaffold.
5306
5330
 
5307
5331
  ### Rules
5308
5332
  - The deck must be a single HTML file \u2014 it will be rendered in an iframe.
@@ -5312,14 +5336,18 @@ Use <current_deck> as your starting point and replace or update the content as n
5312
5336
  - Code must be clean, bug free, and easy to parse. Use GSAP for animations. Pay close attention to layout and alignment to make sure everything is perfect.
5313
5337
  - Keep the progress bar and edge chevrons from the shell \u2014 they are part of the navigation UX.
5314
5338
 
5315
- Respond only with the complete HTML file and absolutely no other text. Your response will be written directly to an html file.`;
5316
- const result = await designExpertTool.execute({ task }, context);
5317
- const htmlMatch = result.match(
5318
- /```(?:html|wireframe)\n([\s\S]*?)```/
5319
- );
5320
- const html = htmlMatch ? htmlMatch[1].trim() : result;
5321
- fs19.writeFileSync(filePath, html, "utf-8");
5322
- return `Pitch deck written successfully.`;
5339
+ ${delivery}`;
5340
+ const result = await runDesignExpertRender({ task }, context);
5341
+ context.subAgentMessages?.set(context.toolCallId, result.messages);
5342
+ if (!fs19.existsSync(filePath)) {
5343
+ return `Error: the design expert did not write ${filePath}. Its reply was:
5344
+ ${result.text}`;
5345
+ }
5346
+ if (before !== null && fs19.statSync(filePath).mtimeMs === before) {
5347
+ return `Error: the pitch deck at ${filePath} was not modified. The design expert's reply was:
5348
+ ${result.text}`;
5349
+ }
5350
+ return `Pitch deck written to ${filePath}. ${result.text}`;
5323
5351
  } catch (err) {
5324
5352
  return `Error generating pitch deck: ${err.message}`;
5325
5353
  }
@@ -5553,7 +5581,7 @@ import fs20 from "fs";
5553
5581
  var OVERVIEW_FILE = "src/overview.html";
5554
5582
  var DESIGN_BRIEF = `We are building the Build Overview for this app \u2014 the home page of its Spec tab. It is a calm, dense, one-page reference of everything the app actually contains, including the parts the user can't see. It renders flush inside the Spec tab's content panel (the IDE supplies the surrounding nav).
5555
5583
 
5556
- Take the plain-language copy in <overview_copy> and lay it out and skin it into a single, beautiful, self-contained HTML document in the app's own brand. If <current_overview> is non-empty, use it as your starting point and preserve its established skin, updating only what the copy changed.
5584
+ Take the plain-language copy in <overview_copy> and lay it out and skin it into a single, beautiful, self-contained HTML document in the app's own brand.
5557
5585
 
5558
5586
  ### The single hard rule
5559
5587
  The copy in <overview_copy> is final \u2014 it was authored and edited before it reached you. Treat it as locked content to typeset, not a draft to improve. Reproduce the words exactly: do not rewrite, rephrase, shorten, expand, reorder, or "polish" them, and do not run them through any copy tool. This is the opposite of your usual role \u2014 here you own layout, typography, and visual design only, and the words (every number, name, label, claim, and sentence) are fixed. A single changed word or wrong number breaks this document's purpose.
@@ -5568,9 +5596,7 @@ The copy in <overview_copy> is final \u2014 it was authored and edited before it
5568
5596
 
5569
5597
  ### Constraints
5570
5598
  - A single self-contained HTML file. Fonts may load from a CDN; everything else (CSS, the logo SVG) is inline.
5571
- - Responsive: fills the embedded panel width and collapses gracefully at narrow widths.
5572
-
5573
- Respond only with the complete HTML file and absolutely no other text. Your response will be written directly to src/overview.html.`;
5599
+ - Responsive: fills the embedded panel width and collapses gracefully at narrow widths.`;
5574
5600
  var OVERVIEW_SHELL = `<!DOCTYPE html>
5575
5601
  <html lang="en">
5576
5602
  <head>
@@ -5591,6 +5617,22 @@ var OVERVIEW_SHELL = `<!DOCTYPE html>
5591
5617
  app's spec. -->
5592
5618
  </body>
5593
5619
  </html>`;
5620
+ function initialDelivery() {
5621
+ return `### Your deliverable
5622
+ Write the complete Build Overview to \`${OVERVIEW_FILE}\`. The file does not exist yet \u2014 start from this scaffold, which carries the technical hygiene for the iframed render context (keep the viewport meta and the reset). Layout, sections, type, and styling are yours to compose.
5623
+
5624
+ <overview_shell>
5625
+ ${OVERVIEW_SHELL}
5626
+ </overview_shell>
5627
+
5628
+ Reply with a one-line summary of what you wrote \u2014 not the HTML.`;
5629
+ }
5630
+ function refreshDelivery() {
5631
+ return `### Your deliverable
5632
+ The Build Overview already exists at \`${OVERVIEW_FILE}\`. Read it, then update it to reflect <overview_copy>, preserving its established skin \u2014 change only what the copy changed.
5633
+
5634
+ Reply with a one-line summary of what you changed \u2014 not the HTML.`;
5635
+ }
5594
5636
  var buildOverviewTool = {
5595
5637
  clearable: false,
5596
5638
  definition: {
@@ -5615,21 +5657,29 @@ var buildOverviewTool = {
5615
5657
  if (!content) {
5616
5658
  return "Error: writeBuildOverview requires non-empty `content` (the overview copy).";
5617
5659
  }
5618
- try {
5619
- const existing = fs20.existsSync(OVERVIEW_FILE) ? fs20.readFileSync(OVERVIEW_FILE, "utf-8").trim() : "";
5620
- const currentOverview = existing || OVERVIEW_SHELL;
5621
- const task = `<overview_copy>${content}</overview_copy>
5660
+ const exists = fs20.existsSync(OVERVIEW_FILE);
5661
+ const task = `<overview_copy>${content}</overview_copy>
5622
5662
 
5623
- <current_overview>${currentOverview}</current_overview>
5663
+ ${DESIGN_BRIEF}
5624
5664
 
5625
- ${DESIGN_BRIEF}`;
5626
- const result = await designExpertTool.execute({ task }, context);
5627
- const htmlMatch = result.match(
5628
- /```(?:html|wireframe)\n([\s\S]*?)```/
5629
- );
5630
- const html = htmlMatch ? htmlMatch[1].trim() : result;
5631
- fs20.writeFileSync(OVERVIEW_FILE, html, "utf-8");
5632
- return "Build overview written successfully to src/overview.html.";
5665
+ ${exists ? refreshDelivery() : initialDelivery()}`;
5666
+ try {
5667
+ if (exists) {
5668
+ input.background = true;
5669
+ const result2 = await runDesignExpertRender(
5670
+ { task, background: true, reportingName: "writeBuildOverview" },
5671
+ context
5672
+ );
5673
+ context.subAgentMessages?.set(context.toolCallId, result2.messages);
5674
+ return result2.text;
5675
+ }
5676
+ const result = await runDesignExpertRender({ task }, context);
5677
+ context.subAgentMessages?.set(context.toolCallId, result.messages);
5678
+ if (!fs20.existsSync(OVERVIEW_FILE)) {
5679
+ return `Error: the design expert did not write ${OVERVIEW_FILE}. Its reply was:
5680
+ ${result.text}`;
5681
+ }
5682
+ return `Build overview written to ${OVERVIEW_FILE}. ${result.text}`;
5633
5683
  } catch (err) {
5634
5684
  return `Error generating build overview: ${err.message}`;
5635
5685
  }
package/dist/index.js CHANGED
@@ -5988,7 +5988,48 @@ var init_history = __esm({
5988
5988
  });
5989
5989
 
5990
5990
  // src/subagents/designExpert/index.ts
5991
- var DESCRIPTION, designExpertTool;
5991
+ async function runDesignExpert(opts, context) {
5992
+ const history = context.conversationMessages ? getSubAgentHistory(context.conversationMessages, "visualDesignExpert") : [];
5993
+ return runSubAgent({
5994
+ system: getDesignExpertPrompt(context.onboardingState),
5995
+ task: opts.task,
5996
+ history: history.length > 0 ? history : void 0,
5997
+ tools: opts.enableWrite ? DESIGN_EXPERT_RENDER_TOOLS : DESIGN_EXPERT_TOOLS,
5998
+ externalTools: /* @__PURE__ */ new Set(),
5999
+ executeTool: (name, input, toolCallId, onLog, sams) => {
6000
+ const childCtx = toolCallId ? { ...deriveContext(context, toolCallId), subAgentMessages: sams } : { ...context, subAgentMessages: sams };
6001
+ if (COMMON_READ_TOOL_NAMES.has(name)) {
6002
+ return executeTool(name, input, childCtx);
6003
+ }
6004
+ if (opts.enableWrite && RENDER_WRITE_TOOL_NAMES.has(name)) {
6005
+ return executeTool(name, input, childCtx);
6006
+ }
6007
+ return executeDesignExpertTool(name, input, childCtx, toolCallId, onLog);
6008
+ },
6009
+ apiConfig: context.apiConfig,
6010
+ model: resolveModel("visualDesignExpert", context.models, context.model),
6011
+ subAgentId: "visualDesignExpert",
6012
+ signal: context.signal,
6013
+ parentToolId: context.toolCallId,
6014
+ requestId: context.requestId,
6015
+ onEvent: context.onEvent,
6016
+ resolveExternalTool: context.resolveExternalTool,
6017
+ toolRegistry: context.toolRegistry,
6018
+ background: opts.background,
6019
+ onBackgroundComplete: opts.background ? (bgResult) => {
6020
+ context.onBackgroundComplete?.(
6021
+ context.toolCallId,
6022
+ opts.reportingName ?? "visualDesignExpert",
6023
+ bgResult.text,
6024
+ bgResult.messages
6025
+ );
6026
+ } : void 0
6027
+ });
6028
+ }
6029
+ async function runDesignExpertRender(opts, context) {
6030
+ return runDesignExpert({ ...opts, enableWrite: true }, context);
6031
+ }
6032
+ var DESCRIPTION, RENDER_WRITE_TOOL_NAMES, DESIGN_EXPERT_RENDER_TOOLS, designExpertTool;
5992
6033
  var init_designExpert = __esm({
5993
6034
  "src/subagents/designExpert/index.ts"() {
5994
6035
  "use strict";
@@ -5999,9 +6040,17 @@ var init_designExpert = __esm({
5999
6040
  init_prompt3();
6000
6041
  init_history();
6001
6042
  init_surfaces();
6043
+ init_writeFile();
6044
+ init_editFile();
6002
6045
  DESCRIPTION = `
6003
6046
  Visual design expert. Describe the situation and what you need \u2014 the agent decides what to deliver. It reads the spec files automatically. Include relevant user requirements and context it can't get from the spec, but do not list specific deliverables or tell it how to do its job. Do not suggest implementation details or ideas - only relay what is needed.
6004
6047
  `.trim();
6048
+ RENDER_WRITE_TOOL_NAMES = /* @__PURE__ */ new Set(["writeFile", "editFile"]);
6049
+ DESIGN_EXPERT_RENDER_TOOLS = [
6050
+ ...DESIGN_EXPERT_TOOLS,
6051
+ writeFileTool.definition,
6052
+ editFileTool.definition
6053
+ ];
6005
6054
  designExpertTool = {
6006
6055
  clearable: false,
6007
6056
  definition: {
@@ -6026,45 +6075,13 @@ Visual design expert. Describe the situation and what you need \u2014 the agent
6026
6075
  if (!context) {
6027
6076
  return "Error: visual design expert requires execution context";
6028
6077
  }
6029
- const history = context.conversationMessages ? getSubAgentHistory(context.conversationMessages, "visualDesignExpert") : [];
6030
- const result = await runSubAgent({
6031
- system: getDesignExpertPrompt(context.onboardingState),
6032
- task: input.task,
6033
- history: history.length > 0 ? history : void 0,
6034
- tools: DESIGN_EXPERT_TOOLS,
6035
- externalTools: /* @__PURE__ */ new Set(),
6036
- executeTool: (name, input2, toolCallId, onLog, sams) => {
6037
- const childCtx = toolCallId ? { ...deriveContext(context, toolCallId), subAgentMessages: sams } : { ...context, subAgentMessages: sams };
6038
- if (COMMON_READ_TOOL_NAMES.has(name)) {
6039
- return executeTool(name, input2, childCtx);
6040
- }
6041
- return executeDesignExpertTool(
6042
- name,
6043
- input2,
6044
- childCtx,
6045
- toolCallId,
6046
- onLog
6047
- );
6078
+ const result = await runDesignExpert(
6079
+ {
6080
+ task: input.task,
6081
+ background: input.background
6048
6082
  },
6049
- apiConfig: context.apiConfig,
6050
- model: resolveModel("visualDesignExpert", context.models, context.model),
6051
- subAgentId: "visualDesignExpert",
6052
- signal: context.signal,
6053
- parentToolId: context.toolCallId,
6054
- requestId: context.requestId,
6055
- onEvent: context.onEvent,
6056
- resolveExternalTool: context.resolveExternalTool,
6057
- toolRegistry: context.toolRegistry,
6058
- background: input.background,
6059
- onBackgroundComplete: input.background ? (bgResult) => {
6060
- context.onBackgroundComplete?.(
6061
- context.toolCallId,
6062
- "visualDesignExpert",
6063
- bgResult.text,
6064
- bgResult.messages
6065
- );
6066
- } : void 0
6067
- });
6083
+ context
6084
+ );
6068
6085
  context.subAgentMessages?.set(context.toolCallId, result.messages);
6069
6086
  return result.text;
6070
6087
  }
@@ -6177,16 +6194,25 @@ ${unifiedDiff(filePath, oldContent, "")}`;
6177
6194
  const filePath = resolve("pitch.html");
6178
6195
  try {
6179
6196
  fs18.mkdirSync(ROADMAP_DIR, { recursive: true });
6180
- const existing = fs18.existsSync(filePath) ? fs18.readFileSync(filePath, "utf-8").trim() : "";
6181
- const currentDeck = existing || PITCH_DECK_SHELL;
6197
+ const exists = fs18.existsSync(filePath);
6198
+ const before = exists ? fs18.statSync(filePath).mtimeMs : null;
6199
+ const delivery = exists ? `### Your deliverable
6200
+ The pitch deck already exists at \`${filePath}\`. Read it, then update it for the new <pitch_content>, keeping the presentation scaffolding intact \u2014 change only what needs to change.
6201
+
6202
+ Reply with a one-line summary of what you changed \u2014 not the HTML.` : `### Your deliverable
6203
+ Write the complete pitch deck to \`${filePath}\`. It does not exist yet \u2014 start from this scaffold, keeping its progress bar, chevron navigation, keyboard navigation, and transition mechanics intact:
6204
+
6205
+ <pitch_deck_shell>
6206
+ ${PITCH_DECK_SHELL}
6207
+ </pitch_deck_shell>
6208
+
6209
+ Reply with a one-line summary of what you wrote \u2014 not the HTML.`;
6182
6210
  const task = `
6183
6211
  <pitch_content>${input.task}</pitch_content>
6184
6212
 
6185
- <current_deck>${currentDeck}</current_deck>
6186
-
6187
6213
  We are building the pitch deck for the app. Using the provided <pitch_content>, as well as the app's spec data, think about what would make a compelling, interactive, self-contained horizontally-scrolling HTML slide deck for this product. Keep it simple, clean, powerful. Giant text, large logo, big, bold stats and claims. Edit the content as necessary to create the most impactful, bold, and beautiful slides. This should not feel like an essay, and it should not feel like a landing page \u2014 it should feel like a modern interactive presentation that leaves the user wowed by the product and excited about its future.
6188
6214
 
6189
- Use <current_deck> as your starting point and replace or update the content as needed, maintaining the bones of the presentation scaffolding. Always keep the progress bar, chevron navigation, and keyboard navigation - they are part of the scaffold.
6215
+ Maintain the bones of the presentation scaffolding. Always keep the progress bar, chevron navigation, and keyboard navigation - they are part of the scaffold.
6190
6216
 
6191
6217
  ### Rules
6192
6218
  - The deck must be a single HTML file \u2014 it will be rendered in an iframe.
@@ -6196,14 +6222,18 @@ Use <current_deck> as your starting point and replace or update the content as n
6196
6222
  - Code must be clean, bug free, and easy to parse. Use GSAP for animations. Pay close attention to layout and alignment to make sure everything is perfect.
6197
6223
  - Keep the progress bar and edge chevrons from the shell \u2014 they are part of the navigation UX.
6198
6224
 
6199
- Respond only with the complete HTML file and absolutely no other text. Your response will be written directly to an html file.`;
6200
- const result = await designExpertTool.execute({ task }, context);
6201
- const htmlMatch = result.match(
6202
- /```(?:html|wireframe)\n([\s\S]*?)```/
6203
- );
6204
- const html = htmlMatch ? htmlMatch[1].trim() : result;
6205
- fs18.writeFileSync(filePath, html, "utf-8");
6206
- return `Pitch deck written successfully.`;
6225
+ ${delivery}`;
6226
+ const result = await runDesignExpertRender({ task }, context);
6227
+ context.subAgentMessages?.set(context.toolCallId, result.messages);
6228
+ if (!fs18.existsSync(filePath)) {
6229
+ return `Error: the design expert did not write ${filePath}. Its reply was:
6230
+ ${result.text}`;
6231
+ }
6232
+ if (before !== null && fs18.statSync(filePath).mtimeMs === before) {
6233
+ return `Error: the pitch deck at ${filePath} was not modified. The design expert's reply was:
6234
+ ${result.text}`;
6235
+ }
6236
+ return `Pitch deck written to ${filePath}. ${result.text}`;
6207
6237
  } catch (err) {
6208
6238
  return `Error generating pitch deck: ${err.message}`;
6209
6239
  }
@@ -6498,6 +6528,22 @@ var init_scrapeWebUrl2 = __esm({
6498
6528
 
6499
6529
  // src/tools/spec/writeBuildOverview.ts
6500
6530
  import fs19 from "fs";
6531
+ function initialDelivery() {
6532
+ return `### Your deliverable
6533
+ Write the complete Build Overview to \`${OVERVIEW_FILE}\`. The file does not exist yet \u2014 start from this scaffold, which carries the technical hygiene for the iframed render context (keep the viewport meta and the reset). Layout, sections, type, and styling are yours to compose.
6534
+
6535
+ <overview_shell>
6536
+ ${OVERVIEW_SHELL}
6537
+ </overview_shell>
6538
+
6539
+ Reply with a one-line summary of what you wrote \u2014 not the HTML.`;
6540
+ }
6541
+ function refreshDelivery() {
6542
+ return `### Your deliverable
6543
+ The Build Overview already exists at \`${OVERVIEW_FILE}\`. Read it, then update it to reflect <overview_copy>, preserving its established skin \u2014 change only what the copy changed.
6544
+
6545
+ Reply with a one-line summary of what you changed \u2014 not the HTML.`;
6546
+ }
6501
6547
  var OVERVIEW_FILE, DESIGN_BRIEF, OVERVIEW_SHELL, buildOverviewTool;
6502
6548
  var init_writeBuildOverview = __esm({
6503
6549
  "src/tools/spec/writeBuildOverview.ts"() {
@@ -6506,7 +6552,7 @@ var init_writeBuildOverview = __esm({
6506
6552
  OVERVIEW_FILE = "src/overview.html";
6507
6553
  DESIGN_BRIEF = `We are building the Build Overview for this app \u2014 the home page of its Spec tab. It is a calm, dense, one-page reference of everything the app actually contains, including the parts the user can't see. It renders flush inside the Spec tab's content panel (the IDE supplies the surrounding nav).
6508
6554
 
6509
- Take the plain-language copy in <overview_copy> and lay it out and skin it into a single, beautiful, self-contained HTML document in the app's own brand. If <current_overview> is non-empty, use it as your starting point and preserve its established skin, updating only what the copy changed.
6555
+ Take the plain-language copy in <overview_copy> and lay it out and skin it into a single, beautiful, self-contained HTML document in the app's own brand.
6510
6556
 
6511
6557
  ### The single hard rule
6512
6558
  The copy in <overview_copy> is final \u2014 it was authored and edited before it reached you. Treat it as locked content to typeset, not a draft to improve. Reproduce the words exactly: do not rewrite, rephrase, shorten, expand, reorder, or "polish" them, and do not run them through any copy tool. This is the opposite of your usual role \u2014 here you own layout, typography, and visual design only, and the words (every number, name, label, claim, and sentence) are fixed. A single changed word or wrong number breaks this document's purpose.
@@ -6521,9 +6567,7 @@ The copy in <overview_copy> is final \u2014 it was authored and edited before it
6521
6567
 
6522
6568
  ### Constraints
6523
6569
  - A single self-contained HTML file. Fonts may load from a CDN; everything else (CSS, the logo SVG) is inline.
6524
- - Responsive: fills the embedded panel width and collapses gracefully at narrow widths.
6525
-
6526
- Respond only with the complete HTML file and absolutely no other text. Your response will be written directly to src/overview.html.`;
6570
+ - Responsive: fills the embedded panel width and collapses gracefully at narrow widths.`;
6527
6571
  OVERVIEW_SHELL = `<!DOCTYPE html>
6528
6572
  <html lang="en">
6529
6573
  <head>
@@ -6568,21 +6612,29 @@ Respond only with the complete HTML file and absolutely no other text. Your resp
6568
6612
  if (!content) {
6569
6613
  return "Error: writeBuildOverview requires non-empty `content` (the overview copy).";
6570
6614
  }
6571
- try {
6572
- const existing = fs19.existsSync(OVERVIEW_FILE) ? fs19.readFileSync(OVERVIEW_FILE, "utf-8").trim() : "";
6573
- const currentOverview = existing || OVERVIEW_SHELL;
6574
- const task = `<overview_copy>${content}</overview_copy>
6615
+ const exists = fs19.existsSync(OVERVIEW_FILE);
6616
+ const task = `<overview_copy>${content}</overview_copy>
6575
6617
 
6576
- <current_overview>${currentOverview}</current_overview>
6618
+ ${DESIGN_BRIEF}
6577
6619
 
6578
- ${DESIGN_BRIEF}`;
6579
- const result = await designExpertTool.execute({ task }, context);
6580
- const htmlMatch = result.match(
6581
- /```(?:html|wireframe)\n([\s\S]*?)```/
6582
- );
6583
- const html = htmlMatch ? htmlMatch[1].trim() : result;
6584
- fs19.writeFileSync(OVERVIEW_FILE, html, "utf-8");
6585
- return "Build overview written successfully to src/overview.html.";
6620
+ ${exists ? refreshDelivery() : initialDelivery()}`;
6621
+ try {
6622
+ if (exists) {
6623
+ input.background = true;
6624
+ const result2 = await runDesignExpertRender(
6625
+ { task, background: true, reportingName: "writeBuildOverview" },
6626
+ context
6627
+ );
6628
+ context.subAgentMessages?.set(context.toolCallId, result2.messages);
6629
+ return result2.text;
6630
+ }
6631
+ const result = await runDesignExpertRender({ task }, context);
6632
+ context.subAgentMessages?.set(context.toolCallId, result.messages);
6633
+ if (!fs19.existsSync(OVERVIEW_FILE)) {
6634
+ return `Error: the design expert did not write ${OVERVIEW_FILE}. Its reply was:
6635
+ ${result.text}`;
6636
+ }
6637
+ return `Build overview written to ${OVERVIEW_FILE}. ${result.text}`;
6586
6638
  } catch (err) {
6587
6639
  return `Error generating build overview: ${err.message}`;
6588
6640
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/remy",
3
- "version": "0.1.230",
3
+ "version": "0.1.231",
4
4
  "description": "Remy coding agent",
5
5
  "repository": {
6
6
  "type": "git",