@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
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Wizard
4
- } from "../chunk-LN76TJJP.js";
5
- import "../chunk-WCCWQ56J.js";
4
+ } from "../chunk-HZQOFFKA.js";
5
+ import "../chunk-UNEJKTLP.js";
6
6
  import "../chunk-YVFGISUO.js";
7
- import "../chunk-ZGD7PLLC.js";
8
- import "../chunk-LTFGEVTM.js";
7
+ import "../chunk-ZOWRO7UQ.js";
8
+ import "../chunk-HH3AWXF4.js";
9
9
  import "../chunk-V36FRPAU.js";
10
- import "../chunk-YYIWB42G.js";
11
- import "../chunk-6VGBO6SZ.js";
12
- import "../chunk-L7COG2EX.js";
13
- import "../chunk-YSLDMYWP.js";
10
+ import "../chunk-Q4DMIPZB.js";
11
+ import "../chunk-5M6Q5UQO.js";
12
+ import "../chunk-LZ7XQ3IU.js";
13
+ import "../chunk-SGZOFIFF.js";
14
14
  import "../chunk-FQTYF3OU.js";
15
15
  import "../chunk-K77I4XGL.js";
16
16
  import "../chunk-ANZV33N5.js";
@@ -20,50 +20,48 @@ import "../chunk-7SOPVGDV.js";
20
20
  import "../chunk-SB2R5KHJ.js";
21
21
  import "../chunk-BEZ6ZPDS.js";
22
22
  import "../chunk-P2FHS5IS.js";
23
- import "../chunk-G2MINRWX.js";
23
+ import "../chunk-C5IYJ42F.js";
24
24
  import "../chunk-NL5EB57E.js";
25
25
  import "../chunk-HSKKGAOW.js";
26
26
  import "../chunk-4QA5TIBU.js";
27
27
  import "../chunk-WJXWYSBT.js";
28
- import "../chunk-7UZUDHP7.js";
28
+ import "../chunk-CXWBVBDM.js";
29
29
  import "../chunk-XO6X5QE5.js";
30
30
  import "../chunk-KUV24B5M.js";
31
- import "../chunk-2XVLQDNI.js";
31
+ import "../chunk-HSLVCKVQ.js";
32
32
  import "../chunk-HEQVUIHQ.js";
33
33
  import "../chunk-U3IGFMCY.js";
34
34
  import "../chunk-HK53FRMU.js";
35
- import {
36
- getAgentDefinitions,
37
- recompileAgents
38
- } from "../chunk-CYPCJ536.js";
39
35
  import {
40
36
  ERROR_MESSAGES,
41
37
  INFO_MESSAGES,
42
38
  STATUS_MESSAGES
43
39
  } from "../chunk-B7KZLXHV.js";
44
40
  import {
45
- buildAndMergeConfig,
41
+ compileAgents,
42
+ copyLocalSkills,
43
+ detectProject,
44
+ discoverInstalledSkills,
45
+ ensureMarketplace,
46
+ installPluginSkills,
47
+ loadAgentDefs,
48
+ loadSource,
49
+ uninstallPluginSkills,
50
+ writeProjectConfig
51
+ } from "../chunk-5UJJQFET.js";
52
+ import "../chunk-N6A7A4RA.js";
53
+ import "../chunk-FBZR46GC.js";
54
+ import {
46
55
  claudePluginInstall,
47
- claudePluginMarketplaceAdd,
48
- claudePluginMarketplaceExists,
49
56
  claudePluginUninstall,
50
- copySkillsToLocalFlattened,
51
57
  deleteLocalSkill,
52
58
  deriveInstallMode,
53
- detectInstallation,
54
59
  detectMigrations,
55
60
  discoverAllPluginSkills,
56
- ensureBlankGlobalConfig,
57
61
  executeMigration,
58
- loadProjectConfig,
59
- loadSkillsMatrixFromSource,
60
- migrateLocalSkillScope,
61
- resolveInstallPaths,
62
- writeScopedConfigs
63
- } from "../chunk-FKXD3EXJ.js";
64
- import {
65
- loadAllAgents
66
- } from "../chunk-YJ2URWF7.js";
62
+ migrateLocalSkillScope
63
+ } from "../chunk-TMTUTUEV.js";
64
+ import "../chunk-B6MYECV6.js";
67
65
  import {
68
66
  getSkillById,
69
67
  matrix
@@ -71,25 +69,17 @@ import {
71
69
  import {
72
70
  BaseCommand,
73
71
  EXIT_CODES
74
- } from "../chunk-LMR7VAP3.js";
72
+ } from "../chunk-MMTMXLI4.js";
75
73
  import {
76
- disableBuffering,
77
- drainBuffer,
78
- enableBuffering,
79
- ensureDir,
80
74
  getErrorMessage,
81
- pushBufferMessage,
82
75
  remove
83
- } from "../chunk-WJKD6EGK.js";
76
+ } from "../chunk-NUU3U43A.js";
84
77
  import "../chunk-6XWHJHNZ.js";
85
78
  import {
86
79
  CLAUDE_DIR,
87
- CLAUDE_SRC_DIR,
88
80
  CLI_BIN_NAME,
89
81
  GLOBAL_INSTALL_ROOT,
90
- PROJECT_ROOT,
91
- SOURCE_DISPLAY_NAMES,
92
- STANDARD_FILES
82
+ SOURCE_DISPLAY_NAMES
93
83
  } from "../chunk-6PGL2XMY.js";
94
84
  import "../chunk-NPMMU4GY.js";
95
85
  import {
@@ -136,66 +126,99 @@ var Edit = class _Edit extends BaseCommand {
136
126
  async run() {
137
127
  const { flags } = await this.parse(_Edit);
138
128
  const cwd = process.cwd();
139
- const installation = await detectInstallation();
140
- if (!installation) {
129
+ const context = await this.loadContext(flags);
130
+ const result = await this.runEditWizard(context, cwd);
131
+ if (!result) this.error("Cancelled", { exit: EXIT_CODES.CANCELLED });
132
+ this.reportValidationErrors(result);
133
+ const changes = detectConfigChanges(context.projectConfig, result, context.currentSkillIds);
134
+ if (!hasAnyChanges(changes)) {
135
+ this.log(INFO_MESSAGES.NO_CHANGES_MADE);
136
+ this.log("Plugin unchanged\n");
137
+ return;
138
+ }
139
+ this.logChangeSummary(changes);
140
+ const migratedSkillIds = await this.applyMigrations(changes, result, context, cwd);
141
+ await this.applyScopeChanges(changes, result, context, cwd);
142
+ await this.applySourceChanges(changes, result, context, cwd, migratedSkillIds);
143
+ await this.applyPluginChanges(changes, result, context, cwd);
144
+ await this.copyNewLocalSkills(changes, result, context, cwd);
145
+ await this.writeConfigAndCompile(result, context, flags, cwd);
146
+ await this.cleanupStaleAgentFiles(changes, cwd);
147
+ this.logCompletionSummary(changes);
148
+ }
149
+ async loadContext(flags) {
150
+ const detected = await detectProject();
151
+ if (!detected) {
141
152
  this.error(ERROR_MESSAGES.NO_INSTALLATION, {
142
153
  exit: EXIT_CODES.ERROR
143
154
  });
144
155
  }
156
+ const { installation, config: projectConfig } = detected;
145
157
  const projectDir = installation.projectDir;
146
- enableBuffering();
147
158
  let sourceResult;
148
159
  let startupMessages = [];
149
160
  try {
150
- sourceResult = await loadSkillsMatrixFromSource({
161
+ const loaded = await loadSource({
151
162
  sourceFlag: flags.source,
152
163
  projectDir,
153
- forceRefresh: flags.refresh
164
+ forceRefresh: flags.refresh,
165
+ captureStartupMessages: true
154
166
  });
167
+ sourceResult = loaded.sourceResult;
168
+ startupMessages = loaded.startupMessages;
155
169
  const sourceInfo = sourceResult.isLocal ? "local" : sourceResult.sourceConfig.sourceOrigin;
156
- pushBufferMessage(
157
- "info",
158
- `Loaded ${Object.keys(matrix.skills).length} skills (${sourceInfo})`
159
- );
170
+ startupMessages.push({
171
+ level: "info",
172
+ text: `Loaded ${Object.keys(matrix.skills).length} skills (${sourceInfo})`
173
+ });
160
174
  } catch (error) {
161
- disableBuffering();
162
175
  this.handleError(error);
163
176
  }
164
- const projectConfig = await loadProjectConfig(projectDir);
165
177
  let currentSkillIds;
166
178
  try {
167
179
  const discoveredSkills = await discoverAllPluginSkills(projectDir);
168
180
  const pluginSkillIds = Object.keys(discoveredSkills);
169
- const configSkillIds = projectConfig?.config?.skills?.map((s) => s.id) ?? [];
181
+ const configSkillIds = projectConfig?.skills?.map((s) => s.id) ?? [];
170
182
  const mergedIds = /* @__PURE__ */ new Set([...pluginSkillIds, ...configSkillIds]);
171
183
  currentSkillIds = [...mergedIds];
172
- pushBufferMessage("info", `Found ${currentSkillIds.length} installed skills`);
184
+ startupMessages.push({
185
+ level: "info",
186
+ text: `Found ${currentSkillIds.length} installed skills`
187
+ });
173
188
  } catch (error) {
174
- disableBuffering();
175
189
  this.handleError(error);
176
190
  }
177
- startupMessages = drainBuffer();
178
- disableBuffering();
191
+ return {
192
+ installation,
193
+ projectConfig,
194
+ projectDir,
195
+ sourceResult,
196
+ startupMessages,
197
+ currentSkillIds
198
+ };
199
+ }
200
+ async runEditWizard(context, cwd) {
201
+ const { projectConfig, projectDir, currentSkillIds } = context;
179
202
  let wizardResult = null;
180
203
  const isGlobalDir = cwd === GLOBAL_INSTALL_ROOT;
181
- const lockedSkillIds = isGlobalDir ? void 0 : projectConfig?.config?.skills?.filter((s) => s.scope === "global").map((s) => s.id);
182
- const lockedAgentNames = isGlobalDir ? void 0 : projectConfig?.config?.agents?.filter((a) => a.scope === "global").map((a) => a.name);
204
+ const lockedSkillIds = isGlobalDir ? void 0 : projectConfig?.skills?.filter((s) => s.scope === "global").map((s) => s.id);
205
+ const lockedAgentNames = isGlobalDir ? void 0 : projectConfig?.agents?.filter((a) => a.scope === "global").map((a) => a.name);
183
206
  const { waitUntilExit } = render(
184
207
  /* @__PURE__ */ jsx(
185
208
  Wizard,
186
209
  {
187
210
  version: this.config.version,
188
211
  initialStep: "build",
189
- initialDomains: projectConfig?.config?.domains,
190
- initialAgents: projectConfig?.config?.selectedAgents,
212
+ initialDomains: projectConfig?.domains,
213
+ initialAgents: projectConfig?.selectedAgents,
191
214
  installedSkillIds: currentSkillIds,
192
- installedSkillConfigs: projectConfig?.config?.skills,
215
+ installedSkillConfigs: projectConfig?.skills,
193
216
  lockedSkillIds,
194
- installedAgentConfigs: projectConfig?.config?.agents,
217
+ installedAgentConfigs: projectConfig?.agents,
195
218
  lockedAgentNames,
196
219
  isEditingFromGlobalScope: isGlobalDir,
197
220
  projectDir,
198
- startupMessages,
221
+ startupMessages: context.startupMessages,
199
222
  onComplete: (result2) => {
200
223
  wizardResult = result2;
201
224
  },
@@ -207,62 +230,26 @@ var Edit = class _Edit extends BaseCommand {
207
230
  );
208
231
  await waitUntilExit();
209
232
  const result = wizardResult;
210
- if (!result || result.cancelled) {
211
- this.error("Cancelled", { exit: EXIT_CODES.CANCELLED });
212
- }
233
+ if (!result || result.cancelled) return null;
234
+ return result;
235
+ }
236
+ reportValidationErrors(result) {
213
237
  if (result.validation.errors.length > 0) {
214
238
  for (const err of result.validation.errors) {
215
239
  this.warn(err.message);
216
240
  }
217
241
  }
218
- const newSkillIds = result.skills.map((s) => s.id);
219
- const addedSkills = newSkillIds.filter((id) => !currentSkillIds.includes(id));
220
- const removedSkills = currentSkillIds.filter((id) => !newSkillIds.includes(id));
221
- const oldAgentNames = projectConfig?.config?.agents?.map((a) => a.name) ?? [];
222
- const newAgentNames = result.agentConfigs.map((a) => a.name);
223
- const addedAgents = newAgentNames.filter((name) => !oldAgentNames.includes(name));
224
- const removedAgents = oldAgentNames.filter((name) => !newAgentNames.includes(name));
225
- const sourceChanges = /* @__PURE__ */ new Map();
226
- const scopeChanges = /* @__PURE__ */ new Map();
227
- if (projectConfig?.config?.skills) {
228
- for (const newSkill of result.skills) {
229
- const oldSkill = projectConfig.config.skills.find((s) => s.id === newSkill.id);
230
- if (oldSkill && oldSkill.source !== newSkill.source) {
231
- sourceChanges.set(newSkill.id, {
232
- from: oldSkill.source,
233
- to: newSkill.source
234
- });
235
- }
236
- if (oldSkill && oldSkill.scope !== newSkill.scope) {
237
- scopeChanges.set(newSkill.id, {
238
- from: oldSkill.scope,
239
- to: newSkill.scope
240
- });
241
- }
242
- }
243
- }
244
- const agentScopeChanges = /* @__PURE__ */ new Map();
245
- if (projectConfig?.config?.agents) {
246
- for (const newAgent of result.agentConfigs) {
247
- const oldAgent = projectConfig.config.agents.find((a) => a.name === newAgent.name);
248
- if (oldAgent && oldAgent.scope !== newAgent.scope) {
249
- agentScopeChanges.set(newAgent.name, {
250
- from: oldAgent.scope,
251
- to: newAgent.scope
252
- });
253
- }
254
- }
255
- }
256
- const hasSourceChanges = sourceChanges.size > 0;
257
- const hasScopeChanges = scopeChanges.size > 0;
258
- const hasAgentScopeChanges = agentScopeChanges.size > 0;
259
- const hasSkillChanges = addedSkills.length > 0 || removedSkills.length > 0;
260
- const hasAgentChanges = addedAgents.length > 0 || removedAgents.length > 0;
261
- if (!hasSkillChanges && !hasAgentChanges && !hasSourceChanges && !hasScopeChanges && !hasAgentScopeChanges) {
262
- this.log(INFO_MESSAGES.NO_CHANGES_MADE);
263
- this.log("Plugin unchanged\n");
264
- return;
265
- }
242
+ }
243
+ logChangeSummary(changes) {
244
+ const {
245
+ addedSkills,
246
+ removedSkills,
247
+ addedAgents,
248
+ removedAgents,
249
+ sourceChanges,
250
+ scopeChanges,
251
+ agentScopeChanges
252
+ } = changes;
266
253
  this.log("\nChanges:");
267
254
  for (const skillId of addedSkills) {
268
255
  this.log(` + ${getSkillById(skillId).displayName}`);
@@ -293,7 +280,9 @@ var Edit = class _Edit extends BaseCommand {
293
280
  this.log(` ~ ${agentName} (${fromLabel} \u2192 ${toLabel})`);
294
281
  }
295
282
  this.log("");
296
- const oldSkills = projectConfig?.config?.skills ?? [];
283
+ }
284
+ async applyMigrations(_changes, result, context, cwd) {
285
+ const oldSkills = context.projectConfig?.skills ?? [];
297
286
  const migrationPlan = detectMigrations(oldSkills, result.skills);
298
287
  const hasMigrations = migrationPlan.toLocal.length > 0 || migrationPlan.toPlugin.length > 0;
299
288
  if (hasMigrations) {
@@ -309,158 +298,144 @@ var Edit = class _Edit extends BaseCommand {
309
298
  this.log(` - ${migration.id}`);
310
299
  }
311
300
  }
312
- const migrationResult = await executeMigration(migrationPlan, cwd, sourceResult);
301
+ const migrationResult = await executeMigration(migrationPlan, cwd, context.sourceResult);
313
302
  for (const warning of migrationResult.warnings) {
314
303
  this.warn(warning);
315
304
  }
316
305
  }
317
- const migratedSkillIds = /* @__PURE__ */ new Set([
306
+ return /* @__PURE__ */ new Set([
318
307
  ...migrationPlan.toLocal.map((m) => m.id),
319
308
  ...migrationPlan.toPlugin.map((m) => m.id)
320
309
  ]);
310
+ }
311
+ async applyScopeChanges(changes, result, context, cwd) {
312
+ const { scopeChanges } = changes;
321
313
  for (const [skillId, change] of scopeChanges) {
322
314
  const skillConfig = result.skills.find((s) => s.id === skillId);
323
315
  if (skillConfig?.source === "local") {
324
316
  await migrateLocalSkillScope(skillId, change.from, cwd);
325
- } else if (sourceResult.marketplace && skillConfig) {
326
- const oldPluginScope = change.from === "global" ? "user" : "project";
327
- const newPluginScope = change.to === "global" ? "user" : "project";
328
- try {
329
- await claudePluginUninstall(skillId, oldPluginScope, cwd);
330
- const pluginRef = `${skillId}@${sourceResult.marketplace}`;
331
- await claudePluginInstall(pluginRef, newPluginScope, cwd);
332
- } catch (error) {
333
- this.warn(`Failed to migrate plugin scope for ${skillId}: ${getErrorMessage(error)}`);
334
- }
335
317
  }
336
318
  }
319
+ if (context.sourceResult.marketplace && scopeChanges.size > 0) {
320
+ const pluginScopeResult = await migratePluginSkillScopes(
321
+ scopeChanges,
322
+ result.skills,
323
+ context.sourceResult.marketplace,
324
+ cwd
325
+ );
326
+ for (const item of pluginScopeResult.failed) {
327
+ this.warn(`Failed to migrate plugin scope for ${item.id}: ${item.error}`);
328
+ }
329
+ }
330
+ }
331
+ async applySourceChanges(changes, _result, context, cwd, migratedSkillIds) {
332
+ const { sourceChanges } = changes;
337
333
  for (const [skillId, change] of sourceChanges) {
338
334
  if (migratedSkillIds.has(skillId)) {
339
335
  continue;
340
336
  }
341
337
  if (change.from === "local") {
342
- const oldSkill = projectConfig?.config?.skills?.find((s) => s.id === skillId);
338
+ const oldSkill = context.projectConfig?.skills?.find((s) => s.id === skillId);
343
339
  const deleteDir = oldSkill?.scope === "global" ? os.homedir() : cwd;
344
340
  await deleteLocalSkill(deleteDir, skillId);
345
341
  }
346
342
  }
347
- if (sourceResult.marketplace) {
348
- const marketplaceExists = await claudePluginMarketplaceExists(sourceResult.marketplace);
349
- if (!marketplaceExists) {
350
- this.log(`Registering marketplace "${sourceResult.marketplace}"...`);
351
- const marketplaceSource = sourceResult.sourceConfig.source.replace(/^github:/, "");
352
- await claudePluginMarketplaceAdd(marketplaceSource);
353
- this.log(`Registered marketplace: ${sourceResult.marketplace}`);
343
+ }
344
+ async applyPluginChanges(changes, result, context, cwd) {
345
+ const { addedSkills, removedSkills } = changes;
346
+ if (context.sourceResult.marketplace) {
347
+ const mpResult = await ensureMarketplace(context.sourceResult);
348
+ if (mpResult.registered) {
349
+ this.log(`Registered marketplace: ${mpResult.marketplace}`);
354
350
  }
355
- for (const skillId of addedSkills) {
356
- const skillConfig = result.skills.find((s) => s.id === skillId);
357
- if (!skillConfig || skillConfig.source === "local") continue;
358
- const pluginRef = `${skillId}@${sourceResult.marketplace}`;
359
- const pluginScope = skillConfig.scope === "global" ? "user" : "project";
360
- this.log(`Installing plugin: ${pluginRef}...`);
361
- try {
362
- await claudePluginInstall(pluginRef, pluginScope, cwd);
363
- } catch (error) {
364
- this.warn(`Failed to install plugin ${pluginRef}: ${getErrorMessage(error)}`);
351
+ const addedPluginSkills = result.skills.filter(
352
+ (s) => addedSkills.includes(s.id) && s.source !== "local"
353
+ );
354
+ if (addedPluginSkills.length > 0) {
355
+ const pluginResult = await installPluginSkills(
356
+ addedPluginSkills,
357
+ context.sourceResult.marketplace,
358
+ cwd
359
+ );
360
+ for (const item of pluginResult.installed) {
361
+ this.log(`Installing plugin: ${item.ref}...`);
362
+ }
363
+ for (const item of pluginResult.failed) {
364
+ this.warn(`Failed to install plugin ${item.id}: ${item.error}`);
365
365
  }
366
366
  }
367
- for (const skillId of removedSkills) {
368
- const oldSkill = projectConfig?.config?.skills?.find((s) => s.id === skillId);
369
- const pluginScope = oldSkill?.scope === "global" ? "user" : "project";
370
- this.log(`Uninstalling plugin: ${skillId}...`);
371
- try {
372
- await claudePluginUninstall(skillId, pluginScope, cwd);
373
- } catch (error) {
374
- this.warn(`Failed to uninstall plugin ${skillId}: ${getErrorMessage(error)}`);
367
+ if (removedSkills.length > 0) {
368
+ const uninstallResult = await uninstallPluginSkills(
369
+ removedSkills,
370
+ context.projectConfig?.skills ?? [],
371
+ cwd
372
+ );
373
+ for (const id of uninstallResult.uninstalled) {
374
+ this.log(`Uninstalling plugin: ${id}...`);
375
+ }
376
+ for (const item of uninstallResult.failed) {
377
+ this.warn(`Failed to uninstall plugin ${item.id}: ${item.error}`);
375
378
  }
376
379
  }
377
380
  }
381
+ }
382
+ async copyNewLocalSkills(changes, result, context, cwd) {
383
+ const { addedSkills } = changes;
378
384
  const addedLocalSkills = result.skills.filter(
379
385
  (s) => addedSkills.includes(s.id) && s.source === "local"
380
386
  );
381
387
  if (addedLocalSkills.length > 0) {
382
- const projectLocalSkills = addedLocalSkills.filter((s) => s.scope !== "global");
383
- const globalLocalSkills = addedLocalSkills.filter((s) => s.scope === "global");
384
- const projectPaths = resolveInstallPaths(cwd, "project");
385
- const globalPaths = resolveInstallPaths(cwd, "global");
386
- if (projectLocalSkills.length > 0) {
387
- await ensureDir(projectPaths.skillsDir);
388
- await copySkillsToLocalFlattened(
389
- projectLocalSkills.map((s) => s.id),
390
- projectPaths.skillsDir,
391
- sourceResult.matrix,
392
- sourceResult
393
- );
394
- }
395
- if (globalLocalSkills.length > 0) {
396
- await ensureDir(globalPaths.skillsDir);
397
- await copySkillsToLocalFlattened(
398
- globalLocalSkills.map((s) => s.id),
399
- globalPaths.skillsDir,
400
- sourceResult.matrix,
401
- sourceResult
402
- );
403
- }
404
- this.log(`Copied ${addedLocalSkills.length} local skill(s) to .claude/skills/`);
388
+ const copyResult = await copyLocalSkills(addedLocalSkills, cwd, context.sourceResult);
389
+ this.log(`Copied ${copyResult.totalCopied} local skill(s) to .claude/skills/`);
405
390
  }
406
- let sourcePath;
391
+ }
392
+ async writeConfigAndCompile(result, context, flags, cwd) {
393
+ let agentDefsResult;
407
394
  this.log(
408
395
  flags["agent-source"] ? STATUS_MESSAGES.FETCHING_AGENT_PARTIALS : STATUS_MESSAGES.LOADING_AGENT_PARTIALS
409
396
  );
410
397
  try {
411
- const agentDefs = await getAgentDefinitions(flags["agent-source"], {
398
+ agentDefsResult = await loadAgentDefs(flags["agent-source"], {
412
399
  forceRefresh: flags.refresh
413
400
  });
414
- sourcePath = agentDefs.sourcePath;
415
401
  this.log(flags["agent-source"] ? "\u2713 Agent partials fetched\n" : "\u2713 Agent partials loaded\n");
416
402
  } catch (error) {
417
403
  this.handleError(error);
418
404
  }
419
405
  try {
420
- const mergeResult = await buildAndMergeConfig(result, sourceResult, cwd, flags.source);
421
- const cliAgents = await loadAllAgents(PROJECT_ROOT);
422
- const sourceAgents = await loadAllAgents(sourcePath);
423
- const agents = { ...cliAgents, ...sourceAgents };
424
- if (cwd !== os.homedir()) {
425
- await ensureBlankGlobalConfig();
426
- }
427
- const configPath = path.join(cwd, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS);
428
- const projectInstallationExists = path.resolve(installation.projectDir) !== path.resolve(os.homedir());
429
- await writeScopedConfigs(
430
- mergeResult.config,
431
- sourceResult.matrix,
432
- agents,
433
- cwd,
434
- configPath,
435
- projectInstallationExists
436
- );
406
+ await writeProjectConfig({
407
+ wizardResult: result,
408
+ sourceResult: context.sourceResult,
409
+ projectDir: cwd,
410
+ sourceFlag: flags.source,
411
+ agents: agentDefsResult.agents
412
+ });
437
413
  } catch (error) {
438
414
  this.warn(`Could not update config: ${getErrorMessage(error)}`);
439
415
  }
440
416
  this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);
441
417
  try {
442
- const recompileSkills = await discoverAllPluginSkills(cwd);
443
418
  const agentScopeMap = new Map(result.agentConfigs.map((a) => [a.name, a.scope]));
444
- const outputDir = path.join(cwd, CLAUDE_DIR, "agents");
445
- const recompileResult = await recompileAgents({
446
- pluginDir: cwd,
447
- sourcePath,
448
- skills: recompileSkills,
419
+ const { allSkills } = await discoverInstalledSkills(cwd);
420
+ const compilationResult = await compileAgents({
449
421
  projectDir: cwd,
450
- outputDir,
422
+ sourcePath: agentDefsResult.sourcePath,
423
+ skills: allSkills,
424
+ pluginDir: cwd,
425
+ outputDir: path.join(cwd, CLAUDE_DIR, "agents"),
451
426
  installMode: deriveInstallMode(result.skills),
452
427
  agentScopeMap
453
428
  });
454
- if (recompileResult.failed.length > 0) {
429
+ if (compilationResult.failed.length > 0) {
455
430
  this.log(
456
- `\u2713 Recompiled ${recompileResult.compiled.length} agents (${recompileResult.failed.length} failed)
431
+ `\u2713 Recompiled ${compilationResult.compiled.length} agents (${compilationResult.failed.length} failed)
457
432
  `
458
433
  );
459
- for (const warning of recompileResult.warnings) {
434
+ for (const warning of compilationResult.warnings) {
460
435
  this.warn(warning);
461
436
  }
462
- } else if (recompileResult.compiled.length > 0) {
463
- this.log(`\u2713 Recompiled ${recompileResult.compiled.length} agents
437
+ } else if (compilationResult.compiled.length > 0) {
438
+ this.log(`\u2713 Recompiled ${compilationResult.compiled.length} agents
464
439
  `);
465
440
  } else {
466
441
  this.log("\u2713 No agents to recompile\n");
@@ -470,6 +445,9 @@ var Edit = class _Edit extends BaseCommand {
470
445
  this.log(`You can manually recompile with '${CLI_BIN_NAME} compile'.
471
446
  `);
472
447
  }
448
+ }
449
+ async cleanupStaleAgentFiles(changes, cwd) {
450
+ const { agentScopeChanges } = changes;
473
451
  for (const [agentName, change] of agentScopeChanges) {
474
452
  const oldBaseDir = change.from === "global" ? os.homedir() : cwd;
475
453
  const oldAgentPath = path.join(oldBaseDir, CLAUDE_DIR, "agents", `${agentName}.md`);
@@ -479,6 +457,21 @@ var Edit = class _Edit extends BaseCommand {
479
457
  this.warn(`Could not remove old agent file ${oldAgentPath}: ${getErrorMessage(error)}`);
480
458
  }
481
459
  }
460
+ }
461
+ logCompletionSummary(changes) {
462
+ const {
463
+ addedSkills,
464
+ removedSkills,
465
+ addedAgents,
466
+ removedAgents,
467
+ sourceChanges,
468
+ scopeChanges,
469
+ agentScopeChanges
470
+ } = changes;
471
+ const hasAgentChanges = addedAgents.length > 0 || removedAgents.length > 0;
472
+ const hasSourceChanges = sourceChanges.size > 0;
473
+ const hasScopeChanges = scopeChanges.size > 0;
474
+ const hasAgentScopeChanges = agentScopeChanges.size > 0;
482
475
  const summaryParts = [`${addedSkills.length} added`, `${removedSkills.length} removed`];
483
476
  if (hasAgentChanges) {
484
477
  summaryParts.push(
@@ -497,6 +490,79 @@ var Edit = class _Edit extends BaseCommand {
497
490
  `);
498
491
  }
499
492
  };
493
+ function detectConfigChanges(oldConfig, wizardResult, currentSkillIds) {
494
+ const newSkillIds = wizardResult.skills.map((s) => s.id);
495
+ const addedSkills = newSkillIds.filter((id) => !currentSkillIds.includes(id));
496
+ const removedSkills = currentSkillIds.filter((id) => !newSkillIds.includes(id));
497
+ const oldAgentNames = oldConfig?.agents?.map((a) => a.name) ?? [];
498
+ const newAgentNames = wizardResult.agentConfigs.map((a) => a.name);
499
+ const addedAgents = newAgentNames.filter((name) => !oldAgentNames.includes(name));
500
+ const removedAgents = oldAgentNames.filter((name) => !newAgentNames.includes(name));
501
+ const sourceChanges = /* @__PURE__ */ new Map();
502
+ const scopeChanges = /* @__PURE__ */ new Map();
503
+ if (oldConfig?.skills) {
504
+ for (const newSkill of wizardResult.skills) {
505
+ const oldSkill = oldConfig.skills.find((s) => s.id === newSkill.id);
506
+ if (oldSkill && oldSkill.source !== newSkill.source) {
507
+ sourceChanges.set(newSkill.id, {
508
+ from: oldSkill.source,
509
+ to: newSkill.source
510
+ });
511
+ }
512
+ if (oldSkill && oldSkill.scope !== newSkill.scope) {
513
+ scopeChanges.set(newSkill.id, {
514
+ from: oldSkill.scope,
515
+ to: newSkill.scope
516
+ });
517
+ }
518
+ }
519
+ }
520
+ const agentScopeChanges = /* @__PURE__ */ new Map();
521
+ if (oldConfig?.agents) {
522
+ for (const newAgent of wizardResult.agentConfigs) {
523
+ const oldAgent = oldConfig.agents.find((a) => a.name === newAgent.name);
524
+ if (oldAgent && oldAgent.scope !== newAgent.scope) {
525
+ agentScopeChanges.set(newAgent.name, {
526
+ from: oldAgent.scope,
527
+ to: newAgent.scope
528
+ });
529
+ }
530
+ }
531
+ }
532
+ return {
533
+ addedSkills,
534
+ removedSkills,
535
+ addedAgents,
536
+ removedAgents,
537
+ sourceChanges,
538
+ scopeChanges,
539
+ agentScopeChanges
540
+ };
541
+ }
542
+ function hasAnyChanges(changes) {
543
+ return changes.addedSkills.length > 0 || changes.removedSkills.length > 0 || changes.addedAgents.length > 0 || changes.removedAgents.length > 0 || changes.sourceChanges.size > 0 || changes.scopeChanges.size > 0 || changes.agentScopeChanges.size > 0;
544
+ }
545
+ async function migratePluginSkillScopes(scopeChanges, skills, marketplace, projectDir) {
546
+ const migrated = [];
547
+ const failed = [];
548
+ for (const [skillId, change] of scopeChanges) {
549
+ const skillConfig = skills.find((s) => s.id === skillId);
550
+ if (!skillConfig || skillConfig.source === "local") {
551
+ continue;
552
+ }
553
+ const oldPluginScope = change.from === "global" ? "user" : "project";
554
+ const newPluginScope = change.to === "global" ? "user" : "project";
555
+ const pluginRef = `${skillId}@${marketplace}`;
556
+ try {
557
+ await claudePluginUninstall(skillId, oldPluginScope, projectDir);
558
+ await claudePluginInstall(pluginRef, newPluginScope, projectDir);
559
+ migrated.push(skillId);
560
+ } catch (error) {
561
+ failed.push({ id: skillId, error: getErrorMessage(error) });
562
+ }
563
+ }
564
+ return { migrated, failed };
565
+ }
500
566
  export {
501
567
  Edit as default
502
568
  };