agents-inc 0.164.0 → 0.166.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 (191) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +8 -9
  3. package/dist/{chunk-X4SSJZLY.js → chunk-25MPBIK3.js} +12 -261
  4. package/dist/chunk-25MPBIK3.js.map +1 -0
  5. package/dist/{chunk-LT5GXEB2.js → chunk-2VUYFTUB.js} +8 -7
  6. package/dist/chunk-2VUYFTUB.js.map +1 -0
  7. package/dist/chunk-4AAOOAIN.js +49 -0
  8. package/dist/chunk-4AAOOAIN.js.map +1 -0
  9. package/dist/{chunk-ARYNOWKF.js → chunk-4NDBUJHK.js} +8 -8
  10. package/dist/{chunk-S63LXWMC.js → chunk-6L75SQZU.js} +2 -2
  11. package/dist/{chunk-7REKOTKG.js → chunk-6LF4CQBY.js} +3 -3
  12. package/dist/{chunk-K5ITEA3I.js → chunk-7JNJ52CD.js} +34 -17
  13. package/dist/chunk-7JNJ52CD.js.map +1 -0
  14. package/dist/{chunk-XPDVAJDH.js → chunk-A4KDXNOT.js} +3519 -1568
  15. package/dist/chunk-A4KDXNOT.js.map +1 -0
  16. package/dist/{chunk-XHPWTL4I.js → chunk-DAIEQJIF.js} +3 -3
  17. package/dist/{chunk-UITEKY2R.js → chunk-ENGYJCTF.js} +28 -4
  18. package/dist/chunk-ENGYJCTF.js.map +1 -0
  19. package/dist/{chunk-G2JJ5BO5.js → chunk-G4JK7WVO.js} +336 -140
  20. package/dist/chunk-G4JK7WVO.js.map +1 -0
  21. package/dist/{chunk-X37UYIE3.js → chunk-G6UREQ4V.js} +436 -739
  22. package/dist/chunk-G6UREQ4V.js.map +1 -0
  23. package/dist/chunk-GE3WKJ6Q.js +375 -0
  24. package/dist/chunk-GE3WKJ6Q.js.map +1 -0
  25. package/dist/{chunk-RGYDFBCT.js → chunk-HHIYT3PI.js} +5 -5
  26. package/dist/{chunk-2CQNPLVF.js → chunk-HWEKHVLE.js} +63 -42
  27. package/dist/chunk-HWEKHVLE.js.map +1 -0
  28. package/dist/{chunk-XVAQG2CV.js → chunk-JOEA52NR.js} +10 -8
  29. package/dist/chunk-JOEA52NR.js.map +1 -0
  30. package/dist/{chunk-3WVH2CTK.js → chunk-JQRJQ4SS.js} +15 -8
  31. package/dist/chunk-JQRJQ4SS.js.map +1 -0
  32. package/dist/{chunk-DSL66I4N.js → chunk-LFWLEDUG.js} +6 -6
  33. package/dist/{chunk-B3Y3QMWI.js → chunk-MAWNVT2C.js} +4 -4
  34. package/dist/{chunk-Q4IRRVXK.js → chunk-MPTNC32T.js} +3 -3
  35. package/dist/chunk-NBXXFIIW.js +73 -0
  36. package/dist/chunk-NBXXFIIW.js.map +1 -0
  37. package/dist/{chunk-B6FSLXYN.js → chunk-PMJWD27C.js} +3 -3
  38. package/dist/{chunk-XATLUKXK.js → chunk-PNB3524H.js} +6 -6
  39. package/dist/chunk-PXWG7KFO.js +39 -0
  40. package/dist/chunk-PXWG7KFO.js.map +1 -0
  41. package/dist/{chunk-4VL3CEOS.js → chunk-QHDPLLK6.js} +3 -3
  42. package/dist/{chunk-AOTCIUGX.js → chunk-RAHSOJQ2.js} +2 -2
  43. package/dist/{chunk-PHCPUQVR.js → chunk-RZDXDMT6.js} +2 -2
  44. package/dist/{chunk-6MV4JOCL.js → chunk-SAYZWCH6.js} +2 -2
  45. package/dist/{chunk-URXIQE7I.js → chunk-SCOQ34YM.js} +2 -2
  46. package/dist/{chunk-NQXO4LR3.js → chunk-SXVHSOTH.js} +16 -11
  47. package/dist/chunk-SXVHSOTH.js.map +1 -0
  48. package/dist/{chunk-QZX7SYKU.js → chunk-T6UWJAB3.js} +2 -2
  49. package/dist/{chunk-ZVXGW2IC.js → chunk-TODCQFRB.js} +4 -6
  50. package/dist/chunk-TODCQFRB.js.map +1 -0
  51. package/dist/{chunk-YRS3QZP2.js → chunk-TTY6DPJN.js} +3 -3
  52. package/dist/{chunk-QGUP3QJF.js → chunk-TZ2YJJKK.js} +22 -18
  53. package/dist/{chunk-QGUP3QJF.js.map → chunk-TZ2YJJKK.js.map} +1 -1
  54. package/dist/chunk-V3I7VQ7N.js +356 -0
  55. package/dist/chunk-V3I7VQ7N.js.map +1 -0
  56. package/dist/{chunk-AVK2HEKB.js → chunk-V5WXIM2F.js} +2 -6
  57. package/dist/{chunk-AVK2HEKB.js.map → chunk-V5WXIM2F.js.map} +1 -1
  58. package/dist/{chunk-NKGYKOB7.js → chunk-VAPTVR3J.js} +7 -8
  59. package/dist/chunk-VAPTVR3J.js.map +1 -0
  60. package/dist/chunk-VRXX4D6K.js +31 -0
  61. package/dist/chunk-VRXX4D6K.js.map +1 -0
  62. package/dist/{chunk-ABAZMMG4.js → chunk-WVUDLKIO.js} +2 -2
  63. package/dist/{chunk-ECURHW3T.js → chunk-WWIFNPJG.js} +13 -12
  64. package/dist/chunk-WWIFNPJG.js.map +1 -0
  65. package/dist/{chunk-J27W6TXS.js → chunk-XQHZPINL.js} +8 -4
  66. package/dist/chunk-XQHZPINL.js.map +1 -0
  67. package/dist/{chunk-V5GLL2JB.js → chunk-XZEVWPX6.js} +7 -7
  68. package/dist/chunk-Y3VIRVVE.js +932 -0
  69. package/dist/chunk-Y3VIRVVE.js.map +1 -0
  70. package/dist/{chunk-NTF4UXGK.js → chunk-Y47EV74W.js} +73 -30
  71. package/dist/chunk-Y47EV74W.js.map +1 -0
  72. package/dist/chunk-ZR4YPKXQ.js +159 -0
  73. package/dist/chunk-ZR4YPKXQ.js.map +1 -0
  74. package/dist/chunk-ZXKBERQU.js +250 -0
  75. package/dist/chunk-ZXKBERQU.js.map +1 -0
  76. package/dist/commands/build/marketplace.js +17 -17
  77. package/dist/commands/build/marketplace.js.map +1 -1
  78. package/dist/commands/build/plugins.js +11 -9
  79. package/dist/commands/build/plugins.js.map +1 -1
  80. package/dist/commands/compile.js +105 -27
  81. package/dist/commands/compile.js.map +1 -1
  82. package/dist/commands/doctor.js +309 -171
  83. package/dist/commands/doctor.js.map +1 -1
  84. package/dist/commands/edit.js +503 -314
  85. package/dist/commands/edit.js.map +1 -1
  86. package/dist/commands/eject.js +40 -23
  87. package/dist/commands/eject.js.map +1 -1
  88. package/dist/commands/init.js +44 -40
  89. package/dist/commands/list.js +44 -10
  90. package/dist/commands/list.js.map +1 -1
  91. package/dist/commands/new/marketplace.js +13 -10
  92. package/dist/commands/new/marketplace.js.map +1 -1
  93. package/dist/commands/search.js +12 -10
  94. package/dist/commands/search.js.map +1 -1
  95. package/dist/commands/share.js +102 -15
  96. package/dist/commands/share.js.map +1 -1
  97. package/dist/commands/uninstall.js +231 -103
  98. package/dist/commands/uninstall.js.map +1 -1
  99. package/dist/commands/update.js +49 -20
  100. package/dist/commands/update.js.map +1 -1
  101. package/dist/components/common/prompt-confirm.js +1 -1
  102. package/dist/components/common/removal-plan-confirm.js +2 -2
  103. package/dist/components/common/select-list.js +3 -3
  104. package/dist/components/common/spinner.js +6 -3
  105. package/dist/components/wizard/category-grid.js +5 -5
  106. package/dist/components/wizard/checkbox-grid.js +4 -4
  107. package/dist/components/wizard/domain-selection.js +9 -9
  108. package/dist/components/wizard/run-wizard-session.js +29 -29
  109. package/dist/components/wizard/scroll-affordance.js +2 -2
  110. package/dist/components/wizard/skill-agent-summary.js +5 -5
  111. package/dist/components/wizard/source-grid.js +6 -6
  112. package/dist/components/wizard/stack-selection.js +8 -8
  113. package/dist/components/wizard/step-agents.js +8 -8
  114. package/dist/components/wizard/step-build.js +8 -8
  115. package/dist/components/wizard/step-confirm.js +9 -9
  116. package/dist/components/wizard/step-sources.js +9 -9
  117. package/dist/components/wizard/step-stack.js +9 -9
  118. package/dist/components/wizard/summary-panel.js +8 -8
  119. package/dist/components/wizard/toast.js +2 -2
  120. package/dist/components/wizard/wizard-layout.js +12 -12
  121. package/dist/components/wizard/wizard-tabs.js +2 -2
  122. package/dist/components/wizard/wizard.js +27 -27
  123. package/dist/hooks/init.js +69 -43
  124. package/dist/hooks/init.js.map +1 -1
  125. package/dist/load-agent-defs-3C27ENC7.js +14 -0
  126. package/dist/recompile-project-agents-DGNBCU3N.js +18 -0
  127. package/dist/{source-loader-GRBVNRAW.js → source-loader-7KZ3MD5O.js} +6 -4
  128. package/dist/src/agents/_templates/agent-body.liquid +55 -0
  129. package/dist/src/agents/_templates/agent.liquid +1 -55
  130. package/dist/src/agents/meta/agent-summoner/output.md +1 -1
  131. package/dist/src/agents/meta/agent-summoner/playbook.md +15 -7
  132. package/dist/stores/wizard-store.js +4 -4
  133. package/package.json +10 -9
  134. package/src/agents/_templates/agent-body.liquid +55 -0
  135. package/src/agents/_templates/agent.liquid +1 -55
  136. package/src/agents/meta/agent-summoner/output.md +1 -1
  137. package/src/agents/meta/agent-summoner/playbook.md +15 -7
  138. package/src/schemas/project-config.schema.json +1 -1
  139. package/src/schemas/project-source-config.schema.json +1 -1
  140. package/dist/chunk-2CQNPLVF.js.map +0 -1
  141. package/dist/chunk-3WVH2CTK.js.map +0 -1
  142. package/dist/chunk-7ANJQLPJ.js +0 -35
  143. package/dist/chunk-7ANJQLPJ.js.map +0 -1
  144. package/dist/chunk-ECURHW3T.js.map +0 -1
  145. package/dist/chunk-FLW25ORT.js +0 -130
  146. package/dist/chunk-FLW25ORT.js.map +0 -1
  147. package/dist/chunk-G2JJ5BO5.js.map +0 -1
  148. package/dist/chunk-J27W6TXS.js.map +0 -1
  149. package/dist/chunk-JCPANDNR.js +0 -35
  150. package/dist/chunk-JCPANDNR.js.map +0 -1
  151. package/dist/chunk-JIERYE6B.js +0 -480
  152. package/dist/chunk-JIERYE6B.js.map +0 -1
  153. package/dist/chunk-JU4ZGJ7A.js +0 -668
  154. package/dist/chunk-JU4ZGJ7A.js.map +0 -1
  155. package/dist/chunk-K5ITEA3I.js.map +0 -1
  156. package/dist/chunk-LT5GXEB2.js.map +0 -1
  157. package/dist/chunk-NKGYKOB7.js.map +0 -1
  158. package/dist/chunk-NQXO4LR3.js.map +0 -1
  159. package/dist/chunk-NTF4UXGK.js.map +0 -1
  160. package/dist/chunk-UITEKY2R.js.map +0 -1
  161. package/dist/chunk-X37UYIE3.js.map +0 -1
  162. package/dist/chunk-X4SSJZLY.js.map +0 -1
  163. package/dist/chunk-XPDVAJDH.js.map +0 -1
  164. package/dist/chunk-XVAQG2CV.js.map +0 -1
  165. package/dist/chunk-ZBPEFQ4G.js +0 -12
  166. package/dist/chunk-ZBPEFQ4G.js.map +0 -1
  167. package/dist/chunk-ZVXGW2IC.js.map +0 -1
  168. package/dist/load-agent-defs-7IM3GBEQ.js +0 -13
  169. package/dist/recompile-project-agents-VR4NLGOU.js +0 -17
  170. /package/dist/{chunk-ARYNOWKF.js.map → chunk-4NDBUJHK.js.map} +0 -0
  171. /package/dist/{chunk-S63LXWMC.js.map → chunk-6L75SQZU.js.map} +0 -0
  172. /package/dist/{chunk-7REKOTKG.js.map → chunk-6LF4CQBY.js.map} +0 -0
  173. /package/dist/{chunk-XHPWTL4I.js.map → chunk-DAIEQJIF.js.map} +0 -0
  174. /package/dist/{chunk-RGYDFBCT.js.map → chunk-HHIYT3PI.js.map} +0 -0
  175. /package/dist/{chunk-DSL66I4N.js.map → chunk-LFWLEDUG.js.map} +0 -0
  176. /package/dist/{chunk-B3Y3QMWI.js.map → chunk-MAWNVT2C.js.map} +0 -0
  177. /package/dist/{chunk-Q4IRRVXK.js.map → chunk-MPTNC32T.js.map} +0 -0
  178. /package/dist/{chunk-B6FSLXYN.js.map → chunk-PMJWD27C.js.map} +0 -0
  179. /package/dist/{chunk-XATLUKXK.js.map → chunk-PNB3524H.js.map} +0 -0
  180. /package/dist/{chunk-4VL3CEOS.js.map → chunk-QHDPLLK6.js.map} +0 -0
  181. /package/dist/{chunk-AOTCIUGX.js.map → chunk-RAHSOJQ2.js.map} +0 -0
  182. /package/dist/{chunk-PHCPUQVR.js.map → chunk-RZDXDMT6.js.map} +0 -0
  183. /package/dist/{chunk-6MV4JOCL.js.map → chunk-SAYZWCH6.js.map} +0 -0
  184. /package/dist/{chunk-URXIQE7I.js.map → chunk-SCOQ34YM.js.map} +0 -0
  185. /package/dist/{chunk-QZX7SYKU.js.map → chunk-T6UWJAB3.js.map} +0 -0
  186. /package/dist/{chunk-YRS3QZP2.js.map → chunk-TTY6DPJN.js.map} +0 -0
  187. /package/dist/{chunk-ABAZMMG4.js.map → chunk-WVUDLKIO.js.map} +0 -0
  188. /package/dist/{chunk-V5GLL2JB.js.map → chunk-XZEVWPX6.js.map} +0 -0
  189. /package/dist/{load-agent-defs-7IM3GBEQ.js.map → load-agent-defs-3C27ENC7.js.map} +0 -0
  190. /package/dist/{recompile-project-agents-VR4NLGOU.js.map → recompile-project-agents-DGNBCU3N.js.map} +0 -0
  191. /package/dist/{source-loader-GRBVNRAW.js.map → source-loader-7KZ3MD5O.js.map} +0 -0
@@ -1,52 +1,59 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  RemovalPlanConfirm
4
- } from "../chunk-ZVXGW2IC.js";
5
- import "../chunk-OZXAJNLA.js";
4
+ } from "../chunk-TODCQFRB.js";
6
5
  import {
7
6
  promptConfirm
8
- } from "../chunk-JCPANDNR.js";
7
+ } from "../chunk-4AAOOAIN.js";
8
+ import "../chunk-OZXAJNLA.js";
9
9
  import {
10
10
  lazyGateDeps,
11
11
  mutateGlobal,
12
12
  propagateGlobalRemoval
13
- } from "../chunk-X37UYIE3.js";
14
- import "../chunk-2CQNPLVF.js";
13
+ } from "../chunk-G6UREQ4V.js";
14
+ import "../chunk-HWEKHVLE.js";
15
15
  import {
16
16
  loadAgentDefs
17
- } from "../chunk-B6FSLXYN.js";
17
+ } from "../chunk-PMJWD27C.js";
18
+ import "../chunk-ZR4YPKXQ.js";
18
19
  import {
19
- listAgentMdFiles,
20
+ listAgentFilesOf,
20
21
  splitAgentsByProvenance
21
- } from "../chunk-JU4ZGJ7A.js";
22
+ } from "../chunk-GE3WKJ6Q.js";
22
23
  import "../chunk-JFLVEFFP.js";
24
+ import {
25
+ providerFlag,
26
+ providerNamedBy,
27
+ refuseAnAmbiguousInstallation
28
+ } from "../chunk-NBXXFIIW.js";
23
29
  import {
24
30
  BaseCommand,
25
31
  EXIT_CODES
26
- } from "../chunk-JIERYE6B.js";
27
- import "../chunk-NKGYKOB7.js";
28
- import "../chunk-PHCPUQVR.js";
32
+ } from "../chunk-Y3VIRVVE.js";
33
+ import "../chunk-VAPTVR3J.js";
34
+ import "../chunk-RZDXDMT6.js";
29
35
  import {
30
36
  ConfigLoadError,
31
37
  INFO_MESSAGES,
32
38
  SUCCESS_MESSAGES,
33
39
  UNINSTALL_PLAN,
40
+ agentCodec,
34
41
  buildMarketplacePluginRef,
35
- claudePluginUninstallBestEffort,
36
42
  compiledAgentsRemoval,
37
43
  directoryExists,
38
44
  fileExists,
39
45
  getErrorMessage,
40
46
  getProjectPluginsDir,
41
- isClaudeCLIAvailable,
47
+ hostAt,
42
48
  isHomeDirectory,
43
49
  listDirectories,
44
50
  listPluginNames,
45
- loadProjectConfigFromDir,
51
+ loadProjectConfigAt,
46
52
  loadSkillsMatrixFromSource,
47
53
  localSkillsRemoval,
48
54
  notInstalledHere,
49
55
  parseMarketplacePluginRef,
56
+ providerInUse,
50
57
  readForkedFromMetadata,
51
58
  registeredProjectUpdateSkipped,
52
59
  registeredProjectsUpdateFailed,
@@ -54,17 +61,19 @@ import {
54
61
  remove,
55
62
  removeDirIfEmpty,
56
63
  resolveInstallPaths,
57
- toClaudePluginScope,
64
+ sourceFolderInUse,
65
+ sourceRootOf,
66
+ uninstallConfigUnreadable,
67
+ uninstallNeedsTerminal,
58
68
  unmarkedAgentsKept
59
- } from "../chunk-XPDVAJDH.js";
60
- import "../chunk-AVK2HEKB.js";
69
+ } from "../chunk-A4KDXNOT.js";
70
+ import "../chunk-V5WXIM2F.js";
61
71
  import {
62
72
  CLAUDE_DIR,
63
- CLAUDE_SRC_DIR,
64
73
  DEFAULT_BRANDING,
65
74
  EJECT_SOURCE,
66
75
  STANDARD_FILES
67
- } from "../chunk-UITEKY2R.js";
76
+ } from "../chunk-ENGYJCTF.js";
68
77
  import "../chunk-OI2H6M5I.js";
69
78
 
70
79
  // src/cli/commands/uninstall.tsx
@@ -80,7 +89,7 @@ function buildRemovalPlan(target) {
80
89
  ...pluginsEntry(target),
81
90
  ...localSkillsEntry(target),
82
91
  ...agents,
83
- ...configManifestEntry(target)
92
+ ...configManifestEntries(target)
84
93
  ],
85
94
  kept: keptStatements(target, agents)
86
95
  };
@@ -100,19 +109,16 @@ function compiledAgentsEntry(target) {
100
109
  if (!target.hasLocalAgents) return [];
101
110
  const agentNames = identifiableAgents(target);
102
111
  if (agentNames.length === 0) return [];
103
- return [{ kind: "agents", agentsDir: target.agentsDir, agentNames }];
112
+ return [{ kind: "agents", agentsDir: target.agentsDir, agentNames, codec: target.agentCodec }];
104
113
  }
105
114
  function identifiableAgents(target) {
106
115
  if (target.configuredAgents.length > 0) return target.configuredAgents;
107
116
  return target.markedAgents;
108
117
  }
109
- function configManifestEntry(target) {
110
- const fileNames = [
111
- ...target.hasClaudeSrcConfig ? [STANDARD_FILES.CONFIG_TS] : [],
112
- ...target.hasClaudeSrcConfigTypes ? [STANDARD_FILES.CONFIG_TYPES_TS] : []
113
- ];
114
- if (fileNames.length === 0) return [];
115
- return [{ kind: "config", claudeSrcDir: target.claudeSrcDir, fileNames }];
118
+ function configManifestEntries(target) {
119
+ const { dir, manifestFiles } = target.sourceFolder;
120
+ if (manifestFiles.length === 0) return [];
121
+ return [{ kind: "config", sourceDir: dir, fileNames: manifestFiles }];
116
122
  }
117
123
  function keptStatements(target, agentRemovals) {
118
124
  const removing = new Set(agentRemovals.flatMap((entry) => entry.agentNames));
@@ -120,6 +126,11 @@ function keptStatements(target, agentRemovals) {
120
126
  if (kept.length === 0) return [];
121
127
  return [unmarkedAgentsKept(target.agentsDir, kept.length)];
122
128
  }
129
+ function planEntries(plan, kind) {
130
+ return plan.entries.filter(
131
+ (entry) => entry.kind === kind
132
+ );
133
+ }
123
134
  function planEntry(plan, kind) {
124
135
  return plan.entries.find(
125
136
  (entry) => entry.kind === kind
@@ -142,7 +153,7 @@ function describeEntry(entry) {
142
153
  case "config":
143
154
  return {
144
155
  label: UNINSTALL_PLAN.CONFIG_HEADING,
145
- items: entry.fileNames.map((fileName) => `${entry.claudeSrcDir}/${fileName}`)
156
+ items: entry.fileNames.map((fileName) => `${entry.sourceDir}/${fileName}`)
146
157
  };
147
158
  default: {
148
159
  const _exhaustive = entry;
@@ -183,7 +194,7 @@ var Uninstall = class _Uninstall extends BaseCommand {
183
194
  */
184
195
  brandingName = DEFAULT_BRANDING.NAME;
185
196
  static summary = `Remove ${DEFAULT_BRANDING.NAME} from this project`;
186
- static description = `Uninstall ${DEFAULT_BRANDING.NAME} from this project. Removes CLI-managed skills (matched by marketplace), compiled agents, plugins, and the .claude-src/ config manifest (config.ts + config-types.ts). User-created content is preserved.`;
197
+ static description = `Uninstall ${DEFAULT_BRANDING.NAME} from this project. Removes CLI-managed skills (matched by marketplace), compiled agents, plugins, and the config manifest (config.ts + config-types.ts) this project keeps. User-created content is preserved.`;
187
198
  static examples = [
188
199
  "<%= config.bin %> <%= command.id %>",
189
200
  "<%= config.bin %> <%= command.id %> --yes"
@@ -193,18 +204,30 @@ var Uninstall = class _Uninstall extends BaseCommand {
193
204
  char: "y",
194
205
  description: "Skip confirmation prompt",
195
206
  default: false
196
- })
207
+ }),
208
+ provider: providerFlag()
197
209
  };
210
+ /**
211
+ * Starts at any terminal size. The size gate exists for the wizard's layout, and this command
212
+ * draws none — a plan and a one-line confirm fit any terminal — while it is the way out of every
213
+ * state, so a window too small to hold a wizard must not hold up an uninstall.
214
+ */
215
+ async ensureTerminalSize() {
216
+ }
198
217
  async run() {
199
218
  const { flags } = await this.parse(_Uninstall);
200
219
  const projectDir = process.cwd();
220
+ await refuseAnAmbiguousInstallation(
221
+ projectDir,
222
+ "uninstall",
223
+ providerNamedBy(flags.provider),
224
+ (message) => this.error(message, { exit: EXIT_CODES.INVALID_ARGS })
225
+ );
201
226
  this.brandingName = await this.resolveBrandingName(projectDir);
202
227
  this.printHeader();
203
228
  const target = await detectUninstallTarget(
204
229
  projectDir,
205
- (reason) => this.warn(
206
- `Could not read the project config \u2014 plugins and compiled agents it lists may be left behind: ${reason}`
207
- )
230
+ (failure) => this.warn(uninstallConfigUnreadable(failure))
208
231
  );
209
232
  const plan = buildRemovalPlan(target);
210
233
  if (!hasAnythingToRemove(plan)) {
@@ -249,6 +272,9 @@ var Uninstall = class _Uninstall extends BaseCommand {
249
272
  return true;
250
273
  }
251
274
  async confirmRemoval(plan) {
275
+ if (!process.stdin.isTTY) {
276
+ this.error(uninstallNeedsTerminal(), { exit: EXIT_CODES.ERROR });
277
+ }
252
278
  const outcome = await promptConfirm(({ onConfirm, onCancel }) => /* @__PURE__ */ jsx(
253
279
  RemovalPlanConfirm,
254
280
  {
@@ -289,7 +315,7 @@ var Uninstall = class _Uninstall extends BaseCommand {
289
315
  /**
290
316
  * Loads what updating registered projects needs (global config with its
291
317
  * projects[] registry, skills matrix, agent definitions) BEFORE the global
292
- * .claude-src manifest is deleted — source resolution reads that config.
318
+ * the config manifest is deleted — source resolution reads that config.
293
319
  * Returns null when nothing is registered or loading fails; a load failure
294
320
  * warns and never aborts the uninstall.
295
321
  *
@@ -302,20 +328,30 @@ var Uninstall = class _Uninstall extends BaseCommand {
302
328
  * local-installer.test.ts). Skipping avoids fetching every registered extra
303
329
  * source (network on a cold cache, plus unreachable-remote warnings) during
304
330
  * an uninstall that must never hang or noise-fail on remote state.
331
+ *
332
+ * `purpose: "upkeep"` because the prune only rewrites projects that are already installed: a
333
+ * marketplace that has since lost its manifest must not leave every registered project naming
334
+ * the global content this uninstall deletes.
305
335
  */
306
336
  async prepareGlobalPropagation(target, projectDir) {
337
+ if (target.config === null || target.registeredProjects.length === 0) return null;
307
338
  const globalConfig = target.config;
308
- if (!globalConfig?.projects?.length) return null;
309
339
  try {
310
340
  const [sourceResult, agentDefs] = await Promise.all([
311
341
  loadSkillsMatrixFromSource({
312
342
  projectDir,
343
+ purpose: "upkeep",
313
344
  skipExtraSources: true,
314
345
  matrixOnly: true
315
346
  }),
316
347
  loadAgentDefs()
317
348
  ]);
318
- return { globalConfig, matrix: sourceResult.matrix, agents: agentDefs.agents };
349
+ return {
350
+ globalConfig,
351
+ matrix: sourceResult.matrix,
352
+ agents: agentDefs.agents,
353
+ provider: providerInUse(projectDir)
354
+ };
319
355
  } catch (error) {
320
356
  this.warn(registeredProjectsUpdateFailed(getErrorMessage(error)));
321
357
  return null;
@@ -331,15 +367,18 @@ var Uninstall = class _Uninstall extends BaseCommand {
331
367
  */
332
368
  async updateRegisteredProjects(propagation) {
333
369
  try {
334
- const report = await propagateGlobalRemoval(propagation.globalConfig, {
335
- matrix: propagation.matrix,
336
- agents: propagation.agents
337
- });
338
- for (const skippedPath of report.propagated.skipped) {
370
+ const report = await propagateGlobalRemoval(
371
+ propagation.globalConfig,
372
+ { matrix: propagation.matrix, agents: propagation.agents },
373
+ propagation.provider
374
+ );
375
+ const { updated, unreadable, failed } = report.propagated;
376
+ this.reportProjectsOutOfReach(report.propagated);
377
+ for (const skippedPath of [...unreadable, ...failed]) {
339
378
  this.warn(registeredProjectUpdateSkipped(skippedPath));
340
379
  }
341
- if (report.propagated.updated.length === 0) return;
342
- this.logSuccess(registeredProjectsUpdated(report.propagated.updated.length));
380
+ if (updated.length === 0) return;
381
+ this.logSuccess(registeredProjectsUpdated(updated.length));
343
382
  this.reportPropagatedRecompile(report);
344
383
  } catch (error) {
345
384
  this.warn(registeredProjectsUpdateFailed(getErrorMessage(error)));
@@ -362,18 +401,35 @@ var Uninstall = class _Uninstall extends BaseCommand {
362
401
  for (const statement of plan.kept) {
363
402
  this.log(statement);
364
403
  }
365
- const cleanup = await cleanupEmptyDirs(target, planEntry(plan, "config"));
366
- if (cleanup.claudeSrcDirRemoved) {
367
- this.logSuccess(`Removed ${CLAUDE_SRC_DIR}/`);
368
- } else if (cleanup.claudeSrcManifestRemoved) {
369
- this.logSuccess(`Removed CLI config from ${CLAUDE_SRC_DIR}/`);
370
- }
404
+ const cleanup = await cleanupEmptyDirs(target, planEntries(plan, "config"));
405
+ this.reportSourceFolderCleanup(cleanup.sourceFolder);
406
+ this.reportSourceRootCleanup(target.sourceRoot, cleanup);
371
407
  if (cleanup.claudeDirRemoved) {
372
408
  this.logSuccess(`Removed ${CLAUDE_DIR}/`);
373
409
  } else if (cleanup.claudeDirKept) {
374
410
  this.log(`Kept ${CLAUDE_DIR}/ (contains user content)`);
375
411
  }
376
412
  }
413
+ /** What became of one source folder: gone, emptied of the CLI's files, or kept for the user's. */
414
+ reportSourceFolderCleanup(folder) {
415
+ if (folder.dirRemoved) {
416
+ this.logSuccess(`Removed ${folder.relName}/`);
417
+ } else if (folder.manifestRemoved) {
418
+ this.logSuccess(`Removed CLI config from ${folder.relName}/`);
419
+ } else if (folder.kept) {
420
+ this.log(`Kept ${folder.relName}/ (contains user content)`);
421
+ }
422
+ }
423
+ /** What became of the `.agents-inc/` parent, said out loud in both directions. */
424
+ reportSourceRootCleanup(sourceRoot, cleanup) {
425
+ if (cleanup.sourceRootRemoved) {
426
+ this.logSuccess(`Removed ${sourceRoot.relName}/`);
427
+ return;
428
+ }
429
+ if (cleanup.sourceRootKept) {
430
+ this.log(`Kept ${sourceRoot.relName}/ (contains user content)`);
431
+ }
432
+ }
377
433
  async removePlannedPlugins(entry, config, projectDir) {
378
434
  if (!entry) return;
379
435
  this.log("Uninstalling plugins...");
@@ -384,9 +440,11 @@ var Uninstall = class _Uninstall extends BaseCommand {
384
440
  projectDir,
385
441
  (name) => this.log(` Uninstalled plugin '${name}'`)
386
442
  );
387
- this.logSuccess(
388
- `Uninstalled ${pluginResult.totalUninstalled} ${pluginResult.totalUninstalled === 1 ? "plugin" : "plugins"}`
389
- );
443
+ if (pluginResult.totalUninstalled > 0) {
444
+ this.logSuccess(
445
+ `Uninstalled ${pluginResult.totalUninstalled} ${pluginResult.totalUninstalled === 1 ? "plugin" : "plugins"}`
446
+ );
447
+ }
390
448
  } catch (error) {
391
449
  this.log("Plugin uninstall failed");
392
450
  this.error(getErrorMessage(error), {
@@ -435,53 +493,69 @@ function getCliInstalledPluginKeys(config) {
435
493
  ])
436
494
  );
437
495
  }
438
- async function loadUninstallConfig(projectDir, onLoadFailed) {
496
+ async function loadUninstallConfig(configPath, projectDir, provider, onLoadFailed) {
439
497
  try {
440
- const result = await loadProjectConfigFromDir(projectDir);
498
+ const result = await loadProjectConfigAt(configPath, projectDir, provider);
441
499
  return result?.config ?? null;
442
500
  } catch (error) {
443
501
  if (!(error instanceof ConfigLoadError)) throw error;
444
- onLoadFailed(getErrorMessage(error));
502
+ onLoadFailed(error);
445
503
  return null;
446
504
  }
447
505
  }
506
+ async function readSourceFolder(folder, projectDir, provider, onConfigLoadFailed) {
507
+ const [manifestFiles, config] = await Promise.all([
508
+ manifestFilesIn(folder.dir),
509
+ loadUninstallConfig(
510
+ path.join(folder.dir, STANDARD_FILES.CONFIG_TS),
511
+ projectDir,
512
+ provider,
513
+ onConfigLoadFailed
514
+ )
515
+ ]);
516
+ return { ...folder, manifestFiles, config };
517
+ }
518
+ async function manifestFilesIn(dir) {
519
+ const manifest = [STANDARD_FILES.CONFIG_TS, STANDARD_FILES.CONFIG_TYPES_TS];
520
+ const present = await Promise.all(
521
+ manifest.map((fileName) => fileExists(path.join(dir, fileName)))
522
+ );
523
+ return manifest.filter((_, index) => present[index]);
524
+ }
525
+ function activeConfigOf(config) {
526
+ return {
527
+ ...config,
528
+ skills: config.skills.filter((s) => !s.excluded),
529
+ agents: config.agents.filter((a) => !a.excluded)
530
+ };
531
+ }
448
532
  async function detectUninstallTarget(projectDir, onConfigLoadFailed) {
449
533
  const pluginsDir = getProjectPluginsDir(projectDir);
450
534
  const { skillsDir, agentsDir } = resolveInstallPaths(projectDir);
451
535
  const claudeDir = path.join(projectDir, CLAUDE_DIR);
452
- const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);
453
- const claudeSrcConfigPath = path.join(claudeSrcDir, STANDARD_FILES.CONFIG_TS);
454
- const claudeSrcConfigTypesPath = path.join(claudeSrcDir, STANDARD_FILES.CONFIG_TYPES_TS);
455
- const [
456
- hasLocalSkills,
457
- hasLocalAgents,
458
- hasClaudeDir,
459
- hasClaudeSrcConfig,
460
- hasClaudeSrcConfigTypes,
461
- config,
462
- agentProvenance
463
- ] = await Promise.all([
536
+ const provider = providerInUse(projectDir);
537
+ const [hasLocalSkills, hasLocalAgents, hasClaudeDir, sourceFolder, agentProvenance] = await Promise.all([
464
538
  directoryExists(skillsDir),
465
539
  directoryExists(agentsDir),
466
540
  directoryExists(claudeDir),
467
- fileExists(claudeSrcConfigPath),
468
- fileExists(claudeSrcConfigTypesPath),
469
- loadUninstallConfig(projectDir, onConfigLoadFailed),
470
- splitAgentsByProvenance(agentsDir)
541
+ readSourceFolder(
542
+ sourceFolderInUse(projectDir, provider),
543
+ projectDir,
544
+ provider,
545
+ onConfigLoadFailed
546
+ ),
547
+ splitAgentsByProvenance(agentsDir, agentCodec(provider))
471
548
  ]);
549
+ const { config } = sourceFolder;
472
550
  let pluginNames = [];
473
551
  try {
474
552
  pluginNames = await listPluginNames(projectDir);
475
553
  } catch {
476
554
  }
477
- const activeConfig = config ? {
478
- ...config,
479
- skills: config.skills.filter((s) => !s.excluded),
480
- agents: config.agents.filter((a) => !a.excluded)
481
- } : null;
555
+ const activeConfig = config === null ? null : activeConfigOf(config);
482
556
  const configuredAgents = collectConfiguredAgents(activeConfig);
483
557
  const cliInstalledKeys = getCliInstalledPluginKeys(activeConfig);
484
- const cliPluginNames = pluginNames.filter((name) => cliInstalledKeys.has(name));
558
+ const cliPluginNames = thisRunOwnsAnyPlugin(projectDir) ? pluginNames.filter((name) => cliInstalledKeys.has(name)) : [];
485
559
  return {
486
560
  hasPlugins: cliPluginNames.length > 0,
487
561
  pluginNames,
@@ -489,19 +563,24 @@ async function detectUninstallTarget(projectDir, onConfigLoadFailed) {
489
563
  hasLocalSkills,
490
564
  hasLocalAgents,
491
565
  hasClaudeDir,
492
- hasClaudeSrcConfig,
493
- hasClaudeSrcConfigTypes,
494
566
  pluginsDir,
495
567
  skillsDir,
496
568
  agentsDir,
497
569
  claudeDir,
498
- claudeSrcDir,
570
+ sourceFolder,
571
+ sourceRoot: sourceRootOf(projectDir),
499
572
  config,
573
+ registeredProjects: config?.projects ?? [],
500
574
  configuredAgents,
575
+ agentCodec: agentCodec(provider),
501
576
  markedAgents: agentProvenance.marked,
502
577
  unmarkedAgents: agentProvenance.unmarked
503
578
  };
504
579
  }
580
+ function thisRunOwnsAnyPlugin(projectDir) {
581
+ if (isHomeDirectory(projectDir)) return true;
582
+ return hostAt(projectDir).installsProjectScopedPlugins;
583
+ }
505
584
  function shouldRemoveSkill(forkedFrom) {
506
585
  return forkedFrom !== null;
507
586
  }
@@ -545,10 +624,10 @@ async function cleanupSkillsDir(dir, allRemoved) {
545
624
  return removeDirIfEmpty(dir);
546
625
  }
547
626
  async function removeMatchingAgents(entry, onRemoved) {
548
- const agentFiles = await listAgentFiles(entry.agentsDir);
549
- const removedNames = agentFiles.map((agentFile) => agentFile.replace(/\.md$/, "")).filter((agentName) => entry.agentNames.includes(agentName));
627
+ const agentFiles = await listAgentFiles(entry.agentsDir, entry.codec);
628
+ const removedNames = agentFiles.map((agentFile) => path.basename(agentFile, entry.codec.extension)).filter((agentName) => entry.agentNames.includes(agentName));
550
629
  for (const agentName of removedNames) {
551
- await remove(path.join(entry.agentsDir, `${agentName}.md`));
630
+ await remove(path.join(entry.agentsDir, `${agentName}${entry.codec.extension}`));
552
631
  onRemoved?.(agentName);
553
632
  }
554
633
  const dirCleaned = await removeDirIfEmpty(entry.agentsDir);
@@ -558,45 +637,94 @@ async function removeMatchingAgents(entry, onRemoved) {
558
637
  dirCleaned
559
638
  };
560
639
  }
640
+ var SCOPE_OF_AN_UNRECORDED_SKILL = "project";
641
+ function pluginScopesToSweep(host, primary) {
642
+ const offered = host.offeredPlacements.filter((placement) => placement.mode === "plugin").map((placement) => placement.scope);
643
+ if (!offered.includes(primary)) return offered;
644
+ return [primary, ...offered.filter((scope) => scope !== primary)];
645
+ }
646
+ async function removePluginWhereverItIsFiled(host, pluginRef, primaryScope, projectDir) {
647
+ let outcome = "absent";
648
+ for (const scope of pluginScopesToSweep(host, primaryScope)) {
649
+ try {
650
+ const swept = await host.uninstallPlugin(pluginRef, scope, projectDir);
651
+ if (swept === "removed") outcome = "removed";
652
+ } catch {
653
+ }
654
+ }
655
+ return outcome;
656
+ }
561
657
  async function uninstallPlugins(entry, config, projectDir, onUninstalled) {
562
- const cliAvailable = await isClaudeCLIAvailable();
658
+ const host = hostAt(projectDir);
659
+ const hostAvailable = await host.isAvailable();
660
+ const observed = [];
563
661
  for (const pluginName of entry.names) {
564
- if (cliAvailable) {
565
- const skillId = parseMarketplacePluginRef(pluginName);
566
- const skillConfig = config?.skills.find((s) => s.id === skillId);
567
- const primaryScope = toClaudePluginScope(skillConfig?.scope);
568
- await claudePluginUninstallBestEffort(pluginName, primaryScope, projectDir);
662
+ const removal = hostAvailable ? await removePluginWhereverItIsFiled(
663
+ host,
664
+ pluginName,
665
+ scopeThePluginIsFiledUnder(config, pluginName),
666
+ projectDir
667
+ ) : nothingWasObserved();
668
+ await remove(path.join(entry.pluginsDir, pluginName));
669
+ if (removal === "removed") {
670
+ observed.push(pluginName);
671
+ onUninstalled?.(pluginName);
569
672
  }
570
- const pluginPath = path.join(entry.pluginsDir, pluginName);
571
- await remove(pluginPath);
572
- onUninstalled?.(pluginName);
573
673
  }
574
674
  return {
575
- uninstalledNames: entry.names,
576
- totalUninstalled: entry.names.length
675
+ uninstalledNames: observed,
676
+ totalUninstalled: observed.length
577
677
  };
578
678
  }
679
+ function scopeThePluginIsFiledUnder(config, pluginName) {
680
+ const skillId = parseMarketplacePluginRef(pluginName);
681
+ return config?.skills.find((skill) => skill.id === skillId)?.scope ?? SCOPE_OF_AN_UNRECORDED_SKILL;
682
+ }
683
+ function nothingWasObserved() {
684
+ return "absent";
685
+ }
579
686
  async function removeConfigManifest(entry) {
580
687
  if (!entry) return { manifestRemoved: false, dirRemoved: false };
581
688
  await Promise.all(
582
- entry.fileNames.map((fileName) => remove(path.join(entry.claudeSrcDir, fileName)))
689
+ entry.fileNames.map((fileName) => remove(path.join(entry.sourceDir, fileName)))
583
690
  );
584
- return { manifestRemoved: true, dirRemoved: await removeDirIfEmpty(entry.claudeSrcDir) };
691
+ return { manifestRemoved: true, dirRemoved: await removeDirIfEmpty(entry.sourceDir) };
585
692
  }
586
- async function cleanupEmptyDirs(target, manifestEntry) {
587
- const manifest = await removeConfigManifest(manifestEntry);
693
+ async function cleanupEmptyDirs(target, manifestEntries) {
694
+ const sourceFolder = await cleanupSourceFolder(
695
+ target.sourceFolder,
696
+ manifestEntries.find((entry) => entry.sourceDir === target.sourceFolder.dir)
697
+ );
698
+ const sourceRoot = await cleanupSourceRoot(target.sourceRoot, sourceFolder.dirRemoved);
588
699
  const claudeDirRemoved = target.hasClaudeDir && await removeDirIfEmpty(target.claudeDir);
589
700
  const claudeDirKept = !claudeDirRemoved && target.hasClaudeDir && await directoryExists(target.claudeDir);
590
701
  return {
591
702
  claudeDirRemoved,
592
- claudeSrcManifestRemoved: manifest.manifestRemoved,
593
- claudeSrcDirRemoved: manifest.dirRemoved,
703
+ sourceFolder,
704
+ sourceRootRemoved: sourceRoot.removed,
705
+ sourceRootKept: sourceRoot.kept,
594
706
  claudeDirKept
595
707
  };
596
708
  }
597
- async function listAgentFiles(agentsDir) {
709
+ async function cleanupSourceFolder(folder, entry) {
710
+ const manifest = await removeConfigManifest(entry);
711
+ const dirRemoved = manifest.dirRemoved || await removeDirIfEmpty(folder.dir);
712
+ const kept = !dirRemoved && await directoryExists(folder.dir);
713
+ return {
714
+ relName: folder.relName,
715
+ manifestRemoved: manifest.manifestRemoved,
716
+ dirRemoved,
717
+ kept
718
+ };
719
+ }
720
+ async function cleanupSourceRoot(sourceRoot, providerDirRemoved) {
721
+ if (!providerDirRemoved) return { removed: false, kept: false };
722
+ const removed = await removeDirIfEmpty(sourceRoot.dir);
723
+ return { removed, kept: !removed && await directoryExists(sourceRoot.dir) };
724
+ }
725
+ async function listAgentFiles(agentsDir, codec) {
598
726
  try {
599
- return await listAgentMdFiles(agentsDir);
727
+ return await listAgentFilesOf(agentsDir, codec);
600
728
  } catch {
601
729
  return [];
602
730
  }