A scheduler for Claude. You write skills, you schedule them, they run. When they need you, they nudge.
Project → where things run (a working directory + its context)
Schedule → when things run
Payload → what runs (skill / flow / prompt / shell)
Nudge → when it needs you
Every UI screen and every CLI surface maps to one of those four. There are no agents, no org charts, no budgets, no approvals. If a job needs human input, it writes a nudge.
- Scheduler daemon — polls every 60s for new schedules, arms a single timer for the soonest due job, spawns Claude (or bash) per job
- Executor —
claude -p "<prompt>"orbash -c "<cmd>". Timeout + graceful kill + stdout/stderr capture. Nothing else. - Nudge watcher — tails each working-directory's
.occ/*.occfiles, ingests new ones into Postgres, syncs button/reply responses back to the file - Registry — discovers
claude,one, available skills (~/.claude/skills/+<project>/.claude/skills/) and flows (one --agent flow list) - REST API —
/api/projects,/api/schedules,/api/jobs,/api/nudges,/api/registry,/api/files - UI — projects, schedules, jobs, nudges inbox, skills (view + edit), flows, sync browser, apps (One connections), files. React + Vite + Tailwind. One Design System palette (Ivory/Charcoal + Yellow CTAs).
- CLI —
one-run projects/schedule/jobs/nudges/registry/serve
- Node 20+ and pnpm 9.15+
- Claude CLI installed and on your
PATH— required forskillandpromptpayloads. Verify withclaude --version. - One CLI (optional) — required for
flowpayloads and the Apps / Sync surfaces. Verify withone --version.
git clone https://github.com/withoneai/run.git one-run
cd one-run
pnpm installpnpm devThis boots:
- the API + scheduler daemon + nudge watcher on
127.0.0.1:7777 - the Vite UI on
http://localhost:5173(proxies/apito 7777)
Or run each half on its own:
pnpm dev:server # API + daemon only
pnpm dev:ui # UI onlyFor a production-style single-process run:
pnpm build
pnpm --filter @one-run/server start # serves UI + API on :7777Open http://localhost:5173. You'll land on a welcome screen — click Attach a project and point it at a working directory (anywhere on disk). Everything else is scoped to that project:
- skills come from
~/.claude/skills/and<project>/.claude/skills/ - flows come from
one --agent flow listrun in that directory - apps are One connections (
one --agent list) scoped to that directory - jobs run with that directory as their
cwd
From the UI: Schedules → New schedule. Pick a skill, pick a cadence (every:1h, cron:…, or once), save. The daemon picks it up within 60s.
Or from the CLI:
one-run schedule add "email triage" --schedule every:1h --skill email-triage
one-run schedule run <id> # fire once, nowWhen the skill wants your input, it writes an .occ file in the project directory. The nudge watcher picks it up and it shows up in Nudges. Approve or reply, and the skill's next run continues.
~/.one-run/ by default — embedded Postgres data, logs. Override with ONE_RUN_HOME=/custom/path. Delete the directory to reset to a clean slate.
# Projects
one-run projects add "ceo" --dir ~/work/ceo
one-run projects list
# Schedules
one-run schedule add "email triage" --schedule every:1h --skill email-triage
one-run schedule add "morning brief" --schedule "cron:0 9 * * 1-5" --tz America/Los_Angeles --skill morning-brief
one-run schedule list
one-run schedule show <id>
one-run schedule run <id> # trigger now
one-run schedule disable <id>
# Jobs (working sessions — each scheduled trigger or manual launch is a job)
one-run jobs list
one-run jobs show <id>
# Nudges (the inbox)
one-run nudges list
one-run nudges show <id>
one-run nudges approve <id> # primary button
one-run nudges reply <id> Ship it with a bump to v2
# Discover what's runnable
one-run registry show| Kind | Expands to |
|---|---|
skill |
claude -p "/<ref>" --dangerously-skip-permissions |
flow |
one --agent flow execute <ref> -i k=v ... |
prompt |
claude -p "<text>" --dangerously-skip-permissions |
shell |
bash -c "<text>" |
When should a scheduled job interrupt you? That's the question, and the answer lives in the skill or flow, not in the platform. If /email-triage sees a VIP email, it writes an .occ file. If it sees routine inbox noise, it stays quiet. Per-skill logic; no platform policy. If everything nudges, the inbox becomes noise.
one-run started as a fork of Paperclip and owes its original scaffolding to that project: the embedded Postgres launcher, the Drizzle migration reconciliation, and the initial Vite + Tailwind UI shell.
Most of that has since been rewritten. The scheduler, executor, nudge watcher, registry, project model, REST API, CLI, and UI pages are new code. Paperclip's runs/agents/org-chart model was removed entirely and replaced with the four-pillar model above (project / schedule / payload / nudge).
Inspired by Paperclip; distinct from it.
MIT — see LICENSE. Portions Copyright (c) 2025 Paperclip AI (retained under the same MIT terms from the original fork).
Early. Shape may still move. Issues welcome.