@vitrinka/cli 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +525 -0
- package/README.md +125 -0
- package/bin/vitrinka.js +81 -0
- package/package.json +40 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
`vitrinka update` prints the sections newer than your previous version after
|
|
4
|
+
updating — keep entries short and user-facing.
|
|
5
|
+
|
|
6
|
+
## 3.3.0 — unreleased
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- **Package renamed: `@lovinka/vitrinka` → `@vitrinka/cli`** (platform packages
|
|
10
|
+
`@vitrinka/cli-<os>-<arch>`). Same CLI, same `vitrinka` bin, now under the
|
|
11
|
+
product's own npm scope alongside `@vitrinka/expo`. `vitrinka update` on an
|
|
12
|
+
old-scope install migrates automatically (removes the legacy package before
|
|
13
|
+
installing this one); `@lovinka/vitrinka` is deprecated with a pointer here.
|
|
14
|
+
|
|
15
|
+
## 3.2.0 — 2026-08-23
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **vitrinka now works from ANY directory.** `vitrinka install` registers the
|
|
19
|
+
MCP forwarder at user scope everywhere (a bound repo also keeps its
|
|
20
|
+
committed project-scope entry, which stays the preferred mechanism and
|
|
21
|
+
always wins), and a new machine-level **default workspace** answers for
|
|
22
|
+
directories no binding covers. Onboarding asks you to pick one; later it's
|
|
23
|
+
`vitrinka config default`.
|
|
24
|
+
- **Path-prefix workspace rules** — map a folder subtree to a workspace
|
|
25
|
+
(`vitrinka config prefix ~/Work/ClientA acme`); the longest matching rule
|
|
26
|
+
wins, the default workspace is the fallback behind them.
|
|
27
|
+
- **A confirm gate on defaulted writes.** A write from a directory that
|
|
28
|
+
resolved through a prefix rule or the default asks once per directory
|
|
29
|
+
(per workspace) before landing — as a y/N in the CLI, and as a structured
|
|
30
|
+
`workspace_confirm_required` re-call for MCP agents. `vitrinka config
|
|
31
|
+
writes auto` turns the asking off; explicit bindings never ask.
|
|
32
|
+
- `vitrinka doctor` shows a `default workspace` row, and the dashboard shows
|
|
33
|
+
the resolved workspace with its provenance.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
- Re-running `install` no longer removes a healthy registration at a scope it
|
|
37
|
+
is not rewriting — committed `.mcp.json` entries survive the global-first
|
|
38
|
+
migration untouched.
|
|
39
|
+
|
|
40
|
+
## 3.1.0 — 2026-08-23
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- **`vitrinka mcp` — MCP registrations no longer carry your token.** The entry
|
|
44
|
+
every client now gets is the same three words in every repo
|
|
45
|
+
(`command: vitrinka, args: ["mcp"]`), with no URL and no credential in it.
|
|
46
|
+
The command resolves the deployment, workspace, token and operator at
|
|
47
|
+
request time, from the repo's committed binding and your OS keychain. That
|
|
48
|
+
makes `.mcp.json` safe to commit — so a clone is born registered — and it
|
|
49
|
+
gives Codex per-repo workspace routing its global, header-less registry
|
|
50
|
+
could never express.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
- **`vitrinka install` rewrites a legacy token-bearing registration** wherever
|
|
54
|
+
it finds one — either Claude scope, or Codex's `config.toml` — and tells you
|
|
55
|
+
to commit the now secret-free `.mcp.json` alongside `project.json`.
|
|
56
|
+
- **`vitrinka doctor` names a credential in a config file for what it is**,
|
|
57
|
+
per file (`.mcp.json`, `.claude.json`, `config.toml`), with `vitrinka
|
|
58
|
+
install` as the repair. It also names a registration that predates the
|
|
59
|
+
forwarder instead of showing it green.
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
- A repo whose `.vitrinka/project.json` cannot be read no longer falls back to
|
|
63
|
+
the default deployment — it refuses and names the file to repair, instead of
|
|
64
|
+
quietly publishing to the wrong install.
|
|
65
|
+
- A locked or unreadable credential store is reported as itself, not as a
|
|
66
|
+
generic 401 from the server, and unlocking it heals the running session
|
|
67
|
+
without relaunching the client.
|
|
68
|
+
- The forwarder no longer outlives the client that launched it: closing the
|
|
69
|
+
pipe ends in-flight work after a short grace, and a stalled handshake can no
|
|
70
|
+
longer hold the process open.
|
|
71
|
+
|
|
72
|
+
## 3.0.2 — 2026-08-22
|
|
73
|
+
|
|
74
|
+
### Added
|
|
75
|
+
- **Workspace bindings travel with the repo.** `vitrinka config bind` now
|
|
76
|
+
writes a committed `.vitrinka/project.json` (per deployment, so on-prem
|
|
77
|
+
coexists) — clone a bound repo on any machine and it is bound at checkout.
|
|
78
|
+
The machine config remains as credentials + fallback.
|
|
79
|
+
- **`vitrinka install` self-heals multi-workspace setups**: writes the
|
|
80
|
+
committed binding from a machine-only one, narrows an old wholesale
|
|
81
|
+
`.vitrinka/` ignore so the binding can reach git, and re-registers the
|
|
82
|
+
Claude MCP entry project-scope when it predates workspace baking.
|
|
83
|
+
- **`vitrinka doctor` explains multi-workspace problems**: binding source
|
|
84
|
+
(committed vs machine-only), ignore rules hiding the binding, and stale MCP
|
|
85
|
+
registrations — each row names the repair.
|
|
86
|
+
|
|
87
|
+
### Changed
|
|
88
|
+
- Working in several workspaces on one machine no longer needs per-repo
|
|
89
|
+
header surgery: the server now also resolves the workspace from the
|
|
90
|
+
project a call names, and refuses (with the fix spelled out) instead of
|
|
91
|
+
guessing when the answer is ambiguous.
|
|
92
|
+
|
|
93
|
+
## 3.0.1 — 2026-08-22
|
|
94
|
+
|
|
95
|
+
### Changed
|
|
96
|
+
- **Hosted Vitrinka now lives at `vitrinka.ai`.** New installs, MCP setup,
|
|
97
|
+
desktop/Snap defaults, share links, and generated config schemas use the new
|
|
98
|
+
domain. Existing credentials and workspace bindings stored for
|
|
99
|
+
`vitrinka.in` continue to work during the compatibility window.
|
|
100
|
+
|
|
101
|
+
## 3.0.0 — 2026-08-18
|
|
102
|
+
|
|
103
|
+
The CLI is now a **compiled Go binary**. `@lovinka/vitrinka` is a thin npm
|
|
104
|
+
launcher: it resolves the per-platform binary package for your machine and
|
|
105
|
+
execs it. Same commands, same flags, same config files — no Node runtime
|
|
106
|
+
needed to run vitrinka, and startup is instant.
|
|
107
|
+
|
|
108
|
+
### Changed
|
|
109
|
+
- **`vitrinka` is Go.** Source moved from `pkg/src/cli.ts` to `cmd/vitrinka` +
|
|
110
|
+
`internal/cli/*` in the vitrinka repo. The npm package ships `bin/vitrinka.js`,
|
|
111
|
+
which launches the binary from `@lovinka/vitrinka-<platform>-<arch>`
|
|
112
|
+
(declared as optionalDependencies, resolved by npm from whatever registry
|
|
113
|
+
you already use — no postinstall download, works offline and behind proxies).
|
|
114
|
+
- Installing with `--omit=optional` / `--no-optional` skips the binary by
|
|
115
|
+
design; the launcher says exactly which platform package is missing.
|
|
116
|
+
|
|
117
|
+
### Removed
|
|
118
|
+
- **The `vitrinka-mcp` bin is gone.** The stdio MCP server is retired in favor
|
|
119
|
+
of the server's remote endpoint. Re-register once:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
claude mcp remove vitrinka
|
|
123
|
+
claude mcp add --scope user --transport http vitrinka https://vitrinka.ai/mcp \
|
|
124
|
+
--header "Authorization: Bearer $(vitrinka token)"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`vitrinka install` / `vitrinka doctor --fix` do this for you (Claude Code and
|
|
128
|
+
Codex both).
|
|
129
|
+
- **The unattended fallback worker (`vitrinka-mcp work`) is gone.** `vitrinka
|
|
130
|
+
watch` plus the native background monitor armed by the `listen` skill is the
|
|
131
|
+
one listening lane now.
|
|
132
|
+
- The `mcp/server.ts`, `mcp/work.ts` and `mcp/index.ts` repo shims are deleted —
|
|
133
|
+
a repo checkout no longer registers an stdio MCP; point at `/mcp` instead.
|
|
134
|
+
|
|
135
|
+
## Unreleased (pre-3.0.0 — TypeScript CLI, never published)
|
|
136
|
+
|
|
137
|
+
### Removed
|
|
138
|
+
- **Claude Code UI wiring is gone.** The `install-claude` command, the
|
|
139
|
+
`[Y/n]` install step and the `--claude`/`--no-claude` flags were removed —
|
|
140
|
+
the statusline extension and the 🧷 board / ⧉ app footer badges never worked
|
|
141
|
+
well. `install`/`update`/`uninstall` now actively strip the old wiring from
|
|
142
|
+
`~/.claude/settings.json` (restoring your original `statusLine.command`).
|
|
143
|
+
|
|
144
|
+
### Added
|
|
145
|
+
- **Consent-gated project indexes.** `setup-project` and `index configure` now
|
|
146
|
+
create a repo-owned `vitrinka.config.json`, with extension presets, a recursive
|
|
147
|
+
tri-state directory picker, strict ignore layers, exact-manifest preview, and
|
|
148
|
+
per-machine approval. `index status`, `--dry-run`, and `--explain <path>` make
|
|
149
|
+
the resulting policy auditable.
|
|
150
|
+
- **Workspaces follow the project, not the token.** `vitrinka login` now
|
|
151
|
+
mints a USER-LEVEL token that acts as you in every workspace you're a
|
|
152
|
+
member of; each repo binds to its own workspace (`vitrinka use`, an
|
|
153
|
+
indexed table you answer by number — or automatically when exactly one of
|
|
154
|
+
your workspaces has the project). Commands in an unbound repo stop with
|
|
155
|
+
the same table and the fix command, so an agent asks you instead of
|
|
156
|
+
writing into the wrong workspace. Workspace-pinned tokens keep working
|
|
157
|
+
but are deprecated — doctor and `vitrinka update` nag to re-login.
|
|
158
|
+
Per-project Claude MCP registrations bake the workspace in as an
|
|
159
|
+
`X-Vitrinka-Workspace` header.
|
|
160
|
+
- **`vitrinka logout`** revokes this machine's token server-side
|
|
161
|
+
(`DELETE /api/v1/me/tokens/current`) and removes the local file; your
|
|
162
|
+
user-level tokens are listable and individually revocable via
|
|
163
|
+
`GET`/`DELETE /api/v1/me/tokens[/{id}]` — a lost laptop has an answer.
|
|
164
|
+
- **Semantic artifacts.** `artifact-init` now scaffolds a `doc.json` you author
|
|
165
|
+
plus a fixed shell rendered by the server-owned kit-3 — palette, type,
|
|
166
|
+
spacing, light/dark and the design direction (editorial · dossier · terminal
|
|
167
|
+
· gallery) come from the kit, and artifacts follow the viewer's theme
|
|
168
|
+
automatically. `artifact-from-set` composes the doc (sections + shot
|
|
169
|
+
figures) the same way. The full-HTML escape hatch lives on as
|
|
170
|
+
`artifact-init --custom`, now themed by default.
|
|
171
|
+
- `push` warns when a hand-authored `index.html` carries HTML entities inside
|
|
172
|
+
template literals (`→` renders literally under htm — write `→`).
|
|
173
|
+
- Findings carry their proof: `status` (verification chip), `cause`, `summary`
|
|
174
|
+
(the bold conclusion) and `evidence` (mono receipt footer citing the exact
|
|
175
|
+
log/file/check) joined the finding block.
|
|
176
|
+
- **Codex MCP registration.** `vitrinka install` now offers to register the
|
|
177
|
+
remote MCP for Codex too (writes `[mcp_servers.vitrinka]` +
|
|
178
|
+
`http_headers` into `$CODEX_HOME/config.toml`), `vitrinka doctor --fix`
|
|
179
|
+
repairs it, and `vitrinka uninstall` removes it. Doctor/install rows are now
|
|
180
|
+
`mcp·claude` / `mcp·codex`. Skills already shipped to Codex via the plugin;
|
|
181
|
+
the MCP was the missing half.
|
|
182
|
+
|
|
183
|
+
### Fixed
|
|
184
|
+
- `vitrinka tag` read option VALUES as positionals, so
|
|
185
|
+
`tag add b1 auth --actor alice` sent `["auth", "alice"]` as tag names — and
|
|
186
|
+
tags autocreate, so routine invocations silently minted junk tags. A flag
|
|
187
|
+
placed before the verb (`tag --actor x add …`) also fell through to the `ls`
|
|
188
|
+
default. Both now come from the shared `positionals()` parse the rest of the
|
|
189
|
+
CLI already uses.
|
|
190
|
+
|
|
191
|
+
### Changed
|
|
192
|
+
- Project indexes are path-only v2 manifests. The CLI no longer reads or sends
|
|
193
|
+
source excerpts, absolute paths, origin remotes, home-directory commands, or
|
|
194
|
+
command descriptions. Missing/disabled/changed policies fail closed; tracked
|
|
195
|
+
`.gitignore` matches, credential/key names, and binary/generated paths are
|
|
196
|
+
denied client-side and again by the server. Deploying this release purges all
|
|
197
|
+
legacy index rows once.
|
|
198
|
+
- **`tag merge` and `tag drop` now REFUSE without a TTY unless `--yes` is
|
|
199
|
+
given** (exit 2). They previously treated "no TTY to ask on" as approval, so
|
|
200
|
+
they ran unconfirmed in scripts, CI and any redirected shell — `drop`
|
|
201
|
+
detaches the tag from every board, card and session. **If you script either
|
|
202
|
+
verb, add `--yes`.**
|
|
203
|
+
|
|
204
|
+
## 1.21.2 — 2026-07-26
|
|
205
|
+
|
|
206
|
+
### Added
|
|
207
|
+
- `vitrinka doctor` reports listener leases held by dead watch processes on this
|
|
208
|
+
machine, and `vitrinka doctor --fix` releases them.
|
|
209
|
+
- `vitrinka extension setup | update | doctor` — install the journey-recorder
|
|
210
|
+
browser extension from the CLI and keep it current. Updates now happen in
|
|
211
|
+
place: the popup's "update available" banner is a button that has the CLI
|
|
212
|
+
download, checksum-verify and swap the release, then reloads the extension
|
|
213
|
+
into it. `--check` reports without installing; `doctor --fix` re-registers the
|
|
214
|
+
native-messaging host after a CLI reinstall moves `node` or the CLI.
|
|
215
|
+
- The extension takes its base URL and token from this machine's CLI config on
|
|
216
|
+
first load, so a fresh install needs no pasting (the options page gains a
|
|
217
|
+
"Fill from the vitrinka CLI" override). Existing settings are never replaced.
|
|
218
|
+
- **Migrating a hand-unzipped copy:** the extension now pins its id, so the
|
|
219
|
+
CLI-managed folder is a *different* extension to Chrome. Run
|
|
220
|
+
`vitrinka extension setup`, load `~/.config/vitrinka/extension`, and remove
|
|
221
|
+
the old card — a token you pasted by hand does not carry over.
|
|
222
|
+
|
|
223
|
+
### Changed
|
|
224
|
+
- `vitrinka install` now detects the Chromium browsers on the machine and offers
|
|
225
|
+
the recorder as a step (`--extension` / `--no-extension`), so re-running it on
|
|
226
|
+
an already-onboarded machine is how you backfill the extension. An install
|
|
227
|
+
that already has it silently re-registers the update host, which is also how a
|
|
228
|
+
browser added since the last run starts working. `vitrinka update` keeps an
|
|
229
|
+
installed extension current, and the update host is registered for the
|
|
230
|
+
browsers detected on the machine (falling back to all of them when none is
|
|
231
|
+
detected, so a fresh box still gets a working host) — so `extension doctor`
|
|
232
|
+
can now tell you the browser you *use* is unregistered instead of counting
|
|
233
|
+
four blind writes.
|
|
234
|
+
|
|
235
|
+
### Fixed
|
|
236
|
+
- A listener could outlive the session that armed it and hold its board's lease
|
|
237
|
+
**forever**. Claude Code signals the wrapper shell it spawned, so the watch
|
|
238
|
+
underneath never got the SIGTERM — it was adopted by init and kept renewing
|
|
239
|
+
its lease, which the TTL cannot reap (the TTL only reaps leases that stop
|
|
240
|
+
heartbeating). Annotations dispatched on that board then vanished into a
|
|
241
|
+
process nobody was reading. Three fixes: `/vitrinka:listen` now arms
|
|
242
|
+
`exec vitrinka watch` so the watch *is* the signalled process; `vitrinka
|
|
243
|
+
watch` self-terminates if it is ever orphaned, covering exits that deliver no
|
|
244
|
+
signal at all (agent SIGKILLed, crashed, terminal closed); and it now handles
|
|
245
|
+
SIGHUP alongside SIGINT/SIGTERM.
|
|
246
|
+
- Release integrity is fail-closed: a feed without a usable SHA-256, or an
|
|
247
|
+
artifact larger than it advertised, is refused before anything is downloaded
|
|
248
|
+
or swapped. Previously the checksum was only verified when the field happened
|
|
249
|
+
to be present, and the whole body was buffered unbounded.
|
|
250
|
+
|
|
251
|
+
## 1.21.1 — 2026-07-25
|
|
252
|
+
|
|
253
|
+
### Fixed
|
|
254
|
+
- `/vitrinka:brainstorming` sometimes skipped the decision map — the map was
|
|
255
|
+
reasoned out but never written, so the round opened straight into a "anything
|
|
256
|
+
to cut, add, or reorder?" picker whose options referenced decisions you could
|
|
257
|
+
not see anywhere, expanded output included. The map is now printed as its own
|
|
258
|
+
message before any question is asked, and the board-mode exemption from
|
|
259
|
+
printing it only applies once a board actually exists.
|
|
260
|
+
|
|
261
|
+
## 1.21.0 — 2026-07-25
|
|
262
|
+
|
|
263
|
+
### Added
|
|
264
|
+
- MCP `get_session` — one recorded testing session as a compact digest (the
|
|
265
|
+
screen walk, issues deduped across steps with live board status, per-route
|
|
266
|
+
web vitals, and facets to group them into fix batches). Address it by session
|
|
267
|
+
id or by the session's board slug. Use it instead of walking raw `/events`.
|
|
268
|
+
|
|
269
|
+
### Changed
|
|
270
|
+
- Closing a session no longer waits for its board. The server builds the board
|
|
271
|
+
on a worker and reports `projection` state, so a stop returns immediately —
|
|
272
|
+
and a recording session's board is now kept live as you test, rather than
|
|
273
|
+
only existing once the session ends. Anything reading `projectionError` off a
|
|
274
|
+
stop response should read `projection.state` instead.
|
|
275
|
+
|
|
276
|
+
## 1.20.0 — 2026-07-23
|
|
277
|
+
|
|
278
|
+
### Changed
|
|
279
|
+
- All output now lives under one `.vitrinka/` home in the target repo:
|
|
280
|
+
`.vitrinka/screenshots/` (was `.screenshots/`), `.vitrinka/artifacts/<slug>/`
|
|
281
|
+
(was `.artifacts/`), plus `.vitrinka/scratch/<topic>/` as the sanctioned spot
|
|
282
|
+
for ad-hoc session output. Legacy roots auto-migrate the first time a command
|
|
283
|
+
touches them; explicit `--root`/`--from` paths are respected as given.
|
|
284
|
+
|
|
285
|
+
### Added
|
|
286
|
+
- `vitrinka tidy [--yes] [--all]` — report-first sweep of legacy roots and
|
|
287
|
+
shot-shaped repo-root litter (`.screenshots-<topic>/`, loose `shot-*.png`)
|
|
288
|
+
into `.vitrinka/`; `--all` also moves loose images and `.aud_*` text litter.
|
|
289
|
+
Git-tracked files are never touched.
|
|
290
|
+
- Plugin skills `/vitrinka:annotations` + `/vitrinka:answers` — manual MCP
|
|
291
|
+
fallback drains for when a "Send to Claude" dispatch doesn't reach the
|
|
292
|
+
session (annotation work queue / durable question answers).
|
|
293
|
+
|
|
294
|
+
## 1.19.0 — 2026-07-23
|
|
295
|
+
|
|
296
|
+
### Added
|
|
297
|
+
- `vitrinka setup-project` — the repo onboarding wizard (clack-styled TUI, the
|
|
298
|
+
pkg's first runtime deps: `@clack/prompts` + `picocolors`). One front door for
|
|
299
|
+
everything a repo needs before the editor and board @ autocomplete work:
|
|
300
|
+
machine-install gate (offers `install` inline when the machine isn't
|
|
301
|
+
onboarded), project name + registry record, file/route index push (verified),
|
|
302
|
+
component-index with auto-detected candidate dirs, desktop-app check, and an
|
|
303
|
+
optional hello board. Status-first and idempotent — re-runs refresh the cheap
|
|
304
|
+
bits and only prompt for what's missing; `--yes`/non-TTY takes every default.
|
|
305
|
+
- `edit` and `status` print a one-line hint toward `vitrinka setup-project`
|
|
306
|
+
while the repo has never been indexed.
|
|
307
|
+
|
|
308
|
+
## 1.18.0 — 2026-07-21
|
|
309
|
+
|
|
310
|
+
### Added
|
|
311
|
+
- `vitrinka edit [path]` — focus the resident Vitrinka.app editor on a file or
|
|
312
|
+
project via the `vitrinka://edit?path=…` deep link (`--print` emits only the
|
|
313
|
+
URL; when the app isn't installed it prints an install hint). The instant
|
|
314
|
+
editor's CLI entry point.
|
|
315
|
+
- Automatic project registry: `edit`, `status`, `watch`, and `board-from-set`
|
|
316
|
+
now record `{project → main-worktree path}` to
|
|
317
|
+
`~/.config/vitrinka/projects.json` as a side effect, so the desktop editor
|
|
318
|
+
auto-discovers your live checkouts with zero extra UX. Best-effort — a write
|
|
319
|
+
failure never breaks the command.
|
|
320
|
+
- `compose_board` accepts kind `"artifact"` — a sandboxed self-contained HTML
|
|
321
|
+
card straight from a compose batch: `{html}` full document or
|
|
322
|
+
`{body, runtime: "tw4"}` markup-only (server inlines the Tailwind v4
|
|
323
|
+
runtime; dramatically cheaper). Up to 8 MiB inline.
|
|
324
|
+
|
|
325
|
+
### Changed
|
|
326
|
+
- `compose_board`'s card schema is slim: the tool description now carries the
|
|
327
|
+
kind index + quick shapes only; per-kind payload contracts live in the
|
|
328
|
+
vitrinka plugin skills (the publish skill's `references/card-kinds.md` is
|
|
329
|
+
the index). Unknown kinds still 400 with the full allowed list.
|
|
330
|
+
- `vitrinka import` (and `POST /import`) replies with a compact per-card
|
|
331
|
+
summary (`{id, elemNo, kind, title, counts, section?}`); pass `--verbose`
|
|
332
|
+
(API: `?verbose=1`) for the full card JSON.
|
|
333
|
+
|
|
334
|
+
## 1.17.0 — 2026-07-20
|
|
335
|
+
|
|
336
|
+
### Added
|
|
337
|
+
- `get_questions` MCP tool — durable post-send retrieval of a board's answered
|
|
338
|
+
decisions (options, notes, ⌖ refs). Choices ride the work wire exactly once,
|
|
339
|
+
so a send with no listening session used to look unrecoverable; now any
|
|
340
|
+
session can re-read the full answer record at any time.
|
|
341
|
+
- `scrape_board` digest now carries a compact `questions[]`
|
|
342
|
+
(`{id, prompt, answer?, note?, staged?}`) — one call reads the decision
|
|
343
|
+
state alongside cards/flow/sections; section scopes keep only their own.
|
|
344
|
+
- `vitrinka watch` keepalive: while a human actually has the board open, the
|
|
345
|
+
leased watch emits a quiet `· keepalive` heartbeat (default every 3000 s,
|
|
346
|
+
`--keepalive 0` off) so the listening session's prompt cache stays warm and
|
|
347
|
+
the next annotation lands cheap. An abandoned board costs nothing.
|
|
348
|
+
|
|
349
|
+
## 1.16.0 — 2026-07-19
|
|
350
|
+
|
|
351
|
+
### Added
|
|
352
|
+
- Listener takeover is automatic on the same machine — arming `vitrinka watch`
|
|
353
|
+
for a scope another of YOUR sessions already holds displaces the older
|
|
354
|
+
listener (its in-flight items go back to the queue) instead of failing with
|
|
355
|
+
a 409 and a manual handoff. The displaced watch prints one stand-down line
|
|
356
|
+
and exits cleanly. Live leases on a *different* machine still refuse the
|
|
357
|
+
claim; `--takeover` still steals expired leases only.
|
|
358
|
+
|
|
359
|
+
### Fixed
|
|
360
|
+
- `vitrinka watch` and the background daemon no longer swallow answered
|
|
361
|
+
brainstorm choices — a pure choice batch used to be drained by the notifier
|
|
362
|
+
and marked delivered while the listening session never woke. Notifier lanes
|
|
363
|
+
now peek without consuming, and watch announces each answer as a
|
|
364
|
+
`№<id> [choice]` line; the acting lane keeps exactly-once delivery.
|
|
365
|
+
|
|
366
|
+
## 1.15.1 — 2026-07-18
|
|
367
|
+
|
|
368
|
+
### Added
|
|
369
|
+
- `vitrinka version` (and `--version`/`-V` for the bare number) — the installed
|
|
370
|
+
version, where it runs from (repo checkout / bun / pnpm / npm install), and
|
|
371
|
+
the last known update state from the notifier cache. No network, instant.
|
|
372
|
+
|
|
373
|
+
### Fixed
|
|
374
|
+
- `vitrinka update` now updates through the package manager that OWNS the
|
|
375
|
+
running copy (bun / pnpm / npm, detected from the executable's path) and
|
|
376
|
+
verifies the running file actually changed — a bun-installed CLI used to
|
|
377
|
+
`npm i -g` into a shadowed prefix and stay stale forever, and update warns
|
|
378
|
+
loudly when another install still shadows it on PATH.
|
|
379
|
+
|
|
380
|
+
## 1.15.0 — 2026-07-18
|
|
381
|
+
|
|
382
|
+
### Added
|
|
383
|
+
- Update notifier v2 — the daily detached check now asks YOUR vitrinka server
|
|
384
|
+
first (new `GET /api/v1/version`: a deploy announces the version, works on
|
|
385
|
+
the mesh with npm unreachable) and falls back to the npm registry. Agent
|
|
386
|
+
shells (non-TTY — an AI session driving the CLI) see the
|
|
387
|
+
`update available … · run: vitrinka update` line on every run so the session
|
|
388
|
+
can offer the update; interactive terminals see it at most once a day.
|
|
389
|
+
|
|
390
|
+
## 1.14.0 — 2026-07-18
|
|
391
|
+
|
|
392
|
+
### Added
|
|
393
|
+
- `compose_board` question options accept **`cardRef`** — trace an option to a
|
|
394
|
+
card created in the SAME compose batch (template + inline cards share one ref
|
|
395
|
+
space), so a decision map and its per-option architecture diagrams land in
|
|
396
|
+
ONE call. `cardId` still traces to existing cards; picking flies only on
|
|
397
|
+
⌘-click now (plain click just stages the answer).
|
|
398
|
+
- The built-in **`decision-map`** template is documented on `compose_board`:
|
|
399
|
+
structured params `{title, context, decisions:[{key, title, stakes, options,
|
|
400
|
+
multiSelect?, kind?: "text"}]}` render the whole brainstorm map — a
|
|
401
|
+
width-filling grid of merged decision tiles — deterministically server-side.
|
|
402
|
+
|
|
403
|
+
## 1.13.0 — 2026-07-17
|
|
404
|
+
|
|
405
|
+
### Added
|
|
406
|
+
- `vitrinka import <file>` + `vitrinka schema push` — refreshable ground-truth
|
|
407
|
+
diagrams from docker-compose / OpenAPI / SQL DDL / a live Postgres;
|
|
408
|
+
`--section` lands them inside a journey frame, `--rev` stamps the git SHA.
|
|
409
|
+
- Journey branch capture: `snap --next/--target` groups + journey-from-set.
|
|
410
|
+
- Unified **publish** skill (session · journey · docs · board · artifact).
|
|
411
|
+
- `compose_board` edges accept `fromRegion`/`toRegion`; `arrange` gains a
|
|
412
|
+
journey mode.
|
|
413
|
+
|
|
414
|
+
### Fixed
|
|
415
|
+
- `add --file` hardened (out-of-root copies, symlinks, non-regular files);
|
|
416
|
+
`push` guards against a huge `--root` and reports tar failures legibly.
|
|
417
|
+
- `doctor` no longer health-checks every Claude MCP server.
|
|
418
|
+
|
|
419
|
+
## 1.11.0 — 2026-07-15
|
|
420
|
+
|
|
421
|
+
### Added
|
|
422
|
+
- `vitrinka upload <files…> --board <slug>` — put PDFs, documents, and images
|
|
423
|
+
on a board as cards straight from disk (the bytes never pass through an AI
|
|
424
|
+
context). PDFs land as live embedded document cards, other files as download
|
|
425
|
+
chips. Placement is intent-based: `--section "Name"` lands inside a journey
|
|
426
|
+
frame (grows to fit), `--anchor <cardId> [--side right|below]` docks beside a
|
|
427
|
+
card, and no flag = server free placement (never a 0,0 pile).
|
|
428
|
+
|
|
429
|
+
## 1.10.1 — 2026-07-13
|
|
430
|
+
|
|
431
|
+
### Changed
|
|
432
|
+
- Canonical domain is now **vitrinka.in** — the CLI/MCP default base URL,
|
|
433
|
+
skills and docs all point there. vitrinka.lovinka.com keeps working as an
|
|
434
|
+
alias; override per-machine with `VITRINKA_URL` as before. Re-run
|
|
435
|
+
`vitrinka install` (or `doctor --fix`) to re-register MCP on the new host.
|
|
436
|
+
|
|
437
|
+
## 1.10.0 — 2026-07-13
|
|
438
|
+
|
|
439
|
+
### Added
|
|
440
|
+
- `compose_board` question options accept `cardId` — the board draws a trace
|
|
441
|
+
wire from the option to the card it names, hovering glows it, and picking
|
|
442
|
+
flies the camera there. Pair it with the new `POST /artifact` params
|
|
443
|
+
(`section`, `device`, `anchor`/`side`): mockups land inside their take's
|
|
444
|
+
section frame, sized by device intent, and scale to fit their card
|
|
445
|
+
automatically (server-measured natural size).
|
|
446
|
+
|
|
447
|
+
## 1.9.0 — 2026-07-12
|
|
448
|
+
|
|
449
|
+
### Changed
|
|
450
|
+
- MCP registration moved to the remote `/mcp` endpoint (streamable HTTP) —
|
|
451
|
+
no local stdio process per session; `vitrinka install`/`doctor --fix`
|
|
452
|
+
re-register automatically. The old stdio bin is deprecated.
|
|
453
|
+
|
|
454
|
+
## 1.8.3 — 2026-07-11
|
|
455
|
+
|
|
456
|
+
### Fixed
|
|
457
|
+
- Interactive prompts (`install`'s operator question, any `promptLine`) strip
|
|
458
|
+
ANSI escape sequences and control characters — arrow-key edits no longer
|
|
459
|
+
persist raw `ESC[D`/`ESC[C` bytes into the operator name (which every fresh
|
|
460
|
+
browser adopted as its board identity). `vitrinka operator <name>` sanitizes
|
|
461
|
+
the same way, and the server now rejects control characters with 422.
|
|
462
|
+
|
|
463
|
+
## 1.8.2 — 2026-07-11
|
|
464
|
+
|
|
465
|
+
### Added
|
|
466
|
+
- Desktop-app flag: `~/.config/vitrinka/desktop-app` is the one canonical
|
|
467
|
+
"is Vitrinka.app installed" answer (content = app path). Stamped by
|
|
468
|
+
`apps/desktop make install`, re-synced by `install-claude` and `doctor`.
|
|
469
|
+
- `install-claude` adds a second **⧉ app** footer badge (only when the app is
|
|
470
|
+
installed) whose `vitrinka://` deep link opens the board in Vitrinka.app.
|
|
471
|
+
- `vitrinka open` opens the board in Vitrinka.app when installed;
|
|
472
|
+
`--browser` forces the browser.
|
|
473
|
+
|
|
474
|
+
## 1.8.1 — 2026-07-11
|
|
475
|
+
|
|
476
|
+
### Added
|
|
477
|
+
- `install-claude` now also wires a `SessionStart` hook
|
|
478
|
+
(`~/.claude/hooks/vitrinka-board-link.sh`) that puts the repo's live board
|
|
479
|
+
URL into session context at start — the clickable 🧷 footer badge exists
|
|
480
|
+
from message one instead of waiting for a board URL to be mentioned.
|
|
481
|
+
`vitrinka doctor` reports (and `--fix` repairs) the hook; `uninstall`
|
|
482
|
+
removes it.
|
|
483
|
+
|
|
484
|
+
## 1.8.0 — 2026-07-11
|
|
485
|
+
|
|
486
|
+
### Changed
|
|
487
|
+
- Skills now distribute EXCLUSIVELY as the vitrinka plugin — for Claude Code
|
|
488
|
+
(`claude plugin install vitrinka@lovinka`) AND Codex (`codex plugin add
|
|
489
|
+
vitrinka`), both from the `LEFTEQ/vitrinka` marketplace. `vitrinka install`,
|
|
490
|
+
`doctor --fix` and `update` install/refresh the plugin in every runtime CLI
|
|
491
|
+
they find; the npm package no longer bundles the skills.
|
|
492
|
+
- Skills layout flattened: `listen` is a first-class skill
|
|
493
|
+
(`/vitrinka:listen` in Claude Code, `$listen` in Codex).
|
|
494
|
+
|
|
495
|
+
### Removed
|
|
496
|
+
- `vitrinka install-skills` — superseded by the plugin. `vitrinka uninstall`
|
|
497
|
+
still clears legacy `~/.claude/skills` copies from pre-plugin machines.
|
|
498
|
+
|
|
499
|
+
## 1.6.0 — 2026-07-08
|
|
500
|
+
|
|
501
|
+
### Added
|
|
502
|
+
- `vitrinka update` — updates the CLI (git pull in a checkout, `npm i -g` when
|
|
503
|
+
behind the registry), prints what's new, and refreshes the installed skills
|
|
504
|
+
and Claude UI wiring.
|
|
505
|
+
- Status-first onboarding: `vitrinka install` now prints a ✓/✗ setup table and
|
|
506
|
+
handles everything install.sh used to (MCP registration, write token,
|
|
507
|
+
operator persona, env checks) — asking only for what's missing.
|
|
508
|
+
- `vitrinka uninstall [--purge]` — clean offboarding (skills, shim, completion,
|
|
509
|
+
Claude wiring, MCP registration; `--purge` also removes token + operator).
|
|
510
|
+
- `vitrinka doctor --fix` — repairs stale skills, a stale/missing shim, a lost
|
|
511
|
+
MCP registration, and the Claude UI wiring.
|
|
512
|
+
- `vitrinka open [--qr]` — opens the capture root's live board; `--qr` renders
|
|
513
|
+
a terminal QR code to scan with the iPad.
|
|
514
|
+
- `vitrinka status` — session dashboard: live board, open work queue, and the
|
|
515
|
+
listener lease for the current repo+branch.
|
|
516
|
+
- Passive update notifier (one dim line, cached daily, npm installs only) and a
|
|
517
|
+
first-run hint on fully unconfigured machines.
|
|
518
|
+
|
|
519
|
+
### Removed
|
|
520
|
+
- `install.sh` — the CLI is the installer now: `vitrinka install` (or
|
|
521
|
+
`node pkg/src/cli.ts install` from a checkout).
|
|
522
|
+
|
|
523
|
+
## 1.5.0 — 2026-07-08
|
|
524
|
+
|
|
525
|
+
- project-memory MCP tools + link/board compose vocabulary (pre-changelog release).
|
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# @vitrinka/cli
|
|
2
|
+
|
|
3
|
+
The [vitrinka](https://github.com/FixIt-Technologies/vitrinka) CLI — capture
|
|
4
|
+
screenshots, publish artifact **sets**, scaffold interactive artifacts, and arm
|
|
5
|
+
the annotation-board `watch` monitor that feeds work to a listening AI session.
|
|
6
|
+
|
|
7
|
+
Since **3.0.0** the CLI is a compiled **Go binary**. This npm package is the
|
|
8
|
+
launcher: `bin/vitrinka.js` resolves the binary for your platform and execs it.
|
|
9
|
+
The binary arrives through per-platform packages declared as
|
|
10
|
+
`optionalDependencies` (`@vitrinka/cli-darwin-arm64` and friends), so npm
|
|
11
|
+
fetches it from whatever registry your machine already uses — no postinstall
|
|
12
|
+
download, no network surprise in sandboxed CI or behind a corporate proxy.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm i -g @vitrinka/cli
|
|
18
|
+
vitrinka install # one-command machine setup
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`vitrinka install` IS the onboarding: it prints a ✓/✗ table of every component,
|
|
22
|
+
silently installs the harmless ones (the skills plugin into each runtime CLI it
|
|
23
|
+
finds, a `vitrinka` shim on PATH, shell completion — all reversible), then asks
|
|
24
|
+
`[Y/n]` only for the config-touchers: MCP registration, the write token (silent
|
|
25
|
+
input, → the OS keyring) and the operator name.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
vitrinka doctor # server, token, operator, skills, shim, MCP
|
|
29
|
+
vitrinka doctor --fix # repairs the repairable
|
|
30
|
+
vitrinka update # update the CLI and everything install put here
|
|
31
|
+
vitrinka uninstall # remove it all (--purge: token too)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Installing with `--omit=optional` / `--no-optional` skips the binary by design.
|
|
35
|
+
The launcher then tells you which platform package is missing rather than
|
|
36
|
+
failing as "command not found".
|
|
37
|
+
|
|
38
|
+
## MCP
|
|
39
|
+
|
|
40
|
+
The MCP server is **remote** — it runs inside the vitrinka server, so there is
|
|
41
|
+
nothing to install and nothing to keep up to date. Register it once:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
claude mcp add --scope user --transport http vitrinka https://vitrinka.ai/mcp \
|
|
45
|
+
--header "Authorization: Bearer $(vitrinka token)"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
For Claude Desktop or any other MCP client, add the equivalent HTTP entry:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"mcpServers": {
|
|
53
|
+
"vitrinka": {
|
|
54
|
+
"type": "http",
|
|
55
|
+
"url": "https://vitrinka.ai/mcp",
|
|
56
|
+
"headers": { "Authorization": "Bearer …" }
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
> The stdio `vitrinka-mcp` bin was **removed in 3.0.0**. If you have a
|
|
63
|
+
> registration pointing at `npx -y --package=@vitrinka/cli vitrinka-mcp`
|
|
64
|
+
> (or at a `mcp/server.ts` repo shim), replace it with the HTTP form above —
|
|
65
|
+
> `vitrinka install` and `vitrinka doctor --fix` will do it for you.
|
|
66
|
+
|
|
67
|
+
vitrinka is reachable over the WireGuard mesh — bring the VPN up (or point
|
|
68
|
+
`VITRINKA_BASE_URL` at any reachable host) before use.
|
|
69
|
+
|
|
70
|
+
## Configuration (env)
|
|
71
|
+
|
|
72
|
+
| Var | Default | Purpose |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| `VITRINKA_URL` / `VITRINKA_BASE_URL` | `https://vitrinka.ai` | vitrinka server base URL. `VITRINKA_URL` wins, then `VITRINKA_BASE_URL`; the CLI's `--base` flag overrides both. |
|
|
75
|
+
| `VITRINKA_TOKEN` | — | Bearer write token. Falls back to the OS keyring / `~/.config/vitrinka/`. Required only by the **mutating** calls; read calls work unauthenticated. |
|
|
76
|
+
| `VITRINKA_OPERATOR` | — | Operator persona name. When set, write calls carry `X-Board-Actor: <name>` so the board credits the operator — agent-authored content keeps its explicit `claude` attribution. |
|
|
77
|
+
|
|
78
|
+
## Trustworthy project index
|
|
79
|
+
|
|
80
|
+
`vitrinka setup-project` or `vitrinka index configure` creates the
|
|
81
|
+
repository-owned `vitrinka.config.json`. The interactive picker chooses
|
|
82
|
+
extension groups and any depth of directory tree, then shows the exact file
|
|
83
|
+
manifest before approval. Choosing "later" writes an explicit disabled policy
|
|
84
|
+
and uploads nothing.
|
|
85
|
+
|
|
86
|
+
The index contains repository-relative paths, derived routes, and repository
|
|
87
|
+
command names only — never source bytes, absolute paths, remotes, command
|
|
88
|
+
descriptions, or files from `~/.claude`. `.gitignore` is an unconditional deny
|
|
89
|
+
layer even for tracked files; detected `.claudeignore` is offered as another;
|
|
90
|
+
untracked files require an explicit advanced opt-in; credential/key filenames
|
|
91
|
+
and binary/generated assets are blocked by both client and server safety floors.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
vitrinka index configure # edit, preview, approve, then refresh
|
|
95
|
+
vitrinka index status # policy + local approval/upload receipt
|
|
96
|
+
vitrinka index --dry-run # exact paths, no network request
|
|
97
|
+
vitrinka index --explain path/to/file # winning selection or deny rule
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The config schema is served by the deployment at
|
|
101
|
+
`https://vitrinka.ai/static/vitrinka.config.schema.json` — reference it from
|
|
102
|
+
`$schema` in your `vitrinka.config.json` for editor completion.
|
|
103
|
+
|
|
104
|
+
## Desktop app
|
|
105
|
+
|
|
106
|
+
`~/.config/vitrinka/desktop-app` is the ONE canonical "is Vitrinka.app installed
|
|
107
|
+
here" answer (content = the app path). `apps/desktop`'s `make install` stamps it;
|
|
108
|
+
`doctor` and `setup-project` re-sync it to reality. `vitrinka open` uses it to
|
|
109
|
+
open boards in the app (pass `--browser` to force the browser), and
|
|
110
|
+
`vitrinka edit [path]` focuses the resident app on a file or project.
|
|
111
|
+
|
|
112
|
+
## Development
|
|
113
|
+
|
|
114
|
+
The CLI source lives in the vitrinka repo — `cmd/vitrinka` + `internal/cli/`:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
go build -o /tmp/vitrinka ./cmd/vitrinka
|
|
118
|
+
go test ./internal/cli/...
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
This package carries no implementation; it is the npm front door only.
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
MIT
|
package/bin/vitrinka.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The npm front door for the Go binary (decisions D7 and D12).
|
|
3
|
+
//
|
|
4
|
+
// `npm i -g @vitrinka/cli` and `npx @vitrinka/cli` must keep working
|
|
5
|
+
// exactly as they do today — it is currently the ONLY documented way to install
|
|
6
|
+
// this tool, and every skill, doc and agent instruction says so. So the npm
|
|
7
|
+
// package survives the port; what changes is that it now launches a compiled
|
|
8
|
+
// binary instead of being the implementation.
|
|
9
|
+
//
|
|
10
|
+
// The binary arrives through per-platform packages declared as
|
|
11
|
+
// optionalDependencies (esbuild's pattern), NOT through a postinstall script
|
|
12
|
+
// that downloads one. That distinction is the whole design:
|
|
13
|
+
//
|
|
14
|
+
// - A postinstall download needs network access at install time, which is
|
|
15
|
+
// blocked in sandboxed CI, in air-gapped environments, and behind exactly
|
|
16
|
+
// the corporate proxies decision D13 exists for.
|
|
17
|
+
// - optionalDependencies are resolved by npm itself, so they come from
|
|
18
|
+
// whatever registry the machine is already configured to use — including
|
|
19
|
+
// the bank's internal mirror (D12) — with no extra machinery.
|
|
20
|
+
// - The lockfile records them, so an install is reproducible.
|
|
21
|
+
//
|
|
22
|
+
// npm installs only the optional dependency matching the host platform and
|
|
23
|
+
// silently skips the rest, which is why all of them can be declared at once.
|
|
24
|
+
|
|
25
|
+
const { spawnSync } = require('node:child_process');
|
|
26
|
+
|
|
27
|
+
const WINDOWS = process.platform === 'win32';
|
|
28
|
+
const PKG = `@vitrinka/cli-${process.platform}-${process.arch}`;
|
|
29
|
+
const BIN = `vitrinka${WINDOWS ? '.exe' : ''}`;
|
|
30
|
+
|
|
31
|
+
function resolveBinary() {
|
|
32
|
+
try {
|
|
33
|
+
return require.resolve(`${PKG}/bin/${BIN}`);
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const binary = resolveBinary();
|
|
40
|
+
|
|
41
|
+
if (!binary) {
|
|
42
|
+
// Say which platform package is missing and why it might be. "command not
|
|
43
|
+
// found" here would send someone to debug their PATH, when the real cause is
|
|
44
|
+
// almost always an --omit=optional install or an unsupported platform.
|
|
45
|
+
process.stderr.write(
|
|
46
|
+
`\n vitrinka: no binary for ${process.platform}-${process.arch}\n\n` +
|
|
47
|
+
` The platform package ${PKG} is not installed.\n\n` +
|
|
48
|
+
` Reinstall without omitting optional dependencies\n` +
|
|
49
|
+
` npm install -g @vitrinka/cli\n\n` +
|
|
50
|
+
` If your installer is configured with --omit=optional or\n` +
|
|
51
|
+
` --no-optional, the binary is skipped by design; allow optional\n` +
|
|
52
|
+
` dependencies, or install the platform package directly\n` +
|
|
53
|
+
` npm install -g ${PKG}\n\n`,
|
|
54
|
+
);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// stdio: 'inherit' is LOAD-BEARING, not a default worth changing.
|
|
59
|
+
//
|
|
60
|
+
// The Go CLI decides what to do by asking whether stdin and stdout are
|
|
61
|
+
// terminals: bare `vitrinka` opens the dashboard on a TTY and prints usage
|
|
62
|
+
// otherwise, and every prompt and spinner branches the same way. Piping the
|
|
63
|
+
// child's streams here would make the binary see pipes in every case — so the
|
|
64
|
+
// dashboard would never open for anyone who installed through npm, which is
|
|
65
|
+
// everyone. Inheriting hands the real terminal straight through.
|
|
66
|
+
const result = spawnSync(binary, process.argv.slice(2), { stdio: 'inherit' });
|
|
67
|
+
|
|
68
|
+
if (result.error) {
|
|
69
|
+
process.stderr.write(`\n vitrinka: could not run ${binary}\n ${result.error.message}\n\n`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// A child killed by a signal has a null status. Reporting the conventional
|
|
74
|
+
// 128+signal keeps `vitrinka ... ; echo $?` and CI's failure detection honest;
|
|
75
|
+
// exiting 0 here would make a SIGKILLed run look successful.
|
|
76
|
+
if (result.signal) {
|
|
77
|
+
const SIGNALS = { SIGINT: 2, SIGQUIT: 3, SIGKILL: 9, SIGTERM: 15 };
|
|
78
|
+
process.exit(128 + (SIGNALS[result.signal] || 0));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vitrinka/cli",
|
|
3
|
+
"version": "3.3.0",
|
|
4
|
+
"description": "vitrinka CLI — capture and publish artifact sets, drive the annotation-board work queue. Thin npm launcher for the single-binary Go CLI.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"vitrinka": "bin/vitrinka.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin",
|
|
10
|
+
"README.md",
|
|
11
|
+
"CHANGELOG.md"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18"
|
|
15
|
+
},
|
|
16
|
+
"optionalDependencies": {
|
|
17
|
+
"@vitrinka/cli-darwin-arm64": "3.3.0",
|
|
18
|
+
"@vitrinka/cli-darwin-x64": "3.3.0",
|
|
19
|
+
"@vitrinka/cli-linux-arm64": "3.3.0",
|
|
20
|
+
"@vitrinka/cli-linux-x64": "3.3.0",
|
|
21
|
+
"@vitrinka/cli-win32-arm64": "3.3.0",
|
|
22
|
+
"@vitrinka/cli-win32-x64": "3.3.0"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"vitrinka",
|
|
26
|
+
"lovinka",
|
|
27
|
+
"cli",
|
|
28
|
+
"mcp",
|
|
29
|
+
"model-context-protocol",
|
|
30
|
+
"screenshots",
|
|
31
|
+
"ai"
|
|
32
|
+
],
|
|
33
|
+
"author": "Lovinka",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/FixIt-Technologies/vitrinka.git",
|
|
38
|
+
"directory": "npm/vitrinka"
|
|
39
|
+
}
|
|
40
|
+
}
|