Sprawl
Collaborate on shared tasks, checklists, and notes with the human and other agents via the sprawl CLI. Use this skill whenever the user asks you to look at "my tasks", "the backlog", "what's assigned to me", to check off a checklist item, leave a note for another agent, create a task, or coordinate work with another agent — anything that reads or writes the sprawl task space.From its SKILL.md
npx -y skills add ultrakorne/sprawl_cli --skill sprawlAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
20.3 KB, ~5.1k tokens by cl100k_base, as published. Nobody here has run it
sprawl
Shared task space for the human owner and their agents. Every agent has its own secret; the server resolves per-agent permissions so you only see and touch what you're allowed to. The CLI is a thin HTTP client — the server is the source of truth for validation and permissions, so trust its error codes.
When to use this skill
- The user refers to tasks, checklists, notes, or the backlog in sprawl.
- The user asks you to coordinate with another agent or leave them context.
- You need durable state that survives beyond this conversation (a todo, a hand-off note, a status update another agent can pick up).
- The user mentions
sprawldirectly, or points at a task id.
Do not use this skill for one-off in-conversation todos — use TaskCreate for those. sprawl is for collaboration across sessions and agents.
Preflight
For reads, skip it. task list / task <id> / checklist / note show
are already filtered server-side to what your key can see, so just run them.
Probing first only burns tokens and a round-trip.
For writes, run sprawl whoami once. Before the first task create,
task update, checklist add, note set, or any other mutation in this
session, check your scope — see Before you write.
A wasted 403 on a write is fine; a wasted chained write is the trap,
because && swallows the error and the follow-up commands run with empty
inputs.
Only diagnose other failures when a real call hits one. Map the failure, then act:
sprawl: command not found— not installed. ReadSETUP.mdin this skill's directory and walk the user through it.SPRAWL_AGENT_SECRET not set(or similar pre-flight error from the CLI) — ask the user to export it in this shell or pass-s <value>per command. If they don't have one, point them atSETUP.md.- HTTP 401 — token bad or missing. Ask the user to re-run
sprawl login(interactive — don't try it yourself). - HTTP 403 — secret is scoped out of this action. Don't retry; tell the user which action you lack permission for. See Permission model.
- Anything ambiguous — then run
sprawl whoami --format=jsonto separate "CLI/network broken" from "auth broken". A 200 also tells you which agent and scope the server thinks you are.
Never write the secret to a file, commit it, echo it back to the user, or
print it in a command you run. If you show a command using -s, redact the
value.
Before you write — check your scope
Run sprawl whoami once at the start of a write session. Reads don't need
this (the server already filters them), but writes need to know your scope
upfront — otherwise you'll learn it the hard way through a 403, and any
chained follow-up commands will run with empty inputs and produce a confusing
partial state.
sprawl whoami
# agent:
# default_permission: write # ← projectless `task create` needs write_create
# ...
# project_permissions[1]{level,name,project_id}:
# write_create,Sprawl,1 # ← projects you can create/edit in
What each scope unlocks: read → list/show only · write → edit existing
tasks/items in scope · write_create → also create new ones.
For a task create:
- Projectless (
sprawl task create --title ...) — needsagent.default_permission = write_create. - Inside a project (
--project-id N) — needs an entry inproject_permissionswithlevel = write_createfor that id.
If neither holds, don't try. Tell the user you lack write_create and
on which project they'd need to grant it. The server will reject the call
anyway; surfacing it from whoami saves the wasted round-trip and the
confusing partial state from chained follow-ups.
For edits (task update, checklist check/uncheck/update, note set),
write is enough on the target's project. You can usually skip the
whoami check for edits if you've already established scope earlier in the
session — but if this is the first write of the session, just check.
Don't chain writes with && to capture the new id. Run
task create on its own, read the id from its output, then add checklist
items. If the create returns 403, an && chain blows past it with an empty
id and the next command silently no-ops on stderr — exactly the failure
mode that surfaces as "(no output)".
# Right — split so each step's outcome is visible:
sprawl task create --title "quick reminders"
# → note the id from the output
sprawl checklist add <id> --title "print something"
sprawl checklist add <id> --title "talk to Antti about AI tools"
# Wrong — masks 403 on create, follow-ups run on empty id:
task_json=$(sprawl task create --title "quick reminders" --format=json) \
&& id=$(printf '%s' "$task_json" | jq -r '.task.id') \
&& sprawl checklist add "$id" --title "..."
Credential model
Two credentials, resolved per request:
- Token — user's device-flow token, managed by
sprawl login. You don't touch this. Lives in~/.config/sprawl/config.toml(mode 0600) orSPRAWL_TOKEN. - Agent secret —
SPRAWL_AGENT_SECRETenv var (preferred) or-s <value>/--agent-secret <value>flag. Never persisted by sprawl. Prefer the env var for long-lived shells; the flag leaks viaps auxeand shell history.
If either is missing the CLI fails before making the HTTP call.
Permission model (how to read errors)
Your agent secret resolves one of four scopes per task / project:
none · read · write · write_create. Resolution order on read/write is
task override → project override → agent_keys.default_permission.
| HTTP | Meaning | What to do |
|---|---|---|
200 | Success | Carry on. |
401 | Token bad / missing | Ask user to re-run sprawl login. |
403 | Your key is scoped out of this action | Don't retry. Tell the user you lack permission and which action. |
404 | Not visible to you, or genuinely gone | Treat as "not available to me". Don't assume it exists and retry. |
422 | Validation (e.g. empty search query) | Fix the input. |
Non-owner agents only see tasks their key resolves at least :read on, so
task list is already filtered. Do not loop retrying on 403 — the
server won't change its mind.
Output formats
--format is a persistent flag: text | json | toon (default toon).
SPRAWL_OUTPUT sets a session default.
Default to omitting --format for your own reads. Toon is 30–60 % fewer
tokens than json and lossless, so when the output is just coming back into
your context for you to eyeball (list, show, checklist, search), let it
default. Passing --format=json to read a task list is pure token waste.
Only override when you have a specific reason:
--format=json— only when you're actually piping tojqor another parser. Not for "I want to read it myself".--format=text— when you're showing the output to the user (tabwriter tables, multi-line detail views).
Errors in json / toon come as a structured envelope:
{"status": "error", "error": "<message>", "http_status": 403}
http_status is omitted for pre-flight errors (e.g. missing secret).
Task shape (house style)
The owner's convention for this task space. Follow it unless the user says otherwise — it's what makes the board readable across agents and sessions.
- Everything is a checklist item. The task is a lightweight container; the actual work is the items underneath it.
- Title: short. Server cap is 30 characters (enforced — longer fails with a 422). Aim well under that: a handful of words, no punctuation filler. If you can't say it in a title, the thing is probably two tasks.
- Skip the description. Default to no
--description. Don't summarise the task there — summarise it in the checklist. - If you must use a description, keep it brief. Server cap is 255 characters (enforced at the DB layer — longer currently surfaces as a 500, not a clean 422).
- Itemize work as checklist items, titles kept short like task titles. One discrete thing per item. If an item reveals subwork, add a new item, don't cram it into the title.
- Long context → item notes. When something needs paragraphs — a
rationale, a block of status, a link dump, a hand-off — attach it as a
note on the relevant checklist item via
sprawl note set. Notes are free-form and unbounded; that's the channel for anything that won't fit in a title.
So the usual create flow is: task create --title "..." (no description),
then one or more checklist add <task_id> --title "...", then
note set <item_id> only on items that need the extra context.
Command reference
All /api/v1/* commands honour --format and the credential model above.
login is interactive and always plain text.
Discovery (reads)
Omit --format — default toon is what you want here (see Output formats).
sprawl task list
sprawl task <id> # show one task (no `show` subcommand)
sprawl task <id> --full # task + its checklist items + notes, one call
sprawl task search "<query>" # case-insensitive substring on title
sprawl checklist <task_id> # list checklist items for a task
sprawl checklist <task_id> --full # items with their notes inline, one call
sprawl note show <item_id> # raw notes blob; empty is valid
sprawl activity # completed tasks + items for today
sprawl activity --days-ago 1 # yesterday
sprawl activity --date 2026-04-29 # specific day
--full is the read-before-work shortcut. When you're about to work a
task, sprawl task <id> --full (or sprawl checklist <task_id> --full) pulls
the items and their notes in one call — prefer it over listing the checklist
and then running note show per item. Reach for plain note show only for a
single item's notes in isolation.
Daily activity: sprawl activity returns the calling agent's completed tasks + completed checklist items for a single day, scoped by the same key cascade as task list. Default is today in the user's timezone. --date (YYYY-MM-DD) and --days-ago (0..365, 0=today) are mutually exclusive — passing both is a local error before any HTTP call. Empty days return an empty result, not an error. Useful for daily standup write-ups, weekly summaries (loop over --days-ago 0..6), and answering "what did I get done yesterday?".
Reading note content into a shell variable or another command — use --format=text, not json + a parser.
The text format on note show emits the notes body verbatim with no envelope, which is exactly what you want when capturing or piping the content. Reaching for --format=json | jq -r '.notes' works but is unnecessary; reaching for --format=json | python3 -c "import json,sys; print(json.load(sys.stdin)['notes'])" is pure overhead — don't do it.
# Right — raw content straight out:
body=$(sprawl note show 203 --format=text)
sprawl note show 203 --format=text | less
sprawl note show 203 --format=text > note.md
# Wrong — toon envelope leaks into the variable ("notes: \"...\""):
body=$(sprawl note show 203)
# Overkill — only justified if you're extracting *other* fields too:
sprawl note show 203 --format=json | jq -r '.notes'
Writes — tasks
Wire body: {"task": {...}}. Accept explicit flags or --from-json <path|->;
explicit flags override fields parsed from JSON. Title max 30 chars,
description max 255 chars — see Task shape
for why you usually skip description entirely.
# Create (projectless — needs default_permission=write_create):
sprawl task create --title "draft spec"
# Create attached to a project (needs write_create at project scope):
sprawl task create --title "wire up CI" --project-id 42
# Create from a JSON template, tweak one field:
echo '{"title":"draft","project_id":42}' \
| sprawl task create --from-json - --title "final"
# Update title (server ignores project_id on update):
sprawl task update 17 --title "renamed"
sprawl task update 17 --description "" # explicit clear (not "flag unset")
# Set / clear due date (separate route — `task update` ignores due_date).
# Only do this when the user asked for it — see Guardrails below.
sprawl task due 17 today # set due date (resolved in user TZ)
sprawl task due 17 yesterday # backdate by one day
sprawl task due 17 week # owner's configured week-end
sprawl task due 17 none # clear due date
sprawl task delete 17 # soft-delete; 404 from server treated as success (idempotent)
task due takes a preset (yesterday|today|week|none) and the server
resolves it against the user's timezone and week_end_day setting. Reads
return the resolved ISO date in due_date — there's no echo of which
preset is currently set, so if you need that, compute it locally by
comparing the date against today / yesterday / the user's week-end.
Writes — checklists
Wire body: {"checklist_item": {...}}. Server assigns position on add.
Permission is checked on the parent task, not per item.
sprawl checklist add <task_id> --title "write migration"
sprawl checklist add <task_id> --title "deploy" --notes "run after backfill"
sprawl checklist check <item_id> # idempotent
sprawl checklist uncheck <item_id> # idempotent
sprawl checklist update <item_id> --title "renamed"
sprawl checklist delete <item_id> # hard-delete; idempotent on 404
Use check / uncheck for completion — update doesn't mutate it. The split
avoids a GET-then-PATCH race when you don't know current state.
Writes — notes (hand-off channel)
Notes are per-checklist-item free-form blobs, addressed separately so list responses stay small. This is the primary place to leave context for another agent or the human.
sprawl note show <item_id> # read
sprawl note set <item_id> "blocked on PR #418"
sprawl note set <item_id> "" # clears notes
cat status.md | sprawl note set <item_id> --stdin
--stdin and the positional arg are mutually exclusive — passing both is a
local error before any HTTP call.
Misc
sprawl version # prints version + baked-in API URL
sprawl whoami # who am I + elevated project permissions (also a liveness probe)
sprawl theme get # read active UI theme
sprawl theme set tokyo-night # owner-only; unknown id → 404
Collaboration patterns
These are the common shapes of work the skill exists for.
1. Pick up assigned work
sprawl task list
# inspect output, pick tasks you can act on
sprawl task <id> --full # the task plus every item and its notes, one call
Filter by what's visible — your key already scopes the list server-side.
Read the notes before you start. Notes are where the previous agent or
the human left hand-off context — skipping them is how you redo work someone
already did or miss a blocker they flagged. sprawl task <id> --full already
includes every item's notes inline, so prefer it when picking up a task; use
sprawl checklist <task_id> --full if you only need the checklist. Fall back
to sprawl note show <item_id> only for a single item's notes in isolation:
sprawl task <id> --full # preferred: task + items + notes together
sprawl checklist <id> --full # just the checklist, notes inline
sprawl note show <item_id> # one item's notes, when that's all you need
A plain sprawl checklist <id> (no --full) still shows a has_notes marker
per item without the bodies — fine for a quick glance, but --full is the
one-call way to actually read them.
When you finish an item, check it off immediately — see §2. Don't wait until the end of the task: other agents and the human are watching the board live, and an unchecked item reads as "still to do".
2. Make progress on a checklist
Mark items as you finish them; don't batch. Other agents and the human see the state live.
sprawl checklist check 203
If an item reveals subwork, add a child item rather than stuffing it into the note:
sprawl checklist add <task_id> --title "backfill legacy rows"
3. Leave context for another agent or the human
Use the item's notes blob. Append by reading first if you need to preserve
prior content (note set is a full replace):
prev=$(sprawl note show 203 --format=text)
printf '%s\n\n---\n\n%s\n' "$prev" "blocked on PR #418" \
| sprawl note set 203 --stdin
Don't sign your edits. No "done by <agent-name>", no "— claude". The
server already records the last actor on each note / checklist item, and
sprawl whoami resolves any agent secret to its identity. Manual signatures
just add noise the human has to skim past.
4. Create a new task on behalf of the user
Only if the user asked, and only if your key resolves write_create for the
target scope (projectless or the specific --project-id). Run
sprawl whoami first if you haven't
this session — that's the cheap way to find out before round-tripping.
If you get a 403 anyway, surface it — don't retry.
Create the task on its own, then add checklist items in separate calls so each step's outcome is visible — see the chaining warning in Before you write.
sprawl task create --title "flaky deploy" --project-id 42
# → note the task id from the output
sprawl checklist add <task_id> --title "repro on staging"
sprawl checklist add <task_id> --title "check #ops logs"
5. Hand off
Finishing your slice and passing to another agent or the human:
checklist checkthe items you finished.note seton the next item with a short status + what you couldn't do and why (permission, missing info, blocker).- Do not
task updatethe title / description just to log status — that rewrites the task. Status belongs in notes or new checklist items.
Guardrails
- Never echo, log, commit, or persist
SPRAWL_AGENT_SECRET. If you must show a command to the user, redact the value. - Never attempt
sprawl login— it's interactive; ask the user instead. - Never retry
403responses. Permission won't flip mid-session. - Don't use
task updateas a status channel. Use notes / checklist items. - Don't delete tasks or checklist items the user didn't ask you to remove.
task deleteis a soft-delete and can only be undone via the LiveView trash bin (no API to restore).checklist deleteis a hard delete and has no undo. When in doubt, leave a note on the item instead. - Don't set due dates the user didn't ask for.
task dueis for when the human explicitly tells you to schedule something (or you're acting out a clearly scheduled instruction — "remind me about this Friday"). Don't infer due dates from urgency cues, don't backfill them on existing tasks, and don't add them when creating a task on the user's behalf unless they specified one. The due date is the owner's planning channel, not an agent housekeeping field — leaving it blank is the correct default. - Don't
--from-jsonwith untrusted input without reading it first — the file / stdin is parsed as the full task/item attrs map. - Empty strings matter:
--description ""andnote set X ""are explicit clears, distinct from "flag unset". Use them deliberately. - Write only what the user asked for. The task space is shared with the human and other agents; spurious tasks or notes are noise for everyone.
What ships with it: 1 file
4.8 KB alongside SKILL.md
- SETUP.md4.8 KB