@agents-inc/cli 0.86.0 → 0.87.0

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/chunk-5UJJQFET.js +564 -0
  3. package/dist/chunk-5UJJQFET.js.map +1 -0
  4. package/dist/{chunk-GED2F75H.js → chunk-7FFNNDJQ.js} +176 -120
  5. package/dist/chunk-7FFNNDJQ.js.map +1 -0
  6. package/dist/{chunk-BV2MIQ3O.js → chunk-I5AZKNNL.js} +1 -1
  7. package/dist/chunk-I5AZKNNL.js.map +1 -0
  8. package/dist/chunk-J6PI73YV.js +68 -0
  9. package/dist/chunk-J6PI73YV.js.map +1 -0
  10. package/dist/commands/compile.js +26 -20
  11. package/dist/commands/compile.js.map +1 -1
  12. package/dist/commands/diff.js +681 -82
  13. package/dist/commands/diff.js.map +1 -1
  14. package/dist/commands/doctor.js +30 -58
  15. package/dist/commands/doctor.js.map +1 -1
  16. package/dist/commands/edit.js +164 -32
  17. package/dist/commands/edit.js.map +1 -1
  18. package/dist/commands/eject.js +177 -27
  19. package/dist/commands/eject.js.map +1 -1
  20. package/dist/commands/import/skill.js +197 -33
  21. package/dist/commands/import/skill.js.map +1 -1
  22. package/dist/commands/info.js +41 -34
  23. package/dist/commands/info.js.map +1 -1
  24. package/dist/commands/init.js +3 -6
  25. package/dist/commands/new/agent.js +140 -44
  26. package/dist/commands/new/agent.js.map +1 -1
  27. package/dist/commands/new/marketplace.js +4 -4
  28. package/dist/commands/new/marketplace.js.map +1 -1
  29. package/dist/commands/new/skill.js +194 -30
  30. package/dist/commands/new/skill.js.map +1 -1
  31. package/dist/commands/outdated.js +1 -3
  32. package/dist/commands/outdated.js.map +1 -1
  33. package/dist/commands/search.js +162 -65
  34. package/dist/commands/search.js.map +1 -1
  35. package/dist/commands/uninstall.js +259 -62
  36. package/dist/commands/uninstall.js.map +1 -1
  37. package/dist/commands/update.js +232 -163
  38. package/dist/commands/update.js.map +1 -1
  39. package/dist/components/skill-search/skill-search.js +1 -1
  40. package/dist/hooks/init.js +2 -4
  41. package/dist/hooks/init.js.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/chunk-BV2MIQ3O.js.map +0 -1
  44. package/dist/chunk-DCVCFBQ7.js +0 -1800
  45. package/dist/chunk-DCVCFBQ7.js.map +0 -1
  46. package/dist/chunk-GED2F75H.js.map +0 -1
  47. package/dist/chunk-O5ZWS26C.js +0 -166
  48. package/dist/chunk-O5ZWS26C.js.map +0 -1
  49. package/dist/chunk-XQK4S22C.js +0 -202
  50. package/dist/chunk-XQK4S22C.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  SkillSearch
4
- } from "../chunk-BV2MIQ3O.js";
4
+ } from "../chunk-I5AZKNNL.js";
5
5
  import "../chunk-HEQVUIHQ.js";
6
6
  import "../chunk-U3IGFMCY.js";
7
7
  import "../chunk-HK53FRMU.js";
@@ -11,31 +11,36 @@ import {
11
11
  SUCCESS_MESSAGES
12
12
  } from "../chunk-B7KZLXHV.js";
13
13
  import {
14
- copySearchedSkillsToLocal,
15
- fetchSkillsFromExternalSource,
16
- filterSkillsByQuery,
17
- loadSource,
18
- toSourcedSkill
19
- } from "../chunk-DCVCFBQ7.js";
14
+ loadSource
15
+ } from "../chunk-5UJJQFET.js";
20
16
  import {
21
17
  truncateText
22
18
  } from "../chunk-N6A7A4RA.js";
23
- import "../chunk-O5ZWS26C.js";
24
- import "../chunk-XQK4S22C.js";
25
19
  import "../chunk-FBZR46GC.js";
26
20
  import {
21
+ fetchFromSource,
27
22
  resolveAllSources
28
23
  } from "../chunk-TMTUTUEV.js";
29
- import "../chunk-B6MYECV6.js";
24
+ import {
25
+ parseFrontmatter
26
+ } from "../chunk-B6MYECV6.js";
30
27
  import "../chunk-ANXHMG32.js";
31
28
  import {
32
29
  BaseCommand,
33
30
  EXIT_CODES
34
31
  } from "../chunk-MMTMXLI4.js";
35
- import "../chunk-NUU3U43A.js";
32
+ import {
33
+ copy,
34
+ ensureDir,
35
+ fileExists,
36
+ listDirectories,
37
+ readFile
38
+ } from "../chunk-NUU3U43A.js";
36
39
  import "../chunk-6XWHJHNZ.js";
37
40
  import {
38
- LOCAL_SKILLS_PATH
41
+ DEFAULT_SKILLS_SUBDIR,
42
+ LOCAL_SKILLS_PATH,
43
+ STANDARD_FILES
39
44
  } from "../chunk-6PGL2XMY.js";
40
45
  import "../chunk-NPMMU4GY.js";
41
46
  import {
@@ -111,45 +116,9 @@ var Search = class _Search extends BaseCommand {
111
116
  }
112
117
  }
113
118
  async runInteractive(initialQuery, forceRefresh, projectDir) {
114
- this.log("Loading skills from all sources...");
115
119
  try {
116
- const { sourceResult } = await loadSource({
117
- sourceFlag: void 0,
118
- projectDir,
119
- forceRefresh
120
- });
121
- const { matrix, sourcePath } = sourceResult;
122
- const primarySkills = Object.values(matrix.skills).filter((skill) => skill !== void 0).map((skill) => toSourcedSkill(skill, "marketplace", sourcePath));
123
- const { extras } = await resolveAllSources(projectDir);
124
- const extraSkillArrays = await Promise.all(
125
- extras.map((source) => fetchSkillsFromExternalSource(source, forceRefresh))
126
- );
127
- const allSkills = [...primarySkills, ...extraSkillArrays.flat()];
128
- const sourceCount = 1 + extras.length;
129
- this.log(`Loaded ${allSkills.length} skills from ${sourceCount} source(s)`);
130
- this.log("");
131
- const searchResultPromise = new Promise((resolve) => {
132
- const { waitUntilExit } = render(
133
- /* @__PURE__ */ jsx(
134
- SkillSearch,
135
- {
136
- skills: allSkills,
137
- sourceCount,
138
- initialQuery,
139
- onComplete: (result) => {
140
- resolve(result);
141
- },
142
- onCancel: () => {
143
- resolve({ selectedSkills: [], cancelled: true });
144
- }
145
- }
146
- )
147
- );
148
- waitUntilExit().then(() => {
149
- resolve({ selectedSkills: [], cancelled: true });
150
- });
151
- });
152
- const searchResult = await searchResultPromise;
120
+ const { allSkills, sourceCount } = await this.loadAllSourceSkills(forceRefresh, projectDir);
121
+ const searchResult = await this.showSearchUI(allSkills, sourceCount, initialQuery);
153
122
  if (searchResult.cancelled) {
154
123
  this.log("Search cancelled");
155
124
  this.exit(EXIT_CODES.CANCELLED);
@@ -158,25 +127,71 @@ var Search = class _Search extends BaseCommand {
158
127
  this.log("No skills selected");
159
128
  return;
160
129
  }
161
- this.log("");
162
- this.log(`Importing ${searchResult.selectedSkills.length} skill(s)...`);
163
- const copyResults = await copySearchedSkillsToLocal(searchResult.selectedSkills, projectDir);
164
- for (const result of copyResults) {
165
- if (result.copied) {
166
- this.logSuccess(`Imported: ${result.id}`);
167
- } else {
168
- this.warn(`Skipping ${result.id}: ${result.reason}`);
169
- }
170
- }
171
- const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);
172
- this.log("");
173
- this.logSuccess(SUCCESS_MESSAGES.IMPORT_COMPLETE);
174
- this.log(`Skills location: ${destDir}`);
175
- this.log(INFO_MESSAGES.RUN_COMPILE);
130
+ await this.importSelectedSkills(searchResult.selectedSkills, projectDir);
176
131
  } catch (error) {
177
132
  this.handleError(error);
178
133
  }
179
134
  }
135
+ async loadAllSourceSkills(forceRefresh, projectDir) {
136
+ this.log("Loading skills from all sources...");
137
+ const { sourceResult } = await loadSource({
138
+ sourceFlag: void 0,
139
+ projectDir,
140
+ forceRefresh
141
+ });
142
+ const { matrix, sourcePath } = sourceResult;
143
+ const primarySkills = Object.values(matrix.skills).filter((skill) => skill !== void 0).map((skill) => toSourcedSkill(skill, "marketplace", sourcePath));
144
+ const { extras } = await resolveAllSources(projectDir);
145
+ const extraSkillArrays = await Promise.all(
146
+ extras.map((source) => fetchSkillsFromExternalSource(source, forceRefresh))
147
+ );
148
+ const allSkills = [...primarySkills, ...extraSkillArrays.flat()];
149
+ const sourceCount = 1 + extras.length;
150
+ this.log(`Loaded ${allSkills.length} skills from ${sourceCount} source(s)`);
151
+ this.log("");
152
+ return { allSkills, sourceCount };
153
+ }
154
+ async showSearchUI(allSkills, sourceCount, initialQuery) {
155
+ const searchResultPromise = new Promise((resolve) => {
156
+ const { waitUntilExit } = render(
157
+ /* @__PURE__ */ jsx(
158
+ SkillSearch,
159
+ {
160
+ skills: allSkills,
161
+ sourceCount,
162
+ initialQuery,
163
+ onComplete: (result) => {
164
+ resolve(result);
165
+ },
166
+ onCancel: () => {
167
+ resolve({ selectedSkills: [], cancelled: true });
168
+ }
169
+ }
170
+ )
171
+ );
172
+ waitUntilExit().then(() => {
173
+ resolve({ selectedSkills: [], cancelled: true });
174
+ });
175
+ });
176
+ return searchResultPromise;
177
+ }
178
+ async importSelectedSkills(skills, projectDir) {
179
+ this.log("");
180
+ this.log(`Importing ${skills.length} skill(s)...`);
181
+ const copyResults = await copySearchedSkillsToLocal(skills, projectDir);
182
+ for (const result of copyResults) {
183
+ if (result.copied) {
184
+ this.logSuccess(`Imported: ${result.id}`);
185
+ } else {
186
+ this.warn(`Skipping ${result.id}: ${result.reason}`);
187
+ }
188
+ }
189
+ const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);
190
+ this.log("");
191
+ this.logSuccess(SUCCESS_MESSAGES.IMPORT_COMPLETE);
192
+ this.log(`Skills location: ${destDir}`);
193
+ this.log(INFO_MESSAGES.RUN_COMPILE);
194
+ }
180
195
  async runStatic(query, flags) {
181
196
  try {
182
197
  this.log(STATUS_MESSAGES.LOADING_SKILLS);
@@ -227,6 +242,88 @@ var Search = class _Search extends BaseCommand {
227
242
  }
228
243
  }
229
244
  };
245
+ async function fetchSkillsFromExternalSource(source, forceRefresh) {
246
+ try {
247
+ const result = await fetchFromSource(source.url, { forceRefresh });
248
+ const skillsDir = path.join(result.path, DEFAULT_SKILLS_SUBDIR);
249
+ if (!await fileExists(skillsDir)) {
250
+ return [];
251
+ }
252
+ const skillDirs = await listDirectories(skillsDir);
253
+ const skills = [];
254
+ for (const skillDir of skillDirs) {
255
+ const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);
256
+ if (!await fileExists(skillMdPath)) continue;
257
+ const content = await readFile(skillMdPath);
258
+ const frontmatter = parseFrontmatter(content, skillMdPath);
259
+ if (!frontmatter) continue;
260
+ skills.push({
261
+ id: frontmatter.name,
262
+ description: frontmatter.description,
263
+ // Boundary cast: directory name used as slug for third-party source skill
264
+ slug: skillDir,
265
+ displayName: skillDir,
266
+ // Boundary cast: external source skills have no real category; "imported" is a display-only placeholder
267
+ category: "imported",
268
+ author: `@${source.name}`,
269
+ conflictsWith: [],
270
+ isRecommended: false,
271
+ requires: [],
272
+ alternatives: [],
273
+ discourages: [],
274
+ compatibleWith: [],
275
+ sourceName: source.name,
276
+ sourceUrl: source.url,
277
+ path: path.join(skillsDir, skillDir)
278
+ });
279
+ }
280
+ return skills;
281
+ } catch {
282
+ return [];
283
+ }
284
+ }
285
+ function matchesQuery(skill, query) {
286
+ const lowerQuery = query.toLowerCase();
287
+ if (skill.id.toLowerCase().includes(lowerQuery)) return true;
288
+ if (skill.displayName.toLowerCase().includes(lowerQuery)) return true;
289
+ if (skill.slug.toLowerCase().includes(lowerQuery)) return true;
290
+ if (skill.description.toLowerCase().includes(lowerQuery)) return true;
291
+ if (skill.category.toLowerCase().includes(lowerQuery)) return true;
292
+ return false;
293
+ }
294
+ function matchesCategory(skill, category) {
295
+ const lowerCategory = category.toLowerCase();
296
+ return skill.category.toLowerCase().includes(lowerCategory);
297
+ }
298
+ function filterSkillsByQuery(skills, options) {
299
+ let results = skills.filter((skill) => matchesQuery(skill, options.query));
300
+ if (options.category) {
301
+ results = results.filter((skill) => matchesCategory(skill, options.category));
302
+ }
303
+ return results;
304
+ }
305
+ function toSourcedSkill(skill, sourceName, sourceUrl) {
306
+ return {
307
+ ...skill,
308
+ sourceName,
309
+ sourceUrl
310
+ };
311
+ }
312
+ async function copySearchedSkillsToLocal(skills, projectDir) {
313
+ const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);
314
+ const results = [];
315
+ for (const skill of skills) {
316
+ if (skill.path) {
317
+ const destPath = path.join(destDir, skill.id);
318
+ await ensureDir(path.dirname(destPath));
319
+ await copy(skill.path, destPath);
320
+ results.push({ id: skill.id, copied: true });
321
+ } else {
322
+ results.push({ id: skill.id, copied: false, reason: "No source path available" });
323
+ }
324
+ }
325
+ return results;
326
+ }
230
327
  export {
231
328
  Search as default
232
329
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/search.tsx","../../src/cli/components/skill-search/index.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport { render } from \"ink\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { SkillSearch, type SkillSearchResult } from \"../components/skill-search/index.js\";\nimport { LOCAL_SKILLS_PATH } from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { resolveAllSources } from \"../lib/configuration/index.js\";\nimport {\n loadSource,\n fetchSkillsFromExternalSource,\n filterSkillsByQuery,\n toSourcedSkill,\n copySearchedSkillsToLocal,\n type SourcedSkill,\n} from \"../lib/operations/index.js\";\nimport type { ResolvedSkill } from \"../types/index.js\";\nimport { SUCCESS_MESSAGES, STATUS_MESSAGES, INFO_MESSAGES } from \"../utils/messages.js\";\nimport { truncateText } from \"../utils/string.js\";\n\nconst MAX_DESCRIPTION_WIDTH = 50;\n\nexport default class Search extends BaseCommand {\n static summary = \"Search available skills\";\n static description =\n \"Search skills by ID, alias, description, or category. \" +\n \"Run without arguments or with -i for interactive mode with multi-select.\";\n\n static examples = [\n {\n description: \"Search for React skills\",\n command: \"<%= config.bin %> search react\",\n },\n {\n description: \"Interactive search mode\",\n command: \"<%= config.bin %> search\",\n },\n {\n description: \"Interactive with pre-filled query\",\n command: \"<%= config.bin %> search -i react\",\n },\n {\n description: \"Search with category filter\",\n command: \"<%= config.bin %> search state -c frontend\",\n },\n ];\n\n static args = {\n query: Args.string({\n description: \"Search query (matches name, description, category)\",\n required: false,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n interactive: Flags.boolean({\n char: \"i\",\n description: \"Launch interactive search with multi-select\",\n default: false,\n }),\n category: Flags.string({\n char: \"c\",\n description: \"Filter by category\",\n required: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote sources\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Search);\n const projectDir = process.cwd();\n\n const isInteractive = flags.interactive || !args.query;\n\n if (isInteractive) {\n await this.runInteractive(args.query, flags.refresh, projectDir);\n } else {\n await this.runStatic(args.query!, flags);\n }\n }\n\n private async runInteractive(\n initialQuery: string | undefined,\n forceRefresh: boolean,\n projectDir: string,\n ): Promise<void> {\n this.log(\"Loading skills from all sources...\");\n\n try {\n const { sourceResult } = await loadSource({\n sourceFlag: undefined,\n projectDir,\n forceRefresh,\n });\n const { matrix, sourcePath } = sourceResult;\n\n const primarySkills = Object.values(matrix.skills)\n .filter((skill): skill is ResolvedSkill => skill !== undefined)\n .map((skill) => toSourcedSkill(skill, \"marketplace\", sourcePath));\n\n const { extras } = await resolveAllSources(projectDir);\n\n const extraSkillArrays = await Promise.all(\n extras.map((source) => fetchSkillsFromExternalSource(source, forceRefresh)),\n );\n\n const allSkills: SourcedSkill[] = [...primarySkills, ...extraSkillArrays.flat()];\n const sourceCount = 1 + extras.length;\n\n this.log(`Loaded ${allSkills.length} skills from ${sourceCount} source(s)`);\n this.log(\"\");\n\n const searchResultPromise = new Promise<SkillSearchResult>((resolve) => {\n const { waitUntilExit } = render(\n <SkillSearch\n skills={allSkills}\n sourceCount={sourceCount}\n initialQuery={initialQuery}\n onComplete={(result) => {\n resolve(result);\n }}\n onCancel={() => {\n resolve({ selectedSkills: [], cancelled: true });\n }}\n />,\n );\n\n waitUntilExit().then(() => {\n resolve({ selectedSkills: [], cancelled: true });\n });\n });\n\n const searchResult = await searchResultPromise;\n\n if (searchResult.cancelled) {\n this.log(\"Search cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n if (searchResult.selectedSkills.length === 0) {\n this.log(\"No skills selected\");\n return;\n }\n\n this.log(\"\");\n this.log(`Importing ${searchResult.selectedSkills.length} skill(s)...`);\n\n const copyResults = await copySearchedSkillsToLocal(searchResult.selectedSkills, projectDir);\n\n for (const result of copyResults) {\n if (result.copied) {\n this.logSuccess(`Imported: ${result.id}`);\n } else {\n this.warn(`Skipping ${result.id}: ${result.reason}`);\n }\n }\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.IMPORT_COMPLETE);\n this.log(`Skills location: ${destDir}`);\n this.log(INFO_MESSAGES.RUN_COMPILE);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async runStatic(\n query: string,\n flags: { source?: string; category?: string },\n ): Promise<void> {\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const { sourceResult } = await loadSource({\n sourceFlag: flags.source,\n projectDir: process.cwd(),\n });\n const { matrix, sourcePath, isLocal } = sourceResult;\n\n this.log(`Loaded from ${isLocal ? \"local\" : \"remote\"}: ${sourcePath}`);\n\n const allSkills = Object.values(matrix.skills).filter(\n (skill): skill is ResolvedSkill => skill !== undefined,\n );\n\n const results = sortBy(\n filterSkillsByQuery(allSkills, { query, category: flags.category }),\n (r) => r.displayName.toLowerCase(),\n );\n\n this.log(\"\");\n if (results.length === 0) {\n this.warn(`No skills found matching \"${query}\"`);\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n } else {\n this.logInfo(\n `Found ${results.length} skill${results.length === 1 ? \"\" : \"s\"} matching \"${query}\"`,\n );\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n this.log(\"\");\n\n printTable({\n data: results.map((skill) => ({\n id: skill.displayName,\n category: skill.category,\n description: truncateText(skill.description, MAX_DESCRIPTION_WIDTH),\n })),\n columns: [\n { key: \"id\", name: \"ID\" },\n { key: \"category\", name: \"Category\" },\n { key: \"description\", name: \"Description\" },\n ],\n headerOptions: { bold: true },\n });\n }\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n","export { SkillSearch, type SkillSearchResult } from \"./skill-search.js\";\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/search.tsx","../../src/cli/components/skill-search/index.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport { render } from \"ink\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport {\n SkillSearch,\n type SkillSearchResult,\n type SourcedSkill,\n} from \"../components/skill-search/index.js\";\nimport { DEFAULT_SKILLS_SUBDIR, LOCAL_SKILLS_PATH, STANDARD_FILES } from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { resolveAllSources } from \"../lib/configuration/index.js\";\nimport { loadSource } from \"../lib/operations/index.js\";\nimport { fetchFromSource, parseFrontmatter } from \"../lib/loading/index.js\";\nimport type { SourceEntry } from \"../types/config.js\";\nimport type { CategoryPath, ResolvedSkill, SkillSlug } from \"../types/index.js\";\nimport { copy, ensureDir, fileExists, listDirectories, readFile } from \"../utils/fs.js\";\nimport { SUCCESS_MESSAGES, STATUS_MESSAGES, INFO_MESSAGES } from \"../utils/messages.js\";\nimport { truncateText } from \"../utils/string.js\";\n\nconst MAX_DESCRIPTION_WIDTH = 50;\n\nexport default class Search extends BaseCommand {\n static summary = \"Search available skills\";\n static description =\n \"Search skills by ID, alias, description, or category. \" +\n \"Run without arguments or with -i for interactive mode with multi-select.\";\n\n static examples = [\n {\n description: \"Search for React skills\",\n command: \"<%= config.bin %> search react\",\n },\n {\n description: \"Interactive search mode\",\n command: \"<%= config.bin %> search\",\n },\n {\n description: \"Interactive with pre-filled query\",\n command: \"<%= config.bin %> search -i react\",\n },\n {\n description: \"Search with category filter\",\n command: \"<%= config.bin %> search state -c frontend\",\n },\n ];\n\n static args = {\n query: Args.string({\n description: \"Search query (matches name, description, category)\",\n required: false,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n interactive: Flags.boolean({\n char: \"i\",\n description: \"Launch interactive search with multi-select\",\n default: false,\n }),\n category: Flags.string({\n char: \"c\",\n description: \"Filter by category\",\n required: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote sources\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Search);\n const projectDir = process.cwd();\n\n const isInteractive = flags.interactive || !args.query;\n\n if (isInteractive) {\n await this.runInteractive(args.query, flags.refresh, projectDir);\n } else {\n await this.runStatic(args.query!, flags);\n }\n }\n\n private async runInteractive(\n initialQuery: string | undefined,\n forceRefresh: boolean,\n projectDir: string,\n ): Promise<void> {\n try {\n const { allSkills, sourceCount } = await this.loadAllSourceSkills(forceRefresh, projectDir);\n const searchResult = await this.showSearchUI(allSkills, sourceCount, initialQuery);\n\n if (searchResult.cancelled) {\n this.log(\"Search cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n if (searchResult.selectedSkills.length === 0) {\n this.log(\"No skills selected\");\n return;\n }\n\n await this.importSelectedSkills(searchResult.selectedSkills, projectDir);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async loadAllSourceSkills(\n forceRefresh: boolean,\n projectDir: string,\n ): Promise<{ allSkills: SourcedSkill[]; sourceCount: number }> {\n this.log(\"Loading skills from all sources...\");\n\n const { sourceResult } = await loadSource({\n sourceFlag: undefined,\n projectDir,\n forceRefresh,\n });\n const { matrix, sourcePath } = sourceResult;\n\n const primarySkills = Object.values(matrix.skills)\n .filter((skill): skill is ResolvedSkill => skill !== undefined)\n .map((skill) => toSourcedSkill(skill, \"marketplace\", sourcePath));\n\n const { extras } = await resolveAllSources(projectDir);\n\n const extraSkillArrays = await Promise.all(\n extras.map((source) => fetchSkillsFromExternalSource(source, forceRefresh)),\n );\n\n const allSkills: SourcedSkill[] = [...primarySkills, ...extraSkillArrays.flat()];\n const sourceCount = 1 + extras.length;\n\n this.log(`Loaded ${allSkills.length} skills from ${sourceCount} source(s)`);\n this.log(\"\");\n\n return { allSkills, sourceCount };\n }\n\n private async showSearchUI(\n allSkills: SourcedSkill[],\n sourceCount: number,\n initialQuery: string | undefined,\n ): Promise<SkillSearchResult> {\n const searchResultPromise = new Promise<SkillSearchResult>((resolve) => {\n const { waitUntilExit } = render(\n <SkillSearch\n skills={allSkills}\n sourceCount={sourceCount}\n initialQuery={initialQuery}\n onComplete={(result) => {\n resolve(result);\n }}\n onCancel={() => {\n resolve({ selectedSkills: [], cancelled: true });\n }}\n />,\n );\n\n waitUntilExit().then(() => {\n resolve({ selectedSkills: [], cancelled: true });\n });\n });\n\n return searchResultPromise;\n }\n\n private async importSelectedSkills(skills: SourcedSkill[], projectDir: string): Promise<void> {\n this.log(\"\");\n this.log(`Importing ${skills.length} skill(s)...`);\n\n const copyResults = await copySearchedSkillsToLocal(skills, projectDir);\n\n for (const result of copyResults) {\n if (result.copied) {\n this.logSuccess(`Imported: ${result.id}`);\n } else {\n this.warn(`Skipping ${result.id}: ${result.reason}`);\n }\n }\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.IMPORT_COMPLETE);\n this.log(`Skills location: ${destDir}`);\n this.log(INFO_MESSAGES.RUN_COMPILE);\n }\n\n private async runStatic(\n query: string,\n flags: { source?: string; category?: string },\n ): Promise<void> {\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const { sourceResult } = await loadSource({\n sourceFlag: flags.source,\n projectDir: process.cwd(),\n });\n const { matrix, sourcePath, isLocal } = sourceResult;\n\n this.log(`Loaded from ${isLocal ? \"local\" : \"remote\"}: ${sourcePath}`);\n\n const allSkills = Object.values(matrix.skills).filter(\n (skill): skill is ResolvedSkill => skill !== undefined,\n );\n\n const results = sortBy(\n filterSkillsByQuery(allSkills, { query, category: flags.category }),\n (r) => r.displayName.toLowerCase(),\n );\n\n this.log(\"\");\n if (results.length === 0) {\n this.warn(`No skills found matching \"${query}\"`);\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n } else {\n this.logInfo(\n `Found ${results.length} skill${results.length === 1 ? \"\" : \"s\"} matching \"${query}\"`,\n );\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n this.log(\"\");\n\n printTable({\n data: results.map((skill) => ({\n id: skill.displayName,\n category: skill.category,\n description: truncateText(skill.description, MAX_DESCRIPTION_WIDTH),\n })),\n columns: [\n { key: \"id\", name: \"ID\" },\n { key: \"category\", name: \"Category\" },\n { key: \"description\", name: \"Description\" },\n ],\n headerOptions: { bold: true },\n });\n }\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n\ntype FilterSkillsOptions = {\n query: string;\n category?: string;\n};\n\ntype CopySearchedSkillResult = {\n id: string;\n copied: boolean;\n /** Reason when `copied` is false */\n reason?: string;\n};\n\nasync function fetchSkillsFromExternalSource(\n source: SourceEntry,\n forceRefresh: boolean,\n): Promise<SourcedSkill[]> {\n try {\n const result = await fetchFromSource(source.url, { forceRefresh });\n const skillsDir = path.join(result.path, DEFAULT_SKILLS_SUBDIR);\n\n if (!(await fileExists(skillsDir))) {\n return [];\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const skills: SourcedSkill[] = [];\n\n for (const skillDir of skillDirs) {\n const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);\n if (!(await fileExists(skillMdPath))) continue;\n\n const content = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(content, skillMdPath);\n if (!frontmatter) continue;\n\n skills.push({\n id: frontmatter.name,\n description: frontmatter.description,\n // Boundary cast: directory name used as slug for third-party source skill\n slug: skillDir as SkillSlug,\n displayName: skillDir,\n // Boundary cast: external source skills have no real category; \"imported\" is a display-only placeholder\n category: \"imported\" as CategoryPath,\n author: `@${source.name}`,\n conflictsWith: [],\n isRecommended: false,\n requires: [],\n alternatives: [],\n discourages: [],\n compatibleWith: [],\n sourceName: source.name,\n sourceUrl: source.url,\n path: path.join(skillsDir, skillDir),\n });\n }\n\n return skills;\n } catch {\n // Source unavailable, return empty\n return [];\n }\n}\n\nfunction matchesQuery(skill: ResolvedSkill, query: string): boolean {\n const lowerQuery = query.toLowerCase();\n\n if (skill.id.toLowerCase().includes(lowerQuery)) return true;\n if (skill.displayName.toLowerCase().includes(lowerQuery)) return true;\n if (skill.slug.toLowerCase().includes(lowerQuery)) return true;\n if (skill.description.toLowerCase().includes(lowerQuery)) return true;\n if (skill.category.toLowerCase().includes(lowerQuery)) return true;\n\n return false;\n}\n\nfunction matchesCategory(skill: ResolvedSkill, category: string): boolean {\n const lowerCategory = category.toLowerCase();\n return skill.category.toLowerCase().includes(lowerCategory);\n}\n\nfunction filterSkillsByQuery(\n skills: ResolvedSkill[],\n options: FilterSkillsOptions,\n): ResolvedSkill[] {\n let results = skills.filter((skill) => matchesQuery(skill, options.query));\n\n if (options.category) {\n results = results.filter((skill) => matchesCategory(skill, options.category!));\n }\n\n return results;\n}\n\nfunction toSourcedSkill(\n skill: ResolvedSkill,\n sourceName: string,\n sourceUrl?: string,\n): SourcedSkill {\n return {\n ...skill,\n sourceName,\n sourceUrl,\n };\n}\n\nasync function copySearchedSkillsToLocal(\n skills: SourcedSkill[],\n projectDir: string,\n): Promise<CopySearchedSkillResult[]> {\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n const results: CopySearchedSkillResult[] = [];\n\n for (const skill of skills) {\n if (skill.path) {\n const destPath = path.join(destDir, skill.id);\n await ensureDir(path.dirname(destPath));\n await copy(skill.path, destPath);\n results.push({ id: skill.id, copied: true });\n } else {\n results.push({ id: skill.id, copied: false, reason: \"No source path available\" });\n }\n }\n\n return results;\n}\n","export { SkillSearch, type SkillSearchResult, type SourcedSkill } from \"./skill-search.js\";\n"],"mappings":"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","names":[]}