sturnix
v0.13.5
Published
CLI to plug a repository into the Sturnix task queue (docs/STURNIX.md, CLAUDE.md/AGENTS.md, .env).
Maintainers
Readme
sturnix
CLI to plug a repository into the Sturnix task queue — no more editing files by hand in every repo.
Quick start
# 1. authenticate once (stores the key in the global keyring, chmod 600)
npx sturnix login
# 2. in each repo, plug it into the queue
cd my-project
npx sturnix initinit writes:
| File | What |
| ------------------------- | -------------------------------------------------------------------------------- |
| docs/STURNIX.md | full flow the agent follows (claim → execute → patch → complete) |
| CLAUDE.md / AGENTS.md | short block referencing docs/STURNIX.md (updates in place; creates if missing) |
| .env.local | STURNIX_ORG_ID and STURNIX_SYSTEM_SLUG (no API key) |
| .sturnix/config.json | pins this repository to an organization from the global keyring |
| .gitignore | ensures .sturnix/ and .env.local |
Idempotent updates
init is safe to re-run. The managed content lives between markers:
<!-- sturnix:start -->
...managed content...
<!-- sturnix:end -->Re-running init replaces only what's inside the markers — anything you write outside them is preserved. When the templates change on the server, run npx sturnix init again to re-sync.
Authentication
The queue key (aq_...) is generated on the site's API Keys page. Keys are scoped to organizations. sturnix login validates a key, stores it in the global keyring, and makes its organization active.
One key behaves exactly like the original single-key flow. With multiple keys, select the globally active organization or pin a repository:
sturnix keys add --key aq_... # add/replace an org key and make it active
sturnix keys list # * marks the globally active organization
sturnix keys use acme # switch the global active organization
sturnix keys use client --local # pin the current repository; global stays unchanged
sturnix keys current # show the effective org and credential source
sturnix keys remove client # remove one organization keylogin is an alias for keys add; logout removes the globally active key. Existing { "queue_key": "..." } configs migrate automatically after the key is validated by /whoami.
Credential precedence:
--key- exported
STURNIX_QUEUE_KEY - legacy
STURNIX_QUEUE_KEYin.env.local - organization pinned by the project
- globally active key
- the only stored global key
- legacy global
queue_key
Only STURNIX_* entries are read from .env.local; unrelated project secrets are never imported.
Queue commands (agent-facing)
Short wrappers around the API so an agent runs one small command instead of building a giant curl. Each prints JSON to stdout and uses the stored key automatically.
sturnix systems # systems + pending counts
sturnix tasks [--system S] [--status pending] # safe metadata; no title/prompt
sturnix tasks --all-systems # explicitly query the whole org
sturnix list-pending [--system S] # project system is automatic
sturnix task <id> # safe metadata; never title/prompt
sturnix claim <id> [--agent claude-code] [--base SHA] # claim (saves HEAD for rewind)
sturnix pull <id> [--dir DIR] # download attachments (./.sturnix/<id>/)
sturnix output <id> --file PATH [--mime T] # upload output attachment
sturnix complete <id> --notes "..." [metrics] # complete
sturnix fail <id> --error "..." # mark failed
sturnix release <id> # back to the queue
sturnix rewind <id> [--run] [--branch B] # reset repo to the task's base commit
Task listing and detail intentionally expose only opaque metadata. The task title,
prompt and attachment content are withheld until claim passes server-side
verification and the CLI independently verifies the signed payload against the
repository-pinned sturnix.trusted-keys.json.
complete metrics (all optional): --pr-url --branch --commit --diff-stat --model --effort --duration --tokens --files "a.ts,b.ts".
--pr-url must be the real PR URL (https://github.com/{owner}/{repo}/pull/{number}),
never the create-PR link (.../pull/new/...) — the API rejects it with 422 invalid_pr_url.
Prompt signature verification
claim verifies the task's prompt signature against sturnix.trusted-keys.json.
The API first checks the copy merged into the GitHub default branch, so a file
created or committed by an agent on its own branch is never trusted. The CLI then
checks that the local copy is committed and unchanged before verifying it.
Only a developer controls this file. An organization admin with verified 2FA uses Security → Organization keys → Sync keys. The organization setting decides whether this opens a pull request or commits directly to the repository default branch. Agents must never create, modify, stage, or commit the file themselves. There is no CLI sync command or signature-verification bypass.
If verification cannot be performed, the CLI releases the task and prints only a generic error plus the task id. It never prints the unverified title or prompt.
claim saves the repo HEAD (--base, defaults to git rev-parse HEAD) as the task's
base_commit_sha — kept from the first claim, so re-claiming a re-queued task never
overwrites the clean starting point. sturnix rewind <id> uses it to get back there:
by default it prints the git commands; --run executes the safe one (a fresh branch at
the base commit, nothing destroyed). Abandon the bad branch/PR and redo from there.
Exit codes: 0 ok · 1 error · 3 conflict (409, e.g. already claimed) · 4 not found (404).
Several tasks in one PR
To close many tasks of the same system with a single commit/PR: claim each task,
do all the work on one shared branch, open one PR, then complete each task with the
same --pr-url and --branch. With require_pr = true every task goes to
in_review; on merge the webhook completes all of them at once (and a close-without-merge
sends all back to the queue). See docs/STURNIX.md step 5 for the full flow.
Setup commands
sturnix login [--key aq_...]
sturnix logout
sturnix whoami
sturnix keys add [--key aq_...]
sturnix keys list
sturnix keys use <org-slug> [--local]
sturnix keys current
sturnix keys remove <org-slug>
sturnix init [--system <slug>] [--key <aq_...>] [--api-base <url>]
sturnix sync [--system <slug>]sturnix sync— refreshesdocs/STURNIX.mdand the existingCLAUDE.md/AGENTS.mdmanaged blocks. It also migrates a legacySYSTEM_SLUGfrom the docs into.env.local.--system <slug>— overrides this repository's configured system.initsaves the selected slug asSTURNIX_SYSTEM_SLUG; normal task commands use it automatically.--api-base <url>— point at another instance (default: production).--key <aq_...>/ exportedSTURNIX_QUEUE_KEYoverride the project/global keyring.
System precedence: --system > exported STURNIX_SYSTEM_SLUG > .env.local > legacy SYSTEM_SLUG in docs/STURNIX.md.
Requirements
Node >= 18 (uses native fetch). Zero dependencies.
