spirewise 1.8.0 → 1.9.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/bin/cli.js +32 -41
- package/install.sh +6 -6
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -211,27 +211,19 @@ function removeFromAgent(agentKey, agent, scope, skills, onItem) {
|
|
|
211
211
|
return removed;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
//
|
|
215
|
-
//
|
|
216
|
-
//
|
|
214
|
+
// Clean single-line horizontal stepper (like a React UI-library Steps component):
|
|
215
|
+
// completed steps show a check, the active step is a filled, highlighted circle,
|
|
216
|
+
// upcoming steps are dim outline circles — joined by thin connectors.
|
|
217
|
+
const STEP_FILLED = ['', '❶', '❷', '❸', '❹', '❺', '❻'];
|
|
218
|
+
const STEP_OUTLINE = ['', '①', '②', '③', '④', '⑤', '⑥'];
|
|
217
219
|
function stepper(current, steps) {
|
|
218
|
-
const
|
|
219
|
-
const PAD = ' ';
|
|
220
|
-
for (let i = 0; i < steps.length; i++) {
|
|
220
|
+
const parts = steps.map((label, i) => {
|
|
221
221
|
const n = i + 1;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
: paint(RAW.dim, steps[i]);
|
|
228
|
-
// rounded square (≈10–15% corner radius via ╭╮╰╯) holding the step number
|
|
229
|
-
out.push(PAD + paint(color, '╭─────╮'));
|
|
230
|
-
out.push(PAD + paint(color, '│ ' + num + ' │') + ' ' + label);
|
|
231
|
-
out.push(PAD + paint(color, '╰─────╯'));
|
|
232
|
-
if (n < steps.length) out.push(PAD + ' ' + paint(RAW.dim, '│')); // centred connector
|
|
233
|
-
}
|
|
234
|
-
return out;
|
|
222
|
+
if (n < current) return `${paint(RAW.green, '✓')} ${paint(RAW.dim, label)}`; // done
|
|
223
|
+
if (n === current) return `${paint(RAW.cyan, STEP_FILLED[n])} ${paint(RAW.bold, label)}`; // active
|
|
224
|
+
return paint(RAW.dim, `${STEP_OUTLINE[n]} ${label}`); // upcoming
|
|
225
|
+
});
|
|
226
|
+
return [' ' + parts.join(paint(RAW.dim, ' ── '))];
|
|
235
227
|
}
|
|
236
228
|
|
|
237
229
|
// Single, in-place updating status line (collapses the install/remove progress
|
|
@@ -411,7 +403,6 @@ async function main() {
|
|
|
411
403
|
|
|
412
404
|
const o = parseArgs(argv);
|
|
413
405
|
const tty = process.stdin.isTTY;
|
|
414
|
-
const verb = action === 'remove' ? 'remove' : 'install';
|
|
415
406
|
const Ving = action === 'remove' ? 'Removing' : 'Installing';
|
|
416
407
|
banner();
|
|
417
408
|
|
|
@@ -425,9 +416,9 @@ async function main() {
|
|
|
425
416
|
});
|
|
426
417
|
} else if (tty) {
|
|
427
418
|
skills = await interactiveSelect({
|
|
428
|
-
title: `
|
|
429
|
-
step: 1, steps: ['
|
|
430
|
-
subtitle: action === 'remove' ? '
|
|
419
|
+
title: `Skills`,
|
|
420
|
+
step: 1, steps: ['Skills', 'Tools', 'Where'],
|
|
421
|
+
subtitle: action === 'remove' ? 'Pick the skills to remove.' : 'Pick the skills you want.',
|
|
431
422
|
items: available.map((s) => ({ value: s, label: s, hint: skillHint(s) })),
|
|
432
423
|
multi: true, preselected: [],
|
|
433
424
|
});
|
|
@@ -441,9 +432,9 @@ async function main() {
|
|
|
441
432
|
for (const k of agentKeys) if (!AGENTS[k]) die(`Unknown agent '${k}'. Run "spirewise agents".`);
|
|
442
433
|
} else if (tty) {
|
|
443
434
|
agentKeys = await interactiveSelect({
|
|
444
|
-
title: `
|
|
445
|
-
step: 2, steps: ['
|
|
446
|
-
subtitle: action === 'remove' ? '
|
|
435
|
+
title: `Tools`,
|
|
436
|
+
step: 2, steps: ['Skills', 'Tools', 'Where'],
|
|
437
|
+
subtitle: action === 'remove' ? 'Pick which tools to remove them from.' : 'Pick which tools to add them to.',
|
|
447
438
|
items: Object.entries(AGENTS).map(([k, a]) => ({ value: k, label: a.label, hint: `(${k}) · ${a.format}` })),
|
|
448
439
|
multi: true, preselected: [],
|
|
449
440
|
});
|
|
@@ -455,13 +446,13 @@ async function main() {
|
|
|
455
446
|
let scope = o.scope;
|
|
456
447
|
if (!scope && tty) {
|
|
457
448
|
scope = await interactiveSelect({
|
|
458
|
-
title: '
|
|
459
|
-
step: 3, steps: ['
|
|
460
|
-
subtitle: action === 'remove' ? 'Where to remove
|
|
449
|
+
title: 'Where',
|
|
450
|
+
step: 3, steps: ['Skills', 'Tools', 'Where'],
|
|
451
|
+
subtitle: action === 'remove' ? 'Where to remove them from?' : 'Where should they go?',
|
|
461
452
|
items: [
|
|
462
|
-
{ value: 'project', label: '
|
|
463
|
-
{ value: 'global', label: '
|
|
464
|
-
{ value: 'both', label: 'Both',
|
|
453
|
+
{ value: 'project', label: 'This project', hint: 'just this folder' },
|
|
454
|
+
{ value: 'global', label: 'Everywhere', hint: 'all your projects' },
|
|
455
|
+
{ value: 'both', label: 'Both', hint: 'this project + everywhere' },
|
|
465
456
|
],
|
|
466
457
|
multi: false, preselected: [],
|
|
467
458
|
});
|
|
@@ -472,33 +463,33 @@ async function main() {
|
|
|
472
463
|
|
|
473
464
|
// ACTION
|
|
474
465
|
console.log('');
|
|
475
|
-
|
|
466
|
+
|
|
467
|
+
const pl = (n, w) => `${n} ${w}${n === 1 ? '' : 's'}`;
|
|
468
|
+
const where = { project: 'this project', global: 'everywhere', both: 'this project + everywhere' }[scope];
|
|
476
469
|
|
|
477
470
|
let count = 0;
|
|
478
471
|
const totalOps = scopes.length * agentKeys.length * skills.length;
|
|
479
472
|
let seen = 0;
|
|
480
|
-
const progress = (agent, skill
|
|
473
|
+
const progress = (agent, skill) => {
|
|
481
474
|
seen++;
|
|
482
|
-
|
|
483
|
-
live(`${paint(RAW.cyan, '⟳')} ${Ving}… ${paint(RAW.bold, String(seen))}/${totalOps} (${pct}%) ${c.dim}${agent.label} · ${skill}${c.reset}`);
|
|
475
|
+
live(`${paint(RAW.cyan, '⟳')} ${Ving}… ${paint(RAW.bold, `${seen}/${totalOps}`)} ${c.dim}${agent.label}${c.reset}`);
|
|
484
476
|
};
|
|
485
477
|
for (const sc of scopes) for (const k of agentKeys) {
|
|
486
478
|
if (action === 'remove') count += removeFromAgent(k, AGENTS[k], sc, skills, progress);
|
|
487
479
|
else { installToAgent(k, AGENTS[k], sc, skills, progress); count += skills.length; }
|
|
488
480
|
}
|
|
489
481
|
// Collapse the whole done process into one final line.
|
|
490
|
-
const scopeLabel = scopes.map((s) => (s === 'project' ? 'workspace' : s)).join(' + ');
|
|
491
482
|
if (action === 'remove') {
|
|
492
|
-
liveEnd(`${count === 0 ? paint(RAW.yellow, '·') : paint(RAW.green, '✓')} Removed ${paint(RAW.bold,
|
|
483
|
+
liveEnd(`${count === 0 ? paint(RAW.yellow, '·') : paint(RAW.green, '✓')} Removed ${paint(RAW.bold, pl(count, 'skill'))} from ${pl(agentKeys.length, 'tool')} ${c.dim}(${where})${c.reset}`);
|
|
493
484
|
} else {
|
|
494
|
-
liveEnd(`${paint(RAW.green, '✓')}
|
|
485
|
+
liveEnd(`${paint(RAW.green, '✓')} Added ${paint(RAW.bold, pl(skills.length, 'skill'))} to ${pl(agentKeys.length, 'tool')} ${c.dim}(${where})${c.reset}`);
|
|
495
486
|
}
|
|
496
487
|
|
|
497
488
|
if (action === 'remove') {
|
|
498
|
-
if (count === 0) liveEnd(paint(RAW.dim, ' nothing
|
|
489
|
+
if (count === 0) liveEnd(paint(RAW.dim, ' nothing to remove — already clean'));
|
|
499
490
|
} else {
|
|
500
491
|
console.log('');
|
|
501
|
-
info(`
|
|
492
|
+
info(`Done. Open your tool and ask it to use a skill.`);
|
|
502
493
|
}
|
|
503
494
|
console.log('');
|
|
504
495
|
}
|
package/install.sh
CHANGED
|
@@ -43,7 +43,7 @@ info() { printf '%s %s\n' "$(color '1;34' '==>')" "$1"; }
|
|
|
43
43
|
ok() { printf '%s %s\n' "$(color '1;32' ' ok')" "$1"; }
|
|
44
44
|
warn() { printf '%s %s\n' "$(color '1;33' ' !')" "$1" >&2; }
|
|
45
45
|
die() { printf '%s %s\n' "$(color '1;31' 'err')" "$1" >&2; exit 1; }
|
|
46
|
-
step() { printf '%s %s
|
|
46
|
+
step() { printf '%s %s\n' "$(color '1;36' " $1.")" "$(color '1' "$2")"; }
|
|
47
47
|
substep() { :; } # per-item output collapses into the single final summary line
|
|
48
48
|
|
|
49
49
|
banner() {
|
|
@@ -255,7 +255,7 @@ fi
|
|
|
255
255
|
banner
|
|
256
256
|
|
|
257
257
|
# Step 1: skills (default all).
|
|
258
|
-
step 1 "
|
|
258
|
+
step 1 "Skills"
|
|
259
259
|
if [[ ${#SELECTED[@]} -eq 0 ]]; then
|
|
260
260
|
SELECTED=("${AVAILABLE[@]}")
|
|
261
261
|
else
|
|
@@ -269,11 +269,11 @@ fi
|
|
|
269
269
|
substep "${#SELECTED[@]} skill(s): ${SELECTED[*]}"
|
|
270
270
|
|
|
271
271
|
# Step 2: agents
|
|
272
|
-
step 2 "
|
|
272
|
+
step 2 "Tools"
|
|
273
273
|
if [[ -n "$AGENT_FILTER" ]]; then substep "agents: $AGENT_FILTER"; else substep "agents: all supported"; fi
|
|
274
274
|
|
|
275
275
|
# Step 3: scope — prompt if not given.
|
|
276
|
-
step 3 "
|
|
276
|
+
step 3 "Where"
|
|
277
277
|
if [[ -z "$SCOPE" ]]; then
|
|
278
278
|
if [[ -t 0 ]]; then
|
|
279
279
|
[[ "$MODE" == "remove" ]] && info "Where should the skills be removed from?" || info "Where should the skills be installed?"
|
|
@@ -308,8 +308,8 @@ done
|
|
|
308
308
|
|
|
309
309
|
printf '\n'
|
|
310
310
|
if [[ "$MODE" == "remove" ]]; then
|
|
311
|
-
ok "Removed $REMOVED
|
|
311
|
+
ok "Removed $REMOVED."
|
|
312
312
|
else
|
|
313
|
-
ok "
|
|
313
|
+
ok "Added ${#SELECTED[@]}. Open your tool and ask it to use a skill."
|
|
314
314
|
fi
|
|
315
315
|
|
package/package.json
CHANGED