@mindstudio-ai/remy 0.1.69 → 0.1.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/headless.js +94 -21
- package/dist/index.js +97 -22
- package/dist/prompt/compiled/auth.md +207 -32
- package/dist/prompt/compiled/interfaces.md +8 -4
- package/dist/prompt/compiled/manifest.md +21 -0
- package/dist/prompt/compiled/methods.md +2 -4
- package/dist/prompt/compiled/platform.md +1 -1
- package/dist/prompt/compiled/tables.md +10 -0
- package/dist/prompt/static/authoring.md +13 -3
- package/dist/prompt/static/coding.md +13 -0
- package/dist/prompt/static/intake.md +2 -1
- package/dist/subagents/browserAutomation/prompt.md +4 -1
- package/dist/subagents/designExpert/prompts/ui-patterns.md +14 -0
- package/package.json +1 -1
|
@@ -1,31 +1,147 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Auth
|
|
2
2
|
|
|
3
|
-
MindStudio apps
|
|
3
|
+
MindStudio 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
|
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
In `mindstudio.json`:
|
|
7
|
+
## Manifest Config
|
|
10
8
|
|
|
11
9
|
```json
|
|
12
10
|
{
|
|
11
|
+
"auth": {
|
|
12
|
+
"enabled": true,
|
|
13
|
+
"methods": ["email-code", "sms-code"],
|
|
14
|
+
"table": {
|
|
15
|
+
"name": "users",
|
|
16
|
+
"columns": {
|
|
17
|
+
"email": "email",
|
|
18
|
+
"phone": "phone",
|
|
19
|
+
"roles": "roles"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
13
23
|
"roles": [
|
|
14
|
-
{ "id": "
|
|
15
|
-
{ "id": "
|
|
16
|
-
{ "id": "admin", "name": "
|
|
17
|
-
{ "id": "ap", "name": "Accounts Payable", "description": "Processes invoices and payments." }
|
|
24
|
+
{ "id": "vendor", "name": "Vendor" },
|
|
25
|
+
{ "id": "buyer", "name": "Buyer" },
|
|
26
|
+
{ "id": "admin", "name": "Admin" }
|
|
18
27
|
]
|
|
19
28
|
}
|
|
20
29
|
```
|
|
21
30
|
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
- `
|
|
31
|
+
- **`auth.enabled`** — opt-in. No auth config = anonymous guest sessions.
|
|
32
|
+
- **`auth.methods`** — which verification methods the app supports. At least one required.
|
|
33
|
+
- `email-code` — 6-digit code sent via email
|
|
34
|
+
- `sms-code` — 6-digit code sent via SMS
|
|
35
|
+
- **`auth.table.name`** — name of the `defineTable` table that holds user records.
|
|
36
|
+
- **`auth.table.columns`** — maps platform-managed fields to column names in the developer's table.
|
|
37
|
+
- `email` — required if `email-code` is in methods
|
|
38
|
+
- `phone` — required if `sms-code` is in methods
|
|
39
|
+
- `roles` — optional. Maps to a JSON array column for role assignments.
|
|
40
|
+
- **`roles`** — declares valid roles for the app. Same as before: `id`, `name`, optional `description`.
|
|
41
|
+
|
|
42
|
+
## Auth Table
|
|
43
|
+
|
|
44
|
+
The user table is a regular `defineTable` table. The platform manages the auth-mapped columns; all other columns are the developer's domain.
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { db } from '@mindstudio-ai/agent';
|
|
48
|
+
|
|
49
|
+
export const Users = db.defineTable<{
|
|
50
|
+
// Mapped to auth — platform keeps these in sync
|
|
51
|
+
email: string;
|
|
52
|
+
phone?: string;
|
|
53
|
+
roles: string[];
|
|
54
|
+
// Developer's own fields
|
|
55
|
+
displayName: string;
|
|
56
|
+
plan: 'free' | 'pro';
|
|
57
|
+
avatarUrl?: string;
|
|
58
|
+
}>('users');
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Platform-Managed Column Behavior
|
|
62
|
+
|
|
63
|
+
- **`email` / `phone`** — read-only from code. Writing via `update()` or `push()` throws a `MindStudioError`. Use the auth API to change a user's email or phone.
|
|
64
|
+
- **`roles`** — read/write from both code and the dashboard. `Users.update(userId, { roles: ['admin'] })` works and syncs to the platform. Dashboard role changes sync back to the table.
|
|
65
|
+
- All other columns are fully the developer's.
|
|
66
|
+
|
|
67
|
+
## Frontend Auth (Interface SDK)
|
|
68
|
+
|
|
69
|
+
The developer builds their own login/signup UI. The SDK provides methods that handle the verification flow and session management.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { auth } from '@mindstudio-ai/interface';
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### User Shape
|
|
25
76
|
|
|
26
|
-
|
|
77
|
+
```typescript
|
|
78
|
+
interface AppUser {
|
|
79
|
+
id: string;
|
|
80
|
+
email: string | null;
|
|
81
|
+
phone: string | null;
|
|
82
|
+
roles: string[];
|
|
83
|
+
createdAt: string;
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`auth.getCurrentUser()` returns `AppUser | null`. `null` means unauthenticated.
|
|
88
|
+
|
|
89
|
+
### State (sync)
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
auth.getCurrentUser() // AppUser | null
|
|
93
|
+
auth.isAuthenticated() // boolean
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Email Code Flow
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
const { verificationId } = await auth.sendEmailCode('user@example.com');
|
|
100
|
+
// User enters the 6-digit code from their email
|
|
101
|
+
const user = await auth.verifyEmailCode(verificationId, '123456');
|
|
102
|
+
// user is now authenticated — auth.getCurrentUser() returns the AppUser
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### SMS Code Flow
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const { verificationId } = await auth.sendSmsCode('+15551234567');
|
|
109
|
+
const user = await auth.verifySmsCode(verificationId, '123456');
|
|
110
|
+
```
|
|
27
111
|
|
|
28
|
-
|
|
112
|
+
### Email/Phone Changes (must be authenticated)
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
await auth.requestEmailChange('newemail@example.com');
|
|
116
|
+
const user = await auth.confirmEmailChange('newemail@example.com', '123456');
|
|
117
|
+
|
|
118
|
+
await auth.requestPhoneChange('+15559876543');
|
|
119
|
+
const user = await auth.confirmPhoneChange('+15559876543', '123456');
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Logout
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
await auth.logout(); // clears session
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Phone Helpers
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
auth.phone.countries // ~180 countries with { code, dialCode, name, flag }
|
|
132
|
+
auth.phone.detectCountry() // guess from timezone, e.g. 'US'
|
|
133
|
+
auth.phone.toE164('5551234567', 'US') // '+15551234567'
|
|
134
|
+
auth.phone.format('+15551234567') // '+1 (555) 123-4567'
|
|
135
|
+
auth.phone.isValid('+15551234567') // true
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Email Helpers
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
auth.email.isValid('user@example.com') // true
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Backend Auth (Agent SDK)
|
|
29
145
|
|
|
30
146
|
```typescript
|
|
31
147
|
import { auth } from '@mindstudio-ai/agent';
|
|
@@ -33,45 +149,104 @@ import { auth } from '@mindstudio-ai/agent';
|
|
|
33
149
|
|
|
34
150
|
### `auth.requireRole(...roles)`
|
|
35
151
|
|
|
36
|
-
Throws
|
|
152
|
+
Throws 403 if the current user doesn't have **any** of the specified roles.
|
|
37
153
|
|
|
38
154
|
```typescript
|
|
39
|
-
auth.requireRole('admin');
|
|
40
|
-
auth.requireRole('admin', 'approver');
|
|
155
|
+
auth.requireRole('admin');
|
|
156
|
+
auth.requireRole('admin', 'approver'); // any of these
|
|
41
157
|
```
|
|
42
158
|
|
|
43
159
|
### `auth.hasRole(...roles)`
|
|
44
160
|
|
|
45
|
-
Returns `boolean`. Same logic as `requireRole` but doesn't throw.
|
|
161
|
+
Returns `boolean`. Same logic as `requireRole` but doesn't throw.
|
|
46
162
|
|
|
47
163
|
### `auth.userId`
|
|
48
164
|
|
|
49
|
-
The current user's
|
|
165
|
+
The current user's ID (the row ID in the auth table). Always available when auth is enabled.
|
|
50
166
|
|
|
51
167
|
### `auth.roles`
|
|
52
168
|
|
|
53
|
-
Array of role
|
|
169
|
+
Array of role IDs assigned to the current user.
|
|
54
170
|
|
|
55
171
|
### `auth.getUsersByRole(role)`
|
|
56
172
|
|
|
57
|
-
Returns an array of user IDs
|
|
173
|
+
Returns an array of user IDs with the specified role.
|
|
58
174
|
|
|
59
|
-
##
|
|
175
|
+
## Login Page Example
|
|
60
176
|
|
|
61
|
-
```
|
|
177
|
+
```tsx
|
|
62
178
|
import { auth } from '@mindstudio-ai/interface';
|
|
63
179
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
180
|
+
function LoginPage() {
|
|
181
|
+
const [email, setEmail] = useState('');
|
|
182
|
+
const [code, setCode] = useState('');
|
|
183
|
+
const [verificationId, setVerificationId] = useState('');
|
|
184
|
+
const [codeSent, setCodeSent] = useState(false);
|
|
185
|
+
|
|
186
|
+
const handleSendCode = async () => {
|
|
187
|
+
const { verificationId } = await auth.sendEmailCode(email);
|
|
188
|
+
setVerificationId(verificationId);
|
|
189
|
+
setCodeSent(true);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const handleVerify = async () => {
|
|
193
|
+
await auth.verifyEmailCode(verificationId, code);
|
|
194
|
+
window.location.href = '/dashboard';
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
if (!codeSent) {
|
|
198
|
+
return (
|
|
199
|
+
<div>
|
|
200
|
+
<h1>Sign in</h1>
|
|
201
|
+
<input placeholder="Email" value={email} onChange={e => setEmail(e.target.value)} />
|
|
202
|
+
<button onClick={handleSendCode}>Send code</button>
|
|
203
|
+
</div>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return (
|
|
208
|
+
<div>
|
|
209
|
+
<p>Enter the code we sent to {email}</p>
|
|
210
|
+
<input placeholder="123456" value={code} onChange={e => setCode(e.target.value)} />
|
|
211
|
+
<button onClick={handleVerify}>Verify</button>
|
|
212
|
+
</div>
|
|
213
|
+
);
|
|
214
|
+
}
|
|
68
215
|
```
|
|
69
216
|
|
|
70
|
-
|
|
217
|
+
## Backend Method Example
|
|
71
218
|
|
|
72
219
|
```typescript
|
|
73
|
-
|
|
74
|
-
{
|
|
220
|
+
import { auth } from '@mindstudio-ai/agent';
|
|
221
|
+
import { Users } from './tables/users';
|
|
222
|
+
|
|
223
|
+
export async function getDashboard() {
|
|
224
|
+
const user = await Users.get(auth.userId);
|
|
225
|
+
|
|
226
|
+
if (auth.hasRole('admin')) {
|
|
227
|
+
const allUsers = await Users.toArray();
|
|
228
|
+
return { user, allUsers, isAdmin: true };
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return { user, isAdmin: false };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export async function promoteToAdmin(input: { userId: string }) {
|
|
235
|
+
auth.requireRole('admin');
|
|
236
|
+
await Users.update(input.userId, { roles: ['admin'] });
|
|
237
|
+
}
|
|
75
238
|
```
|
|
76
239
|
|
|
77
|
-
|
|
240
|
+
## Roles
|
|
241
|
+
|
|
242
|
+
Roles are declared in the manifest, stored as an array column on the user table, and enforced in backend methods. The platform manages role data across the user table and the dashboard.
|
|
243
|
+
|
|
244
|
+
- Declare roles in `mindstudio.json` with `id` and `name`
|
|
245
|
+
- The mapped `roles` column holds a JSON array of role ID strings: `["vendor", "admin"]`
|
|
246
|
+
- Writable from code: `Users.update(userId, { roles: ['admin'] })` — platform syncs automatically
|
|
247
|
+
- Writable from dashboard: MindStudio dashboard shows app users and their roles
|
|
248
|
+
- Backend enforcement: `auth.requireRole('admin')` works as before
|
|
249
|
+
|
|
250
|
+
## Apps Without Auth
|
|
251
|
+
|
|
252
|
+
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.
|
|
@@ -74,10 +74,14 @@ const url = await platform.uploadFile(file, {
|
|
|
74
74
|
});
|
|
75
75
|
controller.abort(); // cancels the upload
|
|
76
76
|
|
|
77
|
-
//
|
|
78
|
-
auth.
|
|
79
|
-
auth.
|
|
80
|
-
auth.email
|
|
77
|
+
// Auth (for apps with auth enabled in manifest)
|
|
78
|
+
auth.getCurrentUser() // AppUser { id, email, phone, roles, createdAt } | null
|
|
79
|
+
auth.isAuthenticated() // boolean
|
|
80
|
+
auth.sendEmailCode(email) // → { verificationId }
|
|
81
|
+
auth.verifyEmailCode(verId, code) // → AppUser (sets session)
|
|
82
|
+
auth.sendSmsCode(phone) // → { verificationId }
|
|
83
|
+
auth.verifySmsCode(verId, code) // → AppUser (sets session)
|
|
84
|
+
auth.logout() // clears session
|
|
81
85
|
```
|
|
82
86
|
|
|
83
87
|
For apps with an agent interface, the SDK also provides `createAgentChatClient()` for thread management and streaming chat. See the "Building Agent Interfaces" section for usage details.
|
|
@@ -9,6 +9,15 @@
|
|
|
9
9
|
"appId": "e452fcf2-06c5-49e8-b4f1-6353563f24b0",
|
|
10
10
|
"name": "Procure-to-Pay",
|
|
11
11
|
|
|
12
|
+
"auth": {
|
|
13
|
+
"enabled": true,
|
|
14
|
+
"methods": ["email-code"],
|
|
15
|
+
"table": {
|
|
16
|
+
"name": "users",
|
|
17
|
+
"columns": { "email": "email", "roles": "roles" }
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
|
|
12
21
|
"roles": [
|
|
13
22
|
{ "id": "requester", "name": "Requester", "description": "Can submit vendor requests and purchase orders." },
|
|
14
23
|
{ "id": "approver", "name": "Approver", "description": "Reviews and approves purchase orders." },
|
|
@@ -56,6 +65,18 @@
|
|
|
56
65
|
### `name` (required)
|
|
57
66
|
`string`. Display name shown in the editor and workspace.
|
|
58
67
|
|
|
68
|
+
### `auth`
|
|
69
|
+
`Object`. Optional. Enables app-managed authentication. Omit for anonymous guest sessions.
|
|
70
|
+
|
|
71
|
+
| Field | Type | Required | Description |
|
|
72
|
+
|-------|------|----------|-------------|
|
|
73
|
+
| `enabled` | `boolean` | Yes | `true` to enable auth |
|
|
74
|
+
| `methods` | `string[]` | Yes | Auth methods: `"email-code"`, `"sms-code"`. At least one required. |
|
|
75
|
+
| `table.name` | `string` | Yes | Name of the `defineTable` table holding user records |
|
|
76
|
+
| `table.columns.email` | `string` | If email-code | Column name for email (platform-managed, read-only from code) |
|
|
77
|
+
| `table.columns.phone` | `string` | If sms-code | Column name for phone (platform-managed, read-only from code) |
|
|
78
|
+
| `table.columns.roles` | `string` | No | Column name for roles array (bidirectional sync) |
|
|
79
|
+
|
|
59
80
|
### `roles`
|
|
60
81
|
`Array<{ id, name?, description? }>`. Defaults to `[]`.
|
|
61
82
|
|
|
@@ -100,10 +100,8 @@ const { markdown } = await agent.scrapeUrl({
|
|
|
100
100
|
url: 'https://example.com',
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
-
//
|
|
104
|
-
const
|
|
105
|
-
userId,
|
|
106
|
-
});
|
|
103
|
+
// Look up a user from your auth table
|
|
104
|
+
const user = await Users.get(auth.userId);
|
|
107
105
|
```
|
|
108
106
|
|
|
109
107
|
No separate API keys needed — the platform routes to the correct provider (OpenAI, Anthropic, Google, etc.) automatically.
|
|
@@ -92,7 +92,7 @@ const { vendor } = await api.approveVendor({ vendorId: '...' });
|
|
|
92
92
|
## What the Platform Provides
|
|
93
93
|
|
|
94
94
|
- **Managed databases.** SQLite with typed schemas. Push a schema change and the platform diffs, migrates, and promotes atomically.
|
|
95
|
-
- **Built-in auth.**
|
|
95
|
+
- **Built-in auth.** Opt-in via manifest. Developer builds login UI, platform handles verification codes (email/SMS), cookie sessions, and role enforcement. Backend methods use `auth.requireRole('admin')` for access control.
|
|
96
96
|
- **Multiple interfaces, one codebase.** Web, API, Discord, Telegram, Cron, Webhook, Email, MCP — all invoke the same methods. Methods don't know which interface called them.
|
|
97
97
|
- **Sandboxed execution.** Methods run in isolated sandboxes with npm packages pre-installed.
|
|
98
98
|
- **Git-native deployment.** Push to default branch to deploy. Push to feature branch for preview. Rollback is a git revert.
|
|
@@ -68,6 +68,16 @@ Every table automatically has these columns. The SDK adds them to the TypeScript
|
|
|
68
68
|
| `updated_at` | `number` (unix ms) | Updated on every write |
|
|
69
69
|
| `last_updated_by` | `string` | Set from the current user's auth context |
|
|
70
70
|
|
|
71
|
+
### Auth-Managed Columns
|
|
72
|
+
|
|
73
|
+
When a table is configured as the auth table in the manifest (`auth.table`), some columns have special behavior:
|
|
74
|
+
|
|
75
|
+
- **`email` / `phone`** (mapped columns) — read-only from code. Writing via `push()`, `update()`, or `upsert()` throws a `MindStudioError`. Use the auth API (`auth.requestEmailChange()` etc.) to change these.
|
|
76
|
+
- **`roles`** (mapped column) — read/write from both code and the dashboard. Writes sync automatically to the platform.
|
|
77
|
+
- All other columns on the auth table behave normally.
|
|
78
|
+
|
|
79
|
+
### Reading System Columns
|
|
80
|
+
|
|
71
81
|
These are always available on read results:
|
|
72
82
|
|
|
73
83
|
```typescript
|
|
@@ -21,9 +21,9 @@ The scaffold starts with these spec files that cover the full picture of the app
|
|
|
21
21
|
|
|
22
22
|
These are starting points, not constraints. Create as many spec files as the project needs — the `src/` folder is your workspace and every `.md` file in it becomes compilation context. If the app has substantial content (presentation slides, copy, lesson plans, menu items, quiz questions), put it in its own file (`src/content.md`, `src/slides.md`, `src/menu.md`, etc.) rather than cramming it into `app.md` or `web.md`. If the domain is complex, split `app.md` into multiple files by area (`src/billing.md`, `src/approvals.md`). Add interface specs for other interface types (`api.md`, `cron.md`, `agent.md`, etc.) if the app uses them. Organize however serves clarity — the platform reads the entire `src/` folder.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Remember: users care about look and feel as much as (and often more than) underlying data structures. Don't treat the brand and interface specs as an afterthought — for many users, the visual identity and voice are the first things they want to get right.
|
|
25
25
|
|
|
26
|
-
Write specs in natural, human language. Describe what the app does the way you'd explain it to a colleague. The spec
|
|
26
|
+
Write specs in natural, human language. Describe what the app does the way you'd explain it to a colleague. The spec renders with annotations hidden is a human-forward document that anyone can read. The spec with annotations visible is the agent-forward document that drives code generation. Keep the prose clean and readable — the user should never see raw CSS, code, or technical values in the prose. Write "square corners on all cards" not `border-radius: 0`. Write "no shadows" not `box-shadow: none`. Technical specifics belong in annotations.
|
|
27
27
|
|
|
28
28
|
When the design expert provides specific implementation details — CSS values, spacing, font sizes, rotation angles, shadow definitions, animation timings, or things to pay special attention to or watch out for — capture them as annotations on the relevant prose. The design expert's recommendations are precise and intentional; don't summarize them into vague language. The prose describes the intent, the annotations preserve the exact values the coder needs:
|
|
29
29
|
|
|
@@ -47,8 +47,18 @@ a background with the headline overlaid where there's negative space.
|
|
|
47
47
|
city skyline, shallow depth of field, shot on 85mm](https://i.mscdn.ai/...)
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
If the app needs users and auth, the spec should capture the user model and access boundaries clearly. Think about who uses the app and what they can see or do at each point:
|
|
51
|
+
- Which screens or content are public (anyone can see) vs. protected (requires login)?
|
|
52
|
+
- What does a brand new user see vs. a returning authenticated user? What's the signup path?
|
|
53
|
+
- If there are roles, which actions require which roles? Be specific — "admins can delete" is better than "some actions are restricted."
|
|
54
|
+
- What user profile data does the app need beyond email/phone? This shapes the auth table.
|
|
55
|
+
- Don't over-engineer auth upfront. Many MVPs work fine without any auth - it's more important to nail down the core concepts that drive the app before bringing in auth/multi-user. Many MVPs work fine with just email verification and no roles. Roles can be added later without changing the core auth flow.
|
|
56
|
+
|
|
57
|
+
**Finalizing the first draft:**
|
|
58
|
+
When you are finished with the first draft and are ready to present it to the user, call `setProjectOnboardingState({ state: "initialSpecReview" })`. This will update the interface so the user can see your work. If you do not call this, the user will not be able to see the spec in the UI.
|
|
59
|
+
|
|
50
60
|
**Refining with the user:**
|
|
51
|
-
|
|
61
|
+
Once you have written the draft and set the project onboarding state to "initialSpecReview," guide the user through the newly-written spec. Don't just ask "does this look good?" — the user is seeing a multi-section spec for the first time.
|
|
52
62
|
|
|
53
63
|
- Walk them through the key decisions and the overall structure.
|
|
54
64
|
- Use `promptUser` inline to ask about specific things you're unsure about or assumptions you flagged ("I assumed approvals go to the team lead — should it be the department manager?", "Do you need an API interface or just the web UI?").
|
|
@@ -28,5 +28,18 @@ Process logs are available at .logs/ in NDJSON format (one JSON object per line)
|
|
|
28
28
|
### MindStudio SDK
|
|
29
29
|
For any work involving AI models, external actions (web scraping, email, SMS), or third-party API/OAuth connections, prefer the `@mindstudio-ai/agent` SDK. It removes the need to research API methods, configure keys and tokens, or require the user to set up developer accounts.
|
|
30
30
|
|
|
31
|
+
### Auth
|
|
32
|
+
- Not every app needs auth, and even for apps that do need auth, not every screen needs auth. Think intentionally about places where auth is required. Don't make auth be the first thing a user sees - that's jarring. Only show auth at intuitive and natural moments in the user's journey - be thoughtful about how to implement auth in the UI.
|
|
33
|
+
- Frontend interfaces are always untrusted. Always enforce auth in backend methods. Use frontend auth and role information as a hint to conditionally show/hide UI to make the experience pleasant and seamless for users depending on their state, but remember to always use backend methods for gating data that is conditional on auth.
|
|
34
|
+
- For signup and login, verification code inputs must feel polished — clear feedback on send, auto-send on paste, a "resend" option, and error messages for wrong/expired codes.
|
|
35
|
+
- The auth table is the user profile. Add custom fields (displayName, avatar, plan, etc.) alongside the platform-managed columns. Don't create a separate profile table.
|
|
36
|
+
- For apps with roles, create scenarios that seed users with different roles so the developer can test each perspective. Use the scenario `roles` field for impersonation.
|
|
37
|
+
|
|
38
|
+
### State Management
|
|
39
|
+
- Calls to methods introduce latency. When building web frontends that load data from methods, consider front-loading as much data as you can in a single API request - e.g., when possible, load a large data object into a central store and use that to render sub-screens in an app, rather than an API call on every screen.
|
|
40
|
+
|
|
41
|
+
### Build Notes
|
|
42
|
+
For complex builds that span many files — especially an initial buildout from a spec — write a `.remy-notes.md` scratchpad in the project root. Use it to record decisions, keep a checklist of tasks, and reference data you'll need across multiple tool calls: design tokens, color values, typography specs, image URLs, what's been built so far, what's left. Read it back instead of restating everything in your messages. Delete it when the build is done. Don't use this for small changes or single-file edits.
|
|
43
|
+
|
|
31
44
|
### Dependencies
|
|
32
45
|
Before installing a package you haven't used in this project, do a quick web search to confirm it's still the best option. The JavaScript ecosystem moves fast — the package you remember from training may have been superseded by something smaller, faster, or better maintained. A 10-second search beats debugging a deprecated library.
|
|
@@ -6,6 +6,7 @@ The user just arrived at a blank project with a full-screen chat. They may have
|
|
|
6
6
|
Don't list features. Frame what MindStudio does through the lens of what the user wants. A MindStudio app is a managed TypeScript project with a backend, optional database, optional auth, and one or more interfaces. The key is that it's extremely flexible — here are some examples of what people build:
|
|
7
7
|
|
|
8
8
|
- **Business tools** — dashboards, admin panels, approval workflows, data entry apps, internal tools with role-based access
|
|
9
|
+
- **General purpose apps** - social networks, membership sites, communities, single or multi-user apps of all varieties.
|
|
9
10
|
- **AI-powered apps** — chatbots, content generators, document processors, image/video tools, conversational agents with tool access, AI agents that take actions (send emails, update CRMs, post to Slack)
|
|
10
11
|
- **Automations with no UI** — a set of cron jobs that scrape websites and send alerts, a webhook handler that syncs data between services, an email processor that triages inbound support requests
|
|
11
12
|
- **Conversational AI Agents** - Full conversational AI agents with custom frontends and access to the app's methods as tools. Make all or only a subset of app functionality available - manage access to methods on a per-user basis; fully custom chat UIs, use any model you want, including Gemini, GPT, Anthropic Claude, and any of the hundreds of other models MindStudio supports automatically.
|
|
@@ -42,4 +43,4 @@ Keep chat brief. Your goal is to understand the general idea, not to nail every
|
|
|
42
43
|
- Do not try to collect everything through chat. Use forms for structured details — they're less taxing for the user and produce better answers.
|
|
43
44
|
|
|
44
45
|
**When intake is done:**
|
|
45
|
-
Once you have a clear enough picture (the core data model, the key workflows, who uses it,
|
|
46
|
+
Once you have a clear enough picture (the core data model, the key workflows, who uses it, which interfaces matter, and how they will be designed/laid out), let the user know you are about to write the spec, and then follow the instructions in <spec_authoring_instructions> to begin writing the spec.
|
|
@@ -4,7 +4,10 @@ You are a browser smoke test agent. You verify that features work end to end by
|
|
|
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
5
|
|
|
6
6
|
## Tester Persona
|
|
7
|
-
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
|
|
7
|
+
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.
|
|
8
|
+
|
|
9
|
+
### Auth Testing
|
|
10
|
+
When the app has a login or signup flow, you must use `remy@mindstudio.ai` for email and `+15551234567` for phone number. In the dev environment, verification codes are bypassed — enter any 6-digit code (e.g., `123456`) and it will be accepted. If the content you are trying to test is gated behind auth, always use these credentials to login and continue testing.
|
|
8
11
|
|
|
9
12
|
## Browser Commands
|
|
10
13
|
### Snapshot format
|
|
@@ -10,6 +10,20 @@ When descirbing UI patterns to the developer, be verbose and explicit. Describe
|
|
|
10
10
|
|
|
11
11
|
The design should look like it could be an Apple iOS/macOS app of the year winner for 2026. Avoid long pages, things that feel like blogs, things that borrow from "dated" app store apps, and the like. It should feel like an award winner from the past two years, not an award winner from a decade ago.
|
|
12
12
|
|
|
13
|
+
### Notes for Designing Auth Flows
|
|
14
|
+
|
|
15
|
+
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.
|
|
16
|
+
|
|
17
|
+
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.
|
|
18
|
+
|
|
19
|
+
**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.
|
|
20
|
+
|
|
21
|
+
**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" to "enter code" should feel smooth, not like a page reload.
|
|
22
|
+
|
|
23
|
+
**The overall login page:** This is a branding moment. Use the app's full visual identity — colors, typography, any 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 should feel like it belongs to this specific app.
|
|
24
|
+
|
|
25
|
+
**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.
|
|
26
|
+
|
|
13
27
|
### Notes for Designing AI Chat Interfaces
|
|
14
28
|
|
|
15
29
|
If the app includes an AI chat interface, take care to make it beautiful and intentional. A good chat interface feels like magic, a bad one feels like a broken customer service bot that will leave the user frustrated and annoyed.
|