task-status-update
Change a task's status in a project's artifacts and, at the end of the turn, publish Full Progress once. Use when work starts, finishes, fails, waits or is blocked on the owner, when a pull request is
SKILL.mdclaude/plugins/artifacts/skills/task-status-update/SKILL.md
GitHubTask — status update
Changes a task's status through the script. Full Progress shows the status. Publish Full Progress once, at the end of the turn, never after each change: claude.ai allows 200 publishes per account per day and every republish counts. Feature artifacts are files in the repository and are never published.
Every activity is a task, the session's own included (contracts, joins, test
runs, releases, cleanup). A task is Running while any work for it runs. It is
Waiting or Needs you when it is blocked on something or someone. Before a
turn ends with work still running in the background, its task is Running.
Built means finished but not released. Live means released. Done is a
retired name that the script stores as Built. Release work that comes later
(join, CI, release) is its own task, Running or To do.
A task set to Running or Built rides a release: pass
--rides <ID or RELEASE-n> in the same call (the command refuses otherwise).
Two cases are exempt:
- The task is a release itself.
- The task ships nothing:
--no-release "REASON", at most 80 characters, never together with--releaseor--rides. Such a task is never Built; when finished, it goes Live.--no-release ""clears it.
Only the script writes the registry. Never edit registry.json or
manifest.json by hand, and never type a status row into an artifact. The
statuses reach the artifact's At a glance block by themselves, so never write
them into a lede. A meta.json lede holds one or two sentences of context the
registry cannot show (an incident, a constraint, a plan).
Every command below is
python "${CLAUDE_PLUGIN_ROOT}/scripts/project_artifacts.py" <command>. Run it
from anywhere inside the project's repository. Exit 0 is success. On any other
exit, read the message, fix the cause and rerun.
Steps
Find the task ID and the new status. The ID is the one in the user's words, in a queued event (
queue list), or at the start of the current branch name (AR5-artifactspecis taskAR5). The status is one of Live, Built, Running, Needs you, Waiting, To do, On hold, Failed, Dropped. A suggested status from a queued event is a suggestion: confirm it matches what happened. A word outside the nine maps to the nearest (MergedisLive, orBuiltwhen the project'smerged_statussays so).Change it:
set-task-status <ID> "<Status>" [--detail "TEXT"] [--expected "DD Mon"] [--item "TEXT"] [--basis "TEXT"] [--history "TEXT"] [--no-release "REASON"] [--started "DD Mon ~HH:MM"|HH:MM] [--into ID|RELEASE-n] [--reason "TEXT"].--detail: plain text, at most 600 characters. Use it when what the row says changed.--expected: a real date fromdatein the project's zone,DD MonorDD Mon ~HH:MM, optionally followed by;and a short note. Nevertoday,soon,tomorrowornextalone. For Live or Built it defaults to the current date; do not pass one.--basis: when you give an Expected time, give its basis too (what it waits on and how long), for example"agent slot ~01:30, ~1.5 h". At most 80 characters;""clears it. Open statuses only: a row that goes Live, Built or Failed drops it.--waits-on owner|work: for a Waiting or On hold task, who it waits on.ownerlists it under Needs you in At a glance.work(the default) lists it under Waiting for other work, with what it waits on (the basis) first.""clears it.--started: when the work began,DD Mon ~HH:MMorHH:MM(today) in the project's zone, before Expected;""clears it. It is where a no-release task's bar starts on the release timeline. Give it for work that began earlier and is now Waiting or Needs you. A task that first moves to Running gets the current time by itself (R5.48).Dropped: closes a task truthfully when its work was folded into another task or is no longer wanted (not Live, not Failed, not On hold). Give--into <task ID or RELEASE-n>(required for a release: the release that took its cargo) and/or--reason "TEXT"(at most 80 characters). The row leaves the open lists and the timeline and showsdropped: folded into RELEASE-nunderLive or built(R5.49). First move any task that rides a dropped release, with--rides.--history: one line for the feature artifact's History table. Use it for a feature task whose change the owner should be able to look up later.
The command does these things:
- renders every artifact that shows the task, and any other page whose look is older than the installed plugin's (R7.5)
- removes the task's queued events
- writes the record to
docs/artifacts/in the working tree
The plugin never commits or pushes the record; the project commits when it chooses.
Do not publish yet. Change as many statuses as the turn needs, each with
set-task-status. They accumulate. Publish at the end of the turn, per "Publishing" below.Clear what is stale. If
queue liststill shows events for tasks that no longer apply, remove them withqueue clear --id <ID>.Report the task, its old and new status, and whether Full Progress was published. If there is no Artifact tool, say what is still unpublished and stop.
Publishing
Publish once, at the end of the turn, never mid-turn. Repeat until pending
exits 0:
- Run
pending --json. It lists Full Progress (the only artifact it lists) and writes the publish copy: the same page with absolutefile:///links to the feature files. The entry carrieskey,title,path(the absolute path of the publish copy) andurl. - Publish with the Artifact tool.
file_pathis the entry'spath, unchanged.urlis the entry'surlwhen it is not empty.- If the publish is refused because the artifact does not exist, list the
owner's artifacts (
action: "list") and match the exacttitle. Publish to that one. Publish a new one (with aniconsuch astracker) only when none matches. - If the publish is refused because the artifact changed elsewhere,
readthe live version once. Copy content-section changes throughexport-content full-progress --to <dir>andedit-content full-progress --from <dir>, then retry once with the newpath. Changes to the generated sections are dropped.
- If the publish is refused because the artifact does not exist, list the
owner's artifacts (
- Run
mark-published full-progress --url <URL>with the URL the publish returned. pendinglists Full Progress only when what the owner sees changed (a task added, or its status, item, Expected or release fields, an open decision, a feature row). A change to a detail, a basis or a content section rides the next publish.- If claude.ai refuses the publish for its daily limit, do not retry. Run
mark-deferred full-progress --until <ISO time of the reset>(for a limit that resets at UTC midnight, the next UTC midnight, for example2026-10-13T00:00:00+00:00). Until thenpendinglists Full Progress asdeferred until HH:MM (<zone>)and exits 0, and the end-of-turn hook does not block; it prints one line. After that timependinglists it again. A latermark-publishedclears the deferral.
Old claude.ai pages
pending also lists retired pages: claude.ai pages of feature artifacts
published before feature artifacts became files. They never block publishing,
and pending's exit code ignores them. Delete one only with the owner's
confirmation: ask the owner, delete each confirmed page with the Artifact tool
(action: "delete"), then run mark-deleted <key> --url <URL> (add --gone
for a page that no longer exists). When the session-start or after-command
context lists retired pages, offer the deletion to the owner at the start.