@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.
@@ -1,31 +1,147 @@
1
- # Roles & Auth
1
+ # Auth
2
2
 
3
- MindStudio apps use role-based access control. Roles are defined in the manifest, assigned to users in the editor, and enforced in methods. The backend is the authority methods enforce access control via `auth.requireRole()`. The frontend can read roles for conditional rendering, but enforcement always happens server-side.
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
- **Roles are optional.** Many apps don't need them — single-user apps, internal tools, simple utilities. If the app doesn't have multiple user types with different permissions, skip roles entirely. Only add them when the app explicitly needs to distinguish who can do what.
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
- ## Defining Roles
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": "requester", "name": "Requester", "description": "Can submit vendor requests and purchase orders." },
15
- { "id": "approver", "name": "Approver", "description": "Reviews and approves purchase orders." },
16
- { "id": "admin", "name": "Administrator", "description": "Full access to all app functions." },
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
- - `id`kebab-case, used in code (`auth.requireRole('admin')`)
23
- - `name`display name shown in the editor
24
- - `description` — what this role can do (useful for the agent and for users in the role assignment UI)
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
- Roles are synced to the platform on deploy. Adding or removing roles in the manifest creates or deletes them on the next push.
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
- ## Backend Auth API
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 a 403 error if the current user doesn't have **any** of the specified roles. Use at the top of methods to gate access.
152
+ Throws 403 if the current user doesn't have **any** of the specified roles.
37
153
 
38
154
  ```typescript
39
- auth.requireRole('admin'); // single role
40
- auth.requireRole('admin', 'approver'); // any of these
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. Use for conditional behavior within a method.
161
+ Returns `boolean`. Same logic as `requireRole` but doesn't throw.
46
162
 
47
163
  ### `auth.userId`
48
164
 
49
- The current user's UUID. Always available.
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 names assigned to the current user.
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 that have the specified role. Useful for things like "notify all admins."
173
+ Returns an array of user IDs with the specified role.
58
174
 
59
- ## Frontend Auth
175
+ ## Login Page Example
60
176
 
61
- ```typescript
177
+ ```tsx
62
178
  import { auth } from '@mindstudio-ai/interface';
63
179
 
64
- auth.userId; // current user's ID
65
- auth.name; // display name
66
- auth.email; // email address
67
- auth.profilePictureUrl; // URL or null
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
- The frontend SDK provides display-only auth context. Role checking for UI purposes (showing/hiding elements) is done by reading role data from the backend:
217
+ ## Backend Method Example
71
218
 
72
219
  ```typescript
73
- const { isAdmin, pendingCount } = await api.getDashboard();
74
- {isAdmin && <AdminPanel />}
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
- The frontend is untrusted — anyone can modify JavaScript in the browser. Access control must be enforced server-side in methods. The frontend shows or hides UI based on role data from the backend, but the backend is the authority.
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
- // Current user (display only)
78
- auth.userId;
79
- auth.name;
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
- // Resolve user display info
104
- const { displayName, email } = await agent.resolveUser({
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.** Define roles in the manifest, call `auth.requireRole('admin')` in methods. Platform handles sessions, tokens, user resolution.
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
- Users often care about look and feel as much as (or 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.
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 rendered 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.
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
- After writing the first draft, guide the user through it. Don't just ask "does this look good?" — the user is seeing a multi-section spec for the first time.
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, and which interfaces matter) let them know you're ready to start writing the spec. First, call `setProjectOnboardingState({ state: "initialSpecAuthoring" })` so the editor opens. Then start writing the real spec with `writeSpec`. The user will see it stream in live.
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, so use that and the email remy@mindstudio.ai as the basis for any testing that requires a 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 - 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/remy",
3
- "version": "0.1.69",
3
+ "version": "0.1.70",
4
4
  "description": "MindStudio coding agent",
5
5
  "repository": {
6
6
  "type": "git",