@mindstudio-ai/remy 0.1.0
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 +314 -0
- package/dist/actions/publish.md +12 -0
- package/dist/actions/sync.md +19 -0
- package/dist/compiled/README.md +100 -0
- package/dist/compiled/auth.md +77 -0
- package/dist/compiled/design.md +173 -0
- package/dist/compiled/dev-and-deploy.md +69 -0
- package/dist/compiled/interfaces.md +238 -0
- package/dist/compiled/manifest.md +107 -0
- package/dist/compiled/media-cdn.md +51 -0
- package/dist/compiled/methods.md +225 -0
- package/dist/compiled/msfm.md +133 -0
- package/dist/compiled/platform.md +101 -0
- package/dist/compiled/scenarios.md +103 -0
- package/dist/compiled/sdk-actions.md +152 -0
- package/dist/compiled/tables.md +192 -0
- package/dist/headless.d.ts +16 -0
- package/dist/headless.js +2515 -0
- package/dist/index.js +3164 -0
- package/dist/static/authoring.md +53 -0
- package/dist/static/identity.md +1 -0
- package/dist/static/instructions.md +21 -0
- package/dist/static/intake.md +44 -0
- package/dist/static/lsp.md +4 -0
- package/dist/static/projectContext.ts +155 -0
- package/package.json +52 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Frontend Design Notes
|
|
2
|
+
|
|
3
|
+
Design standards for web interfaces in MindStudio apps.
|
|
4
|
+
|
|
5
|
+
## Quality Bar
|
|
6
|
+
|
|
7
|
+
Every interface must feel like a polished, shipping product — not a
|
|
8
|
+
prototype, not a starter template, not a homework assignment. The standard
|
|
9
|
+
is iOS and Apple's bundled iOS apps, Notion, Stripe. If it wouldn't look
|
|
10
|
+
good on Dribbble, Behance, or Mobbin, it's not done.
|
|
11
|
+
|
|
12
|
+
MindStudio apps are end-user products. The interface is the product. Users
|
|
13
|
+
judge the entire app by how it looks and feels in the first 3 seconds.
|
|
14
|
+
|
|
15
|
+
## Be Distinctive
|
|
16
|
+
|
|
17
|
+
AI-generated interfaces tend to converge on the same generic look: safe
|
|
18
|
+
fonts, timid colors, predictable layouts. Fight this actively. Every
|
|
19
|
+
interface should have character and intentionality — it should look like a
|
|
20
|
+
designer made deliberate choices, not like it was generated from a template.
|
|
21
|
+
|
|
22
|
+
**Typography must be a conscious choice.** Pick fonts that are beautiful,
|
|
23
|
+
distinctive, and appropriate for the product's personality. Generic system
|
|
24
|
+
fonts and overused defaults make everything look the same. Typography is
|
|
25
|
+
the single fastest way to give an interface identity.
|
|
26
|
+
|
|
27
|
+
**Commit to a color palette.** One or two dominant colors with sharp accents
|
|
28
|
+
outperform timid, evenly-distributed palettes. Draw inspiration from the
|
|
29
|
+
app's domain — a finance tool might use deep greens and golds; a creative
|
|
30
|
+
tool might use bold, saturated primaries. The palette should feel intentional
|
|
31
|
+
and owned, not randomly selected.
|
|
32
|
+
|
|
33
|
+
**Backgrounds create atmosphere.** Solid white or solid gray is the safe
|
|
34
|
+
default and the enemy of distinctiveness. Layer subtle gradients, use warm
|
|
35
|
+
or cool tints, add geometric patterns or contextual textures. The background
|
|
36
|
+
sets the mood before the user reads a single word.
|
|
37
|
+
|
|
38
|
+
**Layouts should surprise.** Avoid the predictable patterns: three equal
|
|
39
|
+
boxes with icons, centered hero with subtitle, generic card grid. Use
|
|
40
|
+
asymmetry, varied column widths, creative negative space, unexpected
|
|
41
|
+
compositions. Study Behance and Mobbin for layout inspiration. Every screen
|
|
42
|
+
should feel considered, not generated.
|
|
43
|
+
|
|
44
|
+
## App-Like, Not Web-Page-Like
|
|
45
|
+
|
|
46
|
+
Interfaces run fullscreen in the user's browser or a wrapped webview mobile
|
|
47
|
+
app. They should feel like native apps, not websites.
|
|
48
|
+
|
|
49
|
+
- **No long scrolling pages.** Use structured layouts: cards, split panes,
|
|
50
|
+
steppers, tabs, grouped sections that fit the viewport. The interface
|
|
51
|
+
should feel like a single-purpose tool, not a document.
|
|
52
|
+
- **On mobile**, scrolling may be necessary, but use sticky headers, fixed
|
|
53
|
+
CTAs, and anchored navigation to keep key actions within reach.
|
|
54
|
+
- Think of every screen as something the user opens, uses, and closes —
|
|
55
|
+
not something they read.
|
|
56
|
+
|
|
57
|
+
## Visual Design
|
|
58
|
+
|
|
59
|
+
- **Typography:** Strong hierarchy — clear distinction between headings,
|
|
60
|
+
body, labels, and captions. Use weight and size, not just color, to
|
|
61
|
+
create hierarchy. Choose fonts that elevate the interface and give it
|
|
62
|
+
personality.
|
|
63
|
+
- **Color:** Clean, vibrant, intentional. Use color to communicate state
|
|
64
|
+
and guide attention, not to decorate. Commit to a direction — bold and
|
|
65
|
+
saturated, or muted and editorial — and follow through consistently.
|
|
66
|
+
- **Spacing:** Consistent and generous. Padding and margins should be
|
|
67
|
+
uniform across all components — nothing should feel cramped or uneven.
|
|
68
|
+
White space is a feature, not wasted space.
|
|
69
|
+
- **Components:** Every component (buttons, inputs, cards, modals, lists)
|
|
70
|
+
should look like it belongs to the same design system. Consistent border
|
|
71
|
+
radii, consistent shadows, consistent padding. If two buttons on the
|
|
72
|
+
same screen look different for no reason, that's a bug.
|
|
73
|
+
|
|
74
|
+
## Animation
|
|
75
|
+
|
|
76
|
+
Use motion to make interactions feel polished, not to show off. Focus on
|
|
77
|
+
high-impact moments: a well-orchestrated page load with staggered reveals
|
|
78
|
+
creates more delight than scattered micro-interactions everywhere.
|
|
79
|
+
|
|
80
|
+
- Transitions between states should be smooth but fast.
|
|
81
|
+
- Streaming content should flow into containers that grow naturally without
|
|
82
|
+
pushing sibling elements around.
|
|
83
|
+
- No parallax, no cheesy scroll effects, no bounce/elastic easing, no
|
|
84
|
+
gratuitous loading animations.
|
|
85
|
+
|
|
86
|
+
## Layout Stability
|
|
87
|
+
|
|
88
|
+
Layout shift is never acceptable. Elements jumping around as content loads
|
|
89
|
+
or streams in makes an interface feel broken.
|
|
90
|
+
|
|
91
|
+
- Reserve space for content that hasn't arrived yet. Use fixed/min-height
|
|
92
|
+
containers, skeletons, or aspect-ratio boxes.
|
|
93
|
+
- Images must always have explicit dimensions so the browser reserves space
|
|
94
|
+
before the image loads.
|
|
95
|
+
- Loading-to-loaded transitions should swap content in-place without
|
|
96
|
+
changing container size.
|
|
97
|
+
- Conditional UI should use opacity/overlay transitions, not insertion into
|
|
98
|
+
flow that displaces existing content.
|
|
99
|
+
|
|
100
|
+
## Responsive Design
|
|
101
|
+
|
|
102
|
+
Every interface must work on both desktop and mobile.
|
|
103
|
+
|
|
104
|
+
- Use the full viewport. Backgrounds should extend to edges.
|
|
105
|
+
- On desktop, use the space — multi-column layouts, sidebars, spacious
|
|
106
|
+
cards. Avoid narrow centered columns with empty gutters on a wide screen.
|
|
107
|
+
- On mobile, stack gracefully. Prioritize content and actions.
|
|
108
|
+
- Test at both extremes. A layout that only looks good at one breakpoint
|
|
109
|
+
is not done.
|
|
110
|
+
|
|
111
|
+
## Forms
|
|
112
|
+
|
|
113
|
+
Forms should feel like interactions, not paperwork.
|
|
114
|
+
|
|
115
|
+
- Group related fields visually. Use cards or sections, not a flat list.
|
|
116
|
+
- Inline validation — show errors as the user types, not after submit.
|
|
117
|
+
Validation must never introduce layout shift.
|
|
118
|
+
- Loading states after submission. Always indicate that something is
|
|
119
|
+
happening.
|
|
120
|
+
- Disabled states should be visually distinct but not jarring.
|
|
121
|
+
- Even data entry can be beautiful. Pay attention to alignment, padding,
|
|
122
|
+
and spacing. Consistency is key.
|
|
123
|
+
|
|
124
|
+
## What Good Looks Like
|
|
125
|
+
|
|
126
|
+
- A dashboard that feels like Linear — clean data, clear hierarchy, every
|
|
127
|
+
pixel intentional.
|
|
128
|
+
- A form that feels like Stripe Checkout — focused, calm, confident.
|
|
129
|
+
- A settings page that feels like iOS Settings — organized, scannable,
|
|
130
|
+
no clutter.
|
|
131
|
+
- A list view that feels like Notion — flexible, spacious, information-dense
|
|
132
|
+
without feeling crowded.
|
|
133
|
+
|
|
134
|
+
## What to Actively Avoid
|
|
135
|
+
|
|
136
|
+
These are the hallmarks of generic AI-generated interfaces. Every one of
|
|
137
|
+
them makes an interface look like it was auto-generated rather than designed.
|
|
138
|
+
|
|
139
|
+
- **Generic fonts.** Overused defaults that strip away all personality.
|
|
140
|
+
Instead: pick a distinctive Google Font that fits the app's character.
|
|
141
|
+
- **Purple or indigo anything.** Purple gradients, purple buttons, purple
|
|
142
|
+
accents. This is the #1 AI-generated aesthetic cliché. Instead: use
|
|
143
|
+
a color palette that fits the app's domain — greens for finance, warm
|
|
144
|
+
neutrals for productivity, bold primaries for creative tools, or just
|
|
145
|
+
confident grayscale.
|
|
146
|
+
- **Colored left-border callout boxes.** Rounded divs with a thick colored
|
|
147
|
+
`border-left` — the generic "info card" pattern. Instead: use typography,
|
|
148
|
+
spacing, and background tints to create hierarchy. If you need to call
|
|
149
|
+
something out, use a full subtle background or a top border.
|
|
150
|
+
- **Three equal boxes with icons.** The default AI landing page layout.
|
|
151
|
+
Instead: use asymmetric layouts, varied column widths, or a single
|
|
152
|
+
focused content area.
|
|
153
|
+
- **Timid color palettes.** Evenly distributed, non-committal colors.
|
|
154
|
+
Instead: one or two dominant colors with sharp accents. Commit to a
|
|
155
|
+
direction.
|
|
156
|
+
- **Card-heavy nested layouts.** Cards inside cards, everything boxed.
|
|
157
|
+
Instead: use space, typography, and dividers to create hierarchy without
|
|
158
|
+
extra containers.
|
|
159
|
+
- **Inconsistent spacing.** 12px here, 20px there, 8px somewhere else.
|
|
160
|
+
Instead: define a spacing scale (4/8/12/16/24/32/48/64) and use it
|
|
161
|
+
everywhere.
|
|
162
|
+
- **Components from different visual languages.** Rounded buttons next to
|
|
163
|
+
square inputs, shadows mixed with flat design. Instead: pick one system
|
|
164
|
+
and apply it consistently.
|
|
165
|
+
- **Long scrolling forms with no visual grouping.** Instead: group fields
|
|
166
|
+
into sections with clear headings, cards, or stepped flows.
|
|
167
|
+
- **Cramped layouts.** Text pressed against edges, no room to breathe.
|
|
168
|
+
Instead: generous padding, comfortable margins, let the content float.
|
|
169
|
+
- **Loading states that are just a centered spinner on a blank page.**
|
|
170
|
+
Instead: use skeletons that mirror the layout, or keep the existing
|
|
171
|
+
structure visible with a subtle loading indicator.
|
|
172
|
+
- **Any interface where the first reaction is "this looks like a demo" or
|
|
173
|
+
"this looks like it was made with a website builder."**
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Development & Deployment
|
|
2
|
+
|
|
3
|
+
## How Development Works
|
|
4
|
+
|
|
5
|
+
The sandbox uses the same tunnel binary and execution pipeline as local development. Code changes take effect immediately — esbuild transpiles methods per-request, no restart needed. The dev database is a disposable snapshot of production.
|
|
6
|
+
|
|
7
|
+
### The Dev Inner Loop
|
|
8
|
+
|
|
9
|
+
1. Edit method code in `dist/methods/src/` — next method invocation uses updated code automatically
|
|
10
|
+
2. Edit frontend code in `dist/interfaces/web/src/` — HMR updates the browser instantly
|
|
11
|
+
3. Add/modify table definitions — schema changes sync to the dev database automatically
|
|
12
|
+
4. Run scenarios to set up specific data states for testing
|
|
13
|
+
|
|
14
|
+
### Dev Database
|
|
15
|
+
|
|
16
|
+
The dev session gets its own database — a snapshot of the live database at session start. Your code writes to this snapshot, not to production.
|
|
17
|
+
|
|
18
|
+
- **Reset to live data** — overwrite the dev database with a fresh copy of production
|
|
19
|
+
- **Truncate** — keep the schema, delete all row data (used by scenarios for a clean canvas)
|
|
20
|
+
- **Schema sync** — add a field to a table interface and it's immediately available in dev
|
|
21
|
+
|
|
22
|
+
The dev database is disposable. Experiment freely — there's no risk of breaking anything.
|
|
23
|
+
|
|
24
|
+
### Debugging
|
|
25
|
+
|
|
26
|
+
`console.log`, `console.warn`, and `console.error` in methods are captured and displayed in the terminal. They don't affect the method's return value. Every method execution is logged with full input, output, duration, and error info.
|
|
27
|
+
|
|
28
|
+
## What Happens on Deploy
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
git push origin main
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The platform builds and deploys automatically:
|
|
35
|
+
|
|
36
|
+
1. **Parse manifest** — read `mindstudio.json` from the commit
|
|
37
|
+
2. **Compile methods** — esbuild bundles each method into a single JS file
|
|
38
|
+
3. **Compile interfaces** — build web SPA (`npm install && npm run build`), generate configs for API/Discord/Telegram/cron/etc.
|
|
39
|
+
4. **Parse table schemas** — TypeScript AST to column definitions, diff against live database
|
|
40
|
+
5. **Compute effects** — roles diff, cron diff, bot command diffs, table DDL
|
|
41
|
+
6. **Apply** — create/update roles, sync bot commands, apply DDL to a staging database copy, swap the live pointer
|
|
42
|
+
|
|
43
|
+
### Preview Deployments
|
|
44
|
+
|
|
45
|
+
Push to a non-default branch for a preview deployment — same build pipeline, but doesn't affect the live app. Useful for testing changes before merging.
|
|
46
|
+
|
|
47
|
+
### Database Migrations on Deploy
|
|
48
|
+
|
|
49
|
+
Schema changes are automatic:
|
|
50
|
+
- **New tables** — `CREATE TABLE` applied automatically
|
|
51
|
+
- **New columns** — `ALTER TABLE ADD COLUMN` applied automatically
|
|
52
|
+
- **Dropped columns** — `ALTER TABLE DROP COLUMN` applied automatically when a column is removed from the interface
|
|
53
|
+
- **Dropped tables** — `DROP TABLE` applied automatically when a table file is removed from the manifest
|
|
54
|
+
- **Type changes and renames** — not supported in the automatic migration path
|
|
55
|
+
|
|
56
|
+
Schema changes are always applied to a clone of the live database, never directly. If DDL fails, the live database is untouched and the release is marked `failed`.
|
|
57
|
+
|
|
58
|
+
### Rollback
|
|
59
|
+
|
|
60
|
+
Rollback is a git revert — creates a new commit, triggers a new build. The previous release's database still exists (databases are per-release), so data isn't lost.
|
|
61
|
+
|
|
62
|
+
### Common Build Failures
|
|
63
|
+
|
|
64
|
+
- **Method compilation error** — TypeScript/syntax error in a method file. Error message includes file and line.
|
|
65
|
+
- **Web build error** — npm install or build command failed. Check build log stdout/stderr.
|
|
66
|
+
- **Table schema error** — TypeScript file couldn't be parsed. Ensure the table definition uses the `defineTable<T>()` pattern.
|
|
67
|
+
- **Missing manifest fields** — method declared but path doesn't exist, or export doesn't match.
|
|
68
|
+
|
|
69
|
+
Failed releases don't affect the current live release.
|
|
@@ -0,0 +1,238 @@
|
|
|
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.
|
|
@@ -0,0 +1,107 @@
|
|
|
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 |
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
- Use remote resources (Google Fonts via CDN). Never self-hosted font
|
|
51
|
+
packages.
|