@emmraan/ai-skills 0.1.0 → 1.0.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/README.md CHANGED
@@ -13,14 +13,21 @@ Install framework-agnostic `SKILLS.md` files for AI agents.
13
13
  - `npx @emmraan/ai-skills list` - List available and installed skills
14
14
  - `npx @emmraan/ai-skills update` - Update all installed skills
15
15
  - `npx @emmraan/ai-skills remove react` - Remove React skill
16
+ - `npx @emmraan/ai-skills remove react --local --platform claude` - Remove from selected local platforms
17
+ - `npx @emmraan/ai-skills remove react --global --all` - Remove from all global platforms
16
18
  - `npx @emmraan/ai-skills generate-local` - Run local backend generator
17
19
 
18
- ## Interactive install flow
20
+ ## Interactive flow
19
21
 
20
22
  When you run `npx @emmraan/ai-skills <skill>` without install flags, the CLI prompts for:
21
23
 
22
24
  1. Install location: Local (current project) or Global (agent platforms)
23
- 2. If Global: All platforms or specific platforms
25
+ 2. Install target: All platforms or specific platforms (for both Local and Global)
26
+
27
+ When you run `npx @emmraan/ai-skills remove <skill>` without remove flags, the CLI prompts for:
28
+
29
+ 1. Remove location: Local (current project) or Global (agent platforms)
30
+ 2. Remove target: All platforms or specific platforms (for both Local and Global)
24
31
 
25
32
  Supported non-interactive install flags:
26
33
 
@@ -29,8 +36,22 @@ Supported non-interactive install flags:
29
36
  - `--platform <name[,name]>`
30
37
  - `--all`
31
38
 
39
+ Supported non-interactive remove flags:
40
+
41
+ - `--local`
42
+ - `--global`
43
+ - `--platform <name[,name]>`
44
+ - `--all`
45
+
32
46
  Default behavior remains global + all platforms.
33
47
 
48
+ ## UX improvements
49
+
50
+ - Subtle welcome banner in TTY sessions
51
+ - Colored logs for info/success/warn/error states
52
+ - Spinners during install/remove operations
53
+ - Interactive prompts via `inquirer`
54
+
34
55
  ## Publish to npm
35
56
 
36
57
  This package is the publishable CLI package for the `ai-skills` command.
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,cAAc,EAAwB,MAAM,mBAAmB,CAAC;AAM/F,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CA0BjE;AAED,wBAAsB,8BAA8B,CAClD,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,cAAc,CAAC,CAyCzB;AA4CD,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAwB/F"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,cAAc,EAAwB,MAAM,mBAAmB,CAAC;AAM/F,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CA0BjE;AAED,wBAAsB,8BAA8B,CAClD,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,cAAc,CAAC,CAyCzB;AAyDD,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CA6B/F"}
@@ -3,9 +3,9 @@ import { installSkill } from '../core/installer.js';
3
3
  import { addSkillToLockfile } from '../core/lockfile.js';
4
4
  import { AGENT_PLATFORMS } from '../core/config.js';
5
5
  import { sha256 } from '../utils/hash.js';
