aweskill 0.1.5 → 0.1.7

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/index.js CHANGED
@@ -4,18 +4,41 @@
4
4
  import { Command } from "commander";
5
5
  import { homedir as homedir2 } from "os";
6
6
 
7
+ // src/commands/backup.ts
8
+ import path3 from "path";
9
+
7
10
  // src/lib/backup.ts
8
- import { access, mkdtemp, mkdir } from "fs/promises";
11
+ import { mkdtemp, mkdir, stat } from "fs/promises";
9
12
  import { tmpdir } from "os";
10
13
  import path2 from "path";
11
14
  import { spawn } from "child_process";
12
15
 
16
+ // src/lib/fs.ts
17
+ import { access } from "fs/promises";
18
+ async function pathExists(targetPath) {
19
+ try {
20
+ await access(targetPath);
21
+ return true;
22
+ } catch {
23
+ return false;
24
+ }
25
+ }
26
+
13
27
  // src/lib/path.ts
14
28
  import { homedir } from "os";
15
29
  import path from "path";
16
30
  function sanitizeName(input) {
17
31
  return input.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+/, "").replace(/-+$/, "").slice(0, 80);
18
32
  }
33
+ function expandHomePath(targetPath, homeDir = homedir()) {
34
+ if (targetPath === "~") {
35
+ return homeDir;
36
+ }
37
+ if (targetPath.startsWith("~/")) {
38
+ return path.join(homeDir, targetPath.slice(2));
39
+ }
40
+ return targetPath;
41
+ }
19
42
  function getAweskillPaths(homeDir) {
20
43
  const rootDir = path.join(homeDir, ".aweskill");
21
44
  return {
@@ -51,11 +74,19 @@ async function runTar(args) {
51
74
  });
52
75
  });
53
76
  }
54
- async function createSkillsBackupArchive(homeDir) {
55
- const { rootDir, skillsDir, backupDir } = getAweskillPaths(homeDir);
56
- await mkdir(backupDir, { recursive: true });
57
- const archivePath = await nextBackupArchivePath(backupDir);
58
- await runTar(["-czf", archivePath, "-C", rootDir, path2.relative(rootDir, skillsDir)]);
77
+ function formatBackupLabel(includeBundles) {
78
+ return includeBundles ? "skills and bundles" : "skills";
79
+ }
80
+ function archiveEntries(homeDir, includeBundles) {
81
+ const { rootDir, skillsDir, bundlesDir } = getAweskillPaths(homeDir);
82
+ return includeBundles ? [path2.relative(rootDir, skillsDir), path2.relative(rootDir, bundlesDir)] : [path2.relative(rootDir, skillsDir)];
83
+ }
84
+ async function createSkillsBackupArchive(homeDir, options = {}) {
85
+ const { rootDir, backupDir } = getAweskillPaths(homeDir);
86
+ const includeBundles = options.includeBundles ?? false;
87
+ const archivePath = await resolveBackupArchivePath(backupDir, options.archivePath);
88
+ await mkdir(path2.dirname(archivePath), { recursive: true });
89
+ await runTar(["-czf", archivePath, "-C", rootDir, ...archiveEntries(homeDir, includeBundles)]);
59
90
  return archivePath;
60
91
  }
61
92
  async function extractSkillsArchive(archivePath) {
@@ -63,9 +94,23 @@ async function extractSkillsArchive(archivePath) {
63
94
  await runTar(["-xzf", archivePath, "-C", tempDir]);
64
95
  return {
65
96
  tempDir,
66
- extractedSkillsDir: path2.join(tempDir, "skills")
97
+ extractedSkillsDir: path2.join(tempDir, "skills"),
98
+ extractedBundlesDir: path2.join(tempDir, "bundles")
67
99
  };
68
100
  }
101
+ async function resolveBackupArchivePath(backupDir, requestedPath) {
102
+ if (!requestedPath) {
103
+ return nextBackupArchivePath(backupDir);
104
+ }
105
+ try {
106
+ const requestedStats = await stat(requestedPath);
107
+ if (requestedStats.isDirectory()) {
108
+ return nextBackupArchivePath(requestedPath);
109
+ }
110
+ } catch {
111
+ }
112
+ return requestedPath;
113
+ }
69
114
  async function nextBackupArchivePath(backupDir) {
70
115
  const base = `skills-${formatTimestamp(/* @__PURE__ */ new Date())}`;
71
116
  const primary = path2.join(backupDir, `${base}.tar.gz`);
@@ -81,38 +126,25 @@ async function nextBackupArchivePath(backupDir) {
81
126
  index += 1;
82
127
  }
83
128
  }
84
- async function pathExists(targetPath) {
85
- try {
86
- await access(targetPath);
87
- return true;
88
- } catch {
89
- return false;
90
- }
91
- }
92
129
 
93
130
  // src/commands/backup.ts
94
- async function runBackup(context) {
95
- const archivePath = await createSkillsBackupArchive(context.homeDir);
96
- context.write(`Backed up skills to ${archivePath}`);
131
+ async function runBackup(context, options = {}) {
132
+ const archivePath = await createSkillsBackupArchive(context.homeDir, {
133
+ archivePath: options.archivePath ? path3.resolve(context.cwd, expandHomePath(options.archivePath, context.homeDir)) : void 0,
134
+ includeBundles: options.includeBundles
135
+ });
136
+ context.write(`Backed up ${formatBackupLabel(options.includeBundles ?? false)} to ${archivePath}`);
97
137
  return { archivePath };
98
138
  }
99
139
 
100
140
  // src/lib/bundles.ts
101
- import { access as access3, mkdir as mkdir3, readFile, readdir as readdir2, rm, writeFile } from "fs/promises";
102
- import path4 from "path";
141
+ import { mkdir as mkdir3, readFile, readdir as readdir2, rm, writeFile } from "fs/promises";
142
+ import path5 from "path";
103
143
  import { parse, stringify } from "yaml";
104
144
 
105
145
  // src/lib/skills.ts
106
- import { access as access2, mkdir as mkdir2, readdir } from "fs/promises";
107
- import path3 from "path";
108
- async function pathExists2(targetPath) {
109
- try {
110
- await access2(targetPath);
111
- return true;
112
- } catch {
113
- return false;
114
- }
115
- }
146
+ import { mkdir as mkdir2, readdir } from "fs/promises";
147
+ import path4 from "path";
116
148
  async function ensureHomeLayout(homeDir) {
117
149
  const paths = getAweskillPaths(homeDir);
118
150
  await mkdir2(paths.rootDir, { recursive: true });
@@ -122,53 +154,45 @@ async function ensureHomeLayout(homeDir) {
122
154
  await mkdir2(paths.bundlesDir, { recursive: true });
123
155
  }
124
156
  function getSkillPath(homeDir, skillName) {
125
- return path3.join(getAweskillPaths(homeDir).skillsDir, sanitizeName(skillName));
157
+ return path4.join(getAweskillPaths(homeDir).skillsDir, sanitizeName(skillName));
126
158
  }
127
159
  async function listSkills(homeDir) {
128
160
  const skillsDir = getAweskillPaths(homeDir).skillsDir;
129
161
  return listSkillEntriesInDirectory(skillsDir);
130
162
  }
131
163
  async function listSkillEntriesInDirectory(skillsDir) {
132
- if (!await pathExists2(skillsDir)) {
164
+ if (!await pathExists(skillsDir)) {
133
165
  return [];
134
166
  }
135
167
  const entries = await readdir(skillsDir, { withFileTypes: true });
136
168
  const skills = await Promise.all(
137
169
  entries.filter((entry) => entry.isDirectory() || entry.isSymbolicLink()).map(async (entry) => {
138
- const skillPath = path3.join(skillsDir, entry.name);
170
+ const skillPath = path4.join(skillsDir, entry.name);
139
171
  return {
140
172
  name: entry.name,
141
173
  path: skillPath,
142
- hasSKILLMd: await pathExists2(path3.join(skillPath, "SKILL.md"))
174
+ hasSKILLMd: await pathExists(path4.join(skillPath, "SKILL.md"))
143
175
  };
144
176
  })
145
177
  );
146
178
  return skills.sort((left, right) => left.name.localeCompare(right.name));
147
179
  }
148
180
  async function assertSkillSource(sourcePath) {
149
- const skillReadme = path3.join(sourcePath, "SKILL.md");
150
- if (!await pathExists2(skillReadme)) {
181
+ const skillReadme = path4.join(sourcePath, "SKILL.md");
182
+ if (!await pathExists(skillReadme)) {
151
183
  throw new Error(`Skill source must contain SKILL.md: ${sourcePath}`);
152
184
  }
153
185
  }
154
186
  async function skillExists(homeDir, skillName) {
155
- return pathExists2(getSkillPath(homeDir, skillName));
187
+ return pathExists(getSkillPath(homeDir, skillName));
156
188
  }
157
189
 
158
190
  // src/lib/bundles.ts
159
- async function pathExists3(targetPath) {
160
- try {
161
- await access3(targetPath);
162
- return true;
163
- } catch {
164
- return false;
165
- }
166
- }
167
191
  function bundleFilePath(homeDir, bundleName) {
168
- return path4.join(getAweskillPaths(homeDir).bundlesDir, `${sanitizeName(bundleName)}.yaml`);
192
+ return path5.join(getAweskillPaths(homeDir).bundlesDir, `${sanitizeName(bundleName)}.yaml`);
169
193
  }
170
194
  function bundleFilePathInDirectory(bundlesDir, bundleName) {
171
- return path4.join(bundlesDir, `${sanitizeName(bundleName)}.yaml`);
195
+ return path5.join(bundlesDir, `${sanitizeName(bundleName)}.yaml`);
172
196
  }
173
197
  function normalizeBundle(raw, fallbackName) {
174
198
  const data = raw ?? {};
@@ -202,7 +226,7 @@ async function readBundleFromDirectory(bundlesDir, bundleName) {
202
226
  async function writeBundle(homeDir, bundle) {
203
227
  const normalized = normalizeBundle(bundle, bundle.name);
204
228
  const filePath = bundleFilePath(homeDir, normalized.name);
205
- await mkdir3(path4.dirname(filePath), { recursive: true });
229
+ await mkdir3(path5.dirname(filePath), { recursive: true });
206
230
  await writeFile(filePath, stringify(normalized), "utf8");
207
231
  return normalized;
208
232
  }
@@ -227,7 +251,7 @@ async function removeSkillFromBundle(homeDir, bundleName, skillName) {
227
251
  }
228
252
  async function deleteBundle(homeDir, bundleName) {
229
253
  const filePath = bundleFilePath(homeDir, bundleName);
230
- if (!await pathExists3(filePath)) {
254
+ if (!await pathExists(filePath)) {
231
255
  return false;
232
256
  }
233
257
  await rm(filePath, { force: true });
@@ -235,25 +259,16 @@ async function deleteBundle(homeDir, bundleName) {
235
259
  }
236
260
 
237
261
  // src/lib/templates.ts
238
- import { access as access4 } from "fs/promises";
239
- import path5 from "path";
262
+ import path6 from "path";
240
263
  import { fileURLToPath } from "url";
241
- async function pathExists4(targetPath) {
242
- try {
243
- await access4(targetPath);
244
- return true;
245
- } catch {
246
- return false;
247
- }
248
- }
249
264
  async function getTemplateBundlesDir() {
250
- const moduleDir = path5.dirname(fileURLToPath(import.meta.url));
265
+ const moduleDir = path6.dirname(fileURLToPath(import.meta.url));
251
266
  const candidates = [
252
- path5.resolve(moduleDir, "..", "..", "template", "bundles"),
253
- path5.resolve(moduleDir, "..", "template", "bundles")
267
+ path6.resolve(moduleDir, "..", "..", "resources", "bundle_templates"),
268
+ path6.resolve(moduleDir, "..", "resources", "bundle_templates")
254
269
  ];
255
270
  for (const candidate of candidates) {
256
- if (await pathExists4(candidate)) {
271
+ if (await pathExists(candidate)) {
257
272
  return candidate;
258
273
  }
259
274
  }
@@ -337,8 +352,8 @@ async function runBundleAddTemplate(context, bundleName) {
337
352
  }
338
353
 
339
354
  // src/lib/import.ts
340
- import { access as access5, cp, lstat, mkdir as mkdir4, readlink, readdir as readdir3, rename, rm as rm2, stat } from "fs/promises";
341
- import path6 from "path";
355
+ import { cp, lstat, mkdir as mkdir4, readlink, readdir as readdir3, rename, rm as rm2, stat as stat2 } from "fs/promises";
356
+ import path7 from "path";
342
357
  var MissingSymlinkSourceError = class extends Error {
343
358
  sourcePath;
344
359
  resolvedSourcePath;
@@ -349,14 +364,6 @@ var MissingSymlinkSourceError = class extends Error {
349
364
  this.resolvedSourcePath = resolvedSourcePath;
350
365
  }
351
366
  };
352
- async function pathExists5(targetPath) {
353
- try {
354
- await access5(targetPath);
355
- return true;
356
- } catch {
357
- return false;
358
- }
359
- }
360
367
  async function resolveImportSource(sourcePath) {
361
368
  const statResult = await lstat(sourcePath);
362
369
  if (!statResult.isSymbolicLink()) {
@@ -366,8 +373,8 @@ async function resolveImportSource(sourcePath) {
366
373
  };
367
374
  }
368
375
  const linkTarget = await readlink(sourcePath);
369
- const resolvedSourcePath = path6.resolve(path6.dirname(sourcePath), linkTarget);
370
- if (!await pathExists5(resolvedSourcePath)) {
376
+ const resolvedSourcePath = path7.resolve(path7.dirname(sourcePath), linkTarget);
377
+ if (!await pathExists(resolvedSourcePath)) {
371
378
  throw new MissingSymlinkSourceError(sourcePath, resolvedSourcePath);
372
379
  }
373
380
  return {
@@ -376,30 +383,30 @@ async function resolveImportSource(sourcePath) {
376
383
  };
377
384
  }
378
385
  async function mergeMissingEntries(sourcePath, destinationPath) {
379
- const sourceStat = await stat(sourcePath);
386
+ const sourceStat = await stat2(sourcePath);
380
387
  if (sourceStat.isDirectory()) {
381
388
  await mkdir4(destinationPath, { recursive: true });
382
389
  const entries = await readdir3(sourcePath, { withFileTypes: true });
383
390
  for (const entry of entries) {
384
- await mergeMissingEntries(path6.join(sourcePath, entry.name), path6.join(destinationPath, entry.name));
391
+ await mergeMissingEntries(path7.join(sourcePath, entry.name), path7.join(destinationPath, entry.name));
385
392
  }
386
393
  return;
387
394
  }
388
- if (await pathExists5(destinationPath)) {
395
+ if (await pathExists(destinationPath)) {
389
396
  return;
390
397
  }
391
- await mkdir4(path6.dirname(destinationPath), { recursive: true });
398
+ await mkdir4(path7.dirname(destinationPath), { recursive: true });
392
399
  await cp(sourcePath, destinationPath, { recursive: false, errorOnExist: true, force: false });
393
400
  }
394
401
  async function copyIntoDestination(sourcePath, destination, override) {
395
- if (!override && await pathExists5(destination)) {
402
+ if (!override && await pathExists(destination)) {
396
403
  await mergeMissingEntries(sourcePath, destination);
397
404
  return;
398
405
  }
399
406
  await cp(sourcePath, destination, { recursive: true, errorOnExist: false, force: override });
400
407
  }
401
408
  async function moveIntoDestination(sourcePath, destination, override) {
402
- if (!await pathExists5(destination)) {
409
+ if (!await pathExists(destination)) {
403
410
  await rename(sourcePath, destination);
404
411
  return;
405
412
  }
@@ -464,8 +471,8 @@ async function listImportableChildren(sourceRoot) {
464
471
  if (!(entry.isDirectory() || entry.isSymbolicLink())) {
465
472
  continue;
466
473
  }
467
- const childPath = path6.join(sourceRoot, entry.name);
468
- if (await pathExists5(path6.join(childPath, "SKILL.md"))) {
474
+ const childPath = path7.join(sourceRoot, entry.name);
475
+ if (await pathExists(path7.join(childPath, "SKILL.md"))) {
469
476
  sources.push({
470
477
  name: sanitizeName(entry.name),
471
478
  path: childPath
@@ -484,12 +491,12 @@ async function listImportableChildren(sourceRoot) {
484
491
  async function importSkill(options) {
485
492
  const { effectiveSourcePath, isSymlinkSource } = await resolveImportSource(options.sourcePath);
486
493
  await assertSkillSource(effectiveSourcePath);
487
- const skillName = sanitizeName(path6.basename(options.sourcePath));
494
+ const skillName = sanitizeName(path7.basename(options.sourcePath));
488
495
  if (!skillName) {
489
496
  throw new Error(`Unable to infer skill name from path: ${options.sourcePath}`);
490
497
  }
491
498
  const destination = getSkillPath(options.homeDir, skillName);
492
- await mkdir4(path6.dirname(destination), { recursive: true });
499
+ await mkdir4(path7.dirname(destination), { recursive: true });
493
500
  const warnings = [];
494
501
  if (isSymlinkSource) {
495
502
  warnings.push(`Source ${options.sourcePath} is a symlink; copied from ${effectiveSourcePath} to ${destination}`);
@@ -513,8 +520,8 @@ async function importScannedSkills(options) {
513
520
  });
514
521
  }
515
522
  async function importPath(options) {
516
- if (await pathExists5(path6.join(options.sourcePath, "SKILL.md"))) {
517
- const skillName = sanitizeName(path6.basename(options.sourcePath));
523
+ if (await pathExists(path7.join(options.sourcePath, "SKILL.md"))) {
524
+ const skillName = sanitizeName(path7.basename(options.sourcePath));
518
525
  const alreadyExisted = skillName ? await skillExists(options.homeDir, skillName) : false;
519
526
  if (alreadyExisted && !options.override) {
520
527
  return {
@@ -542,107 +549,268 @@ async function importPath(options) {
542
549
  }
543
550
 
544
551
  // src/lib/scanner.ts
545
- import { access as access7, lstat as lstat2, readdir as readdir4, readlink as readlink2 } from "fs/promises";
546
- import path8 from "path";
552
+ import { access as access2, lstat as lstat2, readdir as readdir4, readlink as readlink2 } from "fs/promises";
553
+ import path9 from "path";
547
554
 
548
555
  // src/lib/agents.ts
549
- import { access as access6 } from "fs/promises";
550
- import path7 from "path";
556
+ import path8 from "path";
557
+ function defineAgent(id, displayName, options) {
558
+ return {
559
+ id,
560
+ displayName,
561
+ defaultProjectionMode: options.defaultProjectionMode ?? "symlink",
562
+ supportsGlobal: Boolean(options.globalSkillsDir),
563
+ supportsProject: Boolean(options.projectSkillsDir),
564
+ rootDir: options.rootDir,
565
+ globalSkillsDir: options.globalSkillsDir,
566
+ projectSkillsDir: options.projectSkillsDir
567
+ };
568
+ }
551
569
  var AGENTS = {
552
- amp: {
553
- id: "amp",
554
- displayName: "Amp",
555
- defaultProjectionMode: "symlink",
556
- rootDir: (homeDir) => path7.join(homeDir, ".amp"),
557
- globalSkillsDir: (homeDir) => path7.join(homeDir, ".amp", "skills"),
558
- projectSkillsDir: (projectDir) => path7.join(projectDir, ".amp", "skills")
559
- },
560
- "claude-code": {
561
- id: "claude-code",
562
- displayName: "Claude Code",
563
- defaultProjectionMode: "symlink",
564
- rootDir: (homeDir) => path7.join(homeDir, ".claude"),
565
- globalSkillsDir: (homeDir) => path7.join(homeDir, ".claude", "skills"),
566
- projectSkillsDir: (projectDir) => path7.join(projectDir, ".claude", "skills")
567
- },
568
- cline: {
569
- id: "cline",
570
- displayName: "Cline",
571
- defaultProjectionMode: "symlink",
572
- rootDir: (homeDir) => path7.join(homeDir, ".cline"),
573
- globalSkillsDir: (homeDir) => path7.join(homeDir, ".cline", "skills"),
574
- projectSkillsDir: (projectDir) => path7.join(projectDir, ".cline", "skills")
575
- },
576
- codex: {
577
- id: "codex",
578
- displayName: "Codex",
579
- defaultProjectionMode: "symlink",
580
- rootDir: (homeDir) => path7.join(homeDir, ".codex"),
581
- globalSkillsDir: (homeDir) => path7.join(homeDir, ".codex", "skills"),
582
- projectSkillsDir: (projectDir) => path7.join(projectDir, ".codex", "skills")
583
- },
584
- cursor: {
585
- id: "cursor",
586
- displayName: "Cursor",
587
- defaultProjectionMode: "copy",
588
- rootDir: (homeDir) => path7.join(homeDir, ".cursor"),
589
- globalSkillsDir: (homeDir) => path7.join(homeDir, ".cursor", "skills"),
590
- projectSkillsDir: (projectDir) => path7.join(projectDir, ".cursor", "skills")
591
- },
592
- "gemini-cli": {
593
- id: "gemini-cli",
594
- displayName: "Gemini CLI",
595
- defaultProjectionMode: "symlink",
596
- rootDir: (homeDir) => path7.join(homeDir, ".gemini"),
597
- globalSkillsDir: (homeDir) => path7.join(homeDir, ".gemini", "skills"),
598
- projectSkillsDir: (projectDir) => path7.join(projectDir, ".gemini", "skills")
599
- },
600
- goose: {
601
- id: "goose",
602
- displayName: "Goose",
603
- defaultProjectionMode: "symlink",
604
- rootDir: (homeDir) => path7.join(homeDir, ".goose"),
605
- globalSkillsDir: (homeDir) => path7.join(homeDir, ".goose", "skills"),
606
- projectSkillsDir: (projectDir) => path7.join(projectDir, ".goose", "skills")
607
- },
608
- opencode: {
609
- id: "opencode",
610
- displayName: "OpenCode",
611
- defaultProjectionMode: "symlink",
612
- rootDir: (homeDir) => path7.join(homeDir, ".opencode"),
613
- globalSkillsDir: (homeDir) => path7.join(homeDir, ".opencode", "skills"),
614
- projectSkillsDir: (projectDir) => path7.join(projectDir, ".opencode", "skills")
615
- },
616
- roo: {
617
- id: "roo",
618
- displayName: "Roo Code",
619
- defaultProjectionMode: "symlink",
620
- rootDir: (homeDir) => path7.join(homeDir, ".roo"),
621
- globalSkillsDir: (homeDir) => path7.join(homeDir, ".roo", "skills"),
622
- projectSkillsDir: (projectDir) => path7.join(projectDir, ".roo", "skills")
623
- },
624
- windsurf: {
625
- id: "windsurf",
626
- displayName: "Windsurf",
627
- defaultProjectionMode: "symlink",
628
- rootDir: (homeDir) => path7.join(homeDir, ".windsurf"),
629
- globalSkillsDir: (homeDir) => path7.join(homeDir, ".windsurf", "skills"),
630
- projectSkillsDir: (projectDir) => path7.join(projectDir, ".windsurf", "skills")
631
- }
570
+ adal: defineAgent("adal", "AdaL", {
571
+ rootDir: (homeDir) => path8.join(homeDir, ".adal"),
572
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".adal", "skills"),
573
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".adal", "skills")
574
+ }),
575
+ amp: defineAgent("amp", "Amp", {
576
+ rootDir: (homeDir) => path8.join(homeDir, ".agents"),
577
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".agents", "skills"),
578
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".agents", "skills")
579
+ }),
580
+ antigravity: defineAgent("antigravity", "Antigravity", {
581
+ rootDir: (homeDir) => path8.join(homeDir, ".gemini", "antigravity"),
582
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".gemini", "antigravity", "skills"),
583
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".gemini", "antigravity", "skills")
584
+ }),
585
+ augment: defineAgent("augment", "Augment", {
586
+ rootDir: (homeDir) => path8.join(homeDir, ".augment"),
587
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".augment", "skills"),
588
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".augment", "skills")
589
+ }),
590
+ bob: defineAgent("bob", "IBM Bob", {
591
+ rootDir: (homeDir) => path8.join(homeDir, ".bob"),
592
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".bob", "skills"),
593
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".bob", "skills")
594
+ }),
595
+ "claude-code": defineAgent("claude-code", "Claude Code", {
596
+ rootDir: (homeDir) => path8.join(homeDir, ".claude"),
597
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".claude", "skills"),
598
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".claude", "skills")
599
+ }),
600
+ cline: defineAgent("cline", "Cline", {
601
+ rootDir: (homeDir) => path8.join(homeDir, ".cline"),
602
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".cline", "skills"),
603
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".cline", "skills")
604
+ }),
605
+ codebuddy: defineAgent("codebuddy", "CodeBuddy", {
606
+ rootDir: (homeDir) => path8.join(homeDir, ".codebuddy"),
607
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".codebuddy", "skills"),
608
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".codebuddy", "skills")
609
+ }),
610
+ "command-code": defineAgent("command-code", "Command Code", {
611
+ rootDir: (homeDir) => path8.join(homeDir, ".commandcode"),
612
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".commandcode", "skills"),
613
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".commandcode", "skills")
614
+ }),
615
+ continue: defineAgent("continue", "Continue", {
616
+ rootDir: (homeDir) => path8.join(homeDir, ".continue"),
617
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".continue", "skills"),
618
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".continue", "skills")
619
+ }),
620
+ codex: defineAgent("codex", "Codex", {
621
+ rootDir: (homeDir) => path8.join(homeDir, ".codex"),
622
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".codex", "skills"),
623
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".codex", "skills")
624
+ }),
625
+ copilot: defineAgent("copilot", "GitHub Copilot", {
626
+ rootDir: (homeDir) => path8.join(homeDir, ".copilot"),
627
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".copilot", "skills"),
628
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".copilot", "skills")
629
+ }),
630
+ cortex: defineAgent("cortex", "Cortex Code", {
631
+ rootDir: (homeDir) => path8.join(homeDir, ".snowflake", "cortex"),
632
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".snowflake", "cortex", "skills"),
633
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".cortex", "skills")
634
+ }),
635
+ crush: defineAgent("crush", "Crush", {
636
+ rootDir: (homeDir) => path8.join(homeDir, ".config", "crush"),
637
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".config", "crush", "skills"),
638
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".config", "crush", "skills")
639
+ }),
640
+ cursor: defineAgent("cursor", "Cursor", {
641
+ rootDir: (homeDir) => path8.join(homeDir, ".cursor"),
642
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".cursor", "skills"),
643
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".cursor", "skills")
644
+ }),
645
+ deepagents: defineAgent("deepagents", "Deep Agents", {
646
+ rootDir: (homeDir) => path8.join(homeDir, ".deepagents"),
647
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".deepagents", "agent", "skills"),
648
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".deepagents", "agent", "skills")
649
+ }),
650
+ droid: defineAgent("droid", "Droid", {
651
+ rootDir: (homeDir) => path8.join(homeDir, ".factory"),
652
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".factory", "skills"),
653
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".factory", "skills")
654
+ }),
655
+ firebender: defineAgent("firebender", "Firebender", {
656
+ rootDir: (homeDir) => path8.join(homeDir, ".firebender"),
657
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".firebender", "skills"),
658
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".firebender", "skills")
659
+ }),
660
+ "gemini-cli": defineAgent("gemini-cli", "Gemini CLI", {
661
+ rootDir: (homeDir) => path8.join(homeDir, ".gemini"),
662
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".gemini", "skills"),
663
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".gemini", "skills")
664
+ }),
665
+ "github-copilot": defineAgent("github-copilot", "GitHub Copilot", {
666
+ rootDir: (homeDir) => path8.join(homeDir, ".copilot"),
667
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".copilot", "skills"),
668
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".copilot", "skills")
669
+ }),
670
+ goose: defineAgent("goose", "Goose", {
671
+ rootDir: (homeDir) => path8.join(homeDir, ".goose"),
672
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".goose", "skills"),
673
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".goose", "skills")
674
+ }),
675
+ "iflow-cli": defineAgent("iflow-cli", "iFlow CLI", {
676
+ rootDir: (homeDir) => path8.join(homeDir, ".iflow"),
677
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".iflow", "skills"),
678
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".iflow", "skills")
679
+ }),
680
+ junie: defineAgent("junie", "Junie", {
681
+ rootDir: (homeDir) => path8.join(homeDir, ".junie"),
682
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".junie", "skills"),
683
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".junie", "skills")
684
+ }),
685
+ kilo: defineAgent("kilo", "Kilo Code", {
686
+ rootDir: (homeDir) => path8.join(homeDir, ".kilocode"),
687
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".kilocode", "skills"),
688
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".kilocode", "skills")
689
+ }),
690
+ "kiro-cli": defineAgent("kiro-cli", "Kiro CLI", {
691
+ rootDir: (homeDir) => path8.join(homeDir, ".kiro"),
692
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".kiro", "skills"),
693
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".kiro", "skills")
694
+ }),
695
+ "kilo-code": defineAgent("kilo-code", "Kilo Code", {
696
+ rootDir: (homeDir) => path8.join(homeDir, ".kilocode"),
697
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".kilocode", "skills"),
698
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".kilocode", "skills")
699
+ }),
700
+ "kimi-cli": defineAgent("kimi-cli", "Kimi Code CLI", {
701
+ rootDir: (homeDir) => path8.join(homeDir, ".kimi"),
702
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".kimi", "skills"),
703
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".kimi", "skills")
704
+ }),
705
+ kode: defineAgent("kode", "Kode", {
706
+ rootDir: (homeDir) => path8.join(homeDir, ".kode"),
707
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".kode", "skills"),
708
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".kode", "skills")
709
+ }),
710
+ mcpjam: defineAgent("mcpjam", "MCPJam", {
711
+ rootDir: (homeDir) => path8.join(homeDir, ".mcpjam"),
712
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".mcpjam", "skills"),
713
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".mcpjam", "skills")
714
+ }),
715
+ "mistral-vibe": defineAgent("mistral-vibe", "Mistral Vibe", {
716
+ rootDir: (homeDir) => path8.join(homeDir, ".vibe"),
717
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".vibe", "skills"),
718
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".vibe", "skills")
719
+ }),
720
+ mux: defineAgent("mux", "Mux", {
721
+ rootDir: (homeDir) => path8.join(homeDir, ".mux"),
722
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".mux", "skills"),
723
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".mux", "skills")
724
+ }),
725
+ neovate: defineAgent("neovate", "Neovate", {
726
+ rootDir: (homeDir) => path8.join(homeDir, ".neovate"),
727
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".neovate", "skills"),
728
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".neovate", "skills")
729
+ }),
730
+ openclaw: defineAgent("openclaw", "OpenClaw", {
731
+ rootDir: (homeDir) => path8.join(homeDir, ".openclaw"),
732
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".openclaw", "skills"),
733
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".openclaw", "skills")
734
+ }),
735
+ "openclaude-ide": defineAgent("openclaude-ide", "OpenClaude IDE", {
736
+ rootDir: (homeDir) => path8.join(homeDir, ".openclaude"),
737
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".openclaude", "skills"),
738
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".openclaude", "skills")
739
+ }),
740
+ openhands: defineAgent("openhands", "OpenHands", {
741
+ rootDir: (homeDir) => path8.join(homeDir, ".openhands"),
742
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".openhands", "skills"),
743
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".openhands", "skills")
744
+ }),
745
+ opencode: defineAgent("opencode", "OpenCode", {
746
+ rootDir: (homeDir) => path8.join(homeDir, ".opencode"),
747
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".opencode", "skills"),
748
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".opencode", "skills")
749
+ }),
750
+ pi: defineAgent("pi", "Pi", {
751
+ rootDir: (homeDir) => path8.join(homeDir, ".pi", "agent"),
752
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".pi", "agent", "skills"),
753
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".pi", "agent", "skills")
754
+ }),
755
+ pochi: defineAgent("pochi", "Pochi", {
756
+ rootDir: (homeDir) => path8.join(homeDir, ".pochi"),
757
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".pochi", "skills"),
758
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".pochi", "skills")
759
+ }),
760
+ qoder: defineAgent("qoder", "Qoder", {
761
+ rootDir: (homeDir) => path8.join(homeDir, ".qoder"),
762
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".qoder", "skills"),
763
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".qoder", "skills")
764
+ }),
765
+ "qwen-code": defineAgent("qwen-code", "Qwen Code", {
766
+ rootDir: (homeDir) => path8.join(homeDir, ".qwen"),
767
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".qwen", "skills"),
768
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".qwen", "skills")
769
+ }),
770
+ replit: defineAgent("replit", "Replit", {
771
+ rootDir: (homeDir) => path8.join(homeDir, ".config", "replit"),
772
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".agent", "skills")
773
+ }),
774
+ roo: defineAgent("roo", "Roo Code", {
775
+ rootDir: (homeDir) => path8.join(homeDir, ".roo"),
776
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".roo", "skills"),
777
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".roo", "skills")
778
+ }),
779
+ trae: defineAgent("trae", "Trae", {
780
+ rootDir: (homeDir) => path8.join(homeDir, ".trae"),
781
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".trae", "skills"),
782
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".trae", "skills")
783
+ }),
784
+ "trae-cn": defineAgent("trae-cn", "Trae CN", {
785
+ rootDir: (homeDir) => path8.join(homeDir, ".trae-cn"),
786
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".trae-cn", "skills"),
787
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".trae-cn", "skills")
788
+ }),
789
+ warp: defineAgent("warp", "Warp", {
790
+ rootDir: (homeDir) => path8.join(homeDir, ".warp"),
791
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".warp", "skills"),
792
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".warp", "skills")
793
+ }),
794
+ windsurf: defineAgent("windsurf", "Windsurf", {
795
+ rootDir: (homeDir) => path8.join(homeDir, ".codeium", "windsurf"),
796
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".codeium", "windsurf", "skills"),
797
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".codeium", "windsurf", "skills")
798
+ }),
799
+ zencoder: defineAgent("zencoder", "Zencoder", {
800
+ rootDir: (homeDir) => path8.join(homeDir, ".zencoder"),
801
+ globalSkillsDir: (homeDir) => path8.join(homeDir, ".zencoder", "skills"),
802
+ projectSkillsDir: (projectDir) => path8.join(projectDir, ".zencoder", "skills")
803
+ })
632
804
  };
633
- async function pathExists6(targetPath) {
634
- try {
635
- await access6(targetPath);
636
- return true;
637
- } catch {
638
- return false;
639
- }
640
- }
641
805
  function listSupportedAgents() {
642
- return Object.values(AGENTS);
806
+ return Object.values(AGENTS).sort((left, right) => left.id.localeCompare(right.id));
643
807
  }
644
808
  function listSupportedAgentIds() {
645
- return listSupportedAgents().map((agent) => agent.id).sort();
809
+ return listSupportedAgents().map((agent) => agent.id);
810
+ }
811
+ function supportsScope(agentId, scope) {
812
+ const definition = getAgentDefinition(agentId);
813
+ return scope === "global" ? definition.supportsGlobal : definition.supportsProject;
646
814
  }
647
815
  function isAgentId(value) {
648
816
  return value in AGENTS;
@@ -652,7 +820,11 @@ function getAgentDefinition(agentId) {
652
820
  }
653
821
  function resolveAgentSkillsDir(agentId, scope, baseDir) {
654
822
  const definition = getAgentDefinition(agentId);
655
- return scope === "global" ? definition.globalSkillsDir(baseDir) : definition.projectSkillsDir(baseDir);
823
+ const resolver = scope === "global" ? definition.globalSkillsDir : definition.projectSkillsDir;
824
+ if (!resolver) {
825
+ throw new Error(`Agent ${agentId} does not support ${scope} scope.`);
826
+ }
827
+ return resolver(baseDir);
656
828
  }
657
829
  function getProjectionMode(agentId) {
658
830
  return getAgentDefinition(agentId).defaultProjectionMode;
@@ -660,23 +832,23 @@ function getProjectionMode(agentId) {
660
832
  async function detectInstalledAgents(options) {
661
833
  const installed = [];
662
834
  for (const agent of listSupportedAgents()) {
663
- const globalRootPath = agent.rootDir(options.homeDir);
664
- const projectPath = options.projectDir ? agent.projectSkillsDir(options.projectDir) : null;
665
- if (await pathExists6(globalRootPath)) {
835
+ const globalRootPath = agent.supportsGlobal ? agent.rootDir(options.homeDir) : null;
836
+ const projectPath = agent.supportsProject && options.projectDir ? resolveAgentSkillsDir(agent.id, "project", options.projectDir) : null;
837
+ if (globalRootPath && await pathExists(globalRootPath)) {
666
838
  installed.push(agent.id);
667
839
  continue;
668
840
  }
669
- if (projectPath && await pathExists6(projectPath)) {
841
+ if (projectPath && await pathExists(projectPath)) {
670
842
  installed.push(agent.id);
671
843
  }
672
844
  }
673
- return installed.sort();
845
+ return installed;
674
846
  }
675
847
 
676
848
  // src/lib/scanner.ts
677
849
  async function hasSkillReadme(skillDir) {
678
850
  try {
679
- await access7(path8.join(skillDir, "SKILL.md"));
851
+ await access2(path9.join(skillDir, "SKILL.md"));
680
852
  return true;
681
853
  } catch {
682
854
  return false;
@@ -689,21 +861,13 @@ async function isSymlinkPath(targetPath) {
689
861
  return false;
690
862
  }
691
863
  }
692
- async function pathExists7(targetPath) {
693
- try {
694
- await access7(targetPath);
695
- return true;
696
- } catch {
697
- return false;
698
- }
699
- }
700
864
  async function resolveSymlinkSource(targetPath) {
701
865
  try {
702
866
  const linkTarget = await readlink2(targetPath);
703
- const sourcePath = path8.resolve(path8.dirname(targetPath), linkTarget);
867
+ const sourcePath = path9.resolve(path9.dirname(targetPath), linkTarget);
704
868
  return {
705
869
  sourcePath,
706
- isBroken: !await pathExists7(sourcePath)
870
+ isBroken: !await pathExists(sourcePath)
707
871
  };
708
872
  } catch {
709
873
  return {
@@ -719,7 +883,7 @@ async function scanDirectory(baseDir, agentId, scope, projectDir) {
719
883
  if (!entry.isDirectory() && !entry.isSymbolicLink()) {
720
884
  continue;
721
885
  }
722
- const fullPath = path8.join(baseDir, entry.name);
886
+ const fullPath = path9.join(baseDir, entry.name);
723
887
  const isSymlink = await isSymlinkPath(fullPath);
724
888
  const symlinkInfo = isSymlink ? await resolveSymlinkSource(fullPath) : { isBroken: false };
725
889
  if (!await hasSkillReadme(fullPath) && !symlinkInfo.isBroken) {
@@ -744,9 +908,13 @@ async function scanDirectory(baseDir, agentId, scope, projectDir) {
744
908
  async function scanSkills(options) {
745
909
  const results = [];
746
910
  for (const agent of listSupportedAgents()) {
747
- results.push(...await scanDirectory(agent.globalSkillsDir(options.homeDir), agent.id, "global"));
911
+ if (supportsScope(agent.id, "global")) {
912
+ results.push(...await scanDirectory(agent.globalSkillsDir(options.homeDir), agent.id, "global"));
913
+ }
748
914
  for (const projectDir of options.projectDirs ?? []) {
749
- results.push(...await scanDirectory(agent.projectSkillsDir(projectDir), agent.id, "project", projectDir));
915
+ if (supportsScope(agent.id, "project")) {
916
+ results.push(...await scanDirectory(agent.projectSkillsDir(projectDir), agent.id, "project", projectDir));
917
+ }
750
918
  }
751
919
  }
752
920
  return results.sort((left, right) => left.path.localeCompare(right.path));
@@ -826,7 +994,7 @@ async function runImport(context, options) {
826
994
 
827
995
  // src/lib/symlink.ts
828
996
  import { cp as cp2, lstat as lstat3, mkdir as mkdir5, readFile as readFile2, readdir as readdir5, readlink as readlink3, rm as rm3, symlink, unlink, writeFile as writeFile2 } from "fs/promises";
829
- import path9 from "path";
997
+ import path10 from "path";
830
998
  var COPY_MARKER = ".aweskill-projection.json";
831
999
  async function tryLstat(targetPath) {
832
1000
  try {
@@ -837,7 +1005,7 @@ async function tryLstat(targetPath) {
837
1005
  }
838
1006
  async function readCopyMarker(targetPath) {
839
1007
  try {
840
- const content = await readFile2(path9.join(targetPath, COPY_MARKER), "utf8");
1008
+ const content = await readFile2(path10.join(targetPath, COPY_MARKER), "utf8");
841
1009
  const parsed = JSON.parse(content);
842
1010
  return parsed.managedBy === "aweskill" ? parsed : null;
843
1011
  } catch {
@@ -857,8 +1025,8 @@ async function assertProjectionTargetSafe(mode, sourcePath, targetPath, options
857
1025
  throw new Error(`Refusing to overwrite non-symlink target: ${targetPath}`);
858
1026
  }
859
1027
  const currentTarget = await readlink3(targetPath);
860
- const resolvedCurrent = path9.resolve(path9.dirname(targetPath), currentTarget);
861
- if (resolvedCurrent === path9.resolve(sourcePath)) {
1028
+ const resolvedCurrent = path10.resolve(path10.dirname(targetPath), currentTarget);
1029
+ if (resolvedCurrent === path10.resolve(sourcePath)) {
862
1030
  return;
863
1031
  }
864
1032
  return;
@@ -875,12 +1043,12 @@ async function assertProjectionTargetSafe(mode, sourcePath, targetPath, options
875
1043
  }
876
1044
  }
877
1045
  async function createSkillSymlink(sourcePath, targetPath, options = {}) {
878
- await mkdir5(path9.dirname(targetPath), { recursive: true });
1046
+ await mkdir5(path10.dirname(targetPath), { recursive: true });
879
1047
  const existing = await tryLstat(targetPath);
880
1048
  if (existing?.isSymbolicLink()) {
881
1049
  const currentTarget = await readlink3(targetPath);
882
- const resolvedCurrent = path9.resolve(path9.dirname(targetPath), currentTarget);
883
- if (resolvedCurrent === path9.resolve(sourcePath)) {
1050
+ const resolvedCurrent = path10.resolve(path10.dirname(targetPath), currentTarget);
1051
+ if (resolvedCurrent === path10.resolve(sourcePath)) {
884
1052
  return "skipped";
885
1053
  }
886
1054
  await unlink(targetPath);
@@ -891,12 +1059,12 @@ async function createSkillSymlink(sourcePath, targetPath, options = {}) {
891
1059
  throw new Error(`Refusing to overwrite non-symlink target: ${targetPath}`);
892
1060
  }
893
1061
  }
894
- const linkTarget = path9.relative(path9.dirname(targetPath), sourcePath) || ".";
1062
+ const linkTarget = path10.relative(path10.dirname(targetPath), sourcePath) || ".";
895
1063
  await symlink(linkTarget, targetPath, "dir");
896
1064
  return "created";
897
1065
  }
898
1066
  async function createSkillCopy(sourcePath, targetPath, options = {}) {
899
- await mkdir5(path9.dirname(targetPath), { recursive: true });
1067
+ await mkdir5(path10.dirname(targetPath), { recursive: true });
900
1068
  const existing = await tryLstat(targetPath);
901
1069
  if (existing?.isSymbolicLink()) {
902
1070
  await unlink(targetPath);
@@ -910,8 +1078,8 @@ async function createSkillCopy(sourcePath, targetPath, options = {}) {
910
1078
  await rm3(targetPath, { force: true, recursive: true });
911
1079
  }
912
1080
  await cp2(sourcePath, targetPath, { recursive: true });
913
- const marker = { managedBy: "aweskill", sourcePath: path9.resolve(sourcePath) };
914
- await writeFile2(path9.join(targetPath, COPY_MARKER), JSON.stringify(marker, null, 2), "utf8");
1081
+ const marker = { managedBy: "aweskill", sourcePath: path10.resolve(sourcePath) };
1082
+ await writeFile2(path10.join(targetPath, COPY_MARKER), JSON.stringify(marker, null, 2), "utf8");
915
1083
  return "created";
916
1084
  }
917
1085
  async function removeManagedProjection(targetPath) {
@@ -937,12 +1105,12 @@ async function listManagedSkillNames(skillsDir, centralSkillsDir) {
937
1105
  try {
938
1106
  const entries = await readdir5(skillsDir, { withFileTypes: true });
939
1107
  for (const entry of entries) {
940
- const targetPath = path9.join(skillsDir, entry.name);
1108
+ const targetPath = path10.join(skillsDir, entry.name);
941
1109
  if (entry.isSymbolicLink()) {
942
1110
  try {
943
1111
  const currentTarget = await readlink3(targetPath);
944
- const resolvedCurrent = path9.resolve(path9.dirname(targetPath), currentTarget);
945
- if (resolvedCurrent.startsWith(path9.resolve(centralSkillsDir))) {
1112
+ const resolvedCurrent = path10.resolve(path10.dirname(targetPath), currentTarget);
1113
+ if (resolvedCurrent.startsWith(path10.resolve(centralSkillsDir))) {
946
1114
  result.set(entry.name, "symlink");
947
1115
  }
948
1116
  } catch {
@@ -974,13 +1142,17 @@ async function resolveAgentsForScope(context, requestedAgents, scope, projectDir
974
1142
  homeDir: context.homeDir,
975
1143
  projectDir: scope === "project" ? projectDir : void 0
976
1144
  });
977
- return detected.length > 0 ? detected : listSupportedAgentIds();
1145
+ const candidates = detected.length > 0 ? detected : listSupportedAgentIds();
1146
+ return candidates.filter((agentId) => supportsScope(agentId, scope));
978
1147
  }
979
1148
  return uniqueSorted(
980
1149
  requestedAgents.map((agent) => {
981
1150
  if (!isAgentId(agent)) {
982
1151
  throw new Error(`Unsupported agent: ${agent}`);
983
1152
  }
1153
+ if (!supportsScope(agent, scope)) {
1154
+ throw new Error(`Agent ${agent} does not support ${scope} scope.`);
1155
+ }
984
1156
  return agent;
985
1157
  })
986
1158
  );
@@ -1089,13 +1261,17 @@ async function resolveAgentsForScope2(context, requestedAgents, scope, projectDi
1089
1261
  homeDir: context.homeDir,
1090
1262
  projectDir: scope === "project" ? projectDir : void 0
1091
1263
  });
1092
- return detected.length > 0 ? detected : listSupportedAgentIds();
1264
+ const candidates = detected.length > 0 ? detected : listSupportedAgentIds();
1265
+ return candidates.filter((agentId) => supportsScope(agentId, scope));
1093
1266
  }
1094
1267
  return uniqueSorted(
1095
1268
  requestedAgents.map((agent) => {
1096
1269
  if (!isAgentId(agent)) {
1097
1270
  throw new Error(`Unsupported agent: ${agent}`);
1098
1271
  }
1272
+ if (!supportsScope(agent, scope)) {
1273
+ throw new Error(`Agent ${agent} does not support ${scope} scope.`);
1274
+ }
1099
1275
  return agent;
1100
1276
  })
1101
1277
  );
@@ -1112,7 +1288,7 @@ async function resolveSkillNames(context, type, names) {
1112
1288
  homeDir: context.homeDir
1113
1289
  });
1114
1290
  const globalManaged = await Promise.all(
1115
- detected.map(async (agentId) => {
1291
+ detected.filter((agentId) => supportsScope(agentId, "global")).map(async (agentId) => {
1116
1292
  const agentSkillsDir = resolveAgentSkillsDir(agentId, "global", context.homeDir);
1117
1293
  return listManagedSkillNames(agentSkillsDir, centralSkillsDir);
1118
1294
  })
@@ -1220,13 +1396,17 @@ async function resolveAgentsForScope3(context, requestedAgents, scope, projectDi
1220
1396
  homeDir: context.homeDir,
1221
1397
  projectDir: scope === "project" ? projectDir : void 0
1222
1398
  });
1223
- return detected.length > 0 ? detected : listSupportedAgentIds();
1399
+ const candidates = detected.length > 0 ? detected : listSupportedAgentIds();
1400
+ return candidates.filter((agentId) => supportsScope(agentId, scope));
1224
1401
  }
1225
1402
  return uniqueSorted(
1226
1403
  requestedAgents.map((agent) => {
1227
1404
  if (!isAgentId(agent)) {
1228
1405
  throw new Error(`Unsupported agent: ${agent}`);
1229
1406
  }
1407
+ if (!supportsScope(agent, scope)) {
1408
+ throw new Error(`Agent ${agent} does not support ${scope} scope.`);
1409
+ }
1230
1410
  return agent;
1231
1411
  })
1232
1412
  );
@@ -1421,7 +1601,7 @@ async function runListTemplateBundles(context, options = {}) {
1421
1601
 
1422
1602
  // src/commands/recover.ts
1423
1603
  import { cp as cp3, mkdir as mkdir7, readlink as readlink4, unlink as unlink2 } from "fs/promises";
1424
- import path10 from "path";
1604
+ import path11 from "path";
1425
1605
  function getProjectDir4(context, explicitProjectDir) {
1426
1606
  return explicitProjectDir ?? context.cwd;
1427
1607
  }
@@ -1431,13 +1611,17 @@ async function resolveAgentsForScope4(context, requestedAgents, scope, projectDi
1431
1611
  homeDir: context.homeDir,
1432
1612
  projectDir: scope === "project" ? projectDir : void 0
1433
1613
  });
1434
- return detected.length > 0 ? detected : listSupportedAgentIds();
1614
+ const candidates = detected.length > 0 ? detected : listSupportedAgentIds();
1615
+ return candidates.filter((agentId) => supportsScope(agentId, scope));
1435
1616
  }
1436
1617
  return uniqueSorted(
1437
1618
  requestedAgents.map((agent) => {
1438
1619
  if (!isAgentId(agent)) {
1439
1620
  throw new Error(`Unsupported agent: ${agent}`);
1440
1621
  }
1622
+ if (!supportsScope(agent, scope)) {
1623
+ throw new Error(`Agent ${agent} does not support ${scope} scope.`);
1624
+ }
1441
1625
  return agent;
1442
1626
  })
1443
1627
  );
@@ -1455,15 +1639,15 @@ async function runRecover(context, options) {
1455
1639
  if (mode !== "symlink") {
1456
1640
  continue;
1457
1641
  }
1458
- const targetPath = path10.join(agentSkillsDir, skillName);
1459
- const sourcePath = path10.join(centralSkillsDir, skillName);
1642
+ const targetPath = path11.join(agentSkillsDir, skillName);
1643
+ const sourcePath = path11.join(centralSkillsDir, skillName);
1460
1644
  const currentTarget = await readlink4(targetPath);
1461
- const resolvedCurrent = path10.resolve(path10.dirname(targetPath), currentTarget);
1462
- if (resolvedCurrent !== path10.resolve(sourcePath)) {
1645
+ const resolvedCurrent = path11.resolve(path11.dirname(targetPath), currentTarget);
1646
+ if (resolvedCurrent !== path11.resolve(sourcePath)) {
1463
1647
  continue;
1464
1648
  }
1465
1649
  await unlink2(targetPath);
1466
- await mkdir7(path10.dirname(targetPath), { recursive: true });
1650
+ await mkdir7(path11.dirname(targetPath), { recursive: true });
1467
1651
  await cp3(sourcePath, targetPath, { recursive: true });
1468
1652
  recovered.push(`${agentId}:${skillName}`);
1469
1653
  }
@@ -1475,7 +1659,7 @@ async function runRecover(context, options) {
1475
1659
 
1476
1660
  // src/lib/references.ts
1477
1661
  import { rm as rm4 } from "fs/promises";
1478
- import path11 from "path";
1662
+ import path12 from "path";
1479
1663
  async function findSkillReferences(options) {
1480
1664
  const normalizedSkill = sanitizeName(options.skillName);
1481
1665
  const { skillsDir } = getAweskillPaths(options.homeDir);
@@ -1489,6 +1673,9 @@ async function findSkillReferences(options) {
1489
1673
  }
1490
1674
  for (const { scope, dir } of baseDirs) {
1491
1675
  for (const agent of listSupportedAgents()) {
1676
+ if (!supportsScope(agent.id, scope)) {
1677
+ continue;
1678
+ }
1492
1679
  const agentSkillsDir = resolveAgentSkillsDir(agent.id, scope, dir);
1493
1680
  const managed = await listManagedSkillNames(agentSkillsDir, skillsDir);
1494
1681
  if (managed.has(normalizedSkill)) {
@@ -1517,10 +1704,13 @@ async function removeSkillWithReferences(options) {
1517
1704
  }
1518
1705
  for (const { scope, dir } of baseDirs) {
1519
1706
  for (const agent of listSupportedAgents()) {
1707
+ if (!supportsScope(agent.id, scope)) {
1708
+ continue;
1709
+ }
1520
1710
  const agentSkillsDir = resolveAgentSkillsDir(agent.id, scope, dir);
1521
1711
  const managed = await listManagedSkillNames(agentSkillsDir, skillsDir);
1522
1712
  if (managed.has(normalizedSkill)) {
1523
- await removeManagedProjection(path11.join(agentSkillsDir, normalizedSkill));
1713
+ await removeManagedProjection(path12.join(agentSkillsDir, normalizedSkill));
1524
1714
  }
1525
1715
  }
1526
1716
  }
@@ -1555,34 +1745,58 @@ async function runRemove(context, options) {
1555
1745
 
1556
1746
  // src/commands/restore.ts
1557
1747
  import { cp as cp4, mkdir as mkdir8, rm as rm5 } from "fs/promises";
1558
- import path12 from "path";
1748
+ import path13 from "path";
1559
1749
  async function runRestore(context, options) {
1560
- const { tempDir, extractedSkillsDir } = await extractSkillsArchive(options.archivePath);
1750
+ const includeBundles = options.includeBundles ?? false;
1751
+ const { tempDir, extractedSkillsDir, extractedBundlesDir } = await extractSkillsArchive(options.archivePath);
1561
1752
  try {
1562
1753
  const extracted = await listSkillEntriesInDirectory(extractedSkillsDir);
1563
1754
  if (extracted.length === 0) {
1564
1755
  throw new Error(`Archive does not contain a skills/ directory: ${options.archivePath}`);
1565
1756
  }
1566
- const { skillsDir } = getAweskillPaths(context.homeDir);
1757
+ const { skillsDir, bundlesDir } = getAweskillPaths(context.homeDir);
1567
1758
  const current = await listSkillEntriesInDirectory(skillsDir);
1568
1759
  const currentNames = new Set(current.map((entry) => entry.name));
1569
1760
  const conflicts = extracted.map((entry) => entry.name).filter((name) => currentNames.has(name));
1570
- if (conflicts.length > 0 && !options.override) {
1571
- throw new Error(`Restore would overwrite existing skills: ${conflicts.join(", ")}. Use --override to replace them.`);
1761
+ const extractedBundles = includeBundles ? await listBundlesInDirectory(extractedBundlesDir) : [];
1762
+ const currentBundles = includeBundles ? await listBundlesInDirectory(bundlesDir) : [];
1763
+ const currentBundleNames = new Set(currentBundles.map((bundle) => bundle.name));
1764
+ const bundleConflicts = extractedBundles.map((bundle) => bundle.name).filter((name) => currentBundleNames.has(name));
1765
+ if ((conflicts.length > 0 || bundleConflicts.length > 0) && !options.override) {
1766
+ const conflictMessages = [];
1767
+ if (conflicts.length > 0) {
1768
+ conflictMessages.push(`skills: ${conflicts.join(", ")}`);
1769
+ }
1770
+ if (bundleConflicts.length > 0) {
1771
+ conflictMessages.push(`bundles: ${bundleConflicts.join(", ")}`);
1772
+ }
1773
+ throw new Error(`Restore would overwrite existing ${conflictMessages.join("; ")}. Use --override to replace them.`);
1572
1774
  }
1573
- const backupArchivePath = await createSkillsBackupArchive(context.homeDir);
1775
+ const backupArchivePath = await createSkillsBackupArchive(context.homeDir, { includeBundles });
1574
1776
  if (options.override) {
1575
1777
  await rm5(skillsDir, { recursive: true, force: true });
1576
- await mkdir8(path12.dirname(skillsDir), { recursive: true });
1778
+ await mkdir8(path13.dirname(skillsDir), { recursive: true });
1577
1779
  await cp4(extractedSkillsDir, skillsDir, { recursive: true });
1780
+ if (includeBundles) {
1781
+ await rm5(bundlesDir, { recursive: true, force: true });
1782
+ await mkdir8(path13.dirname(bundlesDir), { recursive: true });
1783
+ await cp4(extractedBundlesDir, bundlesDir, { recursive: true });
1784
+ }
1578
1785
  } else {
1579
1786
  await mkdir8(skillsDir, { recursive: true });
1580
1787
  for (const entry of extracted) {
1581
- await cp4(entry.path, path12.join(skillsDir, entry.name), { recursive: true });
1788
+ await cp4(entry.path, path13.join(skillsDir, entry.name), { recursive: true });
1789
+ }
1790
+ if (includeBundles) {
1791
+ await mkdir8(bundlesDir, { recursive: true });
1792
+ for (const bundle of extractedBundles) {
1793
+ await cp4(path13.join(extractedBundlesDir, `${bundle.name}.yaml`), path13.join(bundlesDir, `${bundle.name}.yaml`), { recursive: true });
1794
+ }
1582
1795
  }
1583
1796
  }
1584
- context.write(`Restored ${extracted.length} skills from ${options.archivePath}`);
1585
- context.write(`Backed up current skills to ${backupArchivePath}`);
1797
+ const restoredLabel = includeBundles ? `Restored ${extracted.length} skills and ${extractedBundles.length} bundles from ${options.archivePath}` : `Restored ${extracted.length} skills from ${options.archivePath}`;
1798
+ context.write(restoredLabel);
1799
+ context.write(`Backed up current ${formatBackupLabel(includeBundles)} to ${backupArchivePath}`);
1586
1800
  return { restored: extracted.map((entry) => entry.name), backupArchivePath };
1587
1801
  } finally {
1588
1802
  await rm5(tempDir, { recursive: true, force: true });
@@ -1591,7 +1805,7 @@ async function runRestore(context, options) {
1591
1805
 
1592
1806
  // src/lib/rmdup.ts
1593
1807
  import { mkdir as mkdir9, readdir as readdir7, rename as rename2, rm as rm6 } from "fs/promises";
1594
- import path13 from "path";
1808
+ import path14 from "path";
1595
1809
  var NUMERIC_SUFFIX_PATTERN = /^(.*?)-(\d+(?:\.\d+)*)$/;
1596
1810
  function parseSkillName(name) {
1597
1811
  const match = name.match(NUMERIC_SUFFIX_PATTERN);
@@ -1681,13 +1895,13 @@ async function removeDuplicateSkills(homeDir, duplicates, options = {}) {
1681
1895
  async function nextAvailableDupPath(dupSkillsDir, skillName) {
1682
1896
  const entries = new Set(await readdir7(dupSkillsDir).catch(() => []));
1683
1897
  if (!entries.has(skillName)) {
1684
- return path13.join(dupSkillsDir, skillName);
1898
+ return path14.join(dupSkillsDir, skillName);
1685
1899
  }
1686
1900
  let index = 1;
1687
1901
  while (entries.has(`${skillName}-${index}`)) {
1688
1902
  index += 1;
1689
1903
  }
1690
- return path13.join(dupSkillsDir, `${skillName}-${index}`);
1904
+ return path14.join(dupSkillsDir, `${skillName}-${index}`);
1691
1905
  }
1692
1906
 
1693
1907
  // src/commands/rmdup.ts
@@ -1729,16 +1943,7 @@ async function runRmdup(context, options) {
1729
1943
  }
1730
1944
 
1731
1945
  // src/commands/sync.ts
1732
- import { access as access8 } from "fs/promises";
1733
- import path14 from "path";
1734
- async function pathExists8(targetPath) {
1735
- try {
1736
- await access8(targetPath);
1737
- return true;
1738
- } catch {
1739
- return false;
1740
- }
1741
- }
1946
+ import path15 from "path";
1742
1947
  async function runSync(context, options) {
1743
1948
  const { skillsDir } = getAweskillPaths(context.homeDir);
1744
1949
  const baseDirs = /* @__PURE__ */ new Set();
@@ -1746,19 +1951,22 @@ async function runSync(context, options) {
1746
1951
  if (options.projectDir) {
1747
1952
  baseDirs.add({ scope: "project", dir: options.projectDir });
1748
1953
  }
1749
- if (await pathExists8(path14.join(context.cwd, ".aweskill.yaml"))) {
1954
+ if (await pathExists(path15.join(context.cwd, ".aweskill.yaml"))) {
1750
1955
  baseDirs.add({ scope: "project", dir: context.cwd });
1751
1956
  }
1752
1957
  let removed = 0;
1753
1958
  const warnings = [];
1754
1959
  for (const { scope, dir } of baseDirs) {
1755
1960
  for (const agent of listSupportedAgents()) {
1961
+ if (!supportsScope(agent.id, scope)) {
1962
+ continue;
1963
+ }
1756
1964
  const skillsDir2 = resolveAgentSkillsDir(agent.id, scope, dir);
1757
1965
  const managed = await listManagedSkillNames(skillsDir2, skillsDir);
1758
1966
  for (const [skillName] of managed) {
1759
- const sourcePath = path14.join(skillsDir, skillName);
1760
- if (!await pathExists8(sourcePath)) {
1761
- const wasRemoved = await removeManagedProjection(path14.join(skillsDir2, skillName));
1967
+ const sourcePath = path15.join(skillsDir, skillName);
1968
+ if (!await pathExists(sourcePath)) {
1969
+ const wasRemoved = await removeManagedProjection(path15.join(skillsDir2, skillName));
1762
1970
  if (wasRemoved) {
1763
1971
  removed += 1;
1764
1972
  warnings.push(`Removed stale projection: ${agent.id}:${skillName} (source missing)`);
@@ -1774,16 +1982,39 @@ async function runSync(context, options) {
1774
1982
  return { removed, warnings };
1775
1983
  }
1776
1984
 
1985
+ // src/lib/version.ts
1986
+ import { existsSync, readFileSync } from "fs";
1987
+ import path16 from "path";
1988
+ import { fileURLToPath as fileURLToPath2 } from "url";
1989
+ function readVersionFromPackageJson(packageJsonPath) {
1990
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
1991
+ if (!packageJson.version) {
1992
+ throw new Error(`Missing version in ${packageJsonPath}`);
1993
+ }
1994
+ return packageJson.version;
1995
+ }
1996
+ function resolveVersionForModuleUrl(moduleUrl) {
1997
+ const moduleDir = path16.dirname(fileURLToPath2(moduleUrl));
1998
+ for (const relativePath of ["../package.json", "../../package.json"]) {
1999
+ const packageJsonPath = path16.resolve(moduleDir, relativePath);
2000
+ if (existsSync(packageJsonPath)) {
2001
+ return readVersionFromPackageJson(packageJsonPath);
2002
+ }
2003
+ }
2004
+ throw new Error(`Cannot find package.json for module ${moduleUrl}`);
2005
+ }
2006
+ var AWESKILL_VERSION = resolveVersionForModuleUrl(import.meta.url);
2007
+
1777
2008
  // src/lib/runtime.ts
1778
2009
  import { realpathSync } from "fs";
1779
- import { fileURLToPath as fileURLToPath2, pathToFileURL } from "url";
2010
+ import { fileURLToPath as fileURLToPath3, pathToFileURL } from "url";
1780
2011
  function isDirectCliEntry(importMetaUrl, argv1) {
1781
2012
  if (!argv1) {
1782
2013
  return false;
1783
2014
  }
1784
2015
  try {
1785
2016
  const executedPath = realpathSync(argv1);
1786
- const modulePath = realpathSync(fileURLToPath2(importMetaUrl));
2017
+ const modulePath = realpathSync(fileURLToPath3(importMetaUrl));
1787
2018
  return pathToFileURL(modulePath).href === pathToFileURL(executedPath).href;
1788
2019
  } catch {
1789
2020
  return importMetaUrl === pathToFileURL(argv1).href;
@@ -1933,10 +2164,10 @@ function formatCliErrorMessage(message) {
1933
2164
  return 'Option --agent <agent> argument missing. Use one or more supported agent ids, for example "codex" or "codex,cursor". Run "aweskill agent supported" to see the supported agent list.';
1934
2165
  }
1935
2166
  const normalizedMessage = message.replace(/^error:\s*/i, "");
1936
- const bundleFileMatch = normalizedMessage.match(/ENOENT: no such file or directory, open '([^']+\/bundles\/([^/'"]+)\.ya?ml)'/i);
2167
+ const bundleFileMatch = normalizedMessage.match(/ENOENT: no such file or directory, open '([^']+\/(bundles|resources\/bundle_templates)\/([^/'"]+)\.ya?ml)'/i);
1937
2168
  if (bundleFileMatch) {
1938
- const bundleName = bundleFileMatch[2];
1939
- if (bundleFileMatch[1]?.includes("/template/bundles/")) {
2169
+ const bundleName = bundleFileMatch[3];
2170
+ if (bundleFileMatch[2] === "resources/bundle_templates") {
1940
2171
  return `Bundle template not found: ${bundleName}. Run "aweskill bundle template list" to see available bundle templates.`;
1941
2172
  }
1942
2173
  return `Bundle not found: ${bundleName}. Run "aweskill bundle list" to see available bundles.`;
@@ -1965,16 +2196,7 @@ function formatCliErrorMessage(message) {
1965
2196
  function writeSupportedAgents(context) {
1966
2197
  const lines = [
1967
2198
  "Supported agents:",
1968
- "amp (Amp)",
1969
- "claude-code (Claude Code)",
1970
- "cline (Cline)",
1971
- "codex (Codex)",
1972
- "cursor (Cursor)",
1973
- "gemini-cli (Gemini CLI)",
1974
- "goose (Goose)",
1975
- "opencode (OpenCode)",
1976
- "roo (Roo Code)",
1977
- "windsurf (Windsurf)"
2199
+ ...listSupportedAgents().map((agent) => `${agent.id} (${agent.displayName})`)
1978
2200
  ];
1979
2201
  for (const line of lines) {
1980
2202
  context.write(line);
@@ -1992,7 +2214,7 @@ function configureCommandTree(command) {
1992
2214
  function createProgram(overrides = {}) {
1993
2215
  const context = createRuntimeContext(overrides);
1994
2216
  const program = new Command();
1995
- program.name("aweskill").description("Local skill orchestration CLI for AI agents").version("0.1.5").helpOption("-h, --help", "Display help");
2217
+ program.name("aweskill").description("Local skill orchestration CLI for AI agents").version(AWESKILL_VERSION).helpOption("-h, --help", "Display help");
1996
2218
  const skill = program.command("skill").description("Manage skills in the central store");
1997
2219
  skill.command("list").description("List skills in the central store").option("--verbose", "show all skills instead of a short preview", false).action(async (options) => {
1998
2220
  await runListSkills(context, { verbose: options.verbose });
@@ -2126,15 +2348,22 @@ function createProgram(overrides = {}) {
2126
2348
  store.command("init").description("Create ~/.aweskill layout").option("--scan", "scan existing agent directories after init", false).option("--verbose", "show scanned skill details instead of per-agent totals", false).action(async (options) => {
2127
2349
  await runFramedCommand(" aweskill store init ", async () => runInit(context, options));
2128
2350
  });
2129
- store.command("backup").description("Create a timestamped archive of the central skills repository").action(async () => {
2130
- await runFramedCommand(" aweskill store backup ", async () => runBackup(context));
2351
+ store.command("backup").argument("[archive]").description("Create a timestamped archive of the central skills repository").option("--both", "include bundle definitions in the backup archive", false).action(async (archivePath, options) => {
2352
+ await runFramedCommand(
2353
+ " aweskill store backup ",
2354
+ async () => runBackup(context, {
2355
+ archivePath,
2356
+ includeBundles: options.both
2357
+ })
2358
+ );
2131
2359
  });
2132
- store.command("restore").argument("<archive>").description("Restore skills from a backup archive and auto-back up the current skills first").option("--override", "replace existing skills with the archive contents", false).action(async (archivePath, options) => {
2360
+ store.command("restore").argument("<archive>").description("Restore skills from a backup archive and auto-back up the current skills first").option("--override", "replace existing skills with the archive contents", false).option("--both", "restore bundle definitions and include them in the pre-restore backup", false).action(async (archivePath, options) => {
2133
2361
  await runFramedCommand(
2134
2362
  " aweskill store restore ",
2135
2363
  async () => runRestore(context, {
2136
2364
  archivePath,
2137
- override: options.override
2365
+ override: options.override,
2366
+ includeBundles: options.both
2138
2367
  })
2139
2368
  );
2140
2369
  });