e0ipso / e0ipso/ddev-assistant-cursor
Mirror Cursor seed with rsync instead of rm -rf plus full cp -R on every start
- Dominant language
- Shell
- Stars
- 1
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Problem
The post-start hook in config.assistant-cursor.yaml runs `sudo rm -rf "${HOME}/.cursor"` followed by a full `cp -R -P` of the read-only seed mount on every single `ddev start`. On a real project this took 63,930 ms, the second-slowest hook in a 10m37s start and 10 percent of total start time.
The cost comes from copying data cursor-agent never reads. The seed directory is 713 MB across 37,849 files and 11,299 directories, and it breaks down like this:
- 609 MB `extensions/`, Cursor IDE extensions, which the CLI agent in a container has no use for
- 67 MB `acp-sessions/`
- 21 MB `projects/`
- 7.7 MB `chats/`
- 4.9 MB `ai-tracking/`
- several `statsig-cache.json.*.tmp` files at roughly 700 KB each, left over from host-side writes
That leaves well under 1 percent of the payload as configuration the agent actually needs. The `rm -rf` also guarantees a full re-copy even when nothing on the host changed, so the cost is paid identically on every restart.
`docker-compose.assistant-cursor.yaml` mounts the same host directory read-only at `~/.cred-seed/cursor`, so the container already has a live view of the host tree. The copy exists only to produce a writable version.
## Expected Behavior
Mirroring the host Cursor configuration should be incremental and should skip data the CLI agent does not read. A no-change restart should complete in roughly a second rather than a minute.
`rsync` ships in the ddev-webserver image (verified at /usr/bin/rsync on ddev-webserver v1.25.4), so `rsync -a --delete` with an exclude list gives the same "host is authoritative, no merge" semantics the current comment describes, without the wipe-and-recopy:
rsync -a --delete \
--exclude 'extensions/' \
--exclude 'chats/' \
--exclude 'acp-sessions/' \
--exclude 'ai-tracking/' \
--exclude 'projects/' \
--exclude 'statsig-cache.json.*.tmp' \
"${seed_config}/" "${HOME}/.cursor/"
If rsync cannot be assumed on every supported webserver image, fall back to the current `cp -R` path when `command -v rsync` fails.
## Steps to Reproduce
1. Install the add-on on a project where the host `~/.cursor` has Cursor IDE extensions installed, so the tree is in the hundreds of megabytes.
2. Run `export DDEV_VERBOSE=true` and then `ddev restart`.
3. Find the `PERF: exit app.Exec` line for the assistant-cursor post-start hook and read the elapsed milliseconds.
4. Run `ddev restart` again without touching the host `~/.cursor`. The elapsed time is unchanged, because the hook wipes the target before copying.
## Additional Context
Add-on version v1.0.0. Host is Linux, DDEV v1.25.4, ddev-webserver v1.25.4, project uses apache-fpm and PHP 8.3.
The credentials copy at `~/.cred-seed/cursor-auth` is only 12 KB and is not worth changing. The problem is entirely in the `${seed_config}` branch at config.assistant-cursor.yaml lines 10 to 18.
The same wipe-and-recopy shape appears in the sibling add-ons (assistant-claude, assistant-codex, assistant-copilot), but their seed trees are small enough that the cost is not yet visible. Worth considering a shared approach if this one changes.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at the `${seed_config}` branch in config.assistant-cursor.yaml, lines 10–18, and inspect the existing post-start hook and its host-authoritative comment. Verify rsync availability with `command -v rsync`, preserve the listed exclusions and fallback behavior, then run the documented DDEV restart benchmark twice; done means unchanged restarts avoid the full copy and the hook still produces the writable configuration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- shell
- Domain
- devops
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100