@mindstudio-ai/remy 0.1.34 → 0.1.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/headless.js +578 -393
- package/dist/index.js +652 -385
- package/dist/prompt/sources/llms.txt +1618 -0
- package/dist/prompt/static/instructions.md +1 -1
- package/dist/prompt/static/team.md +1 -1
- package/dist/subagents/.notes-background-agents.md +60 -48
- package/dist/subagents/browserAutomation/prompt.md +14 -11
- package/dist/subagents/designExpert/data/sources/dev/index.html +901 -0
- package/dist/subagents/designExpert/data/sources/dev/serve.mjs +244 -0
- package/dist/subagents/designExpert/data/sources/dev/specimens-fonts.html +126 -0
- package/dist/subagents/designExpert/data/sources/dev/specimens-pairings.html +114 -0
- package/dist/subagents/designExpert/data/{fonts.json → sources/fonts.json} +0 -97
- package/dist/subagents/designExpert/data/sources/inspiration.json +392 -0
- package/dist/subagents/designExpert/prompt.md +36 -12
- package/dist/subagents/designExpert/prompts/animation.md +14 -6
- package/dist/subagents/designExpert/prompts/color.md +25 -5
- package/dist/subagents/designExpert/prompts/{icons.md → components.md} +17 -5
- package/dist/subagents/designExpert/prompts/frontend-design-notes.md +17 -122
- package/dist/subagents/designExpert/prompts/identity.md +15 -61
- package/dist/subagents/designExpert/prompts/images.md +35 -10
- package/dist/subagents/designExpert/prompts/layout.md +14 -9
- package/dist/subagents/designExpert/prompts/typography.md +39 -0
- package/package.json +2 -2
- package/dist/actions/buildFromInitialSpec.md +0 -15
- package/dist/actions/publish.md +0 -12
- package/dist/actions/sync.md +0 -19
- package/dist/compiled/README.md +0 -100
- package/dist/compiled/auth.md +0 -77
- package/dist/compiled/design.md +0 -251
- package/dist/compiled/dev-and-deploy.md +0 -69
- package/dist/compiled/interfaces.md +0 -238
- package/dist/compiled/manifest.md +0 -107
- package/dist/compiled/media-cdn.md +0 -51
- package/dist/compiled/methods.md +0 -225
- package/dist/compiled/msfm.md +0 -222
- package/dist/compiled/platform.md +0 -105
- package/dist/compiled/scenarios.md +0 -103
- package/dist/compiled/sdk-actions.md +0 -146
- package/dist/compiled/tables.md +0 -263
- package/dist/static/authoring.md +0 -101
- package/dist/static/coding.md +0 -29
- package/dist/static/identity.md +0 -1
- package/dist/static/instructions.md +0 -31
- package/dist/static/intake.md +0 -44
- package/dist/static/lsp.md +0 -4
- package/dist/static/projectContext.ts +0 -160
- package/dist/static/team.md +0 -39
- package/dist/subagents/designExpert/data/inspiration.json +0 -392
- package/dist/subagents/designExpert/prompts/instructions.md +0 -18
- /package/dist/subagents/designExpert/data/{compile-font-descriptions.sh → sources/compile-font-descriptions.sh} +0 -0
- /package/dist/subagents/designExpert/data/{compile-inspiration.sh → sources/compile-inspiration.sh} +0 -0
- /package/dist/subagents/designExpert/data/{inspiration.raw.json → sources/inspiration.raw.json} +0 -0
- /package/dist/subagents/designExpert/{prompts/tool-prompts → data/sources/prompts}/design-analysis.md +0 -0
- /package/dist/subagents/designExpert/{prompts/tool-prompts → data/sources/prompts}/font-analysis.md +0 -0
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
# Interfaces
|
|
2
|
-
|
|
3
|
-
Interfaces are projections of the backend contract into different modalities. The same methods power all of them. An interface can be as complex and polished as you want, but it's always safe — the backend contract is where anything real happens. The interface can't break business logic or corrupt data.
|
|
4
|
-
|
|
5
|
-
All external service connections (Discord bot tokens, Telegram bot setup, webhook secrets, email addresses) are configured at the project level by the user through the MindStudio platform. The agent's job is to write the config files and the methods that handle the requests — not to manage API keys, OAuth flows, or service registration.
|
|
6
|
-
|
|
7
|
-
## Web Interface
|
|
8
|
-
|
|
9
|
-
A full web application — typically Vite + React, but any framework that produces static output works.
|
|
10
|
-
|
|
11
|
-
### Project Structure
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
dist/interfaces/web/
|
|
15
|
-
web.json ← interface config
|
|
16
|
-
package.json
|
|
17
|
-
vite.config.ts
|
|
18
|
-
index.html
|
|
19
|
-
src/
|
|
20
|
-
App.tsx
|
|
21
|
-
pages/
|
|
22
|
-
components/
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### Config (`web.json`)
|
|
26
|
-
|
|
27
|
-
```json
|
|
28
|
-
{
|
|
29
|
-
"devPort": 5173,
|
|
30
|
-
"devCommand": "npm run dev"
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
| Field | Type | Default | Description |
|
|
35
|
-
|-------|------|---------|-------------|
|
|
36
|
-
| `devPort` | `number` | `5173` | Port for the dev server |
|
|
37
|
-
| `devCommand` | `string` | `"npm run dev"` | Command to start the dev server |
|
|
38
|
-
|
|
39
|
-
### Frontend SDK
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
import { createClient, platform, auth } from '@mindstudio-ai/interface';
|
|
43
|
-
|
|
44
|
-
// Typed RPC to backend methods — use the camelCase export function names,
|
|
45
|
-
// NOT the kebab-case method IDs from mindstudio.json. The client maps
|
|
46
|
-
// export names to method IDs automatically.
|
|
47
|
-
const api = createClient<{
|
|
48
|
-
submitVendorRequest(input: { name: string }): Promise<{ vendorId: string }>;
|
|
49
|
-
listVendors(): Promise<{ vendors: Vendor[] }>;
|
|
50
|
-
}>();
|
|
51
|
-
|
|
52
|
-
const { vendorId } = await api.submitVendorRequest({ name: 'Acme' });
|
|
53
|
-
const { vendors } = await api.listVendors();
|
|
54
|
-
|
|
55
|
-
// File operations
|
|
56
|
-
const { url } = await platform.requestFile({ type: 'image' });
|
|
57
|
-
const cdnUrl = await platform.uploadFile(file);
|
|
58
|
-
|
|
59
|
-
// Current user (display only)
|
|
60
|
-
auth.userId;
|
|
61
|
-
auth.name;
|
|
62
|
-
auth.email;
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
The project uses `"jsx": "react-jsx"` (automatic JSX transform) — do not `import React from 'react'`. Only import the specific hooks and types you need (e.g., `import { useState, useEffect } from 'react'`).
|
|
66
|
-
|
|
67
|
-
On deploy, the platform runs `npm install && npm run build` in the web directory and hosts the output on CDN.
|
|
68
|
-
|
|
69
|
-
## API Interface
|
|
70
|
-
|
|
71
|
-
Auto-generated REST endpoints. Every method becomes an API endpoint.
|
|
72
|
-
|
|
73
|
-
### Config (`interface.json`)
|
|
74
|
-
|
|
75
|
-
```json
|
|
76
|
-
{
|
|
77
|
-
"methods": ["submit-vendor-request", "list-vendors", "get-dashboard"]
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Omit the `methods` field (or the config entirely) to expose all methods.
|
|
82
|
-
|
|
83
|
-
### Usage
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
curl -X POST https://api.mindstudio.ai/_internal/v2/apps/{appId}/methods/submit-vendor-request/invoke \
|
|
87
|
-
-H "Authorization: Bearer sk..." \
|
|
88
|
-
-H "Content-Type: application/json" \
|
|
89
|
-
-d '{ "input": { "name": "Acme" } }'
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Auth via API key. Returns `{ output, $releaseId, $methodId }`.
|
|
93
|
-
|
|
94
|
-
### Streaming
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
curl -X POST ... -d '{ "input": {...}, "stream": true }'
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Returns SSE: `data: { type: 'token', text }` chunks, then `data: { type: 'done', output }`.
|
|
101
|
-
|
|
102
|
-
## Discord Bot
|
|
103
|
-
|
|
104
|
-
Slash commands that invoke methods.
|
|
105
|
-
|
|
106
|
-
### Config (`interface.json`)
|
|
107
|
-
|
|
108
|
-
```json
|
|
109
|
-
{
|
|
110
|
-
"commands": [
|
|
111
|
-
{
|
|
112
|
-
"name": "submit-vendor",
|
|
113
|
-
"description": "Request a new vendor",
|
|
114
|
-
"method": "submit-vendor-request"
|
|
115
|
-
}
|
|
116
|
-
],
|
|
117
|
-
"loadingMessage": "Processing your request..."
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
Commands are synced to Discord on deploy.
|
|
122
|
-
|
|
123
|
-
## Telegram Bot
|
|
124
|
-
|
|
125
|
-
Bot commands and message handling.
|
|
126
|
-
|
|
127
|
-
### Config (`interface.json`)
|
|
128
|
-
|
|
129
|
-
```json
|
|
130
|
-
{
|
|
131
|
-
"commands": [
|
|
132
|
-
{
|
|
133
|
-
"command": "/submit",
|
|
134
|
-
"description": "Submit a vendor request",
|
|
135
|
-
"method": "submit-vendor-request"
|
|
136
|
-
}
|
|
137
|
-
],
|
|
138
|
-
"defaultMethod": "handle-message"
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
`defaultMethod` handles free-text messages that don't match a command.
|
|
143
|
-
|
|
144
|
-
## Cron
|
|
145
|
-
|
|
146
|
-
Scheduled method execution.
|
|
147
|
-
|
|
148
|
-
### Config (`interface.json`)
|
|
149
|
-
|
|
150
|
-
```json
|
|
151
|
-
{
|
|
152
|
-
"jobs": [
|
|
153
|
-
{
|
|
154
|
-
"schedule": "0 9 * * 5",
|
|
155
|
-
"method": "process-weekly-payments",
|
|
156
|
-
"description": "Process approved invoices every Friday at 9am"
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
"schedule": "*/30 * * * *",
|
|
160
|
-
"method": "sync-vendor-status",
|
|
161
|
-
"description": "Sync vendor statuses every 30 minutes"
|
|
162
|
-
}
|
|
163
|
-
]
|
|
164
|
-
}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
Standard cron expression format. Jobs are synced to the platform on deploy.
|
|
168
|
-
|
|
169
|
-
## Webhook
|
|
170
|
-
|
|
171
|
-
Inbound HTTP endpoints that invoke methods.
|
|
172
|
-
|
|
173
|
-
### Config (`interface.json`)
|
|
174
|
-
|
|
175
|
-
```json
|
|
176
|
-
{
|
|
177
|
-
"endpoints": [
|
|
178
|
-
{
|
|
179
|
-
"method": "handle-payment-webhook",
|
|
180
|
-
"description": "Stripe payment notifications",
|
|
181
|
-
"secret": "whk_abc123..."
|
|
182
|
-
}
|
|
183
|
-
]
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
Endpoint URL: `https://api.mindstudio.ai/_internal/v2/webhook/{appId}/{secret}`
|
|
188
|
-
|
|
189
|
-
Accepts any HTTP method. The method receives `{ method, headers, query, body }` as input.
|
|
190
|
-
|
|
191
|
-
## Email
|
|
192
|
-
|
|
193
|
-
Inbound email triggers.
|
|
194
|
-
|
|
195
|
-
### Config (`interface.json`)
|
|
196
|
-
|
|
197
|
-
```json
|
|
198
|
-
{
|
|
199
|
-
"method": "handle-inbound-email"
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Register a custom address (e.g., `invoices@mindstudio-hooks.com`) via the platform. Inbound emails invoke the specified method with the email content as input.
|
|
204
|
-
|
|
205
|
-
## MCP (Model Context Protocol)
|
|
206
|
-
|
|
207
|
-
Expose methods as AI tools.
|
|
208
|
-
|
|
209
|
-
### Config (`interface.json`)
|
|
210
|
-
|
|
211
|
-
```json
|
|
212
|
-
{
|
|
213
|
-
"methods": ["submit-vendor-request", "list-vendors"]
|
|
214
|
-
}
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
Each listed method becomes an MCP tool. Method names and descriptions from the manifest are used as tool names and descriptions.
|
|
218
|
-
|
|
219
|
-
## Manifest Declaration
|
|
220
|
-
|
|
221
|
-
Each interface is declared in `mindstudio.json`:
|
|
222
|
-
|
|
223
|
-
```json
|
|
224
|
-
{
|
|
225
|
-
"interfaces": [
|
|
226
|
-
{ "type": "web", "path": "dist/interfaces/web/web.json" },
|
|
227
|
-
{ "type": "api" },
|
|
228
|
-
{ "type": "cron", "path": "dist/interfaces/cron/interface.json" },
|
|
229
|
-
{ "type": "discord", "path": "dist/interfaces/discord/interface.json" },
|
|
230
|
-
{ "type": "telegram", "path": "dist/interfaces/telegram/interface.json" },
|
|
231
|
-
{ "type": "webhook", "path": "dist/interfaces/webhook/interface.json" },
|
|
232
|
-
{ "type": "email", "path": "dist/interfaces/email/interface.json" },
|
|
233
|
-
{ "type": "mcp", "path": "dist/interfaces/mcp/interface.json" }
|
|
234
|
-
]
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
Some interfaces (like `api`) work without a config file — just declaring the type is enough. Others need a config for command mappings, schedules, etc. Set `"enabled": false` to skip an interface during build.
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
# Manifest Reference
|
|
2
|
-
|
|
3
|
-
`mindstudio.json` declares everything the platform needs to know about the app. It's read on every deploy to determine what to compile.
|
|
4
|
-
|
|
5
|
-
## Example
|
|
6
|
-
|
|
7
|
-
```json
|
|
8
|
-
{
|
|
9
|
-
"appId": "e452fcf2-06c5-49e8-b4f1-6353563f24b0",
|
|
10
|
-
"name": "Procure-to-Pay",
|
|
11
|
-
|
|
12
|
-
"roles": [
|
|
13
|
-
{ "id": "requester", "name": "Requester", "description": "Can submit vendor requests and purchase orders." },
|
|
14
|
-
{ "id": "approver", "name": "Approver", "description": "Reviews and approves purchase orders." },
|
|
15
|
-
{ "id": "admin", "name": "Administrator", "description": "Full access to all app functions." }
|
|
16
|
-
],
|
|
17
|
-
|
|
18
|
-
"tables": [
|
|
19
|
-
{ "name": "vendors", "path": "dist/methods/src/tables/vendors.ts", "export": "Vendors" },
|
|
20
|
-
{ "name": "purchase-orders", "path": "dist/methods/src/tables/purchase-orders.ts", "export": "PurchaseOrders" }
|
|
21
|
-
],
|
|
22
|
-
|
|
23
|
-
"methods": [
|
|
24
|
-
{
|
|
25
|
-
"id": "submit-vendor-request",
|
|
26
|
-
"name": "Submit Vendor Request",
|
|
27
|
-
"path": "dist/methods/src/submitVendorRequest.ts",
|
|
28
|
-
"export": "submitVendorRequest"
|
|
29
|
-
}
|
|
30
|
-
],
|
|
31
|
-
|
|
32
|
-
"interfaces": [
|
|
33
|
-
{ "type": "web", "path": "dist/interfaces/web/web.json" },
|
|
34
|
-
{ "type": "api" },
|
|
35
|
-
{ "type": "cron", "path": "dist/interfaces/cron/interface.json" }
|
|
36
|
-
],
|
|
37
|
-
|
|
38
|
-
"scenarios": [
|
|
39
|
-
{
|
|
40
|
-
"id": "ap-overdue-invoices",
|
|
41
|
-
"name": "AP: Overdue Invoices",
|
|
42
|
-
"description": "AP user with two invoices past due date.",
|
|
43
|
-
"path": "dist/methods/.scenarios/apOverdueInvoices.ts",
|
|
44
|
-
"export": "apOverdueInvoices",
|
|
45
|
-
"roles": ["ap"]
|
|
46
|
-
}
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Fields
|
|
52
|
-
|
|
53
|
-
### `appId` (required)
|
|
54
|
-
`string` (UUID). The app's platform identifier. Found in the git remote URL: `https://git.mscdn.ai/{appId}.git`.
|
|
55
|
-
|
|
56
|
-
### `name` (required)
|
|
57
|
-
`string`. Display name shown in the editor and workspace.
|
|
58
|
-
|
|
59
|
-
### `roles`
|
|
60
|
-
`Array<{ id, name?, description? }>`. Defaults to `[]`.
|
|
61
|
-
|
|
62
|
-
| Field | Type | Required | Description |
|
|
63
|
-
|-------|------|----------|-------------|
|
|
64
|
-
| `id` | `string` | Yes | Kebab-case identifier (used in code: `auth.requireRole('admin')`) |
|
|
65
|
-
| `name` | `string` | No | Display name |
|
|
66
|
-
| `description` | `string` | No | What this role can do |
|
|
67
|
-
|
|
68
|
-
### `tables`
|
|
69
|
-
`Array<{ name, path, export }>`. Defaults to `[]`.
|
|
70
|
-
|
|
71
|
-
| Field | Type | Required | Description |
|
|
72
|
-
|-------|------|----------|-------------|
|
|
73
|
-
| `name` | `string` | Yes | Table name — snake_case, `[a-zA-Z0-9_]` only (must match `db.defineTable('name')`) |
|
|
74
|
-
| `path` | `string` | Yes | Path to the TypeScript file (relative to project root) |
|
|
75
|
-
| `export` | `string` | Yes | Named export from the file (e.g., `Vendors`) |
|
|
76
|
-
|
|
77
|
-
### `methods` (required, at least one)
|
|
78
|
-
`Array<{ id, name?, path, export }>`.
|
|
79
|
-
|
|
80
|
-
| Field | Type | Required | Description |
|
|
81
|
-
|-------|------|----------|-------------|
|
|
82
|
-
| `id` | `string` | Yes | Kebab-case identifier (used in API URLs and frontend method map) |
|
|
83
|
-
| `name` | `string` | No | Display name |
|
|
84
|
-
| `path` | `string` | Yes | Path to the TypeScript file |
|
|
85
|
-
| `export` | `string` | Yes | Named export (the async function) |
|
|
86
|
-
|
|
87
|
-
### `interfaces`
|
|
88
|
-
`Array<{ type, path?, config?, enabled? }>`. Defaults to `[]`.
|
|
89
|
-
|
|
90
|
-
| Field | Type | Required | Description |
|
|
91
|
-
|-------|------|----------|-------------|
|
|
92
|
-
| `type` | `string` | Yes | One of: `web`, `api`, `discord`, `telegram`, `cron`, `webhook`, `email`, `mcp` |
|
|
93
|
-
| `path` | `string` | No | Path to the interface config file |
|
|
94
|
-
| `config` | `object` | No | Inline config (alternative to a file) |
|
|
95
|
-
| `enabled` | `boolean` | No | Default `true`. Set `false` to skip during build. |
|
|
96
|
-
|
|
97
|
-
### `scenarios`
|
|
98
|
-
`Array<{ id, name?, description?, path, export, roles }>`. Defaults to `[]`.
|
|
99
|
-
|
|
100
|
-
| Field | Type | Required | Description |
|
|
101
|
-
|-------|------|----------|-------------|
|
|
102
|
-
| `id` | `string` | Yes | Kebab-case identifier |
|
|
103
|
-
| `name` | `string` | No | Display name |
|
|
104
|
-
| `description` | `string` | No | What state this scenario creates |
|
|
105
|
-
| `path` | `string` | Yes | Path to the TypeScript file |
|
|
106
|
-
| `export` | `string` | Yes | Named export (the async function) |
|
|
107
|
-
| `roles` | `string[]` | Yes | Roles to impersonate after seeding |
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# Images and Media CDN
|
|
2
|
-
|
|
3
|
-
MindStudio has three CDN hosts:
|
|
4
|
-
|
|
5
|
-
- **Images:** `i.mscdn.ai`
|
|
6
|
-
- **Videos:** `v.mscdn.ai`
|
|
7
|
-
- **Files:** `f.mscdn.ai`
|
|
8
|
-
|
|
9
|
-
Always use CDN transform parameters to request appropriately sized images
|
|
10
|
-
rather than CSS-scaling full-resolution originals.
|
|
11
|
-
|
|
12
|
-
## CDN Image Transforms
|
|
13
|
-
|
|
14
|
-
Combine freely as query string parameters:
|
|
15
|
-
|
|
16
|
-
| Param | Example | Effect |
|
|
17
|
-
|-------|---------|--------|
|
|
18
|
-
| `w` | `?w=400` | Max width in pixels |
|
|
19
|
-
| `h` | `?h=300` | Max height in pixels |
|
|
20
|
-
| `fit` | `?fit=crop` | Resize mode: scale-down, contain, cover, crop, pad |
|
|
21
|
-
| `crop` | `?crop=face` | Face-aware crop (fit=crop + face detection) |
|
|
22
|
-
| `fm` | `?fm=webp` | Output format: avif, webp, jpeg, auto |
|
|
23
|
-
| `dpr` | `?dpr=2` | Device pixel ratio (auto-set to 3 when w/h specified) |
|
|
24
|
-
| `q` | `?q=80` | Quality (1-100) |
|
|
25
|
-
| `blur` | `?blur=10` | Blur radius |
|
|
26
|
-
| `sharpen` | `?sharpen=1` | Sharpen amount |
|
|
27
|
-
|
|
28
|
-
Example: `https://i.mscdn.ai/.../image.png?w=200&h=200&fit=crop&fm=avif`
|
|
29
|
-
|
|
30
|
-
## Video Thumbnails
|
|
31
|
-
|
|
32
|
-
Append `/thumbnail.png` or `/thumbnail.jpg` to any video URL:
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
https://v.mscdn.ai/{orgId}/videos/{videoId}.mp4/thumbnail.png?ts=last&w=400
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
The `ts` param selects the frame: a number (seconds) or `last`. Image CDN
|
|
39
|
-
resize params also work on video thumbnails.
|
|
40
|
-
|
|
41
|
-
## Media Metadata
|
|
42
|
-
|
|
43
|
-
Append `.json` to any CDN URL to get metadata (dimensions, duration, mime
|
|
44
|
-
type, orientation, etc.).
|
|
45
|
-
|
|
46
|
-
## General Rules
|
|
47
|
-
|
|
48
|
-
- Always set explicit width/height or aspect-ratio on images to prevent
|
|
49
|
-
layout shift.
|
|
50
|
-
- Always load fonts directly from CDNs, never self-host font packages
|
|
51
|
-
in the application.
|
package/dist/compiled/methods.md
DELETED
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
# Methods
|
|
2
|
-
|
|
3
|
-
A method is a named async function that runs on the platform. It's the universal unit of backend logic — every interface (web, API, Discord, cron, webhook) invokes methods. Methods run in isolated sandboxes. One file per method, one named export.
|
|
4
|
-
|
|
5
|
-
## Writing a Method
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
// dist/methods/src/submitVendorRequest.ts
|
|
9
|
-
|
|
10
|
-
import { db, auth } from '@mindstudio-ai/agent';
|
|
11
|
-
import { Vendors } from './tables/vendors';
|
|
12
|
-
|
|
13
|
-
export async function submitVendorRequest(input: {
|
|
14
|
-
name: string;
|
|
15
|
-
contactEmail: string;
|
|
16
|
-
taxId: string;
|
|
17
|
-
}) {
|
|
18
|
-
auth.requireRole('requester');
|
|
19
|
-
|
|
20
|
-
const vendor = await Vendors.push({
|
|
21
|
-
name: input.name,
|
|
22
|
-
contactEmail: input.contactEmail,
|
|
23
|
-
taxId: input.taxId,
|
|
24
|
-
status: 'pending',
|
|
25
|
-
requestedBy: auth.userId,
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
return { vendorId: vendor.id, status: vendor.status };
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Manifest Entry
|
|
33
|
-
|
|
34
|
-
```json
|
|
35
|
-
{
|
|
36
|
-
"id": "submit-vendor-request",
|
|
37
|
-
"name": "Submit Vendor Request",
|
|
38
|
-
"path": "dist/methods/src/submitVendorRequest.ts",
|
|
39
|
-
"export": "submitVendorRequest"
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
- `id` — kebab-case, used in API URLs (the platform maps these internally)
|
|
44
|
-
- **Important:** the frontend `createClient` uses the camelCase `export` name, not the kebab-case `id`. Call `api.submitVendorRequest()`, not `api['submit-vendor-request']()`.
|
|
45
|
-
- `path` — relative to project root
|
|
46
|
-
- `export` — must match the function name
|
|
47
|
-
|
|
48
|
-
### Input and Output
|
|
49
|
-
|
|
50
|
-
Methods receive a single `input` parameter (an object) and return an object. Both are JSON-serializable. If no input is needed, the parameter can be omitted or typed as `{}`.
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
53
|
-
export async function getDashboard(input: {
|
|
54
|
-
period?: 'week' | 'month' | 'quarter';
|
|
55
|
-
}) {
|
|
56
|
-
const period = input.period || 'month';
|
|
57
|
-
// ...
|
|
58
|
-
return {
|
|
59
|
-
pendingApprovals,
|
|
60
|
-
recentOrders,
|
|
61
|
-
stats: { totalSpend, vendorCount },
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Platform Capabilities
|
|
67
|
-
|
|
68
|
-
The `@mindstudio-ai/agent` SDK provides access to 200+ AI models and 1,000+ actions (email, SMS, web scraping, file uploads, third-party integrations, and more). Inside a method, create an instance and call actions directly. No constructor arguments needed — credentials are picked up automatically from the execution environment:
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
import { MindStudioAgent } from '@mindstudio-ai/agent';
|
|
72
|
-
|
|
73
|
-
const agent = new MindStudioAgent();
|
|
74
|
-
|
|
75
|
-
// AI text generation
|
|
76
|
-
const { content } = await agent.generateText({
|
|
77
|
-
message: 'Summarize this invoice...',
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// AI image generation
|
|
81
|
-
const { imageUrl } = await agent.generateImage({
|
|
82
|
-
prompt: 'A professional headshot placeholder',
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
// Send email
|
|
86
|
-
await agent.sendEmail({
|
|
87
|
-
to: 'user@example.com',
|
|
88
|
-
subject: 'Your invoice',
|
|
89
|
-
body: content,
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// Upload files
|
|
93
|
-
const { url } = await agent.uploadFile({
|
|
94
|
-
data: buffer,
|
|
95
|
-
fileName: 'report.pdf',
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// Web scraping
|
|
99
|
-
const { markdown } = await agent.scrapeUrl({
|
|
100
|
-
url: 'https://example.com',
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// Resolve user display info
|
|
104
|
-
const { displayName, email } = await agent.resolveUser({
|
|
105
|
-
userId,
|
|
106
|
-
});
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
No separate API keys needed — the platform routes to the correct provider (OpenAI, Anthropic, Google, etc.) automatically.
|
|
110
|
-
|
|
111
|
-
## Error Handling
|
|
112
|
-
|
|
113
|
-
Throw errors with messages that make sense to end users — these may surface in the UI:
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
export async function approveVendor(input: { vendorId: string }) {
|
|
117
|
-
auth.requireRole('admin', 'grc');
|
|
118
|
-
|
|
119
|
-
const vendor = await Vendors.get(input.vendorId);
|
|
120
|
-
if (!vendor) {
|
|
121
|
-
throw new Error('Vendor not found.');
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (vendor.status !== 'pending') {
|
|
125
|
-
throw new Error('This vendor has already been reviewed.');
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// ...
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
`auth.requireRole()` throws a 403 automatically if the user doesn't have the required role.
|
|
133
|
-
|
|
134
|
-
## Common Patterns
|
|
135
|
-
|
|
136
|
-
### CRUD Method
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
export async function listVendors(input: {
|
|
140
|
-
status?: string;
|
|
141
|
-
search?: string;
|
|
142
|
-
}) {
|
|
143
|
-
const vendors = await Vendors
|
|
144
|
-
.filter(v => {
|
|
145
|
-
if (input.status && v.status !== input.status) return false;
|
|
146
|
-
if (input.search && !v.name.includes(input.search)) return false;
|
|
147
|
-
return true;
|
|
148
|
-
})
|
|
149
|
-
.sortBy(v => v.name);
|
|
150
|
-
|
|
151
|
-
return { vendors };
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Role-Gated Operation
|
|
156
|
-
|
|
157
|
-
```typescript
|
|
158
|
-
export async function deleteVendor(input: { vendorId: string }) {
|
|
159
|
-
auth.requireRole('admin');
|
|
160
|
-
|
|
161
|
-
const vendor = await Vendors.get(input.vendorId);
|
|
162
|
-
if (!vendor) throw new Error('Vendor not found.');
|
|
163
|
-
|
|
164
|
-
await Vendors.remove(input.vendorId);
|
|
165
|
-
return { success: true };
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Multi-Table Transaction
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
export async function createPurchaseOrder(input: {
|
|
173
|
-
vendorId: string;
|
|
174
|
-
lineItems: Array<{ description: string; amount: number }>;
|
|
175
|
-
}) {
|
|
176
|
-
auth.requireRole('requester');
|
|
177
|
-
|
|
178
|
-
const vendor = await Vendors.get(input.vendorId);
|
|
179
|
-
if (!vendor || vendor.status !== 'approved') {
|
|
180
|
-
throw new Error('Vendor must be approved before creating a PO.');
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const total = input.lineItems.reduce((sum, li) => sum + li.amount, 0);
|
|
184
|
-
|
|
185
|
-
const po = await PurchaseOrders.push({
|
|
186
|
-
vendorId: input.vendorId,
|
|
187
|
-
requestedBy: auth.userId,
|
|
188
|
-
lineItems: input.lineItems,
|
|
189
|
-
totalAmountCents: total,
|
|
190
|
-
status: 'pending_approval',
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
return { purchaseOrderId: po.id, total };
|
|
194
|
-
}
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
## Shared Helpers
|
|
198
|
-
|
|
199
|
-
Code shared between methods goes in `dist/methods/src/common/`. Helpers are not listed in the manifest — they're internal, imported by methods but not directly invocable.
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
// dist/methods/src/common/getApprovalState.ts
|
|
203
|
-
export function getApprovalState(approvals: Approval[]) {
|
|
204
|
-
const allApproved = approvals.every(a => a.status === 'approved');
|
|
205
|
-
const anyRejected = approvals.some(a => a.status === 'rejected');
|
|
206
|
-
// ...
|
|
207
|
-
}
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
## Streaming
|
|
211
|
-
|
|
212
|
-
Methods can stream token-by-token output (useful for AI-generated content):
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
// Frontend
|
|
216
|
-
const result = await api.generateReport(
|
|
217
|
-
{ month: 'march' },
|
|
218
|
-
{
|
|
219
|
-
stream: true,
|
|
220
|
-
onToken: (text) => setPreview(text),
|
|
221
|
-
},
|
|
222
|
-
);
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
The platform handles the SSE transport. The method returns normally — streaming is managed by the SDK and platform, not by your method code.
|