@agents-inc/cli 0.86.0 → 0.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/chunk-5UJJQFET.js +564 -0
- package/dist/chunk-5UJJQFET.js.map +1 -0
- package/dist/{chunk-GED2F75H.js → chunk-7FFNNDJQ.js} +176 -120
- package/dist/chunk-7FFNNDJQ.js.map +1 -0
- package/dist/{chunk-BV2MIQ3O.js → chunk-I5AZKNNL.js} +1 -1
- package/dist/chunk-I5AZKNNL.js.map +1 -0
- package/dist/chunk-J6PI73YV.js +68 -0
- package/dist/chunk-J6PI73YV.js.map +1 -0
- package/dist/commands/compile.js +26 -20
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/diff.js +681 -82
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +30 -58
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +164 -32
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +177 -27
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +197 -33
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +41 -34
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +3 -6
- package/dist/commands/new/agent.js +140 -44
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/marketplace.js +4 -4
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/new/skill.js +194 -30
- package/dist/commands/new/skill.js.map +1 -1
- package/dist/commands/outdated.js +1 -3
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/search.js +162 -65
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +259 -62
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +232 -163
- package/dist/commands/update.js.map +1 -1
- package/dist/components/skill-search/skill-search.js +1 -1
- package/dist/hooks/init.js +2 -4
- package/dist/hooks/init.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-BV2MIQ3O.js.map +0 -1
- package/dist/chunk-DCVCFBQ7.js +0 -1800
- package/dist/chunk-DCVCFBQ7.js.map +0 -1
- package/dist/chunk-GED2F75H.js.map +0 -1
- package/dist/chunk-O5ZWS26C.js +0 -166
- package/dist/chunk-O5ZWS26C.js.map +0 -1
- package/dist/chunk-XQK4S22C.js +0 -202
- package/dist/chunk-XQK4S22C.js.map +0 -1
|
@@ -7,17 +7,13 @@ import {
|
|
|
7
7
|
SUCCESS_MESSAGES
|
|
8
8
|
} from "../chunk-B7KZLXHV.js";
|
|
9
9
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
import "../chunk-O5ZWS26C.js";
|
|
18
|
-
import "../chunk-XQK4S22C.js";
|
|
19
|
-
import "../chunk-FBZR46GC.js";
|
|
20
|
-
import "../chunk-TMTUTUEV.js";
|
|
10
|
+
claudePluginUninstall,
|
|
11
|
+
getProjectPluginsDir,
|
|
12
|
+
isClaudeCLIAvailable,
|
|
13
|
+
listPluginNames,
|
|
14
|
+
loadProjectConfigFromDir,
|
|
15
|
+
readForkedFromMetadata
|
|
16
|
+
} from "../chunk-TMTUTUEV.js";
|
|
21
17
|
import "../chunk-B6MYECV6.js";
|
|
22
18
|
import "../chunk-ANXHMG32.js";
|
|
23
19
|
import {
|
|
@@ -25,7 +21,10 @@ import {
|
|
|
25
21
|
EXIT_CODES
|
|
26
22
|
} from "../chunk-MMTMXLI4.js";
|
|
27
23
|
import {
|
|
28
|
-
|
|
24
|
+
directoryExists,
|
|
25
|
+
getErrorMessage,
|
|
26
|
+
listDirectories,
|
|
27
|
+
remove
|
|
29
28
|
} from "../chunk-NUU3U43A.js";
|
|
30
29
|
import "../chunk-6XWHJHNZ.js";
|
|
31
30
|
import {
|
|
@@ -41,6 +40,8 @@ import {
|
|
|
41
40
|
|
|
42
41
|
// src/cli/commands/uninstall.tsx
|
|
43
42
|
init_esm_shims();
|
|
43
|
+
import path from "path";
|
|
44
|
+
import { readdir } from "fs/promises";
|
|
44
45
|
import { Flags } from "@oclif/core";
|
|
45
46
|
import { render, Box, Text, useApp } from "ink";
|
|
46
47
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -123,63 +124,75 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
123
124
|
async run() {
|
|
124
125
|
const { flags } = await this.parse(_Uninstall);
|
|
125
126
|
const projectDir = process.cwd();
|
|
126
|
-
this.
|
|
127
|
-
this.log(`${DEFAULT_BRANDING.NAME} Uninstall`);
|
|
128
|
-
this.log("");
|
|
127
|
+
this.printHeader();
|
|
129
128
|
const target = await detectUninstallTarget(projectDir);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
this.warn("Nothing to uninstall.");
|
|
133
|
-
this.log("");
|
|
134
|
-
this.log(INFO_MESSAGES.NOT_INSTALLED);
|
|
135
|
-
this.log("");
|
|
136
|
-
this.log(INFO_MESSAGES.NO_CHANGES_MADE);
|
|
129
|
+
if (!hasAnythingToRemove(target, flags.all)) {
|
|
130
|
+
this.reportNothingToUninstall();
|
|
137
131
|
return;
|
|
138
132
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const { waitUntilExit } = render(
|
|
142
|
-
/* @__PURE__ */ jsx(
|
|
143
|
-
UninstallConfirm,
|
|
144
|
-
{
|
|
145
|
-
target,
|
|
146
|
-
removeAll: flags.all,
|
|
147
|
-
onConfirm: () => resolve(true),
|
|
148
|
-
onCancel: () => resolve(false)
|
|
149
|
-
}
|
|
150
|
-
)
|
|
151
|
-
);
|
|
152
|
-
waitUntilExit().catch(() => resolve(false));
|
|
153
|
-
});
|
|
154
|
-
if (!confirmed) {
|
|
155
|
-
this.log("");
|
|
156
|
-
this.log("Uninstall cancelled");
|
|
157
|
-
this.exit(EXIT_CODES.CANCELLED);
|
|
158
|
-
}
|
|
159
|
-
} else {
|
|
160
|
-
this.log("The following will be removed:");
|
|
133
|
+
const confirmed = flags.yes ? this.printRemovalPlan(target, flags.all) : await this.confirmRemoval(target, flags.all);
|
|
134
|
+
if (!confirmed) {
|
|
161
135
|
this.log("");
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
136
|
+
this.log("Uninstall cancelled");
|
|
137
|
+
this.exit(EXIT_CODES.CANCELLED);
|
|
138
|
+
}
|
|
139
|
+
await this.executeUninstall(target, projectDir, flags.all);
|
|
140
|
+
this.reportSuccess();
|
|
141
|
+
}
|
|
142
|
+
printHeader() {
|
|
143
|
+
this.log("");
|
|
144
|
+
this.log(`${DEFAULT_BRANDING.NAME} Uninstall`);
|
|
145
|
+
this.log("");
|
|
146
|
+
}
|
|
147
|
+
reportNothingToUninstall() {
|
|
148
|
+
this.warn("Nothing to uninstall.");
|
|
149
|
+
this.log("");
|
|
150
|
+
this.log(INFO_MESSAGES.NOT_INSTALLED);
|
|
151
|
+
this.log("");
|
|
152
|
+
this.log(INFO_MESSAGES.NO_CHANGES_MADE);
|
|
153
|
+
}
|
|
154
|
+
printRemovalPlan(target, removeAll) {
|
|
155
|
+
this.log("The following will be removed:");
|
|
156
|
+
this.log("");
|
|
157
|
+
if (target.hasPlugins) {
|
|
158
|
+
this.log(" Plugins:");
|
|
159
|
+
for (const pluginName of target.cliPluginNames) {
|
|
160
|
+
this.log(` ${pluginName}`);
|
|
167
161
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
if (target.hasLocalAgents) {
|
|
174
|
-
this.log(` ${target.agentsDir}/ (CLI-compiled)`);
|
|
175
|
-
}
|
|
162
|
+
}
|
|
163
|
+
if (target.hasLocalSkills || target.hasLocalAgents) {
|
|
164
|
+
this.log(" CLI-managed files:");
|
|
165
|
+
if (target.hasLocalSkills) {
|
|
166
|
+
this.log(` ${target.skillsDir}/ (matching sources)`);
|
|
176
167
|
}
|
|
177
|
-
if (
|
|
178
|
-
this.log(
|
|
179
|
-
this.log(` ${target.claudeSrcDir}/`);
|
|
168
|
+
if (target.hasLocalAgents) {
|
|
169
|
+
this.log(` ${target.agentsDir}/ (CLI-compiled)`);
|
|
180
170
|
}
|
|
181
|
-
this.log("");
|
|
182
171
|
}
|
|
172
|
+
if (removeAll && target.hasClaudeSrcDir) {
|
|
173
|
+
this.log(" Config:");
|
|
174
|
+
this.log(` ${target.claudeSrcDir}/`);
|
|
175
|
+
}
|
|
176
|
+
this.log("");
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
async confirmRemoval(target, removeAll) {
|
|
180
|
+
return new Promise((resolve) => {
|
|
181
|
+
const { waitUntilExit } = render(
|
|
182
|
+
/* @__PURE__ */ jsx(
|
|
183
|
+
UninstallConfirm,
|
|
184
|
+
{
|
|
185
|
+
target,
|
|
186
|
+
removeAll,
|
|
187
|
+
onConfirm: () => resolve(true),
|
|
188
|
+
onCancel: () => resolve(false)
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
);
|
|
192
|
+
waitUntilExit().catch(() => resolve(false));
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
async executeUninstall(target, projectDir, removeAll) {
|
|
183
196
|
if (target.hasPlugins) {
|
|
184
197
|
this.log("Uninstalling plugins...");
|
|
185
198
|
try {
|
|
@@ -199,13 +212,15 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
199
212
|
}
|
|
200
213
|
}
|
|
201
214
|
try {
|
|
202
|
-
await this.removeLocalFiles(target,
|
|
215
|
+
await this.removeLocalFiles(target, removeAll);
|
|
203
216
|
} catch (error) {
|
|
204
217
|
this.log("Failed to remove local files");
|
|
205
218
|
this.error(getErrorMessage(error), {
|
|
206
219
|
exit: EXIT_CODES.ERROR
|
|
207
220
|
});
|
|
208
221
|
}
|
|
222
|
+
}
|
|
223
|
+
reportSuccess() {
|
|
209
224
|
this.log("");
|
|
210
225
|
this.log(`${DEFAULT_BRANDING.NAME} has been uninstalled.`);
|
|
211
226
|
this.log("");
|
|
@@ -243,6 +258,188 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
243
258
|
}
|
|
244
259
|
}
|
|
245
260
|
};
|
|
261
|
+
function hasAnythingToRemove(target, removeAll) {
|
|
262
|
+
return target.hasPlugins || target.hasLocalSkills || target.hasLocalAgents || removeAll && target.hasClaudeSrcDir;
|
|
263
|
+
}
|
|
264
|
+
function collectConfiguredAgents(config) {
|
|
265
|
+
if (!config?.agents) return [];
|
|
266
|
+
return config.agents.map((a) => a.name);
|
|
267
|
+
}
|
|
268
|
+
function getCliInstalledPluginKeys(config) {
|
|
269
|
+
if (!config?.skills) return /* @__PURE__ */ new Set();
|
|
270
|
+
return new Set(config.skills.map((skill) => `${skill.id}@${skill.source}`));
|
|
271
|
+
}
|
|
272
|
+
async function detectUninstallTarget(projectDir) {
|
|
273
|
+
const pluginsDir = getProjectPluginsDir(projectDir);
|
|
274
|
+
const skillsDir = path.join(projectDir, CLAUDE_DIR, "skills");
|
|
275
|
+
const agentsDir = path.join(projectDir, CLAUDE_DIR, "agents");
|
|
276
|
+
const claudeDir = path.join(projectDir, CLAUDE_DIR);
|
|
277
|
+
const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);
|
|
278
|
+
const [hasLocalSkills, hasLocalAgents, hasClaudeDir, hasClaudeSrcDir, config] = await Promise.all(
|
|
279
|
+
[
|
|
280
|
+
directoryExists(skillsDir),
|
|
281
|
+
directoryExists(agentsDir),
|
|
282
|
+
directoryExists(claudeDir),
|
|
283
|
+
directoryExists(claudeSrcDir),
|
|
284
|
+
loadProjectConfigFromDir(projectDir).then((result) => result?.config ?? null)
|
|
285
|
+
]
|
|
286
|
+
);
|
|
287
|
+
let pluginNames = [];
|
|
288
|
+
try {
|
|
289
|
+
pluginNames = await listPluginNames(projectDir);
|
|
290
|
+
} catch {
|
|
291
|
+
}
|
|
292
|
+
const configuredAgents = collectConfiguredAgents(config);
|
|
293
|
+
const cliInstalledKeys = getCliInstalledPluginKeys(config);
|
|
294
|
+
const cliPluginNames = pluginNames.filter((name) => cliInstalledKeys.has(name));
|
|
295
|
+
return {
|
|
296
|
+
hasPlugins: cliPluginNames.length > 0,
|
|
297
|
+
pluginNames,
|
|
298
|
+
cliPluginNames,
|
|
299
|
+
hasLocalSkills,
|
|
300
|
+
hasLocalAgents,
|
|
301
|
+
hasClaudeDir,
|
|
302
|
+
hasClaudeSrcDir,
|
|
303
|
+
pluginsDir,
|
|
304
|
+
skillsDir,
|
|
305
|
+
agentsDir,
|
|
306
|
+
claudeDir,
|
|
307
|
+
claudeSrcDir,
|
|
308
|
+
config,
|
|
309
|
+
configuredAgents
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function shouldRemoveSkill(forkedFrom) {
|
|
313
|
+
return forkedFrom !== null;
|
|
314
|
+
}
|
|
315
|
+
async function removeMatchingSkills(target, onRemoved, onSkipped) {
|
|
316
|
+
if (!target.hasLocalSkills) {
|
|
317
|
+
return {
|
|
318
|
+
removedCount: 0,
|
|
319
|
+
skippedCount: 0,
|
|
320
|
+
removedNames: [],
|
|
321
|
+
skippedNames: [],
|
|
322
|
+
dirCleaned: false
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
const skillDirNames = await listDirectories(target.skillsDir);
|
|
326
|
+
const removedNames = [];
|
|
327
|
+
const skippedNames = [];
|
|
328
|
+
for (const skillDirName of skillDirNames) {
|
|
329
|
+
const skillDir = path.join(target.skillsDir, skillDirName);
|
|
330
|
+
const forkedFrom = await readForkedFromMetadata(skillDir);
|
|
331
|
+
if (shouldRemoveSkill(forkedFrom)) {
|
|
332
|
+
await remove(skillDir);
|
|
333
|
+
removedNames.push(skillDirName);
|
|
334
|
+
onRemoved?.(skillDirName);
|
|
335
|
+
} else {
|
|
336
|
+
skippedNames.push(skillDirName);
|
|
337
|
+
onSkipped?.(skillDirName);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
let dirCleaned = false;
|
|
341
|
+
if (skippedNames.length === 0 && await directoryExists(target.skillsDir)) {
|
|
342
|
+
if (await isDirectoryEmpty(target.skillsDir)) {
|
|
343
|
+
await remove(target.skillsDir);
|
|
344
|
+
dirCleaned = true;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
removedCount: removedNames.length,
|
|
349
|
+
skippedCount: skippedNames.length,
|
|
350
|
+
removedNames,
|
|
351
|
+
skippedNames,
|
|
352
|
+
dirCleaned
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
async function removeMatchingAgents(target, onRemoved) {
|
|
356
|
+
if (!target.hasLocalAgents) {
|
|
357
|
+
return { removedCount: 0, removedNames: [], dirCleaned: false };
|
|
358
|
+
}
|
|
359
|
+
if (target.configuredAgents.length === 0) {
|
|
360
|
+
return { removedCount: 0, removedNames: [], dirCleaned: false };
|
|
361
|
+
}
|
|
362
|
+
const agentFiles = await listAgentFiles(target.agentsDir);
|
|
363
|
+
const removedNames = [];
|
|
364
|
+
for (const agentFile of agentFiles) {
|
|
365
|
+
const agentName = agentFile.replace(/\.md$/, "");
|
|
366
|
+
if (!target.configuredAgents.includes(agentName)) continue;
|
|
367
|
+
await remove(path.join(target.agentsDir, agentFile));
|
|
368
|
+
removedNames.push(agentName);
|
|
369
|
+
onRemoved?.(agentName);
|
|
370
|
+
}
|
|
371
|
+
let dirCleaned = false;
|
|
372
|
+
if (await directoryExists(target.agentsDir)) {
|
|
373
|
+
if (await isDirectoryEmpty(target.agentsDir)) {
|
|
374
|
+
await remove(target.agentsDir);
|
|
375
|
+
dirCleaned = true;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return {
|
|
379
|
+
removedCount: removedNames.length,
|
|
380
|
+
removedNames,
|
|
381
|
+
dirCleaned
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
async function uninstallPlugins(target, projectDir, onUninstalled) {
|
|
385
|
+
if (!target.hasPlugins) {
|
|
386
|
+
return { uninstalledNames: [], totalUninstalled: 0 };
|
|
387
|
+
}
|
|
388
|
+
const cliAvailable = await isClaudeCLIAvailable();
|
|
389
|
+
const uninstalledNames = [];
|
|
390
|
+
for (const pluginName of target.cliPluginNames) {
|
|
391
|
+
if (cliAvailable) {
|
|
392
|
+
try {
|
|
393
|
+
const skillId = pluginName.split("@")[0];
|
|
394
|
+
const skillConfig = target.config?.skills?.find((s) => s.id === skillId);
|
|
395
|
+
const pluginScope = skillConfig?.scope === "global" ? "user" : "project";
|
|
396
|
+
await claudePluginUninstall(pluginName, pluginScope, projectDir);
|
|
397
|
+
} catch {
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
const pluginPath = path.join(target.pluginsDir, pluginName);
|
|
401
|
+
await remove(pluginPath);
|
|
402
|
+
uninstalledNames.push(pluginName);
|
|
403
|
+
onUninstalled?.(pluginName);
|
|
404
|
+
}
|
|
405
|
+
return {
|
|
406
|
+
uninstalledNames,
|
|
407
|
+
totalUninstalled: uninstalledNames.length
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
async function cleanupEmptyDirs(target, removeAll) {
|
|
411
|
+
let claudeSrcDirRemoved = false;
|
|
412
|
+
if (removeAll && target.hasClaudeSrcDir) {
|
|
413
|
+
await remove(target.claudeSrcDir);
|
|
414
|
+
claudeSrcDirRemoved = true;
|
|
415
|
+
}
|
|
416
|
+
let claudeDirRemoved = false;
|
|
417
|
+
let claudeDirKept = false;
|
|
418
|
+
if (target.hasClaudeDir && await directoryExists(target.claudeDir)) {
|
|
419
|
+
if (await isDirectoryEmpty(target.claudeDir)) {
|
|
420
|
+
await remove(target.claudeDir);
|
|
421
|
+
claudeDirRemoved = true;
|
|
422
|
+
} else {
|
|
423
|
+
claudeDirKept = true;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return { claudeDirRemoved, claudeSrcDirRemoved, claudeDirKept };
|
|
427
|
+
}
|
|
428
|
+
async function isDirectoryEmpty(dirPath) {
|
|
429
|
+
try {
|
|
430
|
+
const allEntries = await readdir(dirPath);
|
|
431
|
+
return allEntries.length === 0;
|
|
432
|
+
} catch {
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
async function listAgentFiles(agentsDir) {
|
|
437
|
+
try {
|
|
438
|
+
return (await readdir(agentsDir)).filter((f) => f.endsWith(".md"));
|
|
439
|
+
} catch {
|
|
440
|
+
return [];
|
|
441
|
+
}
|
|
442
|
+
}
|
|
246
443
|
export {
|
|
247
444
|
Uninstall as default
|
|
248
445
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Flags } from \"@oclif/core\";\nimport { render, Box, Text, useApp } from \"ink\";\n\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport {\n detectUninstallTarget,\n removeMatchingSkills,\n removeMatchingAgents,\n uninstallPlugins,\n cleanupEmptyDirs,\n} from \"../lib/operations\";\nimport type { UninstallTarget } from \"../lib/operations\";\nimport { CLAUDE_DIR, CLAUDE_SRC_DIR, CLI_COLORS, DEFAULT_BRANDING } from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport { SUCCESS_MESSAGES, INFO_MESSAGES } from \"../utils/messages\";\n\ntype UninstallConfirmProps = {\n target: UninstallTarget;\n removeAll: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UninstallConfirm: React.FC<UninstallConfirmProps> = ({\n target,\n removeAll,\n onConfirm,\n onCancel,\n}) => {\n const { exit } = useApp();\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>The following will be removed:</Text>\n <Text> </Text>\n\n {target.hasPlugins && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Plugins:</Text>\n {target.cliPluginNames.map((name) => (\n <Text key={name} dimColor>\n {\" \"}\n {name}\n </Text>\n ))}\n </Box>\n )}\n\n {(target.hasLocalSkills || target.hasLocalAgents) && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> CLI-managed files:</Text>\n {target.hasLocalSkills && <Text dimColor> {target.skillsDir}/ (matching sources)</Text>}\n {target.hasLocalAgents && <Text dimColor> {target.agentsDir}/ (CLI-compiled)</Text>}\n </Box>\n )}\n\n {removeAll && target.hasClaudeSrcDir && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Config:</Text>\n <Text dimColor> {target.claudeSrcDir}/</Text>\n </Box>\n )}\n\n <Text> </Text>\n <Confirm\n message=\"Are you sure you want to uninstall?\"\n onConfirm={() => {\n onConfirm();\n exit();\n }}\n onCancel={() => {\n onCancel();\n exit();\n }}\n defaultValue={false}\n />\n </Box>\n );\n};\n\nexport default class Uninstall extends BaseCommand {\n static summary = `Remove ${DEFAULT_BRANDING.NAME} from this project`;\n\n static description = `Uninstall ${DEFAULT_BRANDING.NAME} from this project. Removes CLI-managed skills (matched by source), compiled agents, and plugins. User-created content is preserved.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --all\",\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n all: Flags.boolean({\n description: \"Also remove .claude-src/ config directory\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Uninstall);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Uninstall`);\n this.log(\"\");\n\n const target = await detectUninstallTarget(projectDir);\n\n const hasAnythingToRemove =\n target.hasPlugins ||\n target.hasLocalSkills ||\n target.hasLocalAgents ||\n (flags.all && target.hasClaudeSrcDir);\n\n if (!hasAnythingToRemove) {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n this.log(INFO_MESSAGES.NOT_INSTALLED);\n this.log(\"\");\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n return;\n }\n\n if (!flags.yes) {\n const confirmed = await new Promise<boolean>((resolve) => {\n const { waitUntilExit } = render(\n <UninstallConfirm\n target={target}\n removeAll={flags.all}\n onConfirm={() => resolve(true)}\n onCancel={() => resolve(false)}\n />,\n );\n\n waitUntilExit().catch(() => resolve(false));\n });\n\n if (!confirmed) {\n this.log(\"\");\n this.log(\"Uninstall cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n } else {\n this.log(\"The following will be removed:\");\n this.log(\"\");\n\n if (target.hasPlugins) {\n this.log(\" Plugins:\");\n for (const pluginName of target.cliPluginNames) {\n this.log(` ${pluginName}`);\n }\n }\n\n if (target.hasLocalSkills || target.hasLocalAgents) {\n this.log(\" CLI-managed files:\");\n if (target.hasLocalSkills) {\n this.log(` ${target.skillsDir}/ (matching sources)`);\n }\n if (target.hasLocalAgents) {\n this.log(` ${target.agentsDir}/ (CLI-compiled)`);\n }\n }\n\n if (flags.all && target.hasClaudeSrcDir) {\n this.log(\" Config:\");\n this.log(` ${target.claudeSrcDir}/`);\n }\n\n this.log(\"\");\n }\n\n if (target.hasPlugins) {\n this.log(\"Uninstalling plugins...\");\n\n try {\n const pluginResult = await uninstallPlugins(target, projectDir, (name) =>\n this.log(` Uninstalled plugin '${name}'`),\n );\n\n this.logSuccess(\n `Uninstalled ${pluginResult.totalUninstalled} ${pluginResult.totalUninstalled === 1 ? \"plugin\" : \"plugins\"}`,\n );\n } catch (error) {\n this.log(\"Plugin uninstall failed\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n try {\n await this.removeLocalFiles(target, flags.all);\n } catch (error) {\n this.log(\"Failed to remove local files\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} has been uninstalled.`);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);\n this.log(\"\");\n }\n\n private async removeLocalFiles(target: UninstallTarget, removeAll: boolean): Promise<void> {\n const skillResult = await removeMatchingSkills(\n target,\n (dirName) => this.log(` Uninstalled skill '${dirName}'`),\n (dirName) => this.warn(`Skipping '${dirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`),\n );\n\n if (skillResult.removedCount > 0) {\n this.logSuccess(\n `Removed ${skillResult.removedCount} CLI-installed ${skillResult.removedCount === 1 ? \"skill\" : \"skills\"}`,\n );\n }\n\n const agentResult = await removeMatchingAgents(target, (agentName) =>\n this.log(` Uninstalled agent '${agentName}'`),\n );\n\n if (agentResult.removedCount > 0) {\n this.logSuccess(\n `Removed ${agentResult.removedCount} compiled ${agentResult.removedCount === 1 ? \"agent\" : \"agents\"}`,\n );\n }\n\n const cleanup = await cleanupEmptyDirs(target, removeAll);\n\n if (cleanup.claudeSrcDirRemoved) {\n this.logSuccess(`Removed ${CLAUDE_SRC_DIR}/`);\n }\n\n if (cleanup.claudeDirRemoved) {\n this.logSuccess(`Removed ${CLAUDE_DIR}/`);\n } else if (cleanup.claudeDirKept) {\n this.log(`Kept ${CLAUDE_DIR}/ (contains user content)`);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\nimport path from \"path\";\nimport { readdir } from \"fs/promises\";\n\nimport { Flags } from \"@oclif/core\";\nimport { render, Box, Text, useApp } from \"ink\";\n\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { directoryExists, listDirectories, remove } from \"../utils/fs\";\nimport { claudePluginUninstall, isClaudeCLIAvailable } from \"../utils/exec\";\nimport { listPluginNames, getProjectPluginsDir } from \"../lib/plugins/index\";\nimport { readForkedFromMetadata } from \"../lib/skills/index\";\nimport { loadProjectConfigFromDir } from \"../lib/configuration/project-config\";\nimport { CLAUDE_DIR, CLAUDE_SRC_DIR, CLI_COLORS, DEFAULT_BRANDING } from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport { SUCCESS_MESSAGES, INFO_MESSAGES } from \"../utils/messages\";\nimport type { ProjectConfig } from \"../types/index\";\n\ntype UninstallConfirmProps = {\n target: UninstallTarget;\n removeAll: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UninstallConfirm: React.FC<UninstallConfirmProps> = ({\n target,\n removeAll,\n onConfirm,\n onCancel,\n}) => {\n const { exit } = useApp();\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>The following will be removed:</Text>\n <Text> </Text>\n\n {target.hasPlugins && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Plugins:</Text>\n {target.cliPluginNames.map((name) => (\n <Text key={name} dimColor>\n {\" \"}\n {name}\n </Text>\n ))}\n </Box>\n )}\n\n {(target.hasLocalSkills || target.hasLocalAgents) && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> CLI-managed files:</Text>\n {target.hasLocalSkills && <Text dimColor> {target.skillsDir}/ (matching sources)</Text>}\n {target.hasLocalAgents && <Text dimColor> {target.agentsDir}/ (CLI-compiled)</Text>}\n </Box>\n )}\n\n {removeAll && target.hasClaudeSrcDir && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Config:</Text>\n <Text dimColor> {target.claudeSrcDir}/</Text>\n </Box>\n )}\n\n <Text> </Text>\n <Confirm\n message=\"Are you sure you want to uninstall?\"\n onConfirm={() => {\n onConfirm();\n exit();\n }}\n onCancel={() => {\n onCancel();\n exit();\n }}\n defaultValue={false}\n />\n </Box>\n );\n};\n\nexport default class Uninstall extends BaseCommand {\n static summary = `Remove ${DEFAULT_BRANDING.NAME} from this project`;\n\n static description = `Uninstall ${DEFAULT_BRANDING.NAME} from this project. Removes CLI-managed skills (matched by source), compiled agents, and plugins. User-created content is preserved.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --all\",\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n all: Flags.boolean({\n description: \"Also remove .claude-src/ config directory\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Uninstall);\n const projectDir = process.cwd();\n\n this.printHeader();\n\n const target = await detectUninstallTarget(projectDir);\n if (!hasAnythingToRemove(target, flags.all)) {\n this.reportNothingToUninstall();\n return;\n }\n\n const confirmed = flags.yes\n ? this.printRemovalPlan(target, flags.all)\n : await this.confirmRemoval(target, flags.all);\n if (!confirmed) {\n this.log(\"\");\n this.log(\"Uninstall cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n await this.executeUninstall(target, projectDir, flags.all);\n this.reportSuccess();\n }\n\n private printHeader(): void {\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Uninstall`);\n this.log(\"\");\n }\n\n private reportNothingToUninstall(): void {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n this.log(INFO_MESSAGES.NOT_INSTALLED);\n this.log(\"\");\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n }\n\n private printRemovalPlan(target: UninstallTarget, removeAll: boolean): true {\n this.log(\"The following will be removed:\");\n this.log(\"\");\n\n if (target.hasPlugins) {\n this.log(\" Plugins:\");\n for (const pluginName of target.cliPluginNames) {\n this.log(` ${pluginName}`);\n }\n }\n\n if (target.hasLocalSkills || target.hasLocalAgents) {\n this.log(\" CLI-managed files:\");\n if (target.hasLocalSkills) {\n this.log(` ${target.skillsDir}/ (matching sources)`);\n }\n if (target.hasLocalAgents) {\n this.log(` ${target.agentsDir}/ (CLI-compiled)`);\n }\n }\n\n if (removeAll && target.hasClaudeSrcDir) {\n this.log(\" Config:\");\n this.log(` ${target.claudeSrcDir}/`);\n }\n\n this.log(\"\");\n return true;\n }\n\n private async confirmRemoval(target: UninstallTarget, removeAll: boolean): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const { waitUntilExit } = render(\n <UninstallConfirm\n target={target}\n removeAll={removeAll}\n onConfirm={() => resolve(true)}\n onCancel={() => resolve(false)}\n />,\n );\n\n waitUntilExit().catch(() => resolve(false));\n });\n }\n\n private async executeUninstall(\n target: UninstallTarget,\n projectDir: string,\n removeAll: boolean,\n ): Promise<void> {\n if (target.hasPlugins) {\n this.log(\"Uninstalling plugins...\");\n\n try {\n const pluginResult = await uninstallPlugins(target, projectDir, (name) =>\n this.log(` Uninstalled plugin '${name}'`),\n );\n\n this.logSuccess(\n `Uninstalled ${pluginResult.totalUninstalled} ${pluginResult.totalUninstalled === 1 ? \"plugin\" : \"plugins\"}`,\n );\n } catch (error) {\n this.log(\"Plugin uninstall failed\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n try {\n await this.removeLocalFiles(target, removeAll);\n } catch (error) {\n this.log(\"Failed to remove local files\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n private reportSuccess(): void {\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} has been uninstalled.`);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);\n this.log(\"\");\n }\n\n private async removeLocalFiles(target: UninstallTarget, removeAll: boolean): Promise<void> {\n const skillResult = await removeMatchingSkills(\n target,\n (dirName) => this.log(` Uninstalled skill '${dirName}'`),\n (dirName) => this.warn(`Skipping '${dirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`),\n );\n\n if (skillResult.removedCount > 0) {\n this.logSuccess(\n `Removed ${skillResult.removedCount} CLI-installed ${skillResult.removedCount === 1 ? \"skill\" : \"skills\"}`,\n );\n }\n\n const agentResult = await removeMatchingAgents(target, (agentName) =>\n this.log(` Uninstalled agent '${agentName}'`),\n );\n\n if (agentResult.removedCount > 0) {\n this.logSuccess(\n `Removed ${agentResult.removedCount} compiled ${agentResult.removedCount === 1 ? \"agent\" : \"agents\"}`,\n );\n }\n\n const cleanup = await cleanupEmptyDirs(target, removeAll);\n\n if (cleanup.claudeSrcDirRemoved) {\n this.logSuccess(`Removed ${CLAUDE_SRC_DIR}/`);\n }\n\n if (cleanup.claudeDirRemoved) {\n this.logSuccess(`Removed ${CLAUDE_DIR}/`);\n } else if (cleanup.claudeDirKept) {\n this.log(`Kept ${CLAUDE_DIR}/ (contains user content)`);\n }\n }\n}\n\ntype UninstallTarget = {\n hasPlugins: boolean;\n pluginNames: string[];\n /** Plugin names filtered to only those installed by this CLI (matched against config skills) */\n cliPluginNames: string[];\n hasLocalSkills: boolean;\n hasLocalAgents: boolean;\n hasClaudeDir: boolean;\n hasClaudeSrcDir: boolean;\n pluginsDir: string;\n skillsDir: string;\n agentsDir: string;\n claudeDir: string;\n claudeSrcDir: string;\n /** Resolved project source config from .claude-src/config.ts */\n config: Partial<ProjectConfig> | null;\n /** Agent names from the generated config (e.g., [\"web-developer\"]) */\n configuredAgents: string[];\n};\n\ntype SkillRemovalResult = {\n removedCount: number;\n skippedCount: number;\n removedNames: string[];\n skippedNames: string[];\n /** Whether the skills directory was cleaned up (empty after removal) */\n dirCleaned: boolean;\n};\n\ntype AgentRemovalResult = {\n removedCount: number;\n removedNames: string[];\n /** Whether the agents directory was cleaned up (empty after removal) */\n dirCleaned: boolean;\n};\n\ntype UninstallPluginsResult = {\n uninstalledNames: string[];\n totalUninstalled: number;\n};\n\ntype CleanupResult = {\n claudeDirRemoved: boolean;\n claudeSrcDirRemoved: boolean;\n /** Whether .claude/ still exists with user content after cleanup */\n claudeDirKept: boolean;\n};\n\nfunction hasAnythingToRemove(target: UninstallTarget, removeAll: boolean): boolean {\n return (\n target.hasPlugins ||\n target.hasLocalSkills ||\n target.hasLocalAgents ||\n (removeAll && target.hasClaudeSrcDir)\n );\n}\n\nfunction collectConfiguredAgents(config: Partial<ProjectConfig> | null): string[] {\n if (!config?.agents) return [];\n return config.agents.map((a) => a.name);\n}\n\nfunction getCliInstalledPluginKeys(config: Partial<ProjectConfig> | null): Set<string> {\n if (!config?.skills) return new Set();\n return new Set(config.skills.map((skill) => `${skill.id}@${skill.source}`));\n}\n\n/**\n * Detects what's installed in a project directory for uninstallation.\n *\n * Checks for plugins, local skills, agents, config directories, and\n * resolves which plugins were installed by this CLI.\n */\nasync function detectUninstallTarget(projectDir: string): Promise<UninstallTarget> {\n const pluginsDir = getProjectPluginsDir(projectDir);\n const skillsDir = path.join(projectDir, CLAUDE_DIR, \"skills\");\n const agentsDir = path.join(projectDir, CLAUDE_DIR, \"agents\");\n const claudeDir = path.join(projectDir, CLAUDE_DIR);\n const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);\n\n const [hasLocalSkills, hasLocalAgents, hasClaudeDir, hasClaudeSrcDir, config] = await Promise.all(\n [\n directoryExists(skillsDir),\n directoryExists(agentsDir),\n directoryExists(claudeDir),\n directoryExists(claudeSrcDir),\n loadProjectConfigFromDir(projectDir).then((result) => result?.config ?? null),\n ],\n );\n\n let pluginNames: string[] = [];\n try {\n pluginNames = await listPluginNames(projectDir);\n } catch {\n // Best-effort: plugin detection may fail\n }\n\n const configuredAgents = collectConfiguredAgents(config);\n const cliInstalledKeys = getCliInstalledPluginKeys(config);\n const cliPluginNames = pluginNames.filter((name) => cliInstalledKeys.has(name));\n\n return {\n hasPlugins: cliPluginNames.length > 0,\n pluginNames,\n cliPluginNames,\n hasLocalSkills,\n hasLocalAgents,\n hasClaudeDir,\n hasClaudeSrcDir,\n pluginsDir,\n skillsDir,\n agentsDir,\n claudeDir,\n claudeSrcDir,\n config,\n configuredAgents,\n };\n}\n\nfunction shouldRemoveSkill(forkedFrom: { source?: string } | null): boolean {\n return forkedFrom !== null;\n}\n\n/**\n * Removes local skills that were installed by the CLI (have forked-from metadata).\n *\n * Scans the skills directory, checks each skill for CLI-installed metadata,\n * and removes matching skills. User-created skills (without metadata) are preserved.\n *\n * @param onRemoved - Called for each removed skill directory name (for logging)\n * @param onSkipped - Called for each skipped skill directory name (for logging)\n */\nasync function removeMatchingSkills(\n target: Pick<UninstallTarget, \"hasLocalSkills\" | \"skillsDir\">,\n onRemoved?: (dirName: string) => void,\n onSkipped?: (dirName: string) => void,\n): Promise<SkillRemovalResult> {\n if (!target.hasLocalSkills) {\n return {\n removedCount: 0,\n skippedCount: 0,\n removedNames: [],\n skippedNames: [],\n dirCleaned: false,\n };\n }\n\n const skillDirNames = await listDirectories(target.skillsDir);\n const removedNames: string[] = [];\n const skippedNames: string[] = [];\n\n for (const skillDirName of skillDirNames) {\n const skillDir = path.join(target.skillsDir, skillDirName);\n const forkedFrom = await readForkedFromMetadata(skillDir);\n\n if (shouldRemoveSkill(forkedFrom)) {\n await remove(skillDir);\n removedNames.push(skillDirName);\n onRemoved?.(skillDirName);\n } else {\n skippedNames.push(skillDirName);\n onSkipped?.(skillDirName);\n }\n }\n\n let dirCleaned = false;\n if (skippedNames.length === 0 && (await directoryExists(target.skillsDir))) {\n if (await isDirectoryEmpty(target.skillsDir)) {\n await remove(target.skillsDir);\n dirCleaned = true;\n }\n }\n\n return {\n removedCount: removedNames.length,\n skippedCount: skippedNames.length,\n removedNames,\n skippedNames,\n dirCleaned,\n };\n}\n\n/**\n * Removes compiled agent .md files that match configured agent names.\n *\n * Only removes agents that are listed in the project config (CLI-compiled).\n * Cleans up the agents directory if empty after removal.\n *\n * @param onRemoved - Called for each removed agent name (for logging)\n */\nasync function removeMatchingAgents(\n target: Pick<UninstallTarget, \"hasLocalAgents\" | \"agentsDir\" | \"configuredAgents\">,\n onRemoved?: (agentName: string) => void,\n): Promise<AgentRemovalResult> {\n if (!target.hasLocalAgents) {\n return { removedCount: 0, removedNames: [], dirCleaned: false };\n }\n\n if (target.configuredAgents.length === 0) {\n return { removedCount: 0, removedNames: [], dirCleaned: false };\n }\n\n const agentFiles = await listAgentFiles(target.agentsDir);\n const removedNames: string[] = [];\n\n for (const agentFile of agentFiles) {\n const agentName = agentFile.replace(/\\.md$/, \"\");\n if (!target.configuredAgents.includes(agentName)) continue;\n\n await remove(path.join(target.agentsDir, agentFile));\n removedNames.push(agentName);\n onRemoved?.(agentName);\n }\n\n let dirCleaned = false;\n if (await directoryExists(target.agentsDir)) {\n if (await isDirectoryEmpty(target.agentsDir)) {\n await remove(target.agentsDir);\n dirCleaned = true;\n }\n }\n\n return {\n removedCount: removedNames.length,\n removedNames,\n dirCleaned,\n };\n}\n\n/**\n * Uninstalls CLI-managed plugins by removing them from the Claude CLI\n * and deleting their local directories.\n *\n * Derives scope from per-skill config when available; falls back to project-level.\n *\n * @param onUninstalled - Called for each successfully uninstalled plugin name (for logging)\n */\nasync function uninstallPlugins(\n target: Pick<UninstallTarget, \"hasPlugins\" | \"cliPluginNames\" | \"pluginsDir\" | \"config\">,\n projectDir: string,\n onUninstalled?: (pluginName: string) => void,\n): Promise<UninstallPluginsResult> {\n if (!target.hasPlugins) {\n return { uninstalledNames: [], totalUninstalled: 0 };\n }\n\n const cliAvailable = await isClaudeCLIAvailable();\n const uninstalledNames: string[] = [];\n\n for (const pluginName of target.cliPluginNames) {\n if (cliAvailable) {\n try {\n // Derive scope from per-skill config; fall back to project-level heuristic\n const skillId = pluginName.split(\"@\")[0];\n const skillConfig = target.config?.skills?.find((s) => s.id === skillId);\n const pluginScope = skillConfig?.scope === \"global\" ? \"user\" : \"project\";\n await claudePluginUninstall(pluginName, pluginScope, projectDir);\n } catch {\n // Best-effort: plugin may not be registered with Claude CLI\n }\n }\n\n const pluginPath = path.join(target.pluginsDir, pluginName);\n await remove(pluginPath);\n uninstalledNames.push(pluginName);\n onUninstalled?.(pluginName);\n }\n\n return {\n uninstalledNames,\n totalUninstalled: uninstalledNames.length,\n };\n}\n\n/**\n * Removes empty .claude/ and .claude-src/ directories after uninstall.\n *\n * Only removes .claude-src/ when `removeAll` is true.\n * Only removes .claude/ when it's completely empty.\n */\nasync function cleanupEmptyDirs(\n target: Pick<UninstallTarget, \"hasClaudeDir\" | \"hasClaudeSrcDir\" | \"claudeDir\" | \"claudeSrcDir\">,\n removeAll: boolean,\n): Promise<CleanupResult> {\n let claudeSrcDirRemoved = false;\n if (removeAll && target.hasClaudeSrcDir) {\n await remove(target.claudeSrcDir);\n claudeSrcDirRemoved = true;\n }\n\n let claudeDirRemoved = false;\n let claudeDirKept = false;\n if (target.hasClaudeDir && (await directoryExists(target.claudeDir))) {\n if (await isDirectoryEmpty(target.claudeDir)) {\n await remove(target.claudeDir);\n claudeDirRemoved = true;\n } else {\n claudeDirKept = true;\n }\n }\n\n return { claudeDirRemoved, claudeSrcDirRemoved, claudeDirKept };\n}\n\nasync function isDirectoryEmpty(dirPath: string): Promise<boolean> {\n try {\n const allEntries = await readdir(dirPath);\n return allEntries.length === 0;\n } catch {\n return true;\n }\n}\n\nasync function listAgentFiles(agentsDir: string): Promise<string[]> {\n try {\n return (await readdir(agentsDir)).filter((f) => f.endsWith(\".md\"));\n } catch {\n return [];\n }\n}\n"],"mappings":"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","names":[]}
|