Codex Automation Tools is a Codex plugin marketplace for creating and updating personal Codex automations with reusable script-local context.
It keeps automation-specific helper scripts and their local state under:
/Users/seongho/.codex/automations/<automation-id>/
automation.toml
remote.json
memory.md
docs/
scripts/
<script-name>/
main.mjs
main.test.mjs
README.md
context/
automation.json
repo.json
codebase.json
env.json
db.json
integrations.json
memory/
decisions.md
assumptions.md
history/
runs.jsonl
artifacts/
latest-result.json
tmp/
logs/
automation-workspacesskill for all Codex automation creation and update flows.prepare_automation_workspace.pyhelper to scaffold automation-owned directories.- Node and Python helper entrypoint templates with focused tests and script-local path helpers.
- Script-local
history/andartifacts/directories so run records and generated outputs live beside the code that created them. - Script-local
context/files so automations can reuse repo, codebase, env, DB, integration, action-policy, and output expectations without asking every run. - Script-local
memory/files for durable decisions and assumptions. - Optional
remote.jsonmanifests for automations whose execution host is not the local Codex machine. - Optional
/Users/seongho/.codex/remote-hosts.jsonregistry generated from SSH config for known remote automation runners. manage_remote_hosts.pyhelper for discovering SSH aliases, writing the host registry, and showing configured hosts.manage_remote_automation.pyhelper for remote install, uninstall, run-once, status, reconcile, tombstone delete, and registry diff plans.- Remote cron executor that installs
codex-automation-runner.pyunder the remote root, resolves Node fromCODEX_AUTOMATION_NODE,PATH, nvm, or Homebrew paths, and manages crontab entries with scoped markers. - Guardrails for keeping private automation scripts out of team repositories unless they are intentionally shared.
Add this repository as a Codex plugin marketplace:
codex plugin marketplace add psh4607/codex-automation-tools --ref main
codex plugin add codex-automation-tools@codex-automation-toolsFor local development:
codex plugin marketplace add /Users/seongho/projects/seongho/plugins/codex-automation-tools
codex plugin add codex-automation-tools@codex-automation-toolsStart a new Codex thread after installing so the new skill is loaded.
When creating or updating any Codex automation, the plugin directs Codex to:
- Inspect existing automations and avoid duplicate ids.
- Resolve the automation id.
- Scaffold
/Users/seongho/.codex/automations/<automation-id>/. - Create one helper workspace at
scripts/<script-name>/. - Put repeated or guardrail behavior in
scripts/<script-name>/main.mjs. - Ask and save creation-time context in
scripts/<script-name>/context/. - Put durable decisions and assumptions in
scripts/<script-name>/memory/. - Put run history in
scripts/<script-name>/history/runs.jsonl. - Put durable generated outputs in
scripts/<script-name>/artifacts/. - Update the automation prompt so it calls
scripts/<script-name>/main.mjsby absolute path and reads context before acting.
Manual scaffold example:
python3 plugins/codex-automation-tools/scripts/prepare_automation_workspace.py daily-report-check --script-name run-check --language nodeThis creates:
/Users/seongho/.codex/automations/daily-report-check/scripts/run-check/
main.mjs
main.test.mjs
context/
automation.json
repo.json
codebase.json
env.json
db.json
integrations.json
memory/
decisions.md
assumptions.md
history/
runs.jsonl
artifacts/
latest-result.json
tmp/
logs/
Remote scaffold example:
python3 plugins/codex-automation-tools/scripts/manage_remote_hosts.py discover \
--include dalpha-mac \
--output /Users/seongho/.codex/remote-hosts.json
python3 plugins/codex-automation-tools/scripts/prepare_automation_workspace.py \
daily-report-check \
--script-name run-check \
--language node \
--title "Daily Report Check" \
--remote-host dalpha-macRemote automations should use a local Codex title prefixed with [remote], for example [remote] Daily Report Check. The prefix is an operator signal: the automation definition may be visible locally, but the durable runtime is expected to live on the configured remote host.
The remote scaffold creates /Users/seongho/.codex/automations/<automation-id>/remote.json. That file is a control-plane manifest, not a secret store. It records the host, remote root, scheduler type, reconcile interval, sync policy, and lifecycle policy.
The host registry is optional but recommended:
/Users/seongho/.codex/remote-hosts.json
It is generated from ~/.ssh/config plus ssh -G <alias> output. This validates the SSH alias without opening a remote shell and stores non-secret connection metadata such as hostname, user, port, identity-file path, proxy command, default remote root, scheduler, and reconcile cadence.
Remote lifecycle helper examples:
python3 plugins/codex-automation-tools/scripts/manage_remote_automation.py install \
/Users/seongho/.codex/automations/daily-report-check
python3 plugins/codex-automation-tools/scripts/manage_remote_automation.py install \
/Users/seongho/.codex/automations/daily-report-check \
--execute
python3 plugins/codex-automation-tools/scripts/manage_remote_automation.py pause \
/Users/seongho/.codex/automations/daily-report-check
python3 plugins/codex-automation-tools/scripts/manage_remote_automation.py resume \
/Users/seongho/.codex/automations/daily-report-check
python3 plugins/codex-automation-tools/scripts/manage_remote_automation.py delete \
/Users/seongho/.codex/automations/daily-report-check
python3 plugins/codex-automation-tools/scripts/manage_remote_automation.py run-once \
/Users/seongho/.codex/automations/daily-report-check \
--execute
python3 plugins/codex-automation-tools/scripts/manage_remote_automation.py status \
/Users/seongho/.codex/automations/daily-report-check \
--execute
python3 plugins/codex-automation-tools/scripts/manage_remote_automation.py reconcile \
/Users/seongho/.codex/automations/daily-report-check \
--execute
python3 plugins/codex-automation-tools/scripts/manage_remote_automation.py diff \
--desired desired-registry.json \
--actual actual-registry.jsondelete writes a tombstone first. Remote reconcile should disable the scheduler and archive the workspace before purge. Missing-entry pruning is intentionally opt-in through --prune-missing so an incomplete registry snapshot does not delete healthy remote jobs.
install --execute requires automation.toml so the local RRULE can be converted to cron. Supported RRULE shapes are hourly intervals plus daily/weekly wall-clock schedules. The executor currently supports remote scheduler: cron; macOS hosts such as dalpha-mac should use cron, not systemd-timer.
.agents/plugins/marketplace.json
plugins/codex-automation-tools/
.codex-plugin/plugin.json
skills/automation-workspaces/SKILL.md
scripts/manage_remote_hosts.py
scripts/manage_remote_hosts_test.py
scripts/manage_remote_automation.py
scripts/manage_remote_automation_test.py
scripts/prepare_automation_workspace.py
scripts/prepare_automation_workspace_test.py
python3 plugins/codex-automation-tools/scripts/prepare_automation_workspace_test.py
python3 plugins/codex-automation-tools/scripts/manage_remote_hosts_test.py
python3 plugins/codex-automation-tools/scripts/manage_remote_automation_test.py
python3 -m py_compile \
plugins/codex-automation-tools/scripts/prepare_automation_workspace.py \
plugins/codex-automation-tools/scripts/prepare_automation_workspace_test.py \
plugins/codex-automation-tools/scripts/manage_remote_hosts.py \
plugins/codex-automation-tools/scripts/manage_remote_hosts_test.py \
plugins/codex-automation-tools/scripts/manage_remote_automation.py \
plugins/codex-automation-tools/scripts/manage_remote_automation_test.pyThe plugin is centered on creation-time questions that future runs can reuse:
- Which repo or repos does this automation target?
- Which information is needed every run?
- Should codebase context be read live or cached as a snapshot?
- Which env key names are required, and where are they read at runtime?
- Is DB context needed, and is read-only summary enough?
- Which external systems are involved, such as GitHub, Sentry, Slack, Notion, Linear, Vercel, or Cloudflare?
- Which actions are allowed without asking again, and which require explicit approval?
The answers are stored in context/*.json and can be refreshed by the helper script. The automation should use these files as durable context, while treating live git checkouts, runtime env, live DBs, and external systems as the source of truth.
Codex native automation scheduling is local to the Codex machine. For automations that must continue while the local computer is off, use the remote model:
- Local Codex remains the control plane and authoring surface.
- The automation title must start with
[remote]. /Users/seongho/.codex/remote-hosts.jsonshould contain the remote runner host when practical.remote.jsonis the desired remote runtime manifest.- The remote host owns runtime
history/,artifacts/,tmp/, andlogs/. - The remote host should run reconcile every 6 hours by default, or daily for low-urgency jobs.
- Pause disables the remote scheduler without deleting workspace state.
- Delete writes a tombstone, disables the scheduler, archives the workspace, and purges only after the retention window.
- Diff-based deletion is allowed only for
managedBy: codex-automation-toolsrecords and only when--prune-missingis explicitly enabled. install --executesyncs the automation workspace to the remote host, writes a registry record, installs a per-automation run cron entry, and installs a global reconcile cron entry.run-once --executeexecutes the remote helper through the installed runner and writes script-localhistory/runs.jsonlplusartifacts/latest-result.json.- Node helpers do not require
nodeto be on cron's minimalPATHif Node is available throughCODEX_AUTOMATION_NODE, nvm under~/.nvm/versions/node,/opt/homebrew/bin/node, or/usr/local/bin/node.
Remote host setup:
python3 plugins/codex-automation-tools/scripts/manage_remote_hosts.py discover --include dalpha-mac
python3 plugins/codex-automation-tools/scripts/manage_remote_hosts.py list
python3 plugins/codex-automation-tools/scripts/manage_remote_hosts.py show dalpha-macdiscover --include <ssh-alias> fails if the alias is not present in ~/.ssh/config, so a misspelled host is caught before an automation points at it.
The plugin stores secret context as references and policies, not values. Automation workspaces may keep required env key names, retrieval methods, minimum access rules, redacted verification results, and derived summaries. They must not store raw env files, full connection strings, API tokens, private keys, or decrypted secret values in context/, memory/, history/, artifacts/, logs/, or prompts.
Encrypted blobs are not treated as a complete solution: if an unattended automation can decrypt them, the decrypt key is the real security boundary. Prefer runtime env, ignored local env files, OS keychain entries, or secret-manager references, with read-only or least-privilege credentials where possible.