vitrinka.docs

CLI changelog

What changed in each release of the vitrinka CLI, newest first.

Every release of the vitrinka CLI, newest first, rendered from the changelog the npm package ships. Run vitrinka update to get the newest one. Entries before 5.0.0 use the command names that release retired; its table maps each old name to the new one.

5.25.0

doc.json speaks the board's vocabulary. A document is now a doc element — {"kind": "doc", "payload": {title, …, "elements": [...]}} — and every child is the same {kind, payload} a board composes: md for prose, source for code, cols with keyed rows for tables, elements inside sections. vitrinka board push rewrites a legacy {meta, blocks} doc.json (and its pages) to the new shape on disk before it uploads; the server still converts the old shape for this release and warns, and the next release refuses it. kit-3's Table, Prose, Code and Compare take the element names too; the old ones keep working.

A --json field typo never writes twice. Asking a write verb for a field it does not return (vitrinka task create … --json=id,key) used to fail after the task was filed, with a fix that filed it again. Once a write has landed, a missing field is an unknown_field warning on the successful answer, listing the fields that exist; before the write it is still refused with the corrected call.

Eve can judge a review run. /vitrinka:review … eve plans a run for Eve the way a session's own review does: Eve judges each planned screen or crop once, skips reused and duplicate screens, and fills the same coverage receipt.

A board in another workspace is named, never "no work". vitrinka work on a board slug that lives in another workspace answers the <workspace>/<slug> spelling that reaches it instead of reporting an empty queue.

5.24.0

Reviews read each screen once. vitrinka review plan <board>… (review_plan for agents) plans a review over your boards: the latest capture pass by default, capture gaps left out, exact duplicates judged once, near-duplicates as a crop of what changed, and screens already judged under the same rubric reused — on a few labelled sheets instead of one image per screen. A host that cannot see images is stopped after the first sheet, and the run's receipt says what was inspected, reused or skipped. --checklist adds your own checks; --full re-judges everything.

Pick who judges your reviews. vitrinka config reviewer codex judges screens on the Codex sidekick, self (the default) in the session that runs the review; the session start names the lane when it is not the default.

vitrinka update refreshes a slow Claude Code. When claude --version (or codex --version) took more than three seconds — a busy computer is enough — update printed "claude (absent)" and skipped the plugin refresh without a word. Only a CLI missing from your PATH counts as absent now: a slow one is refreshed, and a refresh that fails says why.

A deleted artifact stays deleted. vitrinka board push to an artifact someone deleted is refused with artifact_deleted and a link to its page, where Restore brings it back. --revive publishes it again on the same page instead.

Ticking one step keeps the rest. A checklist written to a task (vitrinka task field set, an agent's update) now merges by item: send only the step you tick and the other steps and gates stay. --replace writes the whole list, the way to drop, rename or reorder items.

5.23.0

Claude Code stays signed in to vitrinka. vitrinka update and setup modules no longer rewrite the MCP registration when the modules it serves are unchanged — each rewrite signed every session out. Agents can no longer start a vitrinka sign-in: that cleared the sign-in every session on the computer shares. They now ask you to run /mcp → vitrinka → Reconnect instead.

A cut refuses a window that moved. vitrinka project release --cut --expect-head <sha> refuses the cut with release_head_mismatch, cutting nothing, when a refresh moved the head since you checked it. The release prints Page: (and --json carries docHeadSha): whether Eve's page was written for the current head or is stale after a refresh. A window now starts after its start commit, so the PR that commit merged is never listed again.

A deploy mark says when its lineage is partial. vitrinka project deploy-mark prod <sha> also prints how many merge commits were read from GitHub, and when GitHub's listing fell short it warns Partial: with how many merged PRs still ship by time.

5.22.0

memo's memory islands reach vitrinka. This update is all a Mac running memo needs: memo calls four hidden doors from its outbox. memory snapshot put publishes each cloud-bound island's snapshot of a merged commit. The island's current moves only by compare-and-set, and a stale publisher gets cas_mismatch with the cloud's current to adopt. memory usage put sends this Mac's hourly usage tally. memory resolve ranks memo recall --deep through Eve. memory watch put|completions mirrors a for: human watch row to one todo and reports the todos completed here. Agents read the cache as get {kind: "project_memory"}: a bounded, ranked index, paged by cursor.

Cut the release you deployed. vitrinka project release --refresh --until <sha> sweeps only the merges that commit contains and answers its head, so a pipeline cuts exactly the tag it shipped. vitrinka deploy-mark says how History ships a production mark: by ancestry, with how many waiting refs it contains, or by the time rule and why.

5.21.0

A fresh session opens again from Claude Code. vitrinka qa session launch <task url> <dir> runs your $VITRINKA_SESSION_LAUNCHER with both appended and prints its receipt; the brainstorm's and the hand-back's fresh-session exits call it. They used to run the launcher through sh -c, which Claude Code's removal check refuses with nobody at the prompt, so the exit always fell back to /continue. Unset, not runnable or a non-zero exit still names the /continue line to run by hand.

5.20.0

The plugin is four plugins. vitrinka (core: publish, artifact, brainstorming, listen, resolve), vitrinka-pm (pickup, handoff, tasks, release, me — and the session hooks of the work loop, so a Claude Code marketplace install gets them without setup), vitrinka-qa (usertest, review, sessions, pair, spot) and the opt-in, Claude Code only vitrinka-experimental (build-idea, make-idea, test, cleanup). A session on a repo that only needs boards no longer pays for the task engine's skills and tools. vitrinka setup installs core + pm + qa (--modules picks, --experimental adds the fourth); this vitrinka update installs pm and qa once on a machine set up before the split, and respects a choice vitrinka setup modules has recorded. Codex keeps one bundle with every module.

vitrinka setup modules list|enable|disable <module> adds or removes the plugin that ships a module (pm, me, qa, experimental; core is always on) and re-registers Claude Code's MCP door as /mcp?modules=…, so the tool catalogue and its instructions shrink with the plugins you have. vitrinka setup skills show|hide <skill> hides one optional skill without dropping its module. vitrinka doctor shows a plugin·claude and plugin·codex row per runtime and a hooks·claude row.

Six MCP doors the skills used to reach with raw calls: undo (revert your newest batch on a board), refresh (re-parse a living-source card), import (a truth source — openapi, sqlddl, compose, pgschema — as one refreshable diagram), review_verify (link a fresh capture to a failed judgment), get_card_image {annotation} and update {kind: "session"}. spot moved to the qa module; five doors nobody called moved to rare. Every skill was rewritten against the doors that exist — no /api/v1/ route anywhere; the ladder is the MCP tool, then the CLI, then stop.

In Claude Code type the bare /pickup, /publish, …; the qualified /vitrinka-pm:pickup always works. Codex keeps $pickup.

5.19.0

A task says which issue it tracks. vitrinka task links add <id> <url> attaches the GitHub, GitLab or Jira issue a task tracks (or a Confluence page it refers to); task links <id> lists them and task links rm <id> <link-id> detaches one. vitrinka task find <url> answers which task tracks an issue — exactly, and links: [] when none does. task create … --link <url> files a task already linked. An issue has one owner task: attaching it to a second answers link_owned with the task that tracks it.

5.18.0

A write made offline is not lost. When the deployment cannot be reached — the network is down, or an agent's MCP connection dropped with it — task comment, task update, task create, task label, task upload, task handback, me todo add, me todo done and the new board compose <board> --file - (compose_board's arguments) queue their request in an outbox on this machine and exit 0 with ⧗ queued offline. The next command that reaches the deployment replays them first, oldest first, each exactly once. vitrinka outbox list shows what waits and what the server parked, and why; flush, retry and drop act on them. --no-queue (or VITRINKA_NO_QUEUE=1) keeps the old fail-fast behaviour.

5.17.1

A code-mode review shows the sheet as an image, never as text. When a Codex code-mode script reads get_card_image, the review skill and the annotation docs now tell it to hand the image block to the host's image call (image(block)) and print only the text block. A script that logged the whole result would otherwise feed the image's base64 to the model as text, which is how one review's transcript grew to 41 GB.

5.17.0

A ui-loop review keeps what did not move. Each review batch carries a digest per screen and a reviewer records the digests of the screens it actually read, so retaking a few blank shots reopens only those screens, never every finished batch. A screen whose shots did not change since the previous pass is carried: it keeps its findings and verdicts, leaves the review batches and counts as reviewed, and the scoreboard callout names how many were carried.

Several review runs share one ui-loop pass. Each review-loop run claims its own review batches, so a big pass can be reviewed by several identical runs at once: the review stage's return says how many (parallel), each of those runs continues as one, and a run that finds every batch left already claimed ends. A run whose reviewer failed hands its claimed batches to its own next run, which reviews them first. Only the run that takes the pass's synthesis lease writes the backlog, scores the pass and posts the callouts; any other ends saying another run is synthesizing. While a capture runs, every stage waits instead of starting beside it, and areas no longer narrows a review.

A stalled reviewer no longer stalls the pass. A review batch whose reviewer stalls twice (the watchdog stops it) is split in halves, and the same run reviews them with the agents it has left. A half that stalls twice is blocked instead of retried: its screens stay unreviewed and are named in the run's problems, the pass still gets its backlog, and the loop then ends naming them, to judge by hand or reshoot, instead of reviewing the pass again.

A ui-loop polish loop can be paused. vybava ui-loop pause --reason "…" drains the whole loop: no review-loop stage starts (it returns stage paused, a null next and the resume args to launch later), and a running stage ends at its next boundary, after its reviewer round, before the synthesis, between fix lanes or before Settle, keeping what it did. vybava ui-loop resume lifts the pause and frees the stopped runs' batch claims; launch the resume args and the loop goes on where it stopped.

