@lovinka/vitrinka 1.7.1 → 1.8.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 +15 -0
- package/dist/cli.js +98 -121
- package/dist/cli.js.map +1 -1
- package/dist/mcp.js +2 -3
- package/dist/mcp.js.map +1 -1
- package/package.json +5 -7
- package/skills/artifact/SKILL.md +0 -82
- package/skills/brainstorming/SKILL.md +0 -107
- package/skills/screenshot/SKILL.md +0 -108
- package/skills/screenshot/gallery.mjs +0 -6
- package/skills/vitrinka/cli.ts +0 -39
- package/skills/vitrinka/commands/listen.md +0 -10
- package/skills/vitrinka/listen/SKILL.md +0 -197
- package/skills/vitrinka/tests/_helpers.ts +0 -108
- package/skills/vitrinka/tests/derive.test.ts +0 -118
- package/skills/vitrinka/tests/dx.test.ts +0 -264
- package/skills/vitrinka/tests/embed.test.ts +0 -96
- package/skills/vitrinka/tests/index.test.ts +0 -250
- package/skills/vitrinka/tests/install-name.test.ts +0 -117
- package/skills/vitrinka/tests/manifest.test.ts +0 -98
- package/skills/vitrinka/tests/operator.test.ts +0 -119
- package/skills/vitrinka/tests/push.test.ts +0 -115
- package/skills/vitrinka/tests/scaffold.test.ts +0 -173
- package/skills/vitrinka/tests/shim.test.ts +0 -28
- package/skills/vitrinka/tests/snap.test.ts +0 -175
- package/skills/vitrinka/tests/watch.test.ts +0 -204
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
3
3
|
`vitrinka update` prints the sections newer than your previous version after
|
|
4
4
|
updating — keep entries short and user-facing.
|
|
5
5
|
|
|
6
|
+
## 1.8.0 — 2026-07-11
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- Skills now distribute EXCLUSIVELY as the vitrinka plugin — for Claude Code
|
|
10
|
+
(`claude plugin install vitrinka@lovinka`) AND Codex (`codex plugin add
|
|
11
|
+
vitrinka`), both from the `LEFTEQ/vitrinka` marketplace. `vitrinka install`,
|
|
12
|
+
`doctor --fix` and `update` install/refresh the plugin in every runtime CLI
|
|
13
|
+
they find; the npm package no longer bundles the skills.
|
|
14
|
+
- Skills layout flattened: `listen` is a first-class skill
|
|
15
|
+
(`/vitrinka:listen` in Claude Code, `$listen` in Codex).
|
|
16
|
+
|
|
17
|
+
### Removed
|
|
18
|
+
- `vitrinka install-skills` — superseded by the plugin. `vitrinka uninstall`
|
|
19
|
+
still clears legacy `~/.claude/skills` copies from pre-plugin machines.
|
|
20
|
+
|
|
6
21
|
## 1.6.0 — 2026-07-08
|
|
7
22
|
|
|
8
23
|
### Added
|
package/dist/cli.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// skills/screenshot/gallery.mjs (offline marker, COPYFILE_DISABLE, control-file excludes,
|
|
11
11
|
// `--key`, repeatable `--chip`). gallery.mjs is now a passthrough shim to this file.
|
|
12
12
|
// Design: vitrinka/docs/plans/2026-07-03-hand-in-hand-tooling-design.md
|
|
13
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync, rmSync, readdirSync, copyFileSync, mkdtempSync, chmodSync, appendFileSync, statSync,
|
|
13
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, rmSync, readdirSync, copyFileSync, mkdtempSync, chmodSync, appendFileSync, statSync, openSync, readSync, closeSync, realpathSync, } from 'node:fs';
|
|
14
14
|
import { join, resolve, basename, dirname, extname, relative, sep } from 'node:path';
|
|
15
15
|
import { tmpdir, hostname } from 'node:os';
|
|
16
16
|
import { spawnSync, spawn } from 'node:child_process';
|
|
@@ -1218,20 +1218,20 @@ async function doctorCmd(args) {
|
|
|
1218
1218
|
console.log(`✓ operator ${op}`);
|
|
1219
1219
|
else
|
|
1220
1220
|
console.log('✗ operator unset — board writes stay anonymous (fix: vitrinka operator <name>)');
|
|
1221
|
-
// Setup surfaces (
|
|
1221
|
+
// Setup surfaces (plugin / shim / MCP / Claude UI) — informational rows, and
|
|
1222
1222
|
// `--fix` repairs everything repairable in place. Token/operator stay manual
|
|
1223
1223
|
// (they're credentials/identity, not installation).
|
|
1224
1224
|
const fix = args.fix === true;
|
|
1225
1225
|
const home = process.env.HOME || '';
|
|
1226
|
-
const
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
if (
|
|
1230
|
-
console.log(
|
|
1231
|
-
else if (fix)
|
|
1232
|
-
|
|
1226
|
+
for (const rt of pluginRuntimes()) {
|
|
1227
|
+
if (!rt.present)
|
|
1228
|
+
continue; // no runtime, nothing to wire
|
|
1229
|
+
if (rt.installed)
|
|
1230
|
+
console.log(`✓ plugin ${rt.name}: vitrinka installed`);
|
|
1231
|
+
else if (fix && installPluginInto(rt))
|
|
1232
|
+
console.log(`✓ plugin ${rt.name}: vitrinka installed`);
|
|
1233
1233
|
else
|
|
1234
|
-
console.log(`✗
|
|
1234
|
+
console.log(`✗ plugin ${rt.name}: not installed — repair: vitrinka doctor --fix`);
|
|
1235
1235
|
}
|
|
1236
1236
|
if (home) {
|
|
1237
1237
|
const shimP = shimPathOf(home);
|
|
@@ -1269,94 +1269,65 @@ async function doctorCmd(args) {
|
|
|
1269
1269
|
process.exit(1);
|
|
1270
1270
|
}
|
|
1271
1271
|
// ---------- install: PATH shim ----------
|
|
1272
|
-
//
|
|
1273
|
-
//
|
|
1274
|
-
//
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
fail('install-skills: $HOME is not set (or pass --local)');
|
|
1295
|
-
const target = local ? resolve('.claude', 'skills') : join(home, '.claude', 'skills');
|
|
1296
|
-
mkdirSync(target, { recursive: true });
|
|
1297
|
-
// Whole directories: a skill may nest its SKILL.md (the vitrinka skill
|
|
1298
|
-
// keeps it under listen/ next to its CLI + tests).
|
|
1299
|
-
const names = readdirSync(bundle).filter((n) => !n.startsWith('.') && statSync(join(bundle, n)).isDirectory());
|
|
1300
|
-
if (!names.length)
|
|
1301
|
-
fail(`install-skills: no skills found in ${bundle}`);
|
|
1302
|
-
for (const n of names) {
|
|
1303
|
-
rmSync(join(target, n), { recursive: true, force: true });
|
|
1304
|
-
cpSync(join(bundle, n), join(target, n), { recursive: true });
|
|
1305
|
-
// Local installs live at ./.claude/skills — keep referenced CLI paths copy-pasteable.
|
|
1306
|
-
if (local) {
|
|
1307
|
-
for (const doc of [join(target, n, 'SKILL.md'), join(target, n, 'listen', 'SKILL.md')]) {
|
|
1308
|
-
if (!existsSync(doc))
|
|
1309
|
-
continue;
|
|
1310
|
-
writeFileSync(doc, readFileSync(doc, 'utf8')
|
|
1311
|
-
.replaceAll('~/.claude/skills/vitrinka/cli.ts', '.claude/skills/vitrinka/cli.ts'));
|
|
1312
|
-
}
|
|
1272
|
+
// ---------- plugin distribution (skills ship via the runtimes' plugin systems) ----------
|
|
1273
|
+
// The skills bundle used to be copied into ~/.claude/skills (install-skills,
|
|
1274
|
+
// REMOVED 2026-07-11). Skills now distribute exclusively as the `vitrinka`
|
|
1275
|
+
// plugin from the `lovinka` marketplace (this repo), installable into BOTH
|
|
1276
|
+
// Claude Code and Codex — one distribution per machine per runtime.
|
|
1277
|
+
const MARKETPLACE_REPO = 'LEFTEQ/vitrinka';
|
|
1278
|
+
// pluginRuntimes probes which agent CLIs exist and whether the vitrinka
|
|
1279
|
+
// plugin is installed in each. Claude records installs in
|
|
1280
|
+
// ~/.claude/plugins/installed_plugins.json; Codex is asked directly
|
|
1281
|
+
// (`codex plugin list` is fast and authoritative across its versions).
|
|
1282
|
+
function pluginRuntimes() {
|
|
1283
|
+
const home = process.env.HOME || '';
|
|
1284
|
+
const out = [];
|
|
1285
|
+
const claudePresent = claudeCliPresent();
|
|
1286
|
+
let claudeInstalled = false;
|
|
1287
|
+
if (claudePresent && home) {
|
|
1288
|
+
try {
|
|
1289
|
+
claudeInstalled = readFileSync(join(home, '.claude', 'plugins', 'installed_plugins.json'), 'utf8')
|
|
1290
|
+
.includes('vitrinka@lovinka');
|
|
1291
|
+
}
|
|
1292
|
+
catch {
|
|
1293
|
+
claudeInstalled = false; // no plugins file yet — nothing installed
|
|
1313
1294
|
}
|
|
1314
|
-
console.log(`✓ ${n} → ${join(target, n)}`);
|
|
1315
1295
|
}
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
mkdirSync(commandsDir, { recursive: true });
|
|
1323
|
-
let content = readFileSync(stub, 'utf8');
|
|
1324
|
-
if (local)
|
|
1325
|
-
content = content.replaceAll('~/.claude/skills/vitrinka/listen/SKILL.md', '.claude/skills/vitrinka/listen/SKILL.md');
|
|
1326
|
-
writeFileSync(join(commandsDir, 'listen.md'), content);
|
|
1327
|
-
console.log(`✓ /vitrinka:listen command → ${join(commandsDir, 'listen.md')}`);
|
|
1296
|
+
out.push({ name: 'claude', present: claudePresent, installed: claudeInstalled });
|
|
1297
|
+
const codexPresent = !spawnSync('codex', ['--version'], { stdio: 'ignore' }).error;
|
|
1298
|
+
let codexInstalled = false;
|
|
1299
|
+
if (codexPresent) {
|
|
1300
|
+
const r = spawnSync('codex', ['plugin', 'list'], { encoding: 'utf8' });
|
|
1301
|
+
codexInstalled = r.status === 0 && /\bvitrinka\b/.test(r.stdout || '');
|
|
1328
1302
|
}
|
|
1329
|
-
|
|
1303
|
+
out.push({ name: 'codex', present: codexPresent, installed: codexInstalled });
|
|
1304
|
+
return out;
|
|
1330
1305
|
}
|
|
1331
|
-
//
|
|
1332
|
-
//
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1306
|
+
// installPluginInto registers the lovinka marketplace and installs the
|
|
1307
|
+
// vitrinka plugin for one runtime. Both runtimes' commands are idempotent
|
|
1308
|
+
// enough for our purposes (marketplace add on an existing source errors —
|
|
1309
|
+
// tolerated; install/add on an installed plugin re-snapshots).
|
|
1310
|
+
function installPluginInto(rt) {
|
|
1311
|
+
const cmds = rt.name === 'claude'
|
|
1312
|
+
? [['claude', 'plugin', 'marketplace', 'add', MARKETPLACE_REPO], ['claude', 'plugin', 'install', 'vitrinka@lovinka']]
|
|
1313
|
+
: [['codex', 'plugin', 'marketplace', 'add', MARKETPLACE_REPO], ['codex', 'plugin', 'add', 'vitrinka@lovinka']];
|
|
1314
|
+
for (const [bin, ...rest] of cmds) {
|
|
1315
|
+
const r = spawnSync(bin, rest, { encoding: 'utf8' });
|
|
1316
|
+
if (r.status !== 0 && !/already|exists/i.test((r.stderr || '') + (r.stdout || ''))) {
|
|
1317
|
+
console.error(`⚠ ${rt.name}: \`${[bin, ...rest].join(' ')}\` failed${r.stderr ? ` — ${r.stderr.trim().split('\n').pop()}` : ''}`);
|
|
1338
1318
|
return false;
|
|
1339
|
-
const da = statSync(pa).isDirectory(), db = statSync(pb).isDirectory();
|
|
1340
|
-
if (da !== db)
|
|
1341
|
-
return false;
|
|
1342
|
-
if (da) {
|
|
1343
|
-
if (!dirsEqual(pa, pb))
|
|
1344
|
-
return false;
|
|
1345
1319
|
}
|
|
1346
|
-
else if (!readFileSync(pa).equals(readFileSync(pb)))
|
|
1347
|
-
return false;
|
|
1348
1320
|
}
|
|
1349
1321
|
return true;
|
|
1350
1322
|
}
|
|
1351
|
-
//
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
return 'missing';
|
|
1358
|
-
return names.every((n) => dirsEqual(join(bundle, n), join(target, n))) ? 'current' : 'outdated';
|
|
1323
|
+
// updatePluginIn refreshes an installed plugin to the marketplace's latest.
|
|
1324
|
+
function updatePluginIn(rt) {
|
|
1325
|
+
const cmd = rt.name === 'claude'
|
|
1326
|
+
? ['claude', 'plugin', 'update', 'vitrinka@lovinka']
|
|
1327
|
+
: ['codex', 'plugin', 'marketplace', 'upgrade'];
|
|
1328
|
+
return spawnSync(cmd[0], cmd.slice(1), { stdio: 'inherit' }).status === 0;
|
|
1359
1329
|
}
|
|
1330
|
+
// ---------- setup state probing (shared by install / doctor / uninstall) ----------
|
|
1360
1331
|
const SHIM_CONTENT = `#!/bin/sh\nexec node "${CLI_PATH}" "$@"\n`;
|
|
1361
1332
|
function shimPathOf(home) { return join(home, '.local', 'bin', 'vitrinka'); }
|
|
1362
1333
|
function rcPathOf(home) {
|
|
@@ -1431,9 +1402,7 @@ async function installCmd(args) {
|
|
|
1431
1402
|
const base = resolveBaseUrl(strArg(args.base));
|
|
1432
1403
|
const mcpScope = local ? 'project' : 'user';
|
|
1433
1404
|
// ---- probe (before touching anything) ----
|
|
1434
|
-
const
|
|
1435
|
-
const skillsTarget = local ? resolve('.claude', 'skills') : join(home, '.claude', 'skills');
|
|
1436
|
-
const skills = bundle ? skillsStateOf(bundle, skillsTarget) : 'no-bundle';
|
|
1405
|
+
const runtimes = pluginRuntimes();
|
|
1437
1406
|
const shimP = shimPathOf(home);
|
|
1438
1407
|
const shimOk = existsSync(shimP) && readFileSync(shimP, 'utf8') === SHIM_CONTENT;
|
|
1439
1408
|
const rc = rcPathOf(home);
|
|
@@ -1448,8 +1417,9 @@ async function installCmd(args) {
|
|
|
1448
1417
|
console.log(` ${ok ? '✓' : '✗'} ${label.padEnd(11)}${detail}`);
|
|
1449
1418
|
};
|
|
1450
1419
|
console.log(`vitrinka setup — ${base}${local ? ' (local scope)' : ''}`);
|
|
1451
|
-
|
|
1452
|
-
|
|
1420
|
+
for (const rt of runtimes) {
|
|
1421
|
+
row(rt.installed, `plugin·${rt.name}`, rt.installed ? 'vitrinka installed' : rt.present ? 'will install (skills ship as the plugin)' : `${rt.name} CLI not found`);
|
|
1422
|
+
}
|
|
1453
1423
|
if (!local)
|
|
1454
1424
|
row(shimOk, 'shim', shimOk ? shimP : 'will install');
|
|
1455
1425
|
if (!local)
|
|
@@ -1459,9 +1429,11 @@ async function installCmd(args) {
|
|
|
1459
1429
|
row(!!op, 'operator', op || 'unset — board writes stay anonymous');
|
|
1460
1430
|
row(uiOk, 'claude ui', uiOk ? 'statusline + footer wired' : 'not wired');
|
|
1461
1431
|
console.log('');
|
|
1462
|
-
// ---- silent steps:
|
|
1463
|
-
|
|
1464
|
-
|
|
1432
|
+
// ---- silent steps: plugins, shim, PATH, completion (reversible, own dirs) ----
|
|
1433
|
+
for (const rt of runtimes) {
|
|
1434
|
+
if (rt.present && !rt.installed && installPluginInto(rt))
|
|
1435
|
+
console.log(`✓ plugin (${rt.name}) → vitrinka@lovinka`);
|
|
1436
|
+
}
|
|
1465
1437
|
if (!local) {
|
|
1466
1438
|
if (!shimOk) {
|
|
1467
1439
|
mkdirSync(dirname(shimP), { recursive: true });
|
|
@@ -1587,9 +1559,9 @@ export function stripMarkerBlock(content, marker) {
|
|
|
1587
1559
|
}
|
|
1588
1560
|
return out.join('\n');
|
|
1589
1561
|
}
|
|
1590
|
-
//
|
|
1591
|
-
//
|
|
1592
|
-
const
|
|
1562
|
+
// Legacy ~/.claude/skills copy names — removed by uninstall on machines set
|
|
1563
|
+
// up before the plugin distribution (install-skills, removed 2026-07-11).
|
|
1564
|
+
const LEGACY_SKILLS = ['artifact', 'brainstorming', 'screenshot', 'vitrinka', 'listen'];
|
|
1593
1565
|
// uninstallCmd removes everything install put on the machine — the exact
|
|
1594
1566
|
// inverse: bundled skills + the /vitrinka:listen stub, shim, rc marker blocks,
|
|
1595
1567
|
// statusline wrapper (restoring the original statusLine command), the /boards/
|
|
@@ -1600,21 +1572,31 @@ function uninstallCmd(args) {
|
|
|
1600
1572
|
if (!home)
|
|
1601
1573
|
fail('uninstall: $HOME is not set');
|
|
1602
1574
|
const local = args.local === true;
|
|
1603
|
-
if (args.yes !== true && !promptYesNo(`Remove vitrinka from this machine (
|
|
1575
|
+
if (args.yes !== true && !promptYesNo(`Remove vitrinka from this machine (plugins, legacy skill copies, shim, completion, Claude wiring, MCP${args.purge === true ? ', token+operator' : ''})? [Y/n] `)) {
|
|
1604
1576
|
fail('uninstall: aborted (non-interactive runs need --yes)', 2);
|
|
1605
1577
|
}
|
|
1606
|
-
//
|
|
1607
|
-
|
|
1608
|
-
const
|
|
1609
|
-
|
|
1610
|
-
|
|
1578
|
+
// Plugins (the current distribution) + legacy ~/.claude/skills copies +
|
|
1579
|
+
// the old /vitrinka:listen command stub, from machines set up pre-plugin.
|
|
1580
|
+
for (const rt of pluginRuntimes()) {
|
|
1581
|
+
if (!rt.installed)
|
|
1582
|
+
continue;
|
|
1583
|
+
const cmd = rt.name === 'claude'
|
|
1584
|
+
? ['claude', 'plugin', 'uninstall', 'vitrinka@lovinka']
|
|
1585
|
+
: ['codex', 'plugin', 'remove', 'vitrinka@lovinka'];
|
|
1586
|
+
if (spawnSync(cmd[0], cmd.slice(1), { stdio: 'inherit' }).status === 0) {
|
|
1587
|
+
console.log(`✓ removed ${rt.name} plugin`);
|
|
1588
|
+
}
|
|
1589
|
+
else {
|
|
1590
|
+
console.error(`⚠ ${rt.name} plugin removal failed — run: ${cmd.join(' ')}`);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1611
1593
|
const skillsDir = local ? resolve('.claude', 'skills') : join(home, '.claude', 'skills');
|
|
1612
1594
|
const commandsDir = local ? resolve('.claude', 'commands', 'vitrinka') : join(home, '.claude', 'commands', 'vitrinka');
|
|
1613
|
-
for (const n of
|
|
1595
|
+
for (const n of LEGACY_SKILLS) {
|
|
1614
1596
|
if (!existsSync(join(skillsDir, n)))
|
|
1615
1597
|
continue;
|
|
1616
1598
|
rmSync(join(skillsDir, n), { recursive: true, force: true });
|
|
1617
|
-
console.log(`✓ removed skill ${n}`);
|
|
1599
|
+
console.log(`✓ removed legacy skill copy ${n}`);
|
|
1618
1600
|
}
|
|
1619
1601
|
if (existsSync(join(commandsDir, 'listen.md'))) {
|
|
1620
1602
|
rmSync(join(commandsDir, 'listen.md'));
|
|
@@ -1977,7 +1959,7 @@ export function cmpSemver(a, b) {
|
|
|
1977
1959
|
return 0;
|
|
1978
1960
|
}
|
|
1979
1961
|
// Commands that must never carry the notifier/hint noise (setup and meta paths).
|
|
1980
|
-
const HINT_SKIP = new Set(['install', 'install-claude', '
|
|
1962
|
+
const HINT_SKIP = new Set(['install', 'install-claude', 'update', 'uninstall',
|
|
1981
1963
|
'doctor', 'help', 'completion', '__complete', 'ai']);
|
|
1982
1964
|
function updateCheckPath() {
|
|
1983
1965
|
return join(process.env.HOME || '', '.config', 'vitrinka', 'update-check');
|
|
@@ -2070,7 +2052,7 @@ function pkgVersion() {
|
|
|
2070
2052
|
// before, the Claude Code UI wiring. It never asks new consent questions —
|
|
2071
2053
|
// that stays `vitrinka install`'s job. The refresh steps re-exec the (possibly
|
|
2072
2054
|
// just replaced) CLI file so they run the NEW code, not this stale process.
|
|
2073
|
-
async function updateCmd(
|
|
2055
|
+
async function updateCmd(_args) {
|
|
2074
2056
|
const repoTop = git(['rev-parse', '--show-toplevel'], dirname(CLI_PATH));
|
|
2075
2057
|
if (repoTop) {
|
|
2076
2058
|
// Repo checkout — the shim/MCP run the source directly, so a pull IS the update.
|
|
@@ -2124,11 +2106,13 @@ async function updateCmd(args) {
|
|
|
2124
2106
|
}
|
|
2125
2107
|
}
|
|
2126
2108
|
}
|
|
2127
|
-
// Refresh installed surfaces from the NEW code —
|
|
2128
|
-
//
|
|
2109
|
+
// Refresh installed surfaces from the NEW code — plugins where installed,
|
|
2110
|
+
// Claude wiring only if the wrapper shows prior consent.
|
|
2129
2111
|
const rerun = (sub) => spawnSync(process.execPath, [CLI_PATH, ...sub], { stdio: 'inherit' }).status === 0;
|
|
2130
|
-
|
|
2131
|
-
|
|
2112
|
+
for (const rt of pluginRuntimes()) {
|
|
2113
|
+
if (rt.installed && !updatePluginIn(rt)) {
|
|
2114
|
+
console.error(`⚠ update: ${rt.name} plugin refresh failed — re-run its plugin update manually`);
|
|
2115
|
+
}
|
|
2132
2116
|
}
|
|
2133
2117
|
const wrapper = join(process.env.HOME || '', '.claude', 'vitrinka-statusline.sh');
|
|
2134
2118
|
if (existsSync(wrapper)) {
|
|
@@ -2854,12 +2838,7 @@ export const COMMANDS = [
|
|
|
2854
2838
|
examples: ['vitrinka install-claude'],
|
|
2855
2839
|
},
|
|
2856
2840
|
{
|
|
2857
|
-
name: '
|
|
2858
|
-
usage: '[--local]', flags: [{ f: '--local', d: 'install into ./.claude/skills of the current project instead of ~/.claude/skills' }],
|
|
2859
|
-
examples: ['vitrinka install-skills'],
|
|
2860
|
-
},
|
|
2861
|
-
{
|
|
2862
|
-
name: 'update', summary: 'Update the CLI (git pull / npm -g), show what\'s new, refresh the installed skills + Claude wiring',
|
|
2841
|
+
name: 'update', summary: 'Update the CLI (git pull / npm -g), show what\'s new, refresh the installed plugins + Claude wiring',
|
|
2863
2842
|
usage: '[--local]',
|
|
2864
2843
|
flags: [{ f: '--local', d: 'refresh skills into ./.claude/skills of the current project instead of ~/.claude/skills' }],
|
|
2865
2844
|
examples: ['vitrinka update'],
|
|
@@ -3741,8 +3720,6 @@ async function runSub(argv) {
|
|
|
3741
3720
|
await installCmd(args);
|
|
3742
3721
|
else if (cmd === 'install-claude')
|
|
3743
3722
|
installClaudeCmd(args);
|
|
3744
|
-
else if (cmd === 'install-skills')
|
|
3745
|
-
installSkillsCmd(args);
|
|
3746
3723
|
else if (cmd === 'uninstall')
|
|
3747
3724
|
uninstallCmd(args);
|
|
3748
3725
|
else if (cmd === 'update')
|