-
Notifications
You must be signed in to change notification settings - Fork 125
Description
Modules that need to persist data across workspace restarts (state files, cached binaries, scripts) have no standard way to do it. This has led to several ad-hoc patterns, each with its own problems.
Current situation
CODER_SCRIPT_DATA_DIR doesn't work for persistence. It was originally intended as a per-module cache directory, but the path contains a per-script UUID that changes on every workspace start. The module gets a fresh empty directory each time, and the previous one is left orphaned. We never noticed because the default base path is /tmp.
For reference, the on-disk layout when CODER_AGENT_SCRIPT_DATA_DIR=~/.coder:
~/.coder/coder-script-data/
07967256-3f92-4f6b-ab50-b078c13b996a/ # per-script UUID, new each start
fac108ad-1028-47b0-ad60-c71ddc6188be/ # per-script UUID, new each start
bin/ # shared, stable, this one works
CODER_SCRIPT_BIN_DIR (bin/) is stable and shared across scripts. The per-script UUID directories are not.
Some modules write to /tmp with fixed generic names. For example, agentapi writes bootstrap scripts to /tmp/main.sh, which can collide with other modules or be accidentally overwritten. #771 started addressing this for agentapi specifically.
Several modules have independently invented $HOME/<name>/ directories:
- agentapi:
$HOME/${MODULE_DIR_NAME} - amazon-q:
$HOME/.aws/.amazonq - cursor-cli:
$HOME/.cursor-cli-module - kiro-cli:
$HOME/.kiro
This works, but every module picks its own name and location with no shared convention, and it scatters dotdirs across the user's home directory.
A couple of modules still use CODER_SCRIPT_DATA_DIR directly (devcontainers-cli, archive). Whether that's a problem depends on whether they actually need data to survive restarts.
Proposal
Short term (registry convention):
Establish a shared parent directory like $HOME/.coder-modules/ where each module namespaces its own data:
$HOME/.coder-modules/
agentapi/
claude-code/
amazon-q/
This groups module data in one place instead of scattering it across $HOME, and is forward-compatible with a future agent-provided directory (see below).
The work:
- Audit existing modules to understand which need persistent storage, which are fine with ephemeral, and which might have bugs from UUID rotation or
/tmpcollisions. - Document the
$HOME/.coder-modules/<name>/convention so new modules follow it. - Migrate modules that currently use
/tmppaths orCODER_SCRIPT_DATA_DIRincorrectly.
Longer term (coder/coder):
The agent could provide a CODER_MODULE_DATA_DIR pointing to a stable shared directory, similar to how CODER_SCRIPT_BIN_DIR works for binaries. Modules would use $CODER_MODULE_DATA_DIR/<name>/. A shared directory fits better than per-module named ones since the agent sees scripts, not Terraform modules.
Related
- feat(coder/modules/agentapi): add state persistence #736, agentapi state persistence (where this was first discussed)
- fix(registry/coder/modules): write bootstrap scripts to module dir instead of /tmp #771, moving agentapi bootstrap scripts out of
/tmpinto module dir - feat(agentapi): add agentapi_cache_dir for persistent binary caching #769, feat: propagate agentapi_cache_dir to all agentapi-wrapping modules #770, agentapi binary caching (another case where persistent storage is needed)
- Improve agentapi module abstraction for configuration and flags #696, agentapi module abstraction
- Review comment where @DevelopmentCats suggested standardizing across modules