@mindstudio-ai/remy 0.1.199 → 0.1.200
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/automatedActions/debugRequest.md +1 -1
- package/dist/automatedActions/feelingLucky.md +1 -1
- package/dist/automatedActions/postBuildPolish.md +4 -3
- package/dist/brandExtraction/extract.md +1 -1
- package/dist/compaction/conversation.md +1 -1
- package/dist/headless.js +107 -18
- package/dist/index.js +120 -23
- package/dist/prompt/.notes.md +1 -1
- package/dist/prompt/compiled/README.md +2 -2
- package/dist/prompt/compiled/auth.md +2 -2
- package/dist/prompt/compiled/design.md +2 -2
- package/dist/prompt/compiled/interfaces.md +1 -1
- package/dist/prompt/compiled/platform.md +2 -2
- package/dist/prompt/compiled/sdk-actions.md +2 -2
- package/dist/prompt/static/coding.md +1 -1
- package/dist/prompt/static/identity.md +1 -1
- package/dist/prompt/static/instructions.md +1 -0
- package/dist/prompt/static/intake.md +1 -1
- package/dist/subagents/codeSanityCheck/prompt.md +2 -2
- package/dist/subagents/designExpert/prompts/frontend-design-notes.md +2 -2
- package/dist/subagents/designExpert/prompts/ui-patterns.md +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Remy
|
|
2
2
|
|
|
3
|
-
A spec-building and coding agent for
|
|
3
|
+
A spec-building and coding agent for building apps.
|
|
4
4
|
|
|
5
|
-
Remy helps users design, spec, build, and iterate on
|
|
5
|
+
Remy helps users design, spec, build, and iterate on app projects. It runs locally in a terminal or as a headless subprocess in the sandbox. It has tools for reading/writing specs and code, running shell commands, searching code, prompting users with structured forms, and (in the sandbox) TypeScript language server integration. LLM calls are routed through the Remy platform for billing and model routing.
|
|
6
6
|
|
|
7
7
|
## Quick Start
|
|
8
8
|
|
|
@@ -11,7 +11,7 @@ Remy helps users design, spec, build, and iterate on MindStudio projects. It run
|
|
|
11
11
|
mindstudio login
|
|
12
12
|
|
|
13
13
|
# Navigate to your project
|
|
14
|
-
cd my-
|
|
14
|
+
cd my-app
|
|
15
15
|
|
|
16
16
|
# Run remy
|
|
17
17
|
npx remy
|
|
@@ -59,6 +59,7 @@ Tool availability depends on the project's onboarding state, sent by the sandbox
|
|
|
59
59
|
| `visualDesignExpert` | Visual design expert for fonts, colors, palettes, gradients, layouts, imagery, and icons (sub-agent) |
|
|
60
60
|
| `productVision` | Owns the product roadmap — creates/updates/deletes roadmap items in `src/roadmap/` (sub-agent) |
|
|
61
61
|
| `codeSanityCheck` | Quick readonly sanity check on architecture and package choices before building (sub-agent) |
|
|
62
|
+
| `writeBuildOverview` | Generate/refresh the Build Overview (`src/overview.html`) — a single-page plain-language reference of everything the app contains; you author the copy, the design expert lays it out |
|
|
62
63
|
|
|
63
64
|
### Spec Tools
|
|
64
65
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
trigger: debugRequest
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
This is an automated message triggered by the user having clicked "Debug" in the "Request" log detail in
|
|
5
|
+
This is an automated message triggered by the user having clicked "Debug" in the "Request" log detail in the Remy UI. Find the request in .logs/requests.ndjson by its ID. If there is an error, fix it immediately - otherwise, explain the request at a high-level in non-technical/natural language and see what the user wishes to do with it. Remember, the user can't see this message, so keep that in mind when responding.
|
|
6
6
|
|
|
7
7
|
<request_id>
|
|
8
8
|
{{requestId}}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
trigger: feelingLucky
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
This is an automated message triggered by the user having clicked "I'm feeling lucky" in the
|
|
5
|
+
This is an automated message triggered by the user having clicked "I'm feeling lucky" in the Remy UI and selecting a category from a list of app archetypes. They can't see this message. They're likely new to Remy - this might even be their first time using it. They haven't described a specific idea yet and more than likely don't actually have anything specific in mind — they're exploring what they can build and clicked on something that looked interesting. Your job is to ask questions to help them conjure the seed of an idea that is unique, specific, and interesting, and will be compelling to build as an MVP. Don't build something generic - help the user make something unique that allows you to truly show off the power of what you can build. Stay focused on web interfaces for now, unless the user specifically wants a different interface type. When you've aligned on something to build, focus on making it visually beautiful and highly usable from a UX perspective - at this point in the user's experience they're going to be much more "wowed" by something that looks pretty than by something with a ton of backend complexity.
|
|
6
6
|
|
|
7
7
|
<selected_category>
|
|
8
8
|
{{title}}
|
|
@@ -13,6 +13,7 @@ The visual assets — photography, generated images, brand colors, typography
|
|
|
13
13
|
|
|
14
14
|
## Finalizing
|
|
15
15
|
When everything is working and polished:
|
|
16
|
-
1.
|
|
17
|
-
2.
|
|
18
|
-
3. Call `
|
|
16
|
+
1. Write the Build Overview. Author the full copy of everything this build actually produced — the data stores and what each holds, the backend operations, the interfaces, any access and role boundaries, background jobs, and seeded scenarios, including the parts the user can't see — in plain, calm, present-tense language, with real names and exact counts. Then call `writeBuildOverview` to render it. Do this now, before compacting, while the build is still fresh in context.
|
|
17
|
+
2. Use `productVision` to mark the MVP roadmap item as done.
|
|
18
|
+
3. Call `compactConversation` to summarize the build session and free up context for the next phase of work.
|
|
19
|
+
4. Call `setProjectOnboardingState({ state: "buildComplete" })`. This triggers the reveal experience on the frontend, where the user sees their finished app and its Build Overview for the first time.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
You extract a structured `AppBrand` JSON object from the spec files of
|
|
1
|
+
You extract a structured `AppBrand` JSON object from the spec files of an app project.
|
|
2
2
|
|
|
3
3
|
Your output is read by a frontend renderer that uses the brand to style internal documents (implementation plans, sync plans, publish plans) with a "letterhead" treatment — a wordmark, accent color, paper-tone background, and branded fonts. Every field is optional. The renderer falls back to generic styling when a field is missing or invalid.
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
You are summarizing a conversation between a user and an AI coding agent called Remy that builds
|
|
1
|
+
You are summarizing a conversation between a user and an AI coding agent called Remy that builds apps. Your summary will replace the conversation history — the agent will only see your summary plus any new messages, so it must capture everything needed to continue working.
|
|
2
2
|
|
|
3
3
|
Write a tight, factual summary in bullet points. Cover what matters for picking the work back up:
|
|
4
4
|
- What the user is trying to do, and any key decisions, constraints, or preferences they've stated.
|
package/dist/headless.js
CHANGED
|
@@ -4680,9 +4680,9 @@ ${parts.join("\n\n")}
|
|
|
4680
4680
|
}
|
|
4681
4681
|
function loadPlatformBrief() {
|
|
4682
4682
|
return `<platform_brief>
|
|
4683
|
-
## What is a
|
|
4683
|
+
## What is a Remy app?
|
|
4684
4684
|
|
|
4685
|
-
A
|
|
4685
|
+
A Remy app is a managed full-stack TypeScript project with three layers: a spec (natural language in src/), a backend contract (methods, tables, roles in dist/), and one or more interfaces (web, API, bots, cron, etc.). The spec is the source of truth; code is derived from it.
|
|
4686
4686
|
|
|
4687
4687
|
This is a capable, stable platform used in production by 100k+ users. Build with confidence \u2014 you're building production-grade apps, not fragile prototypes.
|
|
4688
4688
|
|
|
@@ -4727,7 +4727,7 @@ TypeScript running in a sandboxed environment. Any npm package can be installed.
|
|
|
4727
4727
|
|
|
4728
4728
|
The first-party SDK (@mindstudio-ai/agent) provides access to 200+ AI models (OpenAI, Anthropic, Google, Meta, Mistral, and more) and 1000+ integrations (email, SMS, Slack, HubSpot, Google Workspace, web scraping, image/video generation, media processing, and much more) with zero configuration \u2014 credentials are handled automatically in the execution environment. No API keys needed. This SDK is robust and battle-tested in production.
|
|
4729
4729
|
|
|
4730
|
-
## What
|
|
4730
|
+
## What Remy apps are NOT good for
|
|
4731
4731
|
|
|
4732
4732
|
- Native mobile apps (iOS/Android). Mobile-responsive web apps are fine.
|
|
4733
4733
|
- Real-time multiplayer with persistent connections (no WebSocket support). Turn-based or async patterns work.
|
|
@@ -5391,6 +5391,94 @@ var scrapeWebUrlTool = {
|
|
|
5391
5391
|
}
|
|
5392
5392
|
};
|
|
5393
5393
|
|
|
5394
|
+
// src/tools/spec/writeBuildOverview.ts
|
|
5395
|
+
import fs20 from "fs";
|
|
5396
|
+
var OVERVIEW_FILE = "src/overview.html";
|
|
5397
|
+
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).
|
|
5398
|
+
|
|
5399
|
+
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. If <current_overview> is non-empty, use it as your starting point and preserve its established skin, updating only what the copy changed.
|
|
5400
|
+
|
|
5401
|
+
### The single hard rule
|
|
5402
|
+
Preserve every fact in <overview_copy> exactly \u2014 every number, name, label, and claim. Do not add, drop, soften, reword, or invent any fact. You own layout, typography, and visual design only; the substance and the words are fixed. A single wrong number breaks this document's entire purpose.
|
|
5403
|
+
|
|
5404
|
+
### What it is (and is not)
|
|
5405
|
+
- A typeset reference dossier: composed, dense, a little cool \u2014 substantial at a glance, then readable. Density communicates substance; sparse and airy reads as "not much here."
|
|
5406
|
+
- Brand-skinned: pull the palette, type system, and a single accent from the app's spec. The accent leads labels and figures; it is a mark, not a fill.
|
|
5407
|
+
- NOT a slide deck \u2014 no theatrics, no building to a climax, no persuasion.
|
|
5408
|
+
- NOT a docs site \u2014 no raised or shadowed cards, no hover-lift, no clickable-feeling surfaces, no sticky table of contents.
|
|
5409
|
+
- NOT a sparse memo \u2014 a restrained single-column page under-sells the work.
|
|
5410
|
+
- No header chrome and no footer: open straight on the app's logo and name so it sits flush with the IDE.
|
|
5411
|
+
|
|
5412
|
+
### Constraints
|
|
5413
|
+
- A single self-contained HTML file. Fonts may load from a CDN; everything else (CSS, the logo SVG) is inline.
|
|
5414
|
+
- Responsive: fills the embedded panel width and collapses gracefully at narrow widths.
|
|
5415
|
+
|
|
5416
|
+
Respond only with the complete HTML file and absolutely no other text. Your response will be written directly to src/overview.html.`;
|
|
5417
|
+
var OVERVIEW_SHELL = `<!DOCTYPE html>
|
|
5418
|
+
<html lang="en">
|
|
5419
|
+
<head>
|
|
5420
|
+
<meta charset="utf-8">
|
|
5421
|
+
<!-- This renders inside an iframe in the IDE. Keep it a simple, self-contained
|
|
5422
|
+
static document \u2014 no scroll/zoom/accessibility scaffolding beyond this head.
|
|
5423
|
+
The user-scalable=no viewport is intentional; leave it. -->
|
|
5424
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
|
5425
|
+
<title>Build Overview</title>
|
|
5426
|
+
<!-- SKIN: link the app's fonts here (CDN \u2014 e.g. Fontshare / Google Fonts). -->
|
|
5427
|
+
<style>
|
|
5428
|
+
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
5429
|
+
</style>
|
|
5430
|
+
</head>
|
|
5431
|
+
<body>
|
|
5432
|
+
<!-- Compose the Build Overview here. Layout, sections, type, and styling are
|
|
5433
|
+
yours \u2014 keep everything inline and self-contained, brand-skinned from the
|
|
5434
|
+
app's spec. -->
|
|
5435
|
+
</body>
|
|
5436
|
+
</html>`;
|
|
5437
|
+
var buildOverviewTool = {
|
|
5438
|
+
clearable: false,
|
|
5439
|
+
definition: {
|
|
5440
|
+
name: "writeBuildOverview",
|
|
5441
|
+
description: "Generate or refresh the Build Overview \u2014 the project's home page in the Spec tab: a single-page, plain-language reference of everything the app actually contains, including the parts the user can't see (data stores, backend operations, access and roles, background jobs, seeded scenarios, the design system). You author the full copy: read the manifest and spec and state, plainly and exactly, what genuinely exists \u2014 real names and accurate counts \u2014 in calm, declarative, present-tense outcome language, with no persuasion or hype. Describe only what exists. Pass the complete copy as `content`; the design expert lays it out and skins it to the app's brand without altering any of your facts. Generate it at the end of a build and refresh it after meaningful work.",
|
|
5442
|
+
inputSchema: {
|
|
5443
|
+
type: "object",
|
|
5444
|
+
properties: {
|
|
5445
|
+
content: {
|
|
5446
|
+
type: "string",
|
|
5447
|
+
description: "The full Build Overview copy you authored: everything the app contains, in plain present-tense outcome language, with real names and exact counts. The design expert lays this out and skins it to the brand without changing any fact."
|
|
5448
|
+
}
|
|
5449
|
+
},
|
|
5450
|
+
required: ["content"]
|
|
5451
|
+
}
|
|
5452
|
+
},
|
|
5453
|
+
async execute(input, context) {
|
|
5454
|
+
if (!context) {
|
|
5455
|
+
return "Error: writeBuildOverview requires execution context for design expert delegation";
|
|
5456
|
+
}
|
|
5457
|
+
const content = (input.content ?? "").trim();
|
|
5458
|
+
if (!content) {
|
|
5459
|
+
return "Error: writeBuildOverview requires non-empty `content` (the overview copy).";
|
|
5460
|
+
}
|
|
5461
|
+
try {
|
|
5462
|
+
const existing = fs20.existsSync(OVERVIEW_FILE) ? fs20.readFileSync(OVERVIEW_FILE, "utf-8").trim() : "";
|
|
5463
|
+
const currentOverview = existing || OVERVIEW_SHELL;
|
|
5464
|
+
const task = `<overview_copy>${content}</overview_copy>
|
|
5465
|
+
|
|
5466
|
+
<current_overview>${currentOverview}</current_overview>
|
|
5467
|
+
|
|
5468
|
+
${DESIGN_BRIEF}`;
|
|
5469
|
+
const result = await designExpertTool.execute({ task }, context);
|
|
5470
|
+
const htmlMatch = result.match(
|
|
5471
|
+
/```(?:html|wireframe)\n([\s\S]*?)```/
|
|
5472
|
+
);
|
|
5473
|
+
const html = htmlMatch ? htmlMatch[1].trim() : result;
|
|
5474
|
+
fs20.writeFileSync(OVERVIEW_FILE, html, "utf-8");
|
|
5475
|
+
return "Build overview written successfully to src/overview.html.";
|
|
5476
|
+
} catch (err) {
|
|
5477
|
+
return `Error generating build overview: ${err.message}`;
|
|
5478
|
+
}
|
|
5479
|
+
}
|
|
5480
|
+
};
|
|
5481
|
+
|
|
5394
5482
|
// src/tools/index.ts
|
|
5395
5483
|
function deriveContext(parent, toolCallId) {
|
|
5396
5484
|
return { ...parent, toolCallId };
|
|
@@ -5407,6 +5495,7 @@ var ALL_TOOLS = [
|
|
|
5407
5495
|
designExpertTool,
|
|
5408
5496
|
productVisionTool,
|
|
5409
5497
|
codeSanityCheckTool,
|
|
5498
|
+
buildOverviewTool,
|
|
5410
5499
|
compactConversationTool,
|
|
5411
5500
|
// Post-onboarding
|
|
5412
5501
|
presentPublishPlanTool,
|
|
@@ -5789,7 +5878,7 @@ function triggerCompaction(state, apiConfig, opts = {}) {
|
|
|
5789
5878
|
}
|
|
5790
5879
|
|
|
5791
5880
|
// src/brandExtraction/index.ts
|
|
5792
|
-
import
|
|
5881
|
+
import fs21 from "fs";
|
|
5793
5882
|
import path10 from "path";
|
|
5794
5883
|
import { createHash } from "crypto";
|
|
5795
5884
|
var log9 = createLogger("brandExtraction");
|
|
@@ -5838,7 +5927,7 @@ function sha256(input) {
|
|
|
5838
5927
|
}
|
|
5839
5928
|
function readSafe(filePath) {
|
|
5840
5929
|
try {
|
|
5841
|
-
return
|
|
5930
|
+
return fs21.readFileSync(filePath, "utf-8");
|
|
5842
5931
|
} catch {
|
|
5843
5932
|
return "";
|
|
5844
5933
|
}
|
|
@@ -5846,7 +5935,7 @@ function readSafe(filePath) {
|
|
|
5846
5935
|
function walkMdFiles3(dir) {
|
|
5847
5936
|
const results = [];
|
|
5848
5937
|
try {
|
|
5849
|
-
const entries =
|
|
5938
|
+
const entries = fs21.readdirSync(dir, { withFileTypes: true });
|
|
5850
5939
|
for (const entry of entries) {
|
|
5851
5940
|
const full = path10.join(dir, entry.name);
|
|
5852
5941
|
if (entry.isDirectory()) {
|
|
@@ -5861,7 +5950,7 @@ function walkMdFiles3(dir) {
|
|
|
5861
5950
|
}
|
|
5862
5951
|
function parseFrontmatter3(filePath) {
|
|
5863
5952
|
try {
|
|
5864
|
-
const content =
|
|
5953
|
+
const content = fs21.readFileSync(filePath, "utf-8");
|
|
5865
5954
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
5866
5955
|
if (!match) {
|
|
5867
5956
|
return { type: "" };
|
|
@@ -6040,14 +6129,14 @@ function pickFont(raw) {
|
|
|
6040
6129
|
}
|
|
6041
6130
|
function persistBrand(brand, inputHash) {
|
|
6042
6131
|
const tmp = `${BRAND_FILE}.tmp`;
|
|
6043
|
-
|
|
6044
|
-
|
|
6132
|
+
fs21.writeFileSync(tmp, JSON.stringify(brand, null, 2), "utf-8");
|
|
6133
|
+
fs21.renameSync(tmp, BRAND_FILE);
|
|
6045
6134
|
const cache = { inputHash, generatedAt: Date.now() };
|
|
6046
|
-
|
|
6135
|
+
fs21.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2), "utf-8");
|
|
6047
6136
|
}
|
|
6048
6137
|
function readCache() {
|
|
6049
6138
|
try {
|
|
6050
|
-
const raw =
|
|
6139
|
+
const raw = fs21.readFileSync(CACHE_FILE, "utf-8");
|
|
6051
6140
|
const parsed = JSON.parse(raw);
|
|
6052
6141
|
if (parsed && typeof parsed.inputHash === "string" && typeof parsed.generatedAt === "number") {
|
|
6053
6142
|
return parsed;
|
|
@@ -6080,14 +6169,14 @@ function triggerBrandExtraction(apiConfig, model) {
|
|
|
6080
6169
|
}
|
|
6081
6170
|
|
|
6082
6171
|
// src/session.ts
|
|
6083
|
-
import
|
|
6172
|
+
import fs22 from "fs";
|
|
6084
6173
|
import path11 from "path";
|
|
6085
6174
|
var log11 = createLogger("session");
|
|
6086
6175
|
var SESSION_FILE = ".remy-session.json";
|
|
6087
6176
|
var ARCHIVE_DIR = ".logs/sessions";
|
|
6088
6177
|
function loadSession(state) {
|
|
6089
6178
|
try {
|
|
6090
|
-
const raw =
|
|
6179
|
+
const raw = fs22.readFileSync(SESSION_FILE, "utf-8");
|
|
6091
6180
|
const data = JSON.parse(raw);
|
|
6092
6181
|
if (data.models && typeof data.models === "object") {
|
|
6093
6182
|
state.models = data.models;
|
|
@@ -6146,7 +6235,7 @@ function saveSession(state) {
|
|
|
6146
6235
|
if (state.models && Object.keys(state.models).length > 0) {
|
|
6147
6236
|
payload.models = state.models;
|
|
6148
6237
|
}
|
|
6149
|
-
|
|
6238
|
+
fs22.writeFileSync(SESSION_FILE, JSON.stringify(payload, null, 2), "utf-8");
|
|
6150
6239
|
log11.info("Session saved", { messageCount: state.messages.length });
|
|
6151
6240
|
} catch (err) {
|
|
6152
6241
|
log11.warn("Session save failed", { error: err.message });
|
|
@@ -6155,11 +6244,11 @@ function saveSession(state) {
|
|
|
6155
6244
|
function clearSession(state) {
|
|
6156
6245
|
state.messages = [];
|
|
6157
6246
|
try {
|
|
6158
|
-
if (
|
|
6159
|
-
|
|
6247
|
+
if (fs22.existsSync(SESSION_FILE)) {
|
|
6248
|
+
fs22.mkdirSync(ARCHIVE_DIR, { recursive: true });
|
|
6160
6249
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
6161
6250
|
const dest = path11.join(ARCHIVE_DIR, `cleared-${ts}.json`);
|
|
6162
|
-
|
|
6251
|
+
fs22.renameSync(SESSION_FILE, dest);
|
|
6163
6252
|
log11.info("Session archived on clear", { dest });
|
|
6164
6253
|
}
|
|
6165
6254
|
} catch (err) {
|
|
@@ -6167,7 +6256,7 @@ function clearSession(state) {
|
|
|
6167
6256
|
error: err.message
|
|
6168
6257
|
});
|
|
6169
6258
|
try {
|
|
6170
|
-
|
|
6259
|
+
fs22.unlinkSync(SESSION_FILE);
|
|
6171
6260
|
} catch {
|
|
6172
6261
|
}
|
|
6173
6262
|
}
|
package/dist/index.js
CHANGED
|
@@ -5461,9 +5461,9 @@ ${parts.join("\n\n")}
|
|
|
5461
5461
|
}
|
|
5462
5462
|
function loadPlatformBrief() {
|
|
5463
5463
|
return `<platform_brief>
|
|
5464
|
-
## What is a
|
|
5464
|
+
## What is a Remy app?
|
|
5465
5465
|
|
|
5466
|
-
A
|
|
5466
|
+
A Remy app is a managed full-stack TypeScript project with three layers: a spec (natural language in src/), a backend contract (methods, tables, roles in dist/), and one or more interfaces (web, API, bots, cron, etc.). The spec is the source of truth; code is derived from it.
|
|
5467
5467
|
|
|
5468
5468
|
This is a capable, stable platform used in production by 100k+ users. Build with confidence \u2014 you're building production-grade apps, not fragile prototypes.
|
|
5469
5469
|
|
|
@@ -5508,7 +5508,7 @@ TypeScript running in a sandboxed environment. Any npm package can be installed.
|
|
|
5508
5508
|
|
|
5509
5509
|
The first-party SDK (@mindstudio-ai/agent) provides access to 200+ AI models (OpenAI, Anthropic, Google, Meta, Mistral, and more) and 1000+ integrations (email, SMS, Slack, HubSpot, Google Workspace, web scraping, image/video generation, media processing, and much more) with zero configuration \u2014 credentials are handled automatically in the execution environment. No API keys needed. This SDK is robust and battle-tested in production.
|
|
5510
5510
|
|
|
5511
|
-
## What
|
|
5511
|
+
## What Remy apps are NOT good for
|
|
5512
5512
|
|
|
5513
5513
|
- Native mobile apps (iOS/Android). Mobile-responsive web apps are fine.
|
|
5514
5514
|
- Real-time multiplayer with persistent connections (no WebSocket support). Turn-based or async patterns work.
|
|
@@ -6303,6 +6303,101 @@ var init_scrapeWebUrl2 = __esm({
|
|
|
6303
6303
|
}
|
|
6304
6304
|
});
|
|
6305
6305
|
|
|
6306
|
+
// src/tools/spec/writeBuildOverview.ts
|
|
6307
|
+
import fs19 from "fs";
|
|
6308
|
+
var OVERVIEW_FILE, DESIGN_BRIEF, OVERVIEW_SHELL, buildOverviewTool;
|
|
6309
|
+
var init_writeBuildOverview = __esm({
|
|
6310
|
+
"src/tools/spec/writeBuildOverview.ts"() {
|
|
6311
|
+
"use strict";
|
|
6312
|
+
init_designExpert();
|
|
6313
|
+
OVERVIEW_FILE = "src/overview.html";
|
|
6314
|
+
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).
|
|
6315
|
+
|
|
6316
|
+
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. If <current_overview> is non-empty, use it as your starting point and preserve its established skin, updating only what the copy changed.
|
|
6317
|
+
|
|
6318
|
+
### The single hard rule
|
|
6319
|
+
Preserve every fact in <overview_copy> exactly \u2014 every number, name, label, and claim. Do not add, drop, soften, reword, or invent any fact. You own layout, typography, and visual design only; the substance and the words are fixed. A single wrong number breaks this document's entire purpose.
|
|
6320
|
+
|
|
6321
|
+
### What it is (and is not)
|
|
6322
|
+
- A typeset reference dossier: composed, dense, a little cool \u2014 substantial at a glance, then readable. Density communicates substance; sparse and airy reads as "not much here."
|
|
6323
|
+
- Brand-skinned: pull the palette, type system, and a single accent from the app's spec. The accent leads labels and figures; it is a mark, not a fill.
|
|
6324
|
+
- NOT a slide deck \u2014 no theatrics, no building to a climax, no persuasion.
|
|
6325
|
+
- NOT a docs site \u2014 no raised or shadowed cards, no hover-lift, no clickable-feeling surfaces, no sticky table of contents.
|
|
6326
|
+
- NOT a sparse memo \u2014 a restrained single-column page under-sells the work.
|
|
6327
|
+
- No header chrome and no footer: open straight on the app's logo and name so it sits flush with the IDE.
|
|
6328
|
+
|
|
6329
|
+
### Constraints
|
|
6330
|
+
- A single self-contained HTML file. Fonts may load from a CDN; everything else (CSS, the logo SVG) is inline.
|
|
6331
|
+
- Responsive: fills the embedded panel width and collapses gracefully at narrow widths.
|
|
6332
|
+
|
|
6333
|
+
Respond only with the complete HTML file and absolutely no other text. Your response will be written directly to src/overview.html.`;
|
|
6334
|
+
OVERVIEW_SHELL = `<!DOCTYPE html>
|
|
6335
|
+
<html lang="en">
|
|
6336
|
+
<head>
|
|
6337
|
+
<meta charset="utf-8">
|
|
6338
|
+
<!-- This renders inside an iframe in the IDE. Keep it a simple, self-contained
|
|
6339
|
+
static document \u2014 no scroll/zoom/accessibility scaffolding beyond this head.
|
|
6340
|
+
The user-scalable=no viewport is intentional; leave it. -->
|
|
6341
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
|
6342
|
+
<title>Build Overview</title>
|
|
6343
|
+
<!-- SKIN: link the app's fonts here (CDN \u2014 e.g. Fontshare / Google Fonts). -->
|
|
6344
|
+
<style>
|
|
6345
|
+
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
6346
|
+
</style>
|
|
6347
|
+
</head>
|
|
6348
|
+
<body>
|
|
6349
|
+
<!-- Compose the Build Overview here. Layout, sections, type, and styling are
|
|
6350
|
+
yours \u2014 keep everything inline and self-contained, brand-skinned from the
|
|
6351
|
+
app's spec. -->
|
|
6352
|
+
</body>
|
|
6353
|
+
</html>`;
|
|
6354
|
+
buildOverviewTool = {
|
|
6355
|
+
clearable: false,
|
|
6356
|
+
definition: {
|
|
6357
|
+
name: "writeBuildOverview",
|
|
6358
|
+
description: "Generate or refresh the Build Overview \u2014 the project's home page in the Spec tab: a single-page, plain-language reference of everything the app actually contains, including the parts the user can't see (data stores, backend operations, access and roles, background jobs, seeded scenarios, the design system). You author the full copy: read the manifest and spec and state, plainly and exactly, what genuinely exists \u2014 real names and accurate counts \u2014 in calm, declarative, present-tense outcome language, with no persuasion or hype. Describe only what exists. Pass the complete copy as `content`; the design expert lays it out and skins it to the app's brand without altering any of your facts. Generate it at the end of a build and refresh it after meaningful work.",
|
|
6359
|
+
inputSchema: {
|
|
6360
|
+
type: "object",
|
|
6361
|
+
properties: {
|
|
6362
|
+
content: {
|
|
6363
|
+
type: "string",
|
|
6364
|
+
description: "The full Build Overview copy you authored: everything the app contains, in plain present-tense outcome language, with real names and exact counts. The design expert lays this out and skins it to the brand without changing any fact."
|
|
6365
|
+
}
|
|
6366
|
+
},
|
|
6367
|
+
required: ["content"]
|
|
6368
|
+
}
|
|
6369
|
+
},
|
|
6370
|
+
async execute(input, context) {
|
|
6371
|
+
if (!context) {
|
|
6372
|
+
return "Error: writeBuildOverview requires execution context for design expert delegation";
|
|
6373
|
+
}
|
|
6374
|
+
const content = (input.content ?? "").trim();
|
|
6375
|
+
if (!content) {
|
|
6376
|
+
return "Error: writeBuildOverview requires non-empty `content` (the overview copy).";
|
|
6377
|
+
}
|
|
6378
|
+
try {
|
|
6379
|
+
const existing = fs19.existsSync(OVERVIEW_FILE) ? fs19.readFileSync(OVERVIEW_FILE, "utf-8").trim() : "";
|
|
6380
|
+
const currentOverview = existing || OVERVIEW_SHELL;
|
|
6381
|
+
const task = `<overview_copy>${content}</overview_copy>
|
|
6382
|
+
|
|
6383
|
+
<current_overview>${currentOverview}</current_overview>
|
|
6384
|
+
|
|
6385
|
+
${DESIGN_BRIEF}`;
|
|
6386
|
+
const result = await designExpertTool.execute({ task }, context);
|
|
6387
|
+
const htmlMatch = result.match(
|
|
6388
|
+
/```(?:html|wireframe)\n([\s\S]*?)```/
|
|
6389
|
+
);
|
|
6390
|
+
const html = htmlMatch ? htmlMatch[1].trim() : result;
|
|
6391
|
+
fs19.writeFileSync(OVERVIEW_FILE, html, "utf-8");
|
|
6392
|
+
return "Build overview written successfully to src/overview.html.";
|
|
6393
|
+
} catch (err) {
|
|
6394
|
+
return `Error generating build overview: ${err.message}`;
|
|
6395
|
+
}
|
|
6396
|
+
}
|
|
6397
|
+
};
|
|
6398
|
+
}
|
|
6399
|
+
});
|
|
6400
|
+
|
|
6306
6401
|
// src/tools/index.ts
|
|
6307
6402
|
function deriveContext(parent, toolCallId) {
|
|
6308
6403
|
return { ...parent, toolCallId };
|
|
@@ -6357,6 +6452,7 @@ var init_tools6 = __esm({
|
|
|
6357
6452
|
init_productVision();
|
|
6358
6453
|
init_codeSanityCheck();
|
|
6359
6454
|
init_scrapeWebUrl2();
|
|
6455
|
+
init_writeBuildOverview();
|
|
6360
6456
|
ALL_TOOLS = [
|
|
6361
6457
|
// Common
|
|
6362
6458
|
setProjectOnboardingStateTool,
|
|
@@ -6369,6 +6465,7 @@ var init_tools6 = __esm({
|
|
|
6369
6465
|
designExpertTool,
|
|
6370
6466
|
productVisionTool,
|
|
6371
6467
|
codeSanityCheckTool,
|
|
6468
|
+
buildOverviewTool,
|
|
6372
6469
|
compactConversationTool,
|
|
6373
6470
|
// Post-onboarding
|
|
6374
6471
|
presentPublishPlanTool,
|
|
@@ -6411,11 +6508,11 @@ var init_tools6 = __esm({
|
|
|
6411
6508
|
});
|
|
6412
6509
|
|
|
6413
6510
|
// src/session.ts
|
|
6414
|
-
import
|
|
6511
|
+
import fs20 from "fs";
|
|
6415
6512
|
import path9 from "path";
|
|
6416
6513
|
function loadSession(state) {
|
|
6417
6514
|
try {
|
|
6418
|
-
const raw =
|
|
6515
|
+
const raw = fs20.readFileSync(SESSION_FILE, "utf-8");
|
|
6419
6516
|
const data = JSON.parse(raw);
|
|
6420
6517
|
if (data.models && typeof data.models === "object") {
|
|
6421
6518
|
state.models = data.models;
|
|
@@ -6474,7 +6571,7 @@ function saveSession(state) {
|
|
|
6474
6571
|
if (state.models && Object.keys(state.models).length > 0) {
|
|
6475
6572
|
payload.models = state.models;
|
|
6476
6573
|
}
|
|
6477
|
-
|
|
6574
|
+
fs20.writeFileSync(SESSION_FILE, JSON.stringify(payload, null, 2), "utf-8");
|
|
6478
6575
|
log8.info("Session saved", { messageCount: state.messages.length });
|
|
6479
6576
|
} catch (err) {
|
|
6480
6577
|
log8.warn("Session save failed", { error: err.message });
|
|
@@ -6483,11 +6580,11 @@ function saveSession(state) {
|
|
|
6483
6580
|
function clearSession(state) {
|
|
6484
6581
|
state.messages = [];
|
|
6485
6582
|
try {
|
|
6486
|
-
if (
|
|
6487
|
-
|
|
6583
|
+
if (fs20.existsSync(SESSION_FILE)) {
|
|
6584
|
+
fs20.mkdirSync(ARCHIVE_DIR, { recursive: true });
|
|
6488
6585
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
6489
6586
|
const dest = path9.join(ARCHIVE_DIR, `cleared-${ts}.json`);
|
|
6490
|
-
|
|
6587
|
+
fs20.renameSync(SESSION_FILE, dest);
|
|
6491
6588
|
log8.info("Session archived on clear", { dest });
|
|
6492
6589
|
}
|
|
6493
6590
|
} catch (err) {
|
|
@@ -6495,7 +6592,7 @@ function clearSession(state) {
|
|
|
6495
6592
|
error: err.message
|
|
6496
6593
|
});
|
|
6497
6594
|
try {
|
|
6498
|
-
|
|
6595
|
+
fs20.unlinkSync(SESSION_FILE);
|
|
6499
6596
|
} catch {
|
|
6500
6597
|
}
|
|
6501
6598
|
}
|
|
@@ -6717,7 +6814,7 @@ var init_errors = __esm({
|
|
|
6717
6814
|
});
|
|
6718
6815
|
|
|
6719
6816
|
// src/brandExtraction/index.ts
|
|
6720
|
-
import
|
|
6817
|
+
import fs21 from "fs";
|
|
6721
6818
|
import path10 from "path";
|
|
6722
6819
|
import { createHash } from "crypto";
|
|
6723
6820
|
async function runExtraction(apiConfig, model) {
|
|
@@ -6762,7 +6859,7 @@ function sha256(input) {
|
|
|
6762
6859
|
}
|
|
6763
6860
|
function readSafe(filePath) {
|
|
6764
6861
|
try {
|
|
6765
|
-
return
|
|
6862
|
+
return fs21.readFileSync(filePath, "utf-8");
|
|
6766
6863
|
} catch {
|
|
6767
6864
|
return "";
|
|
6768
6865
|
}
|
|
@@ -6770,7 +6867,7 @@ function readSafe(filePath) {
|
|
|
6770
6867
|
function walkMdFiles3(dir) {
|
|
6771
6868
|
const results = [];
|
|
6772
6869
|
try {
|
|
6773
|
-
const entries =
|
|
6870
|
+
const entries = fs21.readdirSync(dir, { withFileTypes: true });
|
|
6774
6871
|
for (const entry of entries) {
|
|
6775
6872
|
const full = path10.join(dir, entry.name);
|
|
6776
6873
|
if (entry.isDirectory()) {
|
|
@@ -6785,7 +6882,7 @@ function walkMdFiles3(dir) {
|
|
|
6785
6882
|
}
|
|
6786
6883
|
function parseFrontmatter3(filePath) {
|
|
6787
6884
|
try {
|
|
6788
|
-
const content =
|
|
6885
|
+
const content = fs21.readFileSync(filePath, "utf-8");
|
|
6789
6886
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
6790
6887
|
if (!match) {
|
|
6791
6888
|
return { type: "" };
|
|
@@ -6964,14 +7061,14 @@ function pickFont(raw) {
|
|
|
6964
7061
|
}
|
|
6965
7062
|
function persistBrand(brand, inputHash) {
|
|
6966
7063
|
const tmp = `${BRAND_FILE}.tmp`;
|
|
6967
|
-
|
|
6968
|
-
|
|
7064
|
+
fs21.writeFileSync(tmp, JSON.stringify(brand, null, 2), "utf-8");
|
|
7065
|
+
fs21.renameSync(tmp, BRAND_FILE);
|
|
6969
7066
|
const cache = { inputHash, generatedAt: Date.now() };
|
|
6970
|
-
|
|
7067
|
+
fs21.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2), "utf-8");
|
|
6971
7068
|
}
|
|
6972
7069
|
function readCache() {
|
|
6973
7070
|
try {
|
|
6974
|
-
const raw =
|
|
7071
|
+
const raw = fs21.readFileSync(CACHE_FILE, "utf-8");
|
|
6975
7072
|
const parsed = JSON.parse(raw);
|
|
6976
7073
|
if (parsed && typeof parsed.inputHash === "string" && typeof parsed.generatedAt === "number") {
|
|
6977
7074
|
return parsed;
|
|
@@ -7638,12 +7735,12 @@ var init_agent = __esm({
|
|
|
7638
7735
|
});
|
|
7639
7736
|
|
|
7640
7737
|
// src/config.ts
|
|
7641
|
-
import
|
|
7738
|
+
import fs22 from "fs";
|
|
7642
7739
|
import path11 from "path";
|
|
7643
7740
|
import os from "os";
|
|
7644
7741
|
function loadConfigFile() {
|
|
7645
7742
|
try {
|
|
7646
|
-
const raw =
|
|
7743
|
+
const raw = fs22.readFileSync(CONFIG_PATH, "utf-8");
|
|
7647
7744
|
log12.debug("Loaded config file", { path: CONFIG_PATH });
|
|
7648
7745
|
return JSON.parse(raw);
|
|
7649
7746
|
} catch (err) {
|
|
@@ -8891,7 +8988,7 @@ var init_headless = __esm({
|
|
|
8891
8988
|
// src/index.tsx
|
|
8892
8989
|
import { render } from "ink";
|
|
8893
8990
|
import os2 from "os";
|
|
8894
|
-
import
|
|
8991
|
+
import fs23 from "fs";
|
|
8895
8992
|
import path12 from "path";
|
|
8896
8993
|
|
|
8897
8994
|
// src/tui/App.tsx
|
|
@@ -9173,7 +9270,7 @@ Error: ${err.message}`,
|
|
|
9173
9270
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", gap: 1, children: [
|
|
9174
9271
|
/* @__PURE__ */ jsxs4(Text5, { bold: true, color: "magenta", children: [
|
|
9175
9272
|
"Remy ",
|
|
9176
|
-
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "v0.1.0 \u2014
|
|
9273
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "v0.1.0 \u2014 AI coding agent" })
|
|
9177
9274
|
] }),
|
|
9178
9275
|
sessionRestored && /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
9179
9276
|
"Session restored (",
|
|
@@ -9210,7 +9307,7 @@ for (let i = 0; i < args.length; i++) {
|
|
|
9210
9307
|
var startupLog = createLogger("startup");
|
|
9211
9308
|
function printDebugInfo(config) {
|
|
9212
9309
|
const pkg = JSON.parse(
|
|
9213
|
-
|
|
9310
|
+
fs23.readFileSync(
|
|
9214
9311
|
path12.join(import.meta.dirname, "..", "package.json"),
|
|
9215
9312
|
"utf-8"
|
|
9216
9313
|
)
|
package/dist/prompt/.notes.md
CHANGED
|
@@ -69,7 +69,7 @@ From research into v0, Lovable, Bolt, and Anthropic's `<frontend_aesthetics>` co
|
|
|
69
69
|
|
|
70
70
|
## SDK Usage
|
|
71
71
|
|
|
72
|
-
The canonical import pattern for
|
|
72
|
+
The canonical import pattern for app methods is `import { mindstudio } from '@mindstudio-ai/agent'` with `mindstudio.generateText(...)`, `mindstudio.runTask(...)`, etc. The `mindstudio` singleton handles auth automatically. `new MindStudioAgent({ apiKey })` is only for external usage outside an app.
|
|
73
73
|
|
|
74
74
|
The SDK ships `llms.txt` at the package root with full signatures for all 170+ actions. The compiled fragment references this path (`dist/methods/node_modules/@mindstudio-ai/agent/llms.txt`) so the agent knows where to look up specific action details.
|
|
75
75
|
|
|
@@ -18,7 +18,7 @@ instructions:
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
20
|
**You will compile source docs into prompt fragments for Remy, a coding agent
|
|
21
|
-
that builds
|
|
21
|
+
that builds apps. The compiled fragments go in `src/prompt/compiled/`
|
|
22
22
|
and are loaded into the agent's system prompt at runtime.**
|
|
23
23
|
|
|
24
24
|
**Work through this one source file at a time, sequentially.** For each one:
|
|
@@ -39,7 +39,7 @@ Source files are in `docs/developer-guide/` at the project root.
|
|
|
39
39
|
|
|
40
40
|
**Your audience is an LLM acting as a coding agent.** It needs to produce
|
|
41
41
|
correct code, not learn concepts. Everything you write should be optimized
|
|
42
|
-
for an agent that is actively building
|
|
42
|
+
for an agent that is actively building an app and needs to get
|
|
43
43
|
the details right.
|
|
44
44
|
|
|
45
45
|
### What to keep
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Auth
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Remy apps can have and manage their own users. Auth is opt-in: configure it in the manifest, define a user table, and build your own login UI. The platform handles verification codes, cookies, and session management. Apps without auth config use anonymous guest sessions (current default behavior).
|
|
4
4
|
|
|
5
5
|
**Auth is optional.** Many apps don't need it. Only add auth when the app needs to identify users or restrict access.
|
|
6
6
|
|
|
@@ -338,7 +338,7 @@ Roles are declared in the manifest, stored as an array column on the user table,
|
|
|
338
338
|
- Declare roles in `mindstudio.json` with `id` and `name`
|
|
339
339
|
- The mapped `roles` column holds a JSON array of role ID strings: `["vendor", "admin"]`
|
|
340
340
|
- Writable from code: `Users.update(userId, { roles: ['admin'] })` — platform syncs automatically
|
|
341
|
-
- Writable from dashboard:
|
|
341
|
+
- Writable from dashboard: Remy dashboard shows app users and their roles
|
|
342
342
|
- Backend enforcement: `auth.requireRole('admin')` works as before
|
|
343
343
|
|
|
344
344
|
## Apps Without Auth
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Frontend Design Notes
|
|
2
2
|
|
|
3
|
-
Design standards for web interfaces in
|
|
3
|
+
Design standards for web interfaces in Remy apps.
|
|
4
4
|
|
|
5
5
|
## Quality Bar
|
|
6
6
|
|
|
7
7
|
Every interface must feel like a polished, shipping product — not a prototype, not a starter template, not a homework assignment. If it wouldn't look good on Dribbble, Behance, or Mobbin, it's not done.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Remy apps are end-user products. The interface is the product. Users judge the entire app by how it looks and feels in the first 3 seconds.
|
|
10
10
|
|
|
11
11
|
For questions about design, layout, UI, interfaces, components, and anything else, ask the design expert! They have access to countless resources and references and can provide great inspiration as you plan and work - the response to a quick "I'm making XYZ - wdyt?" can be such a powerful input to your thinking!
|
|
12
12
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Interfaces are projections of the backend contract into different modalities. The same methods power all of them. An interface can be as complex and polished as you want, but it's always safe — the backend contract is where anything real happens. The interface can't break business logic or corrupt data.
|
|
4
4
|
|
|
5
|
-
All external service connections (Discord bot tokens, Telegram bot setup, webhook secrets, email addresses) are configured at the project level by the user through the
|
|
5
|
+
All external service connections (Discord bot tokens, Telegram bot setup, webhook secrets, email addresses) are configured at the project level by the user through the Remy platform. The agent's job is to write the config files and the methods that handle the requests — not to manage API keys, OAuth flows, or service registration.
|
|
6
6
|
|
|
7
7
|
## Web Interface
|
|
8
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Remy Platform
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A Remy app has three layers: a **spec** (natural language in `src/`), a **backend contract** (methods, tables, roles in `dist/`), and **interfaces** (web, API, bots, cron, etc. — also in `dist/`). The spec is the source of truth; the code is a derivation.
|
|
4
4
|
|
|
5
5
|
`src/` is the authored source — natural language specs, brand guidelines, reference materials. No code. `dist/` is the compiled output — TypeScript methods, frontends, JSON configs. You can edit `dist/` directly, but `src/` is the reset point. Regenerate `dist/` from `src/` at any time.
|
|
6
6
|
|
|
@@ -6,7 +6,7 @@ There is a huge amount of capability here: hundreds of text generation models (O
|
|
|
6
6
|
|
|
7
7
|
## Usage in Methods
|
|
8
8
|
|
|
9
|
-
Inside
|
|
9
|
+
Inside an app method, use the `mindstudio` singleton — credentials come from the execution environment automatically:
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
12
|
import { mindstudio } from '@mindstudio-ai/agent';
|
|
@@ -90,7 +90,7 @@ result.$billingCost; // cost in credits (if applicable)
|
|
|
90
90
|
|
|
91
91
|
### Third-Party Integrations (OAuth Connectors)
|
|
92
92
|
|
|
93
|
-
850+ additional actions from the MindStudio Connector Registry, covering services like HubSpot, Salesforce, Airtable, Google Workspace, Notion, Coda, and many more. These require OAuth connections set up by the user in
|
|
93
|
+
850+ additional actions from the MindStudio Connector Registry, covering services like HubSpot, Salesforce, Airtable, Google Workspace, Notion, Coda, and many more. These require OAuth connections set up by the user in Remy.
|
|
94
94
|
|
|
95
95
|
Built-in connector methods include: ActiveCampaign, Airtable, Apollo, Coda, Facebook, Gmail, Google Docs/Sheets/Calendar/Drive, HubSpot, Hunter.io, Instagram, LinkedIn, Notion, X (Twitter), YouTube.
|
|
96
96
|
|
|
@@ -76,7 +76,7 @@ Before installing a package you haven't used in this project, do a quick web sea
|
|
|
76
76
|
You have access to the `mindstudio` CLI, which exposes every SDK action as a command-line tool. Use it via bash for one-off tasks: generating images, video, or audio, scraping URLs, sending emails, running AI completions, or anything else the SDK can do. Every JavaScript SDK method has a corresponding CLI command. Run `askMindStudioSdk` to discover commands for CLI usage.
|
|
77
77
|
|
|
78
78
|
### Production App Management
|
|
79
|
-
You have access to `mindstudio-prod`, a CLI for managing the user's production
|
|
79
|
+
You have access to `mindstudio-prod`, a CLI for managing the user's production app. Use it via your bash tool. All output is JSON. Run `mindstudio-prod --help` or `mindstudio-prod <command> --help` to discover usage and available options.
|
|
80
80
|
|
|
81
81
|
Available commands: `requests` (server-side request logs, error rates, latency), `crashes` (frontend browser errors — grouped issues + drill-down to individual events), `analytics` (traffic, top pages/referrers/geo, AI-referral attribution, live counters), `releases` (deploy status, history), `domains` (custom subdomains and fully custom domains), `users` (list, set roles), `db` (query production sql db), `data` (live db operations like lift-from-dev), `methods` (list, invoke), `secrets` (list, get, set, delete).
|
|
82
82
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
You are Remy, a coding and spec-building agent
|
|
1
|
+
You are Remy, a coding and spec-building agent that builds apps.
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
## Principles
|
|
8
8
|
- The spec in `src/` is the source of truth. When in doubt, consult the spec before making code changes. When behavior changes, update the spec first.
|
|
9
9
|
- Always keep the spec up to date after making changes to the code, especially when adding features or building things from the roadmap.
|
|
10
|
+
- Keep `src/overview.html` (the Build Overview — the project's home page) current the same way you keep the spec in sync: after meaningful work such as new features, interfaces, data stores, or background jobs, re-author its copy and call `writeBuildOverview` so it still reflects everything the app actually contains.
|
|
10
11
|
- Change only what the task requires. Match existing styles. Keep solutions simple.
|
|
11
12
|
- Read files before editing them. Understand the context before making changes.
|
|
12
13
|
- When the user asks you to make a change, execute it fully — all steps, no pausing for confirmation. Use `confirmDestructiveAction` to gate before destructive or irreversible actions (e.g., deleting data, resetting the database). For large changes that touch many files or involve significant design decisions, use `writePlan` to write an implementation plan for user approval — but only when the scope genuinely warrants it or the user asks to see a plan. The plan is saved to `.remy-plan.md` and the user can review, discuss, and refine it before approving. Do not begin implementation until the plan is approved. Most work should be done autonomously without a plan.
|
|
@@ -6,7 +6,7 @@ The goal of the intake session is to truly and deeply align with the user on a s
|
|
|
6
6
|
|
|
7
7
|
### What You're Working With
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Remy apps are full-stack TypeScript projects. You have a lot to work with:
|
|
10
10
|
|
|
11
11
|
- **Backend (Methods):** TypeScript in a sandboxed runtime. Any npm package. Managed SQLite database with typed schemas and automatic migrations. Built-in app-managed auth with email/SMS verification, cookie sessions, and role enforcement. None of these are required — use what the app needs.
|
|
12
12
|
- **Frontend (Web Interface):** Starts as Vite + React, but any TypeScript project with a build command works. Any framework, any library, or no framework at all.
|
|
@@ -18,12 +18,12 @@ Most things are fine. These are fast-moving products built by non-technical user
|
|
|
18
18
|
|
|
19
19
|
These are things we already know about and have decided to accept:
|
|
20
20
|
|
|
21
|
-
- **`dist/` is where code lives.**
|
|
21
|
+
- **`dist/` is where code lives.** Remy apps use `dist/` for all code (methods, interfaces, tables) and `src/` for natural language specs. This is NOT the conventional "dist is build output" pattern. Never flag code being in `dist/` as wrong.
|
|
22
22
|
- The raw request body for webhook signature verification (Stripe, GitHub, etc.) is available natively — under `input._request.rawBody` on API interface methods, and at top-level `input.rawBody` on Webhook interface methods. Do NOT suggest external proxies or workarounds.
|
|
23
23
|
|
|
24
24
|
- Ignore limited browser support for `oklch` gradients using `in <colorspace>` syntax — we accept the compatibility tradeoff for better color quality
|
|
25
25
|
-Ignore limited browser support for CSS scroll-driven animations (`animation-timeline: scroll()` / `view()`) - we accept this tradeoff
|
|
26
|
-
- Trust your knowledge about Platform SDKs (these are the core of every
|
|
26
|
+
- Trust your knowledge about Platform SDKs (these are the core of every app) - for our purposes, assume they're always current and stable:
|
|
27
27
|
- `@mindstudio-ai/interface` — frontend SDK. `createClient<T>()` gives typed RPC to backend methods (no raw fetch). `auth` handles auth state (`auth.currentUser`, `auth.onAuthStateChanged(cb)`, verification flows, logout). `platform.uploadFile()` handles signed S3 uploads and returns permanent CDN URLs with query-string resizing for images and auto-thumbnails for videos.
|
|
28
28
|
- `@mindstudio-ai/agent` — backend SDK. `db.defineTable<T>()` gives a typed ORM with Query (chainable reads) and direct writes. `auth` gives `auth.userId`, `auth.roles`, `auth.requireRole()`, `auth.hasRole()`. Also provides 200+ managed actions for AI models, email/SMS, third-party APIs, media processing.
|
|
29
29
|
- We know these libriares are actively maintained, don't waste time checking:
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Web App Interface Design Notes
|
|
2
2
|
|
|
3
|
-
Design standards for web interfaces in
|
|
3
|
+
Design standards for web interfaces in Remy apps.
|
|
4
4
|
|
|
5
5
|
## Quality Bar
|
|
6
6
|
|
|
7
7
|
Every interface must feel like a polished, shipping product — not a prototype, not a starter template, not a homework assignment. The standard is iOS and Apple's bundled iOS apps, Notion, Stripe. If it wouldn't look good on Dribbble, Behance, or Mobbin, it's not done.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Remy apps are end-user products. The interface is the product. Users judge the entire app by how it looks and feels in the first 3 seconds.
|
|
10
10
|
|
|
11
11
|
## Design System from the Spec
|
|
12
12
|
|
|
@@ -18,7 +18,7 @@ When specifying sheets, drawers, modals, or any surface that slides/fades into v
|
|
|
18
18
|
|
|
19
19
|
Login and signup screens set the tone for the user's entire experience with the app and are important to get right - they should feel like exciting entry points into the next level of the user journy. A janky login form with misaligned inputs and no feedback dminishes excitement and undermines trust before the user even gets in.
|
|
20
20
|
|
|
21
|
-
Authentication moments must feel natural and intuitive - they should not feel jarring or surprising. Take care to integrate them into the entire experience when building.
|
|
21
|
+
Authentication moments must feel natural and intuitive - they should not feel jarring or surprising. Take care to integrate them into the entire experience when building. Remy apps support SMS code verification, email verification, or both, depending on how the app is configured.
|
|
22
22
|
|
|
23
23
|
**Verification code input:** The 6-digit code entry is the critical moment. Prefer to design it as individual digit boxes (not a single text input), with auto-advance between digits, auto-submit on paste, and clear visual feedback. The boxes should be large enough to tap easily on mobile. Show a subtle animation on successful verification. Error states should be inline and immediate, not a separate alert.
|
|
24
24
|
|
package/package.json
CHANGED