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
/tmp collisions.
- Document the
$HOME/.coder-modules/<name>/ convention so new modules follow it.
- Migrate modules that currently use
/tmp paths or CODER_SCRIPT_DATA_DIR incorrectly.
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
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_DIRdoesn'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_SCRIPT_BIN_DIR(bin/) is stable and shared across scripts. The per-script UUID directories are not.Some modules write to
/tmpwith 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:$HOME/${MODULE_DIR_NAME}$HOME/.aws/.amazonq$HOME/.cursor-cli-module$HOME/.kiroThis 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_DIRdirectly (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: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:
/tmpcollisions.$HOME/.coder-modules/<name>/convention so new modules follow it./tmppaths orCODER_SCRIPT_DATA_DIRincorrectly.Longer term (coder/coder):
The agent could provide a
CODER_MODULE_DATA_DIRpointing to a stable shared directory, similar to howCODER_SCRIPT_BIN_DIRworks 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
/tmpinto module dir