chore(release): prepare v0.18.0 - version bump, and the entry point --focus was missing

release-plugin.mjs does not bump these; it REFUSES to release until they
already match the target (release-plugin.mjs:64). The bump belongs in this
repo, not in the catalog session, so the catalog step is now unblocked:
plugin.json, package.json, README badge and all three SKILL.md frontmatters
move to 0.18.0 together, and CHANGELOG's [Unreleased] becomes [0.18.0].

More important than the numbers: --focus was reachable by nobody. The board
SKILL.md is the operator's only entry point and it documented only --plan, so
"fokusdag pa X" would have routed to an unfocused plan on a released 0.18.0.
The skill now passes the user's phrasing through VERBATIM - resolving prose to
a slug in the skill would put a guess in front of a deterministic lookup, and
fokus= already reports what the phrase resolved to. It also relays the three
disclosure lines rather than trimming them as noise, since this is the one
rendering that hides repos.

check-versions: 0 ERROR, 1 WARN (catalog ref lags plugin.json - the documented
transient state before the ref bump).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186vKCzuUEN5WcJB82kddzF
This commit is contained in:
Kjell Tore Guttormsen 2026-08-02 20:15:52 +02:00
commit ecbb34ae48
7 changed files with 45 additions and 10 deletions

View file

@ -8,7 +8,7 @@
*AI-generated: all code produced by Claude Code through dialog-driven development.*
![Version](https://img.shields.io/badge/version-0.17.0-blue)
![Version](https://img.shields.io/badge/version-0.18.0-blue)
![Platform](https://img.shields.io/badge/platform-Claude_Code_Plugin-purple)
![Hooks](https://img.shields.io/badge/hooks-1-green)
![Skills](https://img.shields.io/badge/skills-3-orange)
@ -94,7 +94,7 @@ Scoring is judgement and belongs to the skill; turning scores into a row is a lo
coord-done.sh <filename>... | --all # archive without replying
coord-count.sh [--exclude <mailbox>] # per mailbox: pending + replies owed, delivering nothing
coord-sweep.sh [--write] [--days <n>] [--log <path>] # close aged notices machine-wide (dry-run by default)
board.sh [--roots <dir>[,<dir>...]] [--brief|--plan] # cross-repo attention board (read-only)
board.sh [--roots <dir>[,<dir>...]] [--brief|--plan] [--focus "<prose>"] # cross-repo attention board (read-only)
brief-nightly.sh # render the briefing to a file, atomically
route.sh --path <v> --verification <v> --reversibility <v> \
--scope <v> --rationale "<why>" # model + effort for the next session
@ -109,6 +109,8 @@ It makes **zero model calls**, which is the point rather than a detail. Under su
**`board.sh --plan` renders the day plan**, a *third* rendering of that same scan and the only one that takes a position: which repos to open a tab for today, in what order, and the command to start each. The order is the position, and there is no cutoff — nothing is hidden, and four deterministic rules decide it. Repos owing mail come first, most-owed first, *whatever their status*: excluding `blocked` or `done` is a statement about a repo's own next step, which by definition cannot be moved, while owing an answer is a different axis and answering is often what unblocks it. Then live work (`in-progress`), then `planned`, then last and labelled, the repos with no board line at all — the table already prints a note about those, so a plan that dropped them silently would repeat exactly that defect. Still zero model calls, still read-only, and still cross-checked against `coord-count.sh`.
**`--focus "<prose>"` narrows that plan to one subject, and reports what it held back.** It is the only cutoff this format has, which is why the report is a condition of the feature rather than a refinement of it: `--plan` documents that it hides nothing and labels what it cannot rank, so a silent filter would break a property already written down. The same run prints the subjects the prose resolved to, how many blocks were removed, how many `STATE.md` were searched, and — named, not counted — the repos that *mention* a resolved subject without declaring a marker line. That last class is enumerated because it is where the misses live: a repo can be a heavy participant and never have written a marker, and no string measurement finds it until the held-back population is listed. Each surviving block carries the declaration it survived on. Prose matching nothing prints the *full* plan and says so, since the phrase arrives verbatim from a person and a typo must not empty the day. The subject vocabulary is read from the scanned `STATE.md` themselves, so the "reads `STATE.md` and no other file" invariant is untouched.
It prints `key=value` blocks rather than prose because it has **two consumers**: the operator pasting a command, and a separate repo driving a terminal from it. Prose would make the rendered format an API that no test here could hold stable for a consumer living in another repo. Each block carries `dir=` as an absolute path — a new terminal pane inherits its anchor's working directory, so a plan that omitted it would look right and point at the wrong repo. A repo whose route line is missing or unparseable gets `command_missing=` with the reason, never an empty `command=`: a driver reading `^command=` would type a blank line into a live pane.
The two consumers want the same information shaped differently, so each block carries both. `dir=` and `command=` stay separate for a driver, which moves the pane itself and then types the command. **`paste=` is the operator's line** — the two already joined into one `cd … && claude …` to select and paste. Asking a person to assemble a directory from one field and a command from another is not a saved line of output; it is the step where a session gets started in the wrong repository. `paste=` is emitted only where `command=` is, since `paste=cd X && ` with nothing after it would run the `cd` and then a bare newline, leaving you in the right directory with no session and no error.