@mindstudio-ai/remy 0.1.202 → 0.1.204

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
@@ -3580,6 +3580,13 @@ var MODEL_SURFACES = {
3580
3580
  modelType: "text",
3581
3581
  userPickable: true
3582
3582
  },
3583
+ copyEditor: {
3584
+ default: "claude-4-6-sonnet",
3585
+ label: "Copy Agent",
3586
+ description: "Tightens prose and copy across your app and its launch materials so it reads sharp and human, never machine-made.",
3587
+ modelType: "text",
3588
+ userPickable: true
3589
+ },
3583
3590
  imageGeneration: {
3584
3591
  default: "seedream-4.5",
3585
3592
  label: "Image Generation",
@@ -4545,28 +4552,12 @@ async function execute7(input, onLog, context) {
4545
4552
  });
4546
4553
  }
4547
4554
 
4548
- // src/subagents/designExpert/tools/index.ts
4549
- var tools = {
4550
- searchGoogle: searchGoogle_exports,
4551
- scrapeWebUrl: scrapeWebUrl_exports,
4552
- analyzeDesign: analyzeDesign_exports,
4553
- analyzeImage: analyzeImage_exports,
4554
- screenshot: screenshot_exports,
4555
- generateImages: generateImages_exports,
4556
- editImages: editImages_exports
4557
- };
4558
- var DESIGN_EXPERT_TOOLS = [
4559
- ...COMMON_READ_TOOLS,
4560
- ...Object.values(tools).map((t) => t.definition)
4561
- ];
4562
- async function executeDesignExpertTool(name, input, context, toolCallId, onLog) {
4563
- const tool = tools[name];
4564
- if (!tool) {
4565
- return `Error: unknown tool "${name}"`;
4566
- }
4567
- const childContext = context && toolCallId ? deriveContext(context, toolCallId) : context;
4568
- return tool.execute(input, onLog, childContext);
4569
- }
4555
+ // src/subagents/designExpert/tools/polishCopy.ts
4556
+ var polishCopy_exports = {};
4557
+ __export(polishCopy_exports, {
4558
+ definition: () => definition8,
4559
+ execute: () => execute8
4560
+ });
4570
4561
 
4571
4562
  // src/subagents/common/context.ts
4572
4563
  import fs17 from "fs";
