@meistrari/tela-cli 1.10.0 → 1.10.1
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/dist/commands/skills.js +6 -4
- package/dist/index.js +104 -39
- package/package.json +1 -1
package/dist/commands/skills.js
CHANGED
|
@@ -196,22 +196,24 @@ async function upgradeSkills(args, options, io) {
|
|
|
196
196
|
getClient: async () => (await (0, session_1.loadPantry)(flags)).client,
|
|
197
197
|
onDiagnostic: diagnostic => writeSkillManagerDiagnostic(io, diagnostic),
|
|
198
198
|
});
|
|
199
|
-
const { upgraded, unchanged } = await manager.upgradeSkills(flags.rest, {
|
|
199
|
+
const { upgraded, unchanged, replaced } = await manager.upgradeSkills(flags.rest, {
|
|
200
200
|
force: flags.force,
|
|
201
201
|
ignoreScripts: flags.ignoreScripts,
|
|
202
202
|
...(flags.symlink ? {} : { targets: [] }),
|
|
203
203
|
});
|
|
204
|
-
if (upgraded.length === 0 && unchanged.length === 0) {
|
|
204
|
+
if (upgraded.length === 0 && unchanged.length === 0 && replaced.length === 0) {
|
|
205
205
|
if (options.json)
|
|
206
|
-
(0, output_1.writeJson)(io, { upgraded: [], unchanged: [] });
|
|
206
|
+
(0, output_1.writeJson)(io, { upgraded: [], unchanged: [], replaced: [] });
|
|
207
207
|
else
|
|
208
208
|
(0, output_1.writeLine)(io, 'No skills installed.');
|
|
209
209
|
return 0;
|
|
210
210
|
}
|
|
211
211
|
if (options.json) {
|
|
212
|
-
(0, output_1.writeJson)(io, { upgraded, unchanged });
|
|
212
|
+
(0, output_1.writeJson)(io, { upgraded, unchanged, replaced });
|
|
213
213
|
return 0;
|
|
214
214
|
}
|
|
215
|
+
for (const { from, to } of replaced)
|
|
216
|
+
(0, output_1.writeLine)(io, `Replaced deprecated ${from} with ${to.slug} at ${to.sha.slice(0, 7)}`);
|
|
215
217
|
for (const entry of upgraded)
|
|
216
218
|
(0, output_1.writeLine)(io, `Upgraded ${entry.slug} to ${entry.sha.slice(0, 7)}`);
|
|
217
219
|
for (const slug of unchanged)
|
package/dist/index.js
CHANGED
|
@@ -77216,6 +77216,7 @@ var require_skills = __commonJS({
|
|
|
77216
77216
|
name: ingredient.name,
|
|
77217
77217
|
description: ingredient.description,
|
|
77218
77218
|
status: ingredient.status,
|
|
77219
|
+
replacement: ingredient.replacement,
|
|
77219
77220
|
// A listing carries the skill-only fields under `skillDetails`,
|
|
77220
77221
|
// which is null for anything Pantry has not synced as a skill.
|
|
77221
77222
|
bundle: ingredient.skillDetails?.bundle ?? null,
|
|
@@ -77338,13 +77339,42 @@ Run \`tela skills install ${slug} --force\` to replace it, or remove it by hand.
|
|
|
77338
77339
|
const diagnostics = [];
|
|
77339
77340
|
const upgraded = [];
|
|
77340
77341
|
const unchanged = [];
|
|
77342
|
+
const replaced = [];
|
|
77341
77343
|
const emit = createDiagnosticEmitter(options2, diagnostics);
|
|
77342
77344
|
if (selected.length === 0)
|
|
77343
|
-
return { upgraded, unchanged, diagnostics };
|
|
77345
|
+
return { upgraded, unchanged, replaced, diagnostics };
|
|
77344
77346
|
const targets = normalizeTargets(upgradeOptions.targets ?? paths.targets, paths.installRoot);
|
|
77345
77347
|
const client = await resolveClient();
|
|
77346
77348
|
for (const current of selected) {
|
|
77347
|
-
const { snapshot } = await (0, skills_1.fetchSkillFile)(client, current.slug);
|
|
77349
|
+
const { ingredient, snapshot } = await (0, skills_1.fetchSkillFile)(client, current.slug);
|
|
77350
|
+
const replacementSlug = await resolveReplacementSlug(client, current.slug, ingredient);
|
|
77351
|
+
if (replacementSlug) {
|
|
77352
|
+
const installedReplacement = (await (0, tela_local_config_1.listInstalledSkills)(inventoryFile)).find((entry2) => entry2.slug === replacementSlug);
|
|
77353
|
+
const replacement = await installOne({
|
|
77354
|
+
client,
|
|
77355
|
+
diagnostics: emit,
|
|
77356
|
+
...installedReplacement ? { expectedCurrent: installedReplacement, operation: "upgrade" } : {},
|
|
77357
|
+
force: upgradeOptions.force ?? false,
|
|
77358
|
+
ignoreScripts: upgradeOptions.ignoreScripts ?? false,
|
|
77359
|
+
inventoryFile,
|
|
77360
|
+
paths,
|
|
77361
|
+
slug: replacementSlug,
|
|
77362
|
+
targets
|
|
77363
|
+
});
|
|
77364
|
+
if (!replacement)
|
|
77365
|
+
continue;
|
|
77366
|
+
if (await uninstallOne({
|
|
77367
|
+
diagnostics: emit,
|
|
77368
|
+
entry: current,
|
|
77369
|
+
ignoreScripts: upgradeOptions.ignoreScripts ?? false,
|
|
77370
|
+
inventoryFile,
|
|
77371
|
+
operation: "upgrade",
|
|
77372
|
+
paths
|
|
77373
|
+
})) {
|
|
77374
|
+
replaced.push({ from: current.slug, to: replacement });
|
|
77375
|
+
}
|
|
77376
|
+
continue;
|
|
77377
|
+
}
|
|
77348
77378
|
if (snapshot.sha === current.sha) {
|
|
77349
77379
|
unchanged.push(current.slug);
|
|
77350
77380
|
continue;
|
|
@@ -77364,7 +77394,7 @@ Run \`tela skills install ${slug} --force\` to replace it, or remove it by hand.
|
|
|
77364
77394
|
if (entry)
|
|
77365
77395
|
upgraded.push(entry);
|
|
77366
77396
|
}
|
|
77367
|
-
return { upgraded, unchanged, diagnostics };
|
|
77397
|
+
return { upgraded, unchanged, replaced, diagnostics };
|
|
77368
77398
|
},
|
|
77369
77399
|
uninstallSkills: async (slugs, uninstallOptions = {}) => {
|
|
77370
77400
|
for (const slug of slugs)
|
|
@@ -77375,44 +77405,77 @@ Run \`tela skills install ${slug} --force\` to replace it, or remove it by hand.
|
|
|
77375
77405
|
const removed = [];
|
|
77376
77406
|
const emit = createDiagnosticEmitter(options2, diagnostics);
|
|
77377
77407
|
for (const entry of selected) {
|
|
77378
|
-
|
|
77379
|
-
|
|
77380
|
-
|
|
77381
|
-
|
|
77382
|
-
|
|
77383
|
-
|
|
77384
|
-
|
|
77385
|
-
|
|
77386
|
-
type: "concurrent-change",
|
|
77387
|
-
slug: entry.slug,
|
|
77388
|
-
operation: "uninstall",
|
|
77389
|
-
message: `Skipped ${entry.slug}: it was reinstalled while this uninstall ran`
|
|
77390
|
-
});
|
|
77391
|
-
return registered;
|
|
77392
|
-
}
|
|
77393
|
-
assertManagedInstallDir(entry.slug, registered, paths);
|
|
77394
|
-
for (const linkPath of registered.symlinks) {
|
|
77395
|
-
const outcome = await (0, skill_filesystem_1.removeManagedSymlink)(linkPath, registered.dir);
|
|
77396
|
-
if (outcome.reason) {
|
|
77397
|
-
emit({
|
|
77398
|
-
type: "link-removal-skipped",
|
|
77399
|
-
slug: entry.slug,
|
|
77400
|
-
path: linkPath,
|
|
77401
|
-
message: outcome.reason
|
|
77402
|
-
});
|
|
77403
|
-
}
|
|
77404
|
-
}
|
|
77405
|
-
await (0, promises_1.rm)(registered.dir, { recursive: true, force: true });
|
|
77406
|
-
gone = true;
|
|
77407
|
-
return null;
|
|
77408
|
-
}, inventoryFile);
|
|
77409
|
-
if (gone)
|
|
77408
|
+
if (await uninstallOne({
|
|
77409
|
+
diagnostics: emit,
|
|
77410
|
+
entry,
|
|
77411
|
+
ignoreScripts: uninstallOptions.ignoreScripts ?? false,
|
|
77412
|
+
inventoryFile,
|
|
77413
|
+
operation: "uninstall",
|
|
77414
|
+
paths
|
|
77415
|
+
})) {
|
|
77410
77416
|
removed.push(entry.slug);
|
|
77417
|
+
}
|
|
77411
77418
|
}
|
|
77412
77419
|
return { removed, diagnostics };
|
|
77413
77420
|
}
|
|
77414
77421
|
};
|
|
77415
77422
|
}
|
|
77423
|
+
var MAX_REPLACEMENT_HOPS = 5;
|
|
77424
|
+
async function resolveReplacementSlug(client, slug, ingredient) {
|
|
77425
|
+
let replacement = deprecatedReplacement(ingredient);
|
|
77426
|
+
if (!replacement)
|
|
77427
|
+
return null;
|
|
77428
|
+
const visited = /* @__PURE__ */ new Set([slug]);
|
|
77429
|
+
for (let hop = 0; hop < MAX_REPLACEMENT_HOPS; hop++) {
|
|
77430
|
+
(0, skill_filesystem_1.assertSafeSlug)(replacement, "upgrade");
|
|
77431
|
+
if (visited.has(replacement))
|
|
77432
|
+
throw new Error(`Pantry replacements for ${slug} form a cycle through ${replacement}.`);
|
|
77433
|
+
visited.add(replacement);
|
|
77434
|
+
const next = deprecatedReplacement((await (0, skills_1.fetchSkillFile)(client, replacement)).ingredient);
|
|
77435
|
+
if (!next)
|
|
77436
|
+
return replacement;
|
|
77437
|
+
replacement = next;
|
|
77438
|
+
}
|
|
77439
|
+
throw new Error(`Pantry replacements for ${slug} chain through more than ${MAX_REPLACEMENT_HOPS} deprecated skills.`);
|
|
77440
|
+
}
|
|
77441
|
+
function deprecatedReplacement(ingredient) {
|
|
77442
|
+
return ingredient.status === "deprecated" && ingredient.replacement ? ingredient.replacement : null;
|
|
77443
|
+
}
|
|
77444
|
+
async function uninstallOne(options2) {
|
|
77445
|
+
const { entry, paths } = options2;
|
|
77446
|
+
assertManagedInstallDir(entry.slug, entry, paths);
|
|
77447
|
+
await runLifecycle(entry, "uninstall", options2.ignoreScripts, options2.diagnostics);
|
|
77448
|
+
let gone = false;
|
|
77449
|
+
await (0, tela_local_config_1.updateInstalledSkill)(entry.slug, async (registered) => {
|
|
77450
|
+
if (registered === null)
|
|
77451
|
+
return null;
|
|
77452
|
+
if (!isSameInstall(registered, entry)) {
|
|
77453
|
+
options2.diagnostics({
|
|
77454
|
+
type: "concurrent-change",
|
|
77455
|
+
slug: entry.slug,
|
|
77456
|
+
operation: options2.operation,
|
|
77457
|
+
message: `Skipped ${entry.slug}: it was reinstalled while this ${options2.operation} ran`
|
|
77458
|
+
});
|
|
77459
|
+
return registered;
|
|
77460
|
+
}
|
|
77461
|
+
assertManagedInstallDir(entry.slug, registered, paths);
|
|
77462
|
+
for (const linkPath of registered.symlinks) {
|
|
77463
|
+
const outcome = await (0, skill_filesystem_1.removeManagedSymlink)(linkPath, registered.dir);
|
|
77464
|
+
if (outcome.reason) {
|
|
77465
|
+
options2.diagnostics({
|
|
77466
|
+
type: "link-removal-skipped",
|
|
77467
|
+
slug: entry.slug,
|
|
77468
|
+
path: linkPath,
|
|
77469
|
+
message: outcome.reason
|
|
77470
|
+
});
|
|
77471
|
+
}
|
|
77472
|
+
}
|
|
77473
|
+
await (0, promises_1.rm)(registered.dir, { recursive: true, force: true });
|
|
77474
|
+
gone = true;
|
|
77475
|
+
return null;
|
|
77476
|
+
}, options2.inventoryFile);
|
|
77477
|
+
return gone;
|
|
77478
|
+
}
|
|
77416
77479
|
function createDiagnosticEmitter(options2, diagnostics) {
|
|
77417
77480
|
return (diagnostic) => {
|
|
77418
77481
|
diagnostics.push(diagnostic);
|
|
@@ -389037,22 +389100,24 @@ async function upgradeSkills(args, options2, io) {
|
|
|
389037
389100
|
getClient: async () => (await loadPantry(flags)).client,
|
|
389038
389101
|
onDiagnostic: (diagnostic) => writeSkillManagerDiagnostic(io, diagnostic)
|
|
389039
389102
|
});
|
|
389040
|
-
const { upgraded, unchanged } = await manager.upgradeSkills(flags.rest, {
|
|
389103
|
+
const { upgraded, unchanged, replaced } = await manager.upgradeSkills(flags.rest, {
|
|
389041
389104
|
force: flags.force,
|
|
389042
389105
|
ignoreScripts: flags.ignoreScripts,
|
|
389043
389106
|
...flags.symlink ? {} : { targets: [] }
|
|
389044
389107
|
});
|
|
389045
|
-
if (upgraded.length === 0 && unchanged.length === 0) {
|
|
389108
|
+
if (upgraded.length === 0 && unchanged.length === 0 && replaced.length === 0) {
|
|
389046
389109
|
if (options2.json)
|
|
389047
|
-
writeJson(io, { upgraded: [], unchanged: [] });
|
|
389110
|
+
writeJson(io, { upgraded: [], unchanged: [], replaced: [] });
|
|
389048
389111
|
else
|
|
389049
389112
|
writeLine(io, "No skills installed.");
|
|
389050
389113
|
return 0;
|
|
389051
389114
|
}
|
|
389052
389115
|
if (options2.json) {
|
|
389053
|
-
writeJson(io, { upgraded, unchanged });
|
|
389116
|
+
writeJson(io, { upgraded, unchanged, replaced });
|
|
389054
389117
|
return 0;
|
|
389055
389118
|
}
|
|
389119
|
+
for (const { from, to } of replaced)
|
|
389120
|
+
writeLine(io, `Replaced deprecated ${from} with ${to.slug} at ${to.sha.slice(0, 7)}`);
|
|
389056
389121
|
for (const entry of upgraded)
|
|
389057
389122
|
writeLine(io, `Upgraded ${entry.slug} to ${entry.sha.slice(0, 7)}`);
|
|
389058
389123
|
for (const slug of unchanged)
|