@mindstudio-ai/remy 0.1.69 → 0.1.71
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/README.md +1 -1
- package/dist/headless.js +103 -27
- package/dist/index.js +106 -28
- package/dist/prompt/compiled/auth.md +207 -32
- package/dist/prompt/compiled/design.md +15 -1
- package/dist/prompt/compiled/interfaces.md +8 -4
- package/dist/prompt/compiled/manifest.md +21 -0
- package/dist/prompt/compiled/methods.md +2 -4
- package/dist/prompt/compiled/platform.md +1 -1
- package/dist/prompt/compiled/tables.md +10 -0
- package/dist/prompt/static/authoring.md +13 -3
- package/dist/prompt/static/coding.md +13 -0
- package/dist/prompt/static/intake.md +51 -28
- package/dist/subagents/browserAutomation/prompt.md +4 -1
- package/dist/subagents/designExpert/prompts/instructions.md +3 -0
- package/dist/subagents/designExpert/prompts/ui-patterns.md +14 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -398,6 +398,7 @@ var init_readSpec = __esm({
|
|
|
398
398
|
init_helpers();
|
|
399
399
|
DEFAULT_MAX_LINES = 500;
|
|
400
400
|
readSpecTool = {
|
|
401
|
+
clearable: true,
|
|
401
402
|
definition: {
|
|
402
403
|
name: "readSpec",
|
|
403
404
|
description: "Read a spec file from src/ with line numbers. Always read a spec file before editing it. Paths are relative to the project root and must start with src/ (e.g., src/app.md, src/interfaces/web.md).",
|
|
@@ -511,6 +512,7 @@ var init_writeSpec = __esm({
|
|
|
511
512
|
init_helpers();
|
|
512
513
|
init_diff();
|
|
513
514
|
writeSpecTool = {
|
|
515
|
+
clearable: true,
|
|
514
516
|
definition: {
|
|
515
517
|
name: "writeSpec",
|
|
516
518
|
description: "Create a new spec file or completely overwrite an existing one in src/. Parent directories are created automatically. Use this for new spec files or full rewrites. For targeted changes to existing specs, use editSpec instead.",
|
|
@@ -572,6 +574,7 @@ var init_editSpec = __esm({
|
|
|
572
574
|
init_helpers();
|
|
573
575
|
init_diff();
|
|
574
576
|
editSpecTool = {
|
|
577
|
+
clearable: true,
|
|
575
578
|
definition: {
|
|
576
579
|
name: "editSpec",
|
|
577
580
|
description: 'Make targeted edits to a spec file by heading path. This is the primary tool for modifying existing specs. Each edit targets a section by its heading hierarchy (e.g., "Vendors > Approval Flow") and applies an operation. Multiple edits are applied in order.',
|
|
@@ -714,6 +717,7 @@ var init_listSpecFiles = __esm({
|
|
|
714
717
|
"src/tools/spec/listSpecFiles.ts"() {
|
|
715
718
|
"use strict";
|
|
716
719
|
listSpecFilesTool = {
|
|
720
|
+
clearable: false,
|
|
717
721
|
definition: {
|
|
718
722
|
name: "listSpecFiles",
|
|
719
723
|
description: "List all files in the src/ directory (spec files, brand guidelines, interface specs, references). Use this to understand what spec files exist before reading or editing them.",
|
|
@@ -747,6 +751,7 @@ var init_clearSyncStatus = __esm({
|
|
|
747
751
|
"src/tools/spec/clearSyncStatus.ts"() {
|
|
748
752
|
"use strict";
|
|
749
753
|
clearSyncStatusTool = {
|
|
754
|
+
clearable: false,
|
|
750
755
|
definition: {
|
|
751
756
|
name: "clearSyncStatus",
|
|
752
757
|
description: "Clear the sync status flags after syncing spec and code. Call this after finishing a sync operation.",
|
|
@@ -768,6 +773,7 @@ var init_presentSyncPlan = __esm({
|
|
|
768
773
|
"src/tools/spec/presentSyncPlan.ts"() {
|
|
769
774
|
"use strict";
|
|
770
775
|
presentSyncPlanTool = {
|
|
776
|
+
clearable: false,
|
|
771
777
|
definition: {
|
|
772
778
|
name: "presentSyncPlan",
|
|
773
779
|
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.",
|
|
@@ -796,6 +802,7 @@ var init_presentPublishPlan = __esm({
|
|
|
796
802
|
"src/tools/spec/presentPublishPlan.ts"() {
|
|
797
803
|
"use strict";
|
|
798
804
|
presentPublishPlanTool = {
|
|
805
|
+
clearable: false,
|
|
799
806
|
definition: {
|
|
800
807
|
name: "presentPublishPlan",
|
|
801
808
|
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.",
|
|
@@ -824,6 +831,7 @@ var init_presentPlan = __esm({
|
|
|
824
831
|
"src/tools/spec/presentPlan.ts"() {
|
|
825
832
|
"use strict";
|
|
826
833
|
presentPlanTool = {
|
|
834
|
+
clearable: false,
|
|
827
835
|
definition: {
|
|
828
836
|
name: "presentPlan",
|
|
829
837
|
description: "Present an implementation plan for user approval before making changes. Use this only for large, multi-step changes like new features, new interface types, 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.",
|
|
@@ -852,19 +860,16 @@ var init_setProjectOnboardingState = __esm({
|
|
|
852
860
|
"src/tools/common/setProjectOnboardingState.ts"() {
|
|
853
861
|
"use strict";
|
|
854
862
|
setProjectOnboardingStateTool = {
|
|
863
|
+
clearable: false,
|
|
855
864
|
definition: {
|
|
856
865
|
name: "setProjectOnboardingState",
|
|
857
|
-
description: "Advance the project onboarding state. Call at natural transition points:
|
|
866
|
+
description: "Advance the project onboarding state. Call at natural transition points: after writing the first draft of the spec (initialSpecReview), before starting the first code generation (initialCodegen), after the first build succeeds (onboardingFinished). Forward-only progression.",
|
|
858
867
|
inputSchema: {
|
|
859
868
|
type: "object",
|
|
860
869
|
properties: {
|
|
861
870
|
state: {
|
|
862
871
|
type: "string",
|
|
863
|
-
enum: [
|
|
864
|
-
"initialSpecAuthoring",
|
|
865
|
-
"initialCodegen",
|
|
866
|
-
"onboardingFinished"
|
|
867
|
-
],
|
|
872
|
+
enum: ["initialSpecReview", "initialCodegen", "onboardingFinished"],
|
|
868
873
|
description: "The onboarding state to advance to."
|
|
869
874
|
}
|
|
870
875
|
},
|
|
@@ -884,6 +889,7 @@ var init_promptUser = __esm({
|
|
|
884
889
|
"src/tools/common/promptUser.ts"() {
|
|
885
890
|
"use strict";
|
|
886
891
|
promptUserTool = {
|
|
892
|
+
clearable: false,
|
|
887
893
|
definition: {
|
|
888
894
|
name: "promptUser",
|
|
889
895
|
description: 'Ask the user structured questions. Choose type first: "form" for structured intake (5+ questions, takes over screen), "inline" for quick clarifications or confirmations. Blocks until the user responds. Result contains `_dismissed: true` if the user dismisses without answering.',
|
|
@@ -1021,6 +1027,7 @@ var init_confirmDestructiveAction = __esm({
|
|
|
1021
1027
|
"src/tools/common/confirmDestructiveAction.ts"() {
|
|
1022
1028
|
"use strict";
|
|
1023
1029
|
confirmDestructiveActionTool = {
|
|
1030
|
+
clearable: false,
|
|
1024
1031
|
definition: {
|
|
1025
1032
|
name: "confirmDestructiveAction",
|
|
1026
1033
|
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.",
|
|
@@ -1144,9 +1151,10 @@ var init_sdkConsultant = __esm({
|
|
|
1144
1151
|
"use strict";
|
|
1145
1152
|
init_runCli();
|
|
1146
1153
|
askMindStudioSdkTool = {
|
|
1154
|
+
clearable: false,
|
|
1147
1155
|
definition: {
|
|
1148
1156
|
name: "askMindStudioSdk",
|
|
1149
|
-
description: "@mindstudio-ai/agent SDK expert. Knows every action, model, connector, and configuration option. Returns architectural guidance and working code. Describe what you want to build, not just what API method you need. Batch related questions into a single query.",
|
|
1157
|
+
description: "@mindstudio-ai/agent backend SDK expert. Knows every backend action, AI model, connector, and configuration option. Returns architectural guidance and working code. Only covers the backend SDK (@mindstudio-ai/agent) \u2014 do NOT use for frontend/interface SDK questions (@mindstudio-ai/interface) like file uploads, auth, or client-side APIs. Describe what you want to build, not just what API method you need. Batch related questions into a single query.",
|
|
1150
1158
|
inputSchema: {
|
|
1151
1159
|
type: "object",
|
|
1152
1160
|
properties: {
|
|
@@ -1177,6 +1185,7 @@ var init_searchGoogle = __esm({
|
|
|
1177
1185
|
"use strict";
|
|
1178
1186
|
init_runCli();
|
|
1179
1187
|
searchGoogleTool = {
|
|
1188
|
+
clearable: false,
|
|
1180
1189
|
definition: {
|
|
1181
1190
|
name: "searchGoogle",
|
|
1182
1191
|
description: "Search Google and return results. Use for research, finding documentation, looking up APIs, or any task where web search would help.",
|
|
@@ -1208,6 +1217,7 @@ var init_setProjectMetadata = __esm({
|
|
|
1208
1217
|
"src/tools/common/setProjectMetadata.ts"() {
|
|
1209
1218
|
"use strict";
|
|
1210
1219
|
setProjectMetadataTool = {
|
|
1220
|
+
clearable: false,
|
|
1211
1221
|
definition: {
|
|
1212
1222
|
name: "setProjectMetadata",
|
|
1213
1223
|
description: "Set project metadata. Can update any combination of: display name, app icon, and Open Graph share image. Provide only the fields you want to change.",
|
|
@@ -1253,6 +1263,7 @@ var init_readFile = __esm({
|
|
|
1253
1263
|
"use strict";
|
|
1254
1264
|
DEFAULT_MAX_LINES2 = 500;
|
|
1255
1265
|
readFileTool = {
|
|
1266
|
+
clearable: true,
|
|
1256
1267
|
definition: {
|
|
1257
1268
|
name: "readFile",
|
|
1258
1269
|
description: "Read a file's contents with line numbers. Always read a file before editing it \u2014 never guess at contents. For large files, consider using symbols first to identify the relevant section, then use offset and maxLines to read just that section. Line numbers in the output correspond to what editFile expects. Defaults to first 500 lines. Use a negative offset to read from the end of the file (e.g., offset: -50 reads the last 50 lines).",
|
|
@@ -1321,6 +1332,7 @@ var init_writeFile = __esm({
|
|
|
1321
1332
|
"use strict";
|
|
1322
1333
|
init_diff();
|
|
1323
1334
|
writeFileTool = {
|
|
1335
|
+
clearable: true,
|
|
1324
1336
|
definition: {
|
|
1325
1337
|
name: "writeFile",
|
|
1326
1338
|
description: "Create a new file or completely overwrite an existing one. Parent directories are created automatically. Use this for new files or full rewrites. For targeted changes to existing files, use editFile instead \u2014 it preserves the parts you don't want to change and avoids errors from forgetting to include unchanged code.",
|
|
@@ -1475,6 +1487,7 @@ var init_editFile = __esm({
|
|
|
1475
1487
|
init_diff();
|
|
1476
1488
|
init_helpers2();
|
|
1477
1489
|
editFileTool = {
|
|
1490
|
+
clearable: true,
|
|
1478
1491
|
definition: {
|
|
1479
1492
|
name: "editFile",
|
|
1480
1493
|
description: "Replace a string in a file. old_string must appear exactly once (minor indentation differences are handled automatically). Set replace_all to true to replace every occurrence at once. For bulk mechanical substitutions (renaming a variable, swapping colors), prefer replace_all. Always read the file first so you know the exact text to match. When editing nested structures (objects, function bodies, arrays, template literals), always include the full enclosing structure in old_string rather than just an inner fragment. Replacing a partial slice from the middle of nested code is the most common source of syntax errors.",
|
|
@@ -1568,6 +1581,7 @@ var init_bash = __esm({
|
|
|
1568
1581
|
DEFAULT_TIMEOUT_MS = 12e4;
|
|
1569
1582
|
DEFAULT_MAX_LINES3 = 500;
|
|
1570
1583
|
bashTool = {
|
|
1584
|
+
clearable: true,
|
|
1571
1585
|
definition: {
|
|
1572
1586
|
name: "bash",
|
|
1573
1587
|
description: "Run a shell command and return stdout + stderr. 120-second timeout by default (configurable). Use for: npm install/build/test, git operations, tsc --noEmit, or any CLI tool. Prefer dedicated tools over bash when available (use grep instead of bash + rg, readFile instead of bash + cat). Output is truncated to 500 lines by default.",
|
|
@@ -1657,6 +1671,7 @@ var init_grep = __esm({
|
|
|
1657
1671
|
"use strict";
|
|
1658
1672
|
DEFAULT_MAX = 50;
|
|
1659
1673
|
grepTool = {
|
|
1674
|
+
clearable: true,
|
|
1660
1675
|
definition: {
|
|
1661
1676
|
name: "grep",
|
|
1662
1677
|
description: "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers (default 50 results). Use this to find where something is used, locate function definitions, or search for patterns across the codebase. For finding a symbol's definition precisely, prefer the definition tool if LSP is available. Automatically excludes node_modules and .git.",
|
|
@@ -1718,6 +1733,7 @@ var init_glob = __esm({
|
|
|
1718
1733
|
"use strict";
|
|
1719
1734
|
DEFAULT_MAX2 = 200;
|
|
1720
1735
|
globTool = {
|
|
1736
|
+
clearable: true,
|
|
1721
1737
|
definition: {
|
|
1722
1738
|
name: "glob",
|
|
1723
1739
|
description: 'Find files matching a glob pattern. Returns matching file paths sorted alphabetically (default 200 results). Use this to discover project structure, find files by name or extension, or check if a file exists. Common patterns: "**/*.ts" (all TypeScript files), "src/**/*.tsx" (React components in src), "*.json" (root-level JSON files). Automatically excludes node_modules and .git.',
|
|
@@ -1770,6 +1786,7 @@ var init_listDir = __esm({
|
|
|
1770
1786
|
"src/tools/code/listDir.ts"() {
|
|
1771
1787
|
"use strict";
|
|
1772
1788
|
listDirTool = {
|
|
1789
|
+
clearable: true,
|
|
1773
1790
|
definition: {
|
|
1774
1791
|
name: "listDir",
|
|
1775
1792
|
description: "List the contents of a directory. Shows entries with / suffix for directories, sorted directories-first then alphabetically. Use this for a quick overview of a directory's contents. For finding files across the whole project, use glob instead.",
|
|
@@ -1811,6 +1828,7 @@ var init_editsFinished = __esm({
|
|
|
1811
1828
|
"src/tools/code/editsFinished.ts"() {
|
|
1812
1829
|
"use strict";
|
|
1813
1830
|
editsFinishedTool = {
|
|
1831
|
+
clearable: false,
|
|
1814
1832
|
definition: {
|
|
1815
1833
|
name: "editsFinished",
|
|
1816
1834
|
description: "Signal that file edits are complete. Call this after you finish writing/editing files so the live preview updates cleanly. The preview is paused while you edit to avoid showing broken intermediate states \u2014 this unpauses it. If you forget to call this, the preview updates when your turn ends.",
|
|
@@ -1891,6 +1909,7 @@ var init_lspDiagnostics = __esm({
|
|
|
1891
1909
|
"use strict";
|
|
1892
1910
|
init_lsp();
|
|
1893
1911
|
lspDiagnosticsTool = {
|
|
1912
|
+
clearable: true,
|
|
1894
1913
|
definition: {
|
|
1895
1914
|
name: "lspDiagnostics",
|
|
1896
1915
|
description: "Get TypeScript diagnostics (type errors, warnings) for a file, with suggested fixes when available. Use this after editing a file to check for errors.",
|
|
@@ -1946,6 +1965,7 @@ var init_restartProcess = __esm({
|
|
|
1946
1965
|
"use strict";
|
|
1947
1966
|
init_lsp();
|
|
1948
1967
|
restartProcessTool = {
|
|
1968
|
+
clearable: false,
|
|
1949
1969
|
definition: {
|
|
1950
1970
|
name: "restartProcess",
|
|
1951
1971
|
description: "Restart a managed sandbox process. Use this after running npm install or changing package.json to restart the dev server so it picks up new dependencies.",
|
|
@@ -1978,6 +1998,7 @@ var init_runScenario = __esm({
|
|
|
1978
1998
|
"src/tools/code/runScenario.ts"() {
|
|
1979
1999
|
"use strict";
|
|
1980
2000
|
runScenarioTool = {
|
|
2001
|
+
clearable: true,
|
|
1981
2002
|
definition: {
|
|
1982
2003
|
name: "runScenario",
|
|
1983
2004
|
description: "Run a scenario to seed the dev database with test data. Truncates all tables first, then executes the seed function and impersonates the scenario roles. Blocks until complete. Scenario IDs are defined in mindstudio.json. If it fails, check .logs/tunnel.log or .logs/requests.ndjson for details. Return synchronously - no need to sleep before checking results.",
|
|
@@ -2005,6 +2026,7 @@ var init_runMethod = __esm({
|
|
|
2005
2026
|
"src/tools/code/runMethod.ts"() {
|
|
2006
2027
|
"use strict";
|
|
2007
2028
|
runMethodTool = {
|
|
2029
|
+
clearable: true,
|
|
2008
2030
|
definition: {
|
|
2009
2031
|
name: "runMethod",
|
|
2010
2032
|
description: "Run a method in the dev environment and return the result. Use for testing methods after writing or modifying them. Returns output, captured console output, errors with stack traces, and duration. If it fails, check .logs/tunnel.log or .logs/requests.ndjson for more details. Return synchronously - no need to sleep before checking results.",
|
|
@@ -2109,6 +2131,7 @@ var init_screenshot2 = __esm({
|
|
|
2109
2131
|
"use strict";
|
|
2110
2132
|
init_screenshot();
|
|
2111
2133
|
screenshotTool = {
|
|
2134
|
+
clearable: true,
|
|
2112
2135
|
definition: {
|
|
2113
2136
|
name: "screenshot",
|
|
2114
2137
|
description: "Capture a full-height screenshot of the app preview and get a description of what's on screen. Provides static image analysis only, will not capture animations or video. Optionally provide specific questions about what you're looking for. Use a bulleted list to ask many questions at once. To ask additional questions about a screenshot you have already captured, pass its URL as imageUrl to skip recapture.",
|
|
@@ -2378,6 +2401,7 @@ async function runSubAgent(config) {
|
|
|
2378
2401
|
const fullSystem = `${system}
|
|
2379
2402
|
|
|
2380
2403
|
Current date: ${dateStr}`;
|
|
2404
|
+
const excludeToolsFromClearing = tools2.filter((t) => t.clearable === false).map((t) => t.name);
|
|
2381
2405
|
let turns = 0;
|
|
2382
2406
|
const run = async () => {
|
|
2383
2407
|
const messages = [
|
|
@@ -2441,6 +2465,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
2441
2465
|
system: fullSystem,
|
|
2442
2466
|
messages: cleanMessagesForApi(messages),
|
|
2443
2467
|
tools: tools2,
|
|
2468
|
+
excludeToolsFromClearing,
|
|
2444
2469
|
signal
|
|
2445
2470
|
},
|
|
2446
2471
|
{
|
|
@@ -2706,6 +2731,7 @@ var init_tools = __esm({
|
|
|
2706
2731
|
"use strict";
|
|
2707
2732
|
BROWSER_TOOLS = [
|
|
2708
2733
|
{
|
|
2734
|
+
clearable: true,
|
|
2709
2735
|
name: "browserCommand",
|
|
2710
2736
|
description: "Interact with the app's live preview by sending browser commands. Commands execute sequentially with an animated cursor. Always start with a snapshot to see the current state and get ref identifiers. The result includes a snapshot field with the final page state after all steps complete. On error, the failing step has an error field and execution stops. Timeout: 120s.",
|
|
2711
2737
|
inputSchema: {
|
|
@@ -2786,6 +2812,7 @@ var init_tools = __esm({
|
|
|
2786
2812
|
}
|
|
2787
2813
|
},
|
|
2788
2814
|
{
|
|
2815
|
+
clearable: true,
|
|
2789
2816
|
name: "screenshotFullPage",
|
|
2790
2817
|
description: "Capture a full-height screenshot of the current page. Returns a CDN URL with full text analysis and description.",
|
|
2791
2818
|
inputSchema: {
|
|
@@ -2799,6 +2826,7 @@ var init_tools = __esm({
|
|
|
2799
2826
|
}
|
|
2800
2827
|
},
|
|
2801
2828
|
{
|
|
2829
|
+
clearable: false,
|
|
2802
2830
|
name: "resetBrowser",
|
|
2803
2831
|
description: "Reset the browser to a clean state. Call this once after all tests are complete to restore the preview for the user. Fire and forget \u2014 does not wait for the reload to finish.",
|
|
2804
2832
|
inputSchema: {
|
|
@@ -2893,6 +2921,7 @@ var init_browserAutomation = __esm({
|
|
|
2893
2921
|
init_logger();
|
|
2894
2922
|
log4 = createLogger("browser-automation");
|
|
2895
2923
|
browserAutomationTool = {
|
|
2924
|
+
clearable: true,
|
|
2896
2925
|
definition: {
|
|
2897
2926
|
name: "runAutomatedBrowserTest",
|
|
2898
2927
|
description: "Run an automated browser test against the live preview. Describe what to test \u2014 the agent figures out how. Use after meaningful changes frontend code, to reproduce user-reported issues, or to test end-to-end flows.",
|
|
@@ -3027,6 +3056,7 @@ var init_searchGoogle2 = __esm({
|
|
|
3027
3056
|
"use strict";
|
|
3028
3057
|
init_runCli();
|
|
3029
3058
|
definition = {
|
|
3059
|
+
clearable: false,
|
|
3030
3060
|
name: "searchGoogle",
|
|
3031
3061
|
description: 'Search Google for web results. Reserch modern design trends in industries or verticals, "best [domain] apps 2026", ui patterns, or find something specific if the the user has an explicit reference. Searching for and reading case studies is a great way to get information and context about a project\'s domain. Prioritize authoritative sources like Figma and other design leaders, avoid random blog spam. Pick one or more URLs from the results and then use `scrapeWebUrl` to get their text content.',
|
|
3032
3062
|
inputSchema: {
|
|
@@ -3065,6 +3095,7 @@ var init_scrapeWebUrl = __esm({
|
|
|
3065
3095
|
"use strict";
|
|
3066
3096
|
init_runCli();
|
|
3067
3097
|
definition2 = {
|
|
3098
|
+
clearable: false,
|
|
3068
3099
|
name: "scrapeWebUrl",
|
|
3069
3100
|
description: "Fetch the content of a web page as markdown. Use when reading sites from search results or specific things the user wants to incorporate.",
|
|
3070
3101
|
inputSchema: {
|
|
@@ -3139,6 +3170,7 @@ Identify the specific design moves that make this page interesting and unique, d
|
|
|
3139
3170
|
Respond only with your analysis as Markdown and absolutely no other text. Do not use emojis - use unicode if you need symbols.
|
|
3140
3171
|
`;
|
|
3141
3172
|
definition3 = {
|
|
3173
|
+
clearable: false,
|
|
3142
3174
|
name: "analyzeDesign",
|
|
3143
3175
|
description: "Analyze the visual design of a website or image URL. Websites are automatically screenshotted first. Provides static image analysis only, will not capture animations or video. If no prompt is provided, performs a full design reference analysis (mood, color, typography, layout, distinctiveness). Provide a custom prompt to ask a specific design question instead. Use a bulleted list to ask many questions at once.",
|
|
3144
3176
|
inputSchema: {
|
|
@@ -3182,6 +3214,7 @@ var init_analyzeImage2 = __esm({
|
|
|
3182
3214
|
init_analyzeImage();
|
|
3183
3215
|
DEFAULT_PROMPT = "Describe everything visible in this image \u2014 every element, its position, its size relative to the frame, its colors, its content. Be comprehensive, thorough and spatial. After the inventory, note anything that looks visually broken (overlapping elements, clipped text, misaligned components). Respond only with your analysis as Markdown and absolutely no other text. Do not use emojis - use unicode if you need symbols.";
|
|
3184
3216
|
definition4 = {
|
|
3217
|
+
clearable: true,
|
|
3185
3218
|
name: "analyzeImage",
|
|
3186
3219
|
description: "Analyze an image by URL using a vision model. Provides static image analysis only, will not capture animations or video. Returns an objective description of what is visible \u2014 shapes, colors, layout, text, artifacts. Use for factual inventory of image contents, not for subjective design judgment - the vision model providing the analysis has no sense of design. You are the design expert - use the analysis tool for factual inventory, then apply your own expertise for quality and suitability assessments. Optionally provide specific questions about what you're looking for. Use a bulleted list to ask many questions at once. If you are analyzing a screenshot of the app preview, you can reuse the same screenshot URL multiple times to ask multiple questions.",
|
|
3187
3220
|
inputSchema: {
|
|
@@ -3249,6 +3282,7 @@ var init_screenshot3 = __esm({
|
|
|
3249
3282
|
init_analyzeImage();
|
|
3250
3283
|
init_browserAutomation();
|
|
3251
3284
|
definition5 = {
|
|
3285
|
+
clearable: true,
|
|
3252
3286
|
name: "screenshot",
|
|
3253
3287
|
description: "Capture a full-height screenshot of the current app preview. Returns a CDN URL along with visual analysis. Use to review the current state of the UI being built. Remember, the screenshot analysis is not overly precise - for example, it cannot reliably identify specific fonts by name \u2014 it can only describe what letterforms look like.",
|
|
3254
3288
|
inputSchema: {
|
|
@@ -3449,6 +3483,7 @@ var init_generateImages = __esm({
|
|
|
3449
3483
|
"use strict";
|
|
3450
3484
|
init_imageGenerator();
|
|
3451
3485
|
definition6 = {
|
|
3486
|
+
clearable: false,
|
|
3452
3487
|
name: "generateImages",
|
|
3453
3488
|
description: "Generate images. Returns CDN URLs with a quality analysis for each image. Produces high-quality results for everything from photorealistic images and abstract/creative visuals. Pass multiple prompts to generate in parallel. No need to analyze images separately after generating \u2014 the analysis is included.",
|
|
3454
3489
|
inputSchema: {
|
|
@@ -3502,6 +3537,7 @@ var init_editImages = __esm({
|
|
|
3502
3537
|
"use strict";
|
|
3503
3538
|
init_imageGenerator();
|
|
3504
3539
|
definition7 = {
|
|
3540
|
+
clearable: false,
|
|
3505
3541
|
name: "editImages",
|
|
3506
3542
|
description: "Edit or transform existing images. Provide one or more source image URLs as reference and a prompt describing the desired edit. Use for compositing, style transfer, subject transformation, blending multiple references, or incorporating one or more references into something new. Returns CDN URLs with analysis.",
|
|
3507
3543
|
inputSchema: {
|
|
@@ -3623,15 +3659,19 @@ function loadPlatformBrief() {
|
|
|
3623
3659
|
return `<platform_brief>
|
|
3624
3660
|
## What is a MindStudio app?
|
|
3625
3661
|
|
|
3626
|
-
A MindStudio app is a managed TypeScript project with three layers: a spec (natural language in src/), a backend contract (methods, tables, roles in dist/), and one or more interfaces (web, API, bots, cron, etc.). The spec is the source of truth; code is derived from it.
|
|
3662
|
+
A MindStudio app is a managed full-stack TypeScript project with three layers: a spec (natural language in src/), a backend contract (methods, tables, roles in dist/), and one or more interfaces (web, API, bots, cron, etc.). The spec is the source of truth; code is derived from it.
|
|
3663
|
+
|
|
3664
|
+
This is a capable, stable platform used in production by 100k+ users. Build with confidence \u2014 you're building production-grade apps, not fragile prototypes.
|
|
3627
3665
|
|
|
3628
3666
|
## What people build
|
|
3629
3667
|
|
|
3630
|
-
- Business tools \u2014
|
|
3631
|
-
- AI-powered apps \u2014
|
|
3668
|
+
- Business tools \u2014 client portals, approval workflows, admin panels with role-based access
|
|
3669
|
+
- AI-powered apps \u2014 document processors, image/video tools, content generators, conversational agents that take actions
|
|
3670
|
+
- Full-stack web apps \u2014 social platforms, membership sites, marketplaces, booking systems, community hubs \u2014 multi-user apps with auth, data, UI
|
|
3632
3671
|
- Automations with no UI \u2014 cron jobs, webhook handlers, email processors, data sync pipelines
|
|
3672
|
+
- Marketing & launch pages \u2014 landing pages, waitlist pages with referral mechanics, product sites with scroll animations
|
|
3633
3673
|
- Bots \u2014 Discord slash-command bots, Telegram bots, MCP tool servers for AI assistants
|
|
3634
|
-
- Creative/interactive projects \u2014 games, interactive visualizations, generative art, portfolio sites
|
|
3674
|
+
- Creative/interactive projects \u2014 browser games with p5.js or Three.js, interactive visualizations, generative art, portfolio sites
|
|
3635
3675
|
- API services \u2014 backend logic exposed as REST endpoints
|
|
3636
3676
|
- Simple static sites \u2014 no backend needed, just a web interface with a build step
|
|
3637
3677
|
|
|
@@ -3656,13 +3696,12 @@ Each interface type invokes the same backend methods. Methods don't know which i
|
|
|
3656
3696
|
TypeScript running in a sandboxed environment. Any npm package can be installed. Key capabilities:
|
|
3657
3697
|
|
|
3658
3698
|
- Managed SQLite database with typed schemas and automatic migrations. Define a TypeScript interface, push, and the platform handles diffing and migrating.
|
|
3659
|
-
- Built-in
|
|
3660
|
-
- Sandboxed execution with npm packages pre-installed.
|
|
3699
|
+
- Built-in app-managed auth. Opt-in via manifest \u2014 developer builds login UI, platform handles verification codes (email/SMS), cookie sessions, and role enforcement. Backend methods use auth.requireRole() for access control.
|
|
3661
3700
|
- Git-native deployment. Push to default branch to deploy.
|
|
3662
3701
|
|
|
3663
3702
|
## MindStudio SDK
|
|
3664
3703
|
|
|
3665
|
-
The first-party SDK (@mindstudio-ai/agent) provides access to 200+ AI models (OpenAI, Anthropic, Google, Meta, Mistral, and more) and 1000+ integrations (email, SMS, Slack, HubSpot, Google Workspace, web scraping, image/video generation, media processing, and much more) with zero configuration \u2014 credentials are handled automatically in the execution environment. No API keys needed.
|
|
3704
|
+
The first-party SDK (@mindstudio-ai/agent) provides access to 200+ AI models (OpenAI, Anthropic, Google, Meta, Mistral, and more) and 1000+ integrations (email, SMS, Slack, HubSpot, Google Workspace, web scraping, image/video generation, media processing, and much more) with zero configuration \u2014 credentials are handled automatically in the execution environment. No API keys needed. This SDK is robust and battle-tested in production.
|
|
3666
3705
|
|
|
3667
3706
|
## What MindStudio apps are NOT good for
|
|
3668
3707
|
|
|
@@ -3910,6 +3949,7 @@ var init_designExpert = __esm({
|
|
|
3910
3949
|
Visual design expert. Describe the situation and what you need \u2014 the agent decides what to deliver. It reads the spec files automatically. Include relevant user requirements and context it can't get from the spec, but do not list specific deliverables or tell it how to do its job. Do not suggest implementation details or ideas - only relay what is needed.
|
|
3911
3950
|
`.trim();
|
|
3912
3951
|
designExpertTool = {
|
|
3952
|
+
clearable: false,
|
|
3913
3953
|
definition: {
|
|
3914
3954
|
name: "visualDesignExpert",
|
|
3915
3955
|
description: DESCRIPTION,
|
|
@@ -4244,6 +4284,7 @@ var init_productVision = __esm({
|
|
|
4244
4284
|
init_prompt3();
|
|
4245
4285
|
init_history();
|
|
4246
4286
|
productVisionTool = {
|
|
4287
|
+
clearable: false,
|
|
4247
4288
|
definition: {
|
|
4248
4289
|
name: "productVision",
|
|
4249
4290
|
description: "Owns the product roadmap. Reads spec and roadmap files automatically. Creates, updates, and deletes roadmap items in src/roadmap/. Describe the situation and what needs to happen.",
|
|
@@ -4409,6 +4450,7 @@ var init_codeSanityCheck = __esm({
|
|
|
4409
4450
|
init_tools4();
|
|
4410
4451
|
BASE_PROMPT3 = readAsset("subagents/codeSanityCheck", "prompt.md");
|
|
4411
4452
|
codeSanityCheckTool = {
|
|
4453
|
+
clearable: false,
|
|
4412
4454
|
definition: {
|
|
4413
4455
|
name: "codeSanityCheck",
|
|
4414
4456
|
description: 'Quick sanity check on an approach before building. Reviews architecture, package choices, and flags potential issues. Usually responds with "looks good." Occasionally catches something important. Readonly \u2014 can search the web and read code but cannot modify anything.',
|
|
@@ -4464,6 +4506,7 @@ var init_scrapeWebUrl2 = __esm({
|
|
|
4464
4506
|
"use strict";
|
|
4465
4507
|
init_runCli();
|
|
4466
4508
|
scrapeWebUrlTool = {
|
|
4509
|
+
clearable: false,
|
|
4467
4510
|
definition: {
|
|
4468
4511
|
name: "scrapeWebUrl",
|
|
4469
4512
|
description: "Scrape the content of a web page. Returns the HTML of the page as markdown text. Optionally capture a screenshot if you need see the visual design. Use this when you need to fetch or analyze content from a website",
|
|
@@ -4512,7 +4555,7 @@ function executeTool(name, input, context) {
|
|
|
4512
4555
|
}
|
|
4513
4556
|
return tool.execute(input, context);
|
|
4514
4557
|
}
|
|
4515
|
-
var ALL_TOOLS;
|
|
4558
|
+
var ALL_TOOLS, CLEARABLE_TOOLS;
|
|
4516
4559
|
var init_tools5 = __esm({
|
|
4517
4560
|
"src/tools/index.ts"() {
|
|
4518
4561
|
"use strict";
|
|
@@ -4587,6 +4630,9 @@ var init_tools5 = __esm({
|
|
|
4587
4630
|
lspDiagnosticsTool,
|
|
4588
4631
|
restartProcessTool
|
|
4589
4632
|
];
|
|
4633
|
+
CLEARABLE_TOOLS = new Set(
|
|
4634
|
+
ALL_TOOLS.filter((t) => t.clearable).map((t) => t.definition.name)
|
|
4635
|
+
);
|
|
4590
4636
|
}
|
|
4591
4637
|
});
|
|
4592
4638
|
|
|
@@ -4901,6 +4947,7 @@ async function runTurn(params) {
|
|
|
4901
4947
|
onBackgroundComplete
|
|
4902
4948
|
} = params;
|
|
4903
4949
|
const tools2 = getToolDefinitions(onboardingState);
|
|
4950
|
+
const excludeToolsFromClearing = tools2.filter((t) => !CLEARABLE_TOOLS.has(t.name)).map((t) => t.name);
|
|
4904
4951
|
log6.info("Turn started", {
|
|
4905
4952
|
requestId,
|
|
4906
4953
|
model,
|
|
@@ -4910,11 +4957,17 @@ async function runTurn(params) {
|
|
|
4910
4957
|
}
|
|
4911
4958
|
});
|
|
4912
4959
|
onEvent({ type: "turn_started" });
|
|
4960
|
+
const hasText = userMessage.trim().length > 0;
|
|
4961
|
+
const hasAttachments = attachments && attachments.length > 0;
|
|
4962
|
+
if (!hasText && !hasAttachments) {
|
|
4963
|
+
onEvent({ type: "error", error: "Empty message" });
|
|
4964
|
+
return;
|
|
4965
|
+
}
|
|
4913
4966
|
const userMsg = { role: "user", content: userMessage };
|
|
4914
4967
|
if (hidden) {
|
|
4915
4968
|
userMsg.hidden = true;
|
|
4916
4969
|
}
|
|
4917
|
-
if (
|
|
4970
|
+
if (hasAttachments) {
|
|
4918
4971
|
userMsg.attachments = attachments;
|
|
4919
4972
|
}
|
|
4920
4973
|
state.messages.push(userMsg);
|
|
@@ -5040,6 +5093,7 @@ async function runTurn(params) {
|
|
|
5040
5093
|
system,
|
|
5041
5094
|
messages: cleanMessagesForApi(state.messages),
|
|
5042
5095
|
tools: tools2,
|
|
5096
|
+
excludeToolsFromClearing,
|
|
5043
5097
|
signal
|
|
5044
5098
|
},
|
|
5045
5099
|
{
|
|
@@ -5358,6 +5412,7 @@ var init_agent = __esm({
|
|
|
5358
5412
|
init_statusWatcher();
|
|
5359
5413
|
init_errors();
|
|
5360
5414
|
init_cleanMessages();
|
|
5415
|
+
init_tools5();
|
|
5361
5416
|
log6 = createLogger("agent");
|
|
5362
5417
|
EXTERNAL_TOOLS = /* @__PURE__ */ new Set([
|
|
5363
5418
|
"promptUser",
|
|
@@ -5698,7 +5753,7 @@ var init_config = __esm({
|
|
|
5698
5753
|
});
|
|
5699
5754
|
|
|
5700
5755
|
// src/compaction/index.ts
|
|
5701
|
-
async function compactConversation(state, apiConfig) {
|
|
5756
|
+
async function compactConversation(state, apiConfig, system, tools2) {
|
|
5702
5757
|
const insertionIndex = findSafeInsertionPoint(state.messages);
|
|
5703
5758
|
const summaries = [];
|
|
5704
5759
|
const tasks = [];
|
|
@@ -5712,7 +5767,9 @@ async function compactConversation(state, apiConfig) {
|
|
|
5712
5767
|
apiConfig,
|
|
5713
5768
|
"conversation",
|
|
5714
5769
|
CONVERSATION_SUMMARY_PROMPT,
|
|
5715
|
-
conversationMessages
|
|
5770
|
+
conversationMessages,
|
|
5771
|
+
system,
|
|
5772
|
+
tools2
|
|
5716
5773
|
).then((text) => {
|
|
5717
5774
|
if (text) {
|
|
5718
5775
|
summaries.push({ name: "conversation", text });
|
|
@@ -5732,7 +5789,9 @@ async function compactConversation(state, apiConfig) {
|
|
|
5732
5789
|
apiConfig,
|
|
5733
5790
|
name,
|
|
5734
5791
|
SUBAGENT_SUMMARY_PROMPT,
|
|
5735
|
-
subagentMessages
|
|
5792
|
+
subagentMessages,
|
|
5793
|
+
system,
|
|
5794
|
+
tools2
|
|
5736
5795
|
).then((text) => {
|
|
5737
5796
|
if (text) {
|
|
5738
5797
|
summaries.push({ name, text });
|
|
@@ -5859,22 +5918,33 @@ function serializeForSummary(messages) {
|
|
|
5859
5918
|
return `[${msg.role}]: ${parts.join("\n")}`;
|
|
5860
5919
|
}).join("\n\n");
|
|
5861
5920
|
}
|
|
5862
|
-
async function generateSummary(apiConfig, name,
|
|
5921
|
+
async function generateSummary(apiConfig, name, compactionPrompt, messagesToSummarize, mainSystem, mainTools) {
|
|
5863
5922
|
const serialized = serializeForSummary(messagesToSummarize);
|
|
5864
5923
|
if (!serialized.trim()) {
|
|
5865
5924
|
return null;
|
|
5866
5925
|
}
|
|
5867
5926
|
log8.info("Generating summary", {
|
|
5868
5927
|
name,
|
|
5869
|
-
messageCount: messagesToSummarize.length
|
|
5928
|
+
messageCount: messagesToSummarize.length,
|
|
5929
|
+
cacheReuse: !!mainSystem
|
|
5870
5930
|
});
|
|
5871
5931
|
let summaryText = "";
|
|
5932
|
+
const useMainCache = !!mainSystem;
|
|
5933
|
+
const system = useMainCache ? mainSystem : compactionPrompt;
|
|
5934
|
+
const tools2 = useMainCache ? mainTools ?? [] : [];
|
|
5935
|
+
const userContent = useMainCache ? `${compactionPrompt}
|
|
5936
|
+
|
|
5937
|
+
---
|
|
5938
|
+
|
|
5939
|
+
Conversation to summarize:
|
|
5940
|
+
|
|
5941
|
+
${serialized}` : serialized;
|
|
5872
5942
|
for await (const event of streamChat({
|
|
5873
5943
|
...apiConfig,
|
|
5874
5944
|
subAgentId: "conversationSummarizer",
|
|
5875
|
-
system
|
|
5876
|
-
messages: [{ role: "user", content:
|
|
5877
|
-
tools:
|
|
5945
|
+
system,
|
|
5946
|
+
messages: [{ role: "user", content: userContent }],
|
|
5947
|
+
tools: tools2
|
|
5878
5948
|
})) {
|
|
5879
5949
|
if (event.type === "text") {
|
|
5880
5950
|
summaryText += event.text;
|
|
@@ -6088,6 +6158,7 @@ async function startHeadless(opts = {}) {
|
|
|
6088
6158
|
let currentAbort = null;
|
|
6089
6159
|
let currentRequestId;
|
|
6090
6160
|
let completedEmitted = false;
|
|
6161
|
+
let turnStart = 0;
|
|
6091
6162
|
const EXTERNAL_TOOL_TIMEOUT_MS = 3e5;
|
|
6092
6163
|
const pendingTools = /* @__PURE__ */ new Map();
|
|
6093
6164
|
const earlyResults = /* @__PURE__ */ new Map();
|
|
@@ -6200,8 +6271,8 @@ ${xmlParts}
|
|
|
6200
6271
|
function onEvent(e) {
|
|
6201
6272
|
const rid = currentRequestId;
|
|
6202
6273
|
switch (e.type) {
|
|
6203
|
-
// Suppressed — caller already knows the request started
|
|
6204
6274
|
case "turn_started":
|
|
6275
|
+
emit("turn_started", {}, rid);
|
|
6205
6276
|
return;
|
|
6206
6277
|
// Terminal events — translate to `completed`
|
|
6207
6278
|
case "turn_done":
|
|
@@ -6220,7 +6291,11 @@ ${xmlParts}
|
|
|
6220
6291
|
writeFileSync(".remy-stats.json", JSON.stringify(sessionStats));
|
|
6221
6292
|
} catch {
|
|
6222
6293
|
}
|
|
6223
|
-
emit(
|
|
6294
|
+
emit(
|
|
6295
|
+
"completed",
|
|
6296
|
+
{ success: true, durationMs: Date.now() - turnStart },
|
|
6297
|
+
rid
|
|
6298
|
+
);
|
|
6224
6299
|
setTimeout(() => {
|
|
6225
6300
|
applyPendingBlockUpdates();
|
|
6226
6301
|
flushBackgroundQueue();
|
|
@@ -6360,7 +6435,7 @@ ${xmlParts}
|
|
|
6360
6435
|
currentRequestId = requestId;
|
|
6361
6436
|
currentAbort = new AbortController();
|
|
6362
6437
|
completedEmitted = false;
|
|
6363
|
-
|
|
6438
|
+
turnStart = Date.now();
|
|
6364
6439
|
const attachments = parsed.attachments;
|
|
6365
6440
|
if (attachments?.length) {
|
|
6366
6441
|
console.warn(
|
|
@@ -6505,7 +6580,9 @@ ${xmlParts}
|
|
|
6505
6580
|
writeFileSync(".remy-stats.json", JSON.stringify(sessionStats));
|
|
6506
6581
|
} catch {
|
|
6507
6582
|
}
|
|
6508
|
-
|
|
6583
|
+
const compactSystem = buildSystemPrompt("onboardingFinished");
|
|
6584
|
+
const compactTools = getToolDefinitions("onboardingFinished");
|
|
6585
|
+
compactConversation(state, config, compactSystem, compactTools).then(() => {
|
|
6509
6586
|
saveSession(state);
|
|
6510
6587
|
emit("compaction_complete", {}, requestId);
|
|
6511
6588
|
emit("completed", { success: true }, requestId);
|
|
@@ -6564,6 +6641,7 @@ var init_headless = __esm({
|
|
|
6564
6641
|
init_config();
|
|
6565
6642
|
init_prompt4();
|
|
6566
6643
|
init_compaction();
|
|
6644
|
+
init_tools5();
|
|
6567
6645
|
init_lsp();
|
|
6568
6646
|
init_agent();
|
|
6569
6647
|
init_session();
|