spirewise 1.6.3 → 1.7.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.
Files changed (2) hide show
  1. package/bin/cli.js +23 -6
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -223,7 +223,7 @@ function box(lines) {
223
223
  }
224
224
 
225
225
  // --- Interactive full-width selector ---------------------------------------
226
- function interactiveSelect({ title, subtitle, items, multi = true, preselected = [] }) {
226
+ function interactiveSelect({ title, subtitle, items, multi = true, preselected = [], pageSize = 5 }) {
227
227
  return new Promise((resolve) => {
228
228
  const stdin = process.stdin, stdout = process.stdout;
229
229
  if (!stdin.isTTY) { resolve(null); return; }
@@ -243,17 +243,34 @@ function interactiveSelect({ title, subtitle, items, multi = true, preselected =
243
243
  };
244
244
 
245
245
  function render() {
246
+ // Windowed viewport: show at most `pageSize` rows and keep the cursor
247
+ // centered so long lists (e.g. skills) scroll smoothly with up/down.
248
+ const PAGE = Math.min(pageSize, items.length);
249
+ const half = Math.floor(PAGE / 2);
250
+ let start = index - half;
251
+ if (start < 0) start = 0;
252
+ if (start > items.length - PAGE) start = items.length - PAGE;
253
+ const end = start + PAGE;
254
+
246
255
  const lines = ['', bar(title)];
247
256
  if (subtitle) lines.push(paint(RAW.dim, ' ' + subtitle));
257
+ if (items.length > PAGE) {
258
+ const above = start > 0 ? '▲ more' : ' ';
259
+ lines.push(paint(RAW.dim, ` ${above} ${index + 1}/${items.length}`));
260
+ }
248
261
  lines.push('');
249
- items.forEach((it, i) => {
262
+ for (let i = start; i < end; i++) {
263
+ const it = items[i];
250
264
  const cur = i === index ? paint(RAW.cyan, '❯') : ' ';
251
265
  const mark = multi ? (selected.has(i) ? paint(RAW.green, '◉') : paint(RAW.dim, '◯'))
252
266
  : (i === index ? paint(RAW.green, '◉') : paint(RAW.dim, '◯'));
253
267
  const label = i === index ? paint(RAW.bold, it.label) : it.label;
254
268
  const hint = it.hint ? paint(RAW.dim, ' ' + it.hint) : '';
255
269
  lines.push(` ${cur} ${mark} ${label}${hint}`);
256
- });
270
+ }
271
+ if (items.length > PAGE) {
272
+ lines.push(paint(RAW.dim, ` ${end < items.length ? '▼ more' : ' '}`));
273
+ }
257
274
  lines.push('');
258
275
  lines.push(paint(RAW.dim, ' ' + (multi
259
276
  ? '↑/↓ move · space toggle · a all/none · enter confirm · esc cancel'
@@ -392,7 +409,7 @@ async function main() {
392
409
  title: `Step 1/3 · Select skills to ${verb}`,
393
410
  subtitle: action === 'remove' ? 'These will be deleted from the chosen agents' : 'Copy templates to install into your agents',
394
411
  items: available.map((s) => ({ value: s, label: s, hint: skillHint(s) })),
395
- multi: true, preselected: available,
412
+ multi: true, preselected: [],
396
413
  });
397
414
  if (skills === null) die('Cancelled.');
398
415
  if (!skills.length) die('No skills selected.');
@@ -407,7 +424,7 @@ async function main() {
407
424
  title: `Step 2/3 · Select agents`,
408
425
  subtitle: action === 'remove' ? 'Skills are removed from each agent’s folder' : 'Each agent gets the skills in its own folder + format',
409
426
  items: Object.entries(AGENTS).map(([k, a]) => ({ value: k, label: a.label, hint: `(${k}) · ${a.format}` })),
410
- multi: true, preselected: Object.keys(AGENTS),
427
+ multi: true, preselected: [],
411
428
  });
412
429
  if (agentKeys === null) die('Cancelled.');
413
430
  if (!agentKeys.length) die('No agents selected.');
@@ -424,7 +441,7 @@ async function main() {
424
441
  { value: 'global', label: 'Global', hint: 'your home folders — applies to all projects' },
425
442
  { value: 'both', label: 'Both', hint: 'workspace + global' },
426
443
  ],
427
- multi: false, preselected: ['project'],
444
+ multi: false, preselected: [],
428
445
  });
429
446
  if (scope === null) die('Cancelled.');
430
447
  } else if (!scope) { warn('No terminal; defaulting scope to "workspace".'); scope = 'project'; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spirewise",
3
- "version": "1.6.3",
3
+ "version": "1.7.0",
4
4
  "description": "Installable Agent Skills for GitHub Copilot, Claude Code, and Cursor — copywriting (F6S & LinkedIn), NVIDIA Inception tooling, and 35 website design-system architect skills modeled on real SaaS sites.",
5
5
  "bin": {
6
6
  "spirewise": "bin/cli.js"