6
- import { error, success, info } from '../utils/logger.js';
7
- import { createInterface } from 'readline/promises';
8
- import { stdin as input, stdout as output } from 'process';
6
+ import { error, success } from '../utils/logger.js';
7
+ import inquirer from 'inquirer';
8
+ import { ui } from '../utils/ui.js';
9
9
  export function parseInstallFlags(args) {
10
10
  const flags = {};
11
11
  for (let i = 0; i < args.length; i++) {
@@ -61,7 +61,7 @@ export async function resolveInstallOptionsFromFlags(flags, interactive) {
61
61
  };
62
62
  }
63
63
  if (!hasAnyFlag) {
64
- if (interactive && input.isTTY && output.isTTY) {
64
+ if (interactive && process.stdin.isTTY && process.stdout.isTTY) {
65
65
  return promptInstallOptions();
66
66
  }
67
67
  return { location: 'global', all: true };
@@ -69,50 +69,76 @@ export async function resolveInstallOptionsFromFlags(flags, interactive) {
69
69
  return { location: 'global', all: true };
70
70
  }
71
71
  async function promptInstallOptions() {
72
- const rl = createInterface({ input, output });
73
- try {
74
- const locationAnswer = (await rl.question('Install location? [1] Local (current project) [2] Global (agent platforms) (default: 2): ')).trim();
75
- const location = locationAnswer === '1' ? 'local' : 'global';
76
- if (location === 'local') {
77
- return { location: 'local' };
78
- }
79
- const platformAnswer = (await rl.question('Global install target? [1] All platforms [2] Specific platforms (default: 1): ')).trim();
80
- if (platformAnswer !== '2') {
81
- return { location: 'global', all: true };
82
- }
83
- info(`Available platforms: ${AGENT_PLATFORMS.map((p) => p.replace(/^\./, '')).join(', ')}`);
84
- const selected = (await rl.question('Enter comma-separated platform names (example: claude,gemini,vscode): '))
85
- .split(',')
86
- .map((p) => p.trim())
87
- .filter(Boolean);
88
- return {
89
- location: 'global',
90
- all: selected.length === 0,
91
- platforms: selected,
92
- };
93
- }
94
- finally {
95
- rl.close();
72
+ const { location } = await inquirer.prompt([
73
+ {
74
+ type: 'list',
75
+ name: 'location',
76
+ message: 'Install location',
77
+ choices: [
78
+ { name: 'Local (current project)', value: 'local' },
79
+ { name: 'Global (agent platforms)', value: 'global' },
80
+ ],
81
+ default: 'global',
82
+ },
83
+ ]);
84
+ const { target } = await inquirer.prompt([
85
+ {
86
+ type: 'list',
87
+ name: 'target',
88
+ message: `${location === 'local' ? 'Local' : 'Global'} install target`,
89
+ choices: [
90
+ { name: 'All platforms', value: 'all' },
91
+ { name: 'Specific platforms', value: 'specific' },
92
+ ],
93
+ default: 'all',
94
+ },
95
+ ]);
96
+ if (target === 'all') {
97
+ return { location, all: true };
96
98
  }
99
+ const platformChoices = AGENT_PLATFORMS.map((platform) => {
100
+ const value = platform.replace(/^\./, '');
101
+ return { name: value, value };
102
+ });
103
+ const { platforms } = await inquirer.prompt([
104
+ {
105
+ type: 'checkbox',
106
+ name: 'platforms',
107
+ message: 'Select target platforms',
108
+ choices: platformChoices,
109
+ pageSize: 10,
110
+ validate: (value) => value.length > 0 ? true : 'Please select at least one platform.',
111
+ },
112
+ ]);
113
+ return {
114
+ location,
115
+ all: false,
116
+ platforms,
117
+ };
97
118
  }
98
119
  export async function install(skillName, options = {}) {
99
120
  try {
100
- info(`Fetching ${skillName}...`);
121
+ ui.startSpinner(`Fetching ${skillName}...`);
101
122
  const skillContent = await fetchSkill(skillName);
123
+ ui.stopSpinnerSuccess(`Fetched ${skillName}`);
102
124
  const hash = sha256(skillContent);
103
- info(`Installing ${skillName}...`);
125
+ ui.startSpinner(`Installing ${skillName}...`);
104
126
  const installPaths = await installSkill(skillName, skillContent, options);
127
+ ui.stopSpinnerSuccess(`Installed files for ${skillName}`);
105
128
  if (installPaths.length === 0) {
106
129
  error(`Failed to install ${skillName} to any location`);
107
130
  return false;
108
131
  }
132
+ ui.startSpinner(`Updating lockfile for ${skillName}...`);
109
133
  const index = await fetchRegistryIndex();
110
134
  const skillVersion = index.skills[skillName]?.version || 'unknown';
111
135
  await addSkillToLockfile(skillName, skillVersion, hash, installPaths);
136
+ ui.stopSpinnerSuccess(`Updated lockfile for ${skillName}`);
112
137
  success(`Installed ${skillName} (${skillVersion}) to ${installPaths.length} location(s)`);
113
138
  return true;
114
139
  }
115
140
  catch (err) {
141
+ ui.stopSpinner();
116
142
  error(`Failed to install ${skillName}: ${err instanceof Error ? err.message : String(err)}`);
117
143
  return false;
118
144
  }
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,11 @@
1
- export declare function remove(skillName: string): Promise<boolean>;
1
+ import { type InstallOptions } from '../core/config.js';
2
+ export interface CliRemoveFlags {
3
+ local?: boolean;
4
+ global?: boolean;
5
+ all?: boolean;
6
+ platforms?: string[];
7
+ }
8
+ export declare function parseRemoveFlags(args: string[]): CliRemoveFlags;
9
+ export declare function resolveRemoveOptionsFromFlags(flags: CliRemoveFlags, interactive: boolean): Promise<InstallOptions>;
10
+ export declare function remove(skillName: string, options?: InstallOptions): Promise<boolean>;
2
11
  //# sourceMappingURL=remove.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAIA,wBAAsB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBhE"}
1
+ {"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAMA,OAAO,EAAyC,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAK/F,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CA0B/D;AAED,wBAAsB,6BAA6B,CACjD,KAAK,EAAE,cAAc,EACrB,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,cAAc,CAAC,CAyCzB;AAuDD,wBAAsB,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CA0B9F"}
@@ -1,20 +1,140 @@
1
1
  import { removeSkill } from '../core/installer.js';
2
- import { removeSkillFromLockfile, getSkillEntry } from '../core/lockfile.js';
2
+ import { removeSkillFromLockfile, getSkillEntry, updateSkillInstallPathsInLockfile, } from '../core/lockfile.js';
3
+ import { AGENT_PLATFORMS } from '../core/config.js';
3
4
  import { error, success, info } from '../utils/logger.js';
4
- export async function remove(skillName) {
5
+ import { ui } from '../utils/ui.js';
6
+ import inquirer from 'inquirer';
7
+ export function parseRemoveFlags(args) {
8
+ const flags = {};
9
+ for (let i = 0; i < args.length; i++) {
10
+ const arg = args[i];
11
+ if (arg === '--local') {
12
+ flags.local = true;
13
+ }
14
+ else if (arg === '--global') {
15
+ flags.global = true;
16
+ }
17
+ else if (arg === '--all') {
18
+ flags.all = true;
19
+ }
20
+ else if (arg === '--platform') {
21
+ const value = args[i + 1];
22
+ if (!value || value.startsWith('--')) {
23
+ throw new Error('Missing value for --platform. Example: --platform claude,gemini');
24
+ }
25
+ i++;
26
+ const parsed = value
27
+ .split(',')
28
+ .map((p) => p.trim())
29
+ .filter(Boolean);
30
+ flags.platforms = [...(flags.platforms ?? []), ...parsed];
31
+ }
32
+ }
33
+ return flags;
34
+ }
35
+ export async function resolveRemoveOptionsFromFlags(flags, interactive) {
36
+ if (flags.local && flags.global) {
37
+ throw new Error('Use only one of --local or --global');
38
+ }
39
+ const hasAnyFlag = Boolean(flags.local || flags.global || flags.all || (flags.platforms ?? []).length);
40
+ if (flags.local) {
41
+ return {
42
+ location: 'local',
43
+ all: flags.all || !flags.platforms || flags.platforms.length === 0,
44
+ platforms: flags.platforms,
45
+ };
46
+ }
47
+ if (flags.global) {
48
+ return {
49
+ location: 'global',
50
+ all: flags.all || !flags.platforms || flags.platforms.length === 0,
51
+ platforms: flags.platforms,
52
+ };
53
+ }
54
+ if ((flags.platforms ?? []).length > 0 || flags.all) {
55
+ return {
56
+ location: 'global',
57
+ all: flags.all,
58
+ platforms: flags.platforms,
59
+ };
60
+ }
61
+ if (!hasAnyFlag) {
62
+ if (interactive && process.stdin.isTTY && process.stdout.isTTY) {
63
+ return promptRemoveOptions();
64
+ }
65
+ return { location: 'global', all: true };
66
+ }
67
+ return { location: 'global', all: true };
68
+ }
69
+ async function promptRemoveOptions() {
70
+ const { location } = await inquirer.prompt([
71
+ {
72
+ type: 'list',
73
+ name: 'location',
74
+ message: 'Remove from location',
75
+ choices: [
76
+ { name: 'Local (current project)', value: 'local' },
77
+ { name: 'Global (agent platforms)', value: 'global' },
78
+ ],
79
+ default: 'global',
80
+ },
81
+ ]);
82
+ const { target } = await inquirer.prompt([
83
+ {
84
+ type: 'list',
85
+ name: 'target',
86
+ message: `${location === 'local' ? 'Local' : 'Global'} remove target`,
87
+ choices: [
88
+ { name: 'All platforms', value: 'all' },
89
+ { name: 'Specific platforms', value: 'specific' },
90
+ ],
91
+ default: 'all',
92
+ },
93
+ ]);
94
+ if (target === 'all') {
95
+ return { location, all: true };
96
+ }
97
+ const platformChoices = AGENT_PLATFORMS.map((platform) => {
98
+ const value = platform.replace(/^\./, '');
99
+ return { name: value, value };
100
+ });
101
+ const { platforms } = await inquirer.prompt([
102
+ {
103
+ type: 'checkbox',
104
+ name: 'platforms',
105
+ message: 'Select target platforms',
106
+ choices: platformChoices,
107
+ pageSize: 10,
108
+ },
109
+ ]);
110
+ return {
111
+ location,
112
+ all: platforms.length === 0,
113
+ platforms,
114
+ };
115
+ }
116
+ export async function remove(skillName, options = {}) {
5
117
  try {
6
118
  const entry = await getSkillEntry(skillName);
7
119
  if (!entry) {
8
120
  info(`${skillName} is not installed`);
9
121
  return true;
10
122
  }
11
- info(`Removing ${skillName}...`);
12
- await removeSkill(skillName);
13
- await removeSkillFromLockfile(skillName);
14
- success(`Removed ${skillName}`);
123
+ ui.startSpinner(`Removing ${skillName}...`);
124
+ const removedPaths = await removeSkill(skillName, options);
125
+ const remaining = entry.installPaths.filter((p) => !removedPaths.includes(p));
126
+ if (remaining.length === 0) {
127
+ await removeSkillFromLockfile(skillName);
128
+ }
129
+ else {
130
+ await updateSkillInstallPathsInLockfile(skillName, remaining);
131
+ }
132
+ ui.stopSpinnerSuccess(`Removed files for ${skillName}`);
133
+ success(`Removed ${skillName} from ${removedPaths.length} location(s)`);
15
134
  return true;
16
135
  }
17
136
  catch (err) {
137
+ ui.stopSpinner();
18
138
  error(`Failed to remove ${skillName}: ${err instanceof Error ? err.message : String(err)}`);
19
139
  return false;
20
140
  }
@@ -1 +1 @@
1
- {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,SAAiB;IAC5C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,SAAS,mBAAmB,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,YAAY,SAAS,KAAK,CAAC,CAAC;QACjC,MAAM,WAAW,CAAC,SAAS,CAAC,CAAC;QAC7B,MAAM,uBAAuB,CAAC,SAAS,CAAC,CAAC;QACzC,OAAO,CAAC,WAAW,SAAS,EAAE,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,oBAAoB,SAAS,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5F,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { type InstallOptions } from './config.js';
2
2
  export declare function installSkill(skillName: string, skillContent: string, options?: InstallOptions): Promise<string[]>;
3
- export declare function removeSkill(skillName: string): Promise<string[]>;
3
+ export declare function removeSkill(skillName: string, options?: InstallOptions): Promise<string[]>;
4
4
  export declare function skillExists(skillName: string): Promise<boolean>;
5
5
  export declare function readSkill(skillName: string): Promise<string | null>;
6
6
  //# sourceMappingURL=installer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/core/installer.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+C,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAI/F,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,MAAM,EAAE,CAAC,CA4CnB;AAED,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAmBtE;AAED,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAarE;AAED,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYzE"}
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/core/installer.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+C,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAI/F,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,MAAM,EAAE,CAAC,CA4CnB;AAED,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,MAAM,EAAE,CAAC,CAqBnB;AAED,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAarE;AAED,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYzE"}
@@ -36,21 +36,23 @@ export async function installSkill(skillName, skillContent, options = {}) {
36
36
  }
37
37
  return installedPaths;
38
38
  }
39
- export async function removeSkill(skillName) {
40
- const installPaths = getSkillInstallPaths(skillName);
41
- const metadataPaths = getSkillMetadataPaths(skillName);
39
+ export async function removeSkill(skillName, options = {}) {
40
+ const installPaths = getSkillInstallPaths(skillName, options);
41
+ const metadataPaths = getSkillMetadataPaths(skillName, options);
42
42
  const removedPaths = [];
43
43
  for (let i = 0; i < installPaths.length; i++) {
44
44
  const skillPath = installPaths[i];
45
45
  const metadataPath = metadataPaths[i];
46
+ const skillDir = dirname(skillPath);
46
47
  try {
47
48
  await rm(skillPath, { force: true });
48
49
  await rm(metadataPath, { force: true });
50
+ await rm(skillDir, { recursive: true, force: true });
49
51
  removedPaths.push(skillPath);
50
- info(`Removed ${skillPath}`);
52
+ info(`Removed ${skillDir}`);
51
53
  }
52
54
  catch (err) {
53
- warn(`Failed to remove ${skillPath}: ${err instanceof Error ? err.message : String(err)}`);
55
+ warn(`Failed to remove ${skillDir}: ${err instanceof Error ? err.message : String(err)}`);
54
56
  }
55
57
  }
56
58
  return removedPaths;
@@ -1 +1 @@
1
- {"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/core/installer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/core/installer.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ export declare function readLockfile(): Promise<Lockfile>;
13
13
  export declare function writeLockfile(lockfile: Lockfile): Promise<void>;
14
14
  export declare function addSkillToLockfile(skillName: string, version: string, hash: string, installPaths: string[]): Promise<void>;
15
15
  export declare function removeSkillFromLockfile(skillName: string): Promise<void>;
16
+ export declare function updateSkillInstallPathsInLockfile(skillName: string, installPaths: string[]): Promise<void>;
16
17
  export declare function getInstalledSkills(): Promise<LockfileEntry[]>;
17
18
  export declare function getSkillEntry(skillName: string): Promise<LockfileEntry | null>;
18
19
  //# sourceMappingURL=lockfile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../../src/core/lockfile.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,CAAC,CAAC;IACX,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAChD;AAOD,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,CAQtD;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrE;AAED,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9E;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAGnE;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAGpF"}
1
+ {"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../../src/core/lockfile.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,CAAC,CAAC;IACX,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAChD;AAOD,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,CAQtD;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrE;AAED,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9E;AAED,wBAAsB,iCAAiC,CACrD,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAGnE;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAGpF"}
@@ -36,6 +36,16 @@ export async function removeSkillFromLockfile(skillName) {
36
36
  delete lockfile.installedSkills[skillName];
37
37
  await writeLockfile(lockfile);
38
38
  }
39
+ export async function updateSkillInstallPathsInLockfile(skillName, installPaths) {
40
+ const lockfile = await readLockfile();
41
+ const entry = lockfile.installedSkills[skillName];
42
+ if (!entry) {
43
+ return;
44
+ }
45
+ entry.installPaths = installPaths;
46
+ entry.timestamp = new Date().toISOString();
47
+ await writeLockfile(lockfile);
48
+ }
39
49
  export async function getInstalledSkills() {
40
50
  const lockfile = await readLockfile();
41
51
  return Object.values(lockfile.installedSkills);
@@ -1 +1 @@
1
- {"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../../src/core/lockfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAe9C,MAAM,gBAAgB,GAAa;IACjC,OAAO,EAAE,CAAC;IACV,eAAe,EAAE,EAAE;CACpB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,gBAAgB,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAkB;IACpD,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,OAAe,EACf,IAAY,EACZ,YAAsB;IAEtB,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG;QACpC,IAAI,EAAE,SAAS;QACf,OAAO;QACP,IAAI;QACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,YAAY;KACb,CAAC;IACF,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,SAAiB;IAC7D,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,OAAO,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IAC3C,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,OAAO,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../../src/core/lockfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAe9C,MAAM,gBAAgB,GAAa;IACjC,OAAO,EAAE,CAAC;IACV,eAAe,EAAE,EAAE;CACpB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,gBAAgB,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAkB;IACpD,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,OAAe,EACf,IAAY,EACZ,YAAsB;IAEtB,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG;QACpC,IAAI,EAAE,SAAS;QACf,OAAO;QACP,IAAI;QACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,YAAY;KACb,CAAC;IACF,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,SAAiB;IAC7D,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,OAAO,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IAC3C,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,SAAiB,EACjB,YAAsB;IAEtB,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;IACT,CAAC;IAED,KAAK,CAAC,YAAY,GAAG,YAAY,CAAC;IAClC,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,OAAO,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;AACrD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAiD1C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAqD1C"}
package/dist/index.js CHANGED
@@ -1,11 +1,13 @@
1
1
  import { install, parseInstallFlags, resolveInstallOptionsFromFlags } from './commands/install.js';
2
- import { remove } from './commands/remove.js';
2
+ import { remove, parseRemoveFlags, resolveRemoveOptionsFromFlags } from './commands/remove.js';
3
3
  import { list } from './commands/list.js';
4
4
  import { update } from './commands/update.js';
5
5
  import { generateLocal } from './commands/generate-local.js';
6
6
  import { error, info } from './utils/logger.js';
7
+ import { ui } from './utils/ui.js';
7
8
  const args = process.argv.slice(2);
8
9
  export async function main() {
10
+ ui.printBanner();
9
11
  if (args.length === 0) {
10
12
  showHelp();
11
13
  return;
@@ -21,7 +23,9 @@ export async function main() {
21
23
  }
22
24
  else if (command === 'remove' && args.length >= 2) {
23
25
  const skill = args[1];
24
- const success = await remove(skill);
26
+ const flags = parseRemoveFlags(args.slice(2));
27
+ const options = await resolveRemoveOptionsFromFlags(flags, true);
28
+ const success = await remove(skill, options);
25
29
  process.exit(success ? 0 : 1);
26
30
  }
27
31
  else if (command === 'list') {
@@ -68,7 +72,7 @@ Usage:
68
72
  ai-skills <skill> [options] Install a skill
69
73
  ai-skills install <skill> [options] Install a skill
70
74
  ai-skills list [--json] List installed and available skills
71
- ai-skills remove <skill> Remove an installed skill
75
+ ai-skills remove <skill> [options] Remove an installed skill
72
76
  ai-skills update [--force] Update all installed skills
73
77
  [--skill <name>] Update a specific skill
74
78
  ai-skills generate-local [skill] Run local backend generator
@@ -79,6 +83,12 @@ Install options:
79
83
  --all Install to all global platforms
80
84
  --platform <a,b,c> Install to selected global platforms
81
85
 
86
+ Remove options:
87
+ --local Remove from current project platforms
88
+ --global Remove from home agent platforms
89
+ --all Remove from all platforms for selected scope
90
+ --platform <a,b,c> Remove from selected platforms for selected scope
91
+
82
92
  Examples:
83
93
  ai-skills react
84
94
  ai-skills react --local
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,QAElC;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,QAEnC;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,QAEtC;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,QAEpC;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,QAEnC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAIA,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,QAElC;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,QAEnC;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,QAEtC;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,QAEpC;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,QAEnC"}
@@ -1,17 +1,18 @@
1
1
  /* eslint-disable no-console */
2
+ import chalk from 'chalk';
2
3
  export function log(message) {
3
4
  console.log(message);
4
5
  }
5
6
  export function info(message) {
6
- console.log(`ℹ ${message}`);
7
+ console.log(`${chalk.cyan('ℹ')} ${chalk.gray(message)}`);
7
8
  }
8
9
  export function success(message) {
9
- console.log(`✓ ${message}`);
10
+ console.log(`${chalk.green('✓')} ${chalk.green(message)}`);
10
11
  }
11
12
  export function error(message) {
12
- console.error(`✗ ${message}`);
13
+ console.error(`${chalk.red('✗')} ${chalk.red(message)}`);
13
14
  }
14
15
  export function warn(message) {
15
- console.warn(`⚠ ${message}`);
16
+ console.warn(`${chalk.yellow('⚠')} ${chalk.yellow(message)}`);
16
17
  }
17
18
  //# sourceMappingURL=logger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAE/B,MAAM,UAAU,GAAG,CAAC,OAAe;IACjC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,OAAe;IACnC,OAAO,CAAC,KAAK,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAE/B,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,GAAG,CAAC,OAAe;IACjC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,OAAe;IACnC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const ui: {
2
+ bannerShown: boolean;
3
+ printBanner(): void;
4
+ startSpinner(text: string): void;
5
+ stopSpinnerSuccess(text?: string): void;
6
+ stopSpinnerFail(text?: string): void;
7
+ stopSpinner(): void;
8
+ };
9
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,EAAE;;mBAGE,IAAI;uBAYA,MAAM,GAAG,IAAI;8BAWN,MAAM,GAAG,IAAI;2BAQhB,MAAM,GAAG,IAAI;mBAQrB,IAAI;CAOpB,CAAC"}
@@ -0,0 +1,48 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { info } from '../utils/logger.js';
4
+ let activeSpinner = null;
5
+ export const ui = {
6
+ bannerShown: false,
7
+ printBanner() {
8
+ if (this.bannerShown || !process.stdout.isTTY) {
9
+ return;
10
+ }
11
+ const title = chalk.bold.cyan('AI Skills CLI');
12
+ const subtitle = chalk.gray('Install framework-agnostic SKILLS.md files');
13
+ // Subtle, single-line banner to keep npx output concise
14
+ info(`${title} ${chalk.gray('•')} ${subtitle}`);
15
+ this.bannerShown = true;
16
+ },
17
+ startSpinner(text) {
18
+ if (!process.stdout.isTTY) {
19
+ return;
20
+ }
21
+ if (activeSpinner) {
22
+ activeSpinner.stop();
23
+ }
24
+ activeSpinner = ora({ text, spinner: 'dots' }).start();
25
+ },
26
+ stopSpinnerSuccess(text) {
27
+ if (!activeSpinner) {
28
+ return;
29
+ }
30
+ activeSpinner.succeed(text);
31
+ activeSpinner = null;
32
+ },
33
+ stopSpinnerFail(text) {
34
+ if (!activeSpinner) {
35
+ return;
36
+ }
37
+ activeSpinner.fail(text);
38
+ activeSpinner = null;
39
+ },
40
+ stopSpinner() {
41
+ if (!activeSpinner) {
42
+ return;
43
+ }
44
+ activeSpinner.stop();
45
+ activeSpinner = null;
46
+ },
47
+ };
48
+ //# sourceMappingURL=ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAiB,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,IAAI,aAAa,GAAe,IAAI,CAAC;AAErC,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,WAAW,EAAE,KAAK;IAElB,WAAW;QACT,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QAC1E,wDAAwD;QACxD,IAAI,CAAC,GAAG,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED,YAAY,CAAC,IAAY;QACvB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,aAAa,CAAC,IAAI,EAAE,CAAC;QACvB,CAAC;QACD,aAAa,GAAG,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;IACzD,CAAC;IAED,kBAAkB,CAAC,IAAa;QAC9B,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QACD,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,aAAa,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,eAAe,CAAC,IAAa;QAC3B,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,aAAa,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,WAAW;QACT,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QACD,aAAa,CAAC,IAAI,EAAE,CAAC;QACrB,aAAa,GAAG,IAAI,CAAC;IACvB,CAAC;CACF,CAAC"}
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@emmraan/ai-skills",
3
- "version": "0.1.0",
3
+ "version": "1.0.1",
4
4
  "description": "CLI tool for installing AI Skills across agent platforms",
5
5
  "type": "module",
6
+ "license": "MIT",
6
7
  "bin": {
7
8
  "ai-skills": "bin/skills.js",
8
9
  "skills": "bin/skills.js"
@@ -23,6 +24,11 @@
23
24
  "typecheck": "tsc --noEmit --project tsconfig.json",
24
25
  "clean": "rm -rf dist"
25
26
  },
27
+ "dependencies": {
28
+ "chalk": "^5.4.1",
29
+ "inquirer": "^12.9.6",
30
+ "ora": "^8.2.0"
31
+ },
26
32
  "devDependencies": {
27
33
  "@ai-skills/shared-types": "workspace:*",
28
34
  "@types/node": "^20.10.0",
@@ -3,9 +3,9 @@ import { installSkill } from '../core/installer.js';
3
3
  import { addSkillToLockfile } from '../core/lockfile.js';
4
4
  import { AGENT_PLATFORMS, type InstallOptions, type InstallLocation } from '../core/config.js';
5
5
  import { sha256 } from '../utils/hash.js';
6
- import { error, success, info } from '../utils/logger.js';
7
- import { createInterface } from 'readline/promises';
8
- import { stdin as input, stdout as output } from 'process';
6
+ import { error, success } from '../utils/logger.js';
7
+ import inquirer from 'inquirer';
8
+ import { ui } from '../utils/ui.js';
9
9
 
10
10
  export interface CliInstallFlags {
11
11
  local?: boolean;
@@ -79,7 +79,7 @@ export async function resolveInstallOptionsFromFlags(
79
79
  }
80
80
 
81
81
  if (!hasAnyFlag) {
82
- if (interactive && input.isTTY && output.isTTY) {
82
+ if (interactive && process.stdin.isTTY && process.stdout.isTTY) {
83
83
  return promptInstallOptions();
84
84
  }
85
85
  return { location: 'global', all: true };
@@ -89,68 +89,86 @@ export async function resolveInstallOptionsFromFlags(
89
89
  }
90
90
 
91
91
  async function promptInstallOptions(): Promise<InstallOptions> {
92
- const rl = createInterface({ input, output });
93
- try {
94
- const locationAnswer = (
95
- await rl.question(
96
- 'Install location? [1] Local (current project) [2] Global (agent platforms) (default: 2): '
97
- )
98
- ).trim();
99
-
100
- const location: InstallLocation = locationAnswer === '1' ? 'local' : 'global';
101
- if (location === 'local') {
102
- return { location: 'local' };
103
- }
104
-
105
- const platformAnswer = (
106
- await rl.question(
107
- 'Global install target? [1] All platforms [2] Specific platforms (default: 1): '
108
- )
109
- ).trim();
110
-
111
- if (platformAnswer !== '2') {
112
- return { location: 'global', all: true };
113
- }
114
-
115
- info(`Available platforms: ${AGENT_PLATFORMS.map((p) => p.replace(/^\./, '')).join(', ')}`);
116
- const selected = (
117
- await rl.question('Enter comma-separated platform names (example: claude,gemini,vscode): ')
118
- )
119
- .split(',')
120
- .map((p) => p.trim())
121
- .filter(Boolean);
122
-
123
- return {
124
- location: 'global',
125
- all: selected.length === 0,
126
- platforms: selected,
127
- };
128
- } finally {
129
- rl.close();
92
+ const { location } = await inquirer.prompt<{ location: InstallLocation }>([
93
+ {
94
+ type: 'list',
95
+ name: 'location',
96
+ message: 'Install location',
97
+ choices: [
98
+ { name: 'Local (current project)', value: 'local' },
99
+ { name: 'Global (agent platforms)', value: 'global' },
100
+ ],
101
+ default: 'global',
102
+ },
103
+ ]);
104
+
105
+ const { target } = await inquirer.prompt<{ target: 'all' | 'specific' }>([
106
+ {
107
+ type: 'list',
108
+ name: 'target',
109
+ message: `${location === 'local' ? 'Local' : 'Global'} install target`,
110
+ choices: [
111
+ { name: 'All platforms', value: 'all' },
112
+ { name: 'Specific platforms', value: 'specific' },
113
+ ],
114
+ default: 'all',
115
+ },
116
+ ]);
117
+
118
+ if (target === 'all') {
119
+ return { location, all: true };
130
120
  }
121
+
122
+ const platformChoices = AGENT_PLATFORMS.map((platform) => {
123
+ const value = platform.replace(/^\./, '');
124
+ return { name: value, value };
125
+ });
126
+
127
+ const { platforms } = await inquirer.prompt<{ platforms: string[] }>([
128
+ {
129
+ type: 'checkbox',
130
+ name: 'platforms',
131
+ message: 'Select target platforms',
132
+ choices: platformChoices,
133
+ pageSize: 10,
134
+ validate: (value: string[]) =>
135
+ value.length > 0 ? true : 'Please select at least one platform.',
136
+ },
137
+ ]);
138
+
139
+ return {
140
+ location,
141
+ all: false,
142
+ platforms,
143
+ };
131
144
  }
132
145
 
133
146
  export async function install(skillName: string, options: InstallOptions = {}): Promise<boolean> {
134
147
  try {
135
- info(`Fetching ${skillName}...`);
148
+ ui.startSpinner(`Fetching ${skillName}...`);
136
149
  const skillContent = await fetchSkill(skillName);
150
+ ui.stopSpinnerSuccess(`Fetched ${skillName}`);
137
151
  const hash = sha256(skillContent);
138
152
 
139
- info(`Installing ${skillName}...`);
153
+ ui.startSpinner(`Installing ${skillName}...`);
140
154
  const installPaths = await installSkill(skillName, skillContent, options);
155
+ ui.stopSpinnerSuccess(`Installed files for ${skillName}`);
141
156
 
142
157
  if (installPaths.length === 0) {
143
158
  error(`Failed to install ${skillName} to any location`);
144
159
  return false;
145
160
  }
146
161
 
162
+ ui.startSpinner(`Updating lockfile for ${skillName}...`);
147
163
  const index = await fetchRegistryIndex();
148
164
  const skillVersion = index.skills[skillName]?.version || 'unknown';
149
165
 
150
166
  await addSkillToLockfile(skillName, skillVersion, hash, installPaths);
167
+ ui.stopSpinnerSuccess(`Updated lockfile for ${skillName}`);
151
168
  success(`Installed ${skillName} (${skillVersion}) to ${installPaths.length} location(s)`);
152
169
  return true;
153
170
  } catch (err) {
171
+ ui.stopSpinner();
154
172
  error(`Failed to install ${skillName}: ${err instanceof Error ? err.message : String(err)}`);
155
173
  return false;
156
174
  }
@@ -1,8 +1,149 @@
1
1
  import { removeSkill } from '../core/installer.js';
2
- import { removeSkillFromLockfile, getSkillEntry } from '../core/lockfile.js';
2
+ import {
3
+ removeSkillFromLockfile,
4
+ getSkillEntry,
5
+ updateSkillInstallPathsInLockfile,
6
+ } from '../core/lockfile.js';
7
+ import { AGENT_PLATFORMS, type InstallLocation, type InstallOptions } from '../core/config.js';
3
8
  import { error, success, info } from '../utils/logger.js';
9
+ import { ui } from '../utils/ui.js';
10
+ import inquirer from 'inquirer';
4
11
 
5
- export async function remove(skillName: string): Promise<boolean> {
12
+ export interface CliRemoveFlags {
13
+ local?: boolean;
14
+ global?: boolean;
15
+ all?: boolean;
16
+ platforms?: string[];
17
+ }
18
+
19
+ export function parseRemoveFlags(args: string[]): CliRemoveFlags {
20
+ const flags: CliRemoveFlags = {};
21
+
22
+ for (let i = 0; i < args.length; i++) {
23
+ const arg = args[i];
24
+ if (arg === '--local') {
25
+ flags.local = true;
26
+ } else if (arg === '--global') {
27
+ flags.global = true;
28
+ } else if (arg === '--all') {
29
+ flags.all = true;
30
+ } else if (arg === '--platform') {
31
+ const value = args[i + 1];
32
+ if (!value || value.startsWith('--')) {
33
+ throw new Error('Missing value for --platform. Example: --platform claude,gemini');
34
+ }
35
+ i++;
36
+ const parsed = value
37
+ .split(',')
38
+ .map((p) => p.trim())
39
+ .filter(Boolean);
40
+ flags.platforms = [...(flags.platforms ?? []), ...parsed];
41
+ }
42
+ }
43
+
44
+ return flags;
45
+ }
46
+
47
+ export async function resolveRemoveOptionsFromFlags(
48
+ flags: CliRemoveFlags,
49
+ interactive: boolean
50
+ ): Promise<InstallOptions> {
51
+ if (flags.local && flags.global) {
52
+ throw new Error('Use only one of --local or --global');
53
+ }
54
+
55
+ const hasAnyFlag = Boolean(
56
+ flags.local || flags.global || flags.all || (flags.platforms ?? []).length
57
+ );
58
+
59
+ if (flags.local) {
60
+ return {
61
+ location: 'local',
62
+ all: flags.all || !flags.platforms || flags.platforms.length === 0,
63
+ platforms: flags.platforms,
64
+ };
65
+ }
66
+
67
+ if (flags.global) {
68
+ return {
69
+ location: 'global',
70
+ all: flags.all || !flags.platforms || flags.platforms.length === 0,
71
+ platforms: flags.platforms,
72
+ };
73
+ }
74
+
75
+ if ((flags.platforms ?? []).length > 0 || flags.all) {
76
+ return {
77
+ location: 'global',
78
+ all: flags.all,
79
+ platforms: flags.platforms,
80
+ };
81
+ }
82
+
83
+ if (!hasAnyFlag) {
84
+ if (interactive && process.stdin.isTTY && process.stdout.isTTY) {
85
+ return promptRemoveOptions();
86
+ }
87
+ return { location: 'global', all: true };
88
+ }
89
+
90
+ return { location: 'global', all: true };
91
+ }
92
+
93
+ async function promptRemoveOptions(): Promise<InstallOptions> {
94
+ const { location } = await inquirer.prompt<{ location: InstallLocation }>([
95
+ {
96
+ type: 'list',
97
+ name: 'location',
98
+ message: 'Remove from location',
99
+ choices: [
100
+ { name: 'Local (current project)', value: 'local' },
101
+ { name: 'Global (agent platforms)', value: 'global' },
102
+ ],
103
+ default: 'global',
104
+ },
105
+ ]);
106
+
107
+ const { target } = await inquirer.prompt<{ target: 'all' | 'specific' }>([
108
+ {
109
+ type: 'list',
110
+ name: 'target',
111
+ message: `${location === 'local' ? 'Local' : 'Global'} remove target`,
112
+ choices: [
113
+ { name: 'All platforms', value: 'all' },
114
+ { name: 'Specific platforms', value: 'specific' },
115
+ ],
116
+ default: 'all',
117
+ },
118
+ ]);
119
+
120
+ if (target === 'all') {
121
+ return { location, all: true };
122
+ }
123
+
124
+ const platformChoices = AGENT_PLATFORMS.map((platform) => {
125
+ const value = platform.replace(/^\./, '');
126
+ return { name: value, value };
127
+ });
128
+
129
+ const { platforms } = await inquirer.prompt<{ platforms: string[] }>([
130
+ {
131
+ type: 'checkbox',
132
+ name: 'platforms',
133
+ message: 'Select target platforms',
134
+ choices: platformChoices,
135
+ pageSize: 10,
136
+ },
137
+ ]);
138
+
139
+ return {
140
+ location,
141
+ all: platforms.length === 0,
142
+ platforms,
143
+ };
144
+ }
145
+
146
+ export async function remove(skillName: string, options: InstallOptions = {}): Promise<boolean> {
6
147
  try {
7
148
  const entry = await getSkillEntry(skillName);
8
149
  if (!entry) {
@@ -10,12 +151,21 @@ export async function remove(skillName: string): Promise<boolean> {
10
151
  return true;
11
152
  }
12
153
 
13
- info(`Removing ${skillName}...`);
14
- await removeSkill(skillName);
15
- await removeSkillFromLockfile(skillName);
16
- success(`Removed ${skillName}`);
154
+ ui.startSpinner(`Removing ${skillName}...`);
155
+ const removedPaths = await removeSkill(skillName, options);
156
+
157
+ const remaining = entry.installPaths.filter((p) => !removedPaths.includes(p));
158
+ if (remaining.length === 0) {
159
+ await removeSkillFromLockfile(skillName);
160
+ } else {
161
+ await updateSkillInstallPathsInLockfile(skillName, remaining);
162
+ }
163
+
164
+ ui.stopSpinnerSuccess(`Removed files for ${skillName}`);
165
+ success(`Removed ${skillName} from ${removedPaths.length} location(s)`);
17
166
  return true;
18
167
  } catch (err) {
168
+ ui.stopSpinner();
19
169
  error(`Failed to remove ${skillName}: ${err instanceof Error ? err.message : String(err)}`);
20
170
  return false;
21
171
  }
@@ -54,21 +54,26 @@ export async function installSkill(
54
54
  return installedPaths;
55
55
  }
56
56
 
57
- export async function removeSkill(skillName: string): Promise<string[]> {
58
- const installPaths = getSkillInstallPaths(skillName);
59
- const metadataPaths = getSkillMetadataPaths(skillName);
57
+ export async function removeSkill(
58
+ skillName: string,
59
+ options: InstallOptions = {}
60
+ ): Promise<string[]> {
61
+ const installPaths = getSkillInstallPaths(skillName, options);
62
+ const metadataPaths = getSkillMetadataPaths(skillName, options);
60
63
  const removedPaths: string[] = [];
61
64
 
62
65
  for (let i = 0; i < installPaths.length; i++) {
63
66
  const skillPath = installPaths[i];
64
67
  const metadataPath = metadataPaths[i];
68
+ const skillDir = dirname(skillPath);
65
69
  try {
66
70
  await rm(skillPath, { force: true });
67
71
  await rm(metadataPath, { force: true });
72
+ await rm(skillDir, { recursive: true, force: true });
68
73
  removedPaths.push(skillPath);
69
- info(`Removed ${skillPath}`);
74
+ info(`Removed ${skillDir}`);
70
75
  } catch (err) {
71
- warn(`Failed to remove ${skillPath}: ${err instanceof Error ? err.message : String(err)}`);
76
+ warn(`Failed to remove ${skillDir}: ${err instanceof Error ? err.message : String(err)}`);
72
77
  }
73
78
  }
74
79
 
@@ -59,6 +59,21 @@ export async function removeSkillFromLockfile(skillName: string): Promise<void>
59
59
  await writeLockfile(lockfile);
60
60
  }
61
61
 
62
+ export async function updateSkillInstallPathsInLockfile(
63
+ skillName: string,
64
+ installPaths: string[]
65
+ ): Promise<void> {
66
+ const lockfile = await readLockfile();
67
+ const entry = lockfile.installedSkills[skillName];
68
+ if (!entry) {
69
+ return;
70
+ }
71
+
72
+ entry.installPaths = installPaths;
73
+ entry.timestamp = new Date().toISOString();
74
+ await writeLockfile(lockfile);
75
+ }
76
+
62
77
  export async function getInstalledSkills(): Promise<LockfileEntry[]> {
63
78
  const lockfile = await readLockfile();
64
79
  return Object.values(lockfile.installedSkills);
package/src/index.ts CHANGED
@@ -1,13 +1,16 @@
1
1
  import { install, parseInstallFlags, resolveInstallOptionsFromFlags } from './commands/install.js';
2
- import { remove } from './commands/remove.js';
2
+ import { remove, parseRemoveFlags, resolveRemoveOptionsFromFlags } from './commands/remove.js';
3
3
  import { list } from './commands/list.js';
4
4
  import { update } from './commands/update.js';
5
5
  import { generateLocal } from './commands/generate-local.js';
6
6
  import { error, info } from './utils/logger.js';
7
+ import { ui } from './utils/ui.js';
7
8
 
8
9
  const args = process.argv.slice(2);
9
10
 
10
11
  export async function main(): Promise<void> {
12
+ ui.printBanner();
13
+
11
14
  if (args.length === 0) {
12
15
  showHelp();
13
16
  return;
@@ -24,7 +27,9 @@ export async function main(): Promise<void> {
24
27
  process.exit(success ? 0 : 1);
25
28
  } else if (command === 'remove' && args.length >= 2) {
26
29
  const skill = args[1];
27
- const success = await remove(skill);
30
+ const flags = parseRemoveFlags(args.slice(2));
31
+ const options = await resolveRemoveOptionsFromFlags(flags, true);
32
+ const success = await remove(skill, options);
28
33
  process.exit(success ? 0 : 1);
29
34
  } else if (command === 'list') {
30
35
  const jsonFlag = args.includes('--json');
@@ -66,7 +71,7 @@ Usage:
66
71
  ai-skills <skill> [options] Install a skill
67
72
  ai-skills install <skill> [options] Install a skill
68
73
  ai-skills list [--json] List installed and available skills
69
- ai-skills remove <skill> Remove an installed skill
74
+ ai-skills remove <skill> [options] Remove an installed skill
70
75
  ai-skills update [--force] Update all installed skills
71
76
  [--skill <name>] Update a specific skill
72
77
  ai-skills generate-local [skill] Run local backend generator
@@ -77,6 +82,12 @@ Install options:
77
82
  --all Install to all global platforms
78
83
  --platform <a,b,c> Install to selected global platforms
79
84
 
85
+ Remove options:
86
+ --local Remove from current project platforms
87
+ --global Remove from home agent platforms
88
+ --all Remove from all platforms for selected scope
89
+ --platform <a,b,c> Remove from selected platforms for selected scope
90
+
80
91
  Examples:
81
92
  ai-skills react
82
93
  ai-skills react --local
@@ -1,21 +1,23 @@
1
1
  /* eslint-disable no-console */
2
2
 
3
+ import chalk from 'chalk';
4
+
3
5
  export function log(message: string) {
4
6
  console.log(message);
5
7
  }
6
8
 
7
9
  export function info(message: string) {
8
- console.log(`ℹ ${message}`);
10
+ console.log(`${chalk.cyan('ℹ')} ${chalk.gray(message)}`);
9
11
  }
10
12
 
11
13
  export function success(message: string) {
12
- console.log(`✓ ${message}`);
14
+ console.log(`${chalk.green('✓')} ${chalk.green(message)}`);
13
15
  }
14
16
 
15
17
  export function error(message: string) {
16
- console.error(`✗ ${message}`);
18
+ console.error(`${chalk.red('✗')} ${chalk.red(message)}`);
17
19
  }
18
20
 
19
21
  export function warn(message: string) {
20
- console.warn(`⚠ ${message}`);
22
+ console.warn(`${chalk.yellow('⚠')} ${chalk.yellow(message)}`);
21
23
  }
@@ -0,0 +1,57 @@
1
+ import chalk from 'chalk';
2
+ import ora, { type Ora } from 'ora';
3
+ import { info } from '../utils/logger.js';
4
+
5
+ let activeSpinner: Ora | null = null;
6
+
7
+ export const ui = {
8
+ bannerShown: false,
9
+
10
+ printBanner(): void {
11
+ if (this.bannerShown || !process.stdout.isTTY) {
12
+ return;
13
+ }
14
+
15
+ const title = chalk.bold.cyan('AI Skills CLI');
16
+ const subtitle = chalk.gray('Install framework-agnostic SKILLS.md files');
17
+ // Subtle, single-line banner to keep npx output concise
18
+ info(`${title} ${chalk.gray('•')} ${subtitle}`);
19
+ this.bannerShown = true;
20
+ },
21
+
22
+ startSpinner(text: string): void {
23
+ if (!process.stdout.isTTY) {
24
+ return;
25
+ }
26
+
27
+ if (activeSpinner) {
28
+ activeSpinner.stop();
29
+ }
30
+ activeSpinner = ora({ text, spinner: 'dots' }).start();
31
+ },
32
+
33
+ stopSpinnerSuccess(text?: string): void {
34
+ if (!activeSpinner) {
35
+ return;
36
+ }
37
+ activeSpinner.succeed(text);
38
+ activeSpinner = null;
39
+ },
40
+
41
+ stopSpinnerFail(text?: string): void {
42
+ if (!activeSpinner) {
43
+ return;
44
+ }
45
+ activeSpinner.fail(text);
46
+ activeSpinner = null;
47
+ },
48
+
49
+ stopSpinner(): void {
50
+ if (!activeSpinner) {
51
+ return;
52
+ }
53
+ activeSpinner.stop();
54
+ activeSpinner = null;
55
+ },
56
+ };
57
+