@@ -4736,6 +4727,103 @@ The first-party SDK (@mindstudio-ai/agent) provides access to 200+ AI models (Op
4736
4727
  </platform_brief>`;
4737
4728
  }
4738
4729
 
4730
+ // src/subagents/copyEditor/tools.ts
4731
+ var COPY_EDITOR_TOOLS = [...COMMON_READ_TOOLS];
4732
+
4733
+ // src/subagents/copyEditor/index.ts
4734
+ var BASE_PROMPT2 = readAsset("subagents/copyEditor", "prompt.md");
4735
+ var copyEditorTool = {
4736
+ clearable: false,
4737
+ definition: {
4738
+ name: "copyEditor",
4739
+ description: "Hand it user-facing copy and it hands back a sharper version \u2014 better structured for its audience and free of the overused words, telltale constructions, and rhythms that make text read as AI-generated. Think of it as a design expert for words: it elevates how the copy communicates and strips the AI fingerprints, but it never invents facts or claims you didn't give it. Use it on anything users will read: in-app strings, empty states, errors, the Build Overview, deck copy, launch posts, Slack announcements. Readonly.",
4740
+ inputSchema: {
4741
+ type: "object",
4742
+ properties: {
4743
+ task: {
4744
+ type: "string",
4745
+ description: "The copy to polish, plus what it's for \u2014 the medium, the audience, any brand voice. Paste the text verbatim."
4746
+ }
4747
+ },
4748
+ required: ["task"]
4749
+ }
4750
+ },
4751
+ async execute(input, context) {
4752
+ if (!context) {
4753
+ return "Error: copy editor requires execution context";
4754
+ }
4755
+ const specIndex = loadSpecIndex();
4756
+ const parts = [BASE_PROMPT2];
4757
+ parts.push("<!-- cache_breakpoint -->");
4758
+ if (specIndex) {
4759
+ parts.push(specIndex);
4760
+ }
4761
+ const system = parts.join("\n\n");
4762
+ const result = await runSubAgent({
4763
+ system,
4764
+ task: input.task,
4765
+ tools: COPY_EDITOR_TOOLS,
4766
+ externalTools: /* @__PURE__ */ new Set(),
4767
+ executeTool: (name, toolInput) => executeTool(name, toolInput, context),
4768
+ apiConfig: context.apiConfig,
4769
+ model: resolveModel("copyEditor", context.models, context.model),
4770
+ subAgentId: "copyEditor",
4771
+ signal: context.signal,
4772
+ parentToolId: context.toolCallId,
4773
+ requestId: context.requestId,
4774
+ onEvent: context.onEvent,
4775
+ resolveExternalTool: context.resolveExternalTool,
4776
+ toolRegistry: context.toolRegistry
4777
+ });
4778
+ context.subAgentMessages?.set(context.toolCallId, result.messages);
4779
+ return result.text;
4780
+ }
4781
+ };
4782
+
4783
+ // src/subagents/designExpert/tools/polishCopy.ts
4784
+ var definition8 = {
4785
+ clearable: false,
4786
+ name: "polishCopy",
4787
+ description: "Hand off any user-facing copy you've written \u2014 headlines, captions, labels, body text \u2014 and get back a sharper version: better built for its audience and free of the fingerprints that make writing read as AI. It elevates how the copy communicates without inventing facts or claims you didn't give it. Give it the text plus what it's for (where it appears, the audience).",
4788
+ inputSchema: {
4789
+ type: "object",
4790
+ properties: {
4791
+ task: {
4792
+ type: "string",
4793
+ description: "The copy to polish, plus what it's for \u2014 where it appears, the audience, any brand voice."
4794
+ }
4795
+ },
4796
+ required: ["task"]
4797
+ }
4798
+ };
4799
+ async function execute8(input, _onLog, context) {
4800
+ return copyEditorTool.execute(input, context);
4801
+ }
4802
+
4803
+ // src/subagents/designExpert/tools/index.ts
4804
+ var tools = {
4805
+ searchGoogle: searchGoogle_exports,
4806
+ scrapeWebUrl: scrapeWebUrl_exports,
4807
+ analyzeDesign: analyzeDesign_exports,
4808
+ analyzeImage: analyzeImage_exports,
4809
+ screenshot: screenshot_exports,
4810
+ generateImages: generateImages_exports,
4811
+ editImages: editImages_exports,
4812
+ polishCopy: polishCopy_exports
4813
+ };
4814
+ var DESIGN_EXPERT_TOOLS = [
4815
+ ...COMMON_READ_TOOLS,
4816
+ ...Object.values(tools).map((t) => t.definition)
4817
+ ];
4818
+ async function executeDesignExpertTool(name, input, context, toolCallId, onLog) {
4819
+ const tool = tools[name];
4820
+ if (!tool) {
4821
+ return `Error: unknown tool "${name}"`;
4822
+ }
4823
+ const childContext = context && toolCallId ? deriveContext(context, toolCallId) : context;
4824
+ return tool.execute(input, onLog, childContext);
4825
+ }
4826
+
4739
4827
  // src/subagents/designExpert/data/sampleCache.ts
4740
4828
  import fs18 from "fs";
4741
4829
  var SAMPLE_FILE = ".remy-design-sample.json";
@@ -5175,11 +5263,11 @@ Respond only with the complete HTML file and absolutely no other text. Your resp
5175
5263
  }
5176
5264
 
5177
5265
  // src/subagents/productVision/prompt.ts
5178
- var BASE_PROMPT2 = readAsset("subagents/productVision", "prompt.md");
5266
+ var BASE_PROMPT3 = readAsset("subagents/productVision", "prompt.md");
5179
5267
  function getProductVisionPrompt() {
5180
5268
  const specIndex = loadSpecIndex();
5181
5269
  const roadmapIndex = loadRoadmapIndex();
5182
- const parts = [BASE_PROMPT2, loadPlatformBrief()];
5270
+ const parts = [BASE_PROMPT3, loadPlatformBrief()];
5183
5271
  parts.push("<!-- cache_breakpoint -->");
5184
5272
  if (specIndex) {
5185
5273
  parts.push(specIndex);
@@ -5303,7 +5391,7 @@ var SANITY_CHECK_TOOLS = [
5303
5391
  ];
5304
5392
 
5305
5393
  // src/subagents/codeSanityCheck/index.ts
5306
- var BASE_PROMPT3 = readAsset("subagents/codeSanityCheck", "prompt.md");
5394
+ var BASE_PROMPT4 = readAsset("subagents/codeSanityCheck", "prompt.md");
5307
5395
  var codeSanityCheckTool = {
5308
5396
  clearable: false,
5309
5397
  definition: {
@@ -5325,7 +5413,7 @@ var codeSanityCheckTool = {
5325
5413
  return "Error: code sanity check requires execution context";
5326
5414
  }
5327
5415
  const specIndex = loadSpecIndex();
5328
- const parts = [BASE_PROMPT3, loadPlatformBrief()];
5416
+ const parts = [BASE_PROMPT4, loadPlatformBrief()];
5329
5417
  parts.push("<!-- cache_breakpoint -->");
5330
5418
  if (specIndex) {
5331
5419
  parts.push(specIndex);
@@ -5401,7 +5489,7 @@ var DESIGN_BRIEF = `We are building the Build Overview for this app \u2014 the h
5401
5489
  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.
5402
5490
 
5403
5491
  ### The single hard rule
5404
- Preserve every fact in <overview_copy> exactly \u2014 every number, name, label, and claim. Do not add, drop, soften, reword, or invent any fact. You own layout, typography, and visual design only; the substance and the words are fixed. A single wrong number breaks this document's entire purpose.
5492
+ 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.
5405
5493
 
5406
5494
  ### What it is (and is not)
5407
5495
  - A typeset reference dossier: composed, dense, a little cool \u2014 substantial at a glance, then readable. Density communicates substance; sparse and airy reads as "not much here."
@@ -5440,13 +5528,13 @@ var buildOverviewTool = {
5440
5528
  clearable: false,
5441
5529
  definition: {
5442
5530
  name: "writeBuildOverview",
5443
- description: "Generate or refresh the Build Overview \u2014 the project's home page in the Spec tab: a single-page, plain-language reference of everything the app actually contains, including the parts the user can't see (data stores, backend operations, access and roles, background jobs, seeded scenarios, the design system). You author the full copy: read the manifest and spec and state, plainly and exactly, what genuinely exists \u2014 real names and accurate counts \u2014 in calm, declarative, present-tense outcome language, with no persuasion or hype. Describe only what exists. Pass the complete copy as `content`; the design expert lays it out and skins it to the app's brand without altering any of your facts. Generate it at the end of a build and refresh it after meaningful work.",
5531
+ description: "Generate or refresh the Build Overview \u2014 the project's home page in the Spec tab: a single-page, plain-language reference of everything the app actually contains, including the parts the user can't see (data stores, backend operations, access and roles, background jobs, seeded scenarios, the design system). You author the full copy: read the manifest and spec and state, plainly and exactly, what genuinely exists \u2014 real names and accurate counts \u2014 in calm, declarative, present-tense outcome language, with no persuasion or hype. Describe only what exists. Pass the complete copy as `content`; the design expert lays it out and skins it to the app's brand using your copy verbatim \u2014 it typesets your words, it does not rewrite them, so polish the copy before you pass it. Generate it at the end of a build and refresh it after meaningful work.",
5444
5532
  inputSchema: {
5445
5533
  type: "object",
5446
5534
  properties: {
5447
5535
  content: {
5448
5536
  type: "string",
5449
- description: "The full Build Overview copy you authored: everything the app contains, in plain present-tense outcome language, with real names and exact counts. The design expert lays this out and skins it to the brand without changing any fact."
5537
+ description: "The full Build Overview copy you authored: everything the app contains, in plain present-tense outcome language, with real names and exact counts. The design expert lays this out and skins it to the brand verbatim \u2014 it styles your words, it does not rewrite them \u2014 so this should be the final copy."
5450
5538
  }
5451
5539
  },
5452
5540
  required: ["content"]
@@ -5497,6 +5585,7 @@ var ALL_TOOLS = [
5497
5585
  designExpertTool,
5498
5586
  productVisionTool,
5499
5587
  codeSanityCheckTool,
5588
+ copyEditorTool,
5500
5589
  buildOverviewTool,
5501
5590
  compactConversationTool,
5502
5591
  // Post-onboarding
@@ -5533,6 +5622,7 @@ var SUBAGENT_TOOL_NAMES = /* @__PURE__ */ new Set([
5533
5622
  "visualDesignExpert",
5534
5623
  "productVision",
5535
5624
  "codeSanityCheck",
5625
+ "copyEditor",
5536
5626
  "runAutomatedBrowserTest",
5537
5627
  "askMindStudioSdk"
5538
5628
  ]);
package/dist/index.js CHANGED
@@ -1775,7 +1775,7 @@ var init_compaction = __esm({
1775
1775
  "use strict";
1776
1776
  init_api();
1777
1777
  init_assets();
1778
- init_tools6();
1778
+ init_tools7();
1779
1779
  init_logger();
1780
1780
  init_usageLedger();
1781
1781
  log2 = createLogger("compaction");
@@ -2106,6 +2106,13 @@ var init_surfaces = __esm({
2106
2106
  modelType: "text",
2107
2107
  userPickable: true
2108
2108
  },
2109
+ copyEditor: {
2110
+ default: "claude-4-6-sonnet",
2111
+ label: "Copy Agent",
2112
+ description: "Tightens prose and copy across your app and its launch materials so it reads sharp and human, never machine-made.",
2113
+ modelType: "text",
2114
+ userPickable: true
2115
+ },
2109
2116
  imageGeneration: {
2110
2117
  default: "seedream-4.5",
2111
2118
  label: "Image Generation",
@@ -2205,7 +2212,7 @@ var init_trigger = __esm({
2205
2212
  "use strict";
2206
2213
  init_compaction();
2207
2214
  init_prompt();
2208
- init_tools6();
2215
+ init_tools7();
2209
2216
  init_logger();
2210
2217
  init_surfaces();
2211
2218
  log3 = createLogger("compaction:trigger");
@@ -5311,44 +5318,6 @@ var init_editImages = __esm({
5311
5318
  }
5312
5319
  });
5313
5320
 
5314
- // src/subagents/designExpert/tools/index.ts
5315
- async function executeDesignExpertTool(name, input, context, toolCallId, onLog) {
5316
- const tool = tools[name];
5317
- if (!tool) {
5318
- return `Error: unknown tool "${name}"`;
5319
- }
5320
- const childContext = context && toolCallId ? deriveContext(context, toolCallId) : context;
5321
- return tool.execute(input, onLog, childContext);
5322
- }
5323
- var tools, DESIGN_EXPERT_TOOLS;
5324
- var init_tools3 = __esm({
5325
- "src/subagents/designExpert/tools/index.ts"() {
5326
- "use strict";
5327
- init_tools6();
5328
- init_tools2();
5329
- init_searchGoogle2();
5330
- init_scrapeWebUrl();
5331
- init_analyzeDesign();
5332
- init_analyzeImage2();
5333
- init_screenshot3();
5334
- init_generateImages();
5335
- init_editImages();
5336
- tools = {
5337
- searchGoogle: searchGoogle_exports,
5338
- scrapeWebUrl: scrapeWebUrl_exports,
5339
- analyzeDesign: analyzeDesign_exports,
5340
- analyzeImage: analyzeImage_exports,
5341
- screenshot: screenshot_exports,
5342
- generateImages: generateImages_exports,
5343
- editImages: editImages_exports
5344
- };
5345
- DESIGN_EXPERT_TOOLS = [
5346
- ...COMMON_READ_TOOLS,
5347
- ...Object.values(tools).map((t) => t.definition)
5348
- ];
5349
- }
5350
- });
5351
-
5352
5321
  // src/subagents/common/context.ts
5353
5322
  import fs16 from "fs";
5354
5323
  import path7 from "path";
@@ -5522,6 +5491,150 @@ var init_context = __esm({
5522
5491
  }
5523
5492
  });
5524
5493
 
5494
+ // src/subagents/copyEditor/tools.ts
5495
+ var COPY_EDITOR_TOOLS;
5496
+ var init_tools3 = __esm({
5497
+ "src/subagents/copyEditor/tools.ts"() {
5498
+ "use strict";
5499
+ init_tools2();
5500
+ COPY_EDITOR_TOOLS = [...COMMON_READ_TOOLS];
5501
+ }
5502
+ });
5503
+
5504
+ // src/subagents/copyEditor/index.ts
5505
+ var BASE_PROMPT2, copyEditorTool;
5506
+ var init_copyEditor = __esm({
5507
+ "src/subagents/copyEditor/index.ts"() {
5508
+ "use strict";
5509
+ init_assets();
5510
+ init_runner();
5511
+ init_context();
5512
+ init_tools7();
5513
+ init_tools3();
5514
+ init_surfaces();
5515
+ BASE_PROMPT2 = readAsset("subagents/copyEditor", "prompt.md");
5516
+ copyEditorTool = {
5517
+ clearable: false,
5518
+ definition: {
5519
+ name: "copyEditor",
5520
+ description: "Hand it user-facing copy and it hands back a sharper version \u2014 better structured for its audience and free of the overused words, telltale constructions, and rhythms that make text read as AI-generated. Think of it as a design expert for words: it elevates how the copy communicates and strips the AI fingerprints, but it never invents facts or claims you didn't give it. Use it on anything users will read: in-app strings, empty states, errors, the Build Overview, deck copy, launch posts, Slack announcements. Readonly.",
5521
+ inputSchema: {
5522
+ type: "object",
5523
+ properties: {
5524
+ task: {
5525
+ type: "string",
5526
+ description: "The copy to polish, plus what it's for \u2014 the medium, the audience, any brand voice. Paste the text verbatim."
5527
+ }
5528
+ },
5529
+ required: ["task"]
5530
+ }
5531
+ },
5532
+ async execute(input, context) {
5533
+ if (!context) {
5534
+ return "Error: copy editor requires execution context";
5535
+ }
5536
+ const specIndex = loadSpecIndex();
5537
+ const parts = [BASE_PROMPT2];
5538
+ parts.push("<!-- cache_breakpoint -->");
5539
+ if (specIndex) {
5540
+ parts.push(specIndex);
5541
+ }
5542
+ const system = parts.join("\n\n");
5543
+ const result = await runSubAgent({
5544
+ system,
5545
+ task: input.task,
5546
+ tools: COPY_EDITOR_TOOLS,
5547
+ externalTools: /* @__PURE__ */ new Set(),
5548
+ executeTool: (name, toolInput) => executeTool(name, toolInput, context),
5549
+ apiConfig: context.apiConfig,
5550
+ model: resolveModel("copyEditor", context.models, context.model),
5551
+ subAgentId: "copyEditor",
5552
+ signal: context.signal,
5553
+ parentToolId: context.toolCallId,
5554
+ requestId: context.requestId,
5555
+ onEvent: context.onEvent,
5556
+ resolveExternalTool: context.resolveExternalTool,
5557
+ toolRegistry: context.toolRegistry
5558
+ });
5559
+ context.subAgentMessages?.set(context.toolCallId, result.messages);
5560
+ return result.text;
5561
+ }
5562
+ };
5563
+ }
5564
+ });
5565
+
5566
+ // src/subagents/designExpert/tools/polishCopy.ts
5567
+ var polishCopy_exports = {};
5568
+ __export(polishCopy_exports, {
5569
+ definition: () => definition8,
5570
+ execute: () => execute8
5571
+ });
5572
+ async function execute8(input, _onLog, context) {
5573
+ return copyEditorTool.execute(input, context);
5574
+ }
5575
+ var definition8;
5576
+ var init_polishCopy = __esm({
5577
+ "src/subagents/designExpert/tools/polishCopy.ts"() {
5578
+ "use strict";
5579
+ init_copyEditor();
5580
+ definition8 = {
5581
+ clearable: false,
5582
+ name: "polishCopy",
5583
+ description: "Hand off any user-facing copy you've written \u2014 headlines, captions, labels, body text \u2014 and get back a sharper version: better built for its audience and free of the fingerprints that make writing read as AI. It elevates how the copy communicates without inventing facts or claims you didn't give it. Give it the text plus what it's for (where it appears, the audience).",
5584
+ inputSchema: {
5585
+ type: "object",
5586
+ properties: {
5587
+ task: {
5588
+ type: "string",
5589
+ description: "The copy to polish, plus what it's for \u2014 where it appears, the audience, any brand voice."
5590
+ }
5591
+ },
5592
+ required: ["task"]
5593
+ }
5594
+ };
5595
+ }
5596
+ });
5597
+
5598
+ // src/subagents/designExpert/tools/index.ts
5599
+ async function executeDesignExpertTool(name, input, context, toolCallId, onLog) {
5600
+ const tool = tools[name];
5601
+ if (!tool) {
5602
+ return `Error: unknown tool "${name}"`;
5603
+ }
5604
+ const childContext = context && toolCallId ? deriveContext(context, toolCallId) : context;
5605
+ return tool.execute(input, onLog, childContext);
5606
+ }
5607
+ var tools, DESIGN_EXPERT_TOOLS;
5608
+ var init_tools4 = __esm({
5609
+ "src/subagents/designExpert/tools/index.ts"() {
5610
+ "use strict";
5611
+ init_tools7();
5612
+ init_tools2();
5613
+ init_searchGoogle2();
5614
+ init_scrapeWebUrl();
5615
+ init_analyzeDesign();
5616
+ init_analyzeImage2();
5617
+ init_screenshot3();
5618
+ init_generateImages();
5619
+ init_editImages();
5620
+ init_polishCopy();
5621
+ tools = {
5622
+ searchGoogle: searchGoogle_exports,
5623
+ scrapeWebUrl: scrapeWebUrl_exports,
5624
+ analyzeDesign: analyzeDesign_exports,
5625
+ analyzeImage: analyzeImage_exports,
5626
+ screenshot: screenshot_exports,
5627
+ generateImages: generateImages_exports,
5628
+ editImages: editImages_exports,
5629
+ polishCopy: polishCopy_exports
5630
+ };
5631
+ DESIGN_EXPERT_TOOLS = [
5632
+ ...COMMON_READ_TOOLS,
5633
+ ...Object.values(tools).map((t) => t.definition)
5634
+ ];
5635
+ }
5636
+ });
5637
+
5525
5638
  // src/subagents/designExpert/data/sampleCache.ts
5526
5639
  import fs17 from "fs";
5527
5640
  function generateIndices(poolSize, sampleSize) {
@@ -5801,9 +5914,9 @@ var DESCRIPTION, designExpertTool;
5801
5914
  var init_designExpert = __esm({
5802
5915
  "src/subagents/designExpert/index.ts"() {
5803
5916
  "use strict";
5804
- init_tools6();
5917
+ init_tools7();
5805
5918
  init_runner();
5806
- init_tools3();
5919
+ init_tools4();
5807
5920
  init_tools2();
5808
5921
  init_prompt3();
5809
5922
  init_history();
@@ -5883,7 +5996,7 @@ Visual design expert. Describe the situation and what you need \u2014 the agent
5883
5996
 
5884
5997
  // src/subagents/productVision/tools.ts
5885
5998
  var VISION_TOOLS;
5886
- var init_tools4 = __esm({
5999
+ var init_tools5 = __esm({
5887
6000
  "src/subagents/productVision/tools.ts"() {
5888
6001
  "use strict";
5889
6002
  init_tools2();
@@ -6041,7 +6154,7 @@ var init_executor = __esm({
6041
6154
  function getProductVisionPrompt() {
6042
6155
  const specIndex = loadSpecIndex();
6043
6156
  const roadmapIndex = loadRoadmapIndex();
6044
- const parts = [BASE_PROMPT2, loadPlatformBrief()];
6157
+ const parts = [BASE_PROMPT3, loadPlatformBrief()];
6045
6158
  parts.push("<!-- cache_breakpoint -->");
6046
6159
  if (specIndex) {
6047
6160
  parts.push(specIndex);
@@ -6051,14 +6164,14 @@ function getProductVisionPrompt() {
6051
6164
  }
6052
6165
  return parts.join("\n\n");
6053
6166
  }
6054
- var BASE_PROMPT2;
6167
+ var BASE_PROMPT3;
6055
6168
  var init_prompt4 = __esm({
6056
6169
  "src/subagents/productVision/prompt.ts"() {
6057
6170
  "use strict";
6058
6171
  init_assets();
6059
6172
  init_executor();
6060
6173
  init_context();
6061
- BASE_PROMPT2 = readAsset("subagents/productVision", "prompt.md");
6174
+ BASE_PROMPT3 = readAsset("subagents/productVision", "prompt.md");
6062
6175
  }
6063
6176
  });
6064
6177
 
@@ -6067,9 +6180,9 @@ var productVisionTool;
6067
6180
  var init_productVision = __esm({
6068
6181
  "src/subagents/productVision/index.ts"() {
6069
6182
  "use strict";
6070
- init_tools6();
6183
+ init_tools7();
6071
6184
  init_runner();
6072
- init_tools4();
6185
+ init_tools5();
6073
6186
  init_tools2();
6074
6187
  init_executor();
6075
6188
  init_prompt4();
@@ -6141,7 +6254,7 @@ var init_productVision = __esm({
6141
6254
 
6142
6255
  // src/subagents/codeSanityCheck/tools.ts
6143
6256
  var SANITY_CHECK_TOOLS;
6144
- var init_tools5 = __esm({
6257
+ var init_tools6 = __esm({
6145
6258
  "src/subagents/codeSanityCheck/tools.ts"() {
6146
6259
  "use strict";
6147
6260
  init_tools2();
@@ -6196,17 +6309,17 @@ var init_tools5 = __esm({
6196
6309
  });
6197
6310
 
6198
6311
  // src/subagents/codeSanityCheck/index.ts
6199
- var BASE_PROMPT3, codeSanityCheckTool;
6312
+ var BASE_PROMPT4, codeSanityCheckTool;
6200
6313
  var init_codeSanityCheck = __esm({
6201
6314
  "src/subagents/codeSanityCheck/index.ts"() {
6202
6315
  "use strict";
6203
6316
  init_assets();
6204
6317
  init_runner();
6205
6318
  init_context();
6319
+ init_tools7();
6206
6320
  init_tools6();
6207
- init_tools5();
6208
6321
  init_surfaces();
6209
- BASE_PROMPT3 = readAsset("subagents/codeSanityCheck", "prompt.md");
6322
+ BASE_PROMPT4 = readAsset("subagents/codeSanityCheck", "prompt.md");
6210
6323
  codeSanityCheckTool = {
6211
6324
  clearable: false,
6212
6325
  definition: {
@@ -6228,7 +6341,7 @@ var init_codeSanityCheck = __esm({
6228
6341
  return "Error: code sanity check requires execution context";
6229
6342
  }
6230
6343
  const specIndex = loadSpecIndex();
6231
- const parts = [BASE_PROMPT3, loadPlatformBrief()];
6344
+ const parts = [BASE_PROMPT4, loadPlatformBrief()];
6232
6345
  parts.push("<!-- cache_breakpoint -->");
6233
6346
  if (specIndex) {
6234
6347
  parts.push(specIndex);
@@ -6318,7 +6431,7 @@ var init_writeBuildOverview = __esm({
6318
6431
  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.
6319
6432
 
6320
6433
  ### The single hard rule
6321
- Preserve every fact in <overview_copy> exactly \u2014 every number, name, label, and claim. Do not add, drop, soften, reword, or invent any fact. You own layout, typography, and visual design only; the substance and the words are fixed. A single wrong number breaks this document's entire purpose.
6434
+ 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.
6322
6435
 
6323
6436
  ### What it is (and is not)
6324
6437
  - A typeset reference dossier: composed, dense, a little cool \u2014 substantial at a glance, then readable. Density communicates substance; sparse and airy reads as "not much here."
@@ -6357,13 +6470,13 @@ Respond only with the complete HTML file and absolutely no other text. Your resp
6357
6470
  clearable: false,
6358
6471
  definition: {
6359
6472
  name: "writeBuildOverview",
6360
- description: "Generate or refresh the Build Overview \u2014 the project's home page in the Spec tab: a single-page, plain-language reference of everything the app actually contains, including the parts the user can't see (data stores, backend operations, access and roles, background jobs, seeded scenarios, the design system). You author the full copy: read the manifest and spec and state, plainly and exactly, what genuinely exists \u2014 real names and accurate counts \u2014 in calm, declarative, present-tense outcome language, with no persuasion or hype. Describe only what exists. Pass the complete copy as `content`; the design expert lays it out and skins it to the app's brand without altering any of your facts. Generate it at the end of a build and refresh it after meaningful work.",
6473
+ description: "Generate or refresh the Build Overview \u2014 the project's home page in the Spec tab: a single-page, plain-language reference of everything the app actually contains, including the parts the user can't see (data stores, backend operations, access and roles, background jobs, seeded scenarios, the design system). You author the full copy: read the manifest and spec and state, plainly and exactly, what genuinely exists \u2014 real names and accurate counts \u2014 in calm, declarative, present-tense outcome language, with no persuasion or hype. Describe only what exists. Pass the complete copy as `content`; the design expert lays it out and skins it to the app's brand using your copy verbatim \u2014 it typesets your words, it does not rewrite them, so polish the copy before you pass it. Generate it at the end of a build and refresh it after meaningful work.",
6361
6474
  inputSchema: {
6362
6475
  type: "object",
6363
6476
  properties: {
6364
6477
  content: {
6365
6478
  type: "string",
6366
- description: "The full Build Overview copy you authored: everything the app contains, in plain present-tense outcome language, with real names and exact counts. The design expert lays this out and skins it to the brand without changing any fact."
6479
+ description: "The full Build Overview copy you authored: everything the app contains, in plain present-tense outcome language, with real names and exact counts. The design expert lays this out and skins it to the brand verbatim \u2014 it styles your words, it does not rewrite them \u2014 so this should be the final copy."
6367
6480
  }
6368
6481
  },
6369
6482
  required: ["content"]
@@ -6418,7 +6531,7 @@ function executeTool(name, input, context) {
6418
6531
  return tool.execute(input, context);
6419
6532
  }
6420
6533
  var ALL_TOOLS, CLEARABLE_TOOLS, SUBAGENT_TOOL_NAMES;
6421
- var init_tools6 = __esm({
6534
+ var init_tools7 = __esm({
6422
6535
  "src/tools/index.ts"() {
6423
6536
  "use strict";
6424
6537
  init_readSpec();
@@ -6453,6 +6566,7 @@ var init_tools6 = __esm({
6453
6566
  init_designExpert();
6454
6567
  init_productVision();
6455
6568
  init_codeSanityCheck();
6569
+ init_copyEditor();
6456
6570
  init_scrapeWebUrl2();
6457
6571
  init_writeBuildOverview();
6458
6572
  ALL_TOOLS = [
@@ -6467,6 +6581,7 @@ var init_tools6 = __esm({
6467
6581
  designExpertTool,
6468
6582
  productVisionTool,
6469
6583
  codeSanityCheckTool,
6584
+ copyEditorTool,
6470
6585
  buildOverviewTool,
6471
6586
  compactConversationTool,
6472
6587
  // Post-onboarding
@@ -6503,6 +6618,7 @@ var init_tools6 = __esm({
6503
6618
  "visualDesignExpert",
6504
6619
  "productVision",
6505
6620
  "codeSanityCheck",
6621
+ "copyEditor",
6506
6622
  "runAutomatedBrowserTest",
6507
6623
  "askMindStudioSdk"
6508
6624
  ]);
@@ -7702,7 +7818,7 @@ var init_agent = __esm({
7702
7818
  "src/agent.ts"() {
7703
7819
  "use strict";
7704
7820
  init_api();
7705
- init_tools6();
7821
+ init_tools7();
7706
7822
  init_session();
7707
7823
  init_logger();
7708
7824
  init_usageLedger();
@@ -7710,7 +7826,7 @@ var init_agent = __esm({
7710
7826
  init_statusWatcher();
7711
7827
  init_errors();
7712
7828
  init_cleanMessages();
7713
- init_tools6();
7829
+ init_tools7();
7714
7830
  init_sentinel();
7715
7831
  init_trigger2();
7716
7832
  init_surfaces();
@@ -145,6 +145,7 @@ The intro framing ("you have a lot on your plate") gives the model permission to
145
145
  | `productVision` | Roadmap ownership & product strategy | writeRoadmapItem, updateRoadmapItem, deleteRoadmapItem | Spec files + current roadmap |
146
146
  | `sdkConsultant` | MindStudio SDK architecture | None (shells out to `mindstudio ask` CLI) | None (external agent) |
147
147
  | `codeSanityCheck` | Pre-build review | readFile, grep, glob, searchGoogle, fetchUrl, askMindStudioSdk, bash (readonly) | Spec files |
148
+ | `copyEditor` | Copy-editing / de-AI-ing prose | readFile, listDir, grep, glob (readonly) | Spec files |
148
149
  | `browserAutomation` | Interactive UI testing | browserCommand, screenshotFullPage, setupBrowser | None (interacts with live preview) |
149
150
 
150
151
  ### Shared infrastructure
@@ -160,6 +161,10 @@ The product vision agent uses third-person construction ("The role of the assist
160
161
 
161
162
  The sanity check agent is deliberately low-energy. Its prompt says "lgtm" is a complete response and to let most things slide. This prevents it from becoming a bottleneck or scope-creeper. The only things it flags: outdated packages (via web search), missed SDK managed actions, schema decisions that paint into corners, and file organization that's gotten unwieldy. Tech debt is explicitly called out as normal and sometimes useful in fast-moving products.
162
163
 
164
+ ### Copy editor: polish, never author
165
+
166
+ The copy editor is the "design expert for words" — a cheap, readonly subagent that rewrites user-facing copy (in-app strings, the Build Overview, deck copy, launch posts, Slack notes) to read human instead of AI-generated, and — the bigger half — to communicate better. Like the design expert (which removes AI-design tells *and* elevates the design), it has two jobs: elevate how the copy lands for its audience (structure, framing, what to lead with, what to cut) and strip the AI tells. The hard guardrail mirrors the design expert's: it changes *how* something is said freely but never invents the substance (no new facts/claims/features) — elevate the form, don't fabricate the content. It lives off the main loop on purpose: asking Remy to also "write differently" mid-task is the wrong cognitive load, and isolation contains the one thing we'd never put in the shared prompt — a prescriptive denylist of AI tells (overused words, tic constructions, metronomic rhythm, the em-dash perception tell). The blast radius of that denylist is bounded to this agent. The design expert can also delegate to it for copy inside layouts.
167
+
163
168
  ### Design expert: runtime-sampled data
164
169
 
165
170
  The design expert's prompt is dynamically assembled per invocation. It samples 15 random fonts + 5 pairings from the Fontshare catalog and 5 random pre-analyzed design inspiration screenshots from Godly. This prevents the model from developing favorites and ensures it considers different options each time.
@@ -36,6 +36,10 @@ A quick gut check. Describe what you're about to build and how, and get back a b
36
36
 
37
37
  Always consult the code sanity check before writing code in initialCodegen with your proposed architecture. Use it liberally when making any other architecture decisions - before adding new features, connecting to third-party services, integrating new dependencies, building items from the roadmap, or doing other meaningful work.
38
38
 
39
+ ### Copy Agent (`copyEditor`)
40
+
41
+ Your editor — a design expert for words. Hand it any user-facing copy — an empty state, an error message, button labels, the Build Overview, pitch-deck copy, a launch post, a Slack note announcing the app — and it hands back a sharper version: better built for its audience and free of the telltale fingerprints that make writing read as AI. You're good at deciding *what* to say; it's great at making it land. It won't invent claims or change the facts, but within what you give it, it will restructure, cut, and reframe to communicate better, the same way the design expert elevates a layout without changing what the app does. Fast and cheap, so use it liberally on anything users will read, especially copy meant to be shared externally. Give it the text plus what it's for (the medium, the audience).
42
+
39
43
  ### QA (`runAutomatedBrowserTest`)
40
44
 
41
45
  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.
@@ -0,0 +1,53 @@
1
+ You're a writer and editor for a coding agent that is building products and creating adjacent collateral like pitch decks and social media posts. The code agent hands you copy (a UI string, an empty state, a launch post, deck copy, a Slack note) and you hand back the best version of it. Your work involves two themes: *Communication*: crafting copy that is clear, easy to scan, and built so the reader gets the point at a glance. *De-AI-ifying*: Stripping the fingerprints of a language model — the overused constructions, telltale rhythms, and word choices that make a reader think "this was AI" and, in today's world, dismiss the work wholesale.
2
+
3
+ ## Important: Preserve the substance provided
4
+
5
+ You decide *how* things are said. You never decide what's true. Don't add claims, features, numbers, or facts you weren't given. Don't reverse the meaning or argue a point the source never made. If a claim isn't backed, cut it — don't swap in a better-sounding one you invented. When you're unsure whether a detail is real, leave it as you found it.
6
+
7
+ Inside that line, however, everything is yours: what to lead with, what to cut, how it's structured, how long it runs, how it lands.
8
+
9
+ ## Clarity is the most important aspect of your work
10
+
11
+ Clarity is the floor, and it's the most important thing to get right above all else. Copy can read smoothly, pass every AI-tell check, and still be a chore to follow. If it's technically correct, but you have to read it twice to parse it - or some veribage scans as being clunky - that's a failure. Our bar is higher: clear, easy to read, effortless to scan. A reader should get the point on a single pass, without close reading. Focus on the substance and how to communicate it. All the literary flourish in the world is meaningless if it leaves the reader feeling like there's no actual substance behind it. We'd rather have something that communicates clearly and intuitively than something empty but concise/pithy/beautiful.
12
+
13
+ ## Act as a world-class copy editor
14
+
15
+ Think about audience and purpose. A launch post should make someone want the thing. An error should calm someone down and tell them what to do next. An empty state should make a blank screen feel like a start, not a dead end. A deck headline should land in one read.
16
+
17
+ Take the opportunity to improve and tigthen the copy:
18
+ - Lead with the most important thing. Cut the throat-clearing that buries it.
19
+ - Find the one idea the copy is really about and build around it. Cut what doesn't serve it, even when it's true.
20
+ - Make the abstract concrete. A specific detail beats a general claim every time.
21
+ - Give it a shape: a hook, a turn, an ending that resolves. Even three words can have a shape.
22
+ - Say more with less. The tightest version that keeps the meaning is almost always the best one.
23
+
24
+ ## De-AI-ify the text
25
+
26
+ Unfortunately, even good and clear writing can still read as "machine-written" and cause ordinary readers to mentally check out or dismiss it. Take a pass through the text to remove the telltale signs of AI writing. Pay close attention to:
27
+
28
+ - Tic rhythm — two opposite failure modes. Metronomic: every sentence the same medium length. Staccato: a stack of clipped fragments for manufactured punch. Real writing varies because the meaning calls for it, not to perform a beat.
29
+ - Throat-clearing. Windup before the point ("It's worth noting that," "In today's fast-paced world," "When it comes to X"). Cut to it.
30
+ - Tic constructions. "Not just X, but Y." "It's not about X — it's about Y." "This isn't a feature. It's a philosophy." Rule-of-three lists everywhere. Rhetorical-question openers. Tidy summary sentences that restate what was just said. Fine once if it earns its place; never on autopilot.
31
+ - Manufactured weight. A short line dropped to fake profundity ("That's real." "That's the whole game." "And that changes everything."), or inflating the reader ("you're onto something bigger," "this is about more than X"). Earn the emphasis or cut it.
32
+ - Inflated diction: leverage, utilize, seamless, robust, elevate, unlock, empower, delve, realm, testament, boasts, "designed to," "ensure." Plain words read human; fancy words read generated.
33
+ - Reached-for metaphors. The model's default vocabulary of structural and physical metaphors bolted onto abstract things: load-bearing, spine, seam, substrate, blast radius (also surface area, scaffolding, north star). Say the plain thing.
34
+ - Empty intensifiers and hedges: very, really, truly, incredibly, simply, just. Most can go.
35
+ - Em dashes. You may love them. So do I. But a run of them now reads as an AI tell to a lot of people, fair or not — so spend them sparingly and reach for a period, comma, or parentheses instead. Perception, not grammar.
36
+
37
+ Fix toward, not only away: concrete over abstract, verbs over nominalizations, specific over generic, short over long when both work.
38
+
39
+ ## Don't over-correct
40
+
41
+ The opposite failure is bleaching copy into flat, choppy, personality-free mush — that just reads as AI in a different costume. Keep the voice. Keep a good line when you find one. Vary the rhythm; don't flatten it. If the spec carries a brand voice, match it; otherwise, plain and direct. Natural, not neutered.
42
+
43
+ ## How to respond
44
+
45
+ Before you hand anything back, read it cold, as someone seeing it for the first time: can you scan it once and get the point? Does every line connect and say something real? If not, it isn't done.
46
+
47
+ Return the rewritten copy, ready to drop in. Then one line on what you changed and why ("Led with the outcome, cut two filler sentences, swapped 'leverage' → 'use'").
48
+
49
+ If it's already strong, say so and return it as-is — don't edit for the sake of editing. If you were given several distinct strings, return them in the same structure you received, so they're easy to place back.
50
+
51
+ <voice>
52
+ A great writer with a sharp editor's eye. You can make ordinary copy land, and you can spot generated writing in one read. You change how something is said freely; you never change what's true.
53
+ </voice>
@@ -14,6 +14,7 @@ Think about the ways you can truly elevate the design. Use image generation to c
14
14
  - 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.
15
15
  - 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. You can not use this to scroll - you will always receive a full page screenshot. Only use this if you need to trigger stateful changes within the app to get the full-page screenshot.
16
16
  - After you've taken a screenshot, use analyze image to ask different questions about it - don't re-screenshot the page unnecessarily.
17
+ - When you write user-facing copy (headlines, captions, labels, body text), hand it to `polishCopy` before finalizing. It tightens prose so it reads like a person wrote it rather than a machine, without changing what it says. Cheap and fast — use it on any copy that will ship.
17
18
 
18
19
  ## Voice
19
20
  - No emoji, no filler.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/remy",
3
- "version": "0.1.202",
3
+ "version": "0.1.204",
4
4
  "description": "Remy coding agent",
5
5
  "repository": {
6
6
  "type": "git",