-
Notifications
You must be signed in to change notification settings - Fork 0
CLI Reference
Current — this is the living version. Historical snapshots are linked from Index-Releases.
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 |
Every command that names an existing item — update, close, link,
reopen, resolve, show — accepts either the full 26-char ULID or any
unambiguous prefix, such as the short id list and show print. The
prefix is resolved to the real item before anything is written: an ambiguous
prefix is refused and the matching ids are named
(worklog: 01KY is ambiguous — matches …), and a prefix that matches nothing
is refused (worklog: no item matching …) with no event appended.
The machine-facing ingest and conflict subcommands still take the full
ULID — the sync dispatcher passes ids it already resolved.
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, body, or labels on an open item.
bin/worklog update 01J8X0M2QQ --status in_progress --kind bug --add-label urgent
bin/worklog update 01J8X0M2QQ --body "What and why a junior dev/PM can read"| Flag | Values |
|---|---|
<item> |
positional ULID or unambiguous prefix, required |
--status |
todo in_progress blocked
|
--priority |
P0–P3
|
--title |
new title |
--kind |
feature bug ops triage
|
--milestone <m> |
free string |
--body |
human-readable description (what/why; no ULIDs — spec §13.4) |
--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. --status on a closed item is refused — it would leave
the stale resolution behind; use reopen. --body is the durable prose
source that ticket-body and ticket-sync push to the remote tracker.
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.
Reopen a closed item: moves it back to todo and drops the stale
resolution in one event. Prints the full ULID. Refuses items that aren't
closed.
bin/worklog reopen 01J8X0M2QQAttach 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.
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 if any docs/plans/*-<slug>.md already exists, for any date — 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.
These implement the IA & content model (plan
docs/plans/2026-07-22-ia-content-model.md, plugin 0.13.0) plus artifact
pages (plan docs/plans/2026-07-24-artifact-pages.md, plugin 0.14.0).
Storage paths stay the same; the commands add a reader plane — stable
wiki_key identity, truth_state, generated Home/Sidebar/indexes, a
generated page per ticket/PR/release, a publish manifest, and a typed-edge
traceability graph. Concepts are covered in
the User Guide.
Print the stable wiki_key for a document path (legacy keys are seeded
from the publish ledger; new docs use the §5.5 derivation rules).
bin/worklog wiki-key docs/plans/2026-07-22-ia-content-model.md-v / --verbose adds derivation detail.
Backfill wiki_key + truth_state: sidecars under docs/.index/ for
frozen docs (never edits the frozen file), in-place frontmatter for
sanctioned-live docs, and self-description on the publish ledger.
Idempotent.
bin/worklog ia-normalize
bin/worklog ia-normalize --check # report pending normalizations onlyGenerate docs/.index/_inventory.json — one metadata record per doc
(wiki_key, doc_type, truth_state, relationships).
bin/worklog ia-inventory
bin/worklog ia-inventory --check # validate + freshness onlyRender the reader plane into docs/.index/rendered/ (Home, Sidebar,
Decisions / Releases / Status / Traceability indexes) plus
publish-manifest.json and aliases.json. Deterministic.
ia-manifest is an alias of ia-render.
bin/worklog ia-render
bin/worklog ia-render --check # report stale files instead of writingThe wiki-publish skill consumes publish-manifest.json: each page has a
source, page_name, and either render: as-is or render: doc+banner
(banner prepended at publish time, never written into frozen sources). For
GitHub Wiki, YAML frontmatter is stripped in the wiki copy so Gollum does
not show the --- block.
Convenience wrapper: ia-normalize → ia-inventory → ia-render. Run
after plan-capture, release, or any doc set change that should refresh
navigation.
bin/worklog ia-indexBuild docs/.index/_graph.json — the typed-edge traceability graph
(plan → item → ticket → PR/commit → release, plus ADR/design edges).
bin/worklog ia-graph
bin/worklog ia-graph --seed # propose decides/implements edges into
# .work/suggestions.jsonl (propose-only)Record a PR or commit code edge on an item as a sidecar overlay (the event log still owns item state). Prefer this over hand-editing richness only on the remote ticket.
bin/worklog link-pr 01J8X0M2QQ --pr 104
bin/worklog link-pr 01J8X0M2QQ --commit abcdef1Print the rich issue body for an item — summary, epic/plan/milestone
context, and traceability — for ticket-sync / the issue-description skill
to push. Enrich the source (update --body, link-pr, relationships)
and let sync carry it out.
bin/worklog ticket-body 01J8X0M2QQPreview the generated ticket page for an item — the same page
ia-render writes to docs/.index/rendered/tickets/<ULID>.md and publishes
as wiki page Ticket-<ULID>: own description/status, upward hierarchy to
the epic, downward children/subtasks with a progress rollup, linked PRs
(PR-<num>), and the linked release (Release-<tag>). Releases and PRs get
matching generated pages (releases/<tag>.md, prs/<num>.md) — there's no
separate preview subcommand for those, only for tickets.
bin/worklog ia-ticket 01J8X0M2QQUnlinked-evidence report: closed items missing plan / ticket / PR links.
Warns by default; --strict exits 1 (use pre-release).
bin/worklog trace-check
bin/worklog trace-check --strictInstalled via git config core.hooksPath hooks (done for you by
/worklog:init). An absolute path to the same directory is equally valid and
is what a git worktree needs — a relative hooks resolves against the
worktree's own root. The session doctor accepts either form.
-
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/). -
Branch guard: rejects a commit authored directly on
main/master— those branches are pull-only, land work via a PR instead. A real reconciliation merge (git merge origin/main) is exempt viaWORKLOG_MERGE_COMMIT, set bypre-merge-commitbefore it exec's intopre-commit(MERGE_HEADisn't on disk yet at that point in git's merge sequence).WORKLOG_SKIP_BRANCH_GUARDcovers the tool's own bare, non-commit invocations (worklog doctor, CI's--no-verifybackstop) that would otherwise false-positive onmain.
- Every
-
hooks/commit-msg— every commit message must reference a worklog item (26-char Crockford ULID) or a ticket (#123); merge commits are exempt (detected viaMERGE_HEAD, reliably present by this point in the sequence). -
hooks/pre-merge-commit— runspre-commit's checks (1–4) withWORKLOG_MERGE_COMMITset. 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 checks — including a PR-scoped step that validates every
commit message in the PR range — on every push and PR, so bypassing a 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