A screen nobody could shoot is one line, not a broken finding. A ui-loop screen marked retired (dead code, a plugin not installed, a feature off) is never shot, reviewed or counted, and map marks such screens instead of calling them unreachable. A screen without a single usable shot (unreachable, a failed recipe, an error) no longer counts against review coverage or gets filed as a broken finding: each area board's "Not captured this pass" card lists it once with its reason, instead of once per viewport and theme. The fix round's rig lane (below) repairs its recipe, and the screens a pass still has no shot of when it reaches its final check are named in one problems line and keep it from completing.

A cross-lane fix is reworked, not blocked. A ui-loop fix lane whose fix needs a file another lane owns now defers the item with the change it needs there, and the fix stage gives it a rework lane after the area lanes that owns both, so it is fixed in the same round. A block now means the fix waits on something outside the repo (seed data, a backend, another repo, a decision), and the run that ends the fix round returns every such item of the round in one list, ownerQuestions, to ask their owner in a single batch. A skipped, blocked or deferred item stays checkpointed while its own files are unchanged, whatever other lanes commit; one that no longer counts is listed in the stage's stale, and the next fix round takes it.

A ui-loop fix round repairs its capture recipes. The round ends with one rig lane that fixes the recipes a renamed label or a dead step broke: the literal names vybava ui-loop check --labels finds in no label source, the screens the pass never shot (unless the manifest marks them unreachable with the seed data) and those whose recipe failed; a screen whose code is dead or whose feature is off it marks retired. It reaches a control by its role and accessible name (the harness's action step) instead of a CSS or nth= selector, checks each repair with vybava ui-loop run --probe before it checkpoints it, re-renders the app map with them, and the verify pass reshoots those screens. A screen it cannot repair joins the round's ownerQuestions when its environment blocks it, or reworkStuck when the repair needs the app or the rig's project file. A pass whose review converged gets the same repair: the loop runs the rig lane on it and then captures the screens it repaired, instead of ending with them unshot. A label miss no longer stops a capture, and map writes new recipes the same way.

A ui-loop pass triages its failures. After each capture, and before the review writes the backlog, vybava ui-loop triage groups the shots that failed by cause. Screens that failed on infrastructure (a network blip, a page that stayed blank) come back as one vybava ui-loop run --retake … command in the stage's problems, and one application failure behind many screens is filed as ONE broken item that names them all, instead of a finding per screen. A recipe whose literal left the app goes to the fix round's rig lane. Every ui-loop stage needs Výbava v0.45.0 or later (ui-loop state contract 10) and refuses an older one; run brew upgrade --cask vybava. Update vitrinka with it: an older vitrinka neither waits for a running capture, shares a review between runs nor splits a stalled batch, it cannot finish a review in which a newer one blocked a batch, it would complete a pass whose never-shot screens it never names, and it stops a fix round in which a lane deferred an item.

5.16.1

Every survey uses the contact sheet. The publish and resolve skills and the experimental test flow now survey a set with get_card_image {cardIds} and measure on a single-card read, like review. When the server is busy, a sheet now tells the agent to retry instead of dropping the card, so a survey no longer silently loses a screen.

A ui-loop stage checks its Výbava before it starts. review-loop reads the contract number vybava ui-loop state reports and runs vybava ui-loop doctor for the stage: an older Výbava, a state field it did not report, or a failing doctor check stops the run before anything changes, naming the fix. Reviewers judge against the grid and touch target your vybava.config.ts sets.

A ui-loop pass knows when its shots went stale. vybava ui-loop state reports what changed since a pass was captured (application source, the capture rig, the spec's rules), and review-loop runs the stage it routes to as it is, including the exact screens a verify reshoots, or every screen when a shared primitive changed. A stage you asked for is never swapped for a capture: when the app drifted it stops, lists the changed paths and hands back the capture to run, and a run limited to areas never shoots. Spec rules changed since the capture reach reviewers and fixers as final owner decisions; a screen no reviewer could judge (a missing or blank shot) is filed as a recipe or capture finding the fix round repairs and the verify reshoots, not recaptured. A pass whose captured revision this clone lacks, or one shot before passes recorded their revision, hands back a capture (or the fetch) instead of running on shots nobody can date. Every ui-loop stage needs Výbava v0.35.0 or later (ui-loop state contract 2) and refuses an older one; run brew upgrade --cask vybava.

5.16.0

Review a set of screens through one contact sheet. get_card_image takes cardIds (up to 12) and answers with one labelled sheet plus each tile's card id, source size and version. The review skill surveys a board that way on every host, Codex included, and image bytes never pass through a shell command again: one Codex review had grown to 41 GB echoing base64 into its own commands.

5.15.0

Publish any number of screenshots. board push, board upload, board dump and qa run publish no longer stop at a few hundred files: pushes upload six files at a time, uploads travel in batches with retries, and a big run's screenshots are staged first and published by reference. Nothing to split by hand, ever.

Your project wears its app's icon. vitrinka setup finds the icon in the repository root (public/apple-touch-icon.png, app/icon.png, public/favicon.svg, favicon.ico, Expo's expo.icon, …) and sends it as the project's icon; an icon someone chose in vitrinka stays unless you run vitrinka setup --force-icon.

5.14.2

Every test case keeps its own screenshot. vitrinka qa run used to match screenshots by file name, so a Playwright report written on another machine (a devbox, CI) could put one test-finished-1.png on every card. Paths from another machine are now found again under the report's folder, same-named files from different tests get distinct names, and a screenshot that can't be found is left out with one warning instead of borrowing another test's picture.

5.14.1

Workflows resume from verified progress. Build and review runs share a bounded agent allowance, serialize edits, retain unfinished route and journey checks, and tie reusable reviews to the captured source and screenshot contents. Interrupted fixes resume before stale screenshots trigger a new capture.

5.14.0

A full UI polish pass, chained run by run. In a repo whose vybava.config.ts carries a uiLoop section, the map workflow (scope: "screens") extends the screen manifest, and review-loop runs one stage per run — capture, review, fix, verify — handing back the arguments for the next run. A pass resumes from the files it left after any cutoff. Pass repo (an absolute path) to pin the run to one checkout; a mismatch stops it before anything changes. Needs Výbava v0.25.0 or newer.

One board per area, every pass. A ui-loop pass lays itself out on the area's set board — a section per pass, viewport and theme, plus one "Not captured this pass" card — and never creates a second board.

A pass never calls unjudged screens clean. An empty screen list stops the run, the backlog records which screens were actually reviewed, and the stages hand lists over through vybava ui-loop instead of an agent summarizing them, so large passes (hundreds of screens) run end to end.

vitrinka update migrates a pre-rename Codex plugin. A machine whose Codex marketplace still carries an old name ends up on vitrinka@kit after one update, and vitrinka doctor names the legacy id until then.

5.13.0

Push a big take from a file. vitrinka board artifact push page.html --board <slug> --section "D1 · <title>" --device phone lands one self-contained HTML page (up to 8 MiB) as an artifact card — for takes too large for MCP. On a brainstorm board --section (the decision's chapter) and --device are required; a refusal lists the chapters to pick from.

Brainstorms stay on the brainstorming flow. The brainstorming skill builds a board through the decision map and its chapters — no more raw API takes, which a brainstorm board now refuses with the corrected call. Each option gets its own card that pictures only that take: two options naming one card are refused. The board owns its decisions, so a session no longer mirrors a chapter into a separate question prompt.

5.12.0

Ask a whole project. vitrinka task ask --project <p> "what blocks 4.0.0?" puts an open question to Eve, which searches the project with its own task search and answers in prose with the tasks it found, each with its link and one line on why. Only live tasks of that project come back, and it spends AI credits. task ask <id> "…" still asks about one task.

vitrinka update stops tripping on other marketplaces. Refreshing the Codex plugin now upgrades only the kit marketplace. A failing third-party marketplace no longer reports the vitrinka refresh as failed.

5.11.1

The handoff no longer files a decision you could be asked. The handoff skill's list of steps to file on the task names a decision only when a run nobody attends leaves it; with a human in the session the call is asked and answered there.

Ask for tasks in words. task list --ask "open stories under the restart epic" lets Eve compile the phrase into the filter document, prints what it read, and pages on with that document as --filter; a facet flag beside --ask is refused, and a server that predates it says so instead of answering the unfiltered page. search <ref> --resolve --deep lets Eve break an ambiguous verdict's tie (AI credits).

Decisions are asked while you are there. The handoff and spot skills ask a call the person in the session can answer now and record the answer in the hand-back; a Decide: gate is filed only by a run nobody attends (a Workflow, a headless or scheduled run). A brainstorm decision settled in the terminal closes its board question, and the skills' ?modules= advice names every module to keep (core,pm,qa,me,rare), so opting into rare no longer hides the task and personal tools.

Task search travels light. task search reads compact rows, about 2.5× smaller on the wire, with the same columns; task list --text matches tasks carrying every word while task search ranks any of them. vitrinka help json documents the envelope as it ships (next[].do, diagnostics[].why, exit_code on failure only), and the skills, help and session hints name the current commands and MCP calls.

5.10.0

Find one task in one call. vitrinka search <ref> --resolve reads a title, any id spelling, a URL, a branch or "bugs under <epic>" as one task reference and answers a verdict (exact, confident, ambiguous, none) with at most five candidates, each with its parent, child count and why it matched; a task verb handed a name instead of an id points at that exact call. task search filters by --type, --state, --parent and --epic (any depth), --within <task> searches one task's tree, each row says where it matched (≈ marks a typo correction), and a type, state or project that names nothing is refused with the allowed values instead of an empty list.

Each shot uploads once. Screenshot sets sync file by file: every capture sends only its new shots and the board fills live as they land, an explicit board push drops what the folder no longer holds, a set past 100 files no longer trips the guard, and qa run reuses shots the set already holds; older deployments keep the whole-set upload. The plugin's review and code loops now fix on their last pass, converge only when every gate was green and walk every fixed usertest failure again; the experimental test run marks a PR ready only on a record a reviewer judged.

5.9.0

Task reads are flat, and every task spelling works. task search and task list return flat rows with parentId and url; --json=id,title works on search, list and get; task list --parent <task> and task get --include children read an epic's tree in one call; search stays in this checkout's project unless you pass --all (--limit sizes it). Every task verb reads 42, #42, vt-42, VIT-42, fixit/42 or the task URL, and a spelling it cannot read fails with the fix before any request. --jq never hides a failure: a failed call prints its whole envelope with its exit code.

A failed request names its phase. A DNS lookup that did not answer (with the resolver file behind it), a server that took the connection but never answered, or the network, instead of blanket proxy advice; vitrinka doctor gains a dns row. Also new: board capture safari shoots Mobile Safari on the iOS Simulator through Appium in six states with the measured safe-area insets; setup --experimental installs the opt-in vitrinka-experimental plugin (Claude Code only). setup and doctor keep a ?modules= MCP list, work watch stops with a fix on a board this workspace does not hold, task get marks Eve and agent comments, admin smtp names who may edit the deployment mailer, and the tasks skill finds an epic by name in one call.

5.8.0

Release notes read like a register. Pushed documents take the new release vocabulary — galleries, compare charts, audience-tagged sections and table rows ({cells, audience}), a unit per compare item — and export from one viewer as PDF, HTML, email or Word. vitrinka project release --notes <ref> links a release to its notes document (--notes-clear unlinks it), and the release pool ranks screenshots by visual score so the notes carry the best shots once each. Web captures are 2× device scale by default (capture.hidpi in vitrinka.config.json). Slow uploads fail on an idle stall instead of a fixed deadline (VITRINKA_UPLOAD_IDLE overrides it), rapid captures on a slow link share one background push per capture folder that always ends on the newest shots, and review file without a valid --agent names the accepted runtimes and the corrected call.

5.7.1

Errors say what the server said. When the server answers a 502/503/504 with its own problem (a release sweep that cannot read a repository, for example), the CLI now shows that reason and fix instead of claiming the deployment is not answering; a real gateway outage still reads as one. Composed document cards on boards now size to their content instead of arriving clipped.

5.7.0

Releases span every repository of a project. A new release track sweeps each repository bound to the project, each on its own branch and from its own start, and stores both on the release — later refreshes and the next window after a cut need no flags. PR links name their repository, so two repositories' #123 never mix. Drive it with the new vitrinka project release (--refresh --repo <owner>/<name>:<branch>@<start>, --cut); the release skill documents the fork-point rule for choosing a start on an integration branch, the page's real shape and the X-Vitrinka-Workspace header for raw API calls. Prose links in documents are underlined like table links.

5.6.2

Links are first-class in authored documents. Every section is an anchor (id authored or derived from its label), so /a/<card>#<id> deep-links into a document and {kind:"ref", section} cross-references it in place. Table cells take {v, href, tone} and render inline markdown like prose. meta.sources declares a repository once and alias:path#L3-L9 works as any link target: the push expands it to the canonical GitHub URL and, where the deployment holds a GitHub credential, verifies the path exists at that ref. The artifact skill carries the new rules.

5.6.1

/vitrinka:review files findings and stops. A review pass, local or Eve's, ends with staged annotations on the board and a report grouped by root cause; it no longer fixes code or composes a next pass on its own. The user accepts or dismisses on the board, and /vitrinka:resolve works what was accepted — including re-capturing as a new pass and linking the Eve post-fix audit.

5.6.0

A native work hub without marking your project briefs read. vitrinka me hub --json gathers projects, tasks waiting on you, active runs and linked completion, verification, merge and deployment evidence. History covers up to 30 days, with resumable pages and explicit source coverage.

Live updates over one read-only connection. vitrinka me hub --watch --json streams snapshots when workspace activity changes, without idle polling or claiming an annotation listener. Successes and failures each use one JSON envelope per line, suitable for native clients such as Switcheroo.

Automatic achievements grounded in recorded outcomes. vitrinka me hub --generate --json requests daily-capped Eve proposals and reuses cached definitions. Starter milestones and cached results remain explicit when AI is unavailable; proposals never declare work complete. These commands need the matching work-hub server endpoints and a personal Vitrinka identity.

Capture details survive publishing. Usertest snapshots retain their route, state, device and capture context on QA cards. Capture writes also restore the runtime directory's Git ignore file, keeping local screenshots out of accidental commits.

5.5.1

The 5.5.0 hook ceilings actually arrive. vitrinka setup compared a hook's command but never its timeout, so a row whose command never changed kept the ceiling it was first written with — the Stop gate stayed at 20 s on every upgraded machine while setup reported done and doctor agreed. The timeout is now part of the hook's identity: setup rewrites a stale ceiling in place and counts it as drift. Re-run vitrinka setup once on 5.5.1.

setup repairs the Codex hooks it is told to repair. doctor's hooks·codex row has always named vitrinka setup as its fix, but setup only ever touched Claude's settings.json, so a machine kept the retired hook-context task row in ~/.codex/hooks.json indefinitely. The step now covers every harness present, and the presence probe for the Claude CLI is memoized like its Codex twin — setup asked for it up to three times, each a 3-second subprocess.

5.5.0

Breaking: a hand-back files STEPS on the task, not a pile of child tasks. hand_back / vitrinka task handback lands each next item as a step on the task's own checklist; a child task appears only when the item says task: true with a type, so an agent has to argue for a task and never for a step. New flags: --step "name[::kind][::who-or-date][::when]" and --gate "name[::who][::when]"; --next now means a child TASK. An omitted item starting with Decide: becomes a human gate that blocks Done. A step whose trigger is observable carries when in the todo grammar (pr 12 merged) and the server ticks it with evidence. A pickup leads with the task's open steps, then its children. ⚠️ An older @vitrinka/cli sending a raw next item as {title, type} with no task key now gets a 422 telling it to set task: true — update before handing back.

The session-end auto-archive is gone. vitrinka qa session archive on|off|status and the SessionEnd hook that uploaded a whole redacted transcript whenever a session naming a task ended no longer exist — every such session left a record nobody asked for, and the record buried the hand-back. Archiving a transcript is an explicit hand-off act: vitrinka qa session archive <transcript.jsonl> --task <id> when the work passes to a colleague, with the task labelled eve-distill so they open the digest. vitrinka setup strips the retired hook.

One SessionStart hook instead of three. vitrinka hook-context start prints the run stamp with the pickup, the todo cue and the schedule cue in one process and one envelope; the cues fire only on a real start (Claude Code's source is startup or clear), so a resume or a compaction pays the stamp alone and needs no matcher. Timeouts are short (8 s start, 10 s task-end, 5 s stop, 5 s touch) and the Stop gate reads only the last 4 MiB of a transcript. vitrinka setup replaces the old task, todo and schedule rows in place; the old verbs still answer for machines that have not re-run setup.

NEXT is a work queue, not a menu. The pickup skill works the task's open steps and then every child down the list until only rows a human must do remain — a decision the tree waits on is asked mid-flight, never filed and left; only the context window ends a sitting. Its mirror in the handoff skill: next holds only what the human must do, and work the agent can do is built before the hand-back.

Smaller: the listen skill's ladder is served by the server (docs {topic: "…"}) instead of shipping as a file in the plugin, and the Claude plugin renders into its own kit subtree so an installed plugin cache holds nothing installable.

5.4.0

Breaking: the old <verb>_<kind> tool names are gone. list_tasks, get_task, create_board, get_brief, list_work, get_session and every other name the six generic verbs absorbed in 5.3.0 no longer answer; the call is list · get · create · update · delete · search {kind: "<kind>", …} — the kind is the old name's tail, singular for list and search (list_tasks → list {kind: "task"}, get_brief → get {kind: "brief"}, list_work → list {kind: "work"}). An old name answers a one-line rename hint, nothing else. Per-kind contracts: docs {topic: "kind:<kind>"}. update_cards, get_card_image, get_templates and search keep their names.

The catalogue lost weight. Argument prose moved out of tools/list into docs topics, so a registration pays for the tools it can call, not for their manuals. A new rare module holds the doors a session almost never needs (transfer_project, merge_project, mark_deploy, promote_meeting, rename_set, review_judge*, review_stats, review_job, meeting_notes, save_template, dry_run_rule, edit_journey_node, set_preferences, favorite, unfavorite, my_favorites, retract_questions, board_working, request_review) — never listed by default; opt in on the registration's /mcp URL with ?modules=core,pm,qa,me,rare. usage joins select, jq and budget as a universal argument. vitrinka doctor prints the tool count the server advertises to this registration.

A bare task id is refused where it is ambiguous. On an organisation-wide grant that spans more than one workspace, an id-only tool on the root /mcp door no longer guesses: a bare {id: 42} answers spell it <workspace>/<id>. A project argument that pins the workspace, the /w/<slug>/mcp door and the <workspace>/<id> spelling all work as before.

The contract date moves to 2026-09-15 — served by /api/v1/version, stamped in every skill and in the kit export. Every skill now spells the generic verbs, and the ones that lean on a rare tool say so.

5.3.0

Skills went on a token diet; the MCP refuses to dump. Every MCP tool takes select, jq and budget; a reply above the budget (8k tokens by default, 30k ceiling) comes back as an over_budget envelope naming the tool's narrowing arguments instead of the dump. The 52 <verb>_<kind> tools collapsed behind six generic verbs (list · get · create · update · delete · search {kind}; the old names still answer, flagged deprecated), tools/list is scoped to the project's modules, and PM reads ride compact rows. The plugin ships 15 skills instead of 21: the five personal skills are ONE manual-only me skill, answers and annotations dissolved into the MCP instructions, and every SKILL.md is a trigger plus contracts.

Procedure moved to the server. The step choreography the publish, brainstorming and sessions skills used to carry is served as guide pages: vitrinka docs guide:publish-capture, guide:brainstorm-flow, guide:sessions-pipeline (MCP docs {topic: "guide:<name>"}, index docs {family: "guide"}). A wording fix is a deploy, never a plugin update.

--json envelopes of task pickup, task start, task spot, task handback, qa run and qa usertest start · case · verdict now carry next[] — the command to run next, executable as printed. vitrinka doctor reports MCP replies that ran over budget.

MCP: set_board_meta {archived: true} retires a board (false restores it); a task id spelled as a numeric string ("289") is accepted like the number; the spot and hand_back receipts name the parent task as a line instead of embedding its whole row.

vitrinka project merge <from> --into <to> merges a project into another project of the same workspace: everything <from> owns moves — tasks with their ledger, comments and attachments, boards, sets, sessions, reports, releases, press editions and project memory — nothing is dropped (a clashing custom field is renamed <key>_from_<from>, a clashing set <key>-from-<from>, values kept), and the old name stays as an alias so every old link keeps working. Dry run by default; --apply writes, --adopt --title "<epic>" parents the moved root tasks under one new epic. project merge-plan --into <to> lists the strays a merge would sweep. project fold / fold-plan keep working as hidden aliases; --adopt "<title>" became --adopt --title "<title>".

vitrinka task update <id> --project <slug> moves one task with its whole subtree into another project; states, labels, fields, sprint and milestone map by key and missing keys are created in the target.

5.2.0

One sign-in ever on Claude Code. Claude Code keeps a separate OAuth token per MCP entry, so the project-scope .mcp.json entry cost a sign-in in every repo. vitrinka setup now registers the root /mcp door at user scope only and removes a leftover project entry (commit the change); vitrinka doctor names one; the SessionStart hook tells the session which workspace the repo is bound to and how to address another (<workspace>/<project>). The server resolves a named project to the workspace that knows it — the grant's home first, then the single other workspace of the organisation that has it. Cursor, OpenCode, VS Code and Gemini CLI keep their committed files.

--local no longer registers anything for Claude Code (its registry is global, like Codex's).

5.1.1

vitrinka setup actually performs the 5.1.0 layout migration. In 5.1.0 it reported success and changed nothing on any machine whose plugin and MCP were already registered — which is every machine with a repo old enough to need migrating. Run vitrinka setup once in each bound repo and commit what it prints: the fold into vitrinka.config.json, the untracked manifests and the pruned .gitignore. An ignore line for a SIBLING path like .vitrinka-verify/ is left alone; only the runtime dir's own lines go.

5.1.0

One MCP sign-in per origin, and vitrinka mcp is gone. The OAuth grant now covers every workspace of your organisation: consent picks a home workspace, and every registration names the same /mcp endpoint, so switching repos never re-authenticates and parallel sessions in different workspaces no longer knock each other out. A repo's workspace rides an X-Vitrinka-Workspace header in its committed entry (.mcp.json spells the origin ${VITRINKA_URL:-https://app.vitrinka.ai} so self-hosted clones follow one exported variable); to act in another workspace of the organisation, name the project <workspace>/<project> — in MCP calls and in --project. Codex registers the same door (codex mcp login vitrinka).

--mcp-stdio no longer exists.

One committed vitrinka file per repo. The workspace binding, project slug, runners and run stacks now live at the top of the root vitrinka.config.json, beside the index policy. .vitrinka/ is a machine-local runtime directory that ignores itself, so your .gitignore needs no vitrinka lines at all — and journeys.json / sessions.json are no longer committed (the task engine is their record). The old .vitrinka/project.json is still read for this release; doctor names it until it is gone.

Run vitrinka setup once after updating. It folds .vitrinka/project.json into the root file, untracks the old manifests, removes every .vitrinka line from .gitignore and .git/info/exclude, and rewrites stdio-forwarder and /w/<workspace>/mcp entries onto the one /mcp door. vitrinka doctor names a leftover forwarder as a dead door.

5.0.2

vitrinka setup now installs the todo hooks it always claimed to. doctor names setup as the repair when the SessionStart todo rows are missing their startup|clear matcher or the PreToolUse touch row is absent, but setup only ever wrote the task-run hooks — it printed "Claude hooks done" and changed nothing. Run vitrinka setup once after updating and vitrinka doctor goes clean.

Until a machine does that, its session starts still inject the whole open todo list on every start, resume and compaction, instead of the handful of todos whose condition actually fired.

5.0.1

vitrinka update and vitrinka doctor are back at the top level, the way brew doctor, flutter doctor and <tool> update read; setup update and setup doctor are gone (unknown command, exit 2 — no aliases). setup keeps the bare first run plus uninstall, extension and skills.

vitrinka task list --json id,title (a space before the field list) used to fail as "unknown command id,title". It now says what it means: the field list rides the flag with = — --json=id,title — and the fix line is the corrected command.

5.0.0

One vocabulary. The CLI is twenty entries: nouns that group verbs, three leaf verbs (status, help, completion), nothing else. Old names are gone — they print "unknown command" and exit 2. There are no aliases.

Old                                New
install · project setup            setup            (the whole first run)
doctor · extension doctor          doctor
update · uninstall                 update · setup uninstall
extension … · skills …             setup extension … · setup skills …
set init|push|capture|rename|meta  board init|push|capture|rename|meta
artifact … · diagram …             board artifact … · board diagram …
open · edit                        board open · board edit
run · usertest · pair · session    qa run · qa usertest · qa pair · qa session
todo · diary · brief · time        me todo · me diary · me brief · me time
schedule <title> --in …            me schedule add <title> --in …
schedule list|ripe|move|skip|end   me schedule …
listen                             work listen
resolve <url> · query <sql>        search resolve <url> · search query <sql>
ai <words>                         docs ask <words>
tidy                               project tidy
ui                                 (bare `vitrinka` on a terminal)
login · logout · token             auth login · auth logout · auth token
push · snap · remote-init          board push · board capture · board init
name · meta · upload               board rename · board meta · board upload
board-from-set · journey-from-set  board create · board create --journey
artifact-init · artifact-from-set  board artifact init · board artifact create
watch · setup-project · index      work watch · setup · project index
import · schema                    board diagram import · board diagram schema
operator · use · smtp              config operator · config bind · admin smtp

First run

  • vitrinka setup is the one door: sign in, agent plugin + MCP, detect this repository, review the proposed index (all tracked supported files minus lockfiles, generated, vendored and .github), apply, next action. Done steps are skipped on rerun; Back keeps your answers; the key bar survives 80 columns. --advanced opens the directory picker.
  • vitrinka doctor checks the installation and this repository; --all adds every registered project. --fix shows a target · before · after plan and applies it after review.

Agents

  • --no-input never prompts (also VITRINKA_NO_INPUT=1, CI=true); --yes accepts the proposed plan; a step that needs a person exits 5 needs_human with the plan in the envelope and the --yes rerun in next[].
  • --json=id,title prunes data to those fields; --jq '<expr>' filters the envelope.
  • Exit codes: 0 · 1 · 2 misuse · 3 nothing found · 4 sign in · 5 needs a human · 130 cancelled.
  • vitrinka help exit-codes|json|no-input|environment|agents explain each contract; every command's help carries the same vocabulary.

4.2.0

update can no longer skip a plugin silently, doctor catches a plugin that fell behind the CLI, board reviews become audited judgments, and work time is measured instead of typed.

Fixed

  • vitrinka update refreshes the Codex plugin again. When the codex plugin list probe failed, the runtime printed as (no plugin) and the refresh was skipped without a word — Codex sat two releases behind while update reported success. A failed probe now prints codex (probe failed), warns with the real failure and lands under "steps need a hand" with the re-run; a probe whose process exited is taken as its answer even when a grandchild held the pipe past the deadline.
  • vitrinka doctor reports plugin version drift: an installed plugin whose version disagrees with the CLI shows stale — 3.11.0 installed, CLI is 4.2.0 — repair: vitrinka update instead of a green installed; a failed probe is a red probe failed row, never not installed.

Added

  • vitrinka review judge <board|set> replaces the old board reviewer: captured screens are judged server-side, every failed judgment gets an independent audit, and --status reads compact results. review judge export <job> prints version-pinned judgments for local triage and review file files the ones you keep. Skills review and tasks follow.
  • vitrinka time enable|disable|status|capture and time service install — opt-in, automatic capture of human and agent effort (Claude/Codex hooks, a local collector kept running at login) feeding the task and epic time views; get_work_time / get_work_evidence / get_work_forecasts read the ledger over MCP.

4.1.0

The brainstorm hands itself off: a feature brief the next session reads instead of the whole board, one worktree per feature, and a machine ledger doctor can repair.

Added

  • vitrinka task brief <epic> [--out <file>] composes the brainstorm board's Plan chapter (chosen takes only) and prints the brief skeleton; the skill fills the prose and re-uploads it as the next version.
  • vitrinka task upload <id> <files…> --kind <kind> --hint <text> --version-of <refId> attaches typed, hinted files, optionally as the next version of an existing lineage.
  • vitrinka task pickup honours meta.load on refs: first leads the READ rail, on-demand prints as a read on demand: line, never hides.
  • Brainstorming skill: deep level (same flow, bigger budget), spike / bounded / architectural classification before the first question, the feature worktree created at step 1, a vocabulary challenge, and every brainstorm closes with "in which style to implement".
  • project setup picks the project from the workspace's projects and their declared repositories; project link / project unlink manage a checkout's binding.
  • vitrinka doctor reads the machine ledger (projects.<name>.repos[] in the config) and doctor --fix repairs machine, server and per-repo drift after one confirm.
  • vitrinka dev seeds a personal workspace beside the team one.

Changed

  • project setup appends the origin to a non-empty declared repository list instead of leaving it alone.
  • The repo-side docs guide gains a brief topic (vitrinka docs brief).

4.0.0

One --json shape for ordinary commands, including help, version and doctor. An agent reads ok, then data or diagnostics, then next.

Changed (breaking)

  • --json is an envelope: ordinary commands print {v: 1, ok, verb, data, diagnostics, next} on stdout, success and failure alike. What a command printed before is now its data; a failure carries one or more diagnostics (code · severity · detail · why · fix · http_status) plus exit_code, and next lists {do, cmd} steps. Scripts reading a top-level field (.url, .slug, .error) read .data.url / .diagnostics[0].detail now.
  • Misuse is a coded diagnostic, exit 2 — an unknown command, a wrong argument count or a bad flag value answers unknown_command / bad_argument with the corrected invocation in fix. An unknown subcommand no longer prints the group's help page and exits 0.
  • Every failure carries a code from one closed vocabulary shared with the server (not_signed_in, unreachable, not_found, gateway_unavailable, …); an error with no better class is failed. A raw library error never reaches you as styled prose under --json.

Added

  • A bare group under --json (vitrinka task --json) lists its commands as data.commands instead of printing help.
  • The server's own error code, detail and fix are read into the diagnostic when the reply carries them.
  • REST errors, including authentication and routing failures, carry a code and recovery instructions. MCP exposes the same object in structuredContent.
  • doctor --json emits one failure with check results. Permission failures do not suggest repeated login; malformed JSON bodies cannot silently mutate data.
  • Protocol/stream exceptions retain their output: MCP, extension host, child commands via run, listen, continuous work watch, raw auth token, completion scripts and interactive UI.
  • Go source builds use module github.com/henderson-tech/vitrinka; update custom import paths and -ldflags -X references when building from source.

3.11.0

The task is the handoff: a session picks a task up from one bounded view, files what it spots the moment it sees it, and hands back through one door whose printed block is the hand-back. Every AI coding harness can listen.

Added

  • vitrinka task pickup [id|url] — the server-composed pickup: what the task is about, the last hand-back, the branch (and whether it exists on origin), what to read first, who is on it, the open children in rank order and what was deliberately not loaded. MCP: get_task {view: "pickup"}.
  • vitrinka task handback [id] — one atomic door: next steps and omissions become ranked children, the summary becomes the next version of the task's handoff attachment, PR/board refs and status land, the parent epic's next_action moves, and the printed block is the hand-back to paste verbatim. - reads the exact REST body from stdin. MCP: hand_back.
  • vitrinka task spot <title> — file a defect or follow-up under the bound task (else the project's rolling Found during implementation epic) the moment you see it; --production adds the might-affect-production label. MCP: spot.
  • vitrinka task start with no id binds the checkout's vt-<id> branch.
  • Hooks: vitrinka project setup offers the three Claude Code hooks interactively and shows the exact settings.json entries — SessionStart prints the pickup, SessionEnd writes the git residue into the run, and a Stop gate asks for hand_back on a hand-back turn. vitrinka install keeps registering them.
  • Two built-in rules move status by themselves: a run starting marks the task in progress, an opened PR marks it in review (merged-pr-completes stays).
  • vitrinka listen --harness <name> — host any harness (Codex, Gemini, OpenCode, Cursor, …) over the Agent Client Protocol and feed it the scope's board work; work watch --exec <harness> is the headless resume rung. install provisions the adapters behind consent; doctor prints the listen· and acp· rows.
  • vitrinka search <text> — the ⌘K palette from the terminal: tasks, pages, boards, tags, cards, sessions and shots in one call; vitrinka resolve <url> names what a pasted app URL points at, in any workspace.
  • vitrinka project fold <name> --into <home> (fold-plan for the dry run) folds a stray project name into its real home and leaves an alias; project transfer retires the source name.
  • Skills: pickup, spot and handoff (module pm); listen carries the ONE listening ladder every finishing skill points at.

Changed

  • A task or epic URL in a prompt means "pickup first" for every MCP client; the full tree is never loaded up front.
  • Task deep links are /p/<project>/t/<id>; the /t/<id> short form is gone.

3.10.0

One verb per testing lane: run your suite, or explore by hand, and vitrinka keeps the QA record — task, journeys, verdicts, board, screenshots, bugs.

Added

  • vitrinka run -- <test command> — runs the command with the run env set (VITRINKA_RUN_ID, VITRINKA_RUN_DIR, VITRINKA_RUN_STARTED_AT, VITRINKA_SHOTS=always), finds the results it left (JUnit XML, a Playwright JSON report, allure-results/, wdio reports or a run manifest; declared runners first, else a scan since the start) and publishes them. Exits with the command's exit code; --dry-run prints the folded manifest.
  • vitrinka usertest start · case · verdict · finish — an exploratory session over snap: every capture attaches to the open case, finish publishes one journey per case with its verdict and shots.
  • vitrinka project setup --runners [--check] — declares where each detected runner (Playwright · wdio · Jest · Vitest) writes results in .vitrinka/project.json; --check exits 1 on drift.
  • A run with no task in context lands under the project's rolling Unplanned runs epic instead of failing; run publish does the same.
  • The run door accepts JUnit XML and Playwright JSON bodies directly (POST /tasks/{id}/run, POST /projects/{project}/run).

Changed

  • The usertest skill is the two verbs; board mechanics left it. The publisher agent keeps only walkthrough boards.

3.9.1

The feature-lifecycle follow-ups: the QA board and final artifact from the terminal, and transcripts folded once, on the server.

Added

  • vitrinka task qa-board <id> and task final <id> (--json prints the door reply verbatim) — the qa task's board with its living journeys diagram, and an epic's final board + versioned final page.
  • GET /tasks/{id}/refs/{ref}/transcript — one server-side transcript normalizer feeds the task panel's viewer and Eve's corpus; the upload door stamps the index from it.

Changed

  • eve-summarize's quiet window is a persisted row swept by the runner, so a restart no longer drops it; the daily cap is claimed atomically.
  • The final board's Delivery section lists the releases that shipped an epic's PRs, matched by repository and PR number.
  • session continue reads the whole attachment (full=1) and writes the resume file into a private temp directory.
  • Protocol doc §4.17–4.20 aligned with the eve-ai-layer implementation (derivedFrom {id, version}, pm-ask scope/tree, 415 on binary refs).

3.9.0

Tasks become the feature record: typed, versioned attachments an agent loads progressively, Eve on tasks through eve-* labels and ask_task, coding-agent session archives with a portable continue, a QA plan of journey tasks drawn as a living diagram, and commits that link themselves through a trailer.

Added

  • vitrinka task label <id> --add --remove and task link <id> <to> --rel blocks|relates|duplicates|supersedes|custom; task update --label now reaches the labels door (it was silently ignored).
  • vitrinka session archive on|off|status|<path> --task <id> — opt-in archive of Claude Code / Codex transcripts behind a task: a secret gate (credentials refuse, PII masks), //vitrinka:repo:<remote>/<rel> portable paths, a SessionEnd hook installed by vitrinka install; session continue <task> prints the latest Eve distill as a brief and offers native resume when the harness matches.
  • vitrinka commit-msg (hidden, the per-repo prepare-commit-msg hook project setup installs) appends Vitrinka-Task: vt-<id> from the branch; project commits --subject on|off and workspace commit-prefix bracket|bare|colon control the optional subject prefix.
  • vitrinka task resolve-qa [--task <id>] — the qa task a usertest board or session belongs to, from the branch's vt-<id> or an epic.
  • MCP: label_task, get_task {include}, read_task_ref (raw under budget, Eve-distilled above it or with a question), ask_task {question, intent, scope}, upload_task_file {kind, hint, versionOf}, qa_board, edit_journey_node, compose_final, propose_tasks drafts with key, parentKey, fields; task types qa and journey; ref kinds transcript · conversation · brainstorm · plan · handoff · decision · distill · commit · final; every enum is generated from the server.
  • Skills: tasks (planning an epic, the feature lifecycle, asking Eve), sessions (archive + continue), usertest/publish (auto-link to the qa task), brainstorming (files the feature epic).

Changed

  • Unknown MCP arguments are refused with a 400 naming the accepted set (they were dropped silently) and recorded on the agent-calls ledger.
  • type on create_task/update_task is documented; todo appears in every type enum.

3.8.1

The public-beta surface: vitrinka is an authenticated service at app.vitrinka.ai — sign up, run vitrinka auth login, and every skill, message and manifest now says so. Author and repository moved to Henderson Tech (github.com/henderson-tech/vitrinka-kit).

Removed

  • vitrinka import pultik — the one-off Obsidian vault importer is gone; vitrinka import <file> still forwards to diagram import.

Changed

  • Unreachable-host and doctor messages point at your network or VITRINKA_URL for self-hosted deployments instead of a VPN.
  • Skills and MCP tool descriptions describe the authenticated service; Eve is introduced as vitrinka's AI reviewer; example slugs are acme.
  • The npm launcher and platform packages are Elastic-2.0 and ship the LICENSE; author Henderson Tech; issues and README link to the public kit repository.
  • Docs: the quickstart links sign-up; the report widget page describes the served report-widget-1.mjs script.

3.8.0

Personal todos and scheduled reminders live in vitrinka: a todo task type with the moment preset (trigger · lead · every · context · commit · branch), milestones that can be reached, and ripeness computed when you ask.

Added

  • vitrinka todo add|list|show|done|drop and todo milestone add|list|reach|unreach — the todo engine from the terminal; done rolls a recurring todo forward on your wall clock and keeps it open.
  • vitrinka schedule <title> --in|--at [--lead --every] with list|ripe|move|skip|end — timed reminders; ripe --claim announces once per cooldown through a per-machine, fail-open ledger.
  • vitrinka hook-context todo|schedule — the Claude Code SessionStart context (open todos of this checkout's project; ripe reminders across projects). Prints nothing rather than failing.
  • vitrinka import pultik [<vault>] [--apply] — imports an Obsidian todo vault: dry-run by default, idempotent by title, milestones per project, depends_on as blocks links.
  • Skills /todo, /todo-list, /todo-done, /todo-milestone, /remind under the new me module (vitrinka skills lists core · pm · qa · me).
  • MCP: ripe_todos, complete_todo; update_milestone {reached}; todo add --body-file - reads a body from stdin.

Changed

  • vitrinka import <file> (the legacy diagram import) now lives under the import group and forwards unchanged.
  • task list --type accepts todo; fields=summary rows carry longtext fields as excerpts and an exhausted page omits nextCursor.

3.7.1

Fixed

  • vitrinka update migrates a Codex marketplace registered under a legacy name. Codex refuses marketplace upgrade for a clone registered as lovinka or vitrinka once the kit's manifest names it kit; update now drops the stale registration, re-adds the kit and re-adds the plugin instead of handing you the error.

3.7.0

One version, everywhere: the vitrinka agent plugin (Claude Code / Codex marketplace vitrinka@kit) now carries the CLI's version, so vitrinka update always brings the skills and the MCP vocabulary that match this binary. The plugin jumps from 1.11.0 to 3.7.0 in one step.

Added

  • File a task from a board card. Right-click any card → File a task from this card: the task lands in the project with the card as its evidence, and (when you may accept intake) is projected straight back onto the board as a task card. Cards wear a quiet REN-12 · done ↗ link to the tasks filed from them.
  • Pin a task on a board from the task panel's menu; task cards link back to their task.
  • docs {family: element|board|artifact} narrows the docs index to one layer (about a third of the tokens).

Changed

  • scrape_board and list_sections take board like every other board tool (slug still works).
  • list_tasks answers compact rows — label names, no bodies, no actor objects, no timestamps; get_task has the full record.
  • The docs index shows one sentence per topic.

3.6.0

Added

  • vitrinka docs [topic] — the connected deploy's artifact component reference, in the terminal. No topic prints the compact index; a topic prints that page (props, example, gotchas). It reads the docs off the server you're signed into, so what prints always matches the kit that will actually render your artifact — even one newer than this CLI.
  • push preflight autofixes doc.json. Mechanical mistakes — typos, HTML entities, small JSON damage — are repaired before validation and reported as fixed: lines; --no-fix skips the repair. Validation failures and server rejections now come back as structured diagnostics naming the exact spot (carried in the --json envelope too) instead of a bare error.
  • Artifact pushes come back with a screenshot. After publishing, the server smoke-renders the artifact and the CLI downloads render.png beside it, so you see what shipped without opening a browser. --no-render skips the wait and the download.
  • Your repo's DESIGN.md rides along. Artifact pushes discover the repo's DESIGN.md and send it so renders follow your design language; --no-design opts out. artifact init quotes the style brief into new scaffolds.

Changed

  • artifact init emits ONE scaffold — an editable index.html composing kit components, ready to rework directly. The --custom full-HTML escape hatch is retired; the command points you at composing kit components instead (see vitrinka docs).
  • The project slug follows the repo binding from any subdirectory — a nested working directory now honors the nearest ancestor .vitrinka/project.json instead of resolving as if the repo were unbound.

Fixed

  • An oversized or garbage server response now fails loudly, naming what was wrong with it, instead of being silently truncated into confusing output.

3.5.0

Added

  • vitrinka skills — the skill store. Browse the catalog, see per-runtime install state, and toggle per-skill visibility for Claude Code and Codex, all through the native plugin mechanisms.
  • /vitrinka:usertest — an autonomous exploratory user-tester skill ships in the plugin.

Changed

  • The plugin now installs from the public vitrinka-kit repo — claude plugin marketplace add FixIt-Technologies/vitrinka-kit, spec vitrinka@vitrinka. vitrinka install registers the new source.
  • Machines installed under the legacy vitrinka@lovinka id are migrated automatically by vitrinka install (run it once; vitrinka doctor shows a "legacy id lingers" row until you do).
  • The recall skill dissolved into the MCP server instructions — one fewer skill, same pre-build memory pass.

3.4.2

Fixed

  • npm releases flow again. The npm channel had been stuck at 3.3.0 since the scope move; publishing is restored, so npm i -g @vitrinka/cli and the shelf now carry the same version. No CLI behavior changes since 3.4.1.

3.4.1

Changed

  • Updates come from releases.vitrinka.ai — the public vitrinka release host. vitrinka update and the recorder extension no longer read the internal shelf domain, which was unreachable outside the company network. Mirrors via $VITRINKA_RELEASE_FEED are unchanged.

3.4.0

Changed

  • The CLI targets app.vitrinka.ai — the app moved off the apex in the host split, and the old default could only die on a redirect that drops your credential. Old sign-ins keep working (credentials and bindings carry over), and an explicit --base, $VITRINKA_URL or script still pointing at vitrinka.ai / vitrinka.in self-heals to the app host on its own. Nothing to migrate.
  • vitrinka board create names the board after the whole set — <project>-<branch>-<setkey>, not the set key alone. The key defaults to today's date and board slugs are workspace-global, so two repos capturing on the same day used to ask for the very same board. Pass --slug to name it yourself; existing boards are untouched.

Fixed

  • --base sticks. Signing in (or pasting a token during vitrinka install) now persists that deployment as this machine's default, so bare commands — doctor, watch, mcp — keep talking to the install you signed into instead of the hosted default. No standing $VITRINKA_URL needed; logging out of it resets the default.
  • A taken slug is never adopted blindly. When the board already belongs to another project, board create stops and tells you whose it is instead of importing your set onto someone else's canvas. Reuse of your own board is unchanged — it just says so now.

3.3.1

Fixed

  • Board listeners work again. vitrinka watch no longer degrades to "unreachable" on quiet boards — the long-poll was being killed by the CLI's own 30-second network timeout, so every idle cycle counted as a failure. Idle holds now run their full window and quiet timeouts are treated as the normal heartbeat they are.
  • Redirects between vitrinka hosts (e.g. vitrinka.in → vitrinka.ai) no longer drop your credential mid-flight (HTTPS targets only).

3.3.0 — unreleased

Changed

  • Package renamed to @vitrinka/cli (platform packages @vitrinka/cli-<os>-<arch>). Same CLI, same vitrinka bin, now under the product's own npm scope alongside @vitrinka/expo. vitrinka update on an old-scope install migrates automatically (removes the legacy launcher before installing this one); the retired launcher is deprecated with a pointer here.

3.2.0 — 2026-08-23

Added

  • vitrinka now works from ANY directory. vitrinka install registers the MCP forwarder at user scope everywhere (a bound repo also keeps its committed project-scope entry, which stays the preferred mechanism and always wins), and a new machine-level default workspace answers for directories no binding covers. Onboarding asks you to pick one; later it's vitrinka config default.
  • Path-prefix workspace rules — map a folder subtree to a workspace (vitrinka config prefix ~/Work/ClientA acme); the longest matching rule wins, the default workspace is the fallback behind them.
  • A confirm gate on defaulted writes. A write from a directory that resolved through a prefix rule or the default asks once per directory (per workspace) before landing — as a y/N in the CLI, and as a structured workspace_confirm_required re-call for MCP agents. vitrinka config writes auto turns the asking off; explicit bindings never ask.
  • vitrinka doctor shows a default workspace row, and the dashboard shows the resolved workspace with its provenance.

Changed

  • Re-running install no longer removes a healthy registration at a scope it is not rewriting — committed .mcp.json entries survive the global-first migration untouched.

3.1.0 — 2026-08-23

Added

  • vitrinka mcp — MCP registrations no longer carry your token. The entry every client now gets is the same three words in every repo (command: vitrinka, args: ["mcp"]), with no URL and no credential in it. The command resolves the deployment, workspace, token and operator at request time, from the repo's committed binding and your OS keychain. That makes .mcp.json safe to commit — so a clone is born registered — and it gives Codex per-repo workspace routing its global, header-less registry could never express.

Changed

  • vitrinka install rewrites a legacy token-bearing registration wherever it finds one — either Claude scope, or Codex's config.toml — and tells you to commit the now secret-free .mcp.json alongside project.json.
  • vitrinka doctor names a credential in a config file for what it is, per file (.mcp.json, .claude.json, config.toml), with vitrinka install as the repair. It also names a registration that predates the forwarder instead of showing it green.

Fixed

  • A repo whose .vitrinka/project.json cannot be read no longer falls back to the default deployment — it refuses and names the file to repair, instead of quietly publishing to the wrong install.
  • A locked or unreadable credential store is reported as itself, not as a generic 401 from the server, and unlocking it heals the running session without relaunching the client.
  • The forwarder no longer outlives the client that launched it: closing the pipe ends in-flight work after a short grace, and a stalled handshake can no longer hold the process open.

3.0.2 — 2026-08-22

Added

  • Workspace bindings travel with the repo. vitrinka config bind now writes a committed .vitrinka/project.json (per deployment, so on-prem coexists) — clone a bound repo on any machine and it is bound at checkout. The machine config remains as credentials + fallback.
  • vitrinka install self-heals multi-workspace setups: writes the committed binding from a machine-only one, narrows an old wholesale .vitrinka/ ignore so the binding can reach git, and re-registers the Claude MCP entry project-scope when it predates workspace baking.
  • vitrinka doctor explains multi-workspace problems: binding source (committed vs machine-only), ignore rules hiding the binding, and stale MCP registrations — each row names the repair.

Changed

  • Working in several workspaces on one machine no longer needs per-repo header surgery: the server now also resolves the workspace from the project a call names, and refuses (with the fix spelled out) instead of guessing when the answer is ambiguous.

3.0.1 — 2026-08-22

Changed

  • Hosted Vitrinka now lives at vitrinka.ai. New installs, MCP setup, desktop/Snap defaults, share links, and generated config schemas use the new domain. Existing credentials and workspace bindings stored for vitrinka.in continue to work during the compatibility window.

3.0.0 — 2026-08-18

The CLI is now a compiled Go binary. The npm package is a thin launcher: it resolves the per-platform binary package for your machine and execs it. Same commands, same flags, same config files — no Node runtime needed to run vitrinka, and startup is instant.

Changed

  • vitrinka is Go. Source moved from pkg/src/cli.ts to cmd/vitrinka + internal/cli/* in the vitrinka repo. The npm package ships bin/vitrinka.js, which launches the per-platform binary package (declared as optionalDependencies, resolved by npm from whatever registry you already use — no postinstall download, works offline and behind proxies).
  • Installing with --omit=optional / --no-optional skips the binary by design; the launcher says exactly which platform package is missing.

Removed

  • The vitrinka-mcp bin is gone. The stdio MCP server is retired in favor of the server's remote endpoint. Re-register once:

    claude mcp remove vitrinka
    claude mcp add --scope user --transport http vitrinka https://vitrinka.ai/mcp \
      --header "Authorization: Bearer $(vitrinka token)"

    vitrinka install / vitrinka doctor --fix do this for you (Claude Code and Codex both).

  • The unattended fallback worker (vitrinka-mcp work) is gone. vitrinka watch plus the native background monitor armed by the listen skill is the one listening lane now.

  • The mcp/server.ts, mcp/work.ts and mcp/index.ts repo shims are deleted — a repo checkout no longer registers an stdio MCP; point at /mcp instead.

Unreleased (pre-3.0.0 — TypeScript CLI, never published)

Removed

  • Claude Code UI wiring is gone. The install-claude command, the [Y/n] install step and the --claude/--no-claude flags were removed — the statusline extension and the 🧷 board / ⧉ app footer badges never worked well. install/update/uninstall now actively strip the old wiring from ~/.claude/settings.json (restoring your original statusLine.command).

Added

  • Consent-gated project indexes. setup-project and index configure now create a repo-owned vitrinka.config.json, with extension presets, a recursive tri-state directory picker, strict ignore layers, exact-manifest preview, and per-machine approval. index status, --dry-run, and --explain <path> make the resulting policy auditable.
  • Workspaces follow the project, not the token. vitrinka login now mints a USER-LEVEL token that acts as you in every workspace you're a member of; each repo binds to its own workspace (vitrinka use, an indexed table you answer by number — or automatically when exactly one of your workspaces has the project). Commands in an unbound repo stop with the same table and the fix command, so an agent asks you instead of writing into the wrong workspace. Workspace-pinned tokens keep working but are deprecated — doctor and vitrinka update nag to re-login. Per-project Claude MCP registrations bake the workspace in as an X-Vitrinka-Workspace header.
  • vitrinka logout revokes this machine's token server-side (DELETE /api/v1/me/tokens/current) and removes the local file; your user-level tokens are listable and individually revocable via GET/DELETE /api/v1/me/tokens[/{id}] — a lost laptop has an answer.
  • Semantic artifacts. artifact-init now scaffolds a doc.json you author plus a fixed shell rendered by the server-owned kit-3 — palette, type, spacing, light/dark and the design direction (editorial · dossier · terminal · gallery) come from the kit, and artifacts follow the viewer's theme automatically. artifact-from-set composes the doc (sections + shot figures) the same way. The full-HTML escape hatch lives on as artifact-init --custom, now themed by default.
  • push warns when a hand-authored index.html carries HTML entities inside template literals (&rarr; renders literally under htm — write →).
  • Findings carry their proof: status (verification chip), cause, summary (the bold conclusion) and evidence (mono receipt footer citing the exact log/file/check) joined the finding block.
  • Codex MCP registration. vitrinka install now offers to register the remote MCP for Codex too (writes [mcp_servers.vitrinka] + http_headers into $CODEX_HOME/config.toml), vitrinka doctor --fix repairs it, and vitrinka uninstall removes it. Doctor/install rows are now mcp·claude / mcp·codex. Skills already shipped to Codex via the plugin; the MCP was the missing half.

Fixed

  • vitrinka tag read option VALUES as positionals, so tag add b1 auth --actor alice sent ["auth", "alice"] as tag names — and tags autocreate, so routine invocations silently minted junk tags. A flag placed before the verb (tag --actor x add …) also fell through to the ls default. Both now come from the shared positionals() parse the rest of the CLI already uses.

Changed

  • Project indexes are path-only v2 manifests. The CLI no longer reads or sends source excerpts, absolute paths, origin remotes, home-directory commands, or command descriptions. Missing/disabled/changed policies fail closed; tracked .gitignore matches, credential/key names, and binary/generated paths are denied client-side and again by the server. Deploying this release purges all legacy index rows once.
  • tag merge and tag drop now REFUSE without a TTY unless --yes is given (exit 2). They previously treated "no TTY to ask on" as approval, so they ran unconfirmed in scripts, CI and any redirected shell — drop detaches the tag from every board, card and session. If you script either verb, add --yes.

1.21.2 — 2026-07-26

Added

  • vitrinka doctor reports listener leases held by dead watch processes on this machine, and vitrinka doctor --fix releases them.
  • vitrinka extension setup | update | doctor — install the journey-recorder browser extension from the CLI and keep it current. Updates now happen in place: the popup's "update available" banner is a button that has the CLI download, checksum-verify and swap the release, then reloads the extension into it. --check reports without installing; doctor --fix re-registers the native-messaging host after a CLI reinstall moves node or the CLI.
  • The extension takes its base URL and token from this machine's CLI config on first load, so a fresh install needs no pasting (the options page gains a "Fill from the vitrinka CLI" override). Existing settings are never replaced.
  • Migrating a hand-unzipped copy: the extension now pins its id, so the CLI-managed folder is a different extension to Chrome. Run vitrinka extension setup, load ~/.config/vitrinka/extension, and remove the old card — a token you pasted by hand does not carry over.

Changed

  • vitrinka install now detects the Chromium browsers on the machine and offers the recorder as a step (--extension / --no-extension), so re-running it on an already-onboarded machine is how you backfill the extension. An install that already has it silently re-registers the update host, which is also how a browser added since the last run starts working. vitrinka update keeps an installed extension current, and the update host is registered for the browsers detected on the machine (falling back to all of them when none is detected, so a fresh box still gets a working host) — so extension doctor can now tell you the browser you use is unregistered instead of counting four blind writes.

Fixed

  • A listener could outlive the session that armed it and hold its board's lease forever. Claude Code signals the wrapper shell it spawned, so the watch underneath never got the SIGTERM — it was adopted by init and kept renewing its lease, which the TTL cannot reap (the TTL only reaps leases that stop heartbeating). Annotations dispatched on that board then vanished into a process nobody was reading. Three fixes: /vitrinka:listen now arms exec vitrinka watch so the watch is the signalled process; vitrinka watch self-terminates if it is ever orphaned, covering exits that deliver no signal at all (agent SIGKILLed, crashed, terminal closed); and it now handles SIGHUP alongside SIGINT/SIGTERM.
  • Release integrity is fail-closed: a feed without a usable SHA-256, or an artifact larger than it advertised, is refused before anything is downloaded or swapped. Previously the checksum was only verified when the field happened to be present, and the whole body was buffered unbounded.

1.21.1 — 2026-07-25

Fixed

  • /vitrinka:brainstorming sometimes skipped the decision map — the map was reasoned out but never written, so the round opened straight into a "anything to cut, add, or reorder?" picker whose options referenced decisions you could not see anywhere, expanded output included. The map is now printed as its own message before any question is asked, and the board-mode exemption from printing it only applies once a board actually exists.

1.21.0 — 2026-07-25

Added

  • MCP get_session — one recorded testing session as a compact digest (the screen walk, issues deduped across steps with live board status, per-route web vitals, and facets to group them into fix batches). Address it by session id or by the session's board slug. Use it instead of walking raw /events.

Changed

  • Closing a session no longer waits for its board. The server builds the board on a worker and reports projection state, so a stop returns immediately — and a recording session's board is now kept live as you test, rather than only existing once the session ends. Anything reading projectionError off a stop response should read projection.state instead.

1.20.0 — 2026-07-23

Changed

  • All output now lives under one .vitrinka/ home in the target repo: .vitrinka/screenshots/ (was .screenshots/), .vitrinka/artifacts/<slug>/ (was .artifacts/), plus .vitrinka/scratch/<topic>/ as the sanctioned spot for ad-hoc session output. Legacy roots auto-migrate the first time a command touches them; explicit --root/--from paths are respected as given.

Added

  • vitrinka tidy [--yes] [--all] — report-first sweep of legacy roots and shot-shaped repo-root litter (.screenshots-<topic>/, loose shot-*.png) into .vitrinka/; --all also moves loose images and .aud_* text litter. Git-tracked files are never touched.
  • Plugin skills /vitrinka:annotations + /vitrinka:answers — manual MCP fallback drains for when a "Send to Claude" dispatch doesn't reach the session (annotation work queue / durable question answers).

1.19.0 — 2026-07-23

Added

  • vitrinka setup-project — the repo onboarding wizard (clack-styled TUI, the pkg's first runtime deps: @clack/prompts + picocolors). One front door for everything a repo needs before the editor and board @ autocomplete work: machine-install gate (offers install inline when the machine isn't onboarded), project name + registry record, file/route index push (verified), component-index with auto-detected candidate dirs, desktop-app check, and an optional hello board. Status-first and idempotent — re-runs refresh the cheap bits and only prompt for what's missing; --yes/non-TTY takes every default.
  • edit and status print a one-line hint toward vitrinka setup-project while the repo has never been indexed.

1.18.0 — 2026-07-21

Added

  • vitrinka edit [path] — focus the resident Vitrinka.app editor on a file or project via the vitrinka://edit?path=… deep link (--print emits only the URL; when the app isn't installed it prints an install hint). The instant editor's CLI entry point.
  • Automatic project registry: edit, status, watch, and board-from-set now record {project → main-worktree path} to ~/.config/vitrinka/projects.json as a side effect, so the desktop editor auto-discovers your live checkouts with zero extra UX. Best-effort — a write failure never breaks the command.
  • compose_board accepts kind "artifact" — a sandboxed self-contained HTML card straight from a compose batch: {html} full document or {body, runtime: "tw4"} markup-only (server inlines the Tailwind v4 runtime; dramatically cheaper). Up to 8 MiB inline.

Changed

  • compose_board's card schema is slim: the tool description now carries the kind index + quick shapes only; per-kind payload contracts live in the vitrinka plugin skills (the publish skill's references/card-kinds.md is the index). Unknown kinds still 400 with the full allowed list.
  • vitrinka import (and POST /import) replies with a compact per-card summary ({id, elemNo, kind, title, counts, section?}); pass --verbose (API: ?verbose=1) for the full card JSON.

1.17.0 — 2026-07-20

Added

  • get_questions MCP tool — durable post-send retrieval of a board's answered decisions (options, notes, ⌖ refs). Choices ride the work wire exactly once, so a send with no listening session used to look unrecoverable; now any session can re-read the full answer record at any time.
  • scrape_board digest now carries a compact questions[] ({id, prompt, answer?, note?, staged?}) — one call reads the decision state alongside cards/flow/sections; section scopes keep only their own.
  • vitrinka watch keepalive: while a human actually has the board open, the leased watch emits a quiet · keepalive heartbeat (default every 3000 s, --keepalive 0 off) so the listening session's prompt cache stays warm and the next annotation lands cheap. An abandoned board costs nothing.

1.16.0 — 2026-07-19

Added

  • Listener takeover is automatic on the same machine — arming vitrinka watch for a scope another of YOUR sessions already holds displaces the older listener (its in-flight items go back to the queue) instead of failing with a 409 and a manual handoff. The displaced watch prints one stand-down line and exits cleanly. Live leases on a different machine still refuse the claim; --takeover still steals expired leases only.

Fixed

  • vitrinka watch and the background daemon no longer swallow answered brainstorm choices — a pure choice batch used to be drained by the notifier and marked delivered while the listening session never woke. Notifier lanes now peek without consuming, and watch announces each answer as a №<id> [choice] line; the acting lane keeps exactly-once delivery.

1.15.1 — 2026-07-18

Added

  • vitrinka version (and --version/-V for the bare number) — the installed version, where it runs from (repo checkout / bun / pnpm / npm install), and the last known update state from the notifier cache. No network, instant.

Fixed

  • vitrinka update now updates through the package manager that OWNS the running copy (bun / pnpm / npm, detected from the executable's path) and verifies the running file actually changed — a bun-installed CLI used to npm i -g into a shadowed prefix and stay stale forever, and update warns loudly when another install still shadows it on PATH.

1.15.0 — 2026-07-18

Added

  • Update notifier v2 — the daily detached check now asks YOUR vitrinka server first (new GET /api/v1/version: a deploy announces the version, works on the mesh with npm unreachable) and falls back to the npm registry. Agent shells (non-TTY — an AI session driving the CLI) see the update available … · run: vitrinka update line on every run so the session can offer the update; interactive terminals see it at most once a day.

1.14.0 — 2026-07-18

Added

  • compose_board question options accept cardRef — trace an option to a card created in the SAME compose batch (template + inline cards share one ref space), so a decision map and its per-option architecture diagrams land in ONE call. cardId still traces to existing cards; picking flies only on ⌘-click now (plain click just stages the answer).
  • The built-in decision-map template is documented on compose_board: structured params {title, context, decisions:[{key, title, stakes, options, multiSelect?, kind?: "text"}]} render the whole brainstorm map — a width-filling grid of merged decision tiles — deterministically server-side.

1.13.0 — 2026-07-17

Added

  • vitrinka import <file> + vitrinka schema push — refreshable ground-truth diagrams from docker-compose / OpenAPI / SQL DDL / a live Postgres; --section lands them inside a journey frame, --rev stamps the git SHA.
  • Journey branch capture: snap --next/--target groups + journey-from-set.
  • Unified publish skill (session · journey · docs · board · artifact).
  • compose_board edges accept fromRegion/toRegion; arrange gains a journey mode.

Fixed

  • add --file hardened (out-of-root copies, symlinks, non-regular files); push guards against a huge --root and reports tar failures legibly.
  • doctor no longer health-checks every Claude MCP server.

1.11.0 — 2026-07-15

Added

  • vitrinka upload <files…> --board <slug> — put PDFs, documents, and images on a board as cards straight from disk (the bytes never pass through an AI context). PDFs land as live embedded document cards, other files as download chips. Placement is intent-based: --section "Name" lands inside a journey frame (grows to fit), --anchor <cardId> [--side right|below] docks beside a card, and no flag = server free placement (never a 0,0 pile).

1.10.1 — 2026-07-13

Changed

  • Canonical domain is now vitrinka.in — the CLI/MCP default base URL, skills and docs all point there. vitrinka.lovinka.com keeps working as an alias; override per-machine with VITRINKA_URL as before. Re-run vitrinka install (or doctor --fix) to re-register MCP on the new host.

1.10.0 — 2026-07-13

Added

  • compose_board question options accept cardId — the board draws a trace wire from the option to the card it names, hovering glows it, and picking flies the camera there. Pair it with the new POST /artifact params (section, device, anchor/side): mockups land inside their take's section frame, sized by device intent, and scale to fit their card automatically (server-measured natural size).

1.9.0 — 2026-07-12

Changed

  • MCP registration moved to the remote /mcp endpoint (streamable HTTP) — no local stdio process per session; vitrinka install/doctor --fix re-register automatically. The old stdio bin is deprecated.

1.8.3 — 2026-07-11

Fixed

  • Interactive prompts (install's operator question, any promptLine) strip ANSI escape sequences and control characters — arrow-key edits no longer persist raw ESC[D/ESC[C bytes into the operator name (which every fresh browser adopted as its board identity). vitrinka operator <name> sanitizes the same way, and the server now rejects control characters with 422.

1.8.2 — 2026-07-11

Added

  • Desktop-app flag: ~/.config/vitrinka/desktop-app is the one canonical "is Vitrinka.app installed" answer (content = app path). Stamped by apps/desktop make install, re-synced by install-claude and doctor.
  • install-claude adds a second ⧉ app footer badge (only when the app is installed) whose vitrinka:// deep link opens the board in Vitrinka.app.
  • vitrinka open opens the board in Vitrinka.app when installed; --browser forces the browser.

1.8.1 — 2026-07-11

Added

  • install-claude now also wires a SessionStart hook (~/.claude/hooks/vitrinka-board-link.sh) that puts the repo's live board URL into session context at start — the clickable 🧷 footer badge exists from message one instead of waiting for a board URL to be mentioned. vitrinka doctor reports (and --fix repairs) the hook; uninstall removes it.

1.8.0 — 2026-07-11

Changed

  • Skills now distribute EXCLUSIVELY as the vitrinka plugin — for Claude Code (claude plugin install vitrinka@lovinka) AND Codex (codex plugin add vitrinka), both from the LEFTEQ/vitrinka marketplace. vitrinka install, doctor --fix and update install/refresh the plugin in every runtime CLI they find; the npm package no longer bundles the skills.
  • Skills layout flattened: listen is a first-class skill (/vitrinka:listen in Claude Code, $listen in Codex).

Removed

  • vitrinka install-skills — superseded by the plugin. vitrinka uninstall still clears legacy ~/.claude/skills copies from pre-plugin machines.

1.6.0 — 2026-07-08

Added

  • vitrinka update — updates the CLI (git pull in a checkout, npm i -g when behind the registry), prints what's new, and refreshes the installed skills and Claude UI wiring.
  • Status-first onboarding: vitrinka install now prints a ✓/✗ setup table and handles everything install.sh used to (MCP registration, write token, operator persona, env checks) — asking only for what's missing.
  • vitrinka uninstall [--purge] — clean offboarding (skills, shim, completion, Claude wiring, MCP registration; --purge also removes token + operator).
  • vitrinka doctor --fix — repairs stale skills, a stale/missing shim, a lost MCP registration, and the Claude UI wiring.
  • vitrinka open [--qr] — opens the capture root's live board; --qr renders a terminal QR code to scan with the iPad.
  • vitrinka status — session dashboard: live board, open work queue, and the listener lease for the current repo+branch.
  • Passive update notifier (one dim line, cached daily, npm installs only) and a first-run hint on fully unconfigured machines.

Removed

  • install.sh — the CLI is the installer now: vitrinka install (or node pkg/src/cli.ts install from a checkout).

1.5.0 — 2026-07-08

  • project-memory MCP tools + link/board compose vocabulary (pre-changelog release).

On this page