@mindstudio-ai/remy 0.1.34 → 0.1.35

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.
Files changed (54) hide show
  1. package/dist/headless.js +578 -393
  2. package/dist/index.js +652 -385
  3. package/dist/prompt/sources/llms.txt +1618 -0
  4. package/dist/prompt/static/instructions.md +1 -1
  5. package/dist/prompt/static/team.md +1 -1
  6. package/dist/subagents/.notes-background-agents.md +60 -48
  7. package/dist/subagents/browserAutomation/prompt.md +14 -11
  8. package/dist/subagents/designExpert/data/sources/dev/index.html +901 -0
  9. package/dist/subagents/designExpert/data/sources/dev/serve.mjs +244 -0
  10. package/dist/subagents/designExpert/data/sources/dev/specimens-fonts.html +126 -0
  11. package/dist/subagents/designExpert/data/sources/dev/specimens-pairings.html +114 -0
  12. package/dist/subagents/designExpert/data/{fonts.json → sources/fonts.json} +0 -97
  13. package/dist/subagents/designExpert/data/sources/inspiration.json +392 -0
  14. package/dist/subagents/designExpert/prompt.md +36 -12
  15. package/dist/subagents/designExpert/prompts/animation.md +14 -6
  16. package/dist/subagents/designExpert/prompts/color.md +25 -5
  17. package/dist/subagents/designExpert/prompts/{icons.md → components.md} +17 -5
  18. package/dist/subagents/designExpert/prompts/frontend-design-notes.md +17 -122
  19. package/dist/subagents/designExpert/prompts/identity.md +15 -61
  20. package/dist/subagents/designExpert/prompts/images.md +35 -10
  21. package/dist/subagents/designExpert/prompts/layout.md +14 -9
  22. package/dist/subagents/designExpert/prompts/typography.md +39 -0
  23. package/package.json +2 -2
  24. package/dist/actions/buildFromInitialSpec.md +0 -15
  25. package/dist/actions/publish.md +0 -12
  26. package/dist/actions/sync.md +0 -19
  27. package/dist/compiled/README.md +0 -100
  28. package/dist/compiled/auth.md +0 -77
  29. package/dist/compiled/design.md +0 -251
  30. package/dist/compiled/dev-and-deploy.md +0 -69
  31. package/dist/compiled/interfaces.md +0 -238
  32. package/dist/compiled/manifest.md +0 -107
  33. package/dist/compiled/media-cdn.md +0 -51
  34. package/dist/compiled/methods.md +0 -225
  35. package/dist/compiled/msfm.md +0 -222
  36. package/dist/compiled/platform.md +0 -105
  37. package/dist/compiled/scenarios.md +0 -103
  38. package/dist/compiled/sdk-actions.md +0 -146
  39. package/dist/compiled/tables.md +0 -263
  40. package/dist/static/authoring.md +0 -101
  41. package/dist/static/coding.md +0 -29
  42. package/dist/static/identity.md +0 -1
  43. package/dist/static/instructions.md +0 -31
  44. package/dist/static/intake.md +0 -44
  45. package/dist/static/lsp.md +0 -4
  46. package/dist/static/projectContext.ts +0 -160
  47. package/dist/static/team.md +0 -39
  48. package/dist/subagents/designExpert/data/inspiration.json +0 -392
  49. package/dist/subagents/designExpert/prompts/instructions.md +0 -18
  50. /package/dist/subagents/designExpert/data/{compile-font-descriptions.sh → sources/compile-font-descriptions.sh} +0 -0
  51. /package/dist/subagents/designExpert/data/{compile-inspiration.sh → sources/compile-inspiration.sh} +0 -0
  52. /package/dist/subagents/designExpert/data/{inspiration.raw.json → sources/inspiration.raw.json} +0 -0
  53. /package/dist/subagents/designExpert/{prompts/tool-prompts → data/sources/prompts}/design-analysis.md +0 -0
  54. /package/dist/subagents/designExpert/{prompts/tool-prompts → data/sources/prompts}/font-analysis.md +0 -0
package/dist/index.js CHANGED
@@ -1057,7 +1057,12 @@ function runCli(cmd, options) {
1057
1057
  const entry = JSON.parse(trimmed);
1058
1058
  if (entry.type === "log" && entry.value) {
1059
1059
  const prefix = entry.tag ? `[${entry.tag}]` : "[log]";
1060
- logs.push(`${prefix} ${entry.value}`);
1060
+ const formatted = `${prefix} ${entry.value}`;
1061
+ if (options?.onLog) {
1062
+ options.onLog(formatted);
1063
+ } else {
1064
+ logs.push(formatted);
1065
+ }
1061
1066
  }
1062
1067
  } catch {
1063
1068
  }
@@ -1069,7 +1074,7 @@ function runCli(cmd, options) {
1069
1074
  }, timeout);
1070
1075
  child.on("close", (code) => {
1071
1076
  clearTimeout(timer);
1072
- const logBlock = logs.length > 0 ? logs.join("\n") + "\n\n" : "";
1077
+ const logBlock = !options?.onLog && logs.length > 0 ? logs.join("\n") + "\n\n" : "";
1073
1078
  const out = stdout.trim();
1074
1079
  if (out) {
1075
1080
  resolve(logBlock + out);
@@ -1111,11 +1116,12 @@ var init_sdkConsultant = __esm({
1111
1116
  required: ["query"]
1112
1117
  }
1113
1118
  },
1114
- async execute(input) {
1119
+ async execute(input, context) {
1115
1120
  const query = input.query;
1116
1121
  return runCli(`mindstudio ask ${JSON.stringify(query)}`, {
1117
1122
  timeout: 2e5,
1118
- maxBuffer: 512 * 1024
1123
+ maxBuffer: 512 * 1024,
1124
+ onLog: context?.onLog
1119
1125
  });
1120
1126
  }
1121
1127
  };
@@ -1147,7 +1153,7 @@ var init_fetchUrl = __esm({
1147
1153
  required: ["url"]
1148
1154
  }
1149
1155
  },
1150
- async execute(input) {
1156
+ async execute(input, context) {
1151
1157
  const url = input.url;
1152
1158
  const screenshot = input.screenshot;
1153
1159
  const pageOptions = { onlyMainContent: true };
@@ -1155,7 +1161,8 @@ var init_fetchUrl = __esm({
1155
1161
  pageOptions.screenshot = true;
1156
1162
  }
1157
1163
  return runCli(
1158
- `mindstudio scrape-url --url ${JSON.stringify(url)} --page-options ${JSON.stringify(JSON.stringify(pageOptions))} --no-meta`
1164
+ `mindstudio scrape-url --url ${JSON.stringify(url)} --page-options ${JSON.stringify(JSON.stringify(pageOptions))} --no-meta`,
1165
+ { onLog: context?.onLog }
1159
1166
  );
1160
1167
  }
1161
1168
  };
@@ -1183,11 +1190,11 @@ var init_searchGoogle = __esm({
1183
1190
  required: ["query"]
1184
1191
  }
1185
1192
  },
1186
- async execute(input) {
1193
+ async execute(input, context) {
1187
1194
  const query = input.query;
1188
1195
  return runCli(
1189
1196
  `mindstudio search-google --query ${JSON.stringify(query)} --export-type json --output-key results --no-meta`,
1190
- { maxBuffer: 512 * 1024 }
1197
+ { maxBuffer: 512 * 1024, onLog: context?.onLog }
1191
1198
  );
1192
1199
  }
1193
1200
  };
@@ -1224,9 +1231,9 @@ var init_setProjectName = __esm({
1224
1231
  // src/tools/code/readFile.ts
1225
1232
  import fs6 from "fs/promises";
1226
1233
  function isBinary(buffer) {
1227
- const sample2 = buffer.subarray(0, 8192);
1228
- for (let i = 0; i < sample2.length; i++) {
1229
- if (sample2[i] === 0) {
1234
+ const sample3 = buffer.subarray(0, 8192);
1235
+ for (let i = 0; i < sample3.length; i++) {
1236
+ if (sample3[i] === 0) {
1230
1237
  return true;
1231
1238
  }
1232
1239
  }
@@ -2018,18 +2025,16 @@ var init_runMethod = __esm({
2018
2025
  // src/tools/_helpers/screenshot.ts
2019
2026
  async function captureAndAnalyzeScreenshot(promptOrOptions) {
2020
2027
  let prompt;
2021
- let fullPage = false;
2028
+ let onLog;
2022
2029
  if (typeof promptOrOptions === "object" && promptOrOptions !== null) {
2023
2030
  prompt = promptOrOptions.prompt;
2024
- fullPage = promptOrOptions.fullPage ?? false;
2031
+ onLog = promptOrOptions.onLog;
2025
2032
  } else {
2026
2033
  prompt = promptOrOptions;
2027
2034
  }
2028
- const ssResult = await sidecarRequest(
2029
- "/screenshot",
2030
- { fullPage },
2031
- { timeout: 12e4 }
2032
- );
2035
+ const ssResult = await sidecarRequest("/screenshot-full-page", void 0, {
2036
+ timeout: 12e4
2037
+ });
2033
2038
  log.debug("Screenshot response", { ssResult });
2034
2039
  const url = ssResult?.url || ssResult?.screenshotUrl;
2035
2040
  if (!url) {
@@ -2043,7 +2048,7 @@ async function captureAndAnalyzeScreenshot(promptOrOptions) {
2043
2048
  const analysisPrompt = prompt || SCREENSHOT_ANALYSIS_PROMPT;
2044
2049
  const analysis = await runCli(
2045
2050
  `mindstudio analyze-image --prompt ${JSON.stringify(analysisPrompt)} --image-url ${JSON.stringify(url)} --output-key analysis --no-meta`,
2046
- { timeout: 2e5 }
2051
+ { timeout: 2e5, onLog }
2047
2052
  );
2048
2053
  return JSON.stringify({ url, analysis });
2049
2054
  }
@@ -2067,26 +2072,22 @@ var init_screenshot2 = __esm({
2067
2072
  screenshotTool = {
2068
2073
  definition: {
2069
2074
  name: "screenshot",
2070
- description: "Capture a screenshot of the app preview and get a description of what's on screen. Optionally provide a specific question about what you're looking for. By default captures the viewport (what the user sees). Set fullPage to capture the entire scrollable page.",
2075
+ description: "Capture a full-height screenshot of the app preview and get a description of what's on screen. Optionally provide a specific question about what you're looking for..",
2071
2076
  inputSchema: {
2072
2077
  type: "object",
2073
2078
  properties: {
2074
2079
  prompt: {
2075
2080
  type: "string",
2076
2081
  description: "Optional question about the screenshot. If omitted, returns a general description of what's visible."
2077
- },
2078
- fullPage: {
2079
- type: "boolean",
2080
- description: "Capture the full scrollable page instead of just the viewport. Use when you need to see below-the-fold content."
2081
2082
  }
2082
2083
  }
2083
2084
  }
2084
2085
  },
2085
- async execute(input) {
2086
+ async execute(input, context) {
2086
2087
  try {
2087
2088
  return await captureAndAnalyzeScreenshot({
2088
2089
  prompt: input.prompt,
2089
- fullPage: input.fullPage
2090
+ onLog: context?.onLog
2090
2091
  });
2091
2092
  } catch (err) {
2092
2093
  return `Error taking screenshot: ${err.message}`;
@@ -2135,7 +2136,7 @@ async function runSubAgent(config) {
2135
2136
  const {
2136
2137
  system,
2137
2138
  task,
2138
- tools,
2139
+ tools: tools2,
2139
2140
  externalTools,
2140
2141
  executeTool: executeTool2,
2141
2142
  apiConfig,
@@ -2167,7 +2168,7 @@ Current date/time: ${(/* @__PURE__ */ new Date()).toISOString().replace("T", " "
2167
2168
  subAgentId,
2168
2169
  system: fullSystem,
2169
2170
  messages: cleanMessagesForApi(messages),
2170
- tools,
2171
+ tools: tools2,
2171
2172
  signal
2172
2173
  })) {
2173
2174
  if (signal?.aborted) {
@@ -2260,7 +2261,13 @@ Current date/time: ${(/* @__PURE__ */ new Date()).toISOString().replace("T", " "
2260
2261
  if (externalTools.has(tc.name) && resolveExternalTool) {
2261
2262
  result = await resolveExternalTool(tc.id, tc.name, tc.input);
2262
2263
  } else {
2263
- result = await executeTool2(tc.name, tc.input, tc.id);
2264
+ const onLog = (line) => emit2({
2265
+ type: "tool_input_delta",
2266
+ id: tc.id,
2267
+ name: tc.name,
2268
+ result: line
2269
+ });
2270
+ result = await executeTool2(tc.name, tc.input, tc.id, onLog);
2264
2271
  }
2265
2272
  const isError = result.startsWith("Error");
2266
2273
  emit2({
@@ -2340,7 +2347,7 @@ var init_tools = __esm({
2340
2347
  "styles",
2341
2348
  "screenshot"
2342
2349
  ],
2343
- description: "snapshot: accessibility tree of the page (waits for network to settle). click: click an element (animated cursor, full event sequence). type: type text into input (one char at a time, works with React/Vue/Svelte). select: select a dropdown option by text. wait: wait for an element to appear (polls 100ms, waits for network). navigate: navigate to a URL within the app (waits for load, subsequent steps run on new page). evaluate: run JS in the page. styles: read computed CSS styles from elements (pass properties array with camelCase names, or omit for defaults). screenshot: full-page viewport-stitched screenshot (returns base64 JPEG with dimensions)."
2350
+ description: "snapshot: accessibility tree of the page (waits for network to settle). click: click an element (animated cursor, full event sequence). type: type text into input (one char at a time, works with React/Vue/Svelte). select: select a dropdown option by text. wait: wait for an element to appear (polls 100ms, waits for network). navigate: navigate to a URL within the app (waits for load, subsequent steps run on new page). evaluate: run JS in the page. styles: read computed CSS styles from elements (pass properties array with camelCase names, or omit for defaults). screenshot: full-page viewport-stitched screenshot (returns CDN url with dimensions)."
2344
2351
  },
2345
2352
  ref: {
2346
2353
  type: "string",
@@ -2396,8 +2403,8 @@ var init_tools = __esm({
2396
2403
  }
2397
2404
  },
2398
2405
  {
2399
- name: "screenshot",
2400
- description: "Capture a screenshot of the current page. Returns a CDN URL with dimensions.",
2406
+ name: "screenshotFullPage",
2407
+ description: "Capture a full-height screenshot of the current page. Returns a CDN URL with full text analysis and description.",
2401
2408
  inputSchema: {
2402
2409
  type: "object",
2403
2410
  properties: {}
@@ -2416,12 +2423,54 @@ var init_tools = __esm({
2416
2423
  }
2417
2424
  });
2418
2425
 
2419
- // src/subagents/browserAutomation/prompt.ts
2426
+ // src/assets.ts
2420
2427
  import fs10 from "fs";
2421
2428
  import path4 from "path";
2429
+ function findRoot(start) {
2430
+ let dir = start;
2431
+ while (dir !== path4.dirname(dir)) {
2432
+ if (fs10.existsSync(path4.join(dir, "package.json"))) {
2433
+ return dir;
2434
+ }
2435
+ dir = path4.dirname(dir);
2436
+ }
2437
+ return start;
2438
+ }
2439
+ function assetPath(...segments) {
2440
+ return path4.join(ASSETS_BASE, ...segments);
2441
+ }
2442
+ function readAsset(...segments) {
2443
+ const full = assetPath(...segments);
2444
+ try {
2445
+ return fs10.readFileSync(full, "utf-8").trim();
2446
+ } catch {
2447
+ throw new Error(`Required asset missing: ${full}`);
2448
+ }
2449
+ }
2450
+ function readJsonAsset(fallback, ...segments) {
2451
+ const full = assetPath(...segments);
2452
+ try {
2453
+ return JSON.parse(fs10.readFileSync(full, "utf-8"));
2454
+ } catch {
2455
+ return fallback;
2456
+ }
2457
+ }
2458
+ var ROOT, ASSETS_BASE;
2459
+ var init_assets = __esm({
2460
+ "src/assets.ts"() {
2461
+ "use strict";
2462
+ ROOT = findRoot(
2463
+ import.meta.dirname ?? path4.dirname(new URL(import.meta.url).pathname)
2464
+ );
2465
+ ASSETS_BASE = fs10.existsSync(path4.join(ROOT, "dist", "prompt")) ? path4.join(ROOT, "dist") : path4.join(ROOT, "src");
2466
+ }
2467
+ });
2468
+
2469
+ // src/subagents/browserAutomation/prompt.ts
2470
+ import fs11 from "fs";
2422
2471
  function getBrowserAutomationPrompt() {
2423
2472
  try {
2424
- const appSpec = fs10.readFileSync("src/app.md", "utf-8").trim();
2473
+ const appSpec = fs11.readFileSync("src/app.md", "utf-8").trim();
2425
2474
  return `${BASE_PROMPT}
2426
2475
 
2427
2476
  <app_context>
@@ -2431,14 +2480,12 @@ ${appSpec}
2431
2480
  return BASE_PROMPT;
2432
2481
  }
2433
2482
  }
2434
- var base, local, PROMPT_PATH, BASE_PROMPT;
2483
+ var BASE_PROMPT;
2435
2484
  var init_prompt = __esm({
2436
2485
  "src/subagents/browserAutomation/prompt.ts"() {
2437
2486
  "use strict";
2438
- base = import.meta.dirname ?? path4.dirname(new URL(import.meta.url).pathname);
2439
- local = path4.join(base, "prompt.md");
2440
- PROMPT_PATH = fs10.existsSync(local) ? local : path4.join(base, "subagents", "browserAutomation", "prompt.md");
2441
- BASE_PROMPT = fs10.readFileSync(PROMPT_PATH, "utf-8").trim();
2487
+ init_assets();
2488
+ BASE_PROMPT = readAsset("subagents/browserAutomation", "prompt.md");
2442
2489
  }
2443
2490
  });
2444
2491
 
@@ -2457,7 +2504,7 @@ var init_browserAutomation = __esm({
2457
2504
  browserAutomationTool = {
2458
2505
  definition: {
2459
2506
  name: "runAutomatedBrowserTest",
2460
- description: "Run an automated browser test against the live preview. Describe what to test \u2014 the agent figures out how. Use after writing or modifying frontend code, to reproduce user-reported issues, or to test end-to-end flows.",
2507
+ 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.",
2461
2508
  inputSchema: {
2462
2509
  type: "object",
2463
2510
  properties: {
@@ -2490,10 +2537,10 @@ var init_browserAutomation = __esm({
2490
2537
  task: input.task,
2491
2538
  tools: BROWSER_TOOLS,
2492
2539
  externalTools: BROWSER_EXTERNAL_TOOLS,
2493
- executeTool: async (name) => {
2494
- if (name === "screenshot") {
2540
+ executeTool: async (name, _input, _toolCallId, onLog) => {
2541
+ if (name === "screenshotFullPage") {
2495
2542
  try {
2496
- return await captureAndAnalyzeScreenshot();
2543
+ return await captureAndAnalyzeScreenshot({ onLog });
2497
2544
  } catch (err) {
2498
2545
  return `Error taking screenshot: ${err.message}`;
2499
2546
  }
@@ -2523,7 +2570,7 @@ var init_browserAutomation = __esm({
2523
2570
  try {
2524
2571
  const parsed = JSON.parse(result2);
2525
2572
  const screenshotSteps = (parsed.steps || []).filter(
2526
- (s) => s.command === "screenshot" && s.result?.url
2573
+ (s) => s.command === "screenshotViewport" && s.result?.url
2527
2574
  );
2528
2575
  if (screenshotSteps.length > 0) {
2529
2576
  const batchInput = screenshotSteps.map((s) => ({
@@ -2541,7 +2588,7 @@ var init_browserAutomation = __esm({
2541
2588
  const analyses = JSON.parse(batchResult);
2542
2589
  let ai = 0;
2543
2590
  for (const step of parsed.steps) {
2544
- if (step.command === "screenshot" && step.result?.url && ai < analyses.length) {
2591
+ if (step.command === "screenshotViewport" && step.result?.url && ai < analyses.length) {
2545
2592
  step.result.analysis = analyses[ai]?.output?.analysis || analyses[ai]?.output || "";
2546
2593
  ai++;
2547
2594
  }
@@ -2566,262 +2613,471 @@ var init_browserAutomation = __esm({
2566
2613
  }
2567
2614
  });
2568
2615
 
2569
- // src/subagents/designExpert/tools.ts
2570
- import fs11 from "fs";
2571
- import path5 from "path";
2572
- function resolvePath(filename) {
2573
- const local4 = path5.join(base2, filename);
2574
- return fs11.existsSync(local4) ? local4 : path5.join(base2, "subagents", "designExpert", filename);
2616
+ // src/subagents/designExpert/tools/searchGoogle.ts
2617
+ var searchGoogle_exports = {};
2618
+ __export(searchGoogle_exports, {
2619
+ definition: () => definition,
2620
+ execute: () => execute
2621
+ });
2622
+ async function execute(input, onLog) {
2623
+ return runCli(
2624
+ `mindstudio search-google --query ${JSON.stringify(input.query)} --export-type json --output-key results --no-meta`,
2625
+ { onLog }
2626
+ );
2575
2627
  }
2576
- async function executeDesignExpertTool(name, input, context, toolCallId) {
2577
- switch (name) {
2578
- case "screenshot": {
2579
- try {
2580
- return await captureAndAnalyzeScreenshot({
2581
- prompt: input.prompt,
2582
- fullPage: input.fullPage
2583
- });
2584
- } catch (err) {
2585
- return `Error taking screenshot: ${err.message}`;
2628
+ var definition;
2629
+ var init_searchGoogle2 = __esm({
2630
+ "src/subagents/designExpert/tools/searchGoogle.ts"() {
2631
+ "use strict";
2632
+ init_runCli();
2633
+ definition = {
2634
+ name: "searchGoogle",
2635
+ 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. Prioritize authoritative sources like Figma and other design leaders, avoid random blog spam. Pick one or more URLs from the results and then use `fetchUrl` to get their text content.',
2636
+ inputSchema: {
2637
+ type: "object",
2638
+ properties: {
2639
+ query: {
2640
+ type: "string",
2641
+ description: "The search query."
2642
+ }
2643
+ },
2644
+ required: ["query"]
2586
2645
  }
2587
- }
2588
- case "searchGoogle":
2589
- return runCli(
2590
- `mindstudio search-google --query ${JSON.stringify(input.query)} --export-type json --output-key results --no-meta`
2591
- );
2592
- case "fetchUrl": {
2593
- const pageOptions = { onlyMainContent: true };
2594
- if (input.screenshot) {
2595
- pageOptions.screenshot = true;
2646
+ };
2647
+ }
2648
+ });
2649
+
2650
+ // src/subagents/designExpert/tools/fetchUrl.ts
2651
+ var fetchUrl_exports = {};
2652
+ __export(fetchUrl_exports, {
2653
+ definition: () => definition2,
2654
+ execute: () => execute2
2655
+ });
2656
+ async function execute2(input, onLog) {
2657
+ const pageOptions = { onlyMainContent: true };
2658
+ if (input.screenshot) {
2659
+ pageOptions.screenshot = true;
2660
+ }
2661
+ return runCli(
2662
+ `mindstudio scrape-url --url ${JSON.stringify(input.url)} --page-options ${JSON.stringify(JSON.stringify(pageOptions))} --no-meta`,
2663
+ { onLog }
2664
+ );
2665
+ }
2666
+ var definition2;
2667
+ var init_fetchUrl2 = __esm({
2668
+ "src/subagents/designExpert/tools/fetchUrl.ts"() {
2669
+ "use strict";
2670
+ init_runCli();
2671
+ definition2 = {
2672
+ name: "fetchUrl",
2673
+ 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.",
2674
+ inputSchema: {
2675
+ type: "object",
2676
+ properties: {
2677
+ url: {
2678
+ type: "string",
2679
+ description: "The URL to fetch."
2680
+ }
2681
+ },
2682
+ required: ["url"]
2596
2683
  }
2597
- return runCli(
2598
- `mindstudio scrape-url --url ${JSON.stringify(input.url)} --page-options ${JSON.stringify(JSON.stringify(pageOptions))} --no-meta`
2599
- );
2684
+ };
2685
+ }
2686
+ });
2687
+
2688
+ // src/subagents/designExpert/tools/analyzeDesign.ts
2689
+ var analyzeDesign_exports = {};
2690
+ __export(analyzeDesign_exports, {
2691
+ definition: () => definition3,
2692
+ execute: () => execute3
2693
+ });
2694
+ async function execute3(input, onLog) {
2695
+ const url = input.url;
2696
+ const analysisPrompt = input.prompt || DESIGN_REFERENCE_PROMPT;
2697
+ const isImageUrl = /\.(png|jpe?g|webp|gif|svg|avif)(\?|$)/i.test(url);
2698
+ let imageUrl = url;
2699
+ if (!isImageUrl) {
2700
+ const ssUrl = await runCli(
2701
+ `mindstudio screenshot-url --url ${JSON.stringify(url)} --mode viewport --width 1440 --delay 2000 --output-key screenshotUrl --no-meta`,
2702
+ { timeout: 12e4, onLog }
2703
+ );
2704
+ if (ssUrl.startsWith("Error")) {
2705
+ return `Could not screenshot ${url}: ${ssUrl}`;
2600
2706
  }
2601
- case "analyzeReferenceImageOrUrl": {
2602
- const url = input.url;
2603
- const analysisPrompt = input.prompt || DESIGN_REFERENCE_PROMPT;
2604
- const isImageUrl = /\.(png|jpe?g|webp|gif|svg|avif)(\?|$)/i.test(url);
2605
- let imageUrl = url;
2606
- if (!isImageUrl) {
2607
- const ssUrl = await runCli(
2608
- `mindstudio screenshot-url --url ${JSON.stringify(url)} --mode viewport --width 1440 --delay 2000 --output-key screenshotUrl --no-meta`,
2609
- { timeout: 12e4 }
2610
- );
2611
- if (ssUrl.startsWith("Error")) {
2612
- return `Could not screenshot ${url}: ${ssUrl}`;
2613
- }
2614
- imageUrl = ssUrl;
2615
- }
2616
- const analysis = await runCli(
2617
- `mindstudio analyze-image --prompt ${JSON.stringify(analysisPrompt)} --image-url ${JSON.stringify(imageUrl)} --output-key analysis --no-meta`,
2618
- { timeout: 2e5 }
2619
- );
2620
- return isImageUrl ? analysis : `Screenshot: ${imageUrl}
2707
+ imageUrl = ssUrl;
2708
+ }
2709
+ const analysis = await runCli(
2710
+ `mindstudio analyze-image --prompt ${JSON.stringify(analysisPrompt)} --image-url ${JSON.stringify(imageUrl)} --output-key analysis --no-meta`,
2711
+ { timeout: 2e5, onLog }
2712
+ );
2713
+ return isImageUrl ? analysis : `Screenshot: ${imageUrl}
2621
2714
 
2622
2715
  ${analysis}`;
2623
- }
2624
- case "generateImages": {
2625
- const prompts = input.prompts;
2626
- const width = input.width || 2048;
2627
- const height = input.height || 2048;
2628
- const ANALYZE_PROMPT = "You are reviewing this image for a visual designer sourcing assets for a project. Describe: what the image depicts, the mood and color palette, how the lighting and composition work, whether there are any issues (unwanted text, artifacts, distortions), and how it could be used in a layout (hero background, feature section, card texture, etc). Be concise and practical.";
2629
- let imageUrls;
2630
- if (prompts.length === 1) {
2631
- const step = JSON.stringify({
2632
- prompt: prompts[0],
2633
- imageModelOverride: {
2634
- model: "seedream-4.5",
2635
- config: { width, height }
2716
+ }
2717
+ var DESIGN_REFERENCE_PROMPT, definition3;
2718
+ var init_analyzeDesign = __esm({
2719
+ "src/subagents/designExpert/tools/analyzeDesign.ts"() {
2720
+ "use strict";
2721
+ init_runCli();
2722
+ DESIGN_REFERENCE_PROMPT = `
2723
+ You are analyzing a screenshot of a real website or app for a designer's personal technique/inspiration reference notes.
2724
+
2725
+ Analyze the image and think about what makes the site or app special and unique. What is it doing that is unique, different, original, and creative? What makes it special? What isn't working? What doesn't look or feel good?
2726
+
2727
+ Then, provide the following analysis:
2728
+
2729
+ ## Context
2730
+ What is this page, and what does it look like? Very briefly note the industry/vertical and purpose, then describe the composition with enough context to frame the analysis that follows \u2014 what's on the page, where things are positioned, what does the viewport look and feel like. Give enough detail that someone who can't see the image could understand the spatial references in the techniques section. Do not mention specific brand names. Keep it concise.
2731
+
2732
+ ## Colors
2733
+ List the palette as hex values with short labels. Just the swatches \u2014 no "strategy" paragraph.
2734
+
2735
+ ## Typography
2736
+ Brief description of the types used on the page. If you can identify the actual typeface name, provide it, otherwise provide a concrete description (e.g., "ultra-condensed grotesque, ~900 weight, tracked tight at maybe -0.03em, all-caps"). Include size relationships if notable (e.g., "hero text is viewport-width, body is 14px").
2737
+
2738
+ ## Techniques
2739
+ Identify the specific design moves that make this page interesting and unique, described in terms of how a designer with a technical background would write them down as notes in their notebook for inspiration. Focus only on the non-obvious, hard-to-think-of techniques \u2014 the things that make this page gallery-worthy. Skip basics like "high contrast CTA" or "generous whitespace" that any competent designer already knows.
2740
+
2741
+ Respond only with the analysis and absolutely no other text.
2742
+ `;
2743
+ definition3 = {
2744
+ name: "analyzeDesign",
2745
+ description: "Analyze the visual design of a website or image URL. Websites are automatically screenshotted first. 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.",
2746
+ inputSchema: {
2747
+ type: "object",
2748
+ properties: {
2749
+ url: {
2750
+ type: "string",
2751
+ description: "URL to analyze. Can be an image URL or a website URL (will be screenshotted)."
2752
+ },
2753
+ prompt: {
2754
+ type: "string",
2755
+ description: "Optional custom analysis prompt. If omitted, performs the standard design reference analysis."
2636
2756
  }
2637
- });
2638
- const url = await runCli(
2639
- `mindstudio generate-image '${step}' --output-key imageUrl --no-meta`,
2640
- { jsonLogs: true, timeout: 2e5 }
2641
- );
2642
- imageUrls = [url];
2643
- } else {
2644
- const steps = prompts.map((prompt) => ({
2645
- stepType: "generateImage",
2646
- step: {
2647
- prompt,
2648
- imageModelOverride: {
2649
- model: "seedream-4.5",
2650
- config: { width, height }
2651
- }
2757
+ },
2758
+ required: ["url"]
2759
+ }
2760
+ };
2761
+ }
2762
+ });
2763
+
2764
+ // src/subagents/designExpert/tools/analyzeImage.ts
2765
+ var analyzeImage_exports = {};
2766
+ __export(analyzeImage_exports, {
2767
+ definition: () => definition4,
2768
+ execute: () => execute4
2769
+ });
2770
+ async function execute4(input, onLog) {
2771
+ const imageUrl = input.imageUrl;
2772
+ const prompt = input.prompt || DEFAULT_PROMPT;
2773
+ const analysis = await runCli(
2774
+ `mindstudio analyze-image --prompt ${JSON.stringify(prompt)} --image-url ${JSON.stringify(imageUrl)} --output-key analysis --no-meta`,
2775
+ { timeout: 2e5, onLog }
2776
+ );
2777
+ return JSON.stringify({ url: imageUrl, analysis });
2778
+ }
2779
+ var DEFAULT_PROMPT, definition4;
2780
+ var init_analyzeImage = __esm({
2781
+ "src/subagents/designExpert/tools/analyzeImage.ts"() {
2782
+ "use strict";
2783
+ init_runCli();
2784
+ DEFAULT_PROMPT = "Describe everything visible in this image \u2014 every element, its position, its size relative to the frame, its colors, its content. Be thorough and spatial. After the inventory, note anything that looks visually broken (overlapping elements, clipped text, misaligned components).";
2785
+ definition4 = {
2786
+ name: "analyzeImage",
2787
+ description: "Analyze an image by URL. Returns a detailed description of everything visible. Provide a custom prompt to ask a specific question instead of the default full description.",
2788
+ inputSchema: {
2789
+ type: "object",
2790
+ properties: {
2791
+ imageUrl: {
2792
+ type: "string",
2793
+ description: "The image URL to analyze."
2794
+ },
2795
+ prompt: {
2796
+ type: "string",
2797
+ description: "Optional custom analysis prompt. If omitted, describes everything visible in the image."
2652
2798
  }
2653
- }));
2654
- const batchResult = await runCli(
2655
- `mindstudio batch '${JSON.stringify(steps)}' --no-meta`,
2656
- { jsonLogs: true, timeout: 2e5 }
2657
- );
2658
- try {
2659
- const parsed = JSON.parse(batchResult);
2660
- imageUrls = parsed.results.map(
2661
- (r) => r.output?.imageUrl ?? `Error: ${r.error}`
2662
- );
2663
- } catch {
2664
- return batchResult;
2665
- }
2799
+ },
2800
+ required: ["imageUrl"]
2666
2801
  }
2667
- const images = await Promise.all(
2668
- imageUrls.map(async (url, i) => {
2669
- if (url.startsWith("Error")) {
2670
- return { prompt: prompts[i], error: url };
2802
+ };
2803
+ }
2804
+ });
2805
+
2806
+ // src/subagents/designExpert/tools/screenshot.ts
2807
+ var screenshot_exports = {};
2808
+ __export(screenshot_exports, {
2809
+ definition: () => definition5,
2810
+ execute: () => execute5
2811
+ });
2812
+ async function execute5(input, onLog) {
2813
+ try {
2814
+ return await captureAndAnalyzeScreenshot({
2815
+ prompt: input.prompt,
2816
+ onLog
2817
+ });
2818
+ } catch (err) {
2819
+ return `Error taking screenshot: ${err.message}`;
2820
+ }
2821
+ }
2822
+ var definition5;
2823
+ var init_screenshot3 = __esm({
2824
+ "src/subagents/designExpert/tools/screenshot.ts"() {
2825
+ "use strict";
2826
+ init_screenshot();
2827
+ definition5 = {
2828
+ name: "screenshot",
2829
+ 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.",
2830
+ inputSchema: {
2831
+ type: "object",
2832
+ properties: {
2833
+ prompt: {
2834
+ type: "string",
2835
+ description: "Optional specific question about the screenshot."
2671
2836
  }
2672
- const analysis = await runCli(
2673
- `mindstudio analyze-image --prompt ${JSON.stringify(ANALYZE_PROMPT)} --image-url ${JSON.stringify(url)} --output-key analysis --no-meta`,
2674
- { timeout: 2e5 }
2675
- );
2676
- return { url, prompt: prompts[i], analysis, width, height };
2677
- })
2678
- );
2679
- return `%%JSON%%${JSON.stringify({ images })}`;
2680
- }
2681
- case "runBrowserTest": {
2682
- if (!context) {
2683
- return "Error: browser testing requires execution context (only available in headless mode)";
2837
+ }
2684
2838
  }
2685
- return browserAutomationTool.execute(
2686
- { task: input.task },
2687
- {
2688
- ...context,
2689
- toolCallId: toolCallId || context.toolCallId
2839
+ };
2840
+ }
2841
+ });
2842
+
2843
+ // src/subagents/designExpert/tools/_seedream.ts
2844
+ async function seedreamGenerate(opts) {
2845
+ const { prompts, sourceImages, transparentBackground, onLog } = opts;
2846
+ const width = opts.width || 2048;
2847
+ const height = opts.height || 2048;
2848
+ const config = { width, height };
2849
+ if (sourceImages?.length) {
2850
+ config.images = sourceImages;
2851
+ }
2852
+ let imageUrls;
2853
+ if (prompts.length === 1) {
2854
+ const step = JSON.stringify({
2855
+ prompt: prompts[0],
2856
+ imageModelOverride: {
2857
+ model: "seedream-4.5",
2858
+ config
2859
+ }
2860
+ });
2861
+ const url = await runCli(
2862
+ `mindstudio generate-image ${JSON.stringify(step)} --output-key imageUrl --no-meta`,
2863
+ { jsonLogs: true, timeout: 2e5, onLog }
2864
+ );
2865
+ imageUrls = [url];
2866
+ } else {
2867
+ const steps = prompts.map((prompt) => ({
2868
+ stepType: "generateImage",
2869
+ step: {
2870
+ prompt,
2871
+ imageModelOverride: {
2872
+ model: "seedream-4.5",
2873
+ config
2690
2874
  }
2875
+ }
2876
+ }));
2877
+ const batchResult = await runCli(
2878
+ `mindstudio batch ${JSON.stringify(JSON.stringify(steps))} --no-meta`,
2879
+ { jsonLogs: true, timeout: 2e5, onLog }
2880
+ );
2881
+ try {
2882
+ const parsed = JSON.parse(batchResult);
2883
+ imageUrls = parsed.results.map(
2884
+ (r) => r.output?.imageUrl ?? `Error: ${r.error}`
2691
2885
  );
2886
+ } catch {
2887
+ return batchResult;
2692
2888
  }
2693
- default:
2694
- return `Error: unknown tool "${name}"`;
2695
2889
  }
2890
+ if (transparentBackground) {
2891
+ imageUrls = await Promise.all(
2892
+ imageUrls.map(async (url) => {
2893
+ if (url.startsWith("Error")) {
2894
+ return url;
2895
+ }
2896
+ const result = await runCli(
2897
+ `mindstudio remove-background-from-image --image-url ${JSON.stringify(url)} --output-key imageUrl --no-meta`,
2898
+ { timeout: 2e5, onLog }
2899
+ );
2900
+ return result.startsWith("Error") ? url : result;
2901
+ })
2902
+ );
2903
+ }
2904
+ const images = await Promise.all(
2905
+ imageUrls.map(async (url, i) => {
2906
+ if (url.startsWith("Error")) {
2907
+ return { prompt: prompts[i], error: url };
2908
+ }
2909
+ const analysis = await runCli(
2910
+ `mindstudio analyze-image --prompt ${JSON.stringify(ANALYZE_PROMPT)} --image-url ${JSON.stringify(url)} --output-key analysis --no-meta`,
2911
+ { timeout: 2e5, onLog }
2912
+ );
2913
+ return { url, prompt: prompts[i], analysis, width, height };
2914
+ })
2915
+ );
2916
+ return JSON.stringify({ images });
2696
2917
  }
2697
- var base2, DESIGN_REFERENCE_PROMPT, DESIGN_EXPERT_TOOLS;
2698
- var init_tools2 = __esm({
2699
- "src/subagents/designExpert/tools.ts"() {
2918
+ var ANALYZE_PROMPT;
2919
+ var init_seedream = __esm({
2920
+ "src/subagents/designExpert/tools/_seedream.ts"() {
2700
2921
  "use strict";
2701
2922
  init_runCli();
2702
- init_screenshot();
2703
- init_browserAutomation();
2704
- base2 = import.meta.dirname ?? path5.dirname(new URL(import.meta.url).pathname);
2705
- DESIGN_REFERENCE_PROMPT = fs11.readFileSync(resolvePath("prompts/tool-prompts/design-analysis.md"), "utf-8").trim();
2706
- DESIGN_EXPERT_TOOLS = [
2707
- {
2708
- name: "searchGoogle",
2709
- description: 'Search Google for web results. Reserch modern design trends in industries or verticals, "best [domain] apps 2026", ui patterns, etc. Prioritize authoritative sources like Figma and other design leaders, avoid random blog spam. Pick one or more URLs from the results and then use `fetchUrl` to get their text content.',
2710
- inputSchema: {
2711
- type: "object",
2712
- properties: {
2713
- query: {
2714
- type: "string",
2715
- description: "The search query."
2716
- }
2717
- },
2718
- required: ["query"]
2719
- }
2720
- },
2721
- {
2722
- name: "fetchUrl",
2723
- description: "Fetch the content of a web page as markdown. Optionally capture a screenshot to see the visual design. Use when reading sites from search results or specific things the user wants to incorporate.",
2724
- inputSchema: {
2725
- type: "object",
2726
- properties: {
2727
- url: {
2728
- type: "string",
2729
- description: "The URL to fetch."
2923
+ ANALYZE_PROMPT = "You are reviewing this image for a visual designer sourcing assets for a project. Describe: what the image depicts, the mood and color palette, how the lighting and composition work, whether there are any issues (unwanted text, artifacts, distortions), and how it could be used in a layout (hero background, feature section, card texture, etc). Be concise and practical.";
2924
+ }
2925
+ });
2926
+
2927
+ // src/subagents/designExpert/tools/generateImages.ts
2928
+ var generateImages_exports = {};
2929
+ __export(generateImages_exports, {
2930
+ definition: () => definition6,
2931
+ execute: () => execute6
2932
+ });
2933
+ async function execute6(input, onLog) {
2934
+ return seedreamGenerate({
2935
+ prompts: input.prompts,
2936
+ width: input.width,
2937
+ height: input.height,
2938
+ transparentBackground: input.transparentBackground,
2939
+ onLog
2940
+ });
2941
+ }
2942
+ var definition6;
2943
+ var init_generateImages = __esm({
2944
+ "src/subagents/designExpert/tools/generateImages.ts"() {
2945
+ "use strict";
2946
+ init_seedream();
2947
+ definition6 = {
2948
+ name: "generateImages",
2949
+ description: "Generate images using AI. 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.",
2950
+ inputSchema: {
2951
+ type: "object",
2952
+ properties: {
2953
+ prompts: {
2954
+ type: "array",
2955
+ items: {
2956
+ type: "string"
2730
2957
  },
2731
- screenshot: {
2732
- type: "boolean",
2733
- description: "Capture a screenshot of the page. Use when you need to see the visual design, not just the text."
2734
- }
2958
+ description: "One or more image generation prompts. Be detailed: describe style, mood, composition, colors. Multiple prompts run in parallel."
2735
2959
  },
2736
- required: ["url"]
2737
- }
2738
- },
2739
- {
2740
- name: "analyzeReferenceImageOrUrl",
2741
- description: "Analyze any visual \u2014 pass an image URL or a website URL. Websites are automatically screenshotted first. If no prompt is provided, performs a full design reference analysis (mood, color, typography, layout, distinctiveness). Provide a custom prompt to ask a specific question instead.",
2742
- inputSchema: {
2743
- type: "object",
2744
- properties: {
2745
- url: {
2746
- type: "string",
2747
- description: "URL to analyze. Can be an image URL or a website URL (will be screenshotted)."
2748
- },
2749
- prompt: {
2750
- type: "string",
2751
- description: "Optional custom analysis prompt. If omitted, performs the standard design reference analysis."
2752
- }
2960
+ width: {
2961
+ type: "number",
2962
+ description: "Image width in pixels. Default 2048. Range: 2048-4096."
2753
2963
  },
2754
- required: ["url"]
2755
- }
2756
- },
2757
- {
2758
- name: "screenshot",
2759
- description: "Capture a screenshot of the app preview. Returns a CDN URL with visual analysis. Use to review the current state of the UI being built. By default captures the viewport. Set fullPage to capture the entire scrollable page.",
2760
- inputSchema: {
2761
- type: "object",
2762
- properties: {
2763
- prompt: {
2764
- type: "string",
2765
- description: "Optional specific question about the screenshot."
2766
- },
2767
- fullPage: {
2768
- type: "boolean",
2769
- description: "Capture the full scrollable page instead of just the viewport. Use when you need to see below-the-fold content."
2770
- }
2771
- }
2772
- }
2773
- },
2774
- {
2775
- name: "runBrowserTest",
2776
- description: "Run an automated browser test against the live app preview. Use to verify implementation details via getComputedStyle: font-family names, exact colors, spacing, borders, shadows, font sizes, transforms. Only use this to evaluate computed CSS properties that can't be deduced from sceenshots.",
2777
- inputSchema: {
2778
- type: "object",
2779
- properties: {
2780
- task: {
2781
- type: "string",
2782
- description: 'What to verify, in natural language. Focus on measurable properties: "Check the hero cards have border-radius: 24px and box-shadow" or "Verify the background color of the CTA section is #C4FF0D".'
2783
- }
2964
+ height: {
2965
+ type: "number",
2966
+ description: "Image height in pixels. Default 2048. Range: 2048-4096."
2784
2967
  },
2785
- required: ["task"]
2786
- }
2787
- },
2788
- {
2789
- name: "generateImages",
2790
- description: "Generate images using AI (Seedream). Returns CDN URLs with a quality analysis for each image. Produces high-quality results for both 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.",
2791
- inputSchema: {
2792
- type: "object",
2793
- properties: {
2794
- prompts: {
2795
- type: "array",
2796
- items: {
2797
- type: "string"
2798
- },
2799
- description: "One or more image generation prompts. Be detailed: describe style, mood, composition, colors. Multiple prompts run in parallel."
2968
+ transparentBackground: {
2969
+ type: "boolean",
2970
+ description: "Remove the background from generated images, producing transparent PNGs. Useful for icons, logos, product shots, and assets that need to be composited onto other backgrounds."
2971
+ }
2972
+ },
2973
+ required: ["prompts"]
2974
+ }
2975
+ };
2976
+ }
2977
+ });
2978
+
2979
+ // src/subagents/designExpert/tools/editImages.ts
2980
+ var editImages_exports = {};
2981
+ __export(editImages_exports, {
2982
+ definition: () => definition7,
2983
+ execute: () => execute7
2984
+ });
2985
+ async function execute7(input, onLog) {
2986
+ return seedreamGenerate({
2987
+ prompts: input.prompts,
2988
+ sourceImages: input.sourceImages,
2989
+ width: input.width,
2990
+ height: input.height,
2991
+ transparentBackground: input.transparentBackground,
2992
+ onLog
2993
+ });
2994
+ }
2995
+ var definition7;
2996
+ var init_editImages = __esm({
2997
+ "src/subagents/designExpert/tools/editImages.ts"() {
2998
+ "use strict";
2999
+ init_seedream();
3000
+ definition7 = {
3001
+ name: "editImages",
3002
+ description: "Edit or transform existing images using AI. 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 ferences into something new. Returns CDN URLs with analysis.",
3003
+ inputSchema: {
3004
+ type: "object",
3005
+ properties: {
3006
+ prompts: {
3007
+ type: "array",
3008
+ items: {
3009
+ type: "string"
2800
3010
  },
2801
- width: {
2802
- type: "number",
2803
- description: "Image width in pixels. Default 2048. Range: 2048-4096."
3011
+ description: "One or more edit prompts describing how to transform the source images. Multiple prompts run in parallel, each using the same source images."
3012
+ },
3013
+ sourceImages: {
3014
+ type: "array",
3015
+ items: {
3016
+ type: "string"
2804
3017
  },
2805
- height: {
2806
- type: "number",
2807
- description: "Image height in pixels. Default 2048. Range: 2048-4096."
2808
- }
3018
+ description: "One or more source/reference image URLs. These are used as the basis for the edit \u2014 the AI will use them as reference for style, subject, or composition."
2809
3019
  },
2810
- required: ["prompts"]
2811
- }
3020
+ width: {
3021
+ type: "number",
3022
+ description: "Output width in pixels. Default 2048. Range: 2048-4096."
3023
+ },
3024
+ height: {
3025
+ type: "number",
3026
+ description: "Output height in pixels. Default 2048. Range: 2048-4096."
3027
+ },
3028
+ transparentBackground: {
3029
+ type: "boolean",
3030
+ description: "Remove the background from output images, producing transparent PNGs."
3031
+ }
3032
+ },
3033
+ required: ["prompts", "sourceImages"]
2812
3034
  }
2813
- ];
3035
+ };
3036
+ }
3037
+ });
3038
+
3039
+ // src/subagents/designExpert/tools/index.ts
3040
+ async function executeDesignExpertTool(name, input, context, toolCallId, onLog) {
3041
+ const tool = tools[name];
3042
+ if (!tool) {
3043
+ return `Error: unknown tool "${name}"`;
3044
+ }
3045
+ return tool.execute(input, onLog);
3046
+ }
3047
+ var tools, DESIGN_EXPERT_TOOLS;
3048
+ var init_tools2 = __esm({
3049
+ "src/subagents/designExpert/tools/index.ts"() {
3050
+ "use strict";
3051
+ init_searchGoogle2();
3052
+ init_fetchUrl2();
3053
+ init_analyzeDesign();
3054
+ init_analyzeImage();
3055
+ init_screenshot3();
3056
+ init_generateImages();
3057
+ init_editImages();
3058
+ tools = {
3059
+ searchGoogle: searchGoogle_exports,
3060
+ fetchUrl: fetchUrl_exports,
3061
+ analyzeDesign: analyzeDesign_exports,
3062
+ analyzeImage: analyzeImage_exports,
3063
+ screenshot: screenshot_exports,
3064
+ generateImages: generateImages_exports,
3065
+ editImages: editImages_exports
3066
+ };
3067
+ DESIGN_EXPERT_TOOLS = Object.values(tools).map(
3068
+ (t) => t.definition
3069
+ );
2814
3070
  }
2815
3071
  });
2816
3072
 
2817
3073
  // src/subagents/common/context.ts
2818
3074
  import fs12 from "fs";
2819
- import path6 from "path";
3075
+ import path5 from "path";
2820
3076
  function walkMdFiles(dir, skip) {
2821
3077
  const files = [];
2822
3078
  try {
2823
3079
  for (const entry of fs12.readdirSync(dir, { withFileTypes: true })) {
2824
- const full = path6.join(dir, entry.name);
3080
+ const full = path5.join(dir, entry.name);
2825
3081
  if (entry.isDirectory()) {
2826
3082
  if (!skip?.has(entry.name)) {
2827
3083
  files.push(...walkMdFiles(full, skip));
@@ -2915,23 +3171,7 @@ var init_context = __esm({
2915
3171
  }
2916
3172
  });
2917
3173
 
2918
- // src/subagents/designExpert/prompt.ts
2919
- import fs13 from "fs";
2920
- import path7 from "path";
2921
- function resolvePath2(filename) {
2922
- const local4 = path7.join(base3, filename);
2923
- return fs13.existsSync(local4) ? local4 : path7.join(base3, "subagents", "designExpert", filename);
2924
- }
2925
- function readFile(filename) {
2926
- return fs13.readFileSync(resolvePath2(filename), "utf-8").trim();
2927
- }
2928
- function readJson(filename, fallback) {
2929
- try {
2930
- return JSON.parse(fs13.readFileSync(resolvePath2(filename), "utf-8"));
2931
- } catch {
2932
- return fallback;
2933
- }
2934
- }
3174
+ // src/subagents/designExpert/data/getFontLibrarySample.ts
2935
3175
  function sample(arr, n) {
2936
3176
  if (arr.length <= n) {
2937
3177
  return [...arr];
@@ -2943,10 +3183,12 @@ function sample(arr, n) {
2943
3183
  }
2944
3184
  return copy.slice(0, n);
2945
3185
  }
2946
- function getDesignExpertPrompt() {
2947
- const fonts = sample(fontData.fonts, 30);
2948
- const pairings = sample(fontData.pairings, 20);
2949
- const images = sample(inspirationImages, 15);
3186
+ function getFontLibrarySample() {
3187
+ const fonts = sample(fontData.fonts, 60);
3188
+ const pairings = sample(fontData.pairings, 30);
3189
+ if (!fonts.length) {
3190
+ return "";
3191
+ }
2950
3192
  const fontList = fonts.map((f) => {
2951
3193
  let cssInfo = "";
2952
3194
  if (f.source === "fontshare") {
@@ -2962,60 +3204,102 @@ function getDesignExpertPrompt() {
2962
3204
  const pairingList = pairings.map(
2963
3205
  (p) => `- **${p.heading.font}** (${p.heading.weight}) heading + **${p.body.font}** (${p.body.weight}) body`
2964
3206
  ).join("\n");
2965
- const fontsSection = fonts.length ? `<fonts_to_consider>
2966
- ## Fonts to consider
3207
+ return `
3208
+ ## Font Library
3209
+
3210
+ A random sample from a curated font library. Use these as starting points for font selection.
2967
3211
 
2968
- A random sample from Fontshare, Open Foundry, and Google Fonts. Use these as starting points for font selection.
2969
- CSS URL pattern: ${fontData.cssUrlPattern}
3212
+ ### Fonts
2970
3213
 
2971
3214
  ${fontList}
2972
3215
 
2973
- ### Suggested pairings
3216
+ ### Pairings
2974
3217
 
2975
- ${pairingList}
2976
- </fonts_to_consider>` : "";
2977
- const imageList = images.map((img) => `- ${img.analysis}`).join("\n\n");
2978
- const inspirationSection = images.length ? `<design_inspiration>
2979
- ## Design inspiration
3218
+ ${pairingList}`.trim();
3219
+ }
3220
+ var fontData;
3221
+ var init_getFontLibrarySample = __esm({
3222
+ "src/subagents/designExpert/data/getFontLibrarySample.ts"() {
3223
+ "use strict";
3224
+ init_assets();
3225
+ fontData = readJsonAsset(
3226
+ { cssUrlPattern: "", fonts: [], pairings: [] },
3227
+ "subagents/designExpert/data/sources/fonts.json"
3228
+ );
3229
+ }
3230
+ });
3231
+
3232
+ // src/subagents/designExpert/data/getDesignReferencesSample.ts
3233
+ function sample2(arr, n) {
3234
+ if (arr.length <= n) {
3235
+ return [...arr];
3236
+ }
3237
+ const copy = [...arr];
3238
+ for (let i = copy.length - 1; i > 0; i--) {
3239
+ const j = Math.floor(Math.random() * (i + 1));
3240
+ [copy[i], copy[j]] = [copy[j], copy[i]];
3241
+ }
3242
+ return copy.slice(0, n);
3243
+ }
3244
+ function getDesignReferencesSample() {
3245
+ const images = sample2(inspirationImages, 30);
3246
+ if (!images.length) {
3247
+ return "";
3248
+ }
3249
+ const imageList = images.map((img, i) => `### Reference ${i + 1}
3250
+ ${img.analysis}`).join("\n\n");
3251
+ return `
3252
+ ## Design References
2980
3253
 
2981
3254
  This is what the bar looks like. These are real sites that made it onto curated design galleries because they did something bold, intentional, and memorable. Use them as inspiration and let the takeaways guide your work. Your designs should feel like they belong in this company.
2982
3255
 
2983
- ${imageList}
2984
- </design_inspiration>` : "";
3256
+ ${imageList}`.trim();
3257
+ }
3258
+ var inspirationImages;
3259
+ var init_getDesignReferencesSample = __esm({
3260
+ "src/subagents/designExpert/data/getDesignReferencesSample.ts"() {
3261
+ "use strict";
3262
+ init_assets();
3263
+ inspirationImages = readJsonAsset(
3264
+ { images: [] },
3265
+ "subagents/designExpert/data/sources/inspiration.json"
3266
+ ).images;
3267
+ }
3268
+ });
3269
+
3270
+ // src/subagents/designExpert/prompt.ts
3271
+ import fs13 from "fs";
3272
+ function getDesignExpertPrompt() {
2985
3273
  const specContext = loadSpecContext();
2986
3274
  let prompt = PROMPT_TEMPLATE.replace(
2987
- "{{fonts_to_consider}}",
2988
- fontsSection
2989
- ).replace("{{inspiration_images}}", inspirationSection);
3275
+ "{{font_library}}",
3276
+ getFontLibrarySample()
3277
+ ).replace("{{design_references}}", getDesignReferencesSample());
2990
3278
  if (specContext) {
2991
3279
  prompt += `
2992
3280
 
2993
3281
  ${specContext}`;
3282
+ }
3283
+ try {
3284
+ fs13.writeFileSync(`.design-prompt.md`, prompt);
3285
+ } catch {
2994
3286
  }
2995
3287
  return prompt;
2996
3288
  }
2997
- var base3, RUNTIME_PLACEHOLDERS, PROMPT_TEMPLATE, fontData, inspirationImages;
3289
+ var SUBAGENT, RUNTIME_PLACEHOLDERS, PROMPT_TEMPLATE;
2998
3290
  var init_prompt2 = __esm({
2999
3291
  "src/subagents/designExpert/prompt.ts"() {
3000
3292
  "use strict";
3293
+ init_assets();
3001
3294
  init_context();
3002
- base3 = import.meta.dirname ?? path7.dirname(new URL(import.meta.url).pathname);
3003
- RUNTIME_PLACEHOLDERS = /* @__PURE__ */ new Set([
3004
- "fonts_to_consider",
3005
- "inspiration_images"
3006
- ]);
3007
- PROMPT_TEMPLATE = readFile("prompt.md").replace(/\{\{([^}]+)\}\}/g, (match, key) => {
3295
+ init_getFontLibrarySample();
3296
+ init_getDesignReferencesSample();
3297
+ SUBAGENT = "subagents/designExpert";
3298
+ RUNTIME_PLACEHOLDERS = /* @__PURE__ */ new Set(["font_library", "design_references"]);
3299
+ PROMPT_TEMPLATE = readAsset(SUBAGENT, "prompt.md").replace(/\{\{([^}]+)\}\}/g, (match, key) => {
3008
3300
  const k = key.trim();
3009
- return RUNTIME_PLACEHOLDERS.has(k) ? match : readFile(k);
3301
+ return RUNTIME_PLACEHOLDERS.has(k) ? match : readAsset(SUBAGENT, k);
3010
3302
  }).replace(/\n{3,}/g, "\n\n");
3011
- fontData = readJson("data/fonts.json", {
3012
- cssUrlPattern: "",
3013
- fonts: [],
3014
- pairings: []
3015
- });
3016
- inspirationImages = readJson("data/inspiration.json", {
3017
- images: []
3018
- }).images;
3019
3303
  }
3020
3304
  });
3021
3305
 
@@ -3039,7 +3323,7 @@ Visual design expert. Describe the situation and what you need \u2014 the agent
3039
3323
  properties: {
3040
3324
  task: {
3041
3325
  type: "string",
3042
- description: "What you need, in natural language. Include context about the app when relevant."
3326
+ description: "What you need, in natural language. Include context about the project when relevant."
3043
3327
  }
3044
3328
  },
3045
3329
  required: ["task"]
@@ -3054,7 +3338,7 @@ Visual design expert. Describe the situation and what you need \u2014 the agent
3054
3338
  task: input.task,
3055
3339
  tools: DESIGN_EXPERT_TOOLS,
3056
3340
  externalTools: /* @__PURE__ */ new Set(),
3057
- executeTool: (name, input2, toolCallId) => executeDesignExpertTool(name, input2, context, toolCallId),
3341
+ executeTool: (name, input2, toolCallId, onLog) => executeDesignExpertTool(name, input2, context, toolCallId, onLog),
3058
3342
  apiConfig: context.apiConfig,
3059
3343
  model: context.model,
3060
3344
  subAgentId: "visualDesignExpert",
@@ -3176,7 +3460,7 @@ var init_tools3 = __esm({
3176
3460
 
3177
3461
  // src/subagents/productVision/executor.ts
3178
3462
  import fs14 from "fs";
3179
- import path8 from "path";
3463
+ import path6 from "path";
3180
3464
  function formatRequires(requires) {
3181
3465
  return requires.length === 0 ? "[]" : `[${requires.map((r) => `"${r}"`).join(", ")}]`;
3182
3466
  }
@@ -3191,7 +3475,7 @@ async function executeVisionTool(name, input) {
3191
3475
  requires,
3192
3476
  body
3193
3477
  } = input;
3194
- const filePath = path8.join(ROADMAP_DIR, `${slug}.md`);
3478
+ const filePath = path6.join(ROADMAP_DIR, `${slug}.md`);
3195
3479
  try {
3196
3480
  fs14.mkdirSync(ROADMAP_DIR, { recursive: true });
3197
3481
  const oldContent = fs14.existsSync(filePath) ? fs14.readFileSync(filePath, "utf-8") : "";
@@ -3217,7 +3501,7 @@ ${unifiedDiff(filePath, oldContent, content)}`;
3217
3501
  }
3218
3502
  case "updateRoadmapItem": {
3219
3503
  const { slug } = input;
3220
- const filePath = path8.join(ROADMAP_DIR, `${slug}.md`);
3504
+ const filePath = path6.join(ROADMAP_DIR, `${slug}.md`);
3221
3505
  try {
3222
3506
  if (!fs14.existsSync(filePath)) {
3223
3507
  return `Error: ${filePath} does not exist`;
@@ -3285,7 +3569,7 @@ ${unifiedDiff(filePath, oldContent, content)}`;
3285
3569
  }
3286
3570
  case "deleteRoadmapItem": {
3287
3571
  const { slug } = input;
3288
- const filePath = path8.join(ROADMAP_DIR, `${slug}.md`);
3572
+ const filePath = path6.join(ROADMAP_DIR, `${slug}.md`);
3289
3573
  try {
3290
3574
  if (!fs14.existsSync(filePath)) {
3291
3575
  return `Error: ${filePath} does not exist`;
@@ -3313,8 +3597,6 @@ var init_executor = __esm({
3313
3597
  });
3314
3598
 
3315
3599
  // src/subagents/productVision/prompt.ts
3316
- import fs15 from "fs";
3317
- import path9 from "path";
3318
3600
  function getProductVisionPrompt() {
3319
3601
  const specContext = loadSpecContext();
3320
3602
  const roadmapContext = loadRoadmapContext();
@@ -3327,16 +3609,14 @@ function getProductVisionPrompt() {
3327
3609
  }
3328
3610
  return parts.join("\n\n");
3329
3611
  }
3330
- var base4, local2, PROMPT_PATH2, BASE_PROMPT2;
3612
+ var BASE_PROMPT2;
3331
3613
  var init_prompt3 = __esm({
3332
3614
  "src/subagents/productVision/prompt.ts"() {
3333
3615
  "use strict";
3616
+ init_assets();
3334
3617
  init_executor();
3335
3618
  init_context();
3336
- base4 = import.meta.dirname ?? path9.dirname(new URL(import.meta.url).pathname);
3337
- local2 = path9.join(base4, "prompt.md");
3338
- PROMPT_PATH2 = fs15.existsSync(local2) ? local2 : path9.join(base4, "subagents", "productVision", "prompt.md");
3339
- BASE_PROMPT2 = fs15.readFileSync(PROMPT_PATH2, "utf-8").trim();
3619
+ BASE_PROMPT2 = readAsset("subagents/productVision", "prompt.md");
3340
3620
  }
3341
3621
  });
3342
3622
 
@@ -3487,20 +3767,16 @@ var init_tools4 = __esm({
3487
3767
  });
3488
3768
 
3489
3769
  // src/subagents/codeSanityCheck/index.ts
3490
- import fs16 from "fs";
3491
- import path10 from "path";
3492
- var base5, local3, PROMPT_PATH3, BASE_PROMPT3, codeSanityCheckTool;
3770
+ var BASE_PROMPT3, codeSanityCheckTool;
3493
3771
  var init_codeSanityCheck = __esm({
3494
3772
  "src/subagents/codeSanityCheck/index.ts"() {
3495
3773
  "use strict";
3774
+ init_assets();
3496
3775
  init_runner();
3497
3776
  init_context();
3498
3777
  init_tools5();
3499
3778
  init_tools4();
3500
- base5 = import.meta.dirname ?? path10.dirname(new URL(import.meta.url).pathname);
3501
- local3 = path10.join(base5, "prompt.md");
3502
- PROMPT_PATH3 = fs16.existsSync(local3) ? local3 : path10.join(base5, "subagents", "codeSanityCheck", "prompt.md");
3503
- BASE_PROMPT3 = fs16.readFileSync(PROMPT_PATH3, "utf-8").trim();
3779
+ BASE_PROMPT3 = readAsset("subagents/codeSanityCheck", "prompt.md");
3504
3780
  codeSanityCheckTool = {
3505
3781
  definition: {
3506
3782
  name: "codeSanityCheck",
@@ -3552,7 +3828,7 @@ function getSpecTools() {
3552
3828
  return [readSpecTool, writeSpecTool, editSpecTool, listSpecFilesTool];
3553
3829
  }
3554
3830
  function getCodeTools() {
3555
- const tools = [
3831
+ const tools2 = [
3556
3832
  readFileTool,
3557
3833
  writeFileTool,
3558
3834
  editFileTool,
@@ -3567,9 +3843,9 @@ function getCodeTools() {
3567
3843
  browserAutomationTool
3568
3844
  ];
3569
3845
  if (isLspConfigured()) {
3570
- tools.push(lspDiagnosticsTool, restartProcessTool);
3846
+ tools2.push(lspDiagnosticsTool, restartProcessTool);
3571
3847
  }
3572
- return tools;
3848
+ return tools2;
3573
3849
  }
3574
3850
  function getCommonTools() {
3575
3851
  return [
@@ -3667,10 +3943,10 @@ var init_tools5 = __esm({
3667
3943
  });
3668
3944
 
3669
3945
  // src/session.ts
3670
- import fs17 from "fs";
3946
+ import fs15 from "fs";
3671
3947
  function loadSession(state) {
3672
3948
  try {
3673
- const raw = fs17.readFileSync(SESSION_FILE, "utf-8");
3949
+ const raw = fs15.readFileSync(SESSION_FILE, "utf-8");
3674
3950
  const data = JSON.parse(raw);
3675
3951
  if (Array.isArray(data.messages) && data.messages.length > 0) {
3676
3952
  state.messages = sanitizeMessages(data.messages);
@@ -3718,7 +3994,7 @@ function sanitizeMessages(messages) {
3718
3994
  }
3719
3995
  function saveSession(state) {
3720
3996
  try {
3721
- fs17.writeFileSync(
3997
+ fs15.writeFileSync(
3722
3998
  SESSION_FILE,
3723
3999
  JSON.stringify({ messages: state.messages }, null, 2),
3724
4000
  "utf-8"
@@ -3729,7 +4005,7 @@ function saveSession(state) {
3729
4005
  function clearSession(state) {
3730
4006
  state.messages = [];
3731
4007
  try {
3732
- fs17.unlinkSync(SESSION_FILE);
4008
+ fs15.unlinkSync(SESSION_FILE);
3733
4009
  } catch {
3734
4010
  }
3735
4011
  }
@@ -4053,11 +4329,11 @@ async function runTurn(params) {
4053
4329
  resolveExternalTool,
4054
4330
  hidden
4055
4331
  } = params;
4056
- const tools = getToolDefinitions(onboardingState);
4332
+ const tools2 = getToolDefinitions(onboardingState);
4057
4333
  log.info("Turn started", {
4058
4334
  messageLength: userMessage.length,
4059
- toolCount: tools.length,
4060
- tools: tools.map((t) => t.name),
4335
+ toolCount: tools2.length,
4336
+ tools: tools2.map((t) => t.name),
4061
4337
  ...attachments && attachments.length > 0 && {
4062
4338
  attachmentCount: attachments.length,
4063
4339
  attachmentUrls: attachments.map((a) => a.url)
@@ -4186,7 +4462,7 @@ async function runTurn(params) {
4186
4462
  model,
4187
4463
  system,
4188
4464
  messages: cleanMessagesForApi(state.messages),
4189
- tools,
4465
+ tools: tools2,
4190
4466
  signal
4191
4467
  },
4192
4468
  {
@@ -4384,7 +4660,13 @@ async function runTurn(params) {
4384
4660
  onEvent: wrappedOnEvent,
4385
4661
  resolveExternalTool,
4386
4662
  toolCallId: tc.id,
4387
- subAgentMessages
4663
+ subAgentMessages,
4664
+ onLog: (line) => wrappedOnEvent({
4665
+ type: "tool_input_delta",
4666
+ id: tc.id,
4667
+ name: tc.name,
4668
+ result: line
4669
+ })
4388
4670
  });
4389
4671
  }
4390
4672
  const isError = result.startsWith("Error");
@@ -4475,12 +4757,12 @@ var init_agent = __esm({
4475
4757
  });
4476
4758
 
4477
4759
  // src/prompt/static/projectContext.ts
4478
- import fs18 from "fs";
4479
- import path11 from "path";
4760
+ import fs16 from "fs";
4761
+ import path7 from "path";
4480
4762
  function loadProjectInstructions() {
4481
4763
  for (const file of AGENT_INSTRUCTION_FILES) {
4482
4764
  try {
4483
- const content = fs18.readFileSync(file, "utf-8").trim();
4765
+ const content = fs16.readFileSync(file, "utf-8").trim();
4484
4766
  if (content) {
4485
4767
  return `
4486
4768
  ## Project Instructions (${file})
@@ -4493,7 +4775,7 @@ ${content}`;
4493
4775
  }
4494
4776
  function loadProjectManifest() {
4495
4777
  try {
4496
- const manifest = fs18.readFileSync("mindstudio.json", "utf-8");
4778
+ const manifest = fs16.readFileSync("mindstudio.json", "utf-8");
4497
4779
  return `
4498
4780
  ## Project Manifest (mindstudio.json)
4499
4781
  \`\`\`json
@@ -4534,9 +4816,9 @@ ${entries.join("\n")}`;
4534
4816
  function walkMdFiles2(dir) {
4535
4817
  const results = [];
4536
4818
  try {
4537
- const entries = fs18.readdirSync(dir, { withFileTypes: true });
4819
+ const entries = fs16.readdirSync(dir, { withFileTypes: true });
4538
4820
  for (const entry of entries) {
4539
- const full = path11.join(dir, entry.name);
4821
+ const full = path7.join(dir, entry.name);
4540
4822
  if (entry.isDirectory()) {
4541
4823
  results.push(...walkMdFiles2(full));
4542
4824
  } else if (entry.name.endsWith(".md")) {
@@ -4549,7 +4831,7 @@ function walkMdFiles2(dir) {
4549
4831
  }
4550
4832
  function parseFrontmatter(filePath) {
4551
4833
  try {
4552
- const content = fs18.readFileSync(filePath, "utf-8");
4834
+ const content = fs16.readFileSync(filePath, "utf-8");
4553
4835
  const match = content.match(/^---\n([\s\S]*?)\n---/);
4554
4836
  if (!match) {
4555
4837
  return { name: "", description: "", type: "" };
@@ -4565,7 +4847,7 @@ function parseFrontmatter(filePath) {
4565
4847
  }
4566
4848
  function loadProjectFileListing() {
4567
4849
  try {
4568
- const entries = fs18.readdirSync(".", { withFileTypes: true });
4850
+ const entries = fs16.readdirSync(".", { withFileTypes: true });
4569
4851
  const listing = entries.filter((e) => e.name !== ".git" && e.name !== "node_modules").sort((a, b) => {
4570
4852
  if (a.isDirectory() && !b.isDirectory()) {
4571
4853
  return -1;
@@ -4608,20 +4890,10 @@ var init_projectContext = __esm({
4608
4890
  });
4609
4891
 
4610
4892
  // src/prompt/index.ts
4611
- import fs19 from "fs";
4612
- import path12 from "path";
4613
- function requireFile(filePath) {
4614
- const full = path12.join(PROMPT_DIR, filePath);
4615
- try {
4616
- return fs19.readFileSync(full, "utf-8").trim();
4617
- } catch {
4618
- throw new Error(`Required prompt file missing: ${full}`);
4619
- }
4620
- }
4621
4893
  function resolveIncludes(template) {
4622
4894
  const result = template.replace(
4623
4895
  /\{\{([^}]+)\}\}/g,
4624
- (_, filePath) => requireFile(filePath.trim())
4896
+ (_, filePath) => readAsset("prompt", filePath.trim())
4625
4897
  );
4626
4898
  return result.replace(/\n{3,}/g, "\n\n").trim();
4627
4899
  }
@@ -4731,23 +5003,22 @@ ${viewContext?.activeFile ? `Active file: ${viewContext.activeFile}` : ""}
4731
5003
  `;
4732
5004
  return resolveIncludes(template);
4733
5005
  }
4734
- var PROMPT_DIR;
4735
5006
  var init_prompt4 = __esm({
4736
5007
  "src/prompt/index.ts"() {
4737
5008
  "use strict";
5009
+ init_assets();
4738
5010
  init_lsp();
4739
5011
  init_projectContext();
4740
- PROMPT_DIR = import.meta.dirname ?? path12.dirname(new URL(import.meta.url).pathname);
4741
5012
  }
4742
5013
  });
4743
5014
 
4744
5015
  // src/config.ts
4745
- import fs20 from "fs";
4746
- import path13 from "path";
5016
+ import fs17 from "fs";
5017
+ import path8 from "path";
4747
5018
  import os from "os";
4748
5019
  function loadConfigFile() {
4749
5020
  try {
4750
- const raw = fs20.readFileSync(CONFIG_PATH, "utf-8");
5021
+ const raw = fs17.readFileSync(CONFIG_PATH, "utf-8");
4751
5022
  log.debug("Loaded config file", { path: CONFIG_PATH });
4752
5023
  return JSON.parse(raw);
4753
5024
  } catch (err) {
@@ -4783,7 +5054,7 @@ var init_config = __esm({
4783
5054
  "src/config.ts"() {
4784
5055
  "use strict";
4785
5056
  init_logger();
4786
- CONFIG_PATH = path13.join(
5057
+ CONFIG_PATH = path8.join(
4787
5058
  os.homedir(),
4788
5059
  ".mindstudio-local-tunnel",
4789
5060
  "config.json"
@@ -4798,10 +5069,8 @@ __export(headless_exports, {
4798
5069
  startHeadless: () => startHeadless
4799
5070
  });
4800
5071
  import { createInterface } from "readline";
4801
- import fs21 from "fs";
4802
- import path14 from "path";
4803
5072
  function loadActionPrompt(name) {
4804
- return fs21.readFileSync(path14.join(ACTIONS_DIR, `${name}.md`), "utf-8").trim();
5073
+ return readAsset("prompt", "actions", `${name}.md`);
4805
5074
  }
4806
5075
  function emit(event, data, requestId) {
4807
5076
  const payload = { event, ...data };
@@ -5107,25 +5376,23 @@ async function startHeadless(opts = {}) {
5107
5376
  process.on("SIGINT", shutdown);
5108
5377
  emit("ready");
5109
5378
  }
5110
- var BASE_DIR, ACTIONS_DIR;
5111
5379
  var init_headless = __esm({
5112
5380
  "src/headless.ts"() {
5113
5381
  "use strict";
5382
+ init_assets();
5114
5383
  init_config();
5115
5384
  init_prompt4();
5116
5385
  init_lsp();
5117
5386
  init_agent();
5118
5387
  init_session();
5119
- BASE_DIR = import.meta.dirname ?? path14.dirname(new URL(import.meta.url).pathname);
5120
- ACTIONS_DIR = path14.join(BASE_DIR, "actions");
5121
5388
  }
5122
5389
  });
5123
5390
 
5124
5391
  // src/index.tsx
5125
5392
  import { render } from "ink";
5126
5393
  import os2 from "os";
5127
- import fs22 from "fs";
5128
- import path15 from "path";
5394
+ import fs18 from "fs";
5395
+ import path9 from "path";
5129
5396
 
5130
5397
  // src/tui/App.tsx
5131
5398
  import { useState as useState2, useCallback, useRef } from "react";
@@ -5442,8 +5709,8 @@ for (let i = 0; i < args.length; i++) {
5442
5709
  }
5443
5710
  function printDebugInfo(config) {
5444
5711
  const pkg = JSON.parse(
5445
- fs22.readFileSync(
5446
- path15.join(import.meta.dirname, "..", "package.json"),
5712
+ fs18.readFileSync(
5713
+ path9.join(import.meta.dirname, "..", "package.json"),
5447
5714
  "utf-8"
5448
5715
  )
5449
5716
  );