본문으로 건너뛰기
cccskills
무료GitHub에 공개

headway

Read and edit a Headway kanban board from the command line via the `headway` CLI (crates/headway_cli). Use when the user wants to view the board, add/move/edit/archive cards, or shuffle work between columns like Backlog, Todo, In Progress, In Review, and Done — e.g. "move X to done", "show the board", "add a card to todo".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

damus-io/notedeck스타 317(GitHub 317 + cccskills 0)

실행 점수 미검증

설치 방법 보기

포함된 파일(1)

  • SKILL.md36.9 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Headway board CLI

headway is a CLI over a running notedeck's embedded relay. It keeps its own nostrdb cache, reconciles with the relay each run (NIP-77 negentropy, falling back to NIP-01, or fully offline against the cache), folds the board locally, and forwards edits back so the running app sees them. Source: crates/headway_cli.

Running it

Prefer a built binary; fall back to cargo:

# build once, then call the binary directly (fast, no rebuild per command)
cargo build -p headway_cli            # produces target/debug/headway
target/debug/headway <command>

# or, one-off:
cargo run -q -p headway_cli -- <command>

In examples below, headway means whichever form you're using.

headway --help lists the commands grouped by what they act on, plus the flags every run takes, one line each. Each command then has its own page — headway <command> --help (or headway help <command>) — with just that command's flags and examples; headway help options has the every-run flags in full (env fallbacks, defaults) and how <card>/<col> arguments are read.

Logging in

Everything operates on your own board once you're logged in — show to read, the rest to edit. Relay defaults to ws://127.0.0.1:6677 (notedeck's embedded relay); override with --relay <url> or HEADWAY_RELAY. If no relay answers, the CLI works offline against its cache and edits reach the app on the next connected run.

If a command fails because you're not logged in, ask the user to run headway login. Don't handle the key yourself.

Multiple boards

A board is identified by a slug scoped to your key, so one identity can hold several boards (e.g. a personal headway board and a work board).

Always target a non-default board with the per-run --board <id> flag — never the stateful headway board <id> switch. Pass --board <id> on every command in a sequence, so each call is self-contained:

headway --board work show
headway --board work add "Fix the relay reconnect" --col todo -l bug
headway --board work move 1a2b3c4d… --col done

Why avoid the stateful switch: headway board <id> persists the selection to a file (<data-dir>/headway-cli/board) that is shared mutable state. The running notedeck app — or any other headway process — can flip it between your commands, so a show that targeted work can be followed by an edit that silently lands on headway (you'll see a confusing "no card matching" when the card "vanishes"). The --board flag is scoped to one run and can't be changed underneath you, so a multi-step edit always hits the board you meant.

Board selection precedence, highest first: the --board <id> flag (one run only) → the board named by a headway:<board>/<word-id> card ref (see below) → $HEADWAY_BOARD → the board stored by headway board <id> → the default headway. If you're acting on many boards in one session, prefer --board; only fall back to $HEADWAY_BOARD (an env var, also stable for the session) when you truly want every command to default to the same non-default board.

Full card refs self-route. A selector like headway:commerce/purse-metal-toilet already names its board, so headway show headway:commerce/purse-metal-toilet (and move, comment, …) targets commerce automatically — no --board needed. The headway:<board>/<word-id> that show prints is a working address wherever you paste it, which gives you the same self-contained, un-raceable targeting that --board does — prefer either over relying on the stateful switch. The scheme-less shorthand commerce/purse-metal-toilet self-routes too, and hex prefixes resolve against the current board (so they still need --board to reach another one). A bare word-id (purse-metal-toilet, no board segment) does not self-route — it can't pick a board on its own — but it does resolve against the board you've already selected, so headway --board commerce show purse-metal-toilet works without repeating the slug in the id. Like a hex prefix, a bare word-id also matches by unique prefix — headway --board commerce show purse-metal (or even purse) resolves as long as it's unambiguous. Anything that isn't purely hex digits is treated as a word-id, so only an all-0-9a-f selector is a hex prefix. When a guess misses, the error suggests the real cards that share its leading word instead of a bare "no card matching". Two refs naming different boards in one command — or a ref that disagrees with an explicit --board — are an error, not a silent resolution on the wrong board.

headway board with no argument is a harmless read — it lists the boards in the cache and marks the current one with *; use it to discover slugs. Just don't rely on its persisted * selection for edits. To create a board that doesn't exist yet, headway --board work seed, or headway seed -t "Tune Assistant" to derive the slug (tune-assistant) from the title. seed never falls back to the persisted current board or $HEADWAY_BOARD: with neither --board nor --title it refuses, like next and migrate.

The golden rule: show before you edit

Cards are addressed by their event id, and columns by id or case-insensitive name. When scripting the CLI, pass a hex id from show --json. Any unique prefix resolves, so the full 64-char id is overkill — a 16-char (8-byte) prefix is plenty for a board with a handful of cards, and even an 8-char prefix is usually unambiguous. Use a short prefix for automated edits; just lengthen it (or fall back to the full id) if you ever hit an "ambiguous card prefix" error. The human-readable show instead displays a muted reference like headway:headway/maple-river-canyon (a friendly rendering of that same event id, for quoting in commits/chat); it also resolves as a <card> argument, but prefer the hex id for automated edits. Always run show first to read the current ids and column names, then act on what you actually see — never assume an id or that a card is where you expect.

headway show            # human-readable: columns, titles, labels, word-ids
headway show --archived # also list archived cards in full (default: count only)
headway show --all      # every board in the cache, each printed in full and led
                        # by its slug (with --json, a JSON array of boards)
headway show --json     # machine-readable, for parsing (always includes archived)
headway show <card>...  # print the given cards (word-id or hex) in full
                        # `git show`-style detail, not the whole board; with
                        # --json each card gains a `column` field for the column
                        # it sits in

By default show collapses archived cards to a one-line count to keep the board readable; pass --archived to list them (e.g. to find an id for restore).

show prints each card as <title> [labels] headway:<board>/<word-id>, with the reference muted at the end of the line.

Which form to use — MANDATORY when talking to a human (chat, a commit message, a PR, a board comment): refer to every card by its full scheme reference, headway:<board>/<word-id> — the exact string show prints, scheme and board included (headway:dave/maple-river-canyon; a notebook node is notebook:mango-sibling-false). This is the only form the user's client parses into a live link/chip. Any other form renders as dead text, so it is never acceptable in human-facing prose.

Do not use, ever, when addressing a human:

  • headway#maple-river-canyon or dave#maple-river-canyon — the #/hash form does not linkify. This is the most common mistake; there is no # in a Headway reference.
  • a bare maple-river-canyon (no scheme, no board) — doesn't resolve at all.
  • the scheme-less dave/maple-river-canyon — fine as a CLI argument, but it does not linkify in prose; always add the headway:/notebook: scheme when writing for a human.

The full headway:<board>/<word-id> is also self-routing and unambiguous no matter which board is current when it's read. Apply this to every ref in a message, not just the first — a comment that names five cards writes all five as full scheme references. When you edit the board (move, label, archive, …), pass the canonical hex id from show --json instead, so an automated edit can never hit the wrong card.

All of these resolve as a <card> argument, to the same card every time:

  • a hex event id, full or any unique prefix (a 16-char prefix is plenty) — preferred for editing
  • headway:dave/maple-river-canyon — the full reference; it names its board, so it self-routes there without --board (see Multiple boards)
  • dave/maple-river-canyon — the scheme-less shorthand; self-routes too. A bare maple-river-canyon with no board segment is not a card ref and won't resolve.

Default board columns: Backlog, Todo, In Progress (in-progress), In Review (in-review), Done (done). A column argument matches an id or a name case-insensitively, so --col "in progress", --col in-progress, and --col "In Progress" are equivalent.

Commands

CommandWhat it does
show [cards...] [--archived] [--all] [--json]Print the board, or only the given cards (--archived lists archived cards; --all prints every board)
seed [--board <slug>] [-t|--title <t>]Create a board (born sealed): the --board slug, else one derived from --title; refuses with neither
add <title...> [--col <c>] [-l <labels>] [--parent <card>] [--desc <text>|--desc-file <path>]Add a card (defaults to the first column; -l/--label tags it; --parent creates it as a subissue; --desc/--desc-file sets its description at creation)
move <card> --col <c> [--row <n>]Move a card to a column (optional position)
title <card> <title...>Edit a card's title
desc <card> <text...>Edit a card's description
label <card> [labels...]Set labels — positional, comma-separated, or -l (no labels clears them)
priority <card> <level>Set priority: none/low/medium/high/urgent (none clears it)
parent <card> [parent]Make a card a subissue of [parent]; omit the parent to detach
block <card> --on <other>Mark <card> as blocked by <other> (see Dependencies)
unblock <card> --on <other>Remove the <card>-blocked-by-<other> edge
relate <card> --to <other>Relate two cards (an undirected "see also"; see Dependencies)
unrelate <card> --to <other>Remove the relation (from either endpoint)
due <card> <date>Set a due date (YYYY-MM-DD, or none to clear)
estimate <card> <n>Set an estimate — a number (or none to clear)
seq <card> [--in <c>] [--json]Print where a card sits in a container's work-order: its place, neighbours, and how many ready cards are ahead (see Work order)
seq <card> <pos> [--in <c>]Position a card in a container's work-order (see Work order)
next [--in <c>] [--ready] [-n <k>]Print the ready frontier — what to work on next (see Work order)
grep <pattern> [--board <b>] [--in <c>] [-i|-s] [--color <when>] [--[no-]pager] [--json]Search card text (title, description, comments, review comments) and print each matching line under its card's ref (see Searching cards)
comment <card> <text...> [--reply-to <c>]Comment on a card (NIP-22); --reply-to threads under another comment or a review comment
comment <card> --path <f> --line <a[-b]> [--old] [--record <sha>] <text...>Inline review comment on a review record's commit (newest record by default); --record alone comments on the whole commit
review <card> [--explainer <url>] [--explainer-source <f>] [--code-source <f>] [--deploy <url>] [--commit <rev>]Record a commit for review on the card: sha, title, branch, host, repo path and agentium: ref, read from git in --repo-dir (default cwd) and $AGENTIUM_SESSION; --deploy is the URL where this commit's build is live; the source flags store the explainer's Markdown and its code walk on the record (repeatable, text, 32 KiB a file)
diff <card> [--record <sha>] [--note explain|code]Print the commit the card's newest review record names (git show-style), fetching it from the recording host if this one lacks it; falls back to the card's Headway: trailer. --note prints the commit's explain git note instead
delete <card>Remove a card (reversible tombstone)
archive <card>Archive a card off the board
restore <card>Restore an archived card
link <card> --to <board>Also place the card on another board (it stays on this one)
move-board <card> --to <board>Move the card off this board onto another
board [id]Switch the current board to id, or (no arg) list boards and mark the current one
rename <title...>Rename the current board's display title (slug unchanged)
share <npub|hex> --board <id>Make someone a member of a sealed board you own (see Sharing a board)
terminal <col> [on|off]Mark a column as a "done" column, or clear it with off (see Terminal columns)
login <nsec>Store a signing key so later runs just work
logoutForget the stored signing key

add accepts -l/--label to tag the new card in one step. The flag is repeatable and each value may be comma-separated, so -l a,b --label c and -l a -l b -l c are equivalent:

headway add "Fix the relay reconnect" --col todo -l bug,p1

label <card> takes the same spellings — separate positionals, one comma-separated positional, or the -l/--label flag — so these all set the same two labels. Note it replaces the card's set rather than adding to it, and label <card> with no labels at all is what clears:

headway label 1a2b3c4d… bug p1
headway label 1a2b3c4d… bug,p1
headway label 1a2b3c4d… -l bug,p1
headway label 1a2b3c4d…              # clears

add can also set the new card's description at creation, saving a follow-up headway desc <card> … (and the need to learn the new card's id first). --desc <text> takes the description inline; --desc-file <path> reads it from a file, or from stdin when <path> is -, so a long multi-line markdown description can heredoc in with no shell-escaping. The two are mutually exclusive and trailing whitespace is trimmed (so a heredoc's closing newline doesn't ride along). Both compose with --col/-l/--parent:

headway add "Rework the sync engine" --col todo --desc "Backfill stalls past the maxSyncEvents cap."
headway add "Migration plan" --col todo --desc-file - <<'EOF'
## Migration plan

1. Fork the session loop
2. Retire the per-app poller
EOF

Every new card says where it came from. When a Dave agentic session creates a card, the description starts with a backlink to that session, so whoever reads the card later can open the transcript that produced it instead of hunting for it:

headway add "Cap the media cache" --col todo --desc-file - <<EOF
Created from $AGENTIUM_SESSION while profiling image loads.

Eviction never runs past 2 GB …
EOF

$AGENTIUM_SESSION is your own agentium:<word-id> (see the agentium skill for the fallback when it's unset). This applies to every add — follow-ups, subissues from an epic breakdown, cards filed in passing — and only at creation; later edits to the description keep the line rather than re-adding it. Outside a session, name the card or conversation it came from instead (e.g. Split out of headway:dave/maple-river-canyon).

Other flags: --board <id> (target another board for one run; see Multiple boards), --db <path> (cache dir), --author <pk> (read someone else's board), -h/--help; headway help options has them in full. --on <card> names the blocker for block/unblock; --to is the target board for link/move-board and the partner card for relate/unrelate; --in <c> is the container for seq/next. headway <command> --help lists a command's own flags without the rest.

When a card's work is committed, record it with headway review <card> from the checkout (plus --explainer <url> when there is one, and --deploy <url> when the commit's build was deployed somewhere it can be opened and tried) before the done comment. The record is the machine-readable twin of that comment: headway reads it to show the commit's diff, and the app's review pane links the explainer and the deployed build beside it. When the explainer was written as explain Markdown, pass its source too: --explainer-source ~/explainers/<word-id>/rec/<word-id>.md (the explain inline output) and, for a change with a code walk, --code-source ~/explainers/<word-id>/<word-id>.code.md. Give the paths in full: they are read from the current directory, the checkout, and one that won't read refuses the whole record. Each is stored on the record under its file name, sealed with the board like any card content, and show --json returns it in the review's sources, which is where explain book builds the card's chapter from. The visual-explainer skill says how to write both. show <card> lists a card's records under review, and headway diff <card> prints the commit itself: it looks in the recorded checkout, then any checkout of the same repo (matched by root commit), then a bare cache under the headway-cli data dir, and fetches over ssh from the recording host when none has it — never prompting, never creating refs in your checkout. explain also writes the commit's git notes (refs/notes/explain for the page, refs/notes/explain-code for the walk); headway diff <card> --note explain|code prints one, read from the same place as the commit. Colleagues without headway read them with git log --notes=explain --notes=explain-code after fetching refs/notes/explain*.

Inline review comments left on a commit (in the app's review pane, or by comment --path) print under their record in show <card>, threaded, each with its word-id and path:line (path:old a-b for deleted lines). Answer one with headway comment <card> --reply-to <word-id> <text>: the reply goes on the same record under the same lines, not into the card's comment thread. It is signed by the comment key like any comment (see below).

When the app sends review comments or an X send-back into your session, the message ends with this same hint. Answer each comment where it was left, so the reviewer sees the answer beside it, rather than only in your transcript:

headway show headway:headway/some-card     # each review comment prints with its word-id
headway comment headway:headway/some-card --reply-to ball-double-claw "done in abc1234"
headway comment headway:headway/some-card --path src/lib.rs --line 40-44 "kept the clone: X needs it"

When commenting a finished card's commit hash, a Dave agentic session should also quote its own agentium: session ref (from $AGENTIUM_SESSION) beside the hash — see AGENTS.md "When done with the work" and the agentium skill.

Subissues

A card can be a subissue of one parent card (GitHub sub-issue semantics: one parent per child, any number of children per parent). Use this instead of the old hand-maintained epic pattern — an epic label plus a word-id checklist in the description — whenever work breaks down into trackable pieces: the rollup is derived from the board, so it can never go stale.

headway add "wire up the parser" --col todo --parent <epic>  # create as a subissue
headway parent <card> <epic>    # make an existing card a subissue (or re-parent)
headway parent <card>           # omit the parent to detach

Progress is derived, not stored: a child counts as done when it sits in a terminal column of its board (see "Terminal columns" below — In Review and Done on the default board), or is archived. There is no checkbox to tick — moving the child card is the progress update.

How it renders:

  • The board listing (show) marks parent cards with a dim n/m rollup.

  • Card detail (show <epic>) gains a subissue of line on children and a derived checklist on parents:

    subissues (2/4 done)
        [x] route media loads through imgproxy   headway:headway/mushroom-include-wolf
        [ ] cap media cache size with eviction   headway:headway/extend-decrease-visit
    
  • show --json gains parent (hex), parent_ref (a full headway:<board>/<word-id>), and subissues per card.

Notes: re-parenting that would create a cycle is refused; children may live on a different board than the parent; nesting works (a child can itself be a parent) but each rollup counts direct children only.

Work order: what to do next (next and seq)

Beyond columns and subissues a board carries a work-order — a deliberate sequence over cards that answers "what should I pick up next?". Two commands read and write it:

  • headway next prints the ready frontier: the cards workable right now, in work-order. next alone prints just the first (the single best next thing); next --ready prints the whole frontier; next -n <k> caps it at k. More than one card can be ready at once — that's the parallel-dispatch signal (independent cards you could hand to different workers at the same time).
  • headway seq <card>, with no position flag, prints where the card sits in that order and writes nothing: its place in the whole walk (31 of 40), the cards just before and after it, whether it has a rank of its own or is placed by creation time, how many ready cards next would hand out ahead of it, and why it isn't ready itself if it isn't (done, In Progress, blocked by a card, or has open subissues). The two counts differ on purpose: the place counts every card, "ready ahead" only the frontier. A card the container's walk never reaches is an error. --json gives {ref, container, index, of, sequenced, before, after, ready_ahead, ready, not_ready_why}. Use it rather than next --ready | grep -n, which drops blocked and In Progress cards.
  • headway seq <card> <pos> positions a card in a container's work-order, which is how you curate the order next reads. <pos> is --first, --last, --after <card>, or --before <card>.

--in <c> names the container whose order you mean: a card ref targets that card's subissues, a board slug targets the board root (its top-level cards); omitted, it's the board root. next refuses to guess the board — pass --board <id> or an --in <headway:board/word-id> ref (never the persisted current board).

headway --board dave next               # the single best next card
headway --board dave next --ready       # the whole ready frontier, in order
headway --board dave next -n 3          # the top 3
headway seq <card>                      # where <card> sits in the board-root order
headway seq <epic-child> --in <epic>    # where it sits within its epic
headway seq <card> --first --in dave    # make <card> the first board-root task
headway seq <epic-child> --after <sib> --in <epic>   # order within an epic

What "ready" means. A card is ready when it is not done (not sitting in a terminal column — see "Terminal columns" below), not In Progress (someone already has it), not blocked (no block edge pointing at an unfinished card — see Dependencies), and not a parent with unfinished subissues (an epic's real work is its children, which are in the frontier themselves, so the epic card isn't dispatchable). On the default board both In Review and Done are terminal, so a card in review reads as done and next will not resurface it — matching an integration-test-at-the-end flow where review-stage work no longer blocks its dependents.

Ordering, and the priority caveat. Within a container, members run in seq-order where a seq has been set, else creation order — the board root included. The walk is depth-first: each card is followed by its own subissues before the next card. next does not sort by the priority field — priority is a human-facing label, not an input to the frontier. So a board where nobody has run seq has no real work-order: next --ready is just the board in default order, and you should judge the biggest win yourself rather than trust the first line. Curate with seq to make next meaningful.

Searching cards (grep)

headway grep <pattern> finds the cards that say something, without a show --json + show <card> loop: it searches every card's title, description, comment thread and inline review comments in one run and prints each matching line under the card's full headway:<board>/<word-id> ref and title, with the field it came from and how long ago it was written (2h ago). Cards are listed most recent first, by their newest matching line, across every board searched. A comment is dated by itself; a title or description by the edit that last set it. Labels and review records' commit subjects are not searched. It's a read command — it never signs.

  • <pattern> is a regex, smart-case by default: an all-lowercase pattern matches any case, one with an uppercase letter matches exactly. -i forces case-insensitive, -s case-sensitive. Quote a pattern with spaces — grep takes exactly one.
  • Scope: every board you can read by default, your own and the ones shared with you — the current board doesn't narrow it. --board <b> searches just that board. --in <card> searches only that card and everything under it (the card itself is included, unlike next --in), on the board its ref names; --in <board-slug> is the whole current board.
  • Archived cards are always searched; their column shows as archived. (--all and --archived are still accepted and change nothing.)
  • On a terminal the matches are colored and paged, like git grep and agentium grep: the pager is $HEADWAY_PAGER, else $PAGER, else less -R. Piped, output is plain and unpaged. --no-pager / --pager force paging off or on; --color auto|always|never overrides coloring (--color always keeps the highlight when piping into your own less -R). Agents reading the output should pass --no-pager or --json, though a pipe already turns both off.
  • --json is an array with one object per matching card — ref, id, board, title, column (archived for an archived card) and matches ([{field, text, created_at}], field one of title/desc/comment/review, created_at unix seconds), in the same most-recent-first order. "No matches" is [] (plain output says no matches); either way it exits 0.
headway grep 'relay reconnect' --board notedeck
headway grep -i nostrdb                           # every board you can read
headway grep sealed --in headway:notedeck/saddle-because-liquid   # one epic
headway --json grep 'Changelog' | jq -r '.[].ref'

Terminal columns: what counts as "done"

Doneness — a card clearing its dependents, dropping out of the next frontier, and rendering as done (strikethrough, n/m rollups) — is decided by which terminal columns a board marks. A card in any terminal column is done.

  • On the default board, both In Review and Done are terminal. So a card in review already counts as done: it stops blocking its dependents and next won't resurface it. This suits an integration-test-at-the-end flow.
  • A board that marks no terminal column falls back to treating its last column as terminal — the original behaviour, so older boards are unchanged.
  • Mark or clear the flag with headway terminal <col> [on|off], which republishes the board definition. Boards seeded before this feature carry no marks (last-column fallback) until you opt a column in — e.g. headway --board work terminal in-review on.

show --json reports each column's terminal flag. Terminal is about doneness only; it doesn't merge or reorder columns — In Review and Done stay distinct lanes you move cards through.

Dependencies: block / unblock (and relate)

A card can be blocked by any number of other cards — a directed dependency edge saying "don't start this until that is finished". It is a separate axis from parent/subissue: a card can be both a subissue and blocked, and an edge may point at a card on another board.

headway block <card> --on <blocker>      # <card> is blocked by <blocker>
headway block <card> <blocker>           # same — the blocker may be a 2nd positional
headway unblock <card> --on <blocker>    # drop the edge

Unlike parent (one parent, re-parenting replaces it), blockers accumulate: each block adds to the card's set, and unblock removes one edge.

An edge edit that changes nothing says so, and never as a resolution failure — so don't retry with a longer id. Re-adding an edge that's already there (block, relate) or dropping one that isn't (unblock, unrelate) is idempotent success: exit 0 with ok (0 events) — <card> is already blocked on <blocker> (--json adds a "noop" field). A block or parent that would close a cycle is a real error, and names what it refused:

error: refused: blocking <card> on <blocker> would create a dependency cycle (…)

error: action produced no events (unknown card or column?) remains only for edits the reducer genuinely couldn't resolve.

A blocker is cleared the same way a subissue is done — when it sits in a terminal column of its board (In Review or Done on the default board; see "Terminal columns" below), or is archived. There's nothing to tick: moving the blocker is the unblock.

How it renders:

  • The board listing (show) prefixes a blocked card with a dim ⊘ glyph. A card whose blockers are all cleared loses the glyph, so ⊘ always means "held back right now".

  • Card detail (show <card>) gains blocked by / blocks sections — the forward edges and the reverse ones (cards this one is holding up) — with x marking a cleared blocker so open ones stand out:

    blocked by (2)
        [x] land the negentropy reconcile   headway:headway/mushroom-include-wolf
        [ ] cap media cache size            headway:headway/extend-decrease-visit
    
  • show --json gains blocked (bool — any unfinished blocker), plus blocked_by and blocks arrays of {id, ref, title, done}.

  • next and next --ready skip a card with an unfinished blocker — this is the main reason to record dependencies, since it keeps the frontier to work that's actually startable (see Work order).

relate <card> --to <other> is the third edge kind: an undirected "see also" between two cards. It's symmetric (both ends list each other, and unrelate works from either), may cross boards, and is purely informational — it carries no ordering and never affects is_blocked, the ready frontier, or any rollup. Card detail shows it as a related section and show --json as a related array.

Cross-board cards: link and move-board

Board membership is placement-driven: the same card — one issue with all its overlays (title, description, labels, comments, parent/subissues) — can sit on several boards at once. Two commands manage this:

headway --board work link 1a2b3c4d… --to personal        # now on both boards
headway --board work move-board 1a2b3c4d… --to personal  # re-homed: off work, on personal
  • link adds a placement on the target board and keeps every placement the card already has. Edits made anywhere show everywhere — it's the same card, not a copy. Re-linking an already-linked card is harmless (it just re-ranks).
  • move-board is link + remove from the source board: the card keeps its id, word-id, and all overlays, and now lives only on the target (plus any other boards it was already linked to).
  • On the target, the card lands in the column whose id matches its current column (e.g. a card in in-review stays in in-review), falling back to the target's first column when no such column exists there.
  • The card is resolved on the source board, so combine --board <source> with --to <target>. The target board must already exist — seed it first with headway --board <target> seed if it doesn't.

Sharing a board

A sealed board can be shared with another nostr identity, who then reads and edits it from their own CLI or app:

# owner: gift-wrap the board's channel key to the member (kind-1082 in a 1059)
headway --board ios-port share npub1…
# member: read and edit the owner's board — its slug is enough
headway --board ios-port show
headway --board ios-port add "From a member" --col todo
  • Owner-only. A member's share is refused; so is sharing to yourself.
  • Sealed boards only. A plaintext board has no channel to hand out — headway migrate --board <id> it first (never on a real board casually).
  • --board is required, never the persisted current board: a share can't be revoked, so the board must be named on purpose.
  • Needs a reachable relay. A key-share is sent once and never re-sent by a later run, so an offline share is refused rather than silently lost.
  • Not idempotent on the wire (a fresh throwaway wrap key each run), but a repeat share is harmless: the member's roster dedups it.
  • The member's edits fold on the owner's side attributed to the member's pubkey.

Working on a board someone shared with you

  • headway board lists it under a "shared with me" heading, after your own boards, with its owner (short npub) and card count. show --all includes it too (JSON boards carry an owner hex).
  • The slug resolves the owner. With no --author, a --board <slug> or a headway:<slug>/<word-id> card ref that isn't one of your boards folds the one board shared with you under that slug — so a card ref pasted from the owner works as-is.
  • Your own board wins. If you have a board with that slug in your cache, it is used instead; --author <owner> reaches the shared one.
  • Same slug from two owners is an error that lists both owners in full; pick one with --author <npub|hex>. An explicit --author always wins.
  • seed and migrate never resolve to someone else's board: they only act on boards you own.

Commenting as an agent (a separate comment key)

An agent that runs headway as its user can sign its comments with its own key, so they show as the agent's rather than the user's. Everything else (reads, adds, moves) stays the user's:

HEADWAY_COMMENT_NSEC_FILE=~/.local/share/jex0/nsec \
  headway comment headway:headway/some-card "…"
# or inline: HEADWAY_COMMENT_NSEC=<nsec|hex>, or per run: --comment-nsec <nsec|hex>

Precedence is --comment-nsec > $HEADWAY_COMMENT_NSEC > $HEADWAY_COMMENT_NSEC_FILE. The file holds the key as nsec or hex (a trailing newline is fine); if it can't be read the command fails rather than quietly signing as the user. Dave sessions usually have HEADWAY_COMMENT_NSEC_FILE already set through session_env in dave_settings.json, so a plain headway comment signs as the agent.

The comment is sealed into the board's channel with the user's access, so the comment key needs no membership and holds no board key. It only works on sealed boards: a plaintext board shows just its owner's own events, so the CLI refuses rather than publish a comment nobody would see.

Typical workflow

Move a card from In Progress to Done:

headway show --json                  # match the title, grab its hex `id`
headway move 1a2b3c4d… --col done    # move by hex id (a column may match by name)
headway show                         # verify it landed in Done

To address a card by title, read show --json and match the title to its hex id, then pass that id. Resolution errors are explicit: an ambiguous hex prefix says "ambiguous card prefix", an unknown reference "no card matching", and a bad column lists the valid column names — re-read show and retry with a corrected argument.

Notes

  • Edits print ok (N events); offline edits append — offline, not forwarded to the app, meaning they're cached but haven't reached the running notedeck yet.
  • seed errors if a board already exists; that's expected — just show instead.
  • A board seeded on one machine reaches the account's other machines through the running notedecks' private relay. Its key-share travels twice, as a gift-wrap and as a PNS note, because a private relay may serve gift-wraps only to an authenticated reader. If a board is missing on one machine, run any headway command on the machine that has it (each cache sends its boards' PNS key-shares once), give the notedecks a moment to sync, and list again there.
  • The cache lives at <data-dir>/headway-cli unless --db overrides it. The CLI and the running app converge through the relay, so either side's edits show up on the other after a reconcile.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

agentium

무료

Query and control Dave agentic sessions from the command line via the `agentium` CLI (crates/agentium_cli), and find your OWN session's agentium: reference. Use when an agent running inside a Dave session needs its own ref (e.g. for a headway done-comment), to list sibling sessions, or to pull another session's detail or full conversation transcript — e.g. "what's my agentium ref", "list the running agent sessions", "show sessions in this cwd", "read session X's transcript".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

damus-io/notedeck3172026년 10월 19일 업데이트

cashflow

무료

Categorize jb55's personal finance ledger from the command line via the `cashflow` CLI (crates/cashflow_cli) — burn down the uncategorized ("unknown") transactions with rules, overrides, splits and transfer links, previewing every write first. Use when asked to categorize transactions, clear the triage queue, add or fix a categorization rule, link transfers between own accounts, or review what an agent session categorized — e.g. "categorize my amex rows", "burn down the unknowns", "why is this charge in expenses:unknown", "undo what that session did".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

damus-io/notedeck3172026년 10월 19일 업데이트

Fast-forward master and every git worktree branch up to a target ref (default github/master), skipping any worktree with unmerged commits. Use when the user wants to sync/update their worktree branches to latest master — e.g. "/ff-worktrees", "ff all worktrees to github/master", "fast-forward the worktrees".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

damus-io/notedeck3172026년 10월 19일 업데이트

handoff

무료

Hand off to a fresh Dave session — ask the user what to work on next, spawn a new session in the current worktree, and send it the task as its first message. Use when the user wants to delegate the next unit of work to a brand-new agentic session rather than continue in this one — e.g. "/handoff", "hand this off", "spawn a session to do X next", "start a fresh session on the next task". `/handoff autowork <task>` also branches the new session off the `autowork` branch and has it land its commit there.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

damus-io/notedeck3172026년 10월 19일 업데이트

nd

무료

Drive the running notedeck from the command line via the `nd` CLI (crates/nd_cli) — list its tools and call any of them over its local socket, or spawn a Dave session, e.g. open a headway card or agentium session in the window, open the review queue, or read board data. Use when the user wants to open something in notedeck from a shell, script the app, or see which tools the running notedeck offers — e.g. "open this card in notedeck", "what tools does notedeck have", "call open".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

damus-io/notedeck3172026년 10월 19일 업데이트

notebook

무료

Read and edit a notebook canvas from the command line via the `notebook` CLI (crates/notebook_cli). Use when the user wants to view the canvas, add/move/edit/recolor/delete nodes, connect or disconnect edges, restack, seed, or rename the canvas — e.g. "show the notebook", "add a node", "move that node", "connect these two nodes".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

damus-io/notedeck3172026년 10월 19일 업데이트

damus-io의 스킬 모두 보기

이 스킬의 문제 신고