Problem
Runtime state currently lives inside the source tree:
data/accounts.json — account credentials
- SSH keys, logs, screenshots — ad-hoc locations or absent
- No resolution convention for per-install state
This couples the agent to its checkout, makes plugin installs per-workspace awkward, and makes it hard to run pi-droid in topologies where the source tree isn't writable (e.g., a global install or on-device Termux).
The .pi-droid/ entry exists in .gitignore but is unused — the slot is reserved and we just haven't moved into it.
Proposal
One workspace directory, resolved per-process:
Resolution order
PI_DROID_HOME env var
$XDG_DATA_HOME/pi-droid (if set)
~/.pi-droid/
./.pi-droid/ in repo root (dev mode only, detected by pi-droid package.json in cwd)
Layout
<workspace>/
├── workspace.json # device + transport config
├── accounts.json # replaces data/accounts.json
├── ssh-keys/
├── plugins/ # installed marketplace plugins, per-workspace
├── state/ # resumable flow progress, locks
├── logs/flows/
├── screenshots/ # failure diagnostics only
└── cache/ # transient, e.g., CDP tokens
Permissions: 0700 on root, 0600 on secret-bearing files.
workspace.json schema
{
"version": 1,
"devices": {
"s9-brain": { "transport": "local-adb", "serial": "…" },
"s9-remote": { "transport": "remote-adb", "ssh": "brain", "serial": "…" },
"self": { "transport": "on-device" }
},
"default": "s9-brain"
}
Back-compat
ANDROID_SERIAL env var still works (short-circuits to local-adb).
data/accounts.json still read as fallback with a one-time deprecation warning pointing at ~/.pi-droid/.
ACCOUNTS_JSON env var still honored (wins over both).
Design doc
See docs/CONNECTIVITY.md § Workspace resolution.
Depends on / blocks
Problem
Runtime state currently lives inside the source tree:
data/accounts.json— account credentialsThis couples the agent to its checkout, makes plugin installs per-workspace awkward, and makes it hard to run pi-droid in topologies where the source tree isn't writable (e.g., a global install or on-device Termux).
The
.pi-droid/entry exists in.gitignorebut is unused — the slot is reserved and we just haven't moved into it.Proposal
One workspace directory, resolved per-process:
Resolution order
PI_DROID_HOMEenv var$XDG_DATA_HOME/pi-droid(if set)~/.pi-droid/./.pi-droid/in repo root (dev mode only, detected by pi-droidpackage.jsonin cwd)Layout
Permissions:
0700on root,0600on secret-bearing files.workspace.jsonschema{ "version": 1, "devices": { "s9-brain": { "transport": "local-adb", "serial": "…" }, "s9-remote": { "transport": "remote-adb", "ssh": "brain", "serial": "…" }, "self": { "transport": "on-device" } }, "default": "s9-brain" }Back-compat
ANDROID_SERIALenv var still works (short-circuits to local-adb).data/accounts.jsonstill read as fallback with a one-time deprecation warning pointing at~/.pi-droid/.ACCOUNTS_JSONenv var still honored (wins over both).Design doc
See
docs/CONNECTIVITY.md§ Workspace resolution.Depends on / blocks
workspace.jsondevice definitions)pidroidCLI) — CLI reads workspace to pick default device