claude-agent-skills 1.3.1 → 1.3.3
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/lib/prompts.js +16 -3
- package/lib/summary.js +31 -23
- package/lib/theme.js +25 -0
- package/package.json +1 -1
- package/skills.json +1 -1
package/lib/prompts.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { select, multiselect, confirm, isCancel } from '@clack/prompts';
|
|
2
2
|
import ansis from 'ansis';
|
|
3
|
+
import { skillColor, white, muted, divider } from './theme.js';
|
|
3
4
|
|
|
4
5
|
export class CliCancel extends Error {}
|
|
5
6
|
|
|
@@ -26,11 +27,23 @@ export async function pickScope(flags = {}) {
|
|
|
26
27
|
export async function pickSkills(names, flags = {}, descriptions = {}) {
|
|
27
28
|
if (flags.all) return names;
|
|
28
29
|
if (flags.skill?.length) return flags.skill;
|
|
30
|
+
|
|
31
|
+
// Calculate description width from actual terminal columns.
|
|
32
|
+
// prefix=4 (clack's "□ "), nameCol=32, divider=3 (" │ ")
|
|
33
|
+
const termWidth = process.stdout.columns || 100;
|
|
34
|
+
const descWidth = Math.max(20, termWidth - 4 - 32 - 3);
|
|
35
|
+
|
|
36
|
+
function fitDesc(s) {
|
|
37
|
+
if (!s) return '';
|
|
38
|
+
return s.length <= descWidth ? s : s.slice(0, descWidth - 1) + '…';
|
|
39
|
+
}
|
|
40
|
+
|
|
29
41
|
return guard(await multiselect({
|
|
30
42
|
message: 'Select skills (space to toggle, a for all, enter to confirm)',
|
|
31
|
-
options: names.map(n => {
|
|
32
|
-
const
|
|
33
|
-
|
|
43
|
+
options: names.map((n, i) => {
|
|
44
|
+
const name = skillColor(i)(ansis.bold(n.padEnd(32)));
|
|
45
|
+
const desc = descriptions[n] ? white(fitDesc(descriptions[n])) : '';
|
|
46
|
+
return { value: n, label: name + divider + desc };
|
|
34
47
|
}),
|
|
35
48
|
required: true,
|
|
36
49
|
}));
|
package/lib/summary.js
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
import { brand, muted, success, warn } from './theme.js';
|
|
1
|
+
import { brand, muted, success, warn, white, skillColor, divider } from './theme.js';
|
|
2
2
|
import { VERSION } from './constants.js';
|
|
3
3
|
|
|
4
|
-
const PACK = `claude-skills v${VERSION}`;
|
|
4
|
+
const PACK = `claude-agent-skills v${VERSION}`;
|
|
5
5
|
|
|
6
6
|
function trunc(s, n) { return s.length <= n ? s : `${s.slice(0, n - 1)}…`; }
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
function colorStatus(label, healthy) {
|
|
8
|
+
function colorStatus(label) {
|
|
10
9
|
const padded = label.padEnd(10);
|
|
11
|
-
if (label === 'ok' || label === 'synced')
|
|
12
|
-
if (label === 'installed' || label === 'updated')
|
|
13
|
-
if (label === 'update')
|
|
14
|
-
if (label === 'skipped')
|
|
10
|
+
if (label === 'ok' || label === 'synced') return success(padded);
|
|
11
|
+
if (label === 'installed' || label === 'updated') return brand(padded);
|
|
12
|
+
if (label === 'update') return brand(padded);
|
|
13
|
+
if (label === 'skipped') return muted(padded);
|
|
15
14
|
return warn(padded); // broken / missing / modified / removed / failed
|
|
16
15
|
}
|
|
17
16
|
|
|
17
|
+
// Pride-colored name with divider + white detail text
|
|
18
|
+
function skillRow(index, name, detail = '') {
|
|
19
|
+
const colored = skillColor(index)(trunc(name, 30).padEnd(30));
|
|
20
|
+
return detail ? ` ${colored}${divider}${white(detail)}` : ` ${colored}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
function header({ scope, destination, lockPath }) {
|
|
19
24
|
const lines = [
|
|
20
25
|
`${brand('Pack')}: ${PACK}`,
|
|
@@ -26,11 +31,11 @@ function header({ scope, destination, lockPath }) {
|
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
export function renderInstallSummary({ scope, skillsDir, lockPath, installed, updated, skipped }) {
|
|
29
|
-
|
|
34
|
+
let idx = 0;
|
|
30
35
|
const row = (entry, label) => {
|
|
31
36
|
const name = typeof entry === 'string' ? entry : entry.name;
|
|
32
|
-
const dep = typeof entry === 'object' && entry.dependencyOf ?
|
|
33
|
-
return ` ${colorStatus(label
|
|
37
|
+
const dep = typeof entry === 'object' && entry.dependencyOf ? `dep of ${entry.dependencyOf}` : '';
|
|
38
|
+
return ` ${colorStatus(label)} ${skillColor(idx++)(trunc(name, 28).padEnd(28))}${dep ? divider + muted(dep) : ''}`;
|
|
34
39
|
};
|
|
35
40
|
const rows = [
|
|
36
41
|
...installed.map(e => row(e, 'installed')),
|
|
@@ -48,38 +53,41 @@ export function renderInstallSummary({ scope, skillsDir, lockPath, installed, up
|
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
export function renderSyncSummary({ scope, skillsDir, lockPath, synced, ok: upToDate }) {
|
|
56
|
+
let idx = 0;
|
|
51
57
|
const rows = [
|
|
52
|
-
...synced.map(n =>
|
|
53
|
-
...upToDate.map(n =>
|
|
58
|
+
...synced.map(n => ` ${colorStatus('synced')} ${skillRow(idx++, n)}`),
|
|
59
|
+
...upToDate.map(n => ` ${colorStatus('ok')} ${skillRow(idx++, n)}`),
|
|
54
60
|
];
|
|
55
61
|
return [
|
|
56
62
|
...header({ scope, destination: skillsDir, lockPath }),
|
|
57
63
|
'',
|
|
58
64
|
`Synced: ${synced.length} Up to date: ${upToDate.length}`,
|
|
59
65
|
'',
|
|
60
|
-
`${'STATUS'.padEnd(12)}
|
|
66
|
+
`${'STATUS'.padEnd(12)} NAME`,
|
|
61
67
|
...rows,
|
|
62
68
|
].join('\n');
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
export function renderListSummary({ scope, skillsDir, lockPath, rows }) {
|
|
66
|
-
const tableRows = rows.map(r => {
|
|
72
|
+
const tableRows = rows.map((r, i) => {
|
|
67
73
|
const label = r.healthy ? 'ok' : r.status;
|
|
68
|
-
|
|
74
|
+
const name = skillColor(i)(trunc(r.name, 28).padEnd(28));
|
|
75
|
+
return ` ${colorStatus(label)} ${name}${divider}${white(r.linkType.padEnd(8))}${muted(r.hash)}`;
|
|
69
76
|
});
|
|
70
77
|
return [
|
|
71
78
|
...header({ scope, destination: skillsDir, lockPath }),
|
|
72
79
|
'',
|
|
73
|
-
`${'STATUS'.padEnd(12)} ${'NAME'.padEnd(30)} ${'LINK'.padEnd(
|
|
80
|
+
`${'STATUS'.padEnd(12)} ${'NAME'.padEnd(30)} ${'LINK'.padEnd(11)} HASH`,
|
|
74
81
|
...tableRows,
|
|
75
82
|
].join('\n');
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
export function renderCheckSummary({ scope, skillsDir, lockPath, rows, counts }) {
|
|
79
86
|
const legend = { ok: 0, update: 0, modified: 0, missing: 0, broken: 0, ...counts };
|
|
80
|
-
const tableRows = rows.map(r =>
|
|
81
|
-
|
|
82
|
-
)
|
|
87
|
+
const tableRows = rows.map((r, i) => {
|
|
88
|
+
const name = skillColor(i)(trunc(r.name, 28).padEnd(28));
|
|
89
|
+
return ` ${colorStatus(r.status)} ${name}${divider}${white(r.linkType)}`;
|
|
90
|
+
});
|
|
83
91
|
return [
|
|
84
92
|
...header({ scope, destination: skillsDir, lockPath }),
|
|
85
93
|
'',
|
|
@@ -94,7 +102,7 @@ export function renderUpdateSummary({ scope, skillsDir, lockPath, updated }) {
|
|
|
94
102
|
return [
|
|
95
103
|
...header({ scope, destination: skillsDir, lockPath }),
|
|
96
104
|
'',
|
|
97
|
-
...updated.map(n => ` ${colorStatus('updated'
|
|
105
|
+
...updated.map((n, i) => ` ${colorStatus('updated')} ${skillColor(i)(n)}`),
|
|
98
106
|
].join('\n');
|
|
99
107
|
}
|
|
100
108
|
|
|
@@ -102,7 +110,7 @@ export function renderRemoveSummary({ scope, skillsDir, lockPath, removed, faile
|
|
|
102
110
|
return [
|
|
103
111
|
...header({ scope, destination: skillsDir, lockPath }),
|
|
104
112
|
'',
|
|
105
|
-
...removed.map(n => ` ${colorStatus('removed'
|
|
106
|
-
...failed.map(f => ` ${colorStatus('failed'
|
|
113
|
+
...removed.map((n, i) => ` ${colorStatus('removed')} ${skillColor(i)(n)}`),
|
|
114
|
+
...failed.map((f, i) => ` ${colorStatus('failed')} ${skillColor(i)(f.name)}${divider}${warn(f.error)}`),
|
|
107
115
|
].join('\n');
|
|
108
116
|
}
|
package/lib/theme.js
CHANGED
|
@@ -8,4 +8,29 @@ export const brand = t => ok() ? ansis.hex(BRAND_HEX)(t) : t;
|
|
|
8
8
|
export const success = t => ok() ? ansis.green(t) : t;
|
|
9
9
|
export const warn = t => ok() ? ansis.yellow(t) : t;
|
|
10
10
|
export const muted = t => ok() ? ansis.dim(t) : t;
|
|
11
|
+
export const white = t => ok() ? ansis.white(t) : t;
|
|
11
12
|
export const strip = t => ansis.strip(t);
|
|
13
|
+
|
|
14
|
+
// ── Pride mode ─────────────────────────────────────────────────────────────
|
|
15
|
+
// Set to false after June to revert skill names to brand pink.
|
|
16
|
+
export const PRIDE_MODE = true;
|
|
17
|
+
|
|
18
|
+
const PRIDE_PALETTE = [
|
|
19
|
+
[220, 30, 30], // red
|
|
20
|
+
[255, 140, 0], // orange
|
|
21
|
+
[220, 200, 0], // yellow
|
|
22
|
+
[ 30, 185, 30], // green
|
|
23
|
+
[ 30, 100, 255], // blue
|
|
24
|
+
[150, 30, 230], // purple
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
// Returns a color function for the nth skill. Cycles through pride palette in
|
|
28
|
+
// PRIDE_MODE, falls back to brand pink otherwise.
|
|
29
|
+
export function skillColor(index) {
|
|
30
|
+
if (!ok()) return t => t;
|
|
31
|
+
if (!PRIDE_MODE) return brand;
|
|
32
|
+
const [r, g, b] = PRIDE_PALETTE[index % PRIDE_PALETTE.length];
|
|
33
|
+
return t => ansis.rgb(r, g, b)(t);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const divider = ok() ? ansis.dim(' │ ') : ' | ';
|
package/package.json
CHANGED