antikit 1.12.7 → 1.12.8
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/package.json +1 -1
- package/src/commands/upgrade.js +243 -9
- package/src/index.js +1 -0
- package/src/utils/configManager.js +20 -1
- package/src/utils/constants.js +1 -1
package/package.json
CHANGED
package/src/commands/upgrade.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
2
3
|
import { readdirSync, existsSync, readFileSync } from 'fs';
|
|
3
4
|
import { join } from 'path';
|
|
5
|
+
import { checkbox, confirm, Separator } from '@inquirer/prompts';
|
|
6
|
+
import Table from 'cli-table3';
|
|
4
7
|
import { getOrCreateSkillsDir } from '../utils/local.js';
|
|
5
8
|
import { installSkill } from './install.js';
|
|
6
|
-
import {
|
|
9
|
+
import { fetchSkillInfo } from '../utils/github.js';
|
|
10
|
+
import { compareVersions, DEFAULT_VERSION } from '../utils/version.js';
|
|
11
|
+
import { METADATA_FILE } from '../utils/constants.js';
|
|
7
12
|
|
|
8
13
|
export async function upgradeSkills(skillName, options = {}) {
|
|
9
14
|
const skillsDir = getOrCreateSkillsDir();
|
|
@@ -18,31 +23,230 @@ export async function upgradeSkills(skillName, options = {}) {
|
|
|
18
23
|
return;
|
|
19
24
|
}
|
|
20
25
|
|
|
21
|
-
// 2.
|
|
22
|
-
const
|
|
26
|
+
// 2. Get all installed skills
|
|
27
|
+
const skillNames = readdirSync(skillsDir).filter(
|
|
23
28
|
f => existsSync(join(skillsDir, f)) && !f.startsWith('.')
|
|
24
29
|
);
|
|
25
30
|
|
|
26
|
-
if (
|
|
31
|
+
if (skillNames.length === 0) {
|
|
27
32
|
console.log(chalk.yellow('No skills installed.'));
|
|
28
33
|
return;
|
|
29
34
|
}
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
// 3. Fetch skill metadata and check for updates
|
|
37
|
+
const spinner = ora('Checking for updates...').start();
|
|
38
|
+
const skillsWithInfo = [];
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
for (const skillName of skillNames) {
|
|
41
|
+
const metaPath = join(skillsDir, skillName, METADATA_FILE);
|
|
42
|
+
|
|
43
|
+
if (!existsSync(metaPath)) {
|
|
44
|
+
skillsWithInfo.push({
|
|
45
|
+
name: skillName,
|
|
46
|
+
localVersion: DEFAULT_VERSION,
|
|
47
|
+
remoteVersion: null,
|
|
48
|
+
updateAvailable: false,
|
|
49
|
+
error: 'Missing metadata'
|
|
50
|
+
});
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const meta = JSON.parse(readFileSync(metaPath, 'utf-8'));
|
|
56
|
+
const localVersion = meta.version || DEFAULT_VERSION;
|
|
57
|
+
|
|
58
|
+
if (!meta.source || !meta.source.owner || !meta.source.repo) {
|
|
59
|
+
skillsWithInfo.push({
|
|
60
|
+
name: skillName,
|
|
61
|
+
localVersion,
|
|
62
|
+
remoteVersion: null,
|
|
63
|
+
updateAvailable: false,
|
|
64
|
+
error: 'Invalid metadata',
|
|
65
|
+
meta
|
|
66
|
+
});
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Fetch remote version
|
|
71
|
+
const info = await fetchSkillInfo(
|
|
72
|
+
skillName,
|
|
73
|
+
meta.source.owner,
|
|
74
|
+
meta.source.repo,
|
|
75
|
+
meta.source.path || '',
|
|
76
|
+
meta.source.branch || 'main'
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const remoteVersion = info ? info.version : DEFAULT_VERSION;
|
|
80
|
+
const updateAvailable = compareVersions(remoteVersion, localVersion) > 0;
|
|
81
|
+
|
|
82
|
+
skillsWithInfo.push({
|
|
83
|
+
name: skillName,
|
|
84
|
+
localVersion,
|
|
85
|
+
remoteVersion,
|
|
86
|
+
updateAvailable,
|
|
87
|
+
description: info ? info.description : meta.description,
|
|
88
|
+
meta
|
|
89
|
+
});
|
|
90
|
+
} catch (error) {
|
|
91
|
+
skillsWithInfo.push({
|
|
92
|
+
name: skillName,
|
|
93
|
+
localVersion: DEFAULT_VERSION,
|
|
94
|
+
remoteVersion: null,
|
|
95
|
+
updateAvailable: false,
|
|
96
|
+
error: error.message
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
spinner.succeed(`Found ${skillsWithInfo.length} installed skills`);
|
|
102
|
+
console.log();
|
|
103
|
+
|
|
104
|
+
// 4. Check if interactive mode or auto-upgrade mode
|
|
105
|
+
if (options.interactive || (!options.yes && process.stdout.isTTY)) {
|
|
106
|
+
await interactiveUpgrade(skillsDir, skillsWithInfo);
|
|
107
|
+
} else {
|
|
108
|
+
await autoUpgradeAll(skillsDir, skillsWithInfo, options.yes);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
async function interactiveUpgrade(skillsDir, skills) {
|
|
114
|
+
// Sort skills: updateAvailable first, then by name
|
|
115
|
+
skills.sort((a, b) => {
|
|
116
|
+
if (a.updateAvailable && !b.updateAvailable) return -1;
|
|
117
|
+
if (!a.updateAvailable && b.updateAvailable) return 1;
|
|
118
|
+
return a.name.localeCompare(b.name);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const hasUpdates = skills.some(s => s.updateAvailable);
|
|
122
|
+
|
|
123
|
+
if (!hasUpdates) {
|
|
124
|
+
console.log(chalk.green('✓ All skills are up to date!'));
|
|
125
|
+
console.log();
|
|
126
|
+
displaySkillsTable(skills);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
console.log(chalk.bold('Select skills to upgrade:\n'));
|
|
131
|
+
|
|
132
|
+
const choices = skills.map(skill => {
|
|
133
|
+
let label = '';
|
|
134
|
+
let disabled = false;
|
|
135
|
+
|
|
136
|
+
if (skill.error) {
|
|
137
|
+
label = `${chalk.red('✗')} ${chalk.cyan(skill.name)} ${chalk.dim(`(${skill.error})`)}`;
|
|
138
|
+
disabled = `Cannot upgrade: ${skill.error}`;
|
|
139
|
+
} else if (skill.updateAvailable) {
|
|
140
|
+
label = `${chalk.yellow('↑')} ${chalk.cyan(skill.name)} ${chalk.yellow(`v${skill.localVersion} → v${skill.remoteVersion}`)}`;
|
|
141
|
+
} else {
|
|
142
|
+
label = `${chalk.green('✓')} ${chalk.cyan(skill.name)} ${chalk.dim(`v${skill.localVersion} (Up to date)`)}`;
|
|
143
|
+
disabled = true;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (skill.description && !skill.error) {
|
|
147
|
+
label += ` ${chalk.dim('- ' + skill.description.slice(0, 80) + (skill.description.length > 80 ? '...' : ''))}`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
name: label,
|
|
152
|
+
value: skill,
|
|
153
|
+
disabled
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Show checkbox selection
|
|
158
|
+
const selected = await checkbox({
|
|
159
|
+
message: 'Select skills to upgrade:',
|
|
160
|
+
choices,
|
|
161
|
+
pageSize: 20,
|
|
162
|
+
loop: false
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
if (selected.length === 0) {
|
|
166
|
+
console.log(chalk.yellow('\nNo skills selected.'));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Confirm upgrade
|
|
171
|
+
const shouldUpgrade = await confirm({
|
|
172
|
+
message: `Upgrade ${selected.length} skill(s)?`,
|
|
173
|
+
default: true
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
if (!shouldUpgrade) {
|
|
177
|
+
console.log(chalk.yellow('Operation cancelled.'));
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Upgrade selected skills
|
|
182
|
+
console.log();
|
|
183
|
+
let successCount = 0;
|
|
184
|
+
let failCount = 0;
|
|
185
|
+
|
|
186
|
+
for (const skill of selected) {
|
|
187
|
+
try {
|
|
188
|
+
await upgradeSingleSkill(skillsDir, skill.name);
|
|
189
|
+
successCount++;
|
|
190
|
+
} catch {
|
|
191
|
+
failCount++;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
console.log('\n────────────────────────────────────────');
|
|
196
|
+
if (failCount === 0) {
|
|
197
|
+
console.log(chalk.green(`✓ All ${successCount} skills upgraded successfully`));
|
|
198
|
+
} else {
|
|
199
|
+
console.log(chalk.yellow(`⚠ Upgraded ${successCount} skills, ${failCount} failed`));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async function autoUpgradeAll(skillsDir, skills, autoYes) {
|
|
204
|
+
const upgradableSkills = skills.filter(s => s.updateAvailable && !s.error);
|
|
205
|
+
|
|
206
|
+
if (upgradableSkills.length === 0) {
|
|
207
|
+
console.log(chalk.green('✓ All skills are up to date!'));
|
|
208
|
+
console.log();
|
|
209
|
+
displaySkillsTable(skills);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
console.log(chalk.blue(`Found ${upgradableSkills.length} skill(s) with available updates:`));
|
|
214
|
+
console.log();
|
|
215
|
+
|
|
216
|
+
// Display table of upgradable skills
|
|
217
|
+
const table = new Table({
|
|
218
|
+
head: [chalk.cyan('Skill Name'), chalk.cyan('Current'), chalk.cyan('Latest')],
|
|
219
|
+
colWidths: [30, 15, 15],
|
|
220
|
+
style: { head: [], border: [] }
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
upgradableSkills.forEach(skill => {
|
|
224
|
+
table.push([
|
|
225
|
+
chalk.bold.cyan(skill.name),
|
|
226
|
+
chalk.dim(skill.localVersion),
|
|
227
|
+
chalk.yellow(skill.remoteVersion)
|
|
228
|
+
]);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
console.log(table.toString());
|
|
232
|
+
console.log();
|
|
233
|
+
|
|
234
|
+
let shouldProceed = autoYes;
|
|
34
235
|
if (!shouldProceed) {
|
|
35
236
|
shouldProceed = await confirm({ message: 'Upgrade all skills?', default: true });
|
|
36
237
|
}
|
|
37
238
|
|
|
38
|
-
if (!shouldProceed)
|
|
239
|
+
if (!shouldProceed) {
|
|
240
|
+
console.log(chalk.yellow('Operation cancelled.'));
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
39
243
|
|
|
40
244
|
let successCount = 0;
|
|
41
245
|
let failCount = 0;
|
|
42
246
|
|
|
43
|
-
for (const skill of
|
|
247
|
+
for (const skill of upgradableSkills) {
|
|
44
248
|
try {
|
|
45
|
-
await upgradeSingleSkill(skillsDir, skill);
|
|
249
|
+
await upgradeSingleSkill(skillsDir, skill.name);
|
|
46
250
|
successCount++;
|
|
47
251
|
} catch {
|
|
48
252
|
failCount++;
|
|
@@ -57,6 +261,34 @@ export async function upgradeSkills(skillName, options = {}) {
|
|
|
57
261
|
}
|
|
58
262
|
}
|
|
59
263
|
|
|
264
|
+
function displaySkillsTable(skills) {
|
|
265
|
+
const table = new Table({
|
|
266
|
+
head: [chalk.cyan('Skill Name'), chalk.cyan('Version'), chalk.cyan('Status')],
|
|
267
|
+
colWidths: [30, 15, 20],
|
|
268
|
+
style: { head: [], border: [] }
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
skills.forEach(skill => {
|
|
272
|
+
let status = '';
|
|
273
|
+
if (skill.error) {
|
|
274
|
+
status = chalk.red('Error');
|
|
275
|
+
} else if (skill.updateAvailable) {
|
|
276
|
+
status = chalk.yellow('Update available');
|
|
277
|
+
} else {
|
|
278
|
+
status = chalk.green('Up to date');
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
table.push([
|
|
282
|
+
chalk.bold.cyan(skill.name),
|
|
283
|
+
skill.error ? chalk.dim(skill.localVersion) : skill.localVersion,
|
|
284
|
+
status
|
|
285
|
+
]);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
console.log(table.toString());
|
|
289
|
+
console.log();
|
|
290
|
+
}
|
|
291
|
+
|
|
60
292
|
async function upgradeSingleSkill(skillsDir, skillName) {
|
|
61
293
|
const skillPath = join(skillsDir, skillName);
|
|
62
294
|
const metaPath = join(skillPath, '.antikit-skill.json');
|
|
@@ -79,6 +311,7 @@ async function upgradeSingleSkill(skillsDir, skillName) {
|
|
|
79
311
|
force: true,
|
|
80
312
|
owner: meta.source.owner,
|
|
81
313
|
repo: meta.source.repo,
|
|
314
|
+
path: meta.source.path, // Pass path from metadata
|
|
82
315
|
noExit: true // Don't kill process on error
|
|
83
316
|
});
|
|
84
317
|
} catch (error) {
|
|
@@ -86,3 +319,4 @@ async function upgradeSingleSkill(skillsDir, skillName) {
|
|
|
86
319
|
throw error;
|
|
87
320
|
}
|
|
88
321
|
}
|
|
322
|
+
|
package/src/index.js
CHANGED
|
@@ -54,7 +54,26 @@ export function loadConfig() {
|
|
|
54
54
|
|
|
55
55
|
try {
|
|
56
56
|
const content = readFileSync(CONFIG_FILE, 'utf-8');
|
|
57
|
-
|
|
57
|
+
const config = JSON.parse(content);
|
|
58
|
+
|
|
59
|
+
// Migration: Rename legacy "official" source to "antiskills"
|
|
60
|
+
let needsSave = false;
|
|
61
|
+
if (config.sources) {
|
|
62
|
+
config.sources = config.sources.map(source => {
|
|
63
|
+
if (source.name === 'official') {
|
|
64
|
+
needsSave = true;
|
|
65
|
+
return { ...source, name: OFFICIAL_SOURCE };
|
|
66
|
+
}
|
|
67
|
+
return source;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Save migrated config
|
|
72
|
+
if (needsSave) {
|
|
73
|
+
saveConfig(config);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return config;
|
|
58
77
|
} catch {
|
|
59
78
|
return DEFAULT_CONFIG;
|
|
60
79
|
}
|