@mindstudio-ai/remy 0.1.114 → 0.1.116
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/automatedActions/buildFromInitialSpec.md +7 -6
- package/dist/headless.js +49 -1
- package/dist/index.js +49 -1
- package/dist/prompt/compiled/auth.md +84 -10
- package/dist/prompt/compiled/design.md +1 -19
- package/dist/prompt/compiled/interfaces.md +4 -2
- package/dist/prompt/static/authoring.md +1 -1
- package/dist/prompt/static/team.md +1 -1
- package/dist/subagents/browserAutomation/prompt.md +5 -3
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
This is an automated action triggered by the user pressing "Build" in the editor after reviewing the spec.
|
|
6
6
|
|
|
7
|
-
The user has reviewed the spec and is ready to build. There are four phases to building: planning, coding,
|
|
7
|
+
The user has reviewed the spec and is ready to build. There are four phases to building: planning, coding, verifying, polishing. Execute each phase in order in a single turn.
|
|
8
8
|
|
|
9
9
|
## Planning
|
|
10
10
|
Think about your approach and then get a quick sanity check from `codeSanityCheck` to make sure you aren't missing anything.
|
|
@@ -14,14 +14,15 @@ If you are building a web frontend, consult `visualDesignExpert` for guidance an
|
|
|
14
14
|
## Building
|
|
15
15
|
Then, build everything in one turn: methods, tables, interfaces, manifest updates, and scenarios, using the spec as the master plan. Be sure to delete any unnecessary files from the "Hello World" scaffold that already exist in the project - don't forget to update the page metadata on index.html too.
|
|
16
16
|
|
|
17
|
-
## Polishing
|
|
18
|
-
When code generation is complete, take a step back and do an explicit polish pass before verifying. Re-read the spec files and the design expert's guidance, then walk through each frontend file looking for design details that got skipped in the initial build: animations, transitions, hover states, micro-interactions, spring physics, entrance reveals, gesture handling, layout issues, and anything else. The initial build prioritizes getting everything connected and functional, but this pass closes the gap between "it works" and "it feels great." In many ways this is the most important part of the initial build, as the user's first experience of the deliverable will set their expectations for every iteration that follows. Don't mess this up.
|
|
19
|
-
|
|
20
17
|
## Verifying
|
|
21
18
|
- First, run use `runScenario` to seed test data, then use `runMethod` to confirm important methods work
|
|
22
19
|
- If the app has a web frontend, check the browser logs to make sure there are no errors rendering it.
|
|
23
|
-
-
|
|
24
|
-
- Finally, use `runAutomatedBrowserTest` to smoke-test the main UI flow. The dev database is a disposable snapshot, so don't worry about being destructive. Fix any errors before finishing.
|
|
20
|
+
- Use `runAutomatedBrowserTest` to smoke-test the main UI flow. The dev database is a disposable snapshot, so don't worry about being destructive. Fix any errors before finishing.
|
|
25
21
|
- If there is a scenario that seeds the app with mock data, use it to present the app to the user with initial data seeded, so they can see and play with the real app. Let the user know they can reset the app using a scenario to empty it if they wish. Showing the user something they can play with immediately is important when it comes to landing a strong first impression.
|
|
26
22
|
|
|
23
|
+
## Polishing
|
|
24
|
+
When code generation is complete, take a step back and do an explicit polish pass before verifying. Re-read the spec files and the design expert's guidance, then walk through each frontend file looking for design details that got skipped in the initial build: animations, transitions, hover states, micro-interactions, spring physics, entrance reveals, gesture handling, layout issues, and anything else. The initial build prioritizes getting everything connected and functional, but this pass closes the gap between "it works" and "it feels great." In many ways this is the most important part of the initial build, as the user's first experience of the deliverable will set their expectations for every iteration that follows. Don't mess this up.
|
|
25
|
+
|
|
26
|
+
Then, ask the `visualDesignExpert` to take a screenshot and verity that the visual design looks correct. Fix any issues it flags - we want the user's first time seeing the finished product to truly wow them.
|
|
27
|
+
|
|
27
28
|
When everything is working, use `productVision` to mark the MVP roadmap item as done, then call `setProjectOnboardingState({ state: "onboardingFinished" })`.
|
package/dist/headless.js
CHANGED
|
@@ -3162,6 +3162,39 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3162
3162
|
|
|
3163
3163
|
// src/subagents/browserAutomation/tools.ts
|
|
3164
3164
|
var BROWSER_TOOLS = [
|
|
3165
|
+
{
|
|
3166
|
+
clearable: false,
|
|
3167
|
+
name: "setupBrowser",
|
|
3168
|
+
description: "Pre-authenticate the browser and optionally navigate to a starting page. Call this before interacting with authenticated content instead of manually logging in. Auth is optional \u2014 omit to just navigate without authenticating.",
|
|
3169
|
+
inputSchema: {
|
|
3170
|
+
type: "object",
|
|
3171
|
+
properties: {
|
|
3172
|
+
auth: {
|
|
3173
|
+
type: "object",
|
|
3174
|
+
description: "Authentication config. Upserts the user if they don't exist.",
|
|
3175
|
+
properties: {
|
|
3176
|
+
email: {
|
|
3177
|
+
type: "string",
|
|
3178
|
+
description: "User email address."
|
|
3179
|
+
},
|
|
3180
|
+
phone: {
|
|
3181
|
+
type: "string",
|
|
3182
|
+
description: "User phone number."
|
|
3183
|
+
},
|
|
3184
|
+
roles: {
|
|
3185
|
+
type: "array",
|
|
3186
|
+
items: { type: "string" },
|
|
3187
|
+
description: "Roles to set on the user."
|
|
3188
|
+
}
|
|
3189
|
+
}
|
|
3190
|
+
},
|
|
3191
|
+
path: {
|
|
3192
|
+
type: "string",
|
|
3193
|
+
description: 'Navigate to this path after setup (default "/").'
|
|
3194
|
+
}
|
|
3195
|
+
}
|
|
3196
|
+
}
|
|
3197
|
+
},
|
|
3165
3198
|
{
|
|
3166
3199
|
clearable: true,
|
|
3167
3200
|
name: "browserCommand",
|
|
@@ -3334,6 +3367,21 @@ var browserAutomationTool = {
|
|
|
3334
3367
|
tools: BROWSER_TOOLS,
|
|
3335
3368
|
externalTools: BROWSER_EXTERNAL_TOOLS,
|
|
3336
3369
|
executeTool: async (name, _input, _toolCallId, onLog) => {
|
|
3370
|
+
if (name === "setupBrowser") {
|
|
3371
|
+
try {
|
|
3372
|
+
const result2 = await sidecarRequest(
|
|
3373
|
+
"/setup-browser",
|
|
3374
|
+
{
|
|
3375
|
+
auth: _input.auth,
|
|
3376
|
+
path: _input.path
|
|
3377
|
+
},
|
|
3378
|
+
{ timeout: 15e3 }
|
|
3379
|
+
);
|
|
3380
|
+
return JSON.stringify(result2);
|
|
3381
|
+
} catch (err) {
|
|
3382
|
+
return `Error setting up browser: ${err.message}`;
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3337
3385
|
if (name === "screenshotFullPage") {
|
|
3338
3386
|
try {
|
|
3339
3387
|
return await captureAndAnalyzeScreenshot({
|
|
@@ -3605,7 +3653,7 @@ var definition5 = {
|
|
|
3605
3653
|
},
|
|
3606
3654
|
instructions: {
|
|
3607
3655
|
type: "string",
|
|
3608
|
-
description: "If the screenshot you need requires interaction first (dismissing a modal, clicking a tab, filling out a form, navigating a flow), describe the steps to get there. A browser automation agent will follow these instructions before capturing the screenshot. You will always get back a full-height screenshot of the entire page. Do not attempt to scroll or capture specific areas. Only use instructions when you need to trigger stateful changes."
|
|
3656
|
+
description: "If the screenshot you need requires interaction first (dismissing a modal, clicking a tab, filling out a form, navigating a flow, getting through a login/auth checkpoint), describe the steps to get there. A browser automation agent will follow these instructions before capturing the screenshot - it can bypass auth and get right to where it needs to be if you tell it to authenticate as a test user and give it the path/screen to start its test at. You will always get back a full-height screenshot of the entire page. Do not attempt to scroll or capture specific areas. Only use instructions when you need to trigger stateful changes. Never describe what names or values to use when applying the isntructions - the browser automation agent must use its own values for it to work properly."
|
|
3609
3657
|
}
|
|
3610
3658
|
}
|
|
3611
3659
|
}
|
package/dist/index.js
CHANGED
|
@@ -2903,6 +2903,39 @@ var init_tools = __esm({
|
|
|
2903
2903
|
"src/subagents/browserAutomation/tools.ts"() {
|
|
2904
2904
|
"use strict";
|
|
2905
2905
|
BROWSER_TOOLS = [
|
|
2906
|
+
{
|
|
2907
|
+
clearable: false,
|
|
2908
|
+
name: "setupBrowser",
|
|
2909
|
+
description: "Pre-authenticate the browser and optionally navigate to a starting page. Call this before interacting with authenticated content instead of manually logging in. Auth is optional \u2014 omit to just navigate without authenticating.",
|
|
2910
|
+
inputSchema: {
|
|
2911
|
+
type: "object",
|
|
2912
|
+
properties: {
|
|
2913
|
+
auth: {
|
|
2914
|
+
type: "object",
|
|
2915
|
+
description: "Authentication config. Upserts the user if they don't exist.",
|
|
2916
|
+
properties: {
|
|
2917
|
+
email: {
|
|
2918
|
+
type: "string",
|
|
2919
|
+
description: "User email address."
|
|
2920
|
+
},
|
|
2921
|
+
phone: {
|
|
2922
|
+
type: "string",
|
|
2923
|
+
description: "User phone number."
|
|
2924
|
+
},
|
|
2925
|
+
roles: {
|
|
2926
|
+
type: "array",
|
|
2927
|
+
items: { type: "string" },
|
|
2928
|
+
description: "Roles to set on the user."
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
},
|
|
2932
|
+
path: {
|
|
2933
|
+
type: "string",
|
|
2934
|
+
description: 'Navigate to this path after setup (default "/").'
|
|
2935
|
+
}
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
},
|
|
2906
2939
|
{
|
|
2907
2940
|
clearable: true,
|
|
2908
2941
|
name: "browserCommand",
|
|
@@ -3138,6 +3171,21 @@ var init_browserAutomation = __esm({
|
|
|
3138
3171
|
tools: BROWSER_TOOLS,
|
|
3139
3172
|
externalTools: BROWSER_EXTERNAL_TOOLS,
|
|
3140
3173
|
executeTool: async (name, _input, _toolCallId, onLog) => {
|
|
3174
|
+
if (name === "setupBrowser") {
|
|
3175
|
+
try {
|
|
3176
|
+
const result2 = await sidecarRequest(
|
|
3177
|
+
"/setup-browser",
|
|
3178
|
+
{
|
|
3179
|
+
auth: _input.auth,
|
|
3180
|
+
path: _input.path
|
|
3181
|
+
},
|
|
3182
|
+
{ timeout: 15e3 }
|
|
3183
|
+
);
|
|
3184
|
+
return JSON.stringify(result2);
|
|
3185
|
+
} catch (err) {
|
|
3186
|
+
return `Error setting up browser: ${err.message}`;
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3141
3189
|
if (name === "screenshotFullPage") {
|
|
3142
3190
|
try {
|
|
3143
3191
|
return await captureAndAnalyzeScreenshot({
|
|
@@ -3494,7 +3542,7 @@ var init_screenshot3 = __esm({
|
|
|
3494
3542
|
},
|
|
3495
3543
|
instructions: {
|
|
3496
3544
|
type: "string",
|
|
3497
|
-
description: "If the screenshot you need requires interaction first (dismissing a modal, clicking a tab, filling out a form, navigating a flow), describe the steps to get there. A browser automation agent will follow these instructions before capturing the screenshot. You will always get back a full-height screenshot of the entire page. Do not attempt to scroll or capture specific areas. Only use instructions when you need to trigger stateful changes."
|
|
3545
|
+
description: "If the screenshot you need requires interaction first (dismissing a modal, clicking a tab, filling out a form, navigating a flow, getting through a login/auth checkpoint), describe the steps to get there. A browser automation agent will follow these instructions before capturing the screenshot - it can bypass auth and get right to where it needs to be if you tell it to authenticate as a test user and give it the path/screen to start its test at. You will always get back a full-height screenshot of the entire page. Do not attempt to scroll or capture specific areas. Only use instructions when you need to trigger stateful changes. Never describe what names or values to use when applying the isntructions - the browser automation agent must use its own values for it to work properly."
|
|
3498
3546
|
}
|
|
3499
3547
|
}
|
|
3500
3548
|
}
|
|
@@ -86,11 +86,25 @@ interface AppUser {
|
|
|
86
86
|
|
|
87
87
|
`auth.getCurrentUser()` returns `AppUser | null`. `null` means unauthenticated.
|
|
88
88
|
|
|
89
|
-
### State
|
|
89
|
+
### State
|
|
90
90
|
|
|
91
91
|
```typescript
|
|
92
|
-
auth.getCurrentUser()
|
|
93
|
-
auth.
|
|
92
|
+
auth.getCurrentUser() // AppUser | null
|
|
93
|
+
auth.currentUser // AppUser | null (sync getter, same as getCurrentUser())
|
|
94
|
+
auth.isAuthenticated() // boolean
|
|
95
|
+
auth.onAuthStateChanged(cb) // fires immediately with current user, then on every
|
|
96
|
+
// auth transition (verify, confirm, logout).
|
|
97
|
+
// Returns an unsubscribe function.
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Use `onAuthStateChanged` in React instead of reading `currentUser` once at render time:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
function useAuth() {
|
|
104
|
+
const [user, setUser] = useState<AppUser | null>(null);
|
|
105
|
+
useEffect(() => auth.onAuthStateChanged(setUser), []);
|
|
106
|
+
return user;
|
|
107
|
+
}
|
|
94
108
|
```
|
|
95
109
|
|
|
96
110
|
### Email Code Flow
|
|
@@ -125,6 +139,19 @@ const user = await auth.confirmPhoneChange('+15559876543', '123456');
|
|
|
125
139
|
await auth.logout(); // clears session
|
|
126
140
|
```
|
|
127
141
|
|
|
142
|
+
### Error Codes
|
|
143
|
+
|
|
144
|
+
All auth methods throw on failure with a `code` property:
|
|
145
|
+
|
|
146
|
+
| Code | HTTP | Meaning |
|
|
147
|
+
|------|------|---------|
|
|
148
|
+
| `rate_limited` | 429 | Too many requests |
|
|
149
|
+
| `invalid_code` | 400 | Wrong verification code |
|
|
150
|
+
| `verification_expired` | 400 | Code has expired |
|
|
151
|
+
| `max_attempts_exceeded` | 400 | Too many failed attempts |
|
|
152
|
+
| `not_authenticated` | 401 | No active session |
|
|
153
|
+
| `invalid_session` | 401 | Session expired or invalid |
|
|
154
|
+
|
|
128
155
|
### Phone Helpers
|
|
129
156
|
|
|
130
157
|
```typescript
|
|
@@ -176,31 +203,56 @@ Returns an array of user IDs with the specified role.
|
|
|
176
203
|
## Login Page Example
|
|
177
204
|
|
|
178
205
|
```tsx
|
|
206
|
+
import { useState, useEffect } from 'react';
|
|
179
207
|
import { auth } from '@mindstudio-ai/interface';
|
|
208
|
+
import { useLocation } from 'wouter';
|
|
209
|
+
|
|
210
|
+
function useAuth() {
|
|
211
|
+
const [user, setUser] = useState<AppUser | null>(null);
|
|
212
|
+
useEffect(() => auth.onAuthStateChanged(setUser), []);
|
|
213
|
+
return user;
|
|
214
|
+
}
|
|
180
215
|
|
|
181
216
|
function LoginPage() {
|
|
217
|
+
const user = useAuth();
|
|
218
|
+
const [, navigate] = useLocation();
|
|
182
219
|
const [email, setEmail] = useState('');
|
|
183
220
|
const [code, setCode] = useState('');
|
|
184
221
|
const [verificationId, setVerificationId] = useState('');
|
|
185
|
-
const [
|
|
222
|
+
const [error, setError] = useState('');
|
|
223
|
+
|
|
224
|
+
// Redirect when authenticated (fires via onAuthStateChanged after verify)
|
|
225
|
+
useEffect(() => { if (user) navigate('/dashboard'); }, [user]);
|
|
186
226
|
|
|
187
227
|
const handleSendCode = async () => {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
228
|
+
try {
|
|
229
|
+
const { verificationId } = await auth.sendEmailCode(email);
|
|
230
|
+
setVerificationId(verificationId);
|
|
231
|
+
setError('');
|
|
232
|
+
} catch (err: any) {
|
|
233
|
+
setError(err.code === 'rate_limited' ? 'Too many attempts. Try again later.' : err.message);
|
|
234
|
+
}
|
|
191
235
|
};
|
|
192
236
|
|
|
193
237
|
const handleVerify = async () => {
|
|
194
|
-
|
|
195
|
-
|
|
238
|
+
try {
|
|
239
|
+
await auth.verifyEmailCode(verificationId, code);
|
|
240
|
+
// onAuthStateChanged fires, useAuth updates, redirect happens
|
|
241
|
+
} catch (err: any) {
|
|
242
|
+
if (err.code === 'invalid_code') setError('Wrong code. Try again.');
|
|
243
|
+
else if (err.code === 'verification_expired') setError('Code expired. Request a new one.');
|
|
244
|
+
else if (err.code === 'max_attempts_exceeded') setError('Too many attempts. Request a new code.');
|
|
245
|
+
else setError(err.message);
|
|
246
|
+
}
|
|
196
247
|
};
|
|
197
248
|
|
|
198
|
-
if (!
|
|
249
|
+
if (!verificationId) {
|
|
199
250
|
return (
|
|
200
251
|
<div>
|
|
201
252
|
<h1>Sign in</h1>
|
|
202
253
|
<input placeholder="Email" value={email} onChange={e => setEmail(e.target.value)} />
|
|
203
254
|
<button onClick={handleSendCode}>Send code</button>
|
|
255
|
+
{error && <p>{error}</p>}
|
|
204
256
|
</div>
|
|
205
257
|
);
|
|
206
258
|
}
|
|
@@ -210,6 +262,8 @@ function LoginPage() {
|
|
|
210
262
|
<p>Enter the code we sent to {email}</p>
|
|
211
263
|
<input placeholder="123456" value={code} onChange={e => setCode(e.target.value)} />
|
|
212
264
|
<button onClick={handleVerify}>Verify</button>
|
|
265
|
+
<button onClick={() => setVerificationId('')}>Resend</button>
|
|
266
|
+
{error && <p>{error}</p>}
|
|
213
267
|
</div>
|
|
214
268
|
);
|
|
215
269
|
}
|
|
@@ -251,3 +305,23 @@ Roles are declared in the manifest, stored as an array column on the user table,
|
|
|
251
305
|
## Apps Without Auth
|
|
252
306
|
|
|
253
307
|
Apps without `auth` in the manifest use anonymous guest sessions. No login, no user identity, no roles. This is the default and works fine for single-user apps, internal tools, and simple utilities.
|
|
308
|
+
|
|
309
|
+
## Designing Auth in Web Interfaces
|
|
310
|
+
The most imporant user experience consideration with auth is that 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.
|
|
311
|
+
|
|
312
|
+
For the overwhelming majority of apps, a user should never land on auth at the root of an app when opening it for the first time (except in cases where the app is, e.g., an internal tool or some other protected experience - and even then it should feel more like a welcome/splash screen than an error state). Users should be able to explore public resources, or at least encounter some kind of landing/introduction moment, before they get hit with a signup/login screen. Make auth feel like a natural moment in the user's journey.
|
|
313
|
+
|
|
314
|
+
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.
|
|
315
|
+
|
|
316
|
+
Consult the `visualDesignExpert` to help you work through authentication at a high level, including when and where to show auth, and the design of specific screens.
|
|
317
|
+
|
|
318
|
+
### Rules for Building Auth Screens
|
|
319
|
+
**Auth modes:** Think about which mode(s) makes the most sense for the type of app you are building. Consumer apps likely to be used on mobile should probably tend toward SMS auth as the default - business apps used on desktop make more sense to use email verification - or allow both, there's no harm in giving the user choice!
|
|
320
|
+
|
|
321
|
+
**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, a beautiful animation and 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. Make sure there is no layout shift when loading in the success/error states - loading spinners must never pop in below the input and shift the content, for example.
|
|
322
|
+
|
|
323
|
+
**The send/resend flow:** After the user enters their email or phone and taps "Send code," show clear confirmation that the code was sent ("Check your email" with the address displayed). Include a resend option with a cooldown timer (e.g., "Resend in 30s"). The transition from "enter email/phone" to "enter code" should feel smooth, not like a page reload. Always make sure the user can cancel and exit the flow (e.g., they had a typo in their email, or remembered they used a different email to sign up).
|
|
324
|
+
|
|
325
|
+
**The overall login page:** This is a branding moment. Use the app's full visual identity — colors, typography, any logos, hero imagery, or illustration. A centered card on a branded background is a classic pattern. Don't make it look like a generic SaaS login template. The login page must feel like it belongs to this specific app. Consult the `visualDesignExpert` for guidance on how to really make this shine.
|
|
326
|
+
|
|
327
|
+
**Post-login transition:** After successful verification, the transition into the app should feel seamless and instant. Avoid a blank loading screen — if data needs to load, show the app shell with skeleton states. Always make sure the user has a way of logging out.
|
|
@@ -47,6 +47,7 @@ Every interface must work on both desktop and mobile. Think about how the app wi
|
|
|
47
47
|
- On mobile, stack gracefully. Prioritize content and actions.
|
|
48
48
|
- Test at both extremes. A layout that only looks good at one breakpoint is not done.
|
|
49
49
|
- When the app is primarily mobile (e.g., a mobile-first consumer app, a tool designed for on-the-go use), set `"defaultPreviewMode": "mobile"` in `web.json` so the editor previews in a mobile viewport by default.
|
|
50
|
+
- Even for mobile-first apps, make sure to set desktop or larger device breakpoints - nothing looks jankier than opening a mobile-designed site in a desktop browser and seeing a full width bottom tab bar with nav icons stretching 1000px wide. Don't make sloppy, amateur mistakes or omissions like this - the user will notice them and be disappointed.
|
|
50
51
|
|
|
51
52
|
## Images
|
|
52
53
|
The `designExpert` can create and source amazing, high quality images, graphics, illustrations, and logos to use in the interface - both with and without transparency. This is a huge level for upgrading the premium look, feel, and quality of the app. Use image logos directly instead of plain text wordmarks; use images for empty states, onboarding screens, full-screen loading, and more.
|
|
@@ -88,25 +89,6 @@ The UI should feel instant. Never make the user wait for a server round-trip to
|
|
|
88
89
|
|
|
89
90
|
Handle errors gracefully. You don't need to design for every error case, but if remote API requests fail, make sure to show them nicely in a toast or some other appropriate view with a human-friendly label - don't just drop "Error 500 XYZ" inline in a form.
|
|
90
91
|
|
|
91
|
-
## Auth
|
|
92
|
-
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.
|
|
93
|
-
|
|
94
|
-
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. MindStudio apps support SMS code verification, email verification, or both, depending on how the app is configured.
|
|
95
|
-
|
|
96
|
-
### Rules for building auth screens
|
|
97
|
-
|
|
98
|
-
Consult the `visualDesignExpert` to help you work through authentication at a high level. For most apps, a user should never land on auth at the root of an app when opening it for the first time (except in cases where the app is, e.g., an internal tool or some other protected experience). Users should be able to explore public resources, or at least encounter some kind of landing/introduction moment, before they get hit with a signup/login screen. Make auth feel like a natural moment in the user's journey.
|
|
99
|
-
|
|
100
|
-
**Auth modes:** Think about which mode(s) makes the most sense for the type of app you are building. Consumer apps likely to be used on mobile should probably tend toward SMS auth as the default - business apps used on desktop make more sense to use email verification - or allow both, there's no harm in giving the user choice!
|
|
101
|
-
|
|
102
|
-
**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, a beautiful animation and 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. Make sure there is no layout shift when loading in the success/error states.
|
|
103
|
-
|
|
104
|
-
**The send/resend flow:** After the user enters their email or phone and taps "Send code," show clear confirmation that the code was sent ("Check your email" with the address displayed). Include a resend option with a cooldown timer (e.g., "Resend in 30s"). The transition from "enter email/phone" to "enter code" should feel smooth, not like a page reload. Always make sure the user can cancel and exit the flow (e.g., they had a typo in their email, or remembered they used a different email to sign up).
|
|
105
|
-
|
|
106
|
-
**The overall login page:** This is a branding moment. Use the app's full visual identity — colors, typography, any logos, hero imagery, or illustration. A centered card on a branded background is a classic pattern. Don't make it look like a generic SaaS login template. The login page must feel like it belongs to this specific app. Consult the `visualDesignExpert` for additional guidance.
|
|
107
|
-
|
|
108
|
-
**Post-login transition:** After successful verification, the transition into the app should feel seamless. Avoid a blank loading screen — if data needs to load, show the app shell with skeleton states. Always make sure the user has a way of logging out.
|
|
109
|
-
|
|
110
92
|
## FTUE
|
|
111
93
|
|
|
112
94
|
All interactive apps must be intuitive and easy to use. Form elements must be well-labelled. Complex interfaces should have descriptions or tooltips when helpful. Complex apps benefit from a beautiful simple onboarding modal on first use or a simple click tour. Mobile apps need a beautiful welcome screen sequence that orients the user to the app. Ask the `visualDesignExpert` for advice here.
|
|
@@ -75,8 +75,10 @@ const url = await platform.uploadFile(file, {
|
|
|
75
75
|
controller.abort(); // cancels the upload
|
|
76
76
|
|
|
77
77
|
// Auth (for apps with auth enabled in manifest)
|
|
78
|
-
auth.getCurrentUser()
|
|
79
|
-
auth.
|
|
78
|
+
auth.getCurrentUser() // AppUser { id, email, phone, roles, createdAt } | null
|
|
79
|
+
auth.currentUser // same as getCurrentUser() (sync getter)
|
|
80
|
+
auth.isAuthenticated() // boolean
|
|
81
|
+
auth.onAuthStateChanged(cb) // fires immediately + on transitions; returns unsubscribe
|
|
80
82
|
auth.sendEmailCode(email) // → { verificationId }
|
|
81
83
|
auth.verifyEmailCode(verId, code) // → AppUser (sets session)
|
|
82
84
|
auth.sendSmsCode(phone) // → { verificationId }
|
|
@@ -12,7 +12,7 @@ After intake, write the spec immediately. Do not ask "ready for me to start?" or
|
|
|
12
12
|
The scaffold starts with these spec files that cover the full picture of the app:
|
|
13
13
|
|
|
14
14
|
- **`src/app.md`** — the core application: what it does, how data flows, who's involved, the rules
|
|
15
|
-
- **`src/interfaces/web.md`** — the web interface: layout, screens, interactions,
|
|
15
|
+
- **`src/interfaces/web.md`** — the web interface: layout, screens, interactions, anduser experience, in detail
|
|
16
16
|
- **`src/interfaces/@brand/visual.md`** — aesthetic direction: the overall look, surfaces, spacing, interaction feel
|
|
17
17
|
- **`src/interfaces/@brand/colors.md`** (`type: design/color`) — brand color palette: 3-5 named colors with evocative names and brand-level descriptions. The design system is derived from these.
|
|
18
18
|
- **`src/interfaces/@brand/typography.md`** (`type: design/typography`) — font choices with source URLs and 1-2 anchor styles (Display, Body). Additional styles are derived from these anchors.
|
|
@@ -40,7 +40,7 @@ Always consult the code sanity check before writing code in initialCodegen with
|
|
|
40
40
|
|
|
41
41
|
For verifying complex stateful interactions: multi-step form submissions, auth flows, real-time updates, flows that require specific data/role setup. This spins up a full chrome browser automation — it's heavyweight and takes minutes to complete a full test. Do not use it for basic rendering or navigation checks. If you can verify something with a screenshot or by reading the code, do that instead. Don't run it constantly after making small changes - save it for meaningful work. Run a scenario first to seed test data and set user roles. The user is able to watch QA work on their screen via a live browser preview - the cursor will move, type, etc - so you can also use this to demo functionality to the user and help them understand how to use their app.
|
|
42
42
|
|
|
43
|
-
The QA agent can see the screen. Describe what to test, not how — it will figure out what to click, what to check, and what values to use.
|
|
43
|
+
The QA agent can see the screen. Describe what to test, not how — it will figure out what to click, what to check, and what values to use. By default, it always starts its tests logged out/unauthenticated on "/" root, but if you want to test a deeper piece of the app it can bypass auth and automatically authenticate itself as any user/role - just tell it to authenticate as the test user and navigate to X to start the test. After every test session, the browser is reset to / and any authentication used or created by the tester is cleared and reset.
|
|
44
44
|
|
|
45
45
|
Never tell QA what names to use when testing or what values to input - it will use its own judgment.
|
|
46
46
|
|
|
@@ -2,17 +2,19 @@ You are a browser smoke test agent. You verify that features work end to end by
|
|
|
2
2
|
|
|
3
3
|
## Rules to Remember
|
|
4
4
|
- Don't overthink the tests - the goal is to generally make sure things work as expected, not to provide detailed QA. If something seems mostly okay, note it and move on. Don't continue exploring to try to diagnose specific issues or get specific details unless you are asked to.
|
|
5
|
-
- Fail early: If you encounter a showstopper bug (something doesn't load, something is broken, etc.) do not attempt to diagnose it or work around it. Return early with a report to let the developer fix it, they'll run another test when they're ready.
|
|
5
|
+
- Fail early: If you encounter a showstopper bug (something doesn't load, something is broken, etc.) do not attempt to diagnose it or work around it. We need core common user paths to work - if they don't the app is broken and testing should not continue until it is fixed. Return early with a report to let the developer fix it, they'll run another test when they're ready.
|
|
6
6
|
|
|
7
7
|
## Tester Persona
|
|
8
8
|
The user is watching the automation happen on their screen in real-time. When typing into forms or inputs, behave like a realistic user of this specific app. Use the app context (if provided) to understand the audience and tone. Type the way that audience would actually type — not formal, not robotic. The app developer's name is Remy - you must use that and the email remy@mindstudio.ai as the basis for any testing that requires a persona.
|
|
9
9
|
|
|
10
10
|
### Auth Testing
|
|
11
|
-
When the
|
|
11
|
+
When the content you need to test is behind authentication, use the `setupBrowser` tool to automatically pre-authenticate instead of manually navigating login flows. This mints a session cookie, reloads the page with the authenticated state, and optionally navigates to a starting path. Use `remy@mindstudio.ai` as the email. If the test requires a specific role, pass it in the `roles` array.
|
|
12
|
+
|
|
13
|
+
If you need to test the login/signup flow itself (e.g., verifying the UI, error states, or the verification code input), navigate it manually: use `remy@mindstudio.ai` for email and `+15551234567` for phone. In the dev environment, verification codes are bypassed for this email and any 555-prefixed phone number — enter any 6-digit code (e.g., `123456`).
|
|
12
14
|
|
|
13
15
|
## Browser Commands
|
|
14
16
|
|
|
15
|
-
Your session always starts on the app root / in a logged out/unauthenticated state.
|
|
17
|
+
Your session always starts on the app root / in a logged out/unauthenticated state. Use `setupBrowser` to authenticate before testing protected pages.
|
|
16
18
|
|
|
17
19
|
### Snapshot format
|
|
18
20
|
|