@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.
- package/CHANGELOG.md +10 -0
- package/dist/chunk-5UJJQFET.js +564 -0
- package/dist/chunk-5UJJQFET.js.map +1 -0
- package/dist/{chunk-GED2F75H.js → chunk-7FFNNDJQ.js} +176 -120
- package/dist/chunk-7FFNNDJQ.js.map +1 -0
- package/dist/{chunk-BV2MIQ3O.js → chunk-I5AZKNNL.js} +1 -1
- package/dist/chunk-I5AZKNNL.js.map +1 -0
- package/dist/chunk-J6PI73YV.js +68 -0
- package/dist/chunk-J6PI73YV.js.map +1 -0
- package/dist/commands/compile.js +26 -20
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/diff.js +681 -82
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +30 -58
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +164 -32
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +177 -27
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +197 -33
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +41 -34
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +3 -6
- package/dist/commands/new/agent.js +140 -44
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/marketplace.js +4 -4
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/new/skill.js +194 -30
- package/dist/commands/new/skill.js.map +1 -1
- package/dist/commands/outdated.js +1 -3
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/search.js +162 -65
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +259 -62
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +232 -163
- package/dist/commands/update.js.map +1 -1
- package/dist/components/skill-search/skill-search.js +1 -1
- package/dist/hooks/init.js +2 -4
- package/dist/hooks/init.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-BV2MIQ3O.js.map +0 -1
- package/dist/chunk-DCVCFBQ7.js +0 -1800
- package/dist/chunk-DCVCFBQ7.js.map +0 -1
- package/dist/chunk-GED2F75H.js.map +0 -1
- package/dist/chunk-O5ZWS26C.js +0 -166
- package/dist/chunk-O5ZWS26C.js.map +0 -1
- package/dist/chunk-XQK4S22C.js +0 -202
- package/dist/chunk-XQK4S22C.js.map +0 -1
package/dist/commands/search.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SkillSearch
|
|
4
|
-
} from "../chunk-
|
|
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
|
-
|
|
15
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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 {
|
|
117
|
-
|
|
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.
|
|
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":[]}
|