Skip to content

chore(infra): add Cursor cloud agent environment with FVM - #1100

Closed
leoafarias wants to merge 6 commits into
mainfrom
cursor/fvm-cloud-environment-84ec
Closed

leoafarias wants to merge 6 commits into
mainfrom
cursor/fvm-cloud-environment-84ec

Conversation

@leoafarias

@leoafarias leoafarias commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

Related issue

N/A

Description

Adds a Cursor Cloud Agent environment configuration (.cursor/environment.json) backed by setup.sh on Cursor's default base image (no custom .cursor/Dockerfile). During each Cursor Environment Build, REMOTE_ENV=true bash setup.sh runs once and the full disk state (including ~/fvm, ~/.pub-cache, and /usr/local/bin symlinks) is snapshotted for subsequent agent runs.

Changes

  • .cursor/environment.json:
    • Minimal configuration ({"install": "REMOTE_ENV=true bash setup.sh"}) without build or user keys so the environment uses Cursor's default image and does not lock snapshot updates.
  • setup.sh:
    • Tightened remote detection: Treats the machine as remote only when CLAUDE_CODE_REMOTE=true or REMOTE_ENV=true is explicitly set. Running bash setup.sh without those flags exits immediately at the guard without touching /usr/local/bin, global FVM config, global Flutter version, or global git safe.directory.
    • Single FVM pin & version check: Pins FVM_VERSION=4.3.2 in setup.sh only and verifies the installed fvm --version matches the pin before skipping installation.
    • Config-driven Flutter version via FVM output: Hardcodes no Flutter version anywhere; runs a bare fvm install that reads .fvmrc (3.44.0), queries fvm api project for the configured flutter version (supporting fork-pinned versions and custom FVM_CACHE_PATH locations), and sets fvm global "$SDK_VERSION".
    • Removed duplication & silent error swallowing: Configures fvm config --no-use-git-cache --no-update-check and fvm global "$SDK_VERSION" directly without swallowing errors, sets PATH and safe.directory once, and symlinks /usr/local/bin/{flutter,dart,fvm,melos} via ensure_symlink (using sudo -n when non-root) so tools resolve across Build snapshots.
    • Single Melos installation: Activates melos globally once pinned to the workspace version in pubspec.yaml (6.3.3) and runs melos bootstrap via /usr/local/bin/melos (avoiding compiling melos twice in both ~/.pub-cache and .dart_tool).
  • .fvmrc & .vscode/settings.json:
    • Adds "updateMelosSettings": false to .fvmrc so fvm install runs non-interactively without prompting or dirtying melos.yaml.
    • Updates "dart.flutterSdkPath" in .vscode/settings.json to ".fvm/versions/3.44.0" (matching FVM's default VSCode update) and omits "updateVscodeSettings": false from .fvmrc, eliminating FVM's per-run VSCode warning while keeping git status clean.
  • .gitignore, AGENTS.md, & .github/copilot-instructions.md:
    • Tracks .cursor/environment.json via .cursor/* + !.cursor/environment.json.
    • Clearly scopes REMOTE_ENV=true bash setup.sh in AGENTS.md and .github/copilot-instructions.md to Cursor Cloud / remote containers only, and instructs local agents to run fvm install (or use their own Flutter) and never pass REMOTE_ENV=true locally.

Review Checklist

  • Testing: Verified unflagged bash setup.sh guard behavior, a fresh run of REMOTE_ENV=true bash setup.sh, a second no-op run, tool resolution (flutter, dart, fvm, melos) in a clean login shell, clean git status, and shellcheck setup.sh.
  • Breaking Changes: None. Existing .claude/hooks/session-start.sh (CLAUDE_CODE_REMOTE=true bash setup.sh) continues to work unchanged.
  • Documentation Updates: Scoped remote setup instructions in AGENTS.md and .github/copilot-instructions.md, and included post-merge instructions below.
  • Website Updates: N/A

Additional Information (optional)

Post-Merge Activation Steps

  1. Merge this PR into main.
  2. In the Cursor Cloud Agents dashboard, point the mix Cloud Agents environment's environment.json location at .cursor/environment.json (or create the environment from the repo).
  3. Trigger a Build and check its build logs to confirm REMOTE_ENV=true bash setup.sh completes and snapshots cleanly.

Verification Summary

  • Verified on the Ubuntu 24.04 VM:
    • Unflagged run (bash setup.sh): After clearing global state (/usr/local/bin/{flutter,dart,fvm,melos}, ~/fvm, ~/.config/fvm, and global git safe.directory), ran bash setup.sh without REMOTE_ENV=true or CLAUDE_CODE_REMOTE=true and confirmed it exited at the guard without touching any global state.
    • Fresh run (REMOTE_ENV=true bash setup.sh): Ran from a clean state with no FVM, Flutter, DCM, or Melos installed; verified FVM 4.3.2, Flutter 3.44.0 (from .fvmrc), DCM 1.31.4, and Melos 6.3.3 installed and bootstrapped all 11 workspace packages with no VSCode settings warning.
    • Second run (REMOTE_ENV=true bash setup.sh): Immediately re-ran REMOTE_ENV=true bash setup.sh and confirmed FVM, Flutter SDK, DCM, Melos activation, and /usr/local/bin symlinks were all no-ops.
    • Command resolution & clean working tree: Confirmed flutter, dart, fvm, and melos resolve via /usr/local/bin in a clean login shell (env -i HOME="$HOME" PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" bash -lc), git status remains clean, and shellcheck setup.sh passes with zero warnings.
  • Not verified:
    • An end-to-end Cursor Environment Build from main in the Cursor dashboard (requires merging .cursor/environment.json and pointing the environment's environment.json location at the file post-merge).
Open in Web Open in Cursor 

Add Cursor cloud environment that pre-installs FVM and automatically
provisions Flutter from the repo's .fvmrc configuration.

Changes:
- .cursor/Dockerfile: Ubuntu 24.04 base with FVM 4.3.2
- .cursor/environment.json: Install step runs fvm install (reads .fvmrc),
  creates global symlinks, and bootstraps workspace with melos 6.3.3
- .fvmrc: Add updateVscodeSettings: false to prevent FVM from dirtying
  .vscode/settings.json on every agent run
- .vscode/settings.json: Update dart.flutterSdkPath to match current
  .fvmrc (3.44.0)

Flutter version is NOT hardcoded - bumping .fvmrc will automatically
provision the new version on the next build with zero config changes.

Verified: Config-driven install flow, symlink PATH resolution, and
version bump behavior (simulated: 3.44.0 -> 3.50.0 requires no
Dockerfile or environment.json changes).

Co-authored-by: Leo Farias <leoafarias@users.noreply.github.com>
@github-actions github-actions Bot added the repo label Oct 20, 2026
cursoragent and others added 3 commits October 20, 2026 13:44
- Change --skip-setup to --no-setup (4.3.2 removed --skip-setup in 4.3.0)
- Use git rev-parse --show-toplevel instead of hardcoded /workspace path
- Symlinks remain idempotent (ln -sf overwrites existing links)

Co-authored-by: Leo Farias <leoafarias@users.noreply.github.com>
- Fix .cursor/Dockerfile: install FVM under /home/ubuntu/fvm instead of
  /opt/fvm-cli (FVM installer v2.0.0 rejects FVM_INSTALL_DIR outside $HOME)
- Unify .cursor/environment.json install step with setup.sh as a single
  source of truth across Cursor Cloud Agents, Claude Code remote,
  Codespaces/Devcontainers, CI, and container environments
- Fix setup.sh for non-root environments (sudo support via as_root for
  dpkg and /usr/local/bin symlinks)
- Fix setup.sh FVM flags: use fvm install --skip-pub-get --fvm-skip-input,
  set fvm global dynamically from resolved .fvm/flutter_sdk, disable
  analytics, and read pinned melos version from pubspec.yaml
- Fix .fvmrc: add updateMelosSettings: false and serialize in FVM's
  canonical key order so fvm install does not dirty .fvmrc or prompt
- Point .vscode/settings.json dart.flutterSdkPath to .fvm/flutter_sdk
  so future .fvmrc version bumps do not leave it stale
- Allow tracking .cursor/Dockerfile and .cursor/environment.json in
  .gitignore while ignoring other .cursor/* files

Co-authored-by: Leo Farias <leoafarias@users.noreply.github.com>
- Remove .cursor/Dockerfile and use Cursor's default base image with
  .cursor/environment.json running 'REMOTE_ENV=true bash setup.sh'
- Tighten remote detection in setup.sh to only CLAUDE_CODE_REMOTE=true
  or REMOTE_ENV=true so local developer machines never touch global state
- Pin FVM version in setup.sh only and verify installed FVM version
  matches the pin before skipping install
- Remove duplicated git cache, FVM_CACHE_PATH, PATH, apt, and
  safe.directory steps
- Stop swallowing errors on fvm config and fvm global, and extract
  fork-safe SDK version relative to FVM versions directory
- Use dart run melos instead of parsing pubspec.yaml with sed
- Add Cursor Cloud note to AGENTS.md

Co-authored-by: Leo Farias <leoafarias@users.noreply.github.com>
@cursor cursor Bot changed the title Add Cursor cloud agent environment with FVM chore(infra): add Cursor cloud agent environment with FVM Oct 20, 2026
- Scope REMOTE_ENV=true bash setup.sh in AGENTS.md and
  .github/copilot-instructions.md strictly to remote/cloud containers,
  instructing local agents to run 'fvm install' and never pass REMOTE_ENV
- Read the pinned Flutter version via 'fvm api project' instead of
  stripping FVM_INSTALL_DIR/versions from the SDK path
- Keep only the global melos activation pinned to the workspace version
  in pubspec.yaml so melos is installed once and resolves from any cwd
- Remove updateVscodeSettings: false from .fvmrc and update
  .vscode/settings.json to .fvm/versions/3.44.0 to eliminate the FVM
  warning while keeping git status clean

Co-authored-by: Leo Farias <leoafarias@users.noreply.github.com>
Piping curl into bash under set -eu without pipefail hid a failed
download; write it to a temp file so curl -f stops the script.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants