@mindstudio-ai/remy 0.1.7 → 0.1.9

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
@@ -347,17 +347,24 @@ The current date is ${now}.
347
347
  {{compiled/msfm.md}}
348
348
  </mindstudio_flavored_markdown_spec_docs>
349
349
 
350
- ${isLspConfigured() ? `<typescript_lsp>
351
- {{static/lsp.md}}
352
- </typescript_lsp>` : ""}
353
-
354
350
  <project_context>
355
351
  ${projectContext}
356
352
  </project_context>
357
353
 
354
+ <intake_mode_instructions>
358
355
  {{static/intake.md}}
356
+ </intake_mode_instructions>
359
357
 
358
+ <spec_authoring_instructions>
360
359
  {{static/authoring.md}}
360
+ </spec_authoring_instructions>
361
+
362
+ <code_authoring_instructions>
363
+ {{static/coding.md}}
364
+ ${isLspConfigured() ? `<typescript_lsp>
365
+ {{static/lsp.md}}
366
+ </typescript_lsp>` : ""}
367
+ </code_authoring_instructions>
361
368
 
362
369
  {{static/instructions.md}}
363
370
 
@@ -886,7 +893,88 @@ async function listRecursive(dir) {
886
893
  return results;
887
894
  }
888
895
 
889
- // src/tools/spec/setProjectOnboardingState.ts
896
+ // src/tools/spec/clearSyncStatus.ts
897
+ var clearSyncStatusTool = {
898
+ definition: {
899
+ name: "clearSyncStatus",
900
+ description: "Clear the sync status flags after syncing spec and code. Call this after finishing a sync operation.",
901
+ inputSchema: {
902
+ type: "object",
903
+ properties: {}
904
+ }
905
+ },
906
+ async execute() {
907
+ return "ok";
908
+ }
909
+ };
910
+
911
+ // src/tools/spec/presentSyncPlan.ts
912
+ var presentSyncPlanTool = {
913
+ definition: {
914
+ name: "presentSyncPlan",
915
+ description: "Present a structured sync plan to the user for approval. Write a clear markdown summary of what changed and what you intend to update. The user will see this in a full-screen view and can approve or dismiss. Call this BEFORE making any sync edits.",
916
+ inputSchema: {
917
+ type: "object",
918
+ properties: {
919
+ content: {
920
+ type: "string",
921
+ description: "Markdown plan describing what changed and what will be updated."
922
+ }
923
+ },
924
+ required: ["content"]
925
+ }
926
+ },
927
+ streaming: {},
928
+ async execute() {
929
+ return "approved";
930
+ }
931
+ };
932
+
933
+ // src/tools/spec/presentPublishPlan.ts
934
+ var presentPublishPlanTool = {
935
+ definition: {
936
+ name: "presentPublishPlan",
937
+ description: "Present a publish changelog to the user for approval. Write a clear markdown summary of what changed since the last deploy. The user will see this in a full-screen view and can approve or dismiss. Call this BEFORE committing or pushing.",
938
+ inputSchema: {
939
+ type: "object",
940
+ properties: {
941
+ content: {
942
+ type: "string",
943
+ description: "Markdown changelog describing what changed and what will be deployed."
944
+ }
945
+ },
946
+ required: ["content"]
947
+ }
948
+ },
949
+ streaming: {},
950
+ async execute() {
951
+ return "approved";
952
+ }
953
+ };
954
+
955
+ // src/tools/spec/presentPlan.ts
956
+ var presentPlanTool = {
957
+ definition: {
958
+ name: "presentPlan",
959
+ description: "Present an implementation plan for user approval before making changes. Use this only for large, multi-step changes or when the user explicitly asks to see a plan. Most work should be done autonomously without a plan. Write a clear markdown summary of what you intend to do in plain language \u2014 describe the changes from the user's perspective, not as a list of files and code paths. If the user rejects with feedback, revise and present again.",
960
+ inputSchema: {
961
+ type: "object",
962
+ properties: {
963
+ content: {
964
+ type: "string",
965
+ description: "Markdown plan describing what you intend to do."
966
+ }
967
+ },
968
+ required: ["content"]
969
+ }
970
+ },
971
+ streaming: {},
972
+ async execute() {
973
+ return "approved";
974
+ }
975
+ };
976
+
977
+ // src/tools/common/setProjectOnboardingState.ts
890
978
  var setProjectOnboardingStateTool = {
891
979
  definition: {
892
980
  name: "setProjectOnboardingState",
@@ -912,7 +1000,7 @@ var setProjectOnboardingStateTool = {
912
1000
  }
913
1001
  };
914
1002
 
915
- // src/tools/spec/promptUser.ts
1003
+ // src/tools/common/promptUser.ts
916
1004
  var promptUserTool = {
917
1005
  definition: {
918
1006
  name: "promptUser",
@@ -941,7 +1029,7 @@ var promptUserTool = {
941
1029
  type: {
942
1030
  type: "string",
943
1031
  enum: ["select", "checklist", "text", "file", "color"],
944
- description: "select: pick one from a list. checklist: pick one or more from a list. text: free-form input. file: file/image upload, returns CDN URL(s) that can be referenced directly or curled onto disk. color: color picker (returns hex)."
1032
+ description: 'select: pick one from a list. checklist: pick one or more from a list. The user can always provide a custom "Other" answer for select and checklist questions, so there is no need to include an "Other" option. text: free-form input. file: file/image upload, returns CDN URL(s) that can be referenced directly or curled onto disk. color: color picker (returns hex).'
945
1033
  },
946
1034
  helpText: {
947
1035
  type: "string",
@@ -978,10 +1066,6 @@ var promptUserTool = {
978
1066
  type: "boolean",
979
1067
  description: "For file type: allow multiple uploads (returns array of URLs). Defaults to false."
980
1068
  },
981
- allowOther: {
982
- type: "boolean",
983
- description: 'For select and checklist types: adds an "Other" option that lets the user type a custom answer. Use this instead of adding a separate follow-up text field for custom input. Defaults to false.'
984
- },
985
1069
  format: {
986
1070
  type: "string",
987
1071
  enum: ["email", "url", "phone", "number"],
@@ -1049,113 +1133,160 @@ ${lines.join("\n")}`;
1049
1133
  }
1050
1134
  };
1051
1135
 
1052
- // src/tools/spec/clearSyncStatus.ts
1053
- var clearSyncStatusTool = {
1054
- definition: {
1055
- name: "clearSyncStatus",
1056
- description: "Clear the sync status flags after syncing spec and code. Call this after finishing a sync operation.",
1057
- inputSchema: {
1058
- type: "object",
1059
- properties: {}
1060
- }
1061
- },
1062
- async execute() {
1063
- return "ok";
1064
- }
1065
- };
1066
-
1067
- // src/tools/spec/presentSyncPlan.ts
1068
- var presentSyncPlanTool = {
1136
+ // src/tools/common/confirmDestructiveAction.ts
1137
+ var confirmDestructiveActionTool = {
1069
1138
  definition: {
1070
- name: "presentSyncPlan",
1071
- description: "Present a structured sync plan to the user for approval. Write a clear markdown summary of what changed and what you intend to update. The user will see this in a full-screen view and can approve or dismiss. Call this BEFORE making any sync edits.",
1139
+ name: "confirmDestructiveAction",
1140
+ description: "Confirm a destructive or irreversible action with the user. Use for things like deleting data, resetting the database, or discarding draft work. Do not use after presentSyncPlan, presentPublishPlan, or presentPlan (those already include approval). Do not use before onboarding state transitions.",
1072
1141
  inputSchema: {
1073
1142
  type: "object",
1074
1143
  properties: {
1075
- content: {
1144
+ message: {
1076
1145
  type: "string",
1077
- description: "Markdown plan describing what changed and what will be updated."
1146
+ description: "Explanation of what is about to happen and why confirmation is needed."
1147
+ },
1148
+ confirmLabel: {
1149
+ type: "string",
1150
+ description: 'Custom label for the confirm button (e.g., "Delete", "Reset Database"). Defaults to "Confirm".'
1151
+ },
1152
+ dismissLabel: {
1153
+ type: "string",
1154
+ description: 'Custom label for the dismiss button (e.g., "Keep It", "Go Back"). Defaults to "Cancel".'
1078
1155
  }
1079
1156
  },
1080
- required: ["content"]
1157
+ required: ["message"]
1081
1158
  }
1082
1159
  },
1083
- streaming: {},
1084
1160
  async execute() {
1085
- return "approved";
1161
+ return "confirmed";
1086
1162
  }
1087
1163
  };
1088
1164
 
1089
- // src/tools/spec/presentPublishPlan.ts
1090
- var presentPublishPlanTool = {
1165
+ // src/tools/common/askMindStudioSdk.ts
1166
+ import { exec } from "child_process";
1167
+ var askMindStudioSdkTool = {
1091
1168
  definition: {
1092
- name: "presentPublishPlan",
1093
- description: "Present a publish changelog to the user for approval. Write a clear markdown summary of what changed since the last deploy. The user will see this in a full-screen view and can approve or dismiss. Call this BEFORE committing or pushing.",
1169
+ name: "askMindStudioSdk",
1170
+ description: "Ask the MindStudio SDK assistant about available actions, AI models, connectors, and integrations using natural language. Returns code examples with correct method signatures, model IDs, and config options. Always use this to verify correct SDK usage, especially model IDs and configuration options. Describe what you need, not what API methods you need; the assistant will figure out the right approach. This runs its own LLM call so it has a few seconds of latency; batch multiple questions into a single query.",
1094
1171
  inputSchema: {
1095
1172
  type: "object",
1096
1173
  properties: {
1097
- content: {
1174
+ query: {
1098
1175
  type: "string",
1099
- description: "Markdown changelog describing what changed and what will be deployed."
1176
+ description: "Natural language question about the SDK."
1100
1177
  }
1101
1178
  },
1102
- required: ["content"]
1179
+ required: ["query"]
1103
1180
  }
1104
1181
  },
1105
- streaming: {},
1106
- async execute() {
1107
- return "approved";
1182
+ async execute(input) {
1183
+ const query = input.query;
1184
+ return new Promise((resolve) => {
1185
+ exec(
1186
+ `mindstudio ask ${JSON.stringify(query)}`,
1187
+ { timeout: 6e4, maxBuffer: 512 * 1024 },
1188
+ (err, stdout, stderr) => {
1189
+ if (stdout.trim()) {
1190
+ resolve(stdout.trim());
1191
+ return;
1192
+ }
1193
+ if (err) {
1194
+ resolve(`Error: ${stderr.trim() || err.message}`);
1195
+ return;
1196
+ }
1197
+ resolve("(no response)");
1198
+ }
1199
+ );
1200
+ });
1108
1201
  }
1109
1202
  };
1110
1203
 
1111
- // src/tools/spec/presentPlan.ts
1112
- var presentPlanTool = {
1204
+ // src/tools/common/fetchUrl.ts
1205
+ import { exec as exec2 } from "child_process";
1206
+ var fetchUrlTool = {
1113
1207
  definition: {
1114
- name: "presentPlan",
1115
- description: "Present an implementation plan for user approval before making changes. Use this only for large, multi-step changes or when the user explicitly asks to see a plan. Most work should be done autonomously without a plan. Write a clear markdown summary of what you intend to do in plain language \u2014 describe the changes from the user's perspective, not as a list of files and code paths. If the user rejects with feedback, revise and present again.",
1208
+ name: "fetchUrl",
1209
+ description: "Fetch the content of a web page. Returns the page as markdown text. Optionally capture a screenshot if you need see the visual design.",
1116
1210
  inputSchema: {
1117
1211
  type: "object",
1118
1212
  properties: {
1119
- content: {
1213
+ url: {
1120
1214
  type: "string",
1121
- description: "Markdown plan describing what you intend to do."
1215
+ description: "The URL to fetch."
1216
+ },
1217
+ screenshot: {
1218
+ type: "boolean",
1219
+ description: "Capture a screenshot of the page in addition to the text content. Adds latency; only use when you need to see the visual design."
1122
1220
  }
1123
1221
  },
1124
- required: ["content"]
1222
+ required: ["url"]
1125
1223
  }
1126
1224
  },
1127
- streaming: {},
1128
- async execute() {
1129
- return "approved";
1225
+ async execute(input) {
1226
+ const url = input.url;
1227
+ const screenshot = input.screenshot;
1228
+ const pageOptions = { onlyMainContent: true };
1229
+ if (screenshot) {
1230
+ pageOptions.screenshot = true;
1231
+ }
1232
+ const cmd = `mindstudio scrape-url --url ${JSON.stringify(url)} --page-options ${JSON.stringify(JSON.stringify(pageOptions))} --no-meta`;
1233
+ return new Promise((resolve) => {
1234
+ exec2(
1235
+ cmd,
1236
+ { timeout: 6e4, maxBuffer: 1024 * 1024 },
1237
+ (err, stdout, stderr) => {
1238
+ if (stdout.trim()) {
1239
+ resolve(stdout.trim());
1240
+ return;
1241
+ }
1242
+ if (err) {
1243
+ resolve(`Error: ${stderr.trim() || err.message}`);
1244
+ return;
1245
+ }
1246
+ resolve("(no response)");
1247
+ }
1248
+ );
1249
+ });
1130
1250
  }
1131
1251
  };
1132
1252
 
1133
- // src/tools/spec/confirmDestructiveAction.ts
1134
- var confirmDestructiveActionTool = {
1253
+ // src/tools/common/searchGoogle.ts
1254
+ import { exec as exec3 } from "child_process";
1255
+ var searchGoogleTool = {
1135
1256
  definition: {
1136
- name: "confirmDestructiveAction",
1137
- description: "Confirm a destructive or irreversible action with the user. Use for things like deleting data, resetting the database, or discarding draft work. Do not use after presentSyncPlan, presentPublishPlan, or presentPlan (those already include approval). Do not use before onboarding state transitions.",
1257
+ name: "searchGoogle",
1258
+ description: "Search Google and return results. Use for research, finding documentation, looking up APIs, or any task where web search would help.",
1138
1259
  inputSchema: {
1139
1260
  type: "object",
1140
1261
  properties: {
1141
- message: {
1142
- type: "string",
1143
- description: "Explanation of what is about to happen and why confirmation is needed."
1144
- },
1145
- confirmLabel: {
1146
- type: "string",
1147
- description: 'Custom label for the confirm button (e.g., "Delete", "Reset Database"). Defaults to "Confirm".'
1148
- },
1149
- dismissLabel: {
1262
+ query: {
1150
1263
  type: "string",
1151
- description: 'Custom label for the dismiss button (e.g., "Keep It", "Go Back"). Defaults to "Cancel".'
1264
+ description: "The search query."
1152
1265
  }
1153
1266
  },
1154
- required: ["message"]
1267
+ required: ["query"]
1155
1268
  }
1156
1269
  },
1157
- async execute() {
1158
- return "confirmed";
1270
+ async execute(input) {
1271
+ const query = input.query;
1272
+ const cmd = `mindstudio search-google --query ${JSON.stringify(query)} --export-type json --output-key results --no-meta`;
1273
+ return new Promise((resolve) => {
1274
+ exec3(
1275
+ cmd,
1276
+ { timeout: 6e4, maxBuffer: 512 * 1024 },
1277
+ (err, stdout, stderr) => {
1278
+ if (stdout.trim()) {
1279
+ resolve(stdout.trim());
1280
+ return;
1281
+ }
1282
+ if (err) {
1283
+ resolve(`Error: ${stderr.trim() || err.message}`);
1284
+ return;
1285
+ }
1286
+ resolve("(no response)");
1287
+ }
1288
+ );
1289
+ });
1159
1290
  }
1160
1291
  };
1161
1292
 
@@ -1459,7 +1590,7 @@ ${unifiedDiff(input.path, content, updated)}`;
1459
1590
  };
1460
1591
 
1461
1592
  // src/tools/code/bash.ts
1462
- import { exec } from "child_process";
1593
+ import { exec as exec4 } from "child_process";
1463
1594
  var DEFAULT_TIMEOUT_MS = 12e4;
1464
1595
  var DEFAULT_MAX_LINES3 = 500;
1465
1596
  var bashTool = {
@@ -1493,7 +1624,7 @@ var bashTool = {
1493
1624
  const maxLines = input.maxLines === 0 ? Infinity : input.maxLines || DEFAULT_MAX_LINES3;
1494
1625
  const timeoutMs = input.timeout ? input.timeout * 1e3 : DEFAULT_TIMEOUT_MS;
1495
1626
  return new Promise((resolve) => {
1496
- exec(
1627
+ exec4(
1497
1628
  input.command,
1498
1629
  {
1499
1630
  timeout: timeoutMs,
@@ -1533,7 +1664,7 @@ var bashTool = {
1533
1664
  };
1534
1665
 
1535
1666
  // src/tools/code/grep.ts
1536
- import { exec as exec2 } from "child_process";
1667
+ import { exec as exec5 } from "child_process";
1537
1668
  var DEFAULT_MAX = 50;
1538
1669
  function formatResults(stdout, max) {
1539
1670
  const lines = stdout.trim().split("\n");
@@ -1580,12 +1711,12 @@ var grepTool = {
1580
1711
  const rgCmd = `rg -n --no-heading --max-count=${max}${globFlag} '${escaped}' ${searchPath}`;
1581
1712
  const grepCmd = `grep -rn --max-count=${max} '${escaped}' ${searchPath} --include='*.ts' --include='*.tsx' --include='*.js' --include='*.json' --include='*.md'`;
1582
1713
  return new Promise((resolve) => {
1583
- exec2(rgCmd, { maxBuffer: 512 * 1024 }, (err, stdout) => {
1714
+ exec5(rgCmd, { maxBuffer: 512 * 1024 }, (err, stdout) => {
1584
1715
  if (stdout?.trim()) {
1585
1716
  resolve(formatResults(stdout, max));
1586
1717
  return;
1587
1718
  }
1588
- exec2(grepCmd, { maxBuffer: 512 * 1024 }, (_err, grepStdout) => {
1719
+ exec5(grepCmd, { maxBuffer: 512 * 1024 }, (_err, grepStdout) => {
1589
1720
  if (grepStdout?.trim()) {
1590
1721
  resolve(formatResults(grepStdout, max));
1591
1722
  } else {
@@ -1769,45 +1900,6 @@ var restartProcessTool = {
1769
1900
  }
1770
1901
  };
1771
1902
 
1772
- // src/tools/code/askMindStudioSdk.ts
1773
- import { exec as exec3 } from "child_process";
1774
- var askMindStudioSdkTool = {
1775
- definition: {
1776
- name: "askMindStudioSdk",
1777
- description: "Ask the MindStudio SDK assistant about actions, AI models, connectors, and integrations. Returns code examples with correct method signatures, model IDs, and config options. Use this instead of guessing SDK usage from memory. Describe what you need, not what API methods you need; the assistant will figure out the right approach. This runs its own LLM call so it has a few seconds of latency; batch related questions into a single query.",
1778
- inputSchema: {
1779
- type: "object",
1780
- properties: {
1781
- query: {
1782
- type: "string",
1783
- description: "Natural language question about the SDK."
1784
- }
1785
- },
1786
- required: ["query"]
1787
- }
1788
- },
1789
- async execute(input) {
1790
- const query = input.query;
1791
- return new Promise((resolve) => {
1792
- exec3(
1793
- `mindstudio ask ${JSON.stringify(query)}`,
1794
- { timeout: 6e4, maxBuffer: 512 * 1024 },
1795
- (err, stdout, stderr) => {
1796
- if (stdout.trim()) {
1797
- resolve(stdout.trim());
1798
- return;
1799
- }
1800
- if (err) {
1801
- resolve(`Error: ${stderr.trim() || err.message}`);
1802
- return;
1803
- }
1804
- resolve("(no response)");
1805
- }
1806
- );
1807
- });
1808
- }
1809
- };
1810
-
1811
1903
  // src/tools/code/runScenario.ts
1812
1904
  var runScenarioTool = {
1813
1905
  definition: {
@@ -2128,7 +2220,6 @@ function getCodeTools() {
2128
2220
  globTool,
2129
2221
  listDirTool,
2130
2222
  editsFinishedTool,
2131
- askMindStudioSdkTool,
2132
2223
  runScenarioTool,
2133
2224
  runMethodTool,
2134
2225
  screenshotTool,
@@ -2143,7 +2234,10 @@ function getCommonTools() {
2143
2234
  return [
2144
2235
  setProjectOnboardingStateTool,
2145
2236
  promptUserTool,
2146
- confirmDestructiveActionTool
2237
+ confirmDestructiveActionTool,
2238
+ askMindStudioSdkTool,
2239
+ fetchUrlTool,
2240
+ searchGoogleTool
2147
2241
  ];
2148
2242
  }
2149
2243
  function getPostOnboardingTools() {
package/dist/index.js CHANGED
@@ -634,10 +634,115 @@ var init_listSpecFiles = __esm({
634
634
  }
635
635
  });
636
636
 
637
- // src/tools/spec/setProjectOnboardingState.ts
637
+ // src/tools/spec/clearSyncStatus.ts
638
+ var clearSyncStatusTool;
639
+ var init_clearSyncStatus = __esm({
640
+ "src/tools/spec/clearSyncStatus.ts"() {
641
+ "use strict";
642
+ clearSyncStatusTool = {
643
+ definition: {
644
+ name: "clearSyncStatus",
645
+ description: "Clear the sync status flags after syncing spec and code. Call this after finishing a sync operation.",
646
+ inputSchema: {
647
+ type: "object",
648
+ properties: {}
649
+ }
650
+ },
651
+ async execute() {
652
+ return "ok";
653
+ }
654
+ };
655
+ }
656
+ });
657
+
658
+ // src/tools/spec/presentSyncPlan.ts
659
+ var presentSyncPlanTool;
660
+ var init_presentSyncPlan = __esm({
661
+ "src/tools/spec/presentSyncPlan.ts"() {
662
+ "use strict";
663
+ presentSyncPlanTool = {
664
+ definition: {
665
+ name: "presentSyncPlan",
666
+ description: "Present a structured sync plan to the user for approval. Write a clear markdown summary of what changed and what you intend to update. The user will see this in a full-screen view and can approve or dismiss. Call this BEFORE making any sync edits.",
667
+ inputSchema: {
668
+ type: "object",
669
+ properties: {
670
+ content: {
671
+ type: "string",
672
+ description: "Markdown plan describing what changed and what will be updated."
673
+ }
674
+ },
675
+ required: ["content"]
676
+ }
677
+ },
678
+ streaming: {},
679
+ async execute() {
680
+ return "approved";
681
+ }
682
+ };
683
+ }
684
+ });
685
+
686
+ // src/tools/spec/presentPublishPlan.ts
687
+ var presentPublishPlanTool;
688
+ var init_presentPublishPlan = __esm({
689
+ "src/tools/spec/presentPublishPlan.ts"() {
690
+ "use strict";
691
+ presentPublishPlanTool = {
692
+ definition: {
693
+ name: "presentPublishPlan",
694
+ description: "Present a publish changelog to the user for approval. Write a clear markdown summary of what changed since the last deploy. The user will see this in a full-screen view and can approve or dismiss. Call this BEFORE committing or pushing.",
695
+ inputSchema: {
696
+ type: "object",
697
+ properties: {
698
+ content: {
699
+ type: "string",
700
+ description: "Markdown changelog describing what changed and what will be deployed."
701
+ }
702
+ },
703
+ required: ["content"]
704
+ }
705
+ },
706
+ streaming: {},
707
+ async execute() {
708
+ return "approved";
709
+ }
710
+ };
711
+ }
712
+ });
713
+
714
+ // src/tools/spec/presentPlan.ts
715
+ var presentPlanTool;
716
+ var init_presentPlan = __esm({
717
+ "src/tools/spec/presentPlan.ts"() {
718
+ "use strict";
719
+ presentPlanTool = {
720
+ definition: {
721
+ name: "presentPlan",
722
+ description: "Present an implementation plan for user approval before making changes. Use this only for large, multi-step changes or when the user explicitly asks to see a plan. Most work should be done autonomously without a plan. Write a clear markdown summary of what you intend to do in plain language \u2014 describe the changes from the user's perspective, not as a list of files and code paths. If the user rejects with feedback, revise and present again.",
723
+ inputSchema: {
724
+ type: "object",
725
+ properties: {
726
+ content: {
727
+ type: "string",
728
+ description: "Markdown plan describing what you intend to do."
729
+ }
730
+ },
731
+ required: ["content"]
732
+ }
733
+ },
734
+ streaming: {},
735
+ async execute() {
736
+ return "approved";
737
+ }
738
+ };
739
+ }
740
+ });
741
+
742
+ // src/tools/common/setProjectOnboardingState.ts
638
743
  var setProjectOnboardingStateTool;
639
744
  var init_setProjectOnboardingState = __esm({
640
- "src/tools/spec/setProjectOnboardingState.ts"() {
745
+ "src/tools/common/setProjectOnboardingState.ts"() {
641
746
  "use strict";
642
747
  setProjectOnboardingStateTool = {
643
748
  definition: {
@@ -666,10 +771,10 @@ var init_setProjectOnboardingState = __esm({
666
771
  }
667
772
  });
668
773
 
669
- // src/tools/spec/promptUser.ts
774
+ // src/tools/common/promptUser.ts
670
775
  var promptUserTool;
671
776
  var init_promptUser = __esm({
672
- "src/tools/spec/promptUser.ts"() {
777
+ "src/tools/common/promptUser.ts"() {
673
778
  "use strict";
674
779
  promptUserTool = {
675
780
  definition: {
@@ -699,7 +804,7 @@ var init_promptUser = __esm({
699
804
  type: {
700
805
  type: "string",
701
806
  enum: ["select", "checklist", "text", "file", "color"],
702
- description: "select: pick one from a list. checklist: pick one or more from a list. text: free-form input. file: file/image upload, returns CDN URL(s) that can be referenced directly or curled onto disk. color: color picker (returns hex)."
807
+ description: 'select: pick one from a list. checklist: pick one or more from a list. The user can always provide a custom "Other" answer for select and checklist questions, so there is no need to include an "Other" option. text: free-form input. file: file/image upload, returns CDN URL(s) that can be referenced directly or curled onto disk. color: color picker (returns hex).'
703
808
  },
704
809
  helpText: {
705
810
  type: "string",
@@ -736,10 +841,6 @@ var init_promptUser = __esm({
736
841
  type: "boolean",
737
842
  description: "For file type: allow multiple uploads (returns array of URLs). Defaults to false."
738
843
  },
739
- allowOther: {
740
- type: "boolean",
741
- description: 'For select and checklist types: adds an "Other" option that lets the user type a custom answer. Use this instead of adding a separate follow-up text field for custom input. Defaults to false.'
742
- },
743
844
  format: {
744
845
  type: "string",
745
846
  enum: ["email", "url", "phone", "number"],
@@ -809,141 +910,182 @@ ${lines.join("\n")}`;
809
910
  }
810
911
  });
811
912
 
812
- // src/tools/spec/clearSyncStatus.ts
813
- var clearSyncStatusTool;
814
- var init_clearSyncStatus = __esm({
815
- "src/tools/spec/clearSyncStatus.ts"() {
816
- "use strict";
817
- clearSyncStatusTool = {
818
- definition: {
819
- name: "clearSyncStatus",
820
- description: "Clear the sync status flags after syncing spec and code. Call this after finishing a sync operation.",
821
- inputSchema: {
822
- type: "object",
823
- properties: {}
824
- }
825
- },
826
- async execute() {
827
- return "ok";
828
- }
829
- };
830
- }
831
- });
832
-
833
- // src/tools/spec/presentSyncPlan.ts
834
- var presentSyncPlanTool;
835
- var init_presentSyncPlan = __esm({
836
- "src/tools/spec/presentSyncPlan.ts"() {
913
+ // src/tools/common/confirmDestructiveAction.ts
914
+ var confirmDestructiveActionTool;
915
+ var init_confirmDestructiveAction = __esm({
916
+ "src/tools/common/confirmDestructiveAction.ts"() {
837
917
  "use strict";
838
- presentSyncPlanTool = {
918
+ confirmDestructiveActionTool = {
839
919
  definition: {
840
- name: "presentSyncPlan",
841
- description: "Present a structured sync plan to the user for approval. Write a clear markdown summary of what changed and what you intend to update. The user will see this in a full-screen view and can approve or dismiss. Call this BEFORE making any sync edits.",
920
+ name: "confirmDestructiveAction",
921
+ description: "Confirm a destructive or irreversible action with the user. Use for things like deleting data, resetting the database, or discarding draft work. Do not use after presentSyncPlan, presentPublishPlan, or presentPlan (those already include approval). Do not use before onboarding state transitions.",
842
922
  inputSchema: {
843
923
  type: "object",
844
924
  properties: {
845
- content: {
925
+ message: {
846
926
  type: "string",
847
- description: "Markdown plan describing what changed and what will be updated."
927
+ description: "Explanation of what is about to happen and why confirmation is needed."
928
+ },
929
+ confirmLabel: {
930
+ type: "string",
931
+ description: 'Custom label for the confirm button (e.g., "Delete", "Reset Database"). Defaults to "Confirm".'
932
+ },
933
+ dismissLabel: {
934
+ type: "string",
935
+ description: 'Custom label for the dismiss button (e.g., "Keep It", "Go Back"). Defaults to "Cancel".'
848
936
  }
849
937
  },
850
- required: ["content"]
938
+ required: ["message"]
851
939
  }
852
940
  },
853
- streaming: {},
854
941
  async execute() {
855
- return "approved";
942
+ return "confirmed";
856
943
  }
857
944
  };
858
945
  }
859
946
  });
860
947
 
861
- // src/tools/spec/presentPublishPlan.ts
862
- var presentPublishPlanTool;
863
- var init_presentPublishPlan = __esm({
864
- "src/tools/spec/presentPublishPlan.ts"() {
948
+ // src/tools/common/askMindStudioSdk.ts
949
+ import { exec } from "child_process";
950
+ var askMindStudioSdkTool;
951
+ var init_askMindStudioSdk = __esm({
952
+ "src/tools/common/askMindStudioSdk.ts"() {
865
953
  "use strict";
866
- presentPublishPlanTool = {
954
+ askMindStudioSdkTool = {
867
955
  definition: {
868
- name: "presentPublishPlan",
869
- description: "Present a publish changelog to the user for approval. Write a clear markdown summary of what changed since the last deploy. The user will see this in a full-screen view and can approve or dismiss. Call this BEFORE committing or pushing.",
956
+ name: "askMindStudioSdk",
957
+ description: "Ask the MindStudio SDK assistant about available actions, AI models, connectors, and integrations using natural language. Returns code examples with correct method signatures, model IDs, and config options. Always use this to verify correct SDK usage, especially model IDs and configuration options. Describe what you need, not what API methods you need; the assistant will figure out the right approach. This runs its own LLM call so it has a few seconds of latency; batch multiple questions into a single query.",
870
958
  inputSchema: {
871
959
  type: "object",
872
960
  properties: {
873
- content: {
961
+ query: {
874
962
  type: "string",
875
- description: "Markdown changelog describing what changed and what will be deployed."
963
+ description: "Natural language question about the SDK."
876
964
  }
877
965
  },
878
- required: ["content"]
966
+ required: ["query"]
879
967
  }
880
968
  },
881
- streaming: {},
882
- async execute() {
883
- return "approved";
969
+ async execute(input) {
970
+ const query = input.query;
971
+ return new Promise((resolve) => {
972
+ exec(
973
+ `mindstudio ask ${JSON.stringify(query)}`,
974
+ { timeout: 6e4, maxBuffer: 512 * 1024 },
975
+ (err, stdout, stderr) => {
976
+ if (stdout.trim()) {
977
+ resolve(stdout.trim());
978
+ return;
979
+ }
980
+ if (err) {
981
+ resolve(`Error: ${stderr.trim() || err.message}`);
982
+ return;
983
+ }
984
+ resolve("(no response)");
985
+ }
986
+ );
987
+ });
884
988
  }
885
989
  };
886
990
  }
887
991
  });
888
992
 
889
- // src/tools/spec/presentPlan.ts
890
- var presentPlanTool;
891
- var init_presentPlan = __esm({
892
- "src/tools/spec/presentPlan.ts"() {
993
+ // src/tools/common/fetchUrl.ts
994
+ import { exec as exec2 } from "child_process";
995
+ var fetchUrlTool;
996
+ var init_fetchUrl = __esm({
997
+ "src/tools/common/fetchUrl.ts"() {
893
998
  "use strict";
894
- presentPlanTool = {
999
+ fetchUrlTool = {
895
1000
  definition: {
896
- name: "presentPlan",
897
- description: "Present an implementation plan for user approval before making changes. Use this only for large, multi-step changes or when the user explicitly asks to see a plan. Most work should be done autonomously without a plan. Write a clear markdown summary of what you intend to do in plain language \u2014 describe the changes from the user's perspective, not as a list of files and code paths. If the user rejects with feedback, revise and present again.",
1001
+ name: "fetchUrl",
1002
+ description: "Fetch the content of a web page. Returns the page as markdown text. Optionally capture a screenshot if you need see the visual design.",
898
1003
  inputSchema: {
899
1004
  type: "object",
900
1005
  properties: {
901
- content: {
1006
+ url: {
902
1007
  type: "string",
903
- description: "Markdown plan describing what you intend to do."
1008
+ description: "The URL to fetch."
1009
+ },
1010
+ screenshot: {
1011
+ type: "boolean",
1012
+ description: "Capture a screenshot of the page in addition to the text content. Adds latency; only use when you need to see the visual design."
904
1013
  }
905
1014
  },
906
- required: ["content"]
1015
+ required: ["url"]
907
1016
  }
908
1017
  },
909
- streaming: {},
910
- async execute() {
911
- return "approved";
1018
+ async execute(input) {
1019
+ const url = input.url;
1020
+ const screenshot = input.screenshot;
1021
+ const pageOptions = { onlyMainContent: true };
1022
+ if (screenshot) {
1023
+ pageOptions.screenshot = true;
1024
+ }
1025
+ const cmd = `mindstudio scrape-url --url ${JSON.stringify(url)} --page-options ${JSON.stringify(JSON.stringify(pageOptions))} --no-meta`;
1026
+ return new Promise((resolve) => {
1027
+ exec2(
1028
+ cmd,
1029
+ { timeout: 6e4, maxBuffer: 1024 * 1024 },
1030
+ (err, stdout, stderr) => {
1031
+ if (stdout.trim()) {
1032
+ resolve(stdout.trim());
1033
+ return;
1034
+ }
1035
+ if (err) {
1036
+ resolve(`Error: ${stderr.trim() || err.message}`);
1037
+ return;
1038
+ }
1039
+ resolve("(no response)");
1040
+ }
1041
+ );
1042
+ });
912
1043
  }
913
1044
  };
914
1045
  }
915
1046
  });
916
1047
 
917
- // src/tools/spec/confirmDestructiveAction.ts
918
- var confirmDestructiveActionTool;
919
- var init_confirmDestructiveAction = __esm({
920
- "src/tools/spec/confirmDestructiveAction.ts"() {
1048
+ // src/tools/common/searchGoogle.ts
1049
+ import { exec as exec3 } from "child_process";
1050
+ var searchGoogleTool;
1051
+ var init_searchGoogle = __esm({
1052
+ "src/tools/common/searchGoogle.ts"() {
921
1053
  "use strict";
922
- confirmDestructiveActionTool = {
1054
+ searchGoogleTool = {
923
1055
  definition: {
924
- name: "confirmDestructiveAction",
925
- description: "Confirm a destructive or irreversible action with the user. Use for things like deleting data, resetting the database, or discarding draft work. Do not use after presentSyncPlan, presentPublishPlan, or presentPlan (those already include approval). Do not use before onboarding state transitions.",
1056
+ name: "searchGoogle",
1057
+ description: "Search Google and return results. Use for research, finding documentation, looking up APIs, or any task where web search would help.",
926
1058
  inputSchema: {
927
1059
  type: "object",
928
1060
  properties: {
929
- message: {
930
- type: "string",
931
- description: "Explanation of what is about to happen and why confirmation is needed."
932
- },
933
- confirmLabel: {
934
- type: "string",
935
- description: 'Custom label for the confirm button (e.g., "Delete", "Reset Database"). Defaults to "Confirm".'
936
- },
937
- dismissLabel: {
1061
+ query: {
938
1062
  type: "string",
939
- description: 'Custom label for the dismiss button (e.g., "Keep It", "Go Back"). Defaults to "Cancel".'
1063
+ description: "The search query."
940
1064
  }
941
1065
  },
942
- required: ["message"]
1066
+ required: ["query"]
943
1067
  }
944
1068
  },
945
- async execute() {
946
- return "confirmed";
1069
+ async execute(input) {
1070
+ const query = input.query;
1071
+ const cmd = `mindstudio search-google --query ${JSON.stringify(query)} --export-type json --output-key results --no-meta`;
1072
+ return new Promise((resolve) => {
1073
+ exec3(
1074
+ cmd,
1075
+ { timeout: 6e4, maxBuffer: 512 * 1024 },
1076
+ (err, stdout, stderr) => {
1077
+ if (stdout.trim()) {
1078
+ resolve(stdout.trim());
1079
+ return;
1080
+ }
1081
+ if (err) {
1082
+ resolve(`Error: ${stderr.trim() || err.message}`);
1083
+ return;
1084
+ }
1085
+ resolve("(no response)");
1086
+ }
1087
+ );
1088
+ });
947
1089
  }
948
1090
  };
949
1091
  }
@@ -1273,7 +1415,7 @@ ${unifiedDiff(input.path, content, updated)}`;
1273
1415
  });
1274
1416
 
1275
1417
  // src/tools/code/bash.ts
1276
- import { exec } from "child_process";
1418
+ import { exec as exec4 } from "child_process";
1277
1419
  var DEFAULT_TIMEOUT_MS, DEFAULT_MAX_LINES3, bashTool;
1278
1420
  var init_bash = __esm({
1279
1421
  "src/tools/code/bash.ts"() {
@@ -1311,7 +1453,7 @@ var init_bash = __esm({
1311
1453
  const maxLines = input.maxLines === 0 ? Infinity : input.maxLines || DEFAULT_MAX_LINES3;
1312
1454
  const timeoutMs = input.timeout ? input.timeout * 1e3 : DEFAULT_TIMEOUT_MS;
1313
1455
  return new Promise((resolve) => {
1314
- exec(
1456
+ exec4(
1315
1457
  input.command,
1316
1458
  {
1317
1459
  timeout: timeoutMs,
@@ -1353,7 +1495,7 @@ var init_bash = __esm({
1353
1495
  });
1354
1496
 
1355
1497
  // src/tools/code/grep.ts
1356
- import { exec as exec2 } from "child_process";
1498
+ import { exec as exec5 } from "child_process";
1357
1499
  function formatResults(stdout, max) {
1358
1500
  const lines = stdout.trim().split("\n");
1359
1501
  let result = lines.join("\n");
@@ -1404,12 +1546,12 @@ var init_grep = __esm({
1404
1546
  const rgCmd = `rg -n --no-heading --max-count=${max}${globFlag} '${escaped}' ${searchPath}`;
1405
1547
  const grepCmd = `grep -rn --max-count=${max} '${escaped}' ${searchPath} --include='*.ts' --include='*.tsx' --include='*.js' --include='*.json' --include='*.md'`;
1406
1548
  return new Promise((resolve) => {
1407
- exec2(rgCmd, { maxBuffer: 512 * 1024 }, (err, stdout) => {
1549
+ exec5(rgCmd, { maxBuffer: 512 * 1024 }, (err, stdout) => {
1408
1550
  if (stdout?.trim()) {
1409
1551
  resolve(formatResults(stdout, max));
1410
1552
  return;
1411
1553
  }
1412
- exec2(grepCmd, { maxBuffer: 512 * 1024 }, (_err, grepStdout) => {
1554
+ exec5(grepCmd, { maxBuffer: 512 * 1024 }, (_err, grepStdout) => {
1413
1555
  if (grepStdout?.trim()) {
1414
1556
  resolve(formatResults(grepStdout, max));
1415
1557
  } else {
@@ -1669,51 +1811,6 @@ var init_restartProcess = __esm({
1669
1811
  }
1670
1812
  });
1671
1813
 
1672
- // src/tools/code/askMindStudioSdk.ts
1673
- import { exec as exec3 } from "child_process";
1674
- var askMindStudioSdkTool;
1675
- var init_askMindStudioSdk = __esm({
1676
- "src/tools/code/askMindStudioSdk.ts"() {
1677
- "use strict";
1678
- askMindStudioSdkTool = {
1679
- definition: {
1680
- name: "askMindStudioSdk",
1681
- description: "Ask the MindStudio SDK assistant about actions, AI models, connectors, and integrations. Returns code examples with correct method signatures, model IDs, and config options. Use this instead of guessing SDK usage from memory. Describe what you need, not what API methods you need; the assistant will figure out the right approach. This runs its own LLM call so it has a few seconds of latency; batch related questions into a single query.",
1682
- inputSchema: {
1683
- type: "object",
1684
- properties: {
1685
- query: {
1686
- type: "string",
1687
- description: "Natural language question about the SDK."
1688
- }
1689
- },
1690
- required: ["query"]
1691
- }
1692
- },
1693
- async execute(input) {
1694
- const query = input.query;
1695
- return new Promise((resolve) => {
1696
- exec3(
1697
- `mindstudio ask ${JSON.stringify(query)}`,
1698
- { timeout: 6e4, maxBuffer: 512 * 1024 },
1699
- (err, stdout, stderr) => {
1700
- if (stdout.trim()) {
1701
- resolve(stdout.trim());
1702
- return;
1703
- }
1704
- if (err) {
1705
- resolve(`Error: ${stderr.trim() || err.message}`);
1706
- return;
1707
- }
1708
- resolve("(no response)");
1709
- }
1710
- );
1711
- });
1712
- }
1713
- };
1714
- }
1715
- });
1716
-
1717
1814
  // src/tools/code/runScenario.ts
1718
1815
  var runScenarioTool;
1719
1816
  var init_runScenario = __esm({
@@ -2080,7 +2177,6 @@ function getCodeTools() {
2080
2177
  globTool,
2081
2178
  listDirTool,
2082
2179
  editsFinishedTool,
2083
- askMindStudioSdkTool,
2084
2180
  runScenarioTool,
2085
2181
  runMethodTool,
2086
2182
  screenshotTool,
@@ -2095,7 +2191,10 @@ function getCommonTools() {
2095
2191
  return [
2096
2192
  setProjectOnboardingStateTool,
2097
2193
  promptUserTool,
2098
- confirmDestructiveActionTool
2194
+ confirmDestructiveActionTool,
2195
+ askMindStudioSdkTool,
2196
+ fetchUrlTool,
2197
+ searchGoogleTool
2099
2198
  ];
2100
2199
  }
2101
2200
  function getPostOnboardingTools() {
@@ -2147,13 +2246,16 @@ var init_tools2 = __esm({
2147
2246
  init_writeSpec();
2148
2247
  init_editSpec();
2149
2248
  init_listSpecFiles();
2150
- init_setProjectOnboardingState();
2151
- init_promptUser();
2152
2249
  init_clearSyncStatus();
2153
2250
  init_presentSyncPlan();
2154
2251
  init_presentPublishPlan();
2155
2252
  init_presentPlan();
2253
+ init_setProjectOnboardingState();
2254
+ init_promptUser();
2156
2255
  init_confirmDestructiveAction();
2256
+ init_askMindStudioSdk();
2257
+ init_fetchUrl();
2258
+ init_searchGoogle();
2157
2259
  init_readFile();
2158
2260
  init_writeFile();
2159
2261
  init_editFile();
@@ -2165,7 +2267,6 @@ var init_tools2 = __esm({
2165
2267
  init_lsp();
2166
2268
  init_lspDiagnostics();
2167
2269
  init_restartProcess();
2168
- init_askMindStudioSdk();
2169
2270
  init_runScenario();
2170
2271
  init_runMethod();
2171
2272
  init_screenshot();
@@ -2956,17 +3057,24 @@ The current date is ${now}.
2956
3057
  {{compiled/msfm.md}}
2957
3058
  </mindstudio_flavored_markdown_spec_docs>
2958
3059
 
2959
- ${isLspConfigured() ? `<typescript_lsp>
2960
- {{static/lsp.md}}
2961
- </typescript_lsp>` : ""}
2962
-
2963
3060
  <project_context>
2964
3061
  ${projectContext}
2965
3062
  </project_context>
2966
3063
 
3064
+ <intake_mode_instructions>
2967
3065
  {{static/intake.md}}
3066
+ </intake_mode_instructions>
2968
3067
 
3068
+ <spec_authoring_instructions>
2969
3069
  {{static/authoring.md}}
3070
+ </spec_authoring_instructions>
3071
+
3072
+ <code_authoring_instructions>
3073
+ {{static/coding.md}}
3074
+ ${isLspConfigured() ? `<typescript_lsp>
3075
+ {{static/lsp.md}}
3076
+ </typescript_lsp>` : ""}
3077
+ </code_authoring_instructions>
2970
3078
 
2971
3079
  {{static/instructions.md}}
2972
3080
 
@@ -0,0 +1,29 @@
1
+ ## Code Authoring
2
+
3
+ ### Code Style and Formatting
4
+ - Write code that is highly readable and easy to follow.
5
+ - Use inline comments to make code easy to scan and reason about.
6
+ - Write clean, modern, bug-free, and well-organized TypeScript.
7
+ - Match the scope of changes to what was asked. Solve the current problem with the minimum code required. A bug fix is just a bug fix, not an opportunity to refactor the surrounding code. A new feature is just that feature, not a reason to introduce abstractions for hypothetical future needs. Prefer repeating a few lines of straightforward code over creating a helper that's only used once.
8
+
9
+ ### Verification
10
+ After editing code, check your work with `lspDiagnostics` or by reading the file back. After a big build or significant changes, do a lightweight runtime check to catch the things static analysis misses (schema mismatches, missing imports, bad queries):
11
+
12
+ - Seed test data with `runScenario`, then spot-check the primary method or two with `runMethod`. The dev database is a disposable snapshot, so don't worry about being destructive.
13
+ - For frontend work, take a single `screenshot` to confirm the main view renders correctly or look at the browser log for any console errors in the user's preview.
14
+ - Use `runAutomatedBrowserTest` to verify an interactive flow that you can't confirm from a screenshot, or when the user reports something broken that you can't identify from code alone.
15
+
16
+ Aim for confidence that the core happy paths work. If the 80% case is solid, the remaining edge cases are likely fine and the user can surface them in chat. Don't screenshot every page, test every permutation, or verify every secondary flow. One or two runtime checks that confirm the app loads and data flows through is enough.
17
+
18
+ ### Process Logs
19
+ Process logs are available at `.logs/` for debugging:
20
+ - `.logs/tunnel.log`: method execution, schema sync, session lifecycle, platform connection
21
+ - `.logs/devServer.log`: frontend build errors, HMR, module resolution failures
22
+ - `.logs/requests.ndjson`: structured NDJSON log of every method and scenario execution with full input, output, errors (including stack traces), console output, and duration. Use `tail -5 .logs/requests.ndjson | jq .` or `grep '"success":false' .logs/requests.ndjson | jq .` to inspect.
23
+ - `.logs/browser.ndjson`: browser-side events captured from the web preview. Includes console output, uncaught JS errors with stack traces, failed network requests, and user interactions (clicks). Use `grep '"type":"error"' .logs/browser.ndjson | jq .` to find frontend errors.
24
+
25
+ ### MindStudio SDK usage
26
+ - For any work involving AI models (text, image, video, TTS, transcription, etc), external actions like web scraping, searching Google, sending emails or SMS, or third-party API/Oauth connections to social media services, SaaS platforms, and other services, always prefer to use the `@mindstudio-ai/agent` SDK as it removes the need to research API methods, configure keys, tokens, retries, or require the user to create developer accounts/setup billing (they have a unified billing account for all services through MindStudio platform).
27
+ - Always use `askMindStudioSdk` to look up model IDs, action signatures, and config options before writing any code that calls the SDK. Model IDs change frequently across providers and guessing will produce invalid values, even if the ID looks plausible.
28
+ - Always use `askMindStudioSdk` before writing a custom API connector to a third-party service. The tool will tell you if there is already a connector available, as well as whether or not the user has configured it to be ready fo use.
29
+ - Describe what you need in plain language and the assistant will return the correct method call with current parameters. You can including multiple requests in a single tool call.
@@ -1,25 +1,28 @@
1
1
  ## Workflow
2
2
  1. **Understand first.** Read relevant files and check project structure before making changes.
3
3
  2. **Make changes.** Use the right tool for the job — tool descriptions explain when to use each one.
4
- 3. **Verify.** After editing, check your work with lspDiagnostics or by reading the file back. After a big build or significant backend changes, verify at runtime: use `runScenario` to seed test data, then use `runMethod` to confirm things work. The dev database is a disposable snapshot, so don't worry about being destructive. This catches schema mismatches, missing imports, and bad queries that static checks won't find. For frontend work, you can use `screenshot` to visually check the result after significant layout changes. Use `runAutomatedBrowserTest` to smoke-test interactive flows after initial codegen, after major UI changes, or when the user reports something broken that you can't identify from code alone.
5
- 4. **Iterate.** If something fails, read the error, diagnose the root cause, and try a different approach. Process logs are available at `.logs/` for debugging:
6
- - `.logs/tunnel.log`: method execution, schema sync, session lifecycle, platform connection
7
- - `.logs/devServer.log`: frontend build errors, HMR, module resolution failures
8
- - `.logs/requests.ndjson`: structured NDJSON log of every method and scenario execution with full input, output, errors (including stack traces), console output, and duration. Use `tail -5 .logs/requests.ndjson | jq .` or `grep '"success":false' .logs/requests.ndjson | jq .` to inspect.
9
- - `.logs/browser.ndjson`: browser-side events captured from the web preview. Includes console output, uncaught JS errors with stack traces, failed network requests, and user interactions (clicks). Use `grep '"type":"error"' .logs/browser.ndjson | jq .` to find frontend errors.
4
+ 3. **Verify.** Check your work after making changes.
5
+ 4. **Iterate.** If something fails, read the error, diagnose the root cause, and try a different approach.
10
6
 
11
7
  ## Principles
12
- - The spec is the source of truth. When in doubt, consult the spec before making code changes. When behavior changes, update the spec first.
13
- - Change only what the task requires. Match existing code style. Keep solutions simple.
8
+ - The spec in `src/` is the source of truth. When in doubt, consult the spec before making code changes. When behavior changes, update the spec first.
9
+ - Change only what the task requires. Match existing styles. Keep solutions simple.
14
10
  - Read files before editing them. Understand the context before making changes.
15
11
  - When the user asks you to make a change, execute it fully — all steps, no pausing for confirmation. Use `confirmDestructiveAction` to gate before destructive or irreversible actions (e.g., deleting data, resetting the database). For large changes that touch many files or involve significant design decisions, use `presentPlan` to get user approval first — but only when the scope genuinely warrants it or the user asks to see a plan. Most work should be done autonomously.
12
+ - Work with what you already know. If you've read a file in this session, use what you learned rather than reading it again. If a subagent already researched something, use its findings. Every tool call costs time; prefer acting on information you have over re-gathering it.
16
13
  - After two failed attempts at the same approach, tell the user what's going wrong.
17
14
  - Pushing to main branch will trigger a deploy. Use git via bash when the user wants to deploy.
18
15
 
19
16
  ## Communication
20
- - Be direct and concise. The user can already see tool calls, so summarize outcomes, not steps.
21
- - Keep language accessible. Explain things in plain terms unless the user demonstrates technical fluency. Describe what the app *does*, not how it's implemented.
17
+ The user can already see your tool calls, so most of your work is visible without narration. Focus text output on three things:
18
+ - **Decisions that need input.** Questions, tradeoffs, ambiguity that blocks progress.
19
+ - **Milestones.** What you built, what it looks like, what changed. Summarize in plain language rather than listing a per-file changelog.
20
+ - **Errors or blockers.** Something failed or the approach needs to shift.
21
+
22
+ Skip the rest: narrating what you're about to do, restating what the user asked, explaining tool calls they can already see.
23
+
24
+ Style:
25
+ - Keep language accessible. Describe what the app *does*, not how it's implemented, unless the user demonstrates technical fluency.
22
26
  - Always use full paths relative to the project root when mentioning files (`dist/interfaces/web/src/App.tsx`, not `App.tsx`). Paths will be rendered as clickable links for the user.
23
- - When summarizing changes, describe what you did in plain language rather than listing a per-file changelog.
24
27
  - Use inline `code` formatting only for things the user needs to type or search for.
25
- - Do not use emojis. Avoid em dashes in prose; use periods, commas, colons, or parentheses instead.
28
+ - Avoid em dashes in prose; use periods, commas, colons, or parentheses instead. No emojis.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/remy",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "MindStudio coding agent",
5
5
  "repository": {
6
6
  "type": "git",