skillex 0.2.3 → 0.2.4
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 +7 -0
- package/dist/cli.js +17 -9
- package/dist/output.d.ts +19 -0
- package/dist/output.js +43 -0
- package/dist/ui.d.ts +1 -0
- package/dist/ui.js +16 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.4] - 2026-04-08
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- `skillex ui` skill list now shows compact labels: `Name (id) · tag1, tag2, tag3` — description and full compatibility list removed from each row
|
|
14
|
+
- `skillex ui` shows "Fetching catalog..." while loading and limits visible rows to 12 at a time
|
|
15
|
+
- `skillex install` and `skillex update` now render an inline progress bar (`[████░░░░] 1/5 skill-id`) instead of printing one line per skill
|
|
16
|
+
|
|
10
17
|
## [0.2.3] - 2026-04-08
|
|
11
18
|
|
|
12
19
|
### Fixed
|
package/dist/cli.js
CHANGED
|
@@ -362,11 +362,9 @@ async function handleInstall(positionals, flags, userConfig) {
|
|
|
362
362
|
const result = await installSkills(positionals, {
|
|
363
363
|
...opts,
|
|
364
364
|
installAll,
|
|
365
|
-
onProgress: (current, total, skillId) =>
|
|
366
|
-
output.info(`[${current}/${total}] Installing ${skillId}...`);
|
|
367
|
-
},
|
|
365
|
+
onProgress: (current, total, skillId) => output.progress(current, total, skillId),
|
|
368
366
|
});
|
|
369
|
-
output.success(`Installed ${result.installedCount} skill(s)
|
|
367
|
+
output.success(`Installed ${result.installedCount} skill(s)`);
|
|
370
368
|
for (const skill of result.installedSkills) {
|
|
371
369
|
output.info(` + ${skill.id}@${skill.version}`);
|
|
372
370
|
}
|
|
@@ -374,7 +372,10 @@ async function handleInstall(positionals, flags, userConfig) {
|
|
|
374
372
|
}
|
|
375
373
|
async function handleUpdate(positionals, flags, userConfig) {
|
|
376
374
|
const opts = commonOptions(flags, userConfig);
|
|
377
|
-
const result = await updateInstalledSkills(positionals,
|
|
375
|
+
const result = await updateInstalledSkills(positionals, {
|
|
376
|
+
...opts,
|
|
377
|
+
onProgress: (current, total, skillId) => output.progress(current, total, skillId),
|
|
378
|
+
});
|
|
378
379
|
if (result.updatedSkills.length === 0) {
|
|
379
380
|
output.info("No skills updated.");
|
|
380
381
|
}
|
|
@@ -437,7 +438,9 @@ async function handleUi(flags, userConfig) {
|
|
|
437
438
|
const options = commonOptions(flags, userConfig);
|
|
438
439
|
const state = await getInstalledSkills(options);
|
|
439
440
|
const source = await resolveProjectSource(options);
|
|
441
|
+
output.statusLine("Fetching catalog...");
|
|
440
442
|
const catalog = await loadCatalog({ ...source, ...cacheOptions(options) });
|
|
443
|
+
output.clearStatus();
|
|
441
444
|
if (catalog.skills.length === 0) {
|
|
442
445
|
output.info("No skills available in the catalog.");
|
|
443
446
|
return;
|
|
@@ -450,19 +453,24 @@ async function handleUi(flags, userConfig) {
|
|
|
450
453
|
: "No skills available in the catalog.");
|
|
451
454
|
return;
|
|
452
455
|
}
|
|
453
|
-
const installResult = selection.toInstall.length > 0
|
|
456
|
+
const installResult = selection.toInstall.length > 0
|
|
457
|
+
? await installSkills(selection.toInstall, {
|
|
458
|
+
...options,
|
|
459
|
+
onProgress: (current, total, skillId) => output.progress(current, total, skillId),
|
|
460
|
+
})
|
|
461
|
+
: null;
|
|
454
462
|
const removeResult = selection.toRemove.length > 0 ? await removeSkills(selection.toRemove, options) : null;
|
|
455
463
|
if (!installResult && !removeResult) {
|
|
456
464
|
output.info("No changes applied.");
|
|
457
465
|
return;
|
|
458
466
|
}
|
|
459
|
-
output.success("UI summary:");
|
|
460
467
|
if (installResult) {
|
|
461
|
-
output.
|
|
468
|
+
output.success(`Installed: ${installResult.installedSkills.map((s) => s.id).join(", ")}`);
|
|
462
469
|
}
|
|
463
470
|
if (removeResult) {
|
|
464
|
-
output.
|
|
471
|
+
output.success(`Removed: ${removeResult.removedSkills.join(", ")}`);
|
|
465
472
|
}
|
|
473
|
+
printAutoSyncResult(installResult?.autoSync ?? removeResult?.autoSync ?? null);
|
|
466
474
|
}
|
|
467
475
|
async function handleStatus(flags, userConfig) {
|
|
468
476
|
const options = commonOptions(flags, userConfig);
|
package/dist/output.d.ts
CHANGED
|
@@ -44,3 +44,22 @@ export declare function error(message: string): void;
|
|
|
44
44
|
* @param message - Debug message.
|
|
45
45
|
*/
|
|
46
46
|
export declare function debug(message: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Renders an inline progress bar that overwrites the current line.
|
|
49
|
+
* Prints a newline when current === total.
|
|
50
|
+
*
|
|
51
|
+
* @param current - Number of completed items (1-based).
|
|
52
|
+
* @param total - Total number of items.
|
|
53
|
+
* @param label - Short label shown after the bar.
|
|
54
|
+
*/
|
|
55
|
+
export declare function progress(current: number, total: number, label: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Writes a transient status message on the current line (overwritable with clearStatus).
|
|
58
|
+
*
|
|
59
|
+
* @param message - Status message to display.
|
|
60
|
+
*/
|
|
61
|
+
export declare function statusLine(message: string): void;
|
|
62
|
+
/**
|
|
63
|
+
* Clears the current status line written by {@link statusLine}.
|
|
64
|
+
*/
|
|
65
|
+
export declare function clearStatus(): void;
|
package/dist/output.js
CHANGED
|
@@ -76,3 +76,46 @@ export function debug(message) {
|
|
|
76
76
|
process.stderr.write(applyColor("2", `[debug] ${message}`, process.stderr) + "\n");
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
// Progress and status helpers (TTY-only; fall back to plain lines otherwise)
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
/**
|
|
83
|
+
* Renders an inline progress bar that overwrites the current line.
|
|
84
|
+
* Prints a newline when current === total.
|
|
85
|
+
*
|
|
86
|
+
* @param current - Number of completed items (1-based).
|
|
87
|
+
* @param total - Total number of items.
|
|
88
|
+
* @param label - Short label shown after the bar.
|
|
89
|
+
*/
|
|
90
|
+
export function progress(current, total, label) {
|
|
91
|
+
if (!process.stdout.isTTY) {
|
|
92
|
+
console.log(`[${current}/${total}] ${label}`);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const filled = total > 0 ? Math.round((current / total) * 16) : 0;
|
|
96
|
+
const bar = applyColor("32", "█".repeat(filled), process.stdout) + "░".repeat(16 - filled);
|
|
97
|
+
const counter = applyColor("2", `${current}/${total}`, process.stdout);
|
|
98
|
+
const line = ` [${bar}] ${counter} ${label}`;
|
|
99
|
+
process.stdout.write(`\r${line}\x1b[K`);
|
|
100
|
+
if (current === total) {
|
|
101
|
+
process.stdout.write("\n");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Writes a transient status message on the current line (overwritable with clearStatus).
|
|
106
|
+
*
|
|
107
|
+
* @param message - Status message to display.
|
|
108
|
+
*/
|
|
109
|
+
export function statusLine(message) {
|
|
110
|
+
if (!process.stdout.isTTY)
|
|
111
|
+
return;
|
|
112
|
+
process.stdout.write(`\r ${applyColor("2", message, process.stdout)}\x1b[K`);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Clears the current status line written by {@link statusLine}.
|
|
116
|
+
*/
|
|
117
|
+
export function clearStatus() {
|
|
118
|
+
if (!process.stdout.isTTY)
|
|
119
|
+
return;
|
|
120
|
+
process.stdout.write("\r\x1b[K");
|
|
121
|
+
}
|
package/dist/ui.d.ts
CHANGED
package/dist/ui.js
CHANGED
|
@@ -33,13 +33,21 @@ export async function runInteractiveUi(options) {
|
|
|
33
33
|
const selectedIds = filteredSkills.length === 0
|
|
34
34
|
? []
|
|
35
35
|
: await (prompts.checkbox || fallbackCheckbox)({
|
|
36
|
-
message: "
|
|
37
|
-
instructions: "
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
message: "Select skills",
|
|
37
|
+
instructions: "↑↓ navigate · space select · enter confirm · type to filter",
|
|
38
|
+
pageSize: 12,
|
|
39
|
+
choices: filteredSkills.map((skill) => {
|
|
40
|
+
const tags = (skill.tags ?? []).slice(0, 4).join(", ");
|
|
41
|
+
const detail = tags || (skill.description ?? "").slice(0, 55);
|
|
42
|
+
const label = detail
|
|
43
|
+
? `${skill.name} (${skill.id}) · ${detail}`
|
|
44
|
+
: `${skill.name} (${skill.id})`;
|
|
45
|
+
return {
|
|
46
|
+
name: label,
|
|
47
|
+
value: skill.id,
|
|
48
|
+
checked: installedSet.has(skill.id),
|
|
49
|
+
};
|
|
50
|
+
}),
|
|
43
51
|
});
|
|
44
52
|
const selectedSet = new Set(selectedIds);
|
|
45
53
|
const toInstall = selectedIds.filter((skillId) => !installedSet.has(skillId));
|
|
@@ -62,6 +70,7 @@ async function loadPromptAdapters() {
|
|
|
62
70
|
checkbox: async (options) => prompts.checkbox({
|
|
63
71
|
message: options.message,
|
|
64
72
|
...(options.instructions ? { instructions: options.instructions } : {}),
|
|
73
|
+
...(options.pageSize !== undefined ? { pageSize: options.pageSize } : {}),
|
|
65
74
|
choices: options.choices.map((choice) => ({
|
|
66
75
|
name: choice.name,
|
|
67
76
|
value: choice.value,
|