-
Notifications
You must be signed in to change notification settings - Fork 0
CLI Reference
Complete reference for bin/worklog. For concepts and workflows, start with
the User Guide; for the Claude Code plugin, see the
Plugin Guide.
| Flag | Meaning |
|---|---|
--actor <name> |
Who caused the event (defaults to $USER). Recorded on every event; goes before the subcommand: bin/worklog --actor alice update …
|
--version |
Print the CLI version and exit |
Create a work item. Prints the new item's ULID.
bin/worklog add "Extract auth middleware" --level task --kind feature \
--milestone v0.7.0 --priority P1 --parent 01J8WZZ100 --labels backend,auth| Flag | Values | Default |
|---|---|---|
<title> |
positional, required | — |
--level |
epic story task subtask
|
task |
--kind |
feature bug ops triage
|
omitted — the item folds to triage
|
--milestone <m> |
free string (e.g. v0.7.0) |
none |
--type |
deprecated alias for --level/--kind
|
— |
--priority |
P0 P1 P2 P3
|
P2 |
--parent <ulid> |
parent item (bugs may float free of any epic) | none |
--plan <path> |
plan doc that produced it | none |
--labels a,b |
comma-separated | none |
--unplanned |
flag; requires --discovered-during
|
— |
--discovered-during <ulid> |
what the unplanned work interrupted | — |
Taxonomy rules are checked at write time (see the work taxonomy):
- Omitting
--kindis deliberate: the fold classifies the itemtriage— it never silently becomesfeature. -
--level epic --kind bug(ortriage) fails:worklog: an epic cannot be kind:bug — epics are feature or ops (taxonomy §2.2) -
--level epic --milestone …fails:worklog: milestone lives on leaves; epic milestones are derived (taxonomy §2.5) -
--unplannedwithout--discovered-duringfails:worklog: --unplanned requires --discovered-during (section 5.4) -
--typestill works — it maps to the same (level,kind) pair the fold applies to old events (bug→task/bug, the rest →feature) and prints on stderr:worklog: --type is deprecated; use --level/--kind. See the migration note.
Change status, priority, title, kind, milestone, or labels on an open item.
bin/worklog update 01J8X0M2QQ --status in_progress --kind bug --add-label urgent| Flag | Values |
|---|---|
<item> |
positional ULID, required |
--status |
todo in_progress blocked
|
--priority |
P0–P3
|
--title |
new title |
--kind |
feature bug ops triage
|
--milestone <m> |
free string |
--add-label a,b / --del-label a,b
|
comma-separated |
At least one change flag is required. --kind/--milestone are validated
against the item's current level with the same taxonomy rules (and error
messages) as add — you cannot update an epic to kind:bug or put a
milestone on it.
Close an item as done or cancelled.
bin/worklog close 01J8X0M2QQ --status done --resolution "merged in PR #7"--status is done (default) or cancelled; --resolution is optional
free text. Closing is just an event — nothing moves files at runtime.
Attach an external identity (ticket key, URL) to an item as a link event. Sync calls this for you; it's here for manual wiring.
bin/worklog link 01J8X0M2QQ --system github --key "owner/repo#412" --url <url>--system and --key are required; --url, --rev, --hash optional.
Record a remote-originated change (pull side). The event ID is
deterministic — built from --system/--key/--rev — so identical polls
dedupe across clones. Accepts level, kind, and milestone (plus
status, priority, title, …) in --set FIELD=VALUE. Normally the sync
dispatcher runs this, not you.
bin/worklog ingest 01J8X0M2QQ --system github --key "owner/repo#412" \
--rev 2026-07-18T16:02:11Z --rev-ts-ms 1789142531000 --set status=in_progressRecord a sync conflict on a field (the dispatcher emits these when local
and remote both changed). The fold files it under _conflicts until a
later write clears it. Flags: --field, --local, --remote,
--remote-rev, all required.
Resolve the last open conflict on a field:
bin/worklog resolve 01J8X0M2QQ --field status --take local--take local re-asserts the local value; --take remote accepts the
remote one. Either way it's a normal update event that outsorts the
conflict, so the fold clears it. Open conflicts surface in worklog list
(stderr warning), worklog show, and the status report.
Register a document in the wiki publish set used by the wiki-publish skill.
bin/worklog wiki-add docs/plans/2026-07-18-work-taxonomy.md \
--key work-taxonomy --title "Work taxonomy plan"List open items, sorted by priority. --all includes closed ones.
bin/worklog list --allOutput: short id, priority, status, external key (or -), title. Prints a
warning to stderr if any items carry unresolved sync conflicts.
Print one item's full folded state as JSON. Accepts a unique id prefix.
bin/worklog show 01J8X0M2Print the full folded state of every item (open and closed) as JSON. The read-only building block other tooling (like the plan-next skill) consumes.
bin/worklog foldPromote a classifier suggestion from .work/suggestions.jsonl into exactly
one create event, then mark the suggestion consumed so it is never
re-proposed. The proposed level/kind/milestone are honored as
proposed (including triage) and pass the same taxonomy checks as add.
bin/worklog promote <suggestion-id>See the classifier — the
classifier is propose-only and off by default; promote is the only path
from a suggestion to the event log.
Turn an approved plan into a frozen plan doc plus tracked items: one epic,
one item per - [ ] task under a ## Tasks heading (indented checkboxes
become subtasks; a (P0)–(P3) token sets priority). Writes
docs/plans/<YYYY-MM-DD>-<slug>.md and prints the path and the epic ULID.
bin/worklog plan-capture --slug auth-refactor --title "Auth refactor" --file plan.md| Flag | Meaning |
|---|---|
--slug |
required; kebab-case, becomes the filename |
--title |
required; the epic's title |
--file |
plan markdown (reads stdin if omitted) |
--priority |
epic priority, default P1
|
Refuses to overwrite an existing plan file — plans are never rewritten; pick a new slug to supersede.
Regenerate docs/roadmap.md from the log. Run it after any item change and
commit the roadmap together with the log.
bin/worklog roadmap-renderFreeze the current roadmap as a dated snapshot:
copies docs/roadmap.md to docs/roadmap/<YYYY-MM-DD>_<name>.md.
bin/worklog roadmap-snapshot --name v0.2-roadmapSnapshots are frozen — the command refuses to overwrite an existing snapshot
file. docs/roadmap.md stays the live, regenerated view; snapshots are the
"what did the roadmap say at release time" record.
Run ticket sync through the typed adapter contract. The dispatcher
(bin/sync_dispatch.py) owns every invariant — scope, canonical hash-skip,
create-vs-update, idempotency markers, echo suppression on pull, conflict
detection; the per-system adapter is a dumb translator (see adapter
below). No adapter configured → the run is local-only, which is a mode,
not an error.
bin/worklog sync --dry-run| Flag | Meaning |
|---|---|
--dry-run |
Report what would happen; write nothing |
--keys k1,k2 |
Restrict the run to specific external keys |
--push-only / --pull-only
|
One direction only (mutually exclusive) |
--retry-base-delay <s> |
Base backoff for transient adapter failures |
Every run ends with the drift report — one counts line plus a drift: list
of anything a human should see (conflicts, unsupported fields on the
platform, deferred items, degraded mappings):
sync report: created=1 updated=2 closed=1 skipped=14 pulled=1 conflicts=0 deferred=0
drift:
- fields not synced on github: depends_on
bin/worklog adapter init prints the authoring path for a new adapter:
adapters are adapted from the shipped worked example
(adapters/github/adapter), never written from scratch — read
adapters/README.md, have the model generate one for your
ticketing.system, then validate it. bin/worklog adapter check [path]
validates an adapter against the contract (schema/*.schema.json) in a
throwaway sandbox; nothing activates until adapter check is green. With
no path it checks the adapter for the configured system, falling back to
the shipped fake (the CI test double).
Architecture Decision Records in docs/adr/NNNN-slug.md, schema-validated
front matter (schema/adr.schema.json).
bin/worklog adr new "Green-gates merge policy" --status proposed \
--deciders rick,claude --tags ci,process --supersedes 2
bin/worklog adr list
bin/worklog adr checkadr new <title> picks the next 4-digit number, scaffolds the file
(front matter plus Context / Decision / Consequences sections), registers it
in the wiki-publish ledger (key adr/NNNN-slug, page ADR-NNNN-slug,
republish-on-change), and prints the path. Flags: --status (default
proposed), --deciders a,b, --tags x,y, --supersedes N. adr list
prints an id / status / title table. adr check validates every ADR —
schema, unique ids, filename↔front-matter agreement, consistent
supersedes/superseded_by pairs, required body sections — and exits
nonzero naming each problem; the pre-commit hook runs it whenever
docs/adr/ exists.
Generate a status report from the log.
bin/worklog status --kind weekly --write--kind is daily, weekly, or timecard. By default it prints;
--write saves docs/status/<date>-<kind>.md (frozen once published —
corrections go in the next report), --emit-facts prints the underlying
JSON facts, --since/--until override the window, --dry-run previews,
--force overwrites an unpublished draft.
Compact the event log per spec §7, verifying fold(new) == fold(old)
before writing. Requires --yes. Meant for CI (a nightly job on the main
branch), not day-to-day use — compaction is also what physically migrates
old type events to level/kind.
Installed via git config core.hooksPath hooks (done for you by
/worklog:init). Both hooks run the same checks:
-
hooks/pre-commit— on every commit:- Every
.work/*.jsonlfile ends with a trailing newline (the invariant that keeps union merge safe). - Every log line parses as JSON and carries the required event fields
(
ev,ts,actor,op, anditemexcept oncompactevents). -
docs/roadmap.mdis fresh: the hook regenerates it and diffs — a stale or hand-edited roadmap blocks the commit (Run: worklog roadmap-render). - The fold test suite passes (only in repos that carry
tests/).
- Every
-
hooks/pre-merge-commit— the same script. Git does not runpre-commitfor merge auto-commits, so without this a merge could silently land a stale roadmap or a smuggled corrupt line. If it blocks your merge:bin/worklog roadmap-render && git add -A && git commit --no-edit.
CI runs the same script on every push and PR, so bypassing the local hook
with --no-verify only defers the failure.
-
Merging is gated by
merge-when-green.sh, and auto-merge on green is on by default; teams that want a human on the trigger setfeatures.auto_merge_on_green: falsein.work/config.yml(advisory mode: the script reports green, a human merges). -
Never hand-edit
.work/*.jsonl— no editors, noecho >>. The CLI'sappend()is the only writer; it does a single atomic newline-terminated write and self-heals a missing trailing newline left by a hand edit. -
Never hand-edit
docs/roadmap.md. It's generated; change the work items and re-render. -
Every
.jsonlwrite is newline-terminated. A missing final newline is how two events fuse into one corrupt, unparseable line. -
Item bodies are capped at 2 KB in the log (keeps appends atomic under
PIPE_BUF). Longer prose belongs in the plan doc. -
--typeis deprecated. It maps tolevel/kindand warns on stderr; prefer the new flags. Old events in the log stay valid — the fold normalizes them on load.
- Roadmap
- Design-Doc · Code-Walkthrough
- Plan: Plan-ia-content-model
- Plan: Plan-ticket-sync-and-init-detection
- ADR-0001-event-log-fold-union-merge
- ADR-0002-skill-based-edges-typed-contract
- ADR-0003-green-gates-merge
- Index-Releases
- Latest snapshot: Roadmap-2026-07-29_v0.18.0-release
- Index-Status
- Index-Decisions