@agents-inc/cli 0.85.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 (121) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/{chunk-6VGBO6SZ.js → chunk-5M6Q5UQO.js} +2 -2
  3. package/dist/chunk-5UJJQFET.js +564 -0
  4. package/dist/chunk-5UJJQFET.js.map +1 -0
  5. package/dist/{chunk-TXW257CU.js → chunk-7FFNNDJQ.js} +181 -202
  6. package/dist/chunk-7FFNNDJQ.js.map +1 -0
  7. package/dist/{chunk-YJ2URWF7.js → chunk-B6MYECV6.js} +2 -2
  8. package/dist/{chunk-G2MINRWX.js → chunk-C5IYJ42F.js} +2 -2
  9. package/dist/{chunk-7UZUDHP7.js → chunk-CXWBVBDM.js} +2 -2
  10. package/dist/{chunk-CYPCJ536.js → chunk-FBZR46GC.js} +92 -92
  11. package/dist/chunk-FBZR46GC.js.map +1 -0
  12. package/dist/{chunk-LTFGEVTM.js → chunk-HH3AWXF4.js} +3 -3
  13. package/dist/{chunk-2XVLQDNI.js → chunk-HSLVCKVQ.js} +3 -3
  14. package/dist/{chunk-TAQGYJIS.js → chunk-HZ2IBXVQ.js} +3 -3
  15. package/dist/{chunk-LN76TJJP.js → chunk-HZQOFFKA.js} +10 -10
  16. package/dist/{chunk-W7LHI54P.js → chunk-I44YG6VI.js} +2 -2
  17. package/dist/{chunk-FT46LN7K.js → chunk-I5AZKNNL.js} +7 -8
  18. package/dist/chunk-I5AZKNNL.js.map +1 -0
  19. package/dist/chunk-J6PI73YV.js +68 -0
  20. package/dist/chunk-J6PI73YV.js.map +1 -0
  21. package/dist/{chunk-L7COG2EX.js → chunk-LZ7XQ3IU.js} +2 -2
  22. package/dist/{chunk-LMR7VAP3.js → chunk-MMTMXLI4.js} +2 -2
  23. package/dist/chunk-N6A7A4RA.js +16 -0
  24. package/dist/chunk-N6A7A4RA.js.map +1 -0
  25. package/dist/{chunk-WJKD6EGK.js → chunk-NUU3U43A.js} +5 -6
  26. package/dist/chunk-NUU3U43A.js.map +1 -0
  27. package/dist/{chunk-YYIWB42G.js → chunk-Q4DMIPZB.js} +2 -2
  28. package/dist/{chunk-YSLDMYWP.js → chunk-SGZOFIFF.js} +2 -2
  29. package/dist/{chunk-FKXD3EXJ.js → chunk-TMTUTUEV.js} +42 -228
  30. package/dist/chunk-TMTUTUEV.js.map +1 -0
  31. package/dist/{chunk-WCCWQ56J.js → chunk-UNEJKTLP.js} +3 -3
  32. package/dist/{chunk-ZGD7PLLC.js → chunk-ZOWRO7UQ.js} +3 -3
  33. package/dist/commands/build/marketplace.js +3 -3
  34. package/dist/commands/build/plugins.js +5 -5
  35. package/dist/commands/build/stack.js +5 -5
  36. package/dist/commands/compile.js +77 -171
  37. package/dist/commands/compile.js.map +1 -1
  38. package/dist/commands/config/index.js +5 -5
  39. package/dist/commands/config/path.js +4 -4
  40. package/dist/commands/config/show.js +5 -5
  41. package/dist/commands/diff.js +161 -167
  42. package/dist/commands/diff.js.map +1 -1
  43. package/dist/commands/doctor.js +68 -83
  44. package/dist/commands/doctor.js.map +1 -1
  45. package/dist/commands/edit.js +275 -209
  46. package/dist/commands/edit.js.map +1 -1
  47. package/dist/commands/eject.js +206 -124
  48. package/dist/commands/eject.js.map +1 -1
  49. package/dist/commands/import/skill.js +175 -144
  50. package/dist/commands/import/skill.js.map +1 -1
  51. package/dist/commands/info.js +58 -102
  52. package/dist/commands/info.js.map +1 -1
  53. package/dist/commands/init.js +19 -16
  54. package/dist/commands/list.js +4 -4
  55. package/dist/commands/new/agent.js +124 -102
  56. package/dist/commands/new/agent.js.map +1 -1
  57. package/dist/commands/new/marketplace.js +6 -6
  58. package/dist/commands/new/marketplace.js.map +1 -1
  59. package/dist/commands/new/skill.js +328 -15
  60. package/dist/commands/new/skill.js.map +1 -1
  61. package/dist/commands/outdated.js +16 -24
  62. package/dist/commands/outdated.js.map +1 -1
  63. package/dist/commands/search.js +166 -132
  64. package/dist/commands/search.js.map +1 -1
  65. package/dist/commands/uninstall.js +269 -189
  66. package/dist/commands/uninstall.js.map +1 -1
  67. package/dist/commands/update.js +238 -219
  68. package/dist/commands/update.js.map +1 -1
  69. package/dist/commands/validate.js +4 -4
  70. package/dist/components/skill-search/skill-search.js +2 -1
  71. package/dist/components/wizard/category-grid.test.js +4 -4
  72. package/dist/components/wizard/domain-selection.js +5 -5
  73. package/dist/components/wizard/help-modal.js +5 -5
  74. package/dist/components/wizard/source-grid.test.js +4 -4
  75. package/dist/components/wizard/stack-selection.js +5 -5
  76. package/dist/components/wizard/step-agents.js +5 -5
  77. package/dist/components/wizard/step-agents.test.js +5 -5
  78. package/dist/components/wizard/step-build.js +5 -5
  79. package/dist/components/wizard/step-build.test.js +5 -5
  80. package/dist/components/wizard/step-confirm.test.js +4 -4
  81. package/dist/components/wizard/step-settings.js +4 -4
  82. package/dist/components/wizard/step-settings.test.js +7 -7
  83. package/dist/components/wizard/step-sources.js +5 -5
  84. package/dist/components/wizard/step-sources.test.js +5 -5
  85. package/dist/components/wizard/step-stack.js +6 -6
  86. package/dist/components/wizard/step-stack.test.js +6 -6
  87. package/dist/components/wizard/wizard-layout.js +6 -6
  88. package/dist/components/wizard/wizard.js +14 -14
  89. package/dist/hooks/init.js +19 -16
  90. package/dist/hooks/init.js.map +1 -1
  91. package/dist/{loader-GT2A7R7U.js → loader-GSEGPK64.js} +3 -3
  92. package/dist/{source-loader-TNQW4P47.js → source-loader-OGFTIRIX.js} +4 -4
  93. package/dist/{source-manager-INRXRFJE.js → source-manager-FMMDDVZA.js} +4 -4
  94. package/dist/stores/wizard-store.js +4 -4
  95. package/dist/stores/wizard-store.test.js +4 -4
  96. package/package.json +1 -1
  97. package/dist/chunk-AABH2HSE.js +0 -340
  98. package/dist/chunk-AABH2HSE.js.map +0 -1
  99. package/dist/chunk-CYPCJ536.js.map +0 -1
  100. package/dist/chunk-FKXD3EXJ.js.map +0 -1
  101. package/dist/chunk-FT46LN7K.js.map +0 -1
  102. package/dist/chunk-TXW257CU.js.map +0 -1
  103. package/dist/chunk-WJKD6EGK.js.map +0 -1
  104. /package/dist/{chunk-6VGBO6SZ.js.map → chunk-5M6Q5UQO.js.map} +0 -0
  105. /package/dist/{chunk-YJ2URWF7.js.map → chunk-B6MYECV6.js.map} +0 -0
  106. /package/dist/{chunk-G2MINRWX.js.map → chunk-C5IYJ42F.js.map} +0 -0
  107. /package/dist/{chunk-7UZUDHP7.js.map → chunk-CXWBVBDM.js.map} +0 -0
  108. /package/dist/{chunk-LTFGEVTM.js.map → chunk-HH3AWXF4.js.map} +0 -0
  109. /package/dist/{chunk-2XVLQDNI.js.map → chunk-HSLVCKVQ.js.map} +0 -0
  110. /package/dist/{chunk-TAQGYJIS.js.map → chunk-HZ2IBXVQ.js.map} +0 -0
  111. /package/dist/{chunk-LN76TJJP.js.map → chunk-HZQOFFKA.js.map} +0 -0
  112. /package/dist/{chunk-W7LHI54P.js.map → chunk-I44YG6VI.js.map} +0 -0
  113. /package/dist/{chunk-L7COG2EX.js.map → chunk-LZ7XQ3IU.js.map} +0 -0
  114. /package/dist/{chunk-LMR7VAP3.js.map → chunk-MMTMXLI4.js.map} +0 -0
  115. /package/dist/{chunk-YYIWB42G.js.map → chunk-Q4DMIPZB.js.map} +0 -0
  116. /package/dist/{chunk-YSLDMYWP.js.map → chunk-SGZOFIFF.js.map} +0 -0
  117. /package/dist/{chunk-WCCWQ56J.js.map → chunk-UNEJKTLP.js.map} +0 -0
  118. /package/dist/{chunk-ZGD7PLLC.js.map → chunk-ZOWRO7UQ.js.map} +0 -0
  119. /package/dist/{loader-GT2A7R7U.js.map → loader-GSEGPK64.js.map} +0 -0
  120. /package/dist/{source-loader-TNQW4P47.js.map → source-loader-OGFTIRIX.js.map} +0 -0
  121. /package/dist/{source-manager-INRXRFJE.js.map → source-manager-FMMDDVZA.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,26 @@ Each release has detailed notes in its own file under [`changelogs/`](./changelo
7
7
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
8
8
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
9
9
 
10
+ ## [0.87.0] - 2026-03-26
11
+
12
+ **Declarative commands, operation dissolution, global skill discovery fix**
13
+
14
+ - 14 commands restructured with declarative two-tier pattern — `run()` reads like pseudocode
15
+ - 12 single-use operations dissolved back into their respective commands; operations layer trimmed to 17 shared files
16
+ - Fix: init/edit/update now discover all skills (global + project) before compiling agents
17
+
18
+ See [changelogs/0.87.0.md](./changelogs/0.87.0.md) for full details.
19
+
20
+ ## [0.86.0] - 2026-03-26
21
+
22
+ **Operations layer — composable building blocks for all CLI commands**
23
+
24
+ - 26 typed operations extracted from 15 commands into `src/cli/lib/operations/` (D-145)
25
+ - All commands refactored to use operations layer; compile.ts reduced 40%, uninstall.tsx 39%, import/skill.ts 47%
26
+ - Shared utilities: `truncateText()`, `warn({ suppressInTest })`, `buildSourceSkillsMap()`
27
+
28
+ See [changelogs/0.86.0.md](./changelogs/0.86.0.md) for full details.
29
+
10
30
  ## [0.85.0] - 2026-03-25
11
31
 
12
32
  **Exclusive incompatibility markers, filter deselection, declarative test data**
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-4QA5TIBU.js";
8
8
  import {
9
9
  useWizardStore
10
- } from "./chunk-2XVLQDNI.js";
10
+ } from "./chunk-HSLVCKVQ.js";
11
11
  import {
12
12
  matrix
13
13
  } from "./chunk-ANXHMG32.js";
@@ -191,4 +191,4 @@ var StackSelection = ({ onCancel }) => {
191
191
  export {
192
192
  StackSelection
193
193
  };
194
- //# sourceMappingURL=chunk-6VGBO6SZ.js.map
194
+ //# sourceMappingURL=chunk-5M6Q5UQO.js.map
@@ -0,0 +1,564 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ truncateText
4
+ } from "./chunk-N6A7A4RA.js";
5
+ import {
6
+ getAgentDefinitions,
7
+ recompileAgents
8
+ } from "./chunk-FBZR46GC.js";
9
+ import {
10
+ buildAgentScopeMap,
11
+ buildAndMergeConfig,
12
+ claudePluginInstall,
13
+ claudePluginMarketplaceAdd,
14
+ claudePluginMarketplaceExists,
15
+ claudePluginMarketplaceUpdate,
16
+ claudePluginUninstall,
17
+ compareLocalSkillsWithSource,
18
+ copySkillsToLocalFlattened,
19
+ detectGlobalInstallation,
20
+ detectInstallation,
21
+ detectProjectInstallation,
22
+ discoverAllPluginSkills,
23
+ discoverLocalSkills,
24
+ ensureBlankGlobalConfig,
25
+ fetchMarketplace,
26
+ loadProjectConfig,
27
+ loadProjectConfigFromDir,
28
+ loadSkillsMatrixFromSource,
29
+ resolveInstallPaths,
30
+ writeScopedConfigs
31
+ } from "./chunk-TMTUTUEV.js";
32
+ import {
33
+ loadAllAgents,
34
+ parseFrontmatter
35
+ } from "./chunk-B6MYECV6.js";
36
+ import {
37
+ typedEntries,
38
+ typedKeys
39
+ } from "./chunk-ANXHMG32.js";
40
+ import {
41
+ directoryExists,
42
+ disableBuffering,
43
+ drainBuffer,
44
+ enableBuffering,
45
+ ensureDir,
46
+ fileExists,
47
+ getErrorMessage,
48
+ glob,
49
+ listDirectories,
50
+ readFile,
51
+ verbose,
52
+ warn
53
+ } from "./chunk-NUU3U43A.js";
54
+ import {
55
+ GLOBAL_INSTALL_ROOT,
56
+ LOCAL_SKILLS_PATH,
57
+ PROJECT_ROOT,
58
+ STANDARD_FILES
59
+ } from "./chunk-6PGL2XMY.js";
60
+ import {
61
+ init_esm_shims
62
+ } from "./chunk-DHET7RCE.js";
63
+
64
+ // src/cli/lib/operations/detect-both-installations.ts
65
+ init_esm_shims();
66
+ import os from "os";
67
+ async function detectBothInstallations(projectDir) {
68
+ const global = await detectGlobalInstallation();
69
+ const project = projectDir === os.homedir() ? null : await detectProjectInstallation(projectDir);
70
+ return { global, project, hasBoth: !!global && !!project };
71
+ }
72
+
73
+ // src/cli/lib/operations/load-source.ts
74
+ init_esm_shims();
75
+ async function loadSource(options) {
76
+ const { sourceFlag, projectDir, forceRefresh, captureStartupMessages } = options;
77
+ if (captureStartupMessages) {
78
+ enableBuffering();
79
+ }
80
+ let sourceResult;
81
+ try {
82
+ sourceResult = await loadSkillsMatrixFromSource({
83
+ sourceFlag,
84
+ projectDir,
85
+ forceRefresh
86
+ });
87
+ } catch (error) {
88
+ if (captureStartupMessages) {
89
+ disableBuffering();
90
+ }
91
+ throw error;
92
+ }
93
+ let startupMessages = [];
94
+ if (captureStartupMessages) {
95
+ startupMessages = drainBuffer();
96
+ disableBuffering();
97
+ }
98
+ return { sourceResult, startupMessages };
99
+ }
100
+
101
+ // src/cli/lib/operations/detect-project.ts
102
+ init_esm_shims();
103
+ async function detectProject(projectDir) {
104
+ const resolvedDir = projectDir ?? process.cwd();
105
+ const installation = await detectInstallation(resolvedDir);
106
+ if (!installation) {
107
+ return null;
108
+ }
109
+ const loaded = await loadProjectConfig(installation.projectDir);
110
+ return {
111
+ installation,
112
+ config: loaded?.config ?? null,
113
+ configPath: loaded?.configPath ?? null
114
+ };
115
+ }
116
+
117
+ // src/cli/lib/operations/load-agent-defs.ts
118
+ init_esm_shims();
119
+ async function loadAgentDefs(agentSource, options) {
120
+ const agentSourcePaths = await getAgentDefinitions(agentSource, options);
121
+ const cliAgents = await loadAllAgents(PROJECT_ROOT);
122
+ const sourceAgents = await loadAllAgents(agentSourcePaths.sourcePath);
123
+ const agents = { ...cliAgents, ...sourceAgents };
124
+ return {
125
+ agents,
126
+ sourcePath: agentSourcePaths.sourcePath,
127
+ agentSourcePaths
128
+ };
129
+ }
130
+
131
+ // src/cli/lib/operations/copy-local-skills.ts
132
+ init_esm_shims();
133
+ async function copyLocalSkills(skills, projectDir, sourceResult) {
134
+ const projectLocalSkills = skills.filter((s) => s.scope !== "global");
135
+ const globalLocalSkills = skills.filter((s) => s.scope === "global");
136
+ const projectPaths = resolveInstallPaths(projectDir, "project");
137
+ const globalPaths = resolveInstallPaths(projectDir, "global");
138
+ let projectCopied = [];
139
+ if (projectLocalSkills.length > 0) {
140
+ await ensureDir(projectPaths.skillsDir);
141
+ projectCopied = await copySkillsToLocalFlattened(
142
+ projectLocalSkills.map((s) => s.id),
143
+ projectPaths.skillsDir,
144
+ sourceResult.matrix,
145
+ sourceResult
146
+ );
147
+ }
148
+ let globalCopied = [];
149
+ if (globalLocalSkills.length > 0) {
150
+ await ensureDir(globalPaths.skillsDir);
151
+ globalCopied = await copySkillsToLocalFlattened(
152
+ globalLocalSkills.map((s) => s.id),
153
+ globalPaths.skillsDir,
154
+ sourceResult.matrix,
155
+ sourceResult
156
+ );
157
+ }
158
+ return {
159
+ projectCopied,
160
+ globalCopied,
161
+ totalCopied: projectCopied.length + globalCopied.length
162
+ };
163
+ }
164
+
165
+ // src/cli/lib/operations/install-plugin-skills.ts
166
+ init_esm_shims();
167
+ async function installPluginSkills(skills, marketplace, projectDir) {
168
+ const pluginSkills = skills.filter((s) => s.source !== "local");
169
+ const installed = [];
170
+ const failed = [];
171
+ for (const skill of pluginSkills) {
172
+ const pluginRef = `${skill.id}@${marketplace}`;
173
+ const pluginScope = skill.scope === "global" ? "user" : "project";
174
+ try {
175
+ await claudePluginInstall(pluginRef, pluginScope, projectDir);
176
+ installed.push({ id: skill.id, ref: pluginRef });
177
+ } catch (error) {
178
+ failed.push({ id: skill.id, error: getErrorMessage(error) });
179
+ }
180
+ }
181
+ return { installed, failed };
182
+ }
183
+
184
+ // src/cli/lib/operations/uninstall-plugin-skills.ts
185
+ init_esm_shims();
186
+ async function uninstallPluginSkills(skillIds, oldSkills, projectDir) {
187
+ const uninstalled = [];
188
+ const failed = [];
189
+ for (const skillId of skillIds) {
190
+ const oldSkill = oldSkills.find((s) => s.id === skillId);
191
+ const pluginScope = oldSkill?.scope === "global" ? "user" : "project";
192
+ try {
193
+ await claudePluginUninstall(skillId, pluginScope, projectDir);
194
+ uninstalled.push(skillId);
195
+ } catch (error) {
196
+ failed.push({ id: skillId, error: getErrorMessage(error) });
197
+ }
198
+ }
199
+ return { uninstalled, failed };
200
+ }
201
+
202
+ // src/cli/lib/operations/collect-scoped-skill-dirs.ts
203
+ init_esm_shims();
204
+ import os2 from "os";
205
+ import path from "path";
206
+ async function collectScopedSkillDirs(projectDir) {
207
+ const homeDir = os2.homedir();
208
+ const projectLocalPath = path.join(projectDir, LOCAL_SKILLS_PATH);
209
+ const globalLocalPath = path.join(homeDir, LOCAL_SKILLS_PATH);
210
+ const hasProject = await fileExists(projectLocalPath);
211
+ const hasGlobal = projectDir !== homeDir && await fileExists(globalLocalPath);
212
+ const dirs = [];
213
+ if (hasProject) {
214
+ for (const dirName of await listDirectories(projectLocalPath)) {
215
+ dirs.push({ dirName, localSkillsPath: projectLocalPath, scope: "project" });
216
+ }
217
+ }
218
+ if (hasGlobal) {
219
+ const projectDirNames = new Set(dirs.map((d) => d.dirName));
220
+ for (const dirName of await listDirectories(globalLocalPath)) {
221
+ if (!projectDirNames.has(dirName)) {
222
+ dirs.push({ dirName, localSkillsPath: globalLocalPath, scope: "global" });
223
+ }
224
+ }
225
+ }
226
+ return { dirs, hasProject, hasGlobal, projectLocalPath, globalLocalPath };
227
+ }
228
+
229
+ // src/cli/lib/operations/compare-skills.ts
230
+ init_esm_shims();
231
+ import os3 from "os";
232
+ function buildSourceSkillsMap(matrix) {
233
+ const sourceSkills = {};
234
+ for (const [skillId, skill] of typedEntries(matrix.skills)) {
235
+ if (!skill) continue;
236
+ if (!skill.local) {
237
+ sourceSkills[skillId] = { path: skill.path };
238
+ }
239
+ }
240
+ return sourceSkills;
241
+ }
242
+ async function compareSkillsWithSource(projectDir, sourcePath, matrix) {
243
+ const sourceSkills = buildSourceSkillsMap(matrix);
244
+ const { hasProject, hasGlobal } = await collectScopedSkillDirs(projectDir);
245
+ const homeDir = os3.homedir();
246
+ const projectResults = hasProject ? await compareLocalSkillsWithSource(projectDir, sourcePath, sourceSkills) : [];
247
+ const globalResults = hasGlobal ? await compareLocalSkillsWithSource(homeDir, sourcePath, sourceSkills) : [];
248
+ const seenIds = new Set(projectResults.map((r) => r.id));
249
+ const merged = [...projectResults, ...globalResults.filter((r) => !seenIds.has(r.id))];
250
+ return { projectResults, globalResults, merged };
251
+ }
252
+
253
+ // src/cli/lib/operations/ensure-marketplace.ts
254
+ init_esm_shims();
255
+ async function ensureMarketplace(sourceResult) {
256
+ if (!sourceResult.marketplace) {
257
+ try {
258
+ const marketplaceResult = await fetchMarketplace(sourceResult.sourceConfig.source, {});
259
+ sourceResult.marketplace = marketplaceResult.marketplace.name;
260
+ } catch {
261
+ return { marketplace: null, registered: false };
262
+ }
263
+ }
264
+ const marketplace = sourceResult.marketplace;
265
+ const exists = await claudePluginMarketplaceExists(marketplace);
266
+ if (!exists) {
267
+ const marketplaceSource = sourceResult.sourceConfig.source.replace(/^github:/, "");
268
+ await claudePluginMarketplaceAdd(marketplaceSource);
269
+ return { marketplace, registered: true };
270
+ }
271
+ try {
272
+ await claudePluginMarketplaceUpdate(marketplace);
273
+ } catch {
274
+ warn("Could not update marketplace \u2014 continuing with cached version");
275
+ }
276
+ return { marketplace, registered: false };
277
+ }
278
+
279
+ // src/cli/lib/operations/write-project-config.ts
280
+ init_esm_shims();
281
+ import fs from "fs";
282
+ import os4 from "os";
283
+ import path2 from "path";
284
+ async function writeProjectConfig(options) {
285
+ const { wizardResult, sourceResult, projectDir, sourceFlag } = options;
286
+ const projectPaths = resolveInstallPaths(projectDir, "project");
287
+ await ensureDir(path2.dirname(projectPaths.configPath));
288
+ let agents;
289
+ if (options.agents) {
290
+ agents = options.agents;
291
+ } else {
292
+ const cliAgents = await loadAllAgents(PROJECT_ROOT);
293
+ const sourceAgents = await loadAllAgents(sourceResult.sourcePath);
294
+ agents = { ...cliAgents, ...sourceAgents };
295
+ }
296
+ const mergeResult = await buildAndMergeConfig(wizardResult, sourceResult, projectDir, sourceFlag);
297
+ const finalConfig = mergeResult.config;
298
+ const isProjectContext = fs.realpathSync(projectDir) !== fs.realpathSync(os4.homedir());
299
+ if (isProjectContext) {
300
+ await ensureBlankGlobalConfig();
301
+ }
302
+ await writeScopedConfigs(
303
+ finalConfig,
304
+ sourceResult.matrix,
305
+ agents,
306
+ projectDir,
307
+ projectPaths.configPath,
308
+ isProjectContext
309
+ );
310
+ return {
311
+ config: finalConfig,
312
+ configPath: projectPaths.configPath,
313
+ wasMerged: mergeResult.merged,
314
+ existingConfigPath: mergeResult.existingConfigPath,
315
+ filesWritten: isProjectContext ? 4 : 2
316
+ };
317
+ }
318
+
319
+ // src/cli/lib/operations/compile-agents.ts
320
+ init_esm_shims();
321
+ async function compileAgents(options) {
322
+ let resolvedAgents = options.agents;
323
+ let resolvedAgentScopeMap = options.agentScopeMap;
324
+ if (options.scopeFilter) {
325
+ const loadedConfig = await loadProjectConfigFromDir(options.projectDir);
326
+ if (!resolvedAgentScopeMap && loadedConfig?.config) {
327
+ resolvedAgentScopeMap = buildAgentScopeMap(loadedConfig.config);
328
+ }
329
+ const filteredAgents = loadedConfig?.config?.agents?.filter((a) => a.scope === options.scopeFilter).map((a) => a.name);
330
+ if (resolvedAgents && filteredAgents) {
331
+ const filterSet = new Set(filteredAgents);
332
+ resolvedAgents = resolvedAgents.filter((a) => filterSet.has(a));
333
+ } else if (filteredAgents) {
334
+ resolvedAgents = filteredAgents;
335
+ }
336
+ }
337
+ const recompileResult = await recompileAgents({
338
+ pluginDir: options.pluginDir ?? options.projectDir,
339
+ sourcePath: options.sourcePath,
340
+ agents: resolvedAgents,
341
+ skills: options.skills,
342
+ projectDir: options.projectDir,
343
+ outputDir: options.outputDir,
344
+ installMode: options.installMode,
345
+ agentScopeMap: resolvedAgentScopeMap
346
+ });
347
+ return {
348
+ compiled: recompileResult.compiled,
349
+ failed: recompileResult.failed,
350
+ warnings: recompileResult.warnings
351
+ };
352
+ }
353
+
354
+ // src/cli/lib/operations/discover-skills.ts
355
+ init_esm_shims();
356
+ import os5 from "os";
357
+ import path3 from "path";
358
+ async function loadSkillsFromDir(skillsDir, pathPrefix = "") {
359
+ const skills = {};
360
+ if (!await directoryExists(skillsDir)) {
361
+ return skills;
362
+ }
363
+ const skillFiles = await glob("**/SKILL.md", skillsDir);
364
+ for (const skillFile of skillFiles) {
365
+ const skillPath = path3.join(skillsDir, skillFile);
366
+ const skillDir = path3.dirname(skillPath);
367
+ const relativePath = path3.relative(skillsDir, skillDir);
368
+ const skillDirName = path3.basename(skillDir);
369
+ const metadataPath = path3.join(skillDir, STANDARD_FILES.METADATA_YAML);
370
+ if (!await fileExists(metadataPath)) {
371
+ const displayPath = pathPrefix ? `${pathPrefix}/${relativePath}/` : `${relativePath}/`;
372
+ warn(
373
+ `Skill '${skillDirName}' in '${displayPath}' is missing ${STANDARD_FILES.METADATA_YAML} \u2014 skipped. Add ${STANDARD_FILES.METADATA_YAML} to register it with the CLI.`
374
+ );
375
+ continue;
376
+ }
377
+ try {
378
+ const content = await readFile(skillPath);
379
+ const frontmatter = parseFrontmatter(content, skillPath);
380
+ if (!frontmatter?.name) {
381
+ warn(`Skipping skill in '${skillDirName}': missing or invalid frontmatter name`);
382
+ continue;
383
+ }
384
+ const canonicalId = frontmatter.name;
385
+ const skill = {
386
+ id: canonicalId,
387
+ path: pathPrefix ? `${pathPrefix}/${relativePath}/` : `${relativePath}/`,
388
+ description: frontmatter?.description || ""
389
+ };
390
+ skills[canonicalId] = skill;
391
+ verbose(` Loaded skill: ${canonicalId}`);
392
+ } catch (error) {
393
+ verbose(` Failed to load skill: ${skillFile} - ${error}`);
394
+ }
395
+ }
396
+ return skills;
397
+ }
398
+ async function discoverLocalProjectSkills(projectDir) {
399
+ const localSkillsDir = path3.join(projectDir, LOCAL_SKILLS_PATH);
400
+ return loadSkillsFromDir(localSkillsDir, LOCAL_SKILLS_PATH);
401
+ }
402
+ function mergeSkills(...skillSources) {
403
+ const merged = {};
404
+ for (const source of skillSources) {
405
+ for (const [id, skill] of typedEntries(source)) {
406
+ if (skill) {
407
+ merged[id] = skill;
408
+ }
409
+ }
410
+ }
411
+ return merged;
412
+ }
413
+ async function discoverInstalledSkills(projectDir) {
414
+ const isGlobalProject = projectDir === os5.homedir();
415
+ const globalPluginSkills = isGlobalProject ? {} : await discoverAllPluginSkills(os5.homedir());
416
+ const globalPluginSkillCount = typedKeys(globalPluginSkills).length;
417
+ if (globalPluginSkillCount > 0) {
418
+ verbose(` Found ${globalPluginSkillCount} skills from global plugins`);
419
+ }
420
+ const globalLocalSkillsDir = path3.join(GLOBAL_INSTALL_ROOT, LOCAL_SKILLS_PATH);
421
+ const globalLocalSkills = isGlobalProject ? {} : await loadSkillsFromDir(globalLocalSkillsDir, LOCAL_SKILLS_PATH);
422
+ const globalLocalSkillCount = typedKeys(globalLocalSkills).length;
423
+ if (globalLocalSkillCount > 0) {
424
+ verbose(` Found ${globalLocalSkillCount} global local skills from ~/.claude/skills/`);
425
+ }
426
+ const pluginSkills = await discoverAllPluginSkills(projectDir);
427
+ const pluginSkillCount = typedKeys(pluginSkills).length;
428
+ verbose(` Found ${pluginSkillCount} skills from installed plugins`);
429
+ const localSkills = await discoverLocalProjectSkills(projectDir);
430
+ const localSkillCount = typedKeys(localSkills).length;
431
+ verbose(` Found ${localSkillCount} local skills from .claude/skills/`);
432
+ const allSkills = mergeSkills(globalPluginSkills, globalLocalSkills, pluginSkills, localSkills);
433
+ const totalSkillCount = typedKeys(allSkills).length;
434
+ return {
435
+ allSkills,
436
+ totalSkillCount,
437
+ pluginSkillCount: globalPluginSkillCount + pluginSkillCount,
438
+ localSkillCount: globalLocalSkillCount + localSkillCount,
439
+ globalPluginSkillCount,
440
+ globalLocalSkillCount
441
+ };
442
+ }
443
+
444
+ // src/cli/lib/operations/find-skill-match.ts
445
+ init_esm_shims();
446
+ function findSkillMatch(skillName, results) {
447
+ const exact = results.find((r) => r.id === skillName);
448
+ if (exact) return { match: exact, similar: [] };
449
+ const partial = results.find((r) => {
450
+ const nameWithoutAuthor = r.id.replace(/\s*\(@\w+\)$/, "").toLowerCase();
451
+ return nameWithoutAuthor === skillName.toLowerCase();
452
+ });
453
+ if (partial) return { match: partial, similar: [] };
454
+ const byDir = results.find((r) => r.dirName.toLowerCase() === skillName.toLowerCase());
455
+ if (byDir) return { match: byDir, similar: [] };
456
+ const lowered = skillName.toLowerCase();
457
+ const similar = results.filter((r) => {
458
+ const name = r.id.toLowerCase();
459
+ const dir = r.dirName.toLowerCase();
460
+ return name.includes(lowered) || dir.includes(lowered) || lowered.includes(name.split(" ")[0]);
461
+ }).map((r) => r.id).slice(0, 3);
462
+ return { match: null, similar };
463
+ }
464
+
465
+ // src/cli/lib/operations/resolve-skill-info.ts
466
+ init_esm_shims();
467
+ import path4 from "path";
468
+ var CONTENT_PREVIEW_LINES = 10;
469
+ var MAX_LINE_LENGTH = 80;
470
+ var MAX_SUGGESTIONS = 5;
471
+ function stripFrontmatter(content) {
472
+ const lines = content.split("\n");
473
+ let inFrontmatter = false;
474
+ let frontmatterEndIndex = 0;
475
+ for (let i = 0; i < lines.length; i++) {
476
+ const line = lines[i].trim();
477
+ if (line === "---") {
478
+ if (!inFrontmatter) {
479
+ inFrontmatter = true;
480
+ } else {
481
+ frontmatterEndIndex = i + 1;
482
+ break;
483
+ }
484
+ }
485
+ }
486
+ return lines.slice(frontmatterEndIndex).join("\n");
487
+ }
488
+ function getPreviewLines(content, maxLines) {
489
+ const body = stripFrontmatter(content);
490
+ const lines = body.split("\n");
491
+ const result = [];
492
+ for (const line of lines) {
493
+ if (result.length >= maxLines) break;
494
+ if (line.trim() || result.length > 0) {
495
+ result.push(truncateText(line, MAX_LINE_LENGTH));
496
+ }
497
+ }
498
+ return result;
499
+ }
500
+ function findSuggestions(skills, query, maxSuggestions) {
501
+ const lowerQuery = query.toLowerCase();
502
+ const matches = [];
503
+ for (const skill of Object.values(skills)) {
504
+ if (!skill) continue;
505
+ if (matches.length >= maxSuggestions) break;
506
+ if (skill.id.toLowerCase().includes(lowerQuery) || skill.displayName.toLowerCase().includes(lowerQuery) || skill.slug.toLowerCase().includes(lowerQuery)) {
507
+ matches.push(skill.id);
508
+ }
509
+ }
510
+ return matches;
511
+ }
512
+ async function resolveSkillInfo(options) {
513
+ const { query, skills, slugToId, projectDir, sourcePath, isLocal, includePreview } = options;
514
+ const slugResolvedId = slugToId[query];
515
+ const skill = skills[query] ?? (slugResolvedId ? skills[slugResolvedId] : void 0);
516
+ if (!skill) {
517
+ const suggestions = findSuggestions(skills, query, MAX_SUGGESTIONS);
518
+ return { resolved: null, suggestions };
519
+ }
520
+ const localSkillsResult = await discoverLocalSkills(projectDir);
521
+ const localSkillIds = localSkillsResult?.skills.map((s) => s.id) || [];
522
+ const isInstalled = localSkillIds.includes(skill.id);
523
+ let preview = [];
524
+ if (includePreview) {
525
+ let skillMdPath;
526
+ if (skill.local && skill.localPath) {
527
+ skillMdPath = path4.join(projectDir, skill.localPath, STANDARD_FILES.SKILL_MD);
528
+ } else {
529
+ const sourceDir = isLocal ? sourcePath : path4.dirname(sourcePath);
530
+ skillMdPath = path4.join(sourceDir, skill.path, STANDARD_FILES.SKILL_MD);
531
+ }
532
+ if (await fileExists(skillMdPath)) {
533
+ const content = await readFile(skillMdPath);
534
+ preview = getPreviewLines(content, CONTENT_PREVIEW_LINES);
535
+ }
536
+ }
537
+ return {
538
+ resolved: { skill, isInstalled, preview },
539
+ suggestions: []
540
+ };
541
+ }
542
+
543
+ // src/cli/lib/operations/index.ts
544
+ init_esm_shims();
545
+
546
+ export {
547
+ detectBothInstallations,
548
+ loadSource,
549
+ detectProject,
550
+ loadAgentDefs,
551
+ copyLocalSkills,
552
+ installPluginSkills,
553
+ uninstallPluginSkills,
554
+ collectScopedSkillDirs,
555
+ buildSourceSkillsMap,
556
+ compareSkillsWithSource,
557
+ ensureMarketplace,
558
+ writeProjectConfig,
559
+ compileAgents,
560
+ discoverInstalledSkills,
561
+ findSkillMatch,
562
+ resolveSkillInfo
563
+ };
564
+ //# sourceMappingURL=chunk-5UJJQFET.js.map