Repository navigation
chore(infra): add Cursor cloud agent environment with FVM - #1100
Closed
leoafarias wants to merge 6 commits into
Closed
leoafarias wants to merge 6 commits into
leoafarias wants to merge 6 commits into
Conversation
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>
- 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>
- 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related issue
N/A
Description
Adds a Cursor Cloud Agent environment configuration (
.cursor/environment.json) backed bysetup.shon Cursor's default base image (no custom.cursor/Dockerfile). During each Cursor Environment Build,REMOTE_ENV=true bash setup.shruns once and the full disk state (including~/fvm,~/.pub-cache, and/usr/local/binsymlinks) is snapshotted for subsequent agent runs.Changes
.cursor/environment.json:{"install": "REMOTE_ENV=true bash setup.sh"}) withoutbuildoruserkeys so the environment uses Cursor's default image and does not lock snapshot updates.setup.sh:CLAUDE_CODE_REMOTE=trueorREMOTE_ENV=trueis explicitly set. Runningbash setup.shwithout those flags exits immediately at the guard without touching/usr/local/bin, global FVM config, global Flutter version, or global gitsafe.directory.FVM_VERSION=4.3.2insetup.shonly and verifies the installedfvm --versionmatches the pin before skipping installation.fvm installthat reads.fvmrc(3.44.0), queriesfvm api projectfor the configuredflutterversion (supporting fork-pinned versions and customFVM_CACHE_PATHlocations), and setsfvm global "$SDK_VERSION".fvm config --no-use-git-cache --no-update-checkandfvm global "$SDK_VERSION"directly without swallowing errors, setsPATHandsafe.directoryonce, and symlinks/usr/local/bin/{flutter,dart,fvm,melos}viaensure_symlink(usingsudo -nwhen non-root) so tools resolve across Build snapshots.melosglobally once pinned to the workspace version inpubspec.yaml(6.3.3) and runsmelos bootstrapvia/usr/local/bin/melos(avoiding compilingmelostwice in both~/.pub-cacheand.dart_tool)..fvmrc&.vscode/settings.json:"updateMelosSettings": falseto.fvmrcsofvm installruns non-interactively without prompting or dirtyingmelos.yaml."dart.flutterSdkPath"in.vscode/settings.jsonto".fvm/versions/3.44.0"(matching FVM's default VSCode update) and omits"updateVscodeSettings": falsefrom.fvmrc, eliminating FVM's per-run VSCode warning while keepinggit statusclean..gitignore,AGENTS.md, &.github/copilot-instructions.md:.cursor/environment.jsonvia.cursor/*+!.cursor/environment.json.REMOTE_ENV=true bash setup.shinAGENTS.mdand.github/copilot-instructions.mdto Cursor Cloud / remote containers only, and instructs local agents to runfvm install(or use their own Flutter) and never passREMOTE_ENV=truelocally.Review Checklist
bash setup.shguard behavior, a fresh run ofREMOTE_ENV=true bash setup.sh, a second no-op run, tool resolution (flutter,dart,fvm,melos) in a clean login shell, cleangit status, andshellcheck setup.sh..claude/hooks/session-start.sh(CLAUDE_CODE_REMOTE=true bash setup.sh) continues to work unchanged.AGENTS.mdand.github/copilot-instructions.md, and included post-merge instructions below.Additional Information (optional)
Post-Merge Activation Steps
main.mixCloud Agents environment's environment.json location at.cursor/environment.json(or create the environment from the repo).REMOTE_ENV=true bash setup.shcompletes and snapshots cleanly.Verification Summary
bash setup.sh): After clearing global state (/usr/local/bin/{flutter,dart,fvm,melos},~/fvm,~/.config/fvm, and global gitsafe.directory), ranbash setup.shwithoutREMOTE_ENV=trueorCLAUDE_CODE_REMOTE=trueand confirmed it exited at the guard without touching any global state.REMOTE_ENV=true bash setup.sh): Ran from a clean state with no FVM, Flutter, DCM, or Melos installed; verified FVM4.3.2, Flutter3.44.0(from.fvmrc), DCM1.31.4, and Melos6.3.3installed and bootstrapped all 11 workspace packages with no VSCode settings warning.REMOTE_ENV=true bash setup.sh): Immediately re-ranREMOTE_ENV=true bash setup.shand confirmed FVM, Flutter SDK, DCM, Melos activation, and/usr/local/binsymlinks were all no-ops.flutter,dart,fvm, andmelosresolve via/usr/local/binin a clean login shell (env -i HOME="$HOME" PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" bash -lc),git statusremains clean, andshellcheck setup.shpasses with zero warnings.mainin the Cursor dashboard (requires merging.cursor/environment.jsonand pointing the environment'senvironment.jsonlocation at the file post-merge).