agents-inc 0.153.0 → 0.154.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/{chunk-EFU6P3B7.js → chunk-2IMYK4WN.js} +3 -3
- package/dist/{chunk-U2YSGBHA.js → chunk-4VCWL2IG.js} +33 -16
- package/dist/chunk-4VCWL2IG.js.map +1 -0
- package/dist/{chunk-ORJ5Y222.js → chunk-5MFJ24VM.js} +90 -24
- package/dist/chunk-5MFJ24VM.js.map +1 -0
- package/dist/{chunk-TY6CAOL7.js → chunk-7VZV4O6B.js} +3 -3
- package/dist/{chunk-4VYALFQZ.js → chunk-AKQ5QISO.js} +6 -6
- package/dist/{chunk-U2DNAHFE.js → chunk-AURY6RT6.js} +3 -3
- package/dist/{chunk-ACKC577F.js → chunk-B66SC72V.js} +3 -3
- package/dist/{chunk-WDAO3RUY.js → chunk-BZ4CZBOM.js} +3 -3
- package/dist/{chunk-NXQAY5U7.js → chunk-CBF4ZYV3.js} +4556 -4457
- package/dist/chunk-CBF4ZYV3.js.map +1 -0
- package/dist/{chunk-JFAUQDZM.js → chunk-CHNA5RVS.js} +3 -3
- package/dist/{chunk-2HC2SNRP.js → chunk-DRKSYJZ2.js} +1 -5
- package/dist/chunk-DRKSYJZ2.js.map +1 -0
- package/dist/{chunk-X5XJ6WKO.js → chunk-FMYHWKGG.js} +45 -4
- package/dist/chunk-FMYHWKGG.js.map +1 -0
- package/dist/{chunk-K7PJDWER.js → chunk-GUDGCFSF.js} +6 -6
- package/dist/{chunk-35VOK7XE.js → chunk-IPJOMAWC.js} +4355 -4355
- package/dist/{chunk-35VOK7XE.js.map → chunk-IPJOMAWC.js.map} +1 -1
- package/dist/{chunk-VGEBYCQZ.js → chunk-IXEDSKMH.js} +4 -15
- package/dist/chunk-IXEDSKMH.js.map +1 -0
- package/dist/{chunk-ZNDLUWWD.js → chunk-LA3JPESW.js} +3 -3
- package/dist/{chunk-M5HSTNYU.js → chunk-MJFIO5SX.js} +5 -23
- package/dist/chunk-MJFIO5SX.js.map +1 -0
- package/dist/{chunk-VECFAKM5.js → chunk-NFH6SA62.js} +4 -4
- package/dist/{chunk-R4SEU3DF.js → chunk-NKCY2ULI.js} +2 -2
- package/dist/{chunk-IO4VEW5U.js → chunk-ONWEOS77.js} +2 -2
- package/dist/{chunk-FRWKCE6R.js → chunk-PRJD5MMQ.js} +3 -3
- package/dist/{chunk-HEBPKK5L.js → chunk-QQTYMW7N.js} +11 -23
- package/dist/chunk-QQTYMW7N.js.map +1 -0
- package/dist/{chunk-KET3EVGX.js → chunk-QUDQTO3O.js} +3 -3
- package/dist/{chunk-BMGBA6HJ.js → chunk-R7JV22QK.js} +12 -12
- package/dist/{chunk-FIHTAFST.js → chunk-TUQF577Z.js} +30 -30
- package/dist/{chunk-FIHTAFST.js.map → chunk-TUQF577Z.js.map} +1 -1
- package/dist/{chunk-NXGMM5YN.js → chunk-UW44KSYL.js} +3 -3
- package/dist/{chunk-WG6V6VJV.js → chunk-WRRP47PY.js} +2 -2
- package/dist/{chunk-F7Z5I6GU.js → chunk-XMEIVWAS.js} +4 -4
- package/dist/{chunk-REKOWTIB.js → chunk-ZU6DAR4S.js} +42 -8
- package/dist/chunk-ZU6DAR4S.js.map +1 -0
- package/dist/commands/build/marketplace.js +6 -5
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +6 -6
- package/dist/commands/compile.js +48 -10
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +10 -10
- package/dist/commands/edit.js +93 -59
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +10 -10
- package/dist/commands/init.js +29 -29
- package/dist/commands/list.js +7 -7
- package/dist/commands/search.js +29 -21
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +198 -147
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +5 -5
- package/dist/components/wizard/category-grid.js +3 -3
- package/dist/components/wizard/checkbox-grid.js +2 -2
- package/dist/components/wizard/domain-selection.js +8 -8
- package/dist/components/wizard/run-wizard-session.js +21 -21
- package/dist/components/wizard/skill-agent-summary.js +5 -5
- package/dist/components/wizard/source-grid.js +3 -3
- package/dist/components/wizard/stack-selection.js +5 -5
- package/dist/components/wizard/step-agents.js +8 -8
- package/dist/components/wizard/step-build.js +7 -7
- package/dist/components/wizard/step-confirm.js +8 -8
- package/dist/components/wizard/step-sources.js +7 -7
- package/dist/components/wizard/step-stack.js +6 -6
- package/dist/components/wizard/summary-panel.js +7 -7
- package/dist/components/wizard/wizard-layout.js +9 -9
- package/dist/components/wizard/wizard.js +20 -20
- package/dist/copy-local-skills-WVHJFRPK.js +14 -0
- package/dist/hooks/init.js +29 -29
- package/dist/load-agent-defs-5OT54J5M.js +15 -0
- package/dist/{loader-4U7UCE2Y.js → loader-JIZDTR4G.js} +2 -2
- package/dist/recompile-project-agents-VREEPBDV.js +20 -0
- package/dist/{source-loader-ZNSYJJCI.js → source-loader-OE6EJFPU.js} +4 -4
- package/dist/stores/wizard-store.js +4 -4
- package/package.json +1 -1
- package/src/schemas/plugin.schema.json +3 -0
- package/dist/chunk-2HC2SNRP.js.map +0 -1
- package/dist/chunk-HEBPKK5L.js.map +0 -1
- package/dist/chunk-M5HSTNYU.js.map +0 -1
- package/dist/chunk-NXQAY5U7.js.map +0 -1
- package/dist/chunk-ORJ5Y222.js.map +0 -1
- package/dist/chunk-REKOWTIB.js.map +0 -1
- package/dist/chunk-U2YSGBHA.js.map +0 -1
- package/dist/chunk-VGEBYCQZ.js.map +0 -1
- package/dist/chunk-X5XJ6WKO.js.map +0 -1
- package/dist/copy-local-skills-KF2RAVD3.js +0 -14
- package/dist/load-agent-defs-DGXGBU3Q.js +0 -15
- package/dist/recompile-project-agents-CJVBAWDJ.js +0 -20
- /package/dist/{chunk-EFU6P3B7.js.map → chunk-2IMYK4WN.js.map} +0 -0
- /package/dist/{chunk-TY6CAOL7.js.map → chunk-7VZV4O6B.js.map} +0 -0
- /package/dist/{chunk-4VYALFQZ.js.map → chunk-AKQ5QISO.js.map} +0 -0
- /package/dist/{chunk-U2DNAHFE.js.map → chunk-AURY6RT6.js.map} +0 -0
- /package/dist/{chunk-ACKC577F.js.map → chunk-B66SC72V.js.map} +0 -0
- /package/dist/{chunk-WDAO3RUY.js.map → chunk-BZ4CZBOM.js.map} +0 -0
- /package/dist/{chunk-JFAUQDZM.js.map → chunk-CHNA5RVS.js.map} +0 -0
- /package/dist/{chunk-K7PJDWER.js.map → chunk-GUDGCFSF.js.map} +0 -0
- /package/dist/{chunk-ZNDLUWWD.js.map → chunk-LA3JPESW.js.map} +0 -0
- /package/dist/{chunk-VECFAKM5.js.map → chunk-NFH6SA62.js.map} +0 -0
- /package/dist/{chunk-R4SEU3DF.js.map → chunk-NKCY2ULI.js.map} +0 -0
- /package/dist/{chunk-IO4VEW5U.js.map → chunk-ONWEOS77.js.map} +0 -0
- /package/dist/{chunk-FRWKCE6R.js.map → chunk-PRJD5MMQ.js.map} +0 -0
- /package/dist/{chunk-KET3EVGX.js.map → chunk-QUDQTO3O.js.map} +0 -0
- /package/dist/{chunk-BMGBA6HJ.js.map → chunk-R7JV22QK.js.map} +0 -0
- /package/dist/{chunk-NXGMM5YN.js.map → chunk-UW44KSYL.js.map} +0 -0
- /package/dist/{chunk-WG6V6VJV.js.map → chunk-WRRP47PY.js.map} +0 -0
- /package/dist/{chunk-F7Z5I6GU.js.map → chunk-XMEIVWAS.js.map} +0 -0
- /package/dist/{copy-local-skills-KF2RAVD3.js.map → copy-local-skills-WVHJFRPK.js.map} +0 -0
- /package/dist/{load-agent-defs-DGXGBU3Q.js.map → load-agent-defs-5OT54J5M.js.map} +0 -0
- /package/dist/{loader-4U7UCE2Y.js.map → loader-JIZDTR4G.js.map} +0 -0
- /package/dist/{recompile-project-agents-CJVBAWDJ.js.map → recompile-project-agents-VREEPBDV.js.map} +0 -0
- /package/dist/{source-loader-ZNSYJJCI.js.map → source-loader-OE6EJFPU.js.map} +0 -0
|
@@ -5,28 +5,31 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
promptConfirm
|
|
7
7
|
} from "../chunk-OJJLYHM3.js";
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-XMEIVWAS.js";
|
|
9
|
+
import "../chunk-ZU6DAR4S.js";
|
|
10
|
+
import "../chunk-UW44KSYL.js";
|
|
11
11
|
import {
|
|
12
12
|
loadAgentDefs
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-PRJD5MMQ.js";
|
|
14
14
|
import {
|
|
15
15
|
listAgentMdFiles
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-TUQF577Z.js";
|
|
17
17
|
import "../chunk-JFLVEFFP.js";
|
|
18
18
|
import {
|
|
19
19
|
BaseCommand,
|
|
20
20
|
EXIT_CODES
|
|
21
|
-
} from "../chunk-
|
|
22
|
-
import "../chunk-
|
|
21
|
+
} from "../chunk-FMYHWKGG.js";
|
|
22
|
+
import "../chunk-7VZV4O6B.js";
|
|
23
23
|
import "../chunk-K3O3YQYG.js";
|
|
24
24
|
import {
|
|
25
25
|
ConfigLoadError,
|
|
26
26
|
INFO_MESSAGES,
|
|
27
27
|
SUCCESS_MESSAGES,
|
|
28
|
+
UNINSTALL_PLAN,
|
|
28
29
|
buildMarketplacePluginRef,
|
|
29
30
|
claudePluginUninstallBestEffort,
|
|
31
|
+
compiledAgentsKept,
|
|
32
|
+
compiledAgentsRemoval,
|
|
30
33
|
getProjectPluginsDir,
|
|
31
34
|
isClaudeCLIAvailable,
|
|
32
35
|
isHomeDirectory,
|
|
@@ -34,6 +37,7 @@ import {
|
|
|
34
37
|
listPluginNames,
|
|
35
38
|
loadProjectConfigFromDir,
|
|
36
39
|
loadSkillsMatrixFromSource,
|
|
40
|
+
localSkillsRemoval,
|
|
37
41
|
mutateGlobal,
|
|
38
42
|
parseMarketplacePluginRef,
|
|
39
43
|
propagateGlobalRemoval,
|
|
@@ -43,15 +47,16 @@ import {
|
|
|
43
47
|
registeredProjectsUpdated,
|
|
44
48
|
resolveInstallPaths,
|
|
45
49
|
toClaudePluginScope
|
|
46
|
-
} from "../chunk-
|
|
50
|
+
} from "../chunk-CBF4ZYV3.js";
|
|
47
51
|
import {
|
|
48
52
|
directoryExists,
|
|
49
53
|
fileExists,
|
|
50
54
|
getErrorMessage,
|
|
51
55
|
listDirectories,
|
|
52
|
-
remove
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
remove,
|
|
57
|
+
removeDirIfEmpty
|
|
58
|
+
} from "../chunk-4VCWL2IG.js";
|
|
59
|
+
import "../chunk-IPJOMAWC.js";
|
|
55
60
|
import "../chunk-VASLW636.js";
|
|
56
61
|
import {
|
|
57
62
|
CLAUDE_DIR,
|
|
@@ -67,39 +72,104 @@ import "../chunk-VZRO7RYT.js";
|
|
|
67
72
|
import "react";
|
|
68
73
|
import { partition } from "remeda";
|
|
69
74
|
import path from "path";
|
|
70
|
-
import { readdir } from "fs/promises";
|
|
71
75
|
import { Flags } from "@oclif/core";
|
|
72
76
|
import { Box, Text, useApp } from "ink";
|
|
73
77
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
74
78
|
function buildRemovalPlan(target) {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
79
|
+
const agents = compiledAgentsEntry(target);
|
|
80
|
+
return {
|
|
81
|
+
entries: [
|
|
82
|
+
...pluginsEntry(target),
|
|
83
|
+
...localSkillsEntry(target),
|
|
84
|
+
...agents,
|
|
85
|
+
...configManifestEntry(target)
|
|
86
|
+
],
|
|
87
|
+
kept: keptStatements(target, agents)
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function hasAnythingToRemove(plan) {
|
|
91
|
+
return plan.entries.length > 0;
|
|
92
|
+
}
|
|
93
|
+
function pluginsEntry(target) {
|
|
94
|
+
if (!target.hasPlugins) return [];
|
|
95
|
+
return [{ kind: "plugins", pluginsDir: target.pluginsDir, names: [...target.cliPluginNames] }];
|
|
96
|
+
}
|
|
97
|
+
function localSkillsEntry(target) {
|
|
98
|
+
if (!target.hasLocalSkills) return [];
|
|
99
|
+
return [{ kind: "skills", skillsDir: target.skillsDir }];
|
|
100
|
+
}
|
|
101
|
+
function compiledAgentsEntry(target) {
|
|
102
|
+
if (!target.hasLocalAgents) return [];
|
|
103
|
+
if (target.configuredAgents.length === 0) return [];
|
|
104
|
+
return [{ kind: "agents", agentsDir: target.agentsDir, agentNames: target.configuredAgents }];
|
|
105
|
+
}
|
|
106
|
+
function configManifestEntry(target) {
|
|
107
|
+
const fileNames = [
|
|
108
|
+
...target.hasClaudeSrcConfig ? [STANDARD_FILES.CONFIG_TS] : [],
|
|
109
|
+
...target.hasClaudeSrcConfigTypes ? [STANDARD_FILES.CONFIG_TYPES_TS] : []
|
|
110
|
+
];
|
|
111
|
+
if (fileNames.length === 0) return [];
|
|
112
|
+
return [{ kind: "config", claudeSrcDir: target.claudeSrcDir, fileNames }];
|
|
113
|
+
}
|
|
114
|
+
function keptStatements(target, agentRemovals) {
|
|
115
|
+
if (!target.hasLocalAgents) return [];
|
|
116
|
+
if (agentRemovals.length > 0) return [];
|
|
117
|
+
return [compiledAgentsKept(target.agentsDir)];
|
|
118
|
+
}
|
|
119
|
+
function planEntry(plan, kind) {
|
|
120
|
+
return plan.entries.find(
|
|
121
|
+
(entry) => entry.kind === kind
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
function describeEntry(entry) {
|
|
125
|
+
switch (entry.kind) {
|
|
126
|
+
case "plugins":
|
|
127
|
+
return { label: UNINSTALL_PLAN.PLUGINS_HEADING, items: entry.names };
|
|
128
|
+
case "skills":
|
|
129
|
+
return {
|
|
130
|
+
label: UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,
|
|
131
|
+
items: [localSkillsRemoval(entry.skillsDir)]
|
|
132
|
+
};
|
|
133
|
+
case "agents":
|
|
134
|
+
return {
|
|
135
|
+
label: UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,
|
|
136
|
+
items: [compiledAgentsRemoval(entry.agentsDir)]
|
|
137
|
+
};
|
|
138
|
+
case "config":
|
|
139
|
+
return {
|
|
140
|
+
label: UNINSTALL_PLAN.CONFIG_HEADING,
|
|
141
|
+
items: entry.fileNames.map((fileName) => `${entry.claudeSrcDir}/${fileName}`)
|
|
142
|
+
};
|
|
143
|
+
default: {
|
|
144
|
+
const _exhaustive = entry;
|
|
145
|
+
return _exhaustive;
|
|
92
146
|
}
|
|
93
|
-
sections.push({ label: "Config:", items });
|
|
94
147
|
}
|
|
95
|
-
return sections;
|
|
96
148
|
}
|
|
97
|
-
var
|
|
149
|
+
var PLAN_SECTION_ORDER = [
|
|
150
|
+
UNINSTALL_PLAN.PLUGINS_HEADING,
|
|
151
|
+
UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,
|
|
152
|
+
UNINSTALL_PLAN.CONFIG_HEADING
|
|
153
|
+
];
|
|
154
|
+
function planSections(entries) {
|
|
155
|
+
const described = entries.map(describeEntry);
|
|
156
|
+
return PLAN_SECTION_ORDER.flatMap(
|
|
157
|
+
(label) => sectionWithItems(label, itemsUnder(described, label))
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
function itemsUnder(described, label) {
|
|
161
|
+
return described.filter((section) => section.label === label).flatMap((section) => section.items);
|
|
162
|
+
}
|
|
163
|
+
function sectionWithItems(label, items) {
|
|
164
|
+
if (items.length === 0) return [];
|
|
165
|
+
return [{ label, items }];
|
|
166
|
+
}
|
|
167
|
+
var UninstallConfirm = ({ plan, onConfirm, onCancel }) => {
|
|
98
168
|
const { exit } = useApp();
|
|
99
169
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
100
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children:
|
|
170
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: UNINSTALL_PLAN.PREVIEW_HEADING }),
|
|
101
171
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
102
|
-
|
|
172
|
+
planSections(plan.entries).map((section) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
103
173
|
/* @__PURE__ */ jsxs(Text, { color: CLI_COLORS.ERROR, children: [
|
|
104
174
|
" ",
|
|
105
175
|
section.label
|
|
@@ -109,6 +179,10 @@ var UninstallConfirm = ({ target, onConfirm, onCancel }) => {
|
|
|
109
179
|
item
|
|
110
180
|
] }, item))
|
|
111
181
|
] }, section.label)),
|
|
182
|
+
plan.kept.map((statement) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
183
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
184
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: statement })
|
|
185
|
+
] }, statement)),
|
|
112
186
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
113
187
|
/* @__PURE__ */ jsx(
|
|
114
188
|
Confirm,
|
|
@@ -151,17 +225,18 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
151
225
|
`Could not read the project config \u2014 plugins and compiled agents it lists may be left behind: ${reason}`
|
|
152
226
|
)
|
|
153
227
|
);
|
|
154
|
-
|
|
228
|
+
const plan = buildRemovalPlan(target);
|
|
229
|
+
if (!hasAnythingToRemove(plan)) {
|
|
155
230
|
this.reportNothingToUninstall();
|
|
156
231
|
return;
|
|
157
232
|
}
|
|
158
|
-
const confirmed = flags.yes ? this.printRemovalPlan(
|
|
233
|
+
const confirmed = flags.yes ? this.printRemovalPlan(plan) : await this.confirmRemoval(plan);
|
|
159
234
|
if (!confirmed) {
|
|
160
235
|
this.log("");
|
|
161
236
|
this.log("Uninstall cancelled");
|
|
162
237
|
this.exit(EXIT_CODES.CANCELLED);
|
|
163
238
|
}
|
|
164
|
-
await this.executeUninstall(target, projectDir);
|
|
239
|
+
await this.executeUninstall(plan, target, projectDir);
|
|
165
240
|
this.reportSuccess();
|
|
166
241
|
}
|
|
167
242
|
printHeader() {
|
|
@@ -176,45 +251,32 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
176
251
|
this.log("");
|
|
177
252
|
this.log(INFO_MESSAGES.NO_CHANGES_MADE);
|
|
178
253
|
}
|
|
179
|
-
printRemovalPlan(
|
|
180
|
-
this.log(
|
|
254
|
+
printRemovalPlan(plan) {
|
|
255
|
+
this.log(UNINSTALL_PLAN.PREVIEW_HEADING);
|
|
181
256
|
this.log("");
|
|
182
|
-
for (const section of
|
|
257
|
+
for (const section of planSections(plan.entries)) {
|
|
183
258
|
this.log(` ${section.label}`);
|
|
184
259
|
for (const item of section.items) {
|
|
185
260
|
this.log(` ${item}`);
|
|
186
261
|
}
|
|
187
262
|
}
|
|
263
|
+
for (const statement of plan.kept) {
|
|
264
|
+
this.log("");
|
|
265
|
+
this.log(statement);
|
|
266
|
+
}
|
|
188
267
|
this.log("");
|
|
189
268
|
return true;
|
|
190
269
|
}
|
|
191
|
-
async confirmRemoval(
|
|
192
|
-
const outcome = await promptConfirm(({ onConfirm, onCancel }) => /* @__PURE__ */ jsx(UninstallConfirm, {
|
|
270
|
+
async confirmRemoval(plan) {
|
|
271
|
+
const outcome = await promptConfirm(({ onConfirm, onCancel }) => /* @__PURE__ */ jsx(UninstallConfirm, { plan, onConfirm, onCancel }));
|
|
193
272
|
return outcome === "confirmed";
|
|
194
273
|
}
|
|
195
|
-
async executeUninstall(target, projectDir) {
|
|
274
|
+
async executeUninstall(plan, target, projectDir) {
|
|
196
275
|
const isGlobalUninstall = isHomeDirectory(projectDir);
|
|
197
276
|
const propagation = isGlobalUninstall ? await this.prepareGlobalPropagation(target, projectDir) : null;
|
|
198
|
-
|
|
199
|
-
this.log("Uninstalling plugins...");
|
|
200
|
-
try {
|
|
201
|
-
const pluginResult = await uninstallPlugins(
|
|
202
|
-
target,
|
|
203
|
-
projectDir,
|
|
204
|
-
(name) => this.log(` Uninstalled plugin '${name}'`)
|
|
205
|
-
);
|
|
206
|
-
this.logSuccess(
|
|
207
|
-
`Uninstalled ${pluginResult.totalUninstalled} ${pluginResult.totalUninstalled === 1 ? "plugin" : "plugins"}`
|
|
208
|
-
);
|
|
209
|
-
} catch (error) {
|
|
210
|
-
this.log("Plugin uninstall failed");
|
|
211
|
-
this.error(getErrorMessage(error), {
|
|
212
|
-
exit: EXIT_CODES.ERROR
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
277
|
+
await this.removePlannedPlugins(planEntry(plan, "plugins"), target.config, projectDir);
|
|
216
278
|
try {
|
|
217
|
-
await this.removeLocalFiles(target);
|
|
279
|
+
await this.removeLocalFiles(plan, target);
|
|
218
280
|
} catch (error) {
|
|
219
281
|
this.log("Failed to remove local files");
|
|
220
282
|
this.error(getErrorMessage(error), {
|
|
@@ -299,27 +361,14 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
299
361
|
this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);
|
|
300
362
|
this.log("");
|
|
301
363
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
);
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
`Removed ${skillResult.removedCount} CLI-installed ${skillResult.removedCount === 1 ? "skill" : "skills"}`
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
const agentResult = await removeMatchingAgents(
|
|
314
|
-
target,
|
|
315
|
-
(agentName) => this.log(` Uninstalled agent '${agentName}'`)
|
|
316
|
-
);
|
|
317
|
-
if (agentResult.removedCount > 0) {
|
|
318
|
-
this.logSuccess(
|
|
319
|
-
`Removed ${agentResult.removedCount} compiled ${agentResult.removedCount === 1 ? "agent" : "agents"}`
|
|
320
|
-
);
|
|
321
|
-
}
|
|
322
|
-
const cleanup = await cleanupEmptyDirs(target);
|
|
364
|
+
/**
|
|
365
|
+
* Each step acts only when the plan carries its entry, so what the user was shown and
|
|
366
|
+
* what this run removes are the same list read twice.
|
|
367
|
+
*/
|
|
368
|
+
async removeLocalFiles(plan, target) {
|
|
369
|
+
await this.removePlannedSkills(planEntry(plan, "skills"));
|
|
370
|
+
await this.removePlannedAgents(planEntry(plan, "agents"));
|
|
371
|
+
const cleanup = await cleanupEmptyDirs(target, planEntry(plan, "config"));
|
|
323
372
|
if (cleanup.claudeSrcDirRemoved) {
|
|
324
373
|
this.logSuccess(`Removed ${CLAUDE_SRC_DIR}/`);
|
|
325
374
|
} else if (cleanup.claudeSrcManifestRemoved) {
|
|
@@ -331,10 +380,50 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
331
380
|
this.log(`Kept ${CLAUDE_DIR}/ (contains user content)`);
|
|
332
381
|
}
|
|
333
382
|
}
|
|
383
|
+
async removePlannedPlugins(entry, config, projectDir) {
|
|
384
|
+
if (!entry) return;
|
|
385
|
+
this.log("Uninstalling plugins...");
|
|
386
|
+
try {
|
|
387
|
+
const pluginResult = await uninstallPlugins(
|
|
388
|
+
entry,
|
|
389
|
+
config,
|
|
390
|
+
projectDir,
|
|
391
|
+
(name) => this.log(` Uninstalled plugin '${name}'`)
|
|
392
|
+
);
|
|
393
|
+
this.logSuccess(
|
|
394
|
+
`Uninstalled ${pluginResult.totalUninstalled} ${pluginResult.totalUninstalled === 1 ? "plugin" : "plugins"}`
|
|
395
|
+
);
|
|
396
|
+
} catch (error) {
|
|
397
|
+
this.log("Plugin uninstall failed");
|
|
398
|
+
this.error(getErrorMessage(error), {
|
|
399
|
+
exit: EXIT_CODES.ERROR
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
async removePlannedSkills(entry) {
|
|
404
|
+
if (!entry) return;
|
|
405
|
+
const result = await removeMatchingSkills(
|
|
406
|
+
entry,
|
|
407
|
+
(dirName) => this.log(` Uninstalled skill '${dirName}'`),
|
|
408
|
+
(dirName) => this.warn(`Skipping '${dirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`)
|
|
409
|
+
);
|
|
410
|
+
if (result.removedCount === 0) return;
|
|
411
|
+
this.logSuccess(
|
|
412
|
+
`Removed ${result.removedCount} CLI-installed ${result.removedCount === 1 ? "skill" : "skills"}`
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
async removePlannedAgents(entry) {
|
|
416
|
+
if (!entry) return;
|
|
417
|
+
const result = await removeMatchingAgents(
|
|
418
|
+
entry,
|
|
419
|
+
(agentName) => this.log(` Uninstalled agent '${agentName}'`)
|
|
420
|
+
);
|
|
421
|
+
if (result.removedCount === 0) return;
|
|
422
|
+
this.logSuccess(
|
|
423
|
+
`Removed ${result.removedCount} compiled ${result.removedCount === 1 ? "agent" : "agents"}`
|
|
424
|
+
);
|
|
425
|
+
}
|
|
334
426
|
};
|
|
335
|
-
function hasAnythingToRemove(target) {
|
|
336
|
-
return target.hasPlugins || target.hasLocalSkills || target.hasLocalAgents || target.hasClaudeSrcConfig || target.hasClaudeSrcConfigTypes;
|
|
337
|
-
}
|
|
338
427
|
function collectConfiguredAgents(config) {
|
|
339
428
|
if (!config?.agents) return [];
|
|
340
429
|
return config.agents.map((a) => a.name);
|
|
@@ -418,24 +507,15 @@ async function detectUninstallTarget(projectDir, onConfigLoadFailed) {
|
|
|
418
507
|
function shouldRemoveSkill(forkedFrom) {
|
|
419
508
|
return forkedFrom !== null;
|
|
420
509
|
}
|
|
421
|
-
async function removeMatchingSkills(
|
|
422
|
-
|
|
423
|
-
return {
|
|
424
|
-
removedCount: 0,
|
|
425
|
-
skippedCount: 0,
|
|
426
|
-
removedNames: [],
|
|
427
|
-
skippedNames: [],
|
|
428
|
-
dirCleaned: false
|
|
429
|
-
};
|
|
430
|
-
}
|
|
431
|
-
const classified = await classifySkillDirs(target.skillsDir);
|
|
510
|
+
async function removeMatchingSkills(entry, onRemoved, onSkipped) {
|
|
511
|
+
const classified = await classifySkillDirs(entry.skillsDir);
|
|
432
512
|
const removedNames = await removeClassifiedSkills(
|
|
433
513
|
classified.toRemove,
|
|
434
|
-
|
|
514
|
+
entry.skillsDir,
|
|
435
515
|
onRemoved
|
|
436
516
|
);
|
|
437
517
|
classified.toSkip.forEach((name) => onSkipped?.(name));
|
|
438
|
-
const dirCleaned = await cleanupSkillsDir(
|
|
518
|
+
const dirCleaned = await cleanupSkillsDir(entry.skillsDir, classified.toSkip.length === 0);
|
|
439
519
|
return {
|
|
440
520
|
removedCount: removedNames.length,
|
|
441
521
|
skippedCount: classified.toSkip.length,
|
|
@@ -466,68 +546,47 @@ async function cleanupSkillsDir(dir, allRemoved) {
|
|
|
466
546
|
if (!allRemoved) return false;
|
|
467
547
|
return removeDirIfEmpty(dir);
|
|
468
548
|
}
|
|
469
|
-
async function
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
await remove(dir);
|
|
473
|
-
return true;
|
|
474
|
-
}
|
|
475
|
-
async function removeMatchingAgents(target, onRemoved) {
|
|
476
|
-
if (!target.hasLocalAgents) {
|
|
477
|
-
return { removedCount: 0, removedNames: [], dirCleaned: false };
|
|
478
|
-
}
|
|
479
|
-
if (target.configuredAgents.length === 0) {
|
|
480
|
-
return { removedCount: 0, removedNames: [], dirCleaned: false };
|
|
481
|
-
}
|
|
482
|
-
const agentFiles = await listAgentFiles(target.agentsDir);
|
|
483
|
-
const removedNames = agentFiles.map((agentFile) => agentFile.replace(/\.md$/, "")).filter((agentName) => target.configuredAgents.includes(agentName));
|
|
549
|
+
async function removeMatchingAgents(entry, onRemoved) {
|
|
550
|
+
const agentFiles = await listAgentFiles(entry.agentsDir);
|
|
551
|
+
const removedNames = agentFiles.map((agentFile) => agentFile.replace(/\.md$/, "")).filter((agentName) => entry.agentNames.includes(agentName));
|
|
484
552
|
for (const agentName of removedNames) {
|
|
485
|
-
await remove(path.join(
|
|
553
|
+
await remove(path.join(entry.agentsDir, `${agentName}.md`));
|
|
486
554
|
onRemoved?.(agentName);
|
|
487
555
|
}
|
|
488
|
-
const dirCleaned = await removeDirIfEmpty(
|
|
556
|
+
const dirCleaned = await removeDirIfEmpty(entry.agentsDir);
|
|
489
557
|
return {
|
|
490
558
|
removedCount: removedNames.length,
|
|
491
559
|
removedNames,
|
|
492
560
|
dirCleaned
|
|
493
561
|
};
|
|
494
562
|
}
|
|
495
|
-
async function uninstallPlugins(
|
|
496
|
-
if (!target.hasPlugins) {
|
|
497
|
-
return { uninstalledNames: [], totalUninstalled: 0 };
|
|
498
|
-
}
|
|
563
|
+
async function uninstallPlugins(entry, config, projectDir, onUninstalled) {
|
|
499
564
|
const cliAvailable = await isClaudeCLIAvailable();
|
|
500
|
-
for (const pluginName of
|
|
565
|
+
for (const pluginName of entry.names) {
|
|
501
566
|
if (cliAvailable) {
|
|
502
567
|
const skillId = parseMarketplacePluginRef(pluginName);
|
|
503
|
-
const skillConfig =
|
|
568
|
+
const skillConfig = config?.skills.find((s) => s.id === skillId);
|
|
504
569
|
const primaryScope = toClaudePluginScope(skillConfig?.scope);
|
|
505
570
|
await claudePluginUninstallBestEffort(pluginName, primaryScope, projectDir);
|
|
506
571
|
}
|
|
507
|
-
const pluginPath = path.join(
|
|
572
|
+
const pluginPath = path.join(entry.pluginsDir, pluginName);
|
|
508
573
|
await remove(pluginPath);
|
|
509
574
|
onUninstalled?.(pluginName);
|
|
510
575
|
}
|
|
511
576
|
return {
|
|
512
|
-
uninstalledNames:
|
|
513
|
-
totalUninstalled:
|
|
577
|
+
uninstalledNames: entry.names,
|
|
578
|
+
totalUninstalled: entry.names.length
|
|
514
579
|
};
|
|
515
580
|
}
|
|
516
|
-
async function removeConfigManifest(
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
}
|
|
522
|
-
if (target.hasClaudeSrcConfigTypes) {
|
|
523
|
-
await remove(path.join(target.claudeSrcDir, STANDARD_FILES.CONFIG_TYPES_TS));
|
|
524
|
-
manifestRemoved = true;
|
|
525
|
-
}
|
|
526
|
-
const dirRemoved = manifestRemoved && await removeDirIfEmpty(target.claudeSrcDir);
|
|
527
|
-
return { manifestRemoved, dirRemoved };
|
|
581
|
+
async function removeConfigManifest(entry) {
|
|
582
|
+
if (!entry) return { manifestRemoved: false, dirRemoved: false };
|
|
583
|
+
await Promise.all(
|
|
584
|
+
entry.fileNames.map((fileName) => remove(path.join(entry.claudeSrcDir, fileName)))
|
|
585
|
+
);
|
|
586
|
+
return { manifestRemoved: true, dirRemoved: await removeDirIfEmpty(entry.claudeSrcDir) };
|
|
528
587
|
}
|
|
529
|
-
async function cleanupEmptyDirs(target) {
|
|
530
|
-
const manifest = await removeConfigManifest(
|
|
588
|
+
async function cleanupEmptyDirs(target, manifestEntry) {
|
|
589
|
+
const manifest = await removeConfigManifest(manifestEntry);
|
|
531
590
|
const claudeDirRemoved = target.hasClaudeDir && await removeDirIfEmpty(target.claudeDir);
|
|
532
591
|
const claudeDirKept = !claudeDirRemoved && target.hasClaudeDir && await directoryExists(target.claudeDir);
|
|
533
592
|
return {
|
|
@@ -537,14 +596,6 @@ async function cleanupEmptyDirs(target) {
|
|
|
537
596
|
claudeDirKept
|
|
538
597
|
};
|
|
539
598
|
}
|
|
540
|
-
async function isDirectoryEmpty(dirPath) {
|
|
541
|
-
try {
|
|
542
|
-
const allEntries = await readdir(dirPath);
|
|
543
|
-
return allEntries.length === 0;
|
|
544
|
-
} catch {
|
|
545
|
-
return true;
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
599
|
async function listAgentFiles(agentsDir) {
|
|
549
600
|
try {
|
|
550
601
|
return await listAgentMdFiles(agentsDir);
|