factory-droid¶
Factory Droid is Factory's closed-source coding agent, shipped as the droid command-line binary
for Linux, macOS and Windows. Its parser is in the backlog
(issue 54).
Source and evidence¶
- Closed source. Installer
https://app.factory.ai/cli(read only, not run) pinsVER="0.233.0"and downloadshttps://downloads.factory.ai/factory-cli/releases/0.233.0/<os>/<arch>/droidinto~/.local/bin/droid(lines 64-66, 106). Windows installerhttps://app.factory.ai/cli/windowsfetchesdroid.exeinto%USERPROFILE%\bin(lines 60-62, 105). No npm package. - Binary:
linux/x64/droid0.233.0, 275,543,520 bytes, sha256744a5c50…f7ab8matching the published.sha256; bun-compiled ELF. Evidence level B is strings from this binary:strings -n 8(the 8-bit table holds the minified code) and UTF-16 strings. - Evidence level D is vendor documentation, fetched as Markdown from
https://docs.factory.com/<page>.md(indexhttps://docs.factory.ai/llms.txt). - The Factory-AI/factory GitHub repo is docs only (prior finding; not re-cloned).
Observed¶
No real install.
Source reviews¶
None.
Collection¶
Per-user storage¶
Home resolution (B): getFactoryHome(){return FACTORY_HOME_OVERRIDE ?? HOME ?? USERPROFILE},
getFactoryDirName(){return ".factory"} (.factory-dev in dev builds); helper
Je(r,...)=join(home,".factory",r,...). Same layout on Linux, macOS and Windows
(droid-cli_settings.md:21-22: ~/.factory/settings.json, %USERPROFILE%\.factory\settings.json).
The known top-level directory list in the binary:
Sq=["missions","missionsV2","repl-runs","specs","sessions","logs","cache","artifacts","temp","snapshots","crons","skills","droids","commands","plugins","updates","mermaid","automations","software-factory","worktree-setups","state","telemetry","generated-images"]
~/.factory/ files and directories:
settings.json,settings.local.json(Ddroid-cli_settings.md:28-33), legacyconfig.jsonwithcustom_models(model-independence_byok.md:46),mcp.json(harness_mcp.md:164),hooks.json(harness_hooks.md:20),org-managed-settings.json,host.json,computer.json(B listbf).sessions/: transcriptssessions/<projectKey>/<sessionId>.jsonlwith sidecar<sessionId>.settings.json; legacy flatsessions/<id>.jsonlandsessions/btw/<id>.jsonl(B,CREATE TABLE sessionscomment;sessionFileExists).projectKey="-" + realpath(cwd)with leading/removed and every/→-(B, functionJi), e.g.sessions/-Users-enoreyes-code-work-myapp/*.jsonl(help text).sessions/.favorites.cache/session-index/index.dbSQLite (En(e)=join(e,"cache","session-index","index.db"); tablessessions(session_id, project_key, cwd, title, org_id, owner, mission, …),session_ingest,meta),cache/session-discovery-index.json,cache/feature-flags.json,cache/changelog.json,cache/sounds/*.wav.state/history.jsonprompt history (migrated from~/.factory/history.json),state/mission-readiness-warnings-shown.json.logs/:droid-log-single.log,console.log,factoryd.log,daemon-critical-error.json,daemon-stderr.log; rotation byFACTORY_LOG_MAX_BYTES/FACTORY_LOG_MAX_DAYS, overrideFACTORY_LOG_FILE(B). Hooks example appends~/.factory/bash-command-log.txt(D).droids/,skills/<name>/SKILL.md,commands/,output-styles/,plugins/,automations/<id>/,specs/(specSaveDir),docs/,artifacts/,missions/<sessionId>/(mission.md,features.json,progress_log.jsonl),repl-runs/<sha256>/,software-factory/workstreams/…/{repos,worktrees,review-sessions},worktrees/(defaultworktreeDirectory, Dcli-reference.md:379),ide/(IDE lock/pid files),certs/,bin/(keytar.node,rg,agent-browser,script-runtime-<hash>/),tools/agent-browser/,snapshots/content/(file snapshot store),temp/env/droid-env-<session>-*.sh(environment dumps for hooks),generated-images/,updates/(staged binaries),telemetry/.- No
%APPDATA%orLibrary/Application Supportpaths exist in the binary.
Scratch directories¶
The agent's own working space, all listed above: ~/.factory/worktrees/ (the default
worktreeDirectory), software-factory/workstreams/…/{repos,worktrees,review-sessions},
repl-runs/<sha256>/ and temp/ (see Credentials on temp/env). Exclusions
for them are in Exclusions.
Credentials¶
All under ~/.factory/ (B, class Ne, IH() maps list Uf onto join(home,".factory")):
auth.v2.fileencrypted credentials; key in OS keyring (keytar, service "Factory CLI", accountauth-encryption-key) with markerauth.v2.keyring; macOS alternativesecurityCLI (login-keychain-v2); when the keyring is unavailable ordisableKeyringis set the key is written toauth.v2.key("auth.v2.file exists but auth.v2.key is missing"). Legacyauth.encrypted, and legacy plaintextauth.json(still in the cleanup list["auth.json","config.json","mcp.json","settings.json"]).prem-auth/<sha256(origin)>/credentials.jsonfor Prem deployments.mcp-oauth.v2.file+mcp-oauth.v2.keyMCP OAuth tokens (Dharness_mcp.md:177: keyring "or a fallback file").settings.json/settings.local.json/config.json:customModels[].apiKeymay be literal or${VAR}(Dbyok.md:20-46);mcp.jsonheaders/oauth.clientSecret(Dharness_mcp.md:180).settings.json,settings.local.json,config.jsonandmcp.jsonare flagged, in~/.factory/and in a project's.factory/.FACTORY_API_KEYenv var.temp/env/*.shdumps process environment (may include keys); flagged by.factory/temp/env/*, which the narrowertempexclusion of Exclusions leaves reachable.
Exclusions¶
.factory/updates, .factory/bin, .factory/tools, .factory/snapshots, .factory/worktrees,
.factory/generated-images, .factory/cache/sounds, .factory/software-factory/*/*/repos,
.factory/software-factory/*/*/worktrees, and every entry of .factory/temp whose name does not
start with e (.factory/temp/[!e]*), so temp/env is collected and flagged
(Credentials).
Project-local files¶
.factory/ at git root and in nested folders (D hierarchical-settings.md:15-39): settings.json,
settings.local.json, mcp.json, hooks.json (legacy hooks/hooks.json,
hooks/hooks.migrated.json), hooks/*.sh|py, droids/*.md, skills/*/SKILL.md, commands/*,
output-styles/*.md, worktree-setups/*.yaml, prompts/, docs/, system.md,
pr-risk-thresholds.json, threat-model.md, video/wiki/, automations/. AGENTS.md (also reads
CLAUDE.md, .agents/, .agent/, .claude/ dirs: B arrays WM, h).
.factory-plugin/plugin.json, marketplace.json (D). .droid.yaml is documented only as "an older
project configuration surface" (settings.md:37) and does not occur in the binary. DROID.md
occurs nowhere.
Where the project path is recorded¶
- Transcript first line: JSON with
type:"session_start",cwd, optionallastCwd(B,a.type!=="session_start",a.lastCwd). - Directory name
sessions/<projectKey>encodes cwd (ambiguous when the path contains-). cache/session-index/index.dbtablesessions, columnsproject_key,cwd;cache/session-discovery-index.jsonentriescwd.
Parsing¶
Factory Droid is backlog: its JSONL session transcripts are on disk
(Per-user storage), and the parser is
issue 54.
Confidence¶
- High:
~/.factoryon all OSes,FACTORY_HOME_OVERRIDE, the session layout andprojectKeyencoding, theindex.dbpath and columns, theauth.v2.*andmcp-oauth.v2.*names, the keyring with its file fallback,state/history.json, the log file names and the excluded directories. - Medium: the
software-factorysubtree sizes, theide/contents and theprem-authlayout (from strings, matching the earlier finding). - Low: whether 0.233.0 still writes
auth.json(it is only in the cleanup list). - Not determined: the transcript JSONL schema beyond the first line; the Windows keyring backend
(keytar to Credential Manager is assumed); whether
%USERPROFILE%\bin\droid.exeis the only Windows binary location.