claude-agent-skills 1.5.0 → 1.5.2
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/commands/hub.js +19 -25
- package/lib/banner.js +16 -5
- package/lib/picker.js +3 -1
- package/package.json +1 -1
- package/skills.json +1 -1
package/commands/hub.js
CHANGED
|
@@ -2,10 +2,8 @@ import updateNotifier from 'update-notifier';
|
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
5
|
-
import
|
|
6
|
-
import { showIntro } from '../lib/banner.js';
|
|
5
|
+
import { showIntro, showIntroStatic } from '../lib/banner.js';
|
|
7
6
|
import { CliCancel } from '../lib/prompts.js';
|
|
8
|
-
import { brand, muted, white } from '../lib/theme.js';
|
|
9
7
|
import { inlineSelect } from '../lib/inlineSelect.js';
|
|
10
8
|
|
|
11
9
|
const req = createRequire(import.meta.url);
|
|
@@ -22,31 +20,32 @@ import { runCheck } from './check.js';
|
|
|
22
20
|
const SKIP = { skipIntro: true };
|
|
23
21
|
|
|
24
22
|
const MENU = [
|
|
25
|
-
{ value: 'add', label: 'Add Skill(s)',
|
|
26
|
-
{ value: 'update', label: 'Update Existing Skill(s)',
|
|
27
|
-
{ value: 'remove', label: 'Remove Existing Skill(s)',
|
|
28
|
-
{ value: 'list', label: 'List Installed Skill(s)',
|
|
29
|
-
{ value: 'sync', label: 'Sync/Restore from Lockfile',
|
|
30
|
-
{ value: 'check', label: 'Check Skill(s)',
|
|
23
|
+
{ value: 'add', label: 'Add Skill(s)', hint: 'install new skills' },
|
|
24
|
+
{ value: 'update', label: 'Update Existing Skill(s)', hint: 'pull latest versions' },
|
|
25
|
+
{ value: 'remove', label: 'Remove Existing Skill(s)', hint: 'uninstall skills' },
|
|
26
|
+
{ value: 'list', label: 'List Installed Skill(s)', hint: "show what's installed" },
|
|
27
|
+
{ value: 'sync', label: 'Sync/Restore from Lockfile', hint: 'restore from claude-skills-lock.json' },
|
|
28
|
+
{ value: 'check', label: 'Check Skill(s)', hint: 'verify hashes & lockfile' },
|
|
31
29
|
{ value: 'quit', label: 'Quit' },
|
|
32
30
|
];
|
|
33
31
|
|
|
34
|
-
function
|
|
35
|
-
|
|
36
|
-
process.stdout.write('\n');
|
|
37
|
-
process.stdout.write(brand('◈ CLAUDE SKILLS') + ' ' + silver('Agent Skills for Claude Code') + '\n');
|
|
38
|
-
process.stdout.write('\n');
|
|
32
|
+
function restoreScreen() {
|
|
33
|
+
process.stdout.write('\x1b[?1049l');
|
|
39
34
|
}
|
|
40
35
|
|
|
41
36
|
export async function runHub() {
|
|
42
|
-
|
|
37
|
+
// Alternate screen buffer — isolated viewport, no scrollback. Restored on exit like vim/less.
|
|
38
|
+
process.stdout.write('\x1b[?1049h\x1b[2J\x1b[H');
|
|
39
|
+
process.on('exit', restoreScreen);
|
|
40
|
+
|
|
41
|
+
await showIntro(); // animated banner on first load
|
|
43
42
|
|
|
44
43
|
let first = true;
|
|
45
44
|
for (;;) {
|
|
46
45
|
if (!first) {
|
|
47
|
-
// Clear
|
|
46
|
+
// Clear alt screen and re-render the static banner so it's always visible
|
|
48
47
|
process.stdout.write('\x1b[2J\x1b[H');
|
|
49
|
-
|
|
48
|
+
await showIntroStatic();
|
|
50
49
|
}
|
|
51
50
|
first = false;
|
|
52
51
|
|
|
@@ -57,10 +56,7 @@ export async function runHub() {
|
|
|
57
56
|
options: MENU,
|
|
58
57
|
});
|
|
59
58
|
|
|
60
|
-
if (choice === 'quit') {
|
|
61
|
-
process.stdout.write('\n' + muted('Goodbye.') + '\n');
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
59
|
+
if (choice === 'quit') { restoreScreen(); return; }
|
|
64
60
|
|
|
65
61
|
if (choice === 'add') await runAdd(SKIP);
|
|
66
62
|
if (choice === 'update') await runUpdate(SKIP);
|
|
@@ -70,10 +66,8 @@ export async function runHub() {
|
|
|
70
66
|
if (choice === 'check') await runCheck(SKIP);
|
|
71
67
|
} catch (e) {
|
|
72
68
|
if (e instanceof CliCancel) continue; // sub-command ESC → back to menu
|
|
73
|
-
if (e?.isCancel) {
|
|
74
|
-
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
69
|
+
if (e?.isCancel) { restoreScreen(); return; } // hub menu ESC → quit
|
|
70
|
+
restoreScreen();
|
|
77
71
|
throw e;
|
|
78
72
|
}
|
|
79
73
|
}
|
package/lib/banner.js
CHANGED
|
@@ -89,6 +89,13 @@ async function renderStatic() {
|
|
|
89
89
|
renderFrame(staticColor);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
function printSubtitle() {
|
|
93
|
+
const silver = s => ansis.rgb(190, 190, 190)(s);
|
|
94
|
+
process.stdout.write('\n');
|
|
95
|
+
process.stdout.write(silver('Agent Skills for Claude Code by Pavithran Francis') + '\n\n');
|
|
96
|
+
process.stdout.write(muted('Repository: ') + silver(REPO) + '\n\n');
|
|
97
|
+
}
|
|
98
|
+
|
|
92
99
|
/**
|
|
93
100
|
* showIntro() — full two-sweep entrance + subtitle (call ONCE at startup)
|
|
94
101
|
* showIntro({ skip:true }) — no-op (used inside sub-commands called from hub)
|
|
@@ -100,10 +107,14 @@ export async function showIntro({ skip = false } = {}) {
|
|
|
100
107
|
|
|
101
108
|
await runSweep({ step: 3, fps: 55 }); // first sweep (~0.8 s)
|
|
102
109
|
await runSweep({ step: 3, fps: 55 }); // second sweep (~0.8 s)
|
|
103
|
-
await renderStatic(); // settle to metallic
|
|
110
|
+
await renderStatic(); // settle to metallic state
|
|
104
111
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
printSubtitle();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Static banner with no animation — used on hub loop iterations after the first. */
|
|
116
|
+
export async function showIntroStatic() {
|
|
117
|
+
process.stdout.write('\n'.repeat(ART.length));
|
|
118
|
+
await renderStatic();
|
|
119
|
+
printSubtitle();
|
|
109
120
|
}
|
package/lib/picker.js
CHANGED
|
@@ -157,7 +157,9 @@ export async function skillPicker({ message, options }) {
|
|
|
157
157
|
if (key === KEY.ENTER) {
|
|
158
158
|
if (!sel.size) return;
|
|
159
159
|
cleanup();
|
|
160
|
-
|
|
160
|
+
// Clear entire picker block then write compact confirmation
|
|
161
|
+
if (lastLines > 0) process.stdout.write(`\x1b[${lastLines}A\x1b[0J`);
|
|
162
|
+
process.stdout.write(success('◆') + ' ' +
|
|
161
163
|
white(`${sel.size} skill(s) selected`) + '\n');
|
|
162
164
|
resolve([...sel].sort((a, b) => a - b).map(i => options[i].value));
|
|
163
165
|
return;
|
package/package.json
CHANGED