Agent jobs, brokered
Less overhead.
More time away.
dayshift runs your apps’ agent jobs through one queue with one set of limits, so the work keeps moving even when you finally step away.
- Survives a restart
- One token per app
- Health you can alarm on
Jobs
- 12m 04s running
boogy-forward
portfolio-scan · machines
- 2m 14s running
serially
chapter 14 · draft, turn 3
- 48s running
repair-bench
diagnose · bench log #812
- queued
thingfile
describe · 6 staged photos
- queued
boogy-forward
plan-review · dayshift
- 31m done
serially
chapter 13 · revise
- Running
- 3
- Queued
- 2
- Runner
- claude
Running today behind
- B Boogy Forward
- S Serially
- t thingfile
- R Repair Bench
Four apps, one queue, one set of limits. Each app has its own token and sees only its own jobs.
From request to result
A clear path for every job.
dayshift handles the queueing, the gating and the bookkeeping, so your app only has to ask and your agents can get on with the work.
-
Submit
Your app posts a prompt, a runner and a working directory, and gets a job id back straight away.
-
Admitted
The job waits its turn behind a memory floor, a load ceiling, concurrency caps and a suspend switch.
-
Running
The CLI runs in its own process group, with no shell in between, under a timeout that ends in SIGKILL.
-
Recorded
The outcome is written to disk, and a failure says whether the job or the runner was at fault.
-
Returned
Poll the job, or hold a long-poll open and wake the moment anything you own changes.
What’s in the box
Everything a shift needs.
It’s the machinery each app would otherwise build around its agent CLI badly, built once and applied the same way to every app.
-
A queue that outlives the process
Every job is a file on disk. Restart the broker and queued work is still queued, and a job already running on an agent is adopted rather than interrupted. Lose the agent instead and its job is requeued or marked failed, never left running in the record.
-
A new CLI is a config entry
A runner is data: its binary, its flags, how it takes the prompt and how to read its answer. Adding one is a
runnersentry, not a code change. -
One set of limits for everyone
Memory floor, load ceiling, global and per-runner concurrency, and a suspend switch apply to every caller, instead of throttling one app while the rest ignore them.
-
Conversations that pick up where they left off
A follow-up turn inherits the chat's runner, model, directory and session, so the CLI resumes instead of starting cold. Turns go one at a time.
-
Your jobs are yours
Each app gets its own token and sees only the jobs it submitted — another app's job answers exactly like one that does not exist. One app can be granted read of another's, in the broker's config and never by asking; a grant reads, and can never cancel, delete or reply.
-
Health you can alarm on
Per-runner health counts only the runner's own faults, such as an expired credential or a missing binary. A job that hit its own turn limit doesn't trip the alarm.
-
Workspaces, and branches back
Borrow a tree the broker owns, let an agent edit it, and push the result as
agent/<job-id>, but only if it doesn't break a check its base branch passes. -
Half an answer is an error
When a response runs past the CLI's output cap, dayshift says so and keeps every part, instead of reporting success with only the last one.
-
Watch it live
A dashboard shows the queue, the gates, runner health and every chat, updated over one long-poll with no websocket to keep alive.
-
One queue, many hosts
Agents on your machines poll one coordinator for work. Labels decide where a job may run, a conversation stays on the host that holds its session, and a restart waits for running jobs instead of killing them.
What it isn’t, yet
-
Not a hosted service
dayshift runs on machines you own. A job runs on the host whose agent took it, so an agent goes wherever the work is.
-
No Python or TypeScript library yet
From a shell there is the
dayshiftCLI, from an agent the MCP server, and from C++ a header-only client. Anything else calls the REST API. -
Your own network, your own CA
Agents reach the coordinator over TLS, verified against a certificate authority you run on your network. There is no setup for publicly issued certificates, or for hosts reaching the coordinator across the internet.
Built for real systems
Connect. Control. Unwind.
dayshift sits between your apps and the agent CLIs they call. It owns the queue, the limits, the sessions and the record of what happened, so no app has to fork and exec a CLI itself.
Your apps
- BBoogy Forward
- SSerially
- tthingfile
- RRepair Bench
- Yours next
- Persistent job queue
- Admission gates
- Scheduler and worker pool
- Resumable conversations
- Per-runner health
- One token per caller
REST on :14080 · loopback by default
Agent CLIs
- Claude Code configured
claude -p - Codex example config
codex exec - Your CLI no code change
a runners entry
-
Workspaces
Broker-owned trees an agent may edit
-
Staged inputs
Files for a job, served safely, with thumbnails
-
Job store
One JSON file per job, swept after 30 days
# Hand it a job; the answer comes back on stdout, and only the answer.
dayshift submit --wait "Summarize this repo and list its open risks." > risks.md
# Pipe the prompt in, pick a model, run it in a directory on the broker's host.
git diff | dayshift submit --wait --model claude-opus-5 --workdir /srv/work/app -
# Or hand it over now and collect it later.
id=$(dayshift submit "Tidy the Makefile and explain what changed.")
dayshift wait "$id"
dayshift jobs --status running
dayshift watch # one line whenever a job changes # Give an agent the broker as tools. Read-only unless you allow writes.
claude mcp add dayshift \
--env DAYSHIFT_MCP_URL="$DAYSHIFT_URL" \
--env DAYSHIFT_MCP_TOKEN="$DAYSHIFT_TOKEN" \
--env DAYSHIFT_MCP_ALLOW_WRITES=1 \
-- node dayshift-mcp-ts/dist/index.js
# Then, in a session:
# "Run a full review of this repo on dayshift and tell me when it's done."
# → dayshift_submit_job returns the job id at once
# → dayshift_wait comes back with the answer #include "dayshift_client/client.h" // header-only
namespace ds = dayshift::client;
ds::Client broker(url, token);
ds::JobRequest req;
req.runner = "claude";
req.service = "researcher";
req.prompt = "Summarize this repo and list its open risks.";
req.workdir = "/srv/work/my-repo";
req.allowed_tools = {"Read", "Glob", "Grep"};
// Submit, then poll every 500 ms for up to ten minutes.
ds::JobResult r = broker.runToCompletion(
req, std::chrono::milliseconds(500), std::chrono::seconds(600));
if (r.ok()) std::puts(r.result_text.c_str()); Simple to integrate
Get started in minutes.
From a shell, hand it a job with one command. From an agent, give it the broker as tools. Either way the work runs behind the same limits, and you collect the answer when it’s ready.
dayshift submit --waita job in, the answer out on stdoutdayshift watcha line whenever one of your jobs changesdayshift_submit_joban agent hands work off (read-only until you allow it)
On your phone
Check on the shift from the beach.
The dayshift app puts your jobs, their answers and your conversations in your pocket, so you can see the work is moving without going back to your desk.
Running on Android Signed builds from our own build service. Not in any store yet.
-
Live, without a refresh
Jobs update as they move. The app holds one long-poll open and fetches only what changed.
-
Reply from wherever you are
Read a conversation and add the next turn. The box stays closed while the last turn is still running.
-
Know why it stopped
A failed job says whether it hit its own limits or the runner is broken, so you know if a retry will help.
-
Your token stays in the keystore
The broker token lives in the phone's secure storage, and Settings tests the address and the token separately.
More agents. More freedom.
Run the work. Take the break.
Hand the queue to dayshift and let your agents keep the day shift.