From download to first report.
Factory Log runs on macOS 15 Sequoia or later, on Apple silicon and Intel Macs. Setup is three steps, and the app does the first two for you.
1 · Install the app
Unzip the download and drag Factory Log to your Applications folder. It is one universal app: no installer, no helper daemons, no background service.
On a work laptop where you can't write to /Applications, keep it in ~/Applications instead — everything else works the same.
2 · Clear the first-launch prompt
The app is ad-hoc signed rather than notarized, so macOS asks once. Click Done, then allow it in System Settings → Privacy & Security → Open Anyway, and open the app again. The button appears for about an hour after the first attempt.
Or drop the quarantine flag in Terminal:
xattr -dr com.apple.quarantine "/Applications/Factory Log.app"
The same command fixes a message saying the app is damaged. Gatekeeper never needs to be turned off.
Three steps the welcome screen walks you through.
Agents don't talk to the app directly. Each one runs a small command, factorylog, which appends a line to a log file on your Mac — the app watches that file and shows the new line a second later.
Install the command-line tool
The app copies factorylog to ~/.local/bin. Then it runs command -v factorylog in your login shell, because that shell — not the app — sets the PATH your agents see.
If the shell can't find it and you use zsh, the macOS default, Add to PATH appends one export line to ~/.zshenv. Press Reinstall any time to copy the CLI again.
Connect your coding agent
Codex: adds the instruction to ~/.codex/AGENTS.md, and adds the log folder to Codex's sandbox in ~/.codex/config.toml so the CLI is allowed to write there.
Cursor: adds a rule to ~/.cursor/rules. Another agent: press Copy the instructions and paste them where that agent keeps its standing rules. The same buttons live in Settings → Integrations.
Send a test report
Send a test report runs factorylog start and factorylog archive the same way an agent would, for a closed task called "Test report". If it appears in Today, the command and the app both work.
Then simply ask an agent to build something. Agents report work that changes something — a fix, a feature, new docs. Questions and explanations aren't logged.
Any agent that can run a shell command can report.
Paste the same instruction block where your agent keeps its standing instructions, and restart the agent so it picks them up.
Where each agent reads it
- Claude Code —
~/.claude/CLAUDE.md - Gemini CLI —
~/.gemini/GEMINI.md - Most other agents — an
AGENTS.mdat the root of each project
If the agent runs commands in a sandbox, it also needs permission to write to ~/Library/Application Support/Factory Log. For Codex, that is the [sandbox_workspace_write] section the app appends for you — written out in full, with an absolute path.
What the instructions say
- Start one task when a meaningful piece of work begins; keep the task ID from the JSON response
- Report after a meaningful result, archive when the requested work is finished
- Short and factual: what changed, or what was verified
- No source code, no diffs, no command output, no secrets, no guessed percentages
- On a blocker, keep the task open and name the blocker
Reports aren't showing up. Go through these in order.
1 · Does your shell find the command?
Open a new Terminal window and run command -v factorylog. It should print a path ending in .local/bin/factorylog. If it prints nothing, add the folder to your PATH:
# zsh, the macOS default echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshenv # fish fish_add_path ~/.local/bin
On bash, add the same export line to ~/.bash_profile. Then restart your agent so it picks up the new PATH.
2 · Send a test report
From Settings → Integrations. If it shows up in Today, the command and the app both work — the problem is on the agent's side.
3 · Start a new agent session
Agents read their instructions when a session starts, so a session that was already open hasn't seen them. Cursor might need a restart to notice a new rule.
4 · Check Codex's sandbox
If Codex can't write the log, the log folder has to be in its writable roots, written out in full:
[sandbox_workspace_write] writable_roots = ["/Users/you/Library/Application Support/Factory Log"]
If the file already has a [sandbox_workspace_write] section, add the path to its list — the app never edits a section that is already there.
5 · Ask for real work
A question, an explanation or a status check isn't logged, by design. Only work that changes something produces a report.
Updates
Once a day the app asks whether there is a newer version, and shows what changed. Install and Relaunch swaps it in place after the download's checksum, bundle ID, version and code signature are verified. Factory Log → Check for Updates… checks right away.
# turn the daily check off
defaults write dev.factorylog.app AppUpdaterAutomaticChecks -bool false
Every file it can touch, and every setting.
Factory Log changes a file only when you press the matching button, and it appends in place, so a dotfile that is a symlink stays one.
| Purpose | Default path |
|---|---|
| Event history | ~/Library/Application Support/Factory Log/events.jsonl |
| Writer lock | ~/Library/Application Support/Factory Log/events.jsonl.lock |
| Narrative cache | ~/Library/Application Support/Factory Log/narratives.json |
| Compacted daily totals | ~/Library/Application Support/Factory Log/daily-aggregates.json |
| User CLI | ~/.local/bin/factorylog |
| PATH line for zsh | ~/.zshenv |
| Codex instructions | ~/.codex/AGENTS.md |
| Codex sandbox access | ~/.codex/config.toml |
| Cursor rule | ~/.cursor/rules/factory-log.mdc |
Environment variables
FACTORYLOG_EVENTS_FILE— point the app, watcher and CLI at another JSONL storeFACTORYLOG_OLLAMA_MODEL— recap model, defaultgemma3:4bFACTORYLOG_OLLAMA_HOST— recap endpoint, defaulthttp://127.0.0.1:11434FACTORYLOG_INSTALL_DIR— where the install script puts the CLI
Every CLI command also takes --store and --timestamp. Agents sharing one history must point at the same store.
Bringing old work in
Two optional importers fill the gaps before you installed Factory Log:
- A Git importer that turns runs of your commits into tasks, with
--dry-runand a local-only mode that skips AI-written titles - A plain-text work-log importer for older notes, with timezone and project-mapping flags
Both run only when you start them, both are local by default, and neither invents a project path it cannot find.
~/.local/bin/factorylog, and delete the Factory Log folder in Application Support if you don't want to keep the history. Remove the instruction block from your agents' rule files and nothing else is left behind — there is no service, no login item and no account to close.