@mindstudio-ai/remy 0.1.228 → 0.1.230

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
@@ -682,11 +682,17 @@ function parseFrontmatter(filePath) {
682
682
  return { name: "", description: "", type: "" };
683
683
  }
684
684
  }
685
- function loadPlanStatus() {
685
+ function loadPlanStatus(onboardingState) {
686
686
  try {
687
687
  const content = fs4.readFileSync(".remy-plan.md", "utf-8");
688
688
  const match = content.match(/^---\n([\s\S]*?)\n---/);
689
689
  const status = match?.[1]?.match(/^status:\s*(.+)$/m)?.[1]?.trim();
690
+ if (status === "pending" && onboardingState === "intake") {
691
+ return `
692
+ <pending_initial_plan>
693
+ This is your initial plan, proposed via writePlan and awaiting the user's decision. The user approves it by pressing "Start Building" \u2014 you'll get an approveInitialPlan message when they do, and it will tell you to begin. Until then, stay in intake: keep discussing, and revise with writePlan if the user asks. Don't start building on your own, even if the user says "looks good" in chat.
694
+ </pending_initial_plan>`;
695
+ }
690
696
  if (status === "pending") {
691
697
  return `
692
698
  <pending_plan>
@@ -868,7 +874,7 @@ The user is currently in ${viewContext?.mode ?? "code"} mode.
868
874
  ${viewContext?.activeFile ? `Active file: ${viewContext.activeFile}` : ""}
869
875
  </view_context>
870
876
 
871
- ${loadPlanStatus()}
877
+ ${loadPlanStatus(onboardingState)}
872
878
  `;
873
879
  return resolveIncludes(template);
874
880
  }
@@ -1379,8 +1385,11 @@ var updatePlanStatusTool = {
1379
1385
  required: ["status"]
1380
1386
  }
1381
1387
  },
1382
- async execute(input) {
1388
+ async execute(input, context) {
1383
1389
  const status = input.status;
1390
+ if (context?.onboardingState === "intake") {
1391
+ return `The initial plan isn't approved or rejected through this tool \u2014 the user decides via "Start Building". Keep discussing, and revise the plan with writePlan if they want changes.`;
1392
+ }
1384
1393
  let content;
1385
1394
  try {
1386
1395
  content = await fs10.readFile(PLAN_FILE2, "utf-8");
package/dist/index.js CHANGED
@@ -938,8 +938,11 @@ var init_updatePlanStatus = __esm({
938
938
  required: ["status"]
939
939
  }
940
940
  },
941
- async execute(input) {
941
+ async execute(input, context) {
942
942
  const status = input.status;
943
+ if (context?.onboardingState === "intake") {
944
+ return `The initial plan isn't approved or rejected through this tool \u2014 the user decides via "Start Building". Keep discussing, and revise the plan with writePlan if they want changes.`;
945
+ }
943
946
  let content;
944
947
  try {
945
948
  content = await fs7.readFile(PLAN_FILE2, "utf-8");
@@ -1893,11 +1896,17 @@ function parseFrontmatter(filePath) {
1893
1896
  return { name: "", description: "", type: "" };
1894
1897
  }
1895
1898
  }
1896
- function loadPlanStatus() {
1899
+ function loadPlanStatus(onboardingState) {
1897
1900
  try {
1898
1901
  const content = fs10.readFileSync(".remy-plan.md", "utf-8");
1899
1902
  const match = content.match(/^---\n([\s\S]*?)\n---/);
1900
1903
  const status = match?.[1]?.match(/^status:\s*(.+)$/m)?.[1]?.trim();
1904
+ if (status === "pending" && onboardingState === "intake") {
1905
+ return `
1906
+ <pending_initial_plan>
1907
+ This is your initial plan, proposed via writePlan and awaiting the user's decision. The user approves it by pressing "Start Building" \u2014 you'll get an approveInitialPlan message when they do, and it will tell you to begin. Until then, stay in intake: keep discussing, and revise with writePlan if the user asks. Don't start building on your own, even if the user says "looks good" in chat.
1908
+ </pending_initial_plan>`;
1909
+ }
1901
1910
  if (status === "pending") {
1902
1911
  return `
1903
1912
  <pending_plan>
@@ -2292,7 +2301,7 @@ The user is currently in ${viewContext?.mode ?? "code"} mode.
2292
2301
  ${viewContext?.activeFile ? `Active file: ${viewContext.activeFile}` : ""}
2293
2302
  </view_context>
2294
2303
 
2295
- ${loadPlanStatus()}
2304
+ ${loadPlanStatus(onboardingState)}
2296
2305
  `;
2297
2306
  return resolveIncludes(template);
2298
2307
  }
@@ -357,15 +357,24 @@ A verified custom domain (and the app's `madewithremy.com` subdomain) also **sen
357
357
 
358
358
  ```ts
359
359
  {
360
- to: string; // full recipient address; localpart is arbitrary on catchall tiers
361
- from: string; // bare address, extracted from "Name <a@b>" form
362
- subject: string; // 'No Subject' if missing
363
- message: string; // plain text body, falls back to HTML if text is missing; 'No Body' if neither was sent
364
- html: string; // HTML body, or '' when text-only
365
- attachments: string[]; // CDN URLs already uploaded by the platform
360
+ to: string; // full recipient address; localpart is arbitrary on catchall tiers
361
+ from: string; // bare sender address, extracted from "Name <a@b>" form
362
+ fromName: string | null; // sender display name, or null
363
+ subject: string; // 'No Subject' if missing
364
+ message: string; // plain-text body, falls back to HTML if text is missing; 'No Body' if neither was sent
365
+ html: string; // HTML body, or '' when text-only
366
+ attachments: string[]; // CDN URLs — already uploaded by the platform
367
+ messageId: string | null; // this email's Message-ID, angle-bracketed (<id@host>)
368
+ inReplyTo: string | null; // Message-ID this email is replying to, if any
369
+ references: string[]; // prior Message-IDs in the thread (angle-bracketed); [] if none
370
+ replyTo: string | null; // Reply-To address — reply here, not `from`, when set
371
+ cc: string[]; // Cc recipient addresses
372
+ date: string | null; // original send time, ISO-8601
366
373
  }
367
374
  ```
368
375
 
376
+ To reply in-thread, feed these into `sendEmail`: set `inReplyTo` to the incoming `messageId` and `references` to `[...references, messageId]`. Send to `replyTo` when it's set, otherwise `from`. `sendEmail` returns `{ recipients, cc, bcc, from }` (who it sent to + the sender used); it does not return the sent message's own `Message-ID`, so thread off *inbound* mail, not off messages you sent.
377
+
369
378
  ### Attachments and size limits
370
379
 
371
380
  `attachments[]` is an array of CDN URLs — the platform has already received and uploaded the files. Fetch them server-side via the URL when you need the bytes; pass them through as URLs to UI or downstream services.
@@ -80,11 +80,21 @@ const { imageUrl } = await mindstudio.generateImage({
80
80
  prompt: 'A professional headshot placeholder',
81
81
  });
82
82
 
83
- // Send email
83
+ // Send email — own-brand sender auto-selected (custom domain / subdomain / Remy default)
84
84
  await mindstudio.sendEmail({
85
85
  to: 'user@example.com',
86
86
  subject: 'Your invoice',
87
- body: content,
87
+ body: content, // markdown or HTML, auto-detected; bodyType overrides. cc/bcc/replyTo/attachments also supported
88
+ });
89
+
90
+ // Reply in-thread to an inbound email (fields come from the email interface's input)
91
+ await mindstudio.sendEmail({
92
+ to: input.replyTo ?? input.from,
93
+ subject: `Re: ${input.subject}`,
94
+ body: reply,
95
+ inReplyTo: input.messageId ?? undefined,
96
+ references: input.messageId ? [...input.references, input.messageId] : input.references,
97
+ cc: input.cc, // reply-all
88
98
  });
89
99
 
90
100
  // Upload files
@@ -61,7 +61,7 @@ result.$billingCost; // cost in credits (if applicable)
61
61
 
62
62
  | Action | What it does | Key input | Key output |
63
63
  |--------|-------------|-----------|------------|
64
- | `sendEmail` | Send an email | `to`, `subject`, `body` | `messageId` |
64
+ | `sendEmail` | Send an email (own-brand sender auto-selected) | `to`, `subject`, `body`, `cc?`, `bcc?`, `from?`, `replyTo?`, `inReplyTo?`, `references?`, `bodyType?`, `attachments?` | `recipients`, `cc`, `bcc`, `from` |
65
65
  | `sendSMS` | Send a text message | `to`, `message` | `messageId` |
66
66
  | `postToSlackChannel` | Post to Slack | `channel`, `message` | — |
67
67
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/remy",
3
- "version": "0.1.228",
3
+ "version": "0.1.230",
4
4
  "description": "Remy coding agent",
5
5
  "repository": {
6
6
  "type": "git",