@mindstudio-ai/remy 0.1.229 → 0.1.231
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/headless.js +130 -71
- package/dist/index.js +133 -72
- package/package.json +1 -1
package/dist/headless.js
CHANGED
|
@@ -682,11 +682,17 @@ function parseFrontmatter(filePath) {
|
|
|
682
682
|
return { name: "", description: "", type: "" };
|
|
683
683
|
}
|
|
684
684
|
}
|
|
685
|
-
function loadPlanStatus() {
|
|
685
|
+
function loadPlanStatus(onboardingState) {
|
|
686
686
|
try {
|
|
687
687
|
const content = fs4.readFileSync(".remy-plan.md", "utf-8");
|
|
688
688
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
689
689
|
const status = match?.[1]?.match(/^status:\s*(.+)$/m)?.[1]?.trim();
|
|
690
|
+
if (status === "pending" && onboardingState === "intake") {
|
|
691
|
+
return `
|
|
692
|
+
<pending_initial_plan>
|
|
693
|
+
This is your initial plan, proposed via writePlan and awaiting the user's decision. The user approves it by pressing "Start Building" \u2014 you'll get an approveInitialPlan message when they do, and it will tell you to begin. Until then, stay in intake: keep discussing, and revise with writePlan if the user asks. Don't start building on your own, even if the user says "looks good" in chat.
|
|
694
|
+
</pending_initial_plan>`;
|
|
695
|
+
}
|
|
690
696
|
if (status === "pending") {
|
|
691
697
|
return `
|
|
692
698
|
<pending_plan>
|
|
@@ -868,7 +874,7 @@ The user is currently in ${viewContext?.mode ?? "code"} mode.
|
|
|
868
874
|
${viewContext?.activeFile ? `Active file: ${viewContext.activeFile}` : ""}
|
|
869
875
|
</view_context>
|
|
870
876
|
|
|
871
|
-
${loadPlanStatus()}
|
|
877
|
+
${loadPlanStatus(onboardingState)}
|
|
872
878
|
`;
|
|
873
879
|
return resolveIncludes(template);
|
|
874
880
|
}
|
|
@@ -1379,8 +1385,11 @@ var updatePlanStatusTool = {
|
|
|
1379
1385
|
required: ["status"]
|
|
1380
1386
|
}
|
|
1381
1387
|
},
|
|
1382
|
-
async execute(input) {
|
|
1388
|
+
async execute(input, context) {
|
|
1383
1389
|
const status = input.status;
|
|
1390
|
+
if (context?.onboardingState === "intake") {
|
|
1391
|
+
return `The initial plan isn't approved or rejected through this tool \u2014 the user decides via "Start Building". Keep discussing, and revise the plan with writePlan if they want changes.`;
|
|
1392
|
+
}
|
|
1384
1393
|
let content;
|
|
1385
1394
|
try {
|
|
1386
1395
|
content = await fs10.readFile(PLAN_FILE2, "utf-8");
|
|
@@ -5113,6 +5122,50 @@ ${summaryText}
|
|
|
5113
5122
|
var DESCRIPTION = `
|
|
5114
5123
|
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.
|
|
5115
5124
|
`.trim();
|
|
5125
|
+
var RENDER_WRITE_TOOL_NAMES = /* @__PURE__ */ new Set(["writeFile", "editFile"]);
|
|
5126
|
+
var DESIGN_EXPERT_RENDER_TOOLS = [
|
|
5127
|
+
...DESIGN_EXPERT_TOOLS,
|
|
5128
|
+
writeFileTool.definition,
|
|
5129
|
+
editFileTool.definition
|
|
5130
|
+
];
|
|
5131
|
+
async function runDesignExpert(opts, context) {
|
|
5132
|
+
const history = context.conversationMessages ? getSubAgentHistory(context.conversationMessages, "visualDesignExpert") : [];
|
|
5133
|
+
return runSubAgent({
|
|
5134
|
+
system: getDesignExpertPrompt(context.onboardingState),
|
|
5135
|
+
task: opts.task,
|
|
5136
|
+
history: history.length > 0 ? history : void 0,
|
|
5137
|
+
tools: opts.enableWrite ? DESIGN_EXPERT_RENDER_TOOLS : DESIGN_EXPERT_TOOLS,
|
|
5138
|
+
externalTools: /* @__PURE__ */ new Set(),
|
|
5139
|
+
executeTool: (name, input, toolCallId, onLog, sams) => {
|
|
5140
|
+
const childCtx = toolCallId ? { ...deriveContext(context, toolCallId), subAgentMessages: sams } : { ...context, subAgentMessages: sams };
|
|
5141
|
+
if (COMMON_READ_TOOL_NAMES.has(name)) {
|
|
5142
|
+
return executeTool(name, input, childCtx);
|
|
5143
|
+
}
|
|
5144
|
+
if (opts.enableWrite && RENDER_WRITE_TOOL_NAMES.has(name)) {
|
|
5145
|
+
return executeTool(name, input, childCtx);
|
|
5146
|
+
}
|
|
5147
|
+
return executeDesignExpertTool(name, input, childCtx, toolCallId, onLog);
|
|
5148
|
+
},
|
|
5149
|
+
apiConfig: context.apiConfig,
|
|
5150
|
+
model: resolveModel("visualDesignExpert", context.models, context.model),
|
|
5151
|
+
subAgentId: "visualDesignExpert",
|
|
5152
|
+
signal: context.signal,
|
|
5153
|
+
parentToolId: context.toolCallId,
|
|
5154
|
+
requestId: context.requestId,
|
|
5155
|
+
onEvent: context.onEvent,
|
|
5156
|
+
resolveExternalTool: context.resolveExternalTool,
|
|
5157
|
+
toolRegistry: context.toolRegistry,
|
|
5158
|
+
background: opts.background,
|
|
5159
|
+
onBackgroundComplete: opts.background ? (bgResult) => {
|
|
5160
|
+
context.onBackgroundComplete?.(
|
|
5161
|
+
context.toolCallId,
|
|
5162
|
+
opts.reportingName ?? "visualDesignExpert",
|
|
5163
|
+
bgResult.text,
|
|
5164
|
+
bgResult.messages
|
|
5165
|
+
);
|
|
5166
|
+
} : void 0
|
|
5167
|
+
});
|
|
5168
|
+
}
|
|
5116
5169
|
var designExpertTool = {
|
|
5117
5170
|
clearable: false,
|
|
5118
5171
|
definition: {
|
|
@@ -5137,49 +5190,20 @@ var designExpertTool = {
|
|
|
5137
5190
|
if (!context) {
|
|
5138
5191
|
return "Error: visual design expert requires execution context";
|
|
5139
5192
|
}
|
|
5140
|
-
const
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
history: history.length > 0 ? history : void 0,
|
|
5145
|
-
tools: DESIGN_EXPERT_TOOLS,
|
|
5146
|
-
externalTools: /* @__PURE__ */ new Set(),
|
|
5147
|
-
executeTool: (name, input2, toolCallId, onLog, sams) => {
|
|
5148
|
-
const childCtx = toolCallId ? { ...deriveContext(context, toolCallId), subAgentMessages: sams } : { ...context, subAgentMessages: sams };
|
|
5149
|
-
if (COMMON_READ_TOOL_NAMES.has(name)) {
|
|
5150
|
-
return executeTool(name, input2, childCtx);
|
|
5151
|
-
}
|
|
5152
|
-
return executeDesignExpertTool(
|
|
5153
|
-
name,
|
|
5154
|
-
input2,
|
|
5155
|
-
childCtx,
|
|
5156
|
-
toolCallId,
|
|
5157
|
-
onLog
|
|
5158
|
-
);
|
|
5193
|
+
const result = await runDesignExpert(
|
|
5194
|
+
{
|
|
5195
|
+
task: input.task,
|
|
5196
|
+
background: input.background
|
|
5159
5197
|
},
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
subAgentId: "visualDesignExpert",
|
|
5163
|
-
signal: context.signal,
|
|
5164
|
-
parentToolId: context.toolCallId,
|
|
5165
|
-
requestId: context.requestId,
|
|
5166
|
-
onEvent: context.onEvent,
|
|
5167
|
-
resolveExternalTool: context.resolveExternalTool,
|
|
5168
|
-
toolRegistry: context.toolRegistry,
|
|
5169
|
-
background: input.background,
|
|
5170
|
-
onBackgroundComplete: input.background ? (bgResult) => {
|
|
5171
|
-
context.onBackgroundComplete?.(
|
|
5172
|
-
context.toolCallId,
|
|
5173
|
-
"visualDesignExpert",
|
|
5174
|
-
bgResult.text,
|
|
5175
|
-
bgResult.messages
|
|
5176
|
-
);
|
|
5177
|
-
} : void 0
|
|
5178
|
-
});
|
|
5198
|
+
context
|
|
5199
|
+
);
|
|
5179
5200
|
context.subAgentMessages?.set(context.toolCallId, result.messages);
|
|
5180
5201
|
return result.text;
|
|
5181
5202
|
}
|
|
5182
5203
|
};
|
|
5204
|
+
async function runDesignExpertRender(opts, context) {
|
|
5205
|
+
return runDesignExpert({ ...opts, enableWrite: true }, context);
|
|
5206
|
+
}
|
|
5183
5207
|
|
|
5184
5208
|
// src/subagents/productVision/tools.ts
|
|
5185
5209
|
var VISION_TOOLS = [
|
|
@@ -5284,16 +5308,25 @@ ${unifiedDiff(filePath, oldContent, "")}`;
|
|
|
5284
5308
|
const filePath = resolve("pitch.html");
|
|
5285
5309
|
try {
|
|
5286
5310
|
fs19.mkdirSync(ROADMAP_DIR, { recursive: true });
|
|
5287
|
-
const
|
|
5288
|
-
const
|
|
5311
|
+
const exists = fs19.existsSync(filePath);
|
|
5312
|
+
const before = exists ? fs19.statSync(filePath).mtimeMs : null;
|
|
5313
|
+
const delivery = exists ? `### Your deliverable
|
|
5314
|
+
The pitch deck already exists at \`${filePath}\`. Read it, then update it for the new <pitch_content>, keeping the presentation scaffolding intact \u2014 change only what needs to change.
|
|
5315
|
+
|
|
5316
|
+
Reply with a one-line summary of what you changed \u2014 not the HTML.` : `### Your deliverable
|
|
5317
|
+
Write the complete pitch deck to \`${filePath}\`. It does not exist yet \u2014 start from this scaffold, keeping its progress bar, chevron navigation, keyboard navigation, and transition mechanics intact:
|
|
5318
|
+
|
|
5319
|
+
<pitch_deck_shell>
|
|
5320
|
+
${PITCH_DECK_SHELL}
|
|
5321
|
+
</pitch_deck_shell>
|
|
5322
|
+
|
|
5323
|
+
Reply with a one-line summary of what you wrote \u2014 not the HTML.`;
|
|
5289
5324
|
const task = `
|
|
5290
5325
|
<pitch_content>${input.task}</pitch_content>
|
|
5291
5326
|
|
|
5292
|
-
<current_deck>${currentDeck}</current_deck>
|
|
5293
|
-
|
|
5294
5327
|
We are building the pitch deck for the app. Using the provided <pitch_content>, as well as the app's spec data, think about what would make a compelling, interactive, self-contained horizontally-scrolling HTML slide deck for this product. Keep it simple, clean, powerful. Giant text, large logo, big, bold stats and claims. Edit the content as necessary to create the most impactful, bold, and beautiful slides. This should not feel like an essay, and it should not feel like a landing page \u2014 it should feel like a modern interactive presentation that leaves the user wowed by the product and excited about its future.
|
|
5295
5328
|
|
|
5296
|
-
|
|
5329
|
+
Maintain the bones of the presentation scaffolding. Always keep the progress bar, chevron navigation, and keyboard navigation - they are part of the scaffold.
|
|
5297
5330
|
|
|
5298
5331
|
### Rules
|
|
5299
5332
|
- The deck must be a single HTML file \u2014 it will be rendered in an iframe.
|
|
@@ -5303,14 +5336,18 @@ Use <current_deck> as your starting point and replace or update the content as n
|
|
|
5303
5336
|
- Code must be clean, bug free, and easy to parse. Use GSAP for animations. Pay close attention to layout and alignment to make sure everything is perfect.
|
|
5304
5337
|
- Keep the progress bar and edge chevrons from the shell \u2014 they are part of the navigation UX.
|
|
5305
5338
|
|
|
5306
|
-
|
|
5307
|
-
const result = await
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5339
|
+
${delivery}`;
|
|
5340
|
+
const result = await runDesignExpertRender({ task }, context);
|
|
5341
|
+
context.subAgentMessages?.set(context.toolCallId, result.messages);
|
|
5342
|
+
if (!fs19.existsSync(filePath)) {
|
|
5343
|
+
return `Error: the design expert did not write ${filePath}. Its reply was:
|
|
5344
|
+
${result.text}`;
|
|
5345
|
+
}
|
|
5346
|
+
if (before !== null && fs19.statSync(filePath).mtimeMs === before) {
|
|
5347
|
+
return `Error: the pitch deck at ${filePath} was not modified. The design expert's reply was:
|
|
5348
|
+
${result.text}`;
|
|
5349
|
+
}
|
|
5350
|
+
return `Pitch deck written to ${filePath}. ${result.text}`;
|
|
5314
5351
|
} catch (err) {
|
|
5315
5352
|
return `Error generating pitch deck: ${err.message}`;
|
|
5316
5353
|
}
|
|
@@ -5544,7 +5581,7 @@ import fs20 from "fs";
|
|
|
5544
5581
|
var OVERVIEW_FILE = "src/overview.html";
|
|
5545
5582
|
var DESIGN_BRIEF = `We are building the Build Overview for this app \u2014 the home page of its Spec tab. It is a calm, dense, one-page reference of everything the app actually contains, including the parts the user can't see. It renders flush inside the Spec tab's content panel (the IDE supplies the surrounding nav).
|
|
5546
5583
|
|
|
5547
|
-
Take the plain-language copy in <overview_copy> and lay it out and skin it into a single, beautiful, self-contained HTML document in the app's own brand.
|
|
5584
|
+
Take the plain-language copy in <overview_copy> and lay it out and skin it into a single, beautiful, self-contained HTML document in the app's own brand.
|
|
5548
5585
|
|
|
5549
5586
|
### The single hard rule
|
|
5550
5587
|
The copy in <overview_copy> is final \u2014 it was authored and edited before it reached you. Treat it as locked content to typeset, not a draft to improve. Reproduce the words exactly: do not rewrite, rephrase, shorten, expand, reorder, or "polish" them, and do not run them through any copy tool. This is the opposite of your usual role \u2014 here you own layout, typography, and visual design only, and the words (every number, name, label, claim, and sentence) are fixed. A single changed word or wrong number breaks this document's purpose.
|
|
@@ -5559,9 +5596,7 @@ The copy in <overview_copy> is final \u2014 it was authored and edited before it
|
|
|
5559
5596
|
|
|
5560
5597
|
### Constraints
|
|
5561
5598
|
- A single self-contained HTML file. Fonts may load from a CDN; everything else (CSS, the logo SVG) is inline.
|
|
5562
|
-
- Responsive: fills the embedded panel width and collapses gracefully at narrow widths
|
|
5563
|
-
|
|
5564
|
-
Respond only with the complete HTML file and absolutely no other text. Your response will be written directly to src/overview.html.`;
|
|
5599
|
+
- Responsive: fills the embedded panel width and collapses gracefully at narrow widths.`;
|
|
5565
5600
|
var OVERVIEW_SHELL = `<!DOCTYPE html>
|
|
5566
5601
|
<html lang="en">
|
|
5567
5602
|
<head>
|
|
@@ -5582,6 +5617,22 @@ var OVERVIEW_SHELL = `<!DOCTYPE html>
|
|
|
5582
5617
|
app's spec. -->
|
|
5583
5618
|
</body>
|
|
5584
5619
|
</html>`;
|
|
5620
|
+
function initialDelivery() {
|
|
5621
|
+
return `### Your deliverable
|
|
5622
|
+
Write the complete Build Overview to \`${OVERVIEW_FILE}\`. The file does not exist yet \u2014 start from this scaffold, which carries the technical hygiene for the iframed render context (keep the viewport meta and the reset). Layout, sections, type, and styling are yours to compose.
|
|
5623
|
+
|
|
5624
|
+
<overview_shell>
|
|
5625
|
+
${OVERVIEW_SHELL}
|
|
5626
|
+
</overview_shell>
|
|
5627
|
+
|
|
5628
|
+
Reply with a one-line summary of what you wrote \u2014 not the HTML.`;
|
|
5629
|
+
}
|
|
5630
|
+
function refreshDelivery() {
|
|
5631
|
+
return `### Your deliverable
|
|
5632
|
+
The Build Overview already exists at \`${OVERVIEW_FILE}\`. Read it, then update it to reflect <overview_copy>, preserving its established skin \u2014 change only what the copy changed.
|
|
5633
|
+
|
|
5634
|
+
Reply with a one-line summary of what you changed \u2014 not the HTML.`;
|
|
5635
|
+
}
|
|
5585
5636
|
var buildOverviewTool = {
|
|
5586
5637
|
clearable: false,
|
|
5587
5638
|
definition: {
|
|
@@ -5606,21 +5657,29 @@ var buildOverviewTool = {
|
|
|
5606
5657
|
if (!content) {
|
|
5607
5658
|
return "Error: writeBuildOverview requires non-empty `content` (the overview copy).";
|
|
5608
5659
|
}
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
const currentOverview = existing || OVERVIEW_SHELL;
|
|
5612
|
-
const task = `<overview_copy>${content}</overview_copy>
|
|
5660
|
+
const exists = fs20.existsSync(OVERVIEW_FILE);
|
|
5661
|
+
const task = `<overview_copy>${content}</overview_copy>
|
|
5613
5662
|
|
|
5614
|
-
|
|
5663
|
+
${DESIGN_BRIEF}
|
|
5615
5664
|
|
|
5616
|
-
${
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5665
|
+
${exists ? refreshDelivery() : initialDelivery()}`;
|
|
5666
|
+
try {
|
|
5667
|
+
if (exists) {
|
|
5668
|
+
input.background = true;
|
|
5669
|
+
const result2 = await runDesignExpertRender(
|
|
5670
|
+
{ task, background: true, reportingName: "writeBuildOverview" },
|
|
5671
|
+
context
|
|
5672
|
+
);
|
|
5673
|
+
context.subAgentMessages?.set(context.toolCallId, result2.messages);
|
|
5674
|
+
return result2.text;
|
|
5675
|
+
}
|
|
5676
|
+
const result = await runDesignExpertRender({ task }, context);
|
|
5677
|
+
context.subAgentMessages?.set(context.toolCallId, result.messages);
|
|
5678
|
+
if (!fs20.existsSync(OVERVIEW_FILE)) {
|
|
5679
|
+
return `Error: the design expert did not write ${OVERVIEW_FILE}. Its reply was:
|
|
5680
|
+
${result.text}`;
|
|
5681
|
+
}
|
|
5682
|
+
return `Build overview written to ${OVERVIEW_FILE}. ${result.text}`;
|
|
5624
5683
|
} catch (err) {
|
|
5625
5684
|
return `Error generating build overview: ${err.message}`;
|
|
5626
5685
|
}
|
package/dist/index.js
CHANGED
|
@@ -938,8 +938,11 @@ var init_updatePlanStatus = __esm({
|
|
|
938
938
|
required: ["status"]
|
|
939
939
|
}
|
|
940
940
|
},
|
|
941
|
-
async execute(input) {
|
|
941
|
+
async execute(input, context) {
|
|
942
942
|
const status = input.status;
|
|
943
|
+
if (context?.onboardingState === "intake") {
|
|
944
|
+
return `The initial plan isn't approved or rejected through this tool \u2014 the user decides via "Start Building". Keep discussing, and revise the plan with writePlan if they want changes.`;
|
|
945
|
+
}
|
|
943
946
|
let content;
|
|
944
947
|
try {
|
|
945
948
|
content = await fs7.readFile(PLAN_FILE2, "utf-8");
|
|
@@ -1893,11 +1896,17 @@ function parseFrontmatter(filePath) {
|
|
|
1893
1896
|
return { name: "", description: "", type: "" };
|
|
1894
1897
|
}
|
|
1895
1898
|
}
|
|
1896
|
-
function loadPlanStatus() {
|
|
1899
|
+
function loadPlanStatus(onboardingState) {
|
|
1897
1900
|
try {
|
|
1898
1901
|
const content = fs10.readFileSync(".remy-plan.md", "utf-8");
|
|
1899
1902
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
1900
1903
|
const status = match?.[1]?.match(/^status:\s*(.+)$/m)?.[1]?.trim();
|
|
1904
|
+
if (status === "pending" && onboardingState === "intake") {
|
|
1905
|
+
return `
|
|
1906
|
+
<pending_initial_plan>
|
|
1907
|
+
This is your initial plan, proposed via writePlan and awaiting the user's decision. The user approves it by pressing "Start Building" \u2014 you'll get an approveInitialPlan message when they do, and it will tell you to begin. Until then, stay in intake: keep discussing, and revise with writePlan if the user asks. Don't start building on your own, even if the user says "looks good" in chat.
|
|
1908
|
+
</pending_initial_plan>`;
|
|
1909
|
+
}
|
|
1901
1910
|
if (status === "pending") {
|
|
1902
1911
|
return `
|
|
1903
1912
|
<pending_plan>
|
|
@@ -2292,7 +2301,7 @@ The user is currently in ${viewContext?.mode ?? "code"} mode.
|
|
|
2292
2301
|
${viewContext?.activeFile ? `Active file: ${viewContext.activeFile}` : ""}
|
|
2293
2302
|
</view_context>
|
|
2294
2303
|
|
|
2295
|
-
${loadPlanStatus()}
|
|
2304
|
+
${loadPlanStatus(onboardingState)}
|
|
2296
2305
|
`;
|
|
2297
2306
|
return resolveIncludes(template);
|
|
2298
2307
|
}
|
|
@@ -5979,7 +5988,48 @@ var init_history = __esm({
|
|
|
5979
5988
|
});
|
|
5980
5989
|
|
|
5981
5990
|
// src/subagents/designExpert/index.ts
|
|
5982
|
-
|
|
5991
|
+
async function runDesignExpert(opts, context) {
|
|
5992
|
+
const history = context.conversationMessages ? getSubAgentHistory(context.conversationMessages, "visualDesignExpert") : [];
|
|
5993
|
+
return runSubAgent({
|
|
5994
|
+
system: getDesignExpertPrompt(context.onboardingState),
|
|
5995
|
+
task: opts.task,
|
|
5996
|
+
history: history.length > 0 ? history : void 0,
|
|
5997
|
+
tools: opts.enableWrite ? DESIGN_EXPERT_RENDER_TOOLS : DESIGN_EXPERT_TOOLS,
|
|
5998
|
+
externalTools: /* @__PURE__ */ new Set(),
|
|
5999
|
+
executeTool: (name, input, toolCallId, onLog, sams) => {
|
|
6000
|
+
const childCtx = toolCallId ? { ...deriveContext(context, toolCallId), subAgentMessages: sams } : { ...context, subAgentMessages: sams };
|
|
6001
|
+
if (COMMON_READ_TOOL_NAMES.has(name)) {
|
|
6002
|
+
return executeTool(name, input, childCtx);
|
|
6003
|
+
}
|
|
6004
|
+
if (opts.enableWrite && RENDER_WRITE_TOOL_NAMES.has(name)) {
|
|
6005
|
+
return executeTool(name, input, childCtx);
|
|
6006
|
+
}
|
|
6007
|
+
return executeDesignExpertTool(name, input, childCtx, toolCallId, onLog);
|
|
6008
|
+
},
|
|
6009
|
+
apiConfig: context.apiConfig,
|
|
6010
|
+
model: resolveModel("visualDesignExpert", context.models, context.model),
|
|
6011
|
+
subAgentId: "visualDesignExpert",
|
|
6012
|
+
signal: context.signal,
|
|
6013
|
+
parentToolId: context.toolCallId,
|
|
6014
|
+
requestId: context.requestId,
|
|
6015
|
+
onEvent: context.onEvent,
|
|
6016
|
+
resolveExternalTool: context.resolveExternalTool,
|
|
6017
|
+
toolRegistry: context.toolRegistry,
|
|
6018
|
+
background: opts.background,
|
|
6019
|
+
onBackgroundComplete: opts.background ? (bgResult) => {
|
|
6020
|
+
context.onBackgroundComplete?.(
|
|
6021
|
+
context.toolCallId,
|
|
6022
|
+
opts.reportingName ?? "visualDesignExpert",
|
|
6023
|
+
bgResult.text,
|
|
6024
|
+
bgResult.messages
|
|
6025
|
+
);
|
|
6026
|
+
} : void 0
|
|
6027
|
+
});
|
|
6028
|
+
}
|
|
6029
|
+
async function runDesignExpertRender(opts, context) {
|
|
6030
|
+
return runDesignExpert({ ...opts, enableWrite: true }, context);
|
|
6031
|
+
}
|
|
6032
|
+
var DESCRIPTION, RENDER_WRITE_TOOL_NAMES, DESIGN_EXPERT_RENDER_TOOLS, designExpertTool;
|
|
5983
6033
|
var init_designExpert = __esm({
|
|
5984
6034
|
"src/subagents/designExpert/index.ts"() {
|
|
5985
6035
|
"use strict";
|
|
@@ -5990,9 +6040,17 @@ var init_designExpert = __esm({
|
|
|
5990
6040
|
init_prompt3();
|
|
5991
6041
|
init_history();
|
|
5992
6042
|
init_surfaces();
|
|
6043
|
+
init_writeFile();
|
|
6044
|
+
init_editFile();
|
|
5993
6045
|
DESCRIPTION = `
|
|
5994
6046
|
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.
|
|
5995
6047
|
`.trim();
|
|
6048
|
+
RENDER_WRITE_TOOL_NAMES = /* @__PURE__ */ new Set(["writeFile", "editFile"]);
|
|
6049
|
+
DESIGN_EXPERT_RENDER_TOOLS = [
|
|
6050
|
+
...DESIGN_EXPERT_TOOLS,
|
|
6051
|
+
writeFileTool.definition,
|
|
6052
|
+
editFileTool.definition
|
|
6053
|
+
];
|
|
5996
6054
|
designExpertTool = {
|
|
5997
6055
|
clearable: false,
|
|
5998
6056
|
definition: {
|
|
@@ -6017,45 +6075,13 @@ Visual design expert. Describe the situation and what you need \u2014 the agent
|
|
|
6017
6075
|
if (!context) {
|
|
6018
6076
|
return "Error: visual design expert requires execution context";
|
|
6019
6077
|
}
|
|
6020
|
-
const
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
history: history.length > 0 ? history : void 0,
|
|
6025
|
-
tools: DESIGN_EXPERT_TOOLS,
|
|
6026
|
-
externalTools: /* @__PURE__ */ new Set(),
|
|
6027
|
-
executeTool: (name, input2, toolCallId, onLog, sams) => {
|
|
6028
|
-
const childCtx = toolCallId ? { ...deriveContext(context, toolCallId), subAgentMessages: sams } : { ...context, subAgentMessages: sams };
|
|
6029
|
-
if (COMMON_READ_TOOL_NAMES.has(name)) {
|
|
6030
|
-
return executeTool(name, input2, childCtx);
|
|
6031
|
-
}
|
|
6032
|
-
return executeDesignExpertTool(
|
|
6033
|
-
name,
|
|
6034
|
-
input2,
|
|
6035
|
-
childCtx,
|
|
6036
|
-
toolCallId,
|
|
6037
|
-
onLog
|
|
6038
|
-
);
|
|
6078
|
+
const result = await runDesignExpert(
|
|
6079
|
+
{
|
|
6080
|
+
task: input.task,
|
|
6081
|
+
background: input.background
|
|
6039
6082
|
},
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
subAgentId: "visualDesignExpert",
|
|
6043
|
-
signal: context.signal,
|
|
6044
|
-
parentToolId: context.toolCallId,
|
|
6045
|
-
requestId: context.requestId,
|
|
6046
|
-
onEvent: context.onEvent,
|
|
6047
|
-
resolveExternalTool: context.resolveExternalTool,
|
|
6048
|
-
toolRegistry: context.toolRegistry,
|
|
6049
|
-
background: input.background,
|
|
6050
|
-
onBackgroundComplete: input.background ? (bgResult) => {
|
|
6051
|
-
context.onBackgroundComplete?.(
|
|
6052
|
-
context.toolCallId,
|
|
6053
|
-
"visualDesignExpert",
|
|
6054
|
-
bgResult.text,
|
|
6055
|
-
bgResult.messages
|
|
6056
|
-
);
|
|
6057
|
-
} : void 0
|
|
6058
|
-
});
|
|
6083
|
+
context
|
|
6084
|
+
);
|
|
6059
6085
|
context.subAgentMessages?.set(context.toolCallId, result.messages);
|
|
6060
6086
|
return result.text;
|
|
6061
6087
|
}
|
|
@@ -6168,16 +6194,25 @@ ${unifiedDiff(filePath, oldContent, "")}`;
|
|
|
6168
6194
|
const filePath = resolve("pitch.html");
|
|
6169
6195
|
try {
|
|
6170
6196
|
fs18.mkdirSync(ROADMAP_DIR, { recursive: true });
|
|
6171
|
-
const
|
|
6172
|
-
const
|
|
6197
|
+
const exists = fs18.existsSync(filePath);
|
|
6198
|
+
const before = exists ? fs18.statSync(filePath).mtimeMs : null;
|
|
6199
|
+
const delivery = exists ? `### Your deliverable
|
|
6200
|
+
The pitch deck already exists at \`${filePath}\`. Read it, then update it for the new <pitch_content>, keeping the presentation scaffolding intact \u2014 change only what needs to change.
|
|
6201
|
+
|
|
6202
|
+
Reply with a one-line summary of what you changed \u2014 not the HTML.` : `### Your deliverable
|
|
6203
|
+
Write the complete pitch deck to \`${filePath}\`. It does not exist yet \u2014 start from this scaffold, keeping its progress bar, chevron navigation, keyboard navigation, and transition mechanics intact:
|
|
6204
|
+
|
|
6205
|
+
<pitch_deck_shell>
|
|
6206
|
+
${PITCH_DECK_SHELL}
|
|
6207
|
+
</pitch_deck_shell>
|
|
6208
|
+
|
|
6209
|
+
Reply with a one-line summary of what you wrote \u2014 not the HTML.`;
|
|
6173
6210
|
const task = `
|
|
6174
6211
|
<pitch_content>${input.task}</pitch_content>
|
|
6175
6212
|
|
|
6176
|
-
<current_deck>${currentDeck}</current_deck>
|
|
6177
|
-
|
|
6178
6213
|
We are building the pitch deck for the app. Using the provided <pitch_content>, as well as the app's spec data, think about what would make a compelling, interactive, self-contained horizontally-scrolling HTML slide deck for this product. Keep it simple, clean, powerful. Giant text, large logo, big, bold stats and claims. Edit the content as necessary to create the most impactful, bold, and beautiful slides. This should not feel like an essay, and it should not feel like a landing page \u2014 it should feel like a modern interactive presentation that leaves the user wowed by the product and excited about its future.
|
|
6179
6214
|
|
|
6180
|
-
|
|
6215
|
+
Maintain the bones of the presentation scaffolding. Always keep the progress bar, chevron navigation, and keyboard navigation - they are part of the scaffold.
|
|
6181
6216
|
|
|
6182
6217
|
### Rules
|
|
6183
6218
|
- The deck must be a single HTML file \u2014 it will be rendered in an iframe.
|
|
@@ -6187,14 +6222,18 @@ Use <current_deck> as your starting point and replace or update the content as n
|
|
|
6187
6222
|
- Code must be clean, bug free, and easy to parse. Use GSAP for animations. Pay close attention to layout and alignment to make sure everything is perfect.
|
|
6188
6223
|
- Keep the progress bar and edge chevrons from the shell \u2014 they are part of the navigation UX.
|
|
6189
6224
|
|
|
6190
|
-
|
|
6191
|
-
const result = await
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6225
|
+
${delivery}`;
|
|
6226
|
+
const result = await runDesignExpertRender({ task }, context);
|
|
6227
|
+
context.subAgentMessages?.set(context.toolCallId, result.messages);
|
|
6228
|
+
if (!fs18.existsSync(filePath)) {
|
|
6229
|
+
return `Error: the design expert did not write ${filePath}. Its reply was:
|
|
6230
|
+
${result.text}`;
|
|
6231
|
+
}
|
|
6232
|
+
if (before !== null && fs18.statSync(filePath).mtimeMs === before) {
|
|
6233
|
+
return `Error: the pitch deck at ${filePath} was not modified. The design expert's reply was:
|
|
6234
|
+
${result.text}`;
|
|
6235
|
+
}
|
|
6236
|
+
return `Pitch deck written to ${filePath}. ${result.text}`;
|
|
6198
6237
|
} catch (err) {
|
|
6199
6238
|
return `Error generating pitch deck: ${err.message}`;
|
|
6200
6239
|
}
|
|
@@ -6489,6 +6528,22 @@ var init_scrapeWebUrl2 = __esm({
|
|
|
6489
6528
|
|
|
6490
6529
|
// src/tools/spec/writeBuildOverview.ts
|
|
6491
6530
|
import fs19 from "fs";
|
|
6531
|
+
function initialDelivery() {
|
|
6532
|
+
return `### Your deliverable
|
|
6533
|
+
Write the complete Build Overview to \`${OVERVIEW_FILE}\`. The file does not exist yet \u2014 start from this scaffold, which carries the technical hygiene for the iframed render context (keep the viewport meta and the reset). Layout, sections, type, and styling are yours to compose.
|
|
6534
|
+
|
|
6535
|
+
<overview_shell>
|
|
6536
|
+
${OVERVIEW_SHELL}
|
|
6537
|
+
</overview_shell>
|
|
6538
|
+
|
|
6539
|
+
Reply with a one-line summary of what you wrote \u2014 not the HTML.`;
|
|
6540
|
+
}
|
|
6541
|
+
function refreshDelivery() {
|
|
6542
|
+
return `### Your deliverable
|
|
6543
|
+
The Build Overview already exists at \`${OVERVIEW_FILE}\`. Read it, then update it to reflect <overview_copy>, preserving its established skin \u2014 change only what the copy changed.
|
|
6544
|
+
|
|
6545
|
+
Reply with a one-line summary of what you changed \u2014 not the HTML.`;
|
|
6546
|
+
}
|
|
6492
6547
|
var OVERVIEW_FILE, DESIGN_BRIEF, OVERVIEW_SHELL, buildOverviewTool;
|
|
6493
6548
|
var init_writeBuildOverview = __esm({
|
|
6494
6549
|
"src/tools/spec/writeBuildOverview.ts"() {
|
|
@@ -6497,7 +6552,7 @@ var init_writeBuildOverview = __esm({
|
|
|
6497
6552
|
OVERVIEW_FILE = "src/overview.html";
|
|
6498
6553
|
DESIGN_BRIEF = `We are building the Build Overview for this app \u2014 the home page of its Spec tab. It is a calm, dense, one-page reference of everything the app actually contains, including the parts the user can't see. It renders flush inside the Spec tab's content panel (the IDE supplies the surrounding nav).
|
|
6499
6554
|
|
|
6500
|
-
Take the plain-language copy in <overview_copy> and lay it out and skin it into a single, beautiful, self-contained HTML document in the app's own brand.
|
|
6555
|
+
Take the plain-language copy in <overview_copy> and lay it out and skin it into a single, beautiful, self-contained HTML document in the app's own brand.
|
|
6501
6556
|
|
|
6502
6557
|
### The single hard rule
|
|
6503
6558
|
The copy in <overview_copy> is final \u2014 it was authored and edited before it reached you. Treat it as locked content to typeset, not a draft to improve. Reproduce the words exactly: do not rewrite, rephrase, shorten, expand, reorder, or "polish" them, and do not run them through any copy tool. This is the opposite of your usual role \u2014 here you own layout, typography, and visual design only, and the words (every number, name, label, claim, and sentence) are fixed. A single changed word or wrong number breaks this document's purpose.
|
|
@@ -6512,9 +6567,7 @@ The copy in <overview_copy> is final \u2014 it was authored and edited before it
|
|
|
6512
6567
|
|
|
6513
6568
|
### Constraints
|
|
6514
6569
|
- A single self-contained HTML file. Fonts may load from a CDN; everything else (CSS, the logo SVG) is inline.
|
|
6515
|
-
- Responsive: fills the embedded panel width and collapses gracefully at narrow widths
|
|
6516
|
-
|
|
6517
|
-
Respond only with the complete HTML file and absolutely no other text. Your response will be written directly to src/overview.html.`;
|
|
6570
|
+
- Responsive: fills the embedded panel width and collapses gracefully at narrow widths.`;
|
|
6518
6571
|
OVERVIEW_SHELL = `<!DOCTYPE html>
|
|
6519
6572
|
<html lang="en">
|
|
6520
6573
|
<head>
|
|
@@ -6559,21 +6612,29 @@ Respond only with the complete HTML file and absolutely no other text. Your resp
|
|
|
6559
6612
|
if (!content) {
|
|
6560
6613
|
return "Error: writeBuildOverview requires non-empty `content` (the overview copy).";
|
|
6561
6614
|
}
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
const currentOverview = existing || OVERVIEW_SHELL;
|
|
6565
|
-
const task = `<overview_copy>${content}</overview_copy>
|
|
6615
|
+
const exists = fs19.existsSync(OVERVIEW_FILE);
|
|
6616
|
+
const task = `<overview_copy>${content}</overview_copy>
|
|
6566
6617
|
|
|
6567
|
-
|
|
6618
|
+
${DESIGN_BRIEF}
|
|
6568
6619
|
|
|
6569
|
-
${
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6620
|
+
${exists ? refreshDelivery() : initialDelivery()}`;
|
|
6621
|
+
try {
|
|
6622
|
+
if (exists) {
|
|
6623
|
+
input.background = true;
|
|
6624
|
+
const result2 = await runDesignExpertRender(
|
|
6625
|
+
{ task, background: true, reportingName: "writeBuildOverview" },
|
|
6626
|
+
context
|
|
6627
|
+
);
|
|
6628
|
+
context.subAgentMessages?.set(context.toolCallId, result2.messages);
|
|
6629
|
+
return result2.text;
|
|
6630
|
+
}
|
|
6631
|
+
const result = await runDesignExpertRender({ task }, context);
|
|
6632
|
+
context.subAgentMessages?.set(context.toolCallId, result.messages);
|
|
6633
|
+
if (!fs19.existsSync(OVERVIEW_FILE)) {
|
|
6634
|
+
return `Error: the design expert did not write ${OVERVIEW_FILE}. Its reply was:
|
|
6635
|
+
${result.text}`;
|
|
6636
|
+
}
|
|
6637
|
+
return `Build overview written to ${OVERVIEW_FILE}. ${result.text}`;
|
|
6577
6638
|
} catch (err) {
|
|
6578
6639
|
return `Error generating build overview: ${err.message}`;
|
|
6579
6640
|
}
|