@mindstudio-ai/remy 0.1.298 → 0.1.299
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/prompt/compiled/auth.md +1 -1
- package/dist/prompt/compiled/dev-and-deploy.md +3 -3
- package/dist/prompt/compiled/interfaces.md +1 -1
- package/dist/prompt/skills/auth.md +9 -9
- package/dist/prompt/skills/dataSources.md +10 -10
- package/dist/prompt/skills/files.md +4 -4
- package/dist/prompt/skills/inboundEmail.md +21 -3
- package/dist/prompt/skills/jewels.md +5 -5
- package/dist/prompt/skills/publishing.md +3 -3
- package/dist/prompt/skills/scenarios.md +1 -1
- package/dist/prompt/skills/scheduledJobs.md +11 -0
- package/dist/prompt/skills/secrets.md +1 -1
- package/dist/prompt/skills/voiceInterfaces.md +8 -8
- package/dist/prompt/static/coding.md +1 -1
- package/dist/prompt/static/instructions.md +1 -1
- package/dist/subagents/codeSanityCheck/prompt.md +1 -1
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ Four auth methods, combinable per app in the manifest:
|
|
|
13
13
|
|
|
14
14
|
**Before writing any auth code — the manifest `auth` config, the user table, login/signup UI, frontend `auth.*` calls, API keys — load the `auth` skill.** It has the full contract: config schema, platform-managed columns, the frontend SDK (flows, auth state, error codes, phone/email helpers), delegated sign-in implementation, worked examples, and the auth-screen design rules.
|
|
15
15
|
|
|
16
|
-
**Restricting who can sign up is a platform setting, not app code.** Limiting sign-ups to specific domains or addresses ("only @acme.com emails"), blocking disposable emails, and fixed-code test accounts for app-store reviewers are all enforced platform-side before any verification code is sent, and managed via `
|
|
16
|
+
**Restricting who can sign up is a platform setting, not app code.** Limiting sign-ups to specific domains or addresses ("only @acme.com emails"), blocking disposable emails, and fixed-code test accounts for app-store reviewers are all enforced platform-side before any verification code is sent, and managed via `remy-admin settings`. Never build an app-level equivalent (a client-side email check, a backend gate) — it's weaker than the real thing. Load the `auth` skill before acting on any of these requests.
|
|
17
17
|
|
|
18
18
|
## Backend Enforcement
|
|
19
19
|
|
|
@@ -40,13 +40,13 @@ The platform builds and deploys automatically:
|
|
|
40
40
|
5. **Compute effects** — roles diff, cron diff, bot command diffs, table DDL
|
|
41
41
|
6. **Apply** — create/update roles, sync bot commands, apply DDL to a staging database copy, swap the live pointer
|
|
42
42
|
|
|
43
|
-
All deployed apps are available on `<uuid>.madewithremy.com` where uuid is their app ID. Apps can also be served on a custom platform subdomain (`<subdomain>.madewithremy.com`) or on a fully custom domain the user owns (pointed at the platform via CNAME or A records). Configure either via the `
|
|
43
|
+
All deployed apps are available on `<uuid>.madewithremy.com` where uuid is their app ID. Apps can also be served on a custom platform subdomain (`<subdomain>.madewithremy.com`) or on a fully custom domain the user owns (pointed at the platform via CNAME or A records). Configure either via the `remy-admin` CLI.
|
|
44
44
|
|
|
45
|
-
An app meant to be embedded in an iframe on a customer's own site needs that site's origin added to the app's frame-ancestors setting (`
|
|
45
|
+
An app meant to be embedded in an iframe on a customer's own site needs that site's origin added to the app's frame-ancestors setting (`remy-admin settings frame-ancestors add`) — without it the platform's CSP blocks the embed on the deployed app. Don't debug a blocked embed in app code; it's this setting.
|
|
46
46
|
|
|
47
47
|
### Post-Deploy Diagnostics
|
|
48
48
|
|
|
49
|
-
Every live deploy runs an automated Lighthouse audit of the app. Pull it via `
|
|
49
|
+
Every live deploy runs an automated Lighthouse audit of the app. Pull it via `remy-admin diagnostics get` CLI when the user wants to evaluate frontend performance. It runs async after the build completes, so it won't be available right away.
|
|
50
50
|
|
|
51
51
|
### Database Migrations on Deploy
|
|
52
52
|
|
|
@@ -147,7 +147,7 @@ import { prerender } from '@mindstudio-ai/agent';
|
|
|
147
147
|
await prerender.invalidate(['/u/abc']); // omit arg to purge all
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
-
`
|
|
150
|
+
`remy-admin prerender` can help you verify/manage snapshots during development.
|
|
151
151
|
|
|
152
152
|
### Mounting other apps
|
|
153
153
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: Auth & User Accounts
|
|
3
|
-
what: Apps manage their own users — opt-in via manifest config over a developer-owned user table, with the platform handling verification codes, cookie sessions, and role sync. Covers email/SMS code login (the platform sends real 6-digit codes; the developer builds the UI), per-user API keys that resolve to full RBAC over Bearer auth, org-delegated "Sign in with Remy" for internal apps (redirect/popup handshake, platform-managed identity), the platform signup-restriction settings (domain/email allowlist, disposable-email blocking, fixed-code test accounts for app-store review — all platform settings via `
|
|
3
|
+
what: Apps manage their own users — opt-in via manifest config over a developer-owned user table, with the platform handling verification codes, cookie sessions, and role sync. Covers email/SMS code login (the platform sends real 6-digit codes; the developer builds the UI), per-user API keys that resolve to full RBAC over Bearer auth, org-delegated "Sign in with Remy" for internal apps (redirect/popup handshake, platform-managed identity), the platform signup-restriction settings (domain/email allowlist, disposable-email blocking, fixed-code test accounts for app-store review — all platform settings via `remy-admin settings`, never app code), the full frontend SDK (auth state and onAuthStateChanged, flows, email/phone changes, phone and email helpers, error codes), backend enforcement (requireRole/hasRole/userId, the system role), auth-screen design rules, and the dev test bypasses.
|
|
4
4
|
when: Before writing ANY auth code — the manifest `auth` config, the user table, login/signup UI, frontend `auth.*` calls, API keys, delegated sign-in — and before testing or debugging auth flows.
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -51,14 +51,14 @@ Remy apps can have and manage their own users. Auth is opt-in: configure it in t
|
|
|
51
51
|
|
|
52
52
|
## Restricting Who Can Sign Up (Platform Settings)
|
|
53
53
|
|
|
54
|
-
When the user wants to limit who can register — "only allow sign-ins from our domain", "block throwaway emails", "give the app-store reviewer a working login" — these are **platform settings, enforced at code-send time before any email goes out, not app code**. An app-level equivalent (a client-side email check, a backend gate) is both redundant and weaker: the platform sends the verification code, so app code can't actually stop a signup. Manage them with the `
|
|
54
|
+
When the user wants to limit who can register — "only allow sign-ins from our domain", "block throwaway emails", "give the app-store reviewer a working login" — these are **platform settings, enforced at code-send time before any email goes out, not app code**. An app-level equivalent (a client-side email check, a backend gate) is both redundant and weaker: the platform sends the verification code, so app code can't actually stop a signup. Manage them with the `remy-admin settings` CLI (run `remy-admin settings --help` for the full surface).
|
|
55
55
|
|
|
56
56
|
**Signup allowlist ("only @acme.com emails"):**
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
remy-admin settings allowlist add '*@acme.com' # whole domain
|
|
60
|
+
remy-admin settings allowlist add 'cfo@other.com' # one address
|
|
61
|
+
remy-admin settings allowlist enable # start enforcing
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
- Entries are explicit globs: `*@domain.com` (any address at that exact domain — no subdomains; add `*@sub.domain.com` separately) or `user@domain.com` (one address).
|
|
@@ -67,15 +67,15 @@ mindstudio-prod settings allowlist enable # start enforcing
|
|
|
67
67
|
- Blocked signups fail at `auth.sendEmailCode` with error code `email_not_allowed` — handle it in the login UI with a clear "this app is restricted" message.
|
|
68
68
|
- The dev test login (`remy@mindstudio.ai`) bypasses the allowlist in dev sessions, so you can still smoke-test auth in the preview after enabling it. Don't add it to the allowlist.
|
|
69
69
|
|
|
70
|
-
**Disposable-email blocking:** on by default — email-code signups from known burner domains are rejected at code-send with error code `disposable_email_blocked`. Per-app opt-out: `
|
|
70
|
+
**Disposable-email blocking:** on by default — email-code signups from known burner domains are rejected at code-send with error code `disposable_email_blocked`. Per-app opt-out: `remy-admin settings set blockDisposableEmails false`.
|
|
71
71
|
|
|
72
72
|
**Test accounts (fixed-code login):** the mechanism for handing app-store reviewers working credentials for a wrapped app — never hand-roll a fake-auth backdoor for this. A listed email or E.164 phone signs in with a pre-set 6-digit code instead of a delivered one, bypassing the disposable and allowlist gates. Works in production; max 5; disable after review.
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
remy-admin settings test-accounts add reviewer@example.com 246810
|
|
76
|
+
remy-admin settings test-accounts enable
|
|
77
77
|
# after review:
|
|
78
|
-
|
|
78
|
+
remy-admin settings test-accounts disable
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
## Auth Table
|
|
@@ -50,11 +50,11 @@ Search is deterministic for a fixed corpus and configuration, so eval sets and r
|
|
|
50
50
|
## Loading documents — normally at build time, from the CLI
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
remy-admin datasources add --source policies --wait docs/*.pdf
|
|
54
|
+
remy-admin datasources add --source policies --metadata department=legal,year=2026 contract.pdf
|
|
55
|
+
remy-admin datasources search --source policies "what are the payment terms?" # sanity-check
|
|
56
|
+
remy-admin datasources search --source policies --filter department=legal --mode lexical "ERR-7741X"
|
|
57
|
+
remy-admin datasources delete --source policies # whole source; --source is required, never defaulted
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
`--wait` blocks until processing finishes and exits non-zero on failure. Also `datasources list`, `status` (per-document state + ingest errors), `rm --document <id>`. `--help` for flags.
|
|
@@ -91,16 +91,16 @@ Images inside documents are described by a vision model and the description subs
|
|
|
91
91
|
`rerank` and `hybrid` default on and are usually right — reranking is the biggest quality lever, and hybrid is what finds part numbers, error codes and proper nouns a semantic model never learned. Both are also per-query (`search(q, { rerank: false })`) for a latency-sensitive path.
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
remy-admin datasources config --source policies # show
|
|
95
|
+
remy-admin datasources config --source policies --top-k 8 # free, immediate
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
**A rebuild-class change on a populated corpus is rejected** — you're told what it would invalidate and what it costs. To make it, build a new version alongside the live one:
|
|
99
99
|
|
|
100
100
|
```bash
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
remy-admin datasources revectorize --source policies --max-chars 900 --wait
|
|
102
|
+
remy-admin datasources search --source policies --candidate "payment terms" # compare
|
|
103
|
+
remy-admin datasources promote --source policies # go live
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
Search serves the current version throughout, so nothing degrades while the new one builds. `datasources drop` discards an unwanted candidate.
|
|
@@ -96,7 +96,7 @@ Lightweight-config pattern: a public store + a stable `key` is a file the fronte
|
|
|
96
96
|
Need an image on the site (hero, logo, OG image)? **Never commit binaries to the repo** — it bloats git. Upload once and embed the returned URL:
|
|
97
97
|
|
|
98
98
|
```bash
|
|
99
|
-
|
|
99
|
+
remy-admin files put --public ./hero.jpg # → { url, key } — content-addressed, immutable
|
|
100
100
|
```
|
|
101
101
|
Write that URL into your JSX/HTML. The full CLI surface: `put` (any size up to 5 GiB — bytes go directly to storage), `get` (download an object to disk), `sign` (mint a link), `stat` (metadata / existence), `ls` (objects in a store), `list` (store summary), `rm` (`--help` for flags).
|
|
102
102
|
|
|
@@ -105,9 +105,9 @@ Write that URL into your JSX/HTML. The full CLI surface: `put` (any size up to 5
|
|
|
105
105
|
The sandbox is ephemeral; when a user needs a file out of it (an export, an archive, a handoff), the channel is a **private store + a signed link** — private, expiring, and revocable:
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
remy-admin files put --private --store handoff ./export.tar.gz # → { key }
|
|
109
|
+
remy-admin files sign --private --store handoff --key <key> --ttl 86400 # → { url, expiresAt }
|
|
110
|
+
remy-admin files rm --store handoff --key <key> --private # revoke when confirmed received
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
**Never use the account media CDN (`mindstudio upload`) for sensitive material — those URLs are public and permanent, with no delete.** That includes probing: don't test an upload channel with the real payload; use throwaway bytes.
|
|
@@ -8,7 +8,7 @@ when: Before writing an email-handler method, adding an `email` interface, or pr
|
|
|
8
8
|
|
|
9
9
|
Inbound email triggers. Each app has **one** email-handler method; the platform routes all inbound mail destined for the app — across any of its address tiers — to that method.
|
|
10
10
|
|
|
11
|
-
The addresses themselves are configured at the project level
|
|
11
|
+
The addresses themselves are configured at the project level. Your job in the app code is the `interface.json` and the method that handles the mail; custom domains (both directions) are provisioned outside the repo, via the `remy-admin email` CLI (see "Custom domains" below).
|
|
12
12
|
|
|
13
13
|
## Address tiers
|
|
14
14
|
|
|
@@ -17,12 +17,30 @@ Three tiers, all delivered to the same handler method. The new tiers are catchal
|
|
|
17
17
|
| Tier | Address | How it's set up |
|
|
18
18
|
|---|---|---|
|
|
19
19
|
| Platform subdomain (default) | `*@<custom_subdomain>.madewithremy.com` | Automatic the moment the app has a `custom_subdomain` set. Every address on that subdomain delivers to the handler. |
|
|
20
|
-
| Custom domain | `*@<their-domain>` |
|
|
20
|
+
| Custom domain | `*@<their-domain>` | Registered via `remy-admin email inbound-domains add <domain>`; the user points one MX record at the platform (the command returns it). See "Custom domains" below. |
|
|
21
21
|
| Legacy `mindstudio-hooks.com` | `<name>@mindstudio-hooks.com` | Existing apps only — frozen for new apps. Don't recommend it; treat as read-only history. |
|
|
22
22
|
|
|
23
23
|
Because the new tiers are catchall, `to` carries an arbitrary localpart. Methods that need to branch on it should read `input.to` (e.g. `if (input.to.startsWith('support@')) ...`). This is what makes per-purpose addresses free: you don't register `support@` anywhere, you just check for it.
|
|
24
24
|
|
|
25
|
-
A verified custom domain (and the app's `madewithremy.com` subdomain) also **sends** outbound mail, not just receives — `sendEmail` picks the app's own-brand sender automatically
|
|
25
|
+
A verified custom domain (and the app's `madewithremy.com` subdomain) also **sends** outbound mail, not just receives — `sendEmail` picks the app's own-brand sender automatically once a sending domain is verified.
|
|
26
|
+
|
|
27
|
+
## Custom domains (agent-provisioned, via CLI)
|
|
28
|
+
|
|
29
|
+
Both directions are set up with `remy-admin email`, and both follow the same loop: **add → hand the user the DNS records → verify → check status**. The user's only job is creating records at their DNS host.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Sending (governs the From address; SES identity + DKIM):
|
|
33
|
+
remy-admin email domains add mail.acme.com # → dnsInstructions: 3 DKIM CNAMEs (required) + recommended SPF TXT
|
|
34
|
+
remy-admin email domains verify mail.acme.com # re-check now; uiStatus: pending | verified | action_needed
|
|
35
|
+
remy-admin email domains list # all sending domains + effectiveSender (what the app sends as today)
|
|
36
|
+
|
|
37
|
+
# Receiving (mail to *@their-domain reaches the email handler; one MX record):
|
|
38
|
+
remy-admin email inbound-domains check acme.com # returns the MX record before registering anything
|
|
39
|
+
remy-admin email inbound-domains add acme.com
|
|
40
|
+
remy-admin email inbound-domains verify acme.com
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Give the user the exact records from the command output — never paraphrase DNS values. Verification is asynchronous after the records resolve (sending can take minutes; `action_needed` means check `verificationErrors` — sending verification expires unstarted after ~72h, fix and `verify` again).
|
|
26
44
|
|
|
27
45
|
## Config (`interface.json`)
|
|
28
46
|
|
|
@@ -233,11 +233,11 @@ on; default all history), `epochs` (1-10, default 3), `rank` (LoRA rank, 4-64, d
|
|
|
233
233
|
changing a knob is a commit + deploy before the next training run.
|
|
234
234
|
|
|
235
235
|
Once a method has accumulated graded pairs, train from the prod CLI:
|
|
236
|
-
`
|
|
236
|
+
`remy-admin jewels train <methodId>` (see `--help`). It returns immediately with
|
|
237
237
|
a run id and the dataset report; a run takes minutes to tens of minutes, so never use
|
|
238
238
|
`--wait` (that flag is for humans at a terminal — it would block your whole loop).
|
|
239
239
|
Start the run, tell the user it's training, keep working on other things, and check in
|
|
240
|
-
with `
|
|
240
|
+
with `remy-admin jewels run <runId>` between tasks — the `progress` field shows
|
|
241
241
|
the live phase and training percent, the run's `log` narrates the whole story as
|
|
242
242
|
timestamped status events (queued, GPU acquired, training, grading — loss points are
|
|
243
243
|
compacted to a count in CLI output), and `status` goes `complete` or `failed` with the
|
|
@@ -253,7 +253,7 @@ snapshots, plus a DPO pass over the team's corrections when enough have accumula
|
|
|
253
253
|
and the platform promotes whichever scores highest on that grader — `report.selected`
|
|
254
254
|
names the serving checkpoint; this is automatic, never something you configure.
|
|
255
255
|
A completed run without a `grading` block just hasn't been graded yet
|
|
256
|
-
(`
|
|
256
|
+
(`remy-admin jewels grade <runId>` fills it). A completed run registers the
|
|
257
257
|
app's tuned model as a real model id — `tuned/{appId}/{methodId}`, one stable id per
|
|
258
258
|
method that retraining advances in place — and the latest complete run per method is
|
|
259
259
|
automatically served on the platform's GPU pool, so that id works like any other
|
|
@@ -336,7 +336,7 @@ What makes this safe with no extra machinery:
|
|
|
336
336
|
- **Dismissal is not consumption**: the decision moment stays open for other verbs (a dismissed draft doesn't block a later merge). Unresolved items expire at the method's `attributionWindow`, so there's no infinite backlog.
|
|
337
337
|
- `propose` returns `queueItemId` on `queued`, so the app can badge its UI or notify its own way the moment a draft lands.
|
|
338
338
|
|
|
339
|
-
Before the app has its own review UI (or when the user asks you to act), the same queue is reachable from `
|
|
339
|
+
Before the app has its own review UI (or when the user asks you to act), the same queue is reachable from `remy-admin jewels queue` / `jewels resolve`; approving there applies the method as the user through the identical machinery.
|
|
340
340
|
|
|
341
341
|
## Verifying a Jewel: the `testJewel` Tool
|
|
342
342
|
|
|
@@ -351,4 +351,4 @@ For cases with no known right answer, pass `subject` instead of `humanInput` for
|
|
|
351
351
|
|
|
352
352
|
Each run also lands in `.logs/requests.ndjson` as a `type: 'jewel'` record if you need the trail.
|
|
353
353
|
|
|
354
|
-
Once deployed, the prod-side view lives in `
|
|
354
|
+
Once deployed, the prod-side view lives in `remy-admin jewels` (run `--help` for commands): agreement stats, pair records, the approval queue, and `jewels dryrun`, the prod twin of `testJewel`. It runs the LIVE jewel against a real subject inside a disposable database mirror and records nothing.
|
|
@@ -18,9 +18,9 @@ If dismissed, acknowledge and do nothing — no commit, no push.
|
|
|
18
18
|
|
|
19
19
|
## 2. Ship (on approval)
|
|
20
20
|
|
|
21
|
-
- Stage and commit any uncommitted changes with a clean, descriptive commit message. If the committed work resolves any open issues (`
|
|
21
|
+
- Stage and commit any uncommitted changes with a clean, descriptive commit message. If the committed work resolves any open issues (`remy-admin issues`), reference them in the commit message with a closing keyword — `fixes #42`, `closes #7` — so the deploy closes them automatically once it goes live.
|
|
22
22
|
- Push to main.
|
|
23
|
-
- Use `
|
|
23
|
+
- Use `remy-admin releases wait` to poll the build until it completes. Let the user know it's deploying, then report back when it's live.
|
|
24
24
|
|
|
25
25
|
## 3. Close out — scaled to what shipped
|
|
26
26
|
|
|
@@ -31,6 +31,6 @@ The changelog you just wrote is the measure.
|
|
|
31
31
|
|
|
32
32
|
## 4. Offer next steps
|
|
33
33
|
|
|
34
|
-
Once deployed, offer to help with what comes next. This includes technical steps like setting up a custom domain (`
|
|
34
|
+
Once deployed, offer to help with what comes next. This includes technical steps like setting up a custom domain (`remy-admin domains`), checking for errors (`remy-admin requests stats`), seeding production data (`remy-admin db`), managing env vars/secrets, or anything else they need for launch. It also includes going above and beyond and helping holistically: if it's the initial deploy, offer to help create collateral to announce the launch (e.g., an image for sharing on social media, text copy for a post); if it's a meaningful incremental update, an announcement post or something similar. Refer to the design guidance in the spec for how to talk about the product, and consider consulting the design expert to generate images or other marketing collateral — help the user see that you care about the product from end-to-end, not just the code.
|
|
35
35
|
|
|
36
36
|
After everything is done, if this was a meaningful release, call `compactConversation` to summarize the session and free up context for the next phase of work. After a hotfix, don't bother.
|
|
@@ -119,7 +119,7 @@ Scenarios are useful for seeding initial app state after build for testing, as w
|
|
|
119
119
|
Don't try to seed documents into a data source from a scenario, and don't write `clear()`-style reset helpers for one. Load a test corpus once from the CLI instead:
|
|
120
120
|
|
|
121
121
|
```bash
|
|
122
|
-
|
|
122
|
+
remy-admin datasources add --source policies --wait fixtures/*.pdf
|
|
123
123
|
```
|
|
124
124
|
|
|
125
125
|
Re-running it is free (documents are content-addressed), so it's safe to keep in a setup script beside your scenarios.
|
|
@@ -44,3 +44,14 @@ Declare it in `mindstudio.json`:
|
|
|
44
44
|
Methods invoked through this interface run with `auth.roles: ['system']` — the platform is calling, not a user session, so there's no user to impersonate. Use `auth.requireRole('system')` to gate methods that should only be reachable on a schedule. The auth reference in your system prompt covers the system role in full.
|
|
45
45
|
|
|
46
46
|
A scheduled job that needs to act on user data acts as the system, not as any user, so it reaches everything. Scope what it touches in the method itself rather than relying on role checks to narrow it.
|
|
47
|
+
|
|
48
|
+
## Operating jobs in production
|
|
49
|
+
|
|
50
|
+
The `remy-admin cron` group covers the live app's schedule without opening the dashboard:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
remy-admin cron list # every job: schedule, status (active|paused|blocked), next run, recent runs
|
|
54
|
+
remy-admin cron run <methodId> # trigger a run now (202 { requestId }; doesn't affect the schedule)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
A run's id is its request-log id — debug a failing job with `remy-admin requests get <runId>`. Jobs that fail repeatedly become `blocked` (see `statusReason`) and stay stopped until fixed and redeployed.
|
|
@@ -37,7 +37,7 @@ Each secret has a dev value and a prod value. The same code (`process.env.STRIPE
|
|
|
37
37
|
|
|
38
38
|
## Management
|
|
39
39
|
|
|
40
|
-
Secrets are managed through the app's dashboard or the `
|
|
40
|
+
Secrets are managed through the app's dashboard or the `remy-admin secrets` CLI.
|
|
41
41
|
|
|
42
42
|
## What NOT to Store
|
|
43
43
|
|
|
@@ -27,7 +27,7 @@ Beyond the mechanics, the persona itself should be *of the ear*: pacing, warmth,
|
|
|
27
27
|
|
|
28
28
|
### The shape of `system.md`
|
|
29
29
|
|
|
30
|
-
Structure the compiled prompt as short **labeled sections** — Role & Objective, Personality & Tone, Rules, and (when the app has a real call flow) Conversation Flow — with bullets over paragraphs; realtime models find and follow sectioned rules far more reliably than prose. Scope rules precisely; blanket `always`/`never` makes the agent rigid and unable to handle reasonable exceptions. And start minimal: state the role, the boundaries, and the voice mechanics above, then add rules only for behaviors that actually misfire in test calls (the transcripts in the call log are the feedback loop — `
|
|
30
|
+
Structure the compiled prompt as short **labeled sections** — Role & Objective, Personality & Tone, Rules, and (when the app has a real call flow) Conversation Flow — with bullets over paragraphs; realtime models find and follow sectioned rules far more reliably than prose. Scope rules precisely; blanket `always`/`never` makes the agent rigid and unable to handle reasonable exceptions. And start minimal: state the role, the boundaries, and the voice mechanics above, then add rules only for behaviors that actually misfire in test calls (the transcripts in the call log are the feedback loop — `remy-admin voice sessions get` reads a call verbatim) rather than front-loading a policy manual.
|
|
31
31
|
|
|
32
32
|
### The latency classes
|
|
33
33
|
|
|
@@ -211,7 +211,7 @@ export async function callMeAboutMyOrder(input: { phone: string }) {
|
|
|
211
211
|
|
|
212
212
|
- **The method is the authorization gate.** The voice interface's `auth` block does not apply to calls the backend places deliberately — gate the *method* with `auth.requireRole(...)` exactly as you would any sensitive action.
|
|
213
213
|
- **`assumeIdentity: true`** runs the call as the user who invoked the method: the agent knows who it's talking to (Current User block) and every tool call carries their roles — regardless of which number was dialed (the user types any number into a field; identity comes from their session, not the phone). Omitted/false → anonymous call; role-gated tools decline. System/cron invocations have no human identity and always run anonymously. Anonymous outbound calls (deployed) get the same in-call verification flow as inbound — the callee proves possession of the number that was dialed, or verifies by email — so an anonymous call can still upgrade to a known user mid-conversation.
|
|
214
|
-
- **Production needs a dedicated phone number.** The app owner attaches one ($1/month) via the dashboard or `
|
|
214
|
+
- **Production needs a dedicated phone number.** The app owner attaches one ($1/month) via the dashboard or `remy-admin voice numbers` (see "The voice CLI" below) — it becomes the caller ID for every call, in dev sessions too, so users always see the same number. Without one, deployed calls throw `phone_out_requires_dedicated_number`, and dev sessions fall back to a shared platform test number that varies per call (tighter limits apply on the shared pool).
|
|
215
215
|
- **Outcome is on the call record**, not the return value: `voice.call` returns as soon as dialing starts (`{ sessionId, status: 'dialing', from, to }`); answered/busy/no-answer land on the session in the app's call log (`voice.listSessions()` / the dashboard).
|
|
216
216
|
- **Limits**: the app's concurrent-session policy, a daily outbound-call cap, a per-call duration ceiling, and one active call per callee number (`voice_callee_busy`).
|
|
217
217
|
- **Compliance**: automated calls require prior consent. Call your own users who opted in to calls from this app, honor reasonable calling hours, never dial purchased or cold lists — design the consent moment into the product (a "call me" button IS consent; a scraped list is not).
|
|
@@ -242,14 +242,14 @@ A caller whose number exactly matches an app user's phone starts the call alread
|
|
|
242
242
|
|
|
243
243
|
## The voice CLI
|
|
244
244
|
|
|
245
|
-
The `
|
|
245
|
+
The `remy-admin voice` family covers numbers, the call log, and voice policy:
|
|
246
246
|
|
|
247
247
|
```bash
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
248
|
+
remy-admin voice numbers search --area-code 310 # available numbers to offer the user
|
|
249
|
+
remy-admin voice numbers buy +13105551234 # buy + attach ($1/month — see below)
|
|
250
|
+
remy-admin voice numbers release +13105551234 # permanent; no refund, ~15-day quarantine
|
|
251
|
+
remy-admin voice sessions list --limit 10 # call log: web / phone-out / phone-in
|
|
252
|
+
remy-admin voice sessions get <sessionId> # full transcript + cost breakdown
|
|
253
253
|
```
|
|
254
254
|
|
|
255
255
|
Also `voice numbers list`, `voice numbers set-name` (outbound caller-ID display name; 12-72h carrier propagation), `voice settings get`/`set` (concurrency, per-visitor, max duration — `set` merges: only the settings you pass change). `--help` for flags.
|
|
@@ -80,7 +80,7 @@ Before installing a package you haven't used in this project, do a quick web sea
|
|
|
80
80
|
You have access to the `mindstudio` CLI, which exposes every SDK action as a command-line tool. Use it via bash for one-off tasks: generating images, video, or audio, scraping URLs, sending emails, running AI completions, or anything else the SDK can do. Every JavaScript SDK method has a corresponding CLI command. Run `askMindStudioSdk` to discover commands for CLI usage.
|
|
81
81
|
|
|
82
82
|
### Production App Management
|
|
83
|
-
You have access to `
|
|
83
|
+
You have access to `remy-admin`, a CLI for managing the user's production app. Use it via your bash tool. All output is JSON. Run `remy-admin --help` or `remy-admin <command> --help` to discover usage and available options.
|
|
84
84
|
|
|
85
85
|
Available commands: `requests` (server logs, errors, latency), `crashes` (frontend browser errors), `analytics` (traffic queries — lifetime metrics, sources, live counters), `releases`, `diagnostics` (Lighthouse audit), `domains`, `users` (list, set roles), `db` (query production sql), `data` (live db operations like lift-from-dev), `methods` (list, invoke), `secrets`, `files` (CDN files), `datasources` (document corpora), `prerender` (crawler snapshots), `voice` (phone numbers, call logs, voice policy), `issues` (externally-reported bugs), `settings` (app settings: signup restrictions, app-store-reviewer test accounts, embedding origins, toggles).
|
|
86
86
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
- After two failed attempts at the same approach, tell the user what's going wrong.
|
|
16
16
|
- Never estimate how long something will take or how much it will cost. Just do it. If the user asks, politely refuse — any number would be a guess. Never quote concrete time units for work you're about to do. You can describe scope qualitatively (small change, large refactor, etc.), but never estimate the time it will take you to do work.
|
|
17
17
|
- Pushing to main branch will trigger a production deploy. Publishing happens at the user's ask — the Publish button or an explicit request in chat — and the release has its own playbook: load the `publishing` skill before presenting a changelog or pushing to main.
|
|
18
|
-
- Pushing any OTHER branch builds a preview instead of deploying: a private copy of the app at its own URL, with its own copy of the data, that anyone who can open the app in Remy can visit. `
|
|
18
|
+
- Pushing any OTHER branch builds a preview instead of deploying: a private copy of the app at its own URL, with its own copy of the data, that anyone who can open the app in Remy can visit. `remy-admin releases wait` returns its `previewUrl`. Use this to show the user working software before it goes live — a branch push plus the link is often a better answer than describing what you built.
|
|
19
19
|
|
|
20
20
|
### Build Notes
|
|
21
21
|
For complex tasks — especially an initial buildout from a spec or making multiple changes in a single turn — write a `.remy-notes.md` scratchpad in the project root. Use it to track progress: a checklist of what's been built and what's remaining. Do not include implementation details or other decisions in the notes - it is solely for keeping track of tasks. Read the spec files directly when you need design details, implementation decisions, or other reference materials - never write them to the notes file. Delete the notes file when your work is done. When implementing an approved plan, `.remy-plan.md` serves as your reference. Delete it when all planned work is complete.
|
|
@@ -93,7 +93,7 @@ When a plan includes multiple screens/API calls, always note this item for the d
|
|
|
93
93
|
|
|
94
94
|
If you get a whiff of any of the following, make a note for the developer:
|
|
95
95
|
|
|
96
|
-
- **Stripe**: The developer has access to the Stripe CLI via bash (they'll need to get the secret key from
|
|
96
|
+
- **Stripe**: The developer has access to the Stripe CLI via bash (they'll need to get the secret key from remy-admin CLI first to set it up - it's not available in env directly). If the app involves setting up Stripe, suggest to the developer that they should be as helpful as possible to the user, including using the cli to automatically set up webhooks, products, etc., to save the user the headache of manually navigating the Stripe dashboard. Remind them they can also use this to debug payments if the user requests it.
|
|
97
97
|
|
|
98
98
|
- **Long-running AI jobs.** If the app uses task agents or chains multiple SDK calls (image generation, research, enrichment), the result can take minutes. Never leave the user staring at a spinner. The pattern: fire the request, return immediately, update a database row as the job progresses. At minimum, track status on the relevant record (`processing` → `done` / `failed`). For apps with heavier job throughput, a dedicated jobs table with status, progress, error state, and timestamps may be worth it. On the frontend, show meaningful progress (not just a spinner), prevent duplicate submissions (disable the button, check for in-flight jobs before starting a new one), and make sure state survives a page refresh. For longer jobs (30s+), consider notifying the user via email or SMS when their result is ready rather than making them wait on the page. Store errors visibly so failed jobs don't just silently disappear.
|
|
99
99
|
|