@mindstudio-ai/remy 0.1.69 → 0.1.70
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 +94 -21
- package/dist/index.js +97 -22
- package/dist/prompt/compiled/auth.md +207 -32
- 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 +2 -1
- package/dist/subagents/browserAutomation/prompt.md +4 -1
- package/dist/subagents/designExpert/prompts/ui-patterns.md +14 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ Tool availability depends on the project's onboarding state, sent by the sandbox
|
|
|
49
49
|
|
|
50
50
|
| Tool | Description |
|
|
51
51
|
|------|-------------|
|
|
52
|
-
| `setProjectOnboardingState` | Advance the onboarding flow (intake →
|
|
52
|
+
| `setProjectOnboardingState` | Advance the onboarding flow (intake → initialSpecReview → initialCodegen → onboardingFinished) |
|
|
53
53
|
| `setProjectName` | Set the project name |
|
|
54
54
|
| `promptUser` | Ask the user structured questions (form or inline display) |
|
|
55
55
|
| `confirmDestructiveAction` | Confirm a destructive or irreversible action with the user |
|
package/dist/headless.js
CHANGED
|
@@ -650,7 +650,7 @@ var log4 = createLogger("compaction");
|
|
|
650
650
|
var CONVERSATION_SUMMARY_PROMPT = readAsset("compaction", "conversation.md");
|
|
651
651
|
var SUBAGENT_SUMMARY_PROMPT = readAsset("compaction", "subagent.md");
|
|
652
652
|
var SUMMARIZABLE_SUBAGENTS = ["visualDesignExpert", "productVision"];
|
|
653
|
-
async function compactConversation(state, apiConfig) {
|
|
653
|
+
async function compactConversation(state, apiConfig, system, tools2) {
|
|
654
654
|
const insertionIndex = findSafeInsertionPoint(state.messages);
|
|
655
655
|
const summaries = [];
|
|
656
656
|
const tasks = [];
|
|
@@ -664,7 +664,9 @@ async function compactConversation(state, apiConfig) {
|
|
|
664
664
|
apiConfig,
|
|
665
665
|
"conversation",
|
|
666
666
|
CONVERSATION_SUMMARY_PROMPT,
|
|
667
|
-
conversationMessages
|
|
667
|
+
conversationMessages,
|
|
668
|
+
system,
|
|
669
|
+
tools2
|
|
668
670
|
).then((text) => {
|
|
669
671
|
if (text) {
|
|
670
672
|
summaries.push({ name: "conversation", text });
|
|
@@ -684,7 +686,9 @@ async function compactConversation(state, apiConfig) {
|
|
|
684
686
|
apiConfig,
|
|
685
687
|
name,
|
|
686
688
|
SUBAGENT_SUMMARY_PROMPT,
|
|
687
|
-
subagentMessages
|
|
689
|
+
subagentMessages,
|
|
690
|
+
system,
|
|
691
|
+
tools2
|
|
688
692
|
).then((text) => {
|
|
689
693
|
if (text) {
|
|
690
694
|
summaries.push({ name, text });
|
|
@@ -811,22 +815,33 @@ function serializeForSummary(messages) {
|
|
|
811
815
|
return `[${msg.role}]: ${parts.join("\n")}`;
|
|
812
816
|
}).join("\n\n");
|
|
813
817
|
}
|
|
814
|
-
async function generateSummary(apiConfig, name,
|
|
818
|
+
async function generateSummary(apiConfig, name, compactionPrompt, messagesToSummarize, mainSystem, mainTools) {
|
|
815
819
|
const serialized = serializeForSummary(messagesToSummarize);
|
|
816
820
|
if (!serialized.trim()) {
|
|
817
821
|
return null;
|
|
818
822
|
}
|
|
819
823
|
log4.info("Generating summary", {
|
|
820
824
|
name,
|
|
821
|
-
messageCount: messagesToSummarize.length
|
|
825
|
+
messageCount: messagesToSummarize.length,
|
|
826
|
+
cacheReuse: !!mainSystem
|
|
822
827
|
});
|
|
823
828
|
let summaryText = "";
|
|
829
|
+
const useMainCache = !!mainSystem;
|
|
830
|
+
const system = useMainCache ? mainSystem : compactionPrompt;
|
|
831
|
+
const tools2 = useMainCache ? mainTools ?? [] : [];
|
|
832
|
+
const userContent = useMainCache ? `${compactionPrompt}
|
|
833
|
+
|
|
834
|
+
---
|
|
835
|
+
|
|
836
|
+
Conversation to summarize:
|
|
837
|
+
|
|
838
|
+
${serialized}` : serialized;
|
|
824
839
|
for await (const event of streamChat({
|
|
825
840
|
...apiConfig,
|
|
826
841
|
subAgentId: "conversationSummarizer",
|
|
827
|
-
system
|
|
828
|
-
messages: [{ role: "user", content:
|
|
829
|
-
tools:
|
|
842
|
+
system,
|
|
843
|
+
messages: [{ role: "user", content: userContent }],
|
|
844
|
+
tools: tools2
|
|
830
845
|
})) {
|
|
831
846
|
if (event.type === "text") {
|
|
832
847
|
summaryText += event.text;
|
|
@@ -934,6 +949,7 @@ function getHeadingTree(content) {
|
|
|
934
949
|
// src/tools/spec/readSpec.ts
|
|
935
950
|
var DEFAULT_MAX_LINES = 500;
|
|
936
951
|
var readSpecTool = {
|
|
952
|
+
clearable: true,
|
|
937
953
|
definition: {
|
|
938
954
|
name: "readSpec",
|
|
939
955
|
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).",
|
|
@@ -1035,6 +1051,7 @@ function unifiedDiff(filePath, oldText, newText) {
|
|
|
1035
1051
|
|
|
1036
1052
|
// src/tools/spec/writeSpec.ts
|
|
1037
1053
|
var writeSpecTool = {
|
|
1054
|
+
clearable: true,
|
|
1038
1055
|
definition: {
|
|
1039
1056
|
name: "writeSpec",
|
|
1040
1057
|
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.",
|
|
@@ -1088,6 +1105,7 @@ ${unifiedDiff(input.path, oldContent ?? "", input.content)}`;
|
|
|
1088
1105
|
// src/tools/spec/editSpec.ts
|
|
1089
1106
|
import fs7 from "fs/promises";
|
|
1090
1107
|
var editSpecTool = {
|
|
1108
|
+
clearable: true,
|
|
1091
1109
|
definition: {
|
|
1092
1110
|
name: "editSpec",
|
|
1093
1111
|
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.',
|
|
@@ -1201,6 +1219,7 @@ ${tree}`;
|
|
|
1201
1219
|
import fs8 from "fs/promises";
|
|
1202
1220
|
import path5 from "path";
|
|
1203
1221
|
var listSpecFilesTool = {
|
|
1222
|
+
clearable: false,
|
|
1204
1223
|
definition: {
|
|
1205
1224
|
name: "listSpecFiles",
|
|
1206
1225
|
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.",
|
|
@@ -1251,6 +1270,7 @@ async function listRecursive(dir) {
|
|
|
1251
1270
|
|
|
1252
1271
|
// src/tools/spec/clearSyncStatus.ts
|
|
1253
1272
|
var clearSyncStatusTool = {
|
|
1273
|
+
clearable: false,
|
|
1254
1274
|
definition: {
|
|
1255
1275
|
name: "clearSyncStatus",
|
|
1256
1276
|
description: "Clear the sync status flags after syncing spec and code. Call this after finishing a sync operation.",
|
|
@@ -1266,6 +1286,7 @@ var clearSyncStatusTool = {
|
|
|
1266
1286
|
|
|
1267
1287
|
// src/tools/spec/presentSyncPlan.ts
|
|
1268
1288
|
var presentSyncPlanTool = {
|
|
1289
|
+
clearable: false,
|
|
1269
1290
|
definition: {
|
|
1270
1291
|
name: "presentSyncPlan",
|
|
1271
1292
|
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.",
|
|
@@ -1288,6 +1309,7 @@ var presentSyncPlanTool = {
|
|
|
1288
1309
|
|
|
1289
1310
|
// src/tools/spec/presentPublishPlan.ts
|
|
1290
1311
|
var presentPublishPlanTool = {
|
|
1312
|
+
clearable: false,
|
|
1291
1313
|
definition: {
|
|
1292
1314
|
name: "presentPublishPlan",
|
|
1293
1315
|
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.",
|
|
@@ -1310,6 +1332,7 @@ var presentPublishPlanTool = {
|
|
|
1310
1332
|
|
|
1311
1333
|
// src/tools/spec/presentPlan.ts
|
|
1312
1334
|
var presentPlanTool = {
|
|
1335
|
+
clearable: false,
|
|
1313
1336
|
definition: {
|
|
1314
1337
|
name: "presentPlan",
|
|
1315
1338
|
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.",
|
|
@@ -1332,19 +1355,16 @@ var presentPlanTool = {
|
|
|
1332
1355
|
|
|
1333
1356
|
// src/tools/common/setProjectOnboardingState.ts
|
|
1334
1357
|
var setProjectOnboardingStateTool = {
|
|
1358
|
+
clearable: false,
|
|
1335
1359
|
definition: {
|
|
1336
1360
|
name: "setProjectOnboardingState",
|
|
1337
|
-
description: "Advance the project onboarding state. Call at natural transition points:
|
|
1361
|
+
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.",
|
|
1338
1362
|
inputSchema: {
|
|
1339
1363
|
type: "object",
|
|
1340
1364
|
properties: {
|
|
1341
1365
|
state: {
|
|
1342
1366
|
type: "string",
|
|
1343
|
-
enum: [
|
|
1344
|
-
"initialSpecAuthoring",
|
|
1345
|
-
"initialCodegen",
|
|
1346
|
-
"onboardingFinished"
|
|
1347
|
-
],
|
|
1367
|
+
enum: ["initialSpecReview", "initialCodegen", "onboardingFinished"],
|
|
1348
1368
|
description: "The onboarding state to advance to."
|
|
1349
1369
|
}
|
|
1350
1370
|
},
|
|
@@ -1358,6 +1378,7 @@ var setProjectOnboardingStateTool = {
|
|
|
1358
1378
|
|
|
1359
1379
|
// src/tools/common/promptUser.ts
|
|
1360
1380
|
var promptUserTool = {
|
|
1381
|
+
clearable: false,
|
|
1361
1382
|
definition: {
|
|
1362
1383
|
name: "promptUser",
|
|
1363
1384
|
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.',
|
|
@@ -1489,6 +1510,7 @@ ${lines.join("\n")}`;
|
|
|
1489
1510
|
|
|
1490
1511
|
// src/tools/common/confirmDestructiveAction.ts
|
|
1491
1512
|
var confirmDestructiveActionTool = {
|
|
1513
|
+
clearable: false,
|
|
1492
1514
|
definition: {
|
|
1493
1515
|
name: "confirmDestructiveAction",
|
|
1494
1516
|
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.",
|
|
@@ -1600,9 +1622,10 @@ function runCli(cmd, options) {
|
|
|
1600
1622
|
|
|
1601
1623
|
// src/subagents/sdkConsultant/index.ts
|
|
1602
1624
|
var askMindStudioSdkTool = {
|
|
1625
|
+
clearable: false,
|
|
1603
1626
|
definition: {
|
|
1604
1627
|
name: "askMindStudioSdk",
|
|
1605
|
-
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.",
|
|
1628
|
+
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.",
|
|
1606
1629
|
inputSchema: {
|
|
1607
1630
|
type: "object",
|
|
1608
1631
|
properties: {
|
|
@@ -1626,6 +1649,7 @@ var askMindStudioSdkTool = {
|
|
|
1626
1649
|
|
|
1627
1650
|
// src/tools/common/searchGoogle.ts
|
|
1628
1651
|
var searchGoogleTool = {
|
|
1652
|
+
clearable: false,
|
|
1629
1653
|
definition: {
|
|
1630
1654
|
name: "searchGoogle",
|
|
1631
1655
|
description: "Search Google and return results. Use for research, finding documentation, looking up APIs, or any task where web search would help.",
|
|
@@ -1651,6 +1675,7 @@ var searchGoogleTool = {
|
|
|
1651
1675
|
|
|
1652
1676
|
// src/tools/common/setProjectMetadata.ts
|
|
1653
1677
|
var setProjectMetadataTool = {
|
|
1678
|
+
clearable: false,
|
|
1654
1679
|
definition: {
|
|
1655
1680
|
name: "setProjectMetadata",
|
|
1656
1681
|
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.",
|
|
@@ -1690,6 +1715,7 @@ function isBinary(buffer) {
|
|
|
1690
1715
|
return false;
|
|
1691
1716
|
}
|
|
1692
1717
|
var readFileTool = {
|
|
1718
|
+
clearable: true,
|
|
1693
1719
|
definition: {
|
|
1694
1720
|
name: "readFile",
|
|
1695
1721
|
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).",
|
|
@@ -1751,6 +1777,7 @@ var readFileTool = {
|
|
|
1751
1777
|
import fs10 from "fs/promises";
|
|
1752
1778
|
import path6 from "path";
|
|
1753
1779
|
var writeFileTool = {
|
|
1780
|
+
clearable: true,
|
|
1754
1781
|
definition: {
|
|
1755
1782
|
name: "writeFile",
|
|
1756
1783
|
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.",
|
|
@@ -1894,6 +1921,7 @@ function formatOccurrenceError(count, lines, filePath) {
|
|
|
1894
1921
|
|
|
1895
1922
|
// src/tools/code/editFile/index.ts
|
|
1896
1923
|
var editFileTool = {
|
|
1924
|
+
clearable: true,
|
|
1897
1925
|
definition: {
|
|
1898
1926
|
name: "editFile",
|
|
1899
1927
|
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.",
|
|
@@ -1981,6 +2009,7 @@ import { exec } from "child_process";
|
|
|
1981
2009
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
1982
2010
|
var DEFAULT_MAX_LINES3 = 500;
|
|
1983
2011
|
var bashTool = {
|
|
2012
|
+
clearable: true,
|
|
1984
2013
|
definition: {
|
|
1985
2014
|
name: "bash",
|
|
1986
2015
|
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.",
|
|
@@ -2064,6 +2093,7 @@ function formatResults(stdout, max) {
|
|
|
2064
2093
|
return result;
|
|
2065
2094
|
}
|
|
2066
2095
|
var grepTool = {
|
|
2096
|
+
clearable: true,
|
|
2067
2097
|
definition: {
|
|
2068
2098
|
name: "grep",
|
|
2069
2099
|
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.",
|
|
@@ -2119,6 +2149,7 @@ var grepTool = {
|
|
|
2119
2149
|
import fg from "fast-glob";
|
|
2120
2150
|
var DEFAULT_MAX2 = 200;
|
|
2121
2151
|
var globTool = {
|
|
2152
|
+
clearable: true,
|
|
2122
2153
|
definition: {
|
|
2123
2154
|
name: "glob",
|
|
2124
2155
|
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.',
|
|
@@ -2165,6 +2196,7 @@ var globTool = {
|
|
|
2165
2196
|
// src/tools/code/listDir.ts
|
|
2166
2197
|
import fs12 from "fs/promises";
|
|
2167
2198
|
var listDirTool = {
|
|
2199
|
+
clearable: true,
|
|
2168
2200
|
definition: {
|
|
2169
2201
|
name: "listDir",
|
|
2170
2202
|
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.",
|
|
@@ -2200,6 +2232,7 @@ var listDirTool = {
|
|
|
2200
2232
|
|
|
2201
2233
|
// src/tools/code/editsFinished.ts
|
|
2202
2234
|
var editsFinishedTool = {
|
|
2235
|
+
clearable: false,
|
|
2203
2236
|
definition: {
|
|
2204
2237
|
name: "editsFinished",
|
|
2205
2238
|
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.",
|
|
@@ -2216,6 +2249,7 @@ var editsFinishedTool = {
|
|
|
2216
2249
|
|
|
2217
2250
|
// src/tools/code/lspDiagnostics.ts
|
|
2218
2251
|
var lspDiagnosticsTool = {
|
|
2252
|
+
clearable: true,
|
|
2219
2253
|
definition: {
|
|
2220
2254
|
name: "lspDiagnostics",
|
|
2221
2255
|
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.",
|
|
@@ -2264,6 +2298,7 @@ var lspDiagnosticsTool = {
|
|
|
2264
2298
|
|
|
2265
2299
|
// src/tools/code/restartProcess.ts
|
|
2266
2300
|
var restartProcessTool = {
|
|
2301
|
+
clearable: false,
|
|
2267
2302
|
definition: {
|
|
2268
2303
|
name: "restartProcess",
|
|
2269
2304
|
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.",
|
|
@@ -2290,6 +2325,7 @@ var restartProcessTool = {
|
|
|
2290
2325
|
|
|
2291
2326
|
// src/tools/code/runScenario.ts
|
|
2292
2327
|
var runScenarioTool = {
|
|
2328
|
+
clearable: true,
|
|
2293
2329
|
definition: {
|
|
2294
2330
|
name: "runScenario",
|
|
2295
2331
|
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.",
|
|
@@ -2311,6 +2347,7 @@ var runScenarioTool = {
|
|
|
2311
2347
|
|
|
2312
2348
|
// src/tools/code/runMethod.ts
|
|
2313
2349
|
var runMethodTool = {
|
|
2350
|
+
clearable: true,
|
|
2314
2351
|
definition: {
|
|
2315
2352
|
name: "runMethod",
|
|
2316
2353
|
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.",
|
|
@@ -2393,6 +2430,7 @@ async function captureAndAnalyzeScreenshot(promptOrOptions) {
|
|
|
2393
2430
|
|
|
2394
2431
|
// src/tools/code/screenshot.ts
|
|
2395
2432
|
var screenshotTool = {
|
|
2433
|
+
clearable: true,
|
|
2396
2434
|
definition: {
|
|
2397
2435
|
name: "screenshot",
|
|
2398
2436
|
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.",
|
|
@@ -2651,6 +2689,7 @@ async function runSubAgent(config) {
|
|
|
2651
2689
|
const fullSystem = `${system}
|
|
2652
2690
|
|
|
2653
2691
|
Current date: ${dateStr}`;
|
|
2692
|
+
const excludeToolsFromClearing = tools2.filter((t) => t.clearable === false).map((t) => t.name);
|
|
2654
2693
|
let turns = 0;
|
|
2655
2694
|
const run = async () => {
|
|
2656
2695
|
const messages = [
|
|
@@ -2714,6 +2753,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
2714
2753
|
system: fullSystem,
|
|
2715
2754
|
messages: cleanMessagesForApi(messages),
|
|
2716
2755
|
tools: tools2,
|
|
2756
|
+
excludeToolsFromClearing,
|
|
2717
2757
|
signal
|
|
2718
2758
|
},
|
|
2719
2759
|
{
|
|
@@ -2964,6 +3004,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
2964
3004
|
// src/subagents/browserAutomation/tools.ts
|
|
2965
3005
|
var BROWSER_TOOLS = [
|
|
2966
3006
|
{
|
|
3007
|
+
clearable: true,
|
|
2967
3008
|
name: "browserCommand",
|
|
2968
3009
|
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.",
|
|
2969
3010
|
inputSchema: {
|
|
@@ -3044,6 +3085,7 @@ var BROWSER_TOOLS = [
|
|
|
3044
3085
|
}
|
|
3045
3086
|
},
|
|
3046
3087
|
{
|
|
3088
|
+
clearable: true,
|
|
3047
3089
|
name: "screenshotFullPage",
|
|
3048
3090
|
description: "Capture a full-height screenshot of the current page. Returns a CDN URL with full text analysis and description.",
|
|
3049
3091
|
inputSchema: {
|
|
@@ -3057,6 +3099,7 @@ var BROWSER_TOOLS = [
|
|
|
3057
3099
|
}
|
|
3058
3100
|
},
|
|
3059
3101
|
{
|
|
3102
|
+
clearable: false,
|
|
3060
3103
|
name: "resetBrowser",
|
|
3061
3104
|
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.",
|
|
3062
3105
|
inputSchema: {
|
|
@@ -3088,6 +3131,7 @@ ${appSpec}
|
|
|
3088
3131
|
// src/subagents/browserAutomation/index.ts
|
|
3089
3132
|
var log6 = createLogger("browser-automation");
|
|
3090
3133
|
var browserAutomationTool = {
|
|
3134
|
+
clearable: true,
|
|
3091
3135
|
definition: {
|
|
3092
3136
|
name: "runAutomatedBrowserTest",
|
|
3093
3137
|
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.",
|
|
@@ -3209,6 +3253,7 @@ __export(searchGoogle_exports, {
|
|
|
3209
3253
|
execute: () => execute
|
|
3210
3254
|
});
|
|
3211
3255
|
var definition = {
|
|
3256
|
+
clearable: false,
|
|
3212
3257
|
name: "searchGoogle",
|
|
3213
3258
|
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.',
|
|
3214
3259
|
inputSchema: {
|
|
@@ -3236,6 +3281,7 @@ __export(scrapeWebUrl_exports, {
|
|
|
3236
3281
|
execute: () => execute2
|
|
3237
3282
|
});
|
|
3238
3283
|
var definition2 = {
|
|
3284
|
+
clearable: false,
|
|
3239
3285
|
name: "scrapeWebUrl",
|
|
3240
3286
|
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.",
|
|
3241
3287
|
inputSchema: {
|
|
@@ -3290,6 +3336,7 @@ Identify the specific design moves that make this page interesting and unique, d
|
|
|
3290
3336
|
Respond only with your analysis as Markdown and absolutely no other text. Do not use emojis - use unicode if you need symbols.
|
|
3291
3337
|
`;
|
|
3292
3338
|
var definition3 = {
|
|
3339
|
+
clearable: false,
|
|
3293
3340
|
name: "analyzeDesign",
|
|
3294
3341
|
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.",
|
|
3295
3342
|
inputSchema: {
|
|
@@ -3338,6 +3385,7 @@ __export(analyzeImage_exports, {
|
|
|
3338
3385
|
});
|
|
3339
3386
|
var 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.";
|
|
3340
3387
|
var definition4 = {
|
|
3388
|
+
clearable: true,
|
|
3341
3389
|
name: "analyzeImage",
|
|
3342
3390
|
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.",
|
|
3343
3391
|
inputSchema: {
|
|
@@ -3373,6 +3421,7 @@ __export(screenshot_exports, {
|
|
|
3373
3421
|
execute: () => execute5
|
|
3374
3422
|
});
|
|
3375
3423
|
var definition5 = {
|
|
3424
|
+
clearable: true,
|
|
3376
3425
|
name: "screenshot",
|
|
3377
3426
|
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.",
|
|
3378
3427
|
inputSchema: {
|
|
@@ -3575,6 +3624,7 @@ async function generateImageAssets(opts) {
|
|
|
3575
3624
|
|
|
3576
3625
|
// src/subagents/designExpert/tools/images/generateImages.ts
|
|
3577
3626
|
var definition6 = {
|
|
3627
|
+
clearable: false,
|
|
3578
3628
|
name: "generateImages",
|
|
3579
3629
|
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.",
|
|
3580
3630
|
inputSchema: {
|
|
@@ -3620,6 +3670,7 @@ __export(editImages_exports, {
|
|
|
3620
3670
|
execute: () => execute7
|
|
3621
3671
|
});
|
|
3622
3672
|
var definition7 = {
|
|
3673
|
+
clearable: false,
|
|
3623
3674
|
name: "editImages",
|
|
3624
3675
|
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.",
|
|
3625
3676
|
inputSchema: {
|
|
@@ -3772,7 +3823,7 @@ Each interface type invokes the same backend methods. Methods don't know which i
|
|
|
3772
3823
|
TypeScript running in a sandboxed environment. Any npm package can be installed. Key capabilities:
|
|
3773
3824
|
|
|
3774
3825
|
- Managed SQLite database with typed schemas and automatic migrations. Define a TypeScript interface, push, and the platform handles diffing and migrating.
|
|
3775
|
-
- Built-in
|
|
3826
|
+
- 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.
|
|
3776
3827
|
- Sandboxed execution with npm packages pre-installed.
|
|
3777
3828
|
- Git-native deployment. Push to default branch to deploy.
|
|
3778
3829
|
|
|
@@ -3975,6 +4026,7 @@ var DESCRIPTION = `
|
|
|
3975
4026
|
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.
|
|
3976
4027
|
`.trim();
|
|
3977
4028
|
var designExpertTool = {
|
|
4029
|
+
clearable: false,
|
|
3978
4030
|
definition: {
|
|
3979
4031
|
name: "visualDesignExpert",
|
|
3980
4032
|
description: DESCRIPTION,
|
|
@@ -4275,6 +4327,7 @@ function getProductVisionPrompt() {
|
|
|
4275
4327
|
|
|
4276
4328
|
// src/subagents/productVision/index.ts
|
|
4277
4329
|
var productVisionTool = {
|
|
4330
|
+
clearable: false,
|
|
4278
4331
|
definition: {
|
|
4279
4332
|
name: "productVision",
|
|
4280
4333
|
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.",
|
|
@@ -4423,6 +4476,7 @@ var SANITY_CHECK_TOOLS = [
|
|
|
4423
4476
|
// src/subagents/codeSanityCheck/index.ts
|
|
4424
4477
|
var BASE_PROMPT3 = readAsset("subagents/codeSanityCheck", "prompt.md");
|
|
4425
4478
|
var codeSanityCheckTool = {
|
|
4479
|
+
clearable: false,
|
|
4426
4480
|
definition: {
|
|
4427
4481
|
name: "codeSanityCheck",
|
|
4428
4482
|
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.',
|
|
@@ -4471,6 +4525,7 @@ var codeSanityCheckTool = {
|
|
|
4471
4525
|
|
|
4472
4526
|
// src/tools/common/scrapeWebUrl.ts
|
|
4473
4527
|
var scrapeWebUrlTool = {
|
|
4528
|
+
clearable: false,
|
|
4474
4529
|
definition: {
|
|
4475
4530
|
name: "scrapeWebUrl",
|
|
4476
4531
|
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",
|
|
@@ -4543,6 +4598,9 @@ var ALL_TOOLS = [
|
|
|
4543
4598
|
lspDiagnosticsTool,
|
|
4544
4599
|
restartProcessTool
|
|
4545
4600
|
];
|
|
4601
|
+
var CLEARABLE_TOOLS = new Set(
|
|
4602
|
+
ALL_TOOLS.filter((t) => t.clearable).map((t) => t.definition.name)
|
|
4603
|
+
);
|
|
4546
4604
|
function getToolDefinitions(_onboardingState) {
|
|
4547
4605
|
return ALL_TOOLS.map((t) => t.definition);
|
|
4548
4606
|
}
|
|
@@ -4863,6 +4921,7 @@ async function runTurn(params) {
|
|
|
4863
4921
|
onBackgroundComplete
|
|
4864
4922
|
} = params;
|
|
4865
4923
|
const tools2 = getToolDefinitions(onboardingState);
|
|
4924
|
+
const excludeToolsFromClearing = tools2.filter((t) => !CLEARABLE_TOOLS.has(t.name)).map((t) => t.name);
|
|
4866
4925
|
log8.info("Turn started", {
|
|
4867
4926
|
requestId,
|
|
4868
4927
|
model,
|
|
@@ -4872,11 +4931,17 @@ async function runTurn(params) {
|
|
|
4872
4931
|
}
|
|
4873
4932
|
});
|
|
4874
4933
|
onEvent({ type: "turn_started" });
|
|
4934
|
+
const hasText = userMessage.trim().length > 0;
|
|
4935
|
+
const hasAttachments = attachments && attachments.length > 0;
|
|
4936
|
+
if (!hasText && !hasAttachments) {
|
|
4937
|
+
onEvent({ type: "error", error: "Empty message" });
|
|
4938
|
+
return;
|
|
4939
|
+
}
|
|
4875
4940
|
const userMsg = { role: "user", content: userMessage };
|
|
4876
4941
|
if (hidden) {
|
|
4877
4942
|
userMsg.hidden = true;
|
|
4878
4943
|
}
|
|
4879
|
-
if (
|
|
4944
|
+
if (hasAttachments) {
|
|
4880
4945
|
userMsg.attachments = attachments;
|
|
4881
4946
|
}
|
|
4882
4947
|
state.messages.push(userMsg);
|
|
@@ -5002,6 +5067,7 @@ async function runTurn(params) {
|
|
|
5002
5067
|
system,
|
|
5003
5068
|
messages: cleanMessagesForApi(state.messages),
|
|
5004
5069
|
tools: tools2,
|
|
5070
|
+
excludeToolsFromClearing,
|
|
5005
5071
|
signal
|
|
5006
5072
|
},
|
|
5007
5073
|
{
|
|
@@ -5474,6 +5540,7 @@ async function startHeadless(opts = {}) {
|
|
|
5474
5540
|
let currentAbort = null;
|
|
5475
5541
|
let currentRequestId;
|
|
5476
5542
|
let completedEmitted = false;
|
|
5543
|
+
let turnStart = 0;
|
|
5477
5544
|
const EXTERNAL_TOOL_TIMEOUT_MS = 3e5;
|
|
5478
5545
|
const pendingTools = /* @__PURE__ */ new Map();
|
|
5479
5546
|
const earlyResults = /* @__PURE__ */ new Map();
|
|
@@ -5586,8 +5653,8 @@ ${xmlParts}
|
|
|
5586
5653
|
function onEvent(e) {
|
|
5587
5654
|
const rid = currentRequestId;
|
|
5588
5655
|
switch (e.type) {
|
|
5589
|
-
// Suppressed — caller already knows the request started
|
|
5590
5656
|
case "turn_started":
|
|
5657
|
+
emit("turn_started", {}, rid);
|
|
5591
5658
|
return;
|
|
5592
5659
|
// Terminal events — translate to `completed`
|
|
5593
5660
|
case "turn_done":
|
|
@@ -5606,7 +5673,11 @@ ${xmlParts}
|
|
|
5606
5673
|
writeFileSync(".remy-stats.json", JSON.stringify(sessionStats));
|
|
5607
5674
|
} catch {
|
|
5608
5675
|
}
|
|
5609
|
-
emit(
|
|
5676
|
+
emit(
|
|
5677
|
+
"completed",
|
|
5678
|
+
{ success: true, durationMs: Date.now() - turnStart },
|
|
5679
|
+
rid
|
|
5680
|
+
);
|
|
5610
5681
|
setTimeout(() => {
|
|
5611
5682
|
applyPendingBlockUpdates();
|
|
5612
5683
|
flushBackgroundQueue();
|
|
@@ -5746,7 +5817,7 @@ ${xmlParts}
|
|
|
5746
5817
|
currentRequestId = requestId;
|
|
5747
5818
|
currentAbort = new AbortController();
|
|
5748
5819
|
completedEmitted = false;
|
|
5749
|
-
|
|
5820
|
+
turnStart = Date.now();
|
|
5750
5821
|
const attachments = parsed.attachments;
|
|
5751
5822
|
if (attachments?.length) {
|
|
5752
5823
|
console.warn(
|
|
@@ -5891,7 +5962,9 @@ ${xmlParts}
|
|
|
5891
5962
|
writeFileSync(".remy-stats.json", JSON.stringify(sessionStats));
|
|
5892
5963
|
} catch {
|
|
5893
5964
|
}
|
|
5894
|
-
|
|
5965
|
+
const compactSystem = buildSystemPrompt("onboardingFinished");
|
|
5966
|
+
const compactTools = getToolDefinitions("onboardingFinished");
|
|
5967
|
+
compactConversation(state, config, compactSystem, compactTools).then(() => {
|
|
5895
5968
|
saveSession(state);
|
|
5896
5969
|
emit("compaction_complete", {}, requestId);
|
|
5897
5970
|
emit("completed", { success: true }, requestId);
|