Environment/setup notes for Cursor agents running this repo in a Cursor Cloud VM.
General repo rules live in AGENTS.md (generated by ai-sync from ai/rules/); this
file is specific to the Cursor Cloud environment.
Config lives in .cursor/environment.json (install / start / terminals). Do
not pin a VM snapshot — snapshot-20260629 makes Cloud builds crash in
Cursor's VNC/exec-daemon overlay before install.sh runs. install runs
agent-bootstrap.sh so Postgres 18, Redis Stack, ClickHouse, JRE, and
ElasticMQ are created on the current Cloud image.
package.json is unchanged from laptop: bun dw is still
infisical run --env=dev --recursive -- bun scripts/dw/index.ts.
infisical run uses Cursor's INFISICAL_TOKEN (machine-identity Token Auth
access token). Cloud start copies it to ~/.cache/autumn-infisical-token
and ~/.autumn-agent/env.sh (BASH_ENV) so later shells still have it.
No infisical login. The stock node_modules/.bin/infisical is not replaced.
INFISICAL_PROJECT_ID comes from .infisical.json workspaceId. Start does
not start the app.
CLOUD_AGENT=1 is set on start. That skips portless HTTPS aliases, the emulate
daemon, and Neon (even if Infisical has NEON_WORKTREE_API_KEY). Worktree #1
uses the local Postgres/Redis/ElasticMQ from agent-services.sh.
infisical run injects the shared dev vault (laptop Docker Redis :6380,
Dragonfly Cloud, Neon, AWS SQS). bun dw / bun dw run re-pins localhost
via applyCloudAgentDevEnv (Postgres :5432, one Redis :6379, ElasticMQ
:9324). There is no isolation.env. server/.env must not pin a random
ENCRYPTION_* — that cannot decrypt vault/DB Dragonfly backups (BAD_DECRYPT).
Do not pin dummy AWS_ACCESS_KEY_ID=x either — ElasticMQ is fine with
Infisical keys; dummy keys make S3 edge-config fail.
agent-services.sh CreateQueue-s autumn.fifo, autumn-track.fifo,
autumn-track-async, and autumn-stripe-webhook.fifo (snapshot conf may
only have autumn.fifo).
bun dw # provision-if-needed is a no-op without Neon; starts the app
bun dw run # same stack; stripe listen attaches when STRIPE_SANDBOX_SECRET_KEY is present
bun dw setup # bun install + ai submodule sync; no Neon/Docker
bun dw identify # URLs / portsStack: server :8080, vite :3000, checkout :3001, workers, leaf :3099.
eve is skipped under CLOUD_AGENT=1 (npx eve hits EOVERRIDE / drizzle catalog).
Non-blocking noise: trigger waits for a login; leaf may crash without
SLACK_* / FIRECRAWL_API_KEY.
Started every boot by scripts/setup/cursor-cloud/start.sh → agent-services.sh:
| Service | Port |
|---|---|
| PostgreSQL | 5432 (autumn / postgres / postgres) |
| Redis Stack | 6379 |
| ClickHouse | 8123 |
| ElasticMQ | 9324 |
If they are down: bash scripts/setup/agent-services.sh.
Skills live in the private ai submodule (github.com/useautumn/ai). bun ai sync does run on Cloud install — that is not enough by itself.
ai-sync writes symlinks from .cursor/skills/<name> into
ai/config/skills/**. Cloud agents read ~/.cursor/skills, so
bun ai sync --copy also copies real skill dirs there.
After a boot you should have /tdd and /autumn-tdd-test. tdd supersedes
autumn-tdd-test; both are installed during the transition.
AGENTS.md is also gitignored/generated. Cursor Cloud auto-loads it (it does
not auto-load this file). Install appends a "Cursor Cloud specific
instructions" section so the agent still knows to read the skill files.
To refresh: (cd ai && bun install) && bun ai/src/cli.ts sync --copy.
Agents started from the saved team environment (install: bun install
only, no start) never run this path — start a new agent from this branch so
.cursor/environment.json is used.
ai/config/mcps.json authenticates Executor with
Authorization: Bearer ${env:EXECUTOR_API_KEY} (the key lives in Infisical
dev as EXECUTOR_API_KEY). ai-sync drops that header when the env var
is unset so laptop OAuth still works. Cloud cannot complete OAuth.
start pulls just that one secret via infisical run -- printenv EXECUTOR_API_KEY
(same pattern as ngrok) and writes the Bearer header into gitignored
.cursor/mcp.json and ~/.cursor/mcp.json. It also exports the var in
~/.autumn-agent/env.sh. The key is never committed or logged.
Optional belt-and-suspenders: a Team Runtime Secret named EXECUTOR_API_KEY
(same rules as Infisical client id — Team scope, Runtime Secret type). If it
is already in the process environment, Infisical is not queried for it.
Cloud Agents do not mount this VM as a Desktop workspace. They push a branch + draft PR. To get Source Control → Agent Review + Graph (the classic editor sidebar):
- Wait for the agent to push (default).
- In Cursor Desktop, check out that branch (or open the PR).
- Agent Review → Review changes against
dev.
Cmd+Shift+P → Open IDE from the Agents Window opens a local editor window;
it is not a remote SSH mount of this VM. Remote desktop on the agent page is for
clicking through the running app, not for that review UI.
AUTUMN_DB_DIRECT=1 DATABASE_URL=postgresql://postgres:postgres@localhost:5432/autumn bun db migrateAdd --bootstrap only on a fresh/empty DB.
Email OTP login. With no RESEND_API_KEY, the code is printed to the server log:
grep -a "SIGN IN OTP" <server output>.
Do not paste client IDs or secrets into chat. They would land in the transcript.
This repo has .cursor/environment.json, so Cloud Agents use repository
config, not the saved team environment. Secrets whose scope is
Environment on that dashboard page are not injected (the agent’s
environmentPublicId is null). Add them as Team (or User) Runtime
Secrets on Cloud Agents → Secrets
— Apply to this repo / all repos. Type stays Runtime Secret.
| Name | Type | Scope |
|---|---|---|
INFISICAL_TOKEN |
Runtime Secret | Team (not Environment) |
EXECUTOR_API_KEY |
Runtime Secret | Team (optional; also in Infisical dev) |
Public tunnel tokens live in Infisical dev, not Cursor secrets:
CLOUDFLARE_TUNNEL_API_TOKENCLOUDFLARE_TUNNEL_ACCOUNT_ID
INFISICAL_TOKEN is the Token Auth access token (identity → Token Auth →
Create Token). infisical run uses it directly. Client id/secret are unused
on Cloud. Do not overwrite node_modules/.bin/infisical.
Localhost DB/Redis/SQS come from bun dw Cloud-agent mode, not a Cloud overlay file.
The vault is not dumped to disk.
scripts/dev.ts starts stripe listen --forward-connect-to http://localhost:8080/webhooks/connect/sandbox
when the Stripe CLI is installed and STRIPE_SANDBOX_SECRET_KEY is present (from Infisical).
Stripe's CLI opens an outbound tunnel — no public URL / port-forward
required for webhooks. This is attached by bun dw / bun dw run.
STRIPE_WEBHOOK_SKIP_VERIFY=true is set by applyCloudAgentDevEnv because the
CLI's whsec_ is not the Infisical dashboard endpoint secret. Signature skip is
localhost-only.
If the CLI is present but the sandbox key is missing, CLOUD_AGENT=1 skips
stripe listen instead of killing the whole stack.
There is no SSH into this VM, so a manual ssh -L port-forward is not an option.
The in-IDE Browser tab stays blank even when Vite is up — Cursor bug, any
URL, not Autumn. Each agent is its own VM, so another chat's Browser is a
different localhost:3000. Use one of:
- Public Cloudflare hosts (what Cloud browsers should use).
bun dw setupcreates one hostname per service, salted with~/.autumn-agent/machine-idso VMs do not collide:autumn-wt1-<hash>.autumnworktree.com(Vite),-api,-checkout,-leaf,-emulate.bun dw identifyprints them. - Cursor port forwarding.
.cursor/environment.jsondeclaresports8080 / 3000 / 3001 / 3099. In the agent editor, open the plug / Ports panel — Cursor forwards them to localhost on your laptop. Then openhttp://localhost:3000in Chrome or Safari. - Remote desktop on the agent page — take control, open Chrome with
--no-sandbox, go tohttp://localhost:3000. Most reliable if Ports is empty.
The access terminal reprints these instructions on every boot. It does not
start the app.
- Lint/format:
bunx biome check .(configbiome.json). - Typecheck:
bun ts. - Integration tests:
bun test:integration(needs services +server/.env).