feat(install): per-instance data dir isolation via --data-dir / --instance (#193)
Apra Fleet is an open-source MCP server
Brought to you by:
apralabs
Originally created by: yashrajsapra
Originally owned by: yashrajsapra
--data-dir and --instance flags to install so multiple Claude Code instances running on the same machine use isolated config/log directories instead of fighting over a shared one--data-dir is eliminated by switching to execFileSync argv array (security fix surfaced in review)feat(install): per-instance data dir isolation via --data-dir / --instance + workspace CLIdocs: multi-instance usage guidefix(install): eliminate shell injection in --data-dir via execFileSync argv arraychore: cleanup fleet control files (PLAN.md, progress.json, feedback.md, CLAUDE.md, AGENTS.md)node dist/index.js install --data-dir /tmp/inst-a and --data-dir /tmp/inst-b produce fully isolated runtime dirsnode dist/index.js install --instance myproject resolves to a deterministic subdirectory--data-dir does not cause shell injection--data-dir continue to use the default data directory unchanged🤖 Generated with Claude Code
Originally posted by: kumaakh
Design suggestion for the
install-config.jsonfixRather than a per-workspace file,
install-config.jsonshould be a singleton accumulator at~/.apra-fleet/install-config.json(outside any data dir) that tracks every install invocation:Each entry maps 1:1 to a CLI invocation.
apra-fleet updatereads this one file and replays every entry in order — no need to discover workspaces viaworkspaces.jsonfirst.Upsert rule: key on
{ instance, dataDir }(both optional/undefined for the default workspace). On re-install, replace the matching entry rather than append — so runningapra-fleet install --instance work --llm geminia second time updates that entry in place.Changes needed:
src/cli/install.ts— after MCP registration, upsert into~/.apra-fleet/install-config.json(not${dataDir}/install-config.json)src/cli/update.ts— readconfig.installs[], replay each entry with['install', '--llm', e.llm, '--skill', e.skill, ...(e.instance ? ['--instance', e.instance] : []), ...(e.dataDir ? ['--data-dir', e.dataDir] : [])]--instancevalues and verifiesupdatewould replay both