agents-inc 0.171.0 → 0.173.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 +31 -0
- package/dist/{chunk-W4KAY26P.js → chunk-2RTBSLSR.js} +12 -3
- package/dist/{chunk-W4KAY26P.js.map → chunk-2RTBSLSR.js.map} +1 -1
- package/dist/{chunk-WM2N2D6Q.js → chunk-3N4FSTVX.js} +12 -6
- package/dist/{chunk-WM2N2D6Q.js.map → chunk-3N4FSTVX.js.map} +1 -1
- package/dist/{chunk-ZC6GC66J.js → chunk-3R3LHA4Q.js} +2 -2
- package/dist/{chunk-24OD7IP4.js → chunk-7OG635DK.js} +26 -4
- package/dist/chunk-7OG635DK.js.map +1 -0
- package/dist/{chunk-WDH6HHA3.js → chunk-A3ZAXL5T.js} +4 -5
- package/dist/{chunk-WDH6HHA3.js.map → chunk-A3ZAXL5T.js.map} +1 -1
- package/dist/{chunk-KMOCMVK5.js → chunk-AARQBW5L.js} +106 -60
- package/dist/chunk-AARQBW5L.js.map +1 -0
- package/dist/{chunk-WII6GOPM.js → chunk-BRZA7ZCX.js} +52 -31
- package/dist/chunk-BRZA7ZCX.js.map +1 -0
- package/dist/{chunk-AWWCRL5A.js → chunk-EHJIQDXR.js} +8 -6
- package/dist/{chunk-AWWCRL5A.js.map → chunk-EHJIQDXR.js.map} +1 -1
- package/dist/{chunk-RDXY4GRO.js → chunk-F437ICEG.js} +2 -2
- package/dist/chunk-G7NUK3BF.js +253 -0
- package/dist/chunk-G7NUK3BF.js.map +1 -0
- package/dist/{chunk-7IVLVEHX.js → chunk-ITQF35UQ.js} +3 -3
- package/dist/{chunk-QIR56IDM.js → chunk-LJQXQTFC.js} +29 -102
- package/dist/chunk-LJQXQTFC.js.map +1 -0
- package/dist/{chunk-A6OWEJGC.js → chunk-MHAQWMNJ.js} +35 -5
- package/dist/{chunk-A6OWEJGC.js.map → chunk-MHAQWMNJ.js.map} +1 -1
- package/dist/{chunk-YLUOGAW7.js → chunk-N33AKFLR.js} +2 -2
- package/dist/{chunk-TNFYBKVD.js → chunk-Q4UNHVPX.js} +25 -14
- package/dist/chunk-Q4UNHVPX.js.map +1 -0
- package/dist/chunk-Q6WRR4BN.js +195 -0
- package/dist/chunk-Q6WRR4BN.js.map +1 -0
- package/dist/{chunk-JGPE4RRE.js → chunk-SPQSNZMM.js} +2 -2
- package/dist/{chunk-EOKNEGRD.js → chunk-VR6QTK5Z.js} +8 -8
- package/dist/{chunk-S2SKVJT2.js → chunk-VSPC74SS.js} +48 -26
- package/dist/chunk-VSPC74SS.js.map +1 -0
- package/dist/{chunk-3YYHL76L.js → chunk-WVFBBZEP.js} +648 -394
- package/dist/chunk-WVFBBZEP.js.map +1 -0
- package/dist/commands/build/marketplace.js +16 -14
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +6 -6
- package/dist/commands/compile.js +12 -12
- package/dist/commands/doctor.js +87 -86
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +150 -152
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +25 -30
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +19 -16
- package/dist/commands/list.js +14 -17
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +4 -4
- package/dist/commands/search.js +15 -13
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +11 -11
- package/dist/commands/uninstall.js +145 -130
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +6 -6
- package/dist/components/common/scroll-affordance.js +2 -2
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/common/skill-agent-summary.js +3 -4
- package/dist/components/common/summary-panel.js +11 -146
- package/dist/components/common/summary-panel.js.map +1 -1
- package/dist/hooks/init.js +39 -27
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-E67DSYTN.js +14 -0
- package/dist/{recompile-project-agents-IQANWGOP.js → recompile-project-agents-6G6M2RS6.js} +8 -8
- package/dist/{source-loader-YGG7DY2W.js → source-loader-W7XCNKNA.js} +4 -4
- package/dist/src/agents/tester/web-tester/playbook.md +1 -1
- package/package.json +1 -1
- package/src/agents/tester/web-tester/playbook.md +1 -1
- package/dist/chunk-24OD7IP4.js.map +0 -1
- package/dist/chunk-3YYHL76L.js.map +0 -1
- package/dist/chunk-4RQKCV6I.js +0 -103
- package/dist/chunk-4RQKCV6I.js.map +0 -1
- package/dist/chunk-5FM77WKW.js +0 -69
- package/dist/chunk-5FM77WKW.js.map +0 -1
- package/dist/chunk-KMOCMVK5.js.map +0 -1
- package/dist/chunk-QIR56IDM.js.map +0 -1
- package/dist/chunk-R572RLTI.js +0 -108
- package/dist/chunk-R572RLTI.js.map +0 -1
- package/dist/chunk-S2SKVJT2.js.map +0 -1
- package/dist/chunk-TNFYBKVD.js.map +0 -1
- package/dist/chunk-WII6GOPM.js.map +0 -1
- package/dist/components/common/removal-plan-confirm.js +0 -10
- package/dist/load-agent-defs-UBWITIEI.js +0 -14
- package/dist/source-loader-YGG7DY2W.js.map +0 -1
- /package/dist/{chunk-ZC6GC66J.js.map → chunk-3R3LHA4Q.js.map} +0 -0
- /package/dist/{chunk-RDXY4GRO.js.map → chunk-F437ICEG.js.map} +0 -0
- /package/dist/{chunk-7IVLVEHX.js.map → chunk-ITQF35UQ.js.map} +0 -0
- /package/dist/{chunk-YLUOGAW7.js.map → chunk-N33AKFLR.js.map} +0 -0
- /package/dist/{chunk-JGPE4RRE.js.map → chunk-SPQSNZMM.js.map} +0 -0
- /package/dist/{chunk-EOKNEGRD.js.map → chunk-VR6QTK5Z.js.map} +0 -0
- /package/dist/{components/common/removal-plan-confirm.js.map → load-agent-defs-E67DSYTN.js.map} +0 -0
- /package/dist/{recompile-project-agents-IQANWGOP.js.map → recompile-project-agents-6G6M2RS6.js.map} +0 -0
- /package/dist/{load-agent-defs-UBWITIEI.js.map → source-loader-W7XCNKNA.js.map} +0 -0
|
@@ -1,59 +1,62 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "../chunk-
|
|
3
|
+
Confirm
|
|
4
|
+
} from "../chunk-OZXAJNLA.js";
|
|
5
5
|
import {
|
|
6
6
|
promptConfirm
|
|
7
7
|
} from "../chunk-P6CYS4JK.js";
|
|
8
|
-
import
|
|
8
|
+
import {
|
|
9
|
+
summaryPanelBlock
|
|
10
|
+
} from "../chunk-Q6WRR4BN.js";
|
|
11
|
+
import "../chunk-N33AKFLR.js";
|
|
9
12
|
import {
|
|
10
13
|
lazyGateDeps,
|
|
11
14
|
mutateGlobal,
|
|
12
15
|
propagateGlobalRemoval
|
|
13
|
-
} from "../chunk-
|
|
14
|
-
import "../chunk-
|
|
16
|
+
} from "../chunk-VSPC74SS.js";
|
|
17
|
+
import "../chunk-VR6QTK5Z.js";
|
|
15
18
|
import {
|
|
16
19
|
loadAgentDefs
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
20
|
+
} from "../chunk-ITQF35UQ.js";
|
|
21
|
+
import "../chunk-BRZA7ZCX.js";
|
|
19
22
|
import {
|
|
20
23
|
listAgentFilesOf,
|
|
21
24
|
splitAgentsByProvenance
|
|
22
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-EHJIQDXR.js";
|
|
23
26
|
import "../chunk-KIK5EZYD.js";
|
|
27
|
+
import "../chunk-G7NUK3BF.js";
|
|
24
28
|
import {
|
|
25
29
|
providerFlag,
|
|
26
30
|
providerNamedBy,
|
|
27
31
|
refuseAnAmbiguousInstallation
|
|
28
|
-
} from "../chunk-
|
|
32
|
+
} from "../chunk-2RTBSLSR.js";
|
|
29
33
|
import {
|
|
30
34
|
BaseCommand,
|
|
31
35
|
EXIT_CODES
|
|
32
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-LJQXQTFC.js";
|
|
33
37
|
import {
|
|
34
38
|
ConfigLoadError,
|
|
35
39
|
INFO_MESSAGES,
|
|
36
40
|
SUCCESS_MESSAGES,
|
|
37
|
-
UNINSTALL_PLAN,
|
|
38
41
|
agentCodec,
|
|
39
42
|
buildMarketplacePluginRef,
|
|
40
|
-
|
|
43
|
+
configFileRemoved,
|
|
41
44
|
directoryExists,
|
|
42
45
|
fileExists,
|
|
43
46
|
getErrorMessage,
|
|
44
47
|
getProjectPluginsDir,
|
|
45
48
|
hostAt,
|
|
49
|
+
isAgentName,
|
|
46
50
|
isHomeDirectory,
|
|
47
51
|
listDirectories,
|
|
48
52
|
listPluginNames,
|
|
49
53
|
loadProjectConfigAt,
|
|
50
54
|
loadSkillsMatrixFromSource,
|
|
51
|
-
localSkillsRemoval,
|
|
52
55
|
notInstalledHere,
|
|
53
56
|
parseMarketplacePluginRef,
|
|
54
57
|
pluginLeftRegistered,
|
|
55
58
|
providerInUse,
|
|
56
|
-
|
|
59
|
+
readLocalSkillMetadata,
|
|
57
60
|
registeredProjectUpdateSkipped,
|
|
58
61
|
registeredProjectsUpdateFailed,
|
|
59
62
|
registeredProjectsUpdated,
|
|
@@ -66,21 +69,22 @@ import {
|
|
|
66
69
|
uninstallNeedsTerminal,
|
|
67
70
|
uninstallSkillMetadataUnreadable,
|
|
68
71
|
unmarkedAgentsKept
|
|
69
|
-
} from "../chunk-
|
|
72
|
+
} from "../chunk-WVFBBZEP.js";
|
|
70
73
|
import {
|
|
71
74
|
plural
|
|
72
|
-
} from "../chunk-
|
|
75
|
+
} from "../chunk-7OG635DK.js";
|
|
73
76
|
import {
|
|
74
77
|
CLAUDE_DIR,
|
|
75
78
|
DEFAULT_BRANDING,
|
|
76
79
|
EJECT_SOURCE,
|
|
77
|
-
STANDARD_FILES
|
|
78
|
-
|
|
80
|
+
STANDARD_FILES,
|
|
81
|
+
isActiveAt
|
|
82
|
+
} from "../chunk-MHAQWMNJ.js";
|
|
79
83
|
import "../chunk-GHHJYNAN.js";
|
|
80
84
|
|
|
81
85
|
// src/cli/commands/uninstall.tsx
|
|
82
86
|
import "react";
|
|
83
|
-
import { unique } from "remeda";
|
|
87
|
+
import { unique, uniqueBy } from "remeda";
|
|
84
88
|
import path from "path";
|
|
85
89
|
import { Flags } from "@oclif/core";
|
|
86
90
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -96,16 +100,73 @@ function buildRemovalPlan(target) {
|
|
|
96
100
|
kept: keptStatements(target, agents)
|
|
97
101
|
};
|
|
98
102
|
}
|
|
103
|
+
function removalPanel(plan, target) {
|
|
104
|
+
const kept = target.scope === "project" ? globalEntriesOf(target.config) : NOTHING_KEPT;
|
|
105
|
+
return {
|
|
106
|
+
skillConfigs: kept.skills,
|
|
107
|
+
agentConfigs: kept.agents,
|
|
108
|
+
installedSkillConfigs: [...removedSkills(plan, target), ...kept.skills],
|
|
109
|
+
installedAgentConfigs: [...namedAgentRemovals(plan, target.scope).named, ...kept.agents],
|
|
110
|
+
isInitMode: false,
|
|
111
|
+
skillNames: namesTheCopiesRecord(target.cliSkills),
|
|
112
|
+
stackName: void 0
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function namesTheCopiesRecord(cliSkills) {
|
|
116
|
+
return new Map(
|
|
117
|
+
cliSkills.flatMap(
|
|
118
|
+
({ skillId, displayName }) => displayName === void 0 ? [] : [[skillId, displayName]]
|
|
119
|
+
)
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
var NOTHING_KEPT = { skills: [], agents: [] };
|
|
123
|
+
function globalEntriesOf(config) {
|
|
124
|
+
if (config === null) return NOTHING_KEPT;
|
|
125
|
+
return {
|
|
126
|
+
skills: config.skills.filter((skill) => isActiveAt(skill, "global")),
|
|
127
|
+
agents: config.agents.filter((agent) => isActiveAt(agent, "global"))
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function removedSkills(plan, target) {
|
|
131
|
+
const copied = new Set(planEntries(plan, "skills").flatMap((entry) => entry.skillNames));
|
|
132
|
+
const plugins = new Set(planEntries(plan, "plugins").flatMap((entry) => entry.names));
|
|
133
|
+
const marketplaceName = target.config?.marketplaceName;
|
|
134
|
+
const copies = target.cliSkills.filter(({ dirName }) => copied.has(dirName)).map(({ skillId }) => ({ id: skillId, scope: target.scope, origin: EJECT_SOURCE }));
|
|
135
|
+
const pluginSkills = (target.config?.skills ?? []).filter((skill) => !skill.excluded).filter((skill) => pluginRefsOf(skill, marketplaceName).some((ref) => plugins.has(ref))).map((skill) => ({ ...skill, scope: target.scope }));
|
|
136
|
+
return uniqueBy([...copies, ...pluginSkills], (skill) => skill.id);
|
|
137
|
+
}
|
|
138
|
+
function namedAgentRemovals(plan, scope) {
|
|
139
|
+
const entries = planEntries(plan, "agents");
|
|
140
|
+
const names = entries.flatMap((entry) => entry.agentNames);
|
|
141
|
+
return {
|
|
142
|
+
named: names.filter(isAgentName).map((name) => ({ name, scope })),
|
|
143
|
+
files: entries.flatMap(
|
|
144
|
+
(entry) => entry.agentNames.filter((name) => !isAgentName(name)).map((name) => path.join(entry.agentsDir, `${name}${entry.codec.extension}`))
|
|
145
|
+
)
|
|
146
|
+
};
|
|
147
|
+
}
|
|
99
148
|
function hasAnythingToRemove(plan) {
|
|
100
149
|
return plan.entries.length > 0;
|
|
101
150
|
}
|
|
151
|
+
function removedFileLines(plan, scope) {
|
|
152
|
+
const configFiles = planEntries(plan, "config").flatMap(
|
|
153
|
+
(entry) => entry.fileNames.map((fileName) => `${entry.sourceDir}/${fileName}`)
|
|
154
|
+
);
|
|
155
|
+
return [...namedAgentRemovals(plan, scope).files, ...configFiles].map(configFileRemoved);
|
|
156
|
+
}
|
|
102
157
|
function pluginsEntry(target) {
|
|
103
158
|
if (!target.hasPlugins) return [];
|
|
104
159
|
return [{ kind: "plugins", pluginsDir: target.pluginsDir, names: [...target.cliPluginNames] }];
|
|
105
160
|
}
|
|
106
161
|
function localSkillsEntry(target) {
|
|
107
162
|
if (target.cliSkills.length === 0) return [];
|
|
108
|
-
return [
|
|
163
|
+
return [
|
|
164
|
+
{
|
|
165
|
+
kind: "skills",
|
|
166
|
+
skillsDir: target.skillsDir,
|
|
167
|
+
skillNames: target.cliSkills.map(({ dirName }) => dirName)
|
|
168
|
+
}
|
|
169
|
+
];
|
|
109
170
|
}
|
|
110
171
|
function compiledAgentsEntry(target) {
|
|
111
172
|
const agentNames = identifiableAgents(target);
|
|
@@ -138,49 +199,6 @@ function planEntry(plan, kind) {
|
|
|
138
199
|
(entry) => entry.kind === kind
|
|
139
200
|
);
|
|
140
201
|
}
|
|
141
|
-
function describeEntry(entry) {
|
|
142
|
-
switch (entry.kind) {
|
|
143
|
-
case "plugins":
|
|
144
|
-
return { label: UNINSTALL_PLAN.PLUGINS_HEADING, items: entry.names };
|
|
145
|
-
case "skills":
|
|
146
|
-
return {
|
|
147
|
-
label: UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,
|
|
148
|
-
items: [localSkillsRemoval(entry.skillsDir)]
|
|
149
|
-
};
|
|
150
|
-
case "agents":
|
|
151
|
-
return {
|
|
152
|
-
label: UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,
|
|
153
|
-
items: [compiledAgentsRemoval(entry.agentsDir)]
|
|
154
|
-
};
|
|
155
|
-
case "config":
|
|
156
|
-
return {
|
|
157
|
-
label: UNINSTALL_PLAN.CONFIG_HEADING,
|
|
158
|
-
items: entry.fileNames.map((fileName) => `${entry.sourceDir}/${fileName}`)
|
|
159
|
-
};
|
|
160
|
-
default: {
|
|
161
|
-
const _exhaustive = entry;
|
|
162
|
-
return _exhaustive;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
var PLAN_SECTION_ORDER = [
|
|
167
|
-
UNINSTALL_PLAN.PLUGINS_HEADING,
|
|
168
|
-
UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,
|
|
169
|
-
UNINSTALL_PLAN.CONFIG_HEADING
|
|
170
|
-
];
|
|
171
|
-
function planSections(entries) {
|
|
172
|
-
const described = entries.map(describeEntry);
|
|
173
|
-
return PLAN_SECTION_ORDER.flatMap(
|
|
174
|
-
(label) => sectionWithItems(label, itemsUnder(described, label))
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
function itemsUnder(described, label) {
|
|
178
|
-
return described.filter((section) => section.label === label).flatMap((section) => section.items);
|
|
179
|
-
}
|
|
180
|
-
function sectionWithItems(label, items) {
|
|
181
|
-
if (items.length === 0) return [];
|
|
182
|
-
return [{ label, items }];
|
|
183
|
-
}
|
|
184
202
|
var UNINSTALL_CONFIRM_MESSAGE = "Are you sure you want to uninstall?";
|
|
185
203
|
var Uninstall = class _Uninstall extends BaseCommand {
|
|
186
204
|
/** Replaced in `run` before anything prints. */
|
|
@@ -223,7 +241,7 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
223
241
|
this.reportNothingToUninstall();
|
|
224
242
|
return;
|
|
225
243
|
}
|
|
226
|
-
const approved = await this.removalApproved(plan, flags.yes, namedProvider);
|
|
244
|
+
const approved = await this.removalApproved(plan, target, flags.yes, namedProvider);
|
|
227
245
|
if (!approved) this.cancelUninstall();
|
|
228
246
|
await this.executeUninstall(plan, target, projectDir);
|
|
229
247
|
this.reportSuccess();
|
|
@@ -240,9 +258,10 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
240
258
|
this.log("");
|
|
241
259
|
this.log(INFO_MESSAGES.NO_CHANGES_MADE);
|
|
242
260
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
this.
|
|
261
|
+
/** With `--yes` nothing is asked, so the plan prints where the question would be. */
|
|
262
|
+
async removalApproved(plan, target, skipConfirmation, namedProvider) {
|
|
263
|
+
if (!skipConfirmation) return this.confirmRemoval(plan, target, namedProvider);
|
|
264
|
+
this.showRemovalPlan(plan, target);
|
|
246
265
|
return true;
|
|
247
266
|
}
|
|
248
267
|
cancelUninstall() {
|
|
@@ -250,36 +269,22 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
250
269
|
this.log("Uninstall cancelled");
|
|
251
270
|
this.exit(EXIT_CODES.CANCELLED);
|
|
252
271
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
for (const statement of plan.kept) {
|
|
263
|
-
this.log("");
|
|
264
|
-
this.log(statement);
|
|
272
|
+
showRemovalPlan(plan, target) {
|
|
273
|
+
const lines = summaryPanelBlock(
|
|
274
|
+
removalPanel(plan, target),
|
|
275
|
+
removedFileLines(plan, target.scope),
|
|
276
|
+
plan.kept
|
|
277
|
+
);
|
|
278
|
+
for (const line of lines) {
|
|
279
|
+
this.log(line);
|
|
265
280
|
}
|
|
266
|
-
this.log("");
|
|
267
281
|
}
|
|
268
|
-
async confirmRemoval(plan, namedProvider) {
|
|
282
|
+
async confirmRemoval(plan, target, namedProvider) {
|
|
269
283
|
if (!process.stdin.isTTY) {
|
|
270
284
|
this.error(uninstallNeedsTerminal(namedProvider), { exit: EXIT_CODES.ERROR });
|
|
271
285
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
{
|
|
275
|
-
heading: UNINSTALL_PLAN.PREVIEW_HEADING,
|
|
276
|
-
sections: planSections(plan.entries),
|
|
277
|
-
statements: plan.kept,
|
|
278
|
-
message: UNINSTALL_CONFIRM_MESSAGE,
|
|
279
|
-
onConfirm,
|
|
280
|
-
onCancel
|
|
281
|
-
}
|
|
282
|
-
));
|
|
286
|
+
this.showRemovalPlan(plan, target);
|
|
287
|
+
const outcome = await promptConfirm(({ onConfirm, onCancel }) => /* @__PURE__ */ jsx(Confirm, { message: UNINSTALL_CONFIRM_MESSAGE, onConfirm, onCancel }));
|
|
283
288
|
return outcome === "confirmed";
|
|
284
289
|
}
|
|
285
290
|
async executeUninstall(plan, target, projectDir) {
|
|
@@ -288,15 +293,18 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
288
293
|
await this.removePlannedPlugins(planEntry(plan, "plugins"), target.config, projectDir);
|
|
289
294
|
await this.removeLocalFilesOrFail(plan, target);
|
|
290
295
|
if (!isGlobalUninstall) {
|
|
291
|
-
await this.deregisterProject(projectDir);
|
|
296
|
+
await this.deregisterProject(projectDir, target.provider);
|
|
292
297
|
return;
|
|
293
298
|
}
|
|
294
299
|
if (propagation) await this.updateRegisteredProjects(propagation);
|
|
295
300
|
}
|
|
296
301
|
/** Degrades: a missing or corrupt global config must never fail the uninstall. */
|
|
297
|
-
async deregisterProject(projectDir) {
|
|
302
|
+
async deregisterProject(projectDir, provider) {
|
|
298
303
|
try {
|
|
299
|
-
await mutateGlobal(
|
|
304
|
+
await mutateGlobal(
|
|
305
|
+
{ kind: "deregister-project", projectDir, provider },
|
|
306
|
+
lazyGateDeps(projectDir)
|
|
307
|
+
);
|
|
300
308
|
} catch (error) {
|
|
301
309
|
this.warn(`Could not update the global project registry: ${getErrorMessage(error)}`);
|
|
302
310
|
}
|
|
@@ -380,22 +388,27 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
380
388
|
this.reportDirCleanup(target.sourceRoot.relName, cleanup.sourceRoot);
|
|
381
389
|
this.reportDirCleanup(CLAUDE_DIR, cleanup.claudeDir);
|
|
382
390
|
}
|
|
383
|
-
reportSourceFolderCleanup(
|
|
384
|
-
if (
|
|
385
|
-
this.logSuccess(`Removed ${
|
|
386
|
-
|
|
387
|
-
this.logSuccess(`Removed CLI config from ${folder.relName}/`);
|
|
388
|
-
} else if (folder.kept) {
|
|
389
|
-
this.log(`Kept ${folder.relName}/ (contains user content)`);
|
|
391
|
+
reportSourceFolderCleanup({ relName, outcome }) {
|
|
392
|
+
if (outcome === "config-removed") {
|
|
393
|
+
this.logSuccess(`Removed CLI config from ${relName}/`);
|
|
394
|
+
return;
|
|
390
395
|
}
|
|
396
|
+
this.reportDirCleanup(relName, outcome);
|
|
391
397
|
}
|
|
392
398
|
reportDirCleanup(relName, cleanup) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
+
switch (cleanup) {
|
|
400
|
+
case "removed":
|
|
401
|
+
this.logSuccess(`Removed ${relName}/`);
|
|
402
|
+
return;
|
|
403
|
+
case "kept":
|
|
404
|
+
this.log(`Kept ${relName}/ (contains user content)`);
|
|
405
|
+
return;
|
|
406
|
+
case "untouched":
|
|
407
|
+
return;
|
|
408
|
+
default: {
|
|
409
|
+
const _exhaustive = cleanup;
|
|
410
|
+
return _exhaustive;
|
|
411
|
+
}
|
|
399
412
|
}
|
|
400
413
|
}
|
|
401
414
|
async removePlannedPlugins(entry, config, projectDir) {
|
|
@@ -508,6 +521,8 @@ async function detectUninstallTarget(projectDir, handlers) {
|
|
|
508
521
|
const activeConfig = config === null ? null : activeConfigOf(config);
|
|
509
522
|
const cliPluginNames = await pluginsThisRunRemoves(projectDir, activeConfig);
|
|
510
523
|
return {
|
|
524
|
+
scope: isHomeDirectory(projectDir) ? "global" : "project",
|
|
525
|
+
provider,
|
|
511
526
|
hasPlugins: cliPluginNames.length > 0,
|
|
512
527
|
cliPluginNames,
|
|
513
528
|
cliSkills,
|
|
@@ -539,17 +554,22 @@ function thisRunOwnsAnyPlugin(projectDir) {
|
|
|
539
554
|
async function skillsThisCliInstalled(skillsDir, onMetadataUnreadable) {
|
|
540
555
|
const dirNames = await listDirectories(skillsDir);
|
|
541
556
|
const skills = await Promise.all(
|
|
542
|
-
dirNames.map(async (
|
|
543
|
-
|
|
544
|
-
|
|
557
|
+
dirNames.map(async (dirName) => ({
|
|
558
|
+
dirName,
|
|
559
|
+
metadata: await readCopyMetadata(skillsDir, dirName, onMetadataUnreadable)
|
|
545
560
|
}))
|
|
546
561
|
);
|
|
547
|
-
return skills.
|
|
562
|
+
return skills.flatMap(
|
|
563
|
+
({ dirName, metadata }) => metadata?.forkedFrom === void 0 ? [] : [{ dirName, skillId: metadata.forkedFrom.skillId, displayName: recordedName(metadata) }]
|
|
564
|
+
);
|
|
548
565
|
}
|
|
549
|
-
|
|
566
|
+
function recordedName(metadata) {
|
|
567
|
+
return typeof metadata.displayName === "string" ? metadata.displayName : void 0;
|
|
568
|
+
}
|
|
569
|
+
async function readCopyMetadata(skillsDir, dirName, onUnreadable) {
|
|
550
570
|
const skillDir = path.join(skillsDir, dirName);
|
|
551
571
|
try {
|
|
552
|
-
return await
|
|
572
|
+
return await readLocalSkillMetadata(skillDir);
|
|
553
573
|
} catch {
|
|
554
574
|
return onUnreadable(path.join(skillDir, STANDARD_FILES.METADATA_YAML));
|
|
555
575
|
}
|
|
@@ -619,11 +639,11 @@ function nothingWasObserved() {
|
|
|
619
639
|
return "absent";
|
|
620
640
|
}
|
|
621
641
|
async function removeConfigManifest(entry) {
|
|
622
|
-
if (!entry) return
|
|
642
|
+
if (!entry) return false;
|
|
623
643
|
await Promise.all(
|
|
624
644
|
entry.fileNames.map((fileName) => remove(path.join(entry.sourceDir, fileName)))
|
|
625
645
|
);
|
|
626
|
-
return
|
|
646
|
+
return true;
|
|
627
647
|
}
|
|
628
648
|
async function cleanupEmptyDirs(target, manifestEntries) {
|
|
629
649
|
await removeDirIfEmpty(target.skillsDir);
|
|
@@ -632,32 +652,27 @@ async function cleanupEmptyDirs(target, manifestEntries) {
|
|
|
632
652
|
target.sourceFolder,
|
|
633
653
|
manifestEntries.find((entry) => entry.sourceDir === target.sourceFolder.dir)
|
|
634
654
|
);
|
|
635
|
-
const sourceRoot = await cleanupSourceRoot(target.sourceRoot, sourceFolder.
|
|
655
|
+
const sourceRoot = await cleanupSourceRoot(target.sourceRoot, sourceFolder.outcome === "removed");
|
|
636
656
|
const claudeDir = await cleanupClaudeDir(target);
|
|
637
657
|
return { sourceFolder, sourceRoot, claudeDir };
|
|
638
658
|
}
|
|
639
659
|
async function cleanupSourceFolder(folder, entry) {
|
|
640
|
-
const
|
|
641
|
-
const
|
|
642
|
-
const
|
|
643
|
-
return {
|
|
644
|
-
relName: folder.relName,
|
|
645
|
-
manifestRemoved: manifest.manifestRemoved,
|
|
646
|
-
dirRemoved,
|
|
647
|
-
kept
|
|
648
|
-
};
|
|
660
|
+
const manifestRemoved = await removeConfigManifest(entry);
|
|
661
|
+
const dir = await removeDirUnlessUserContent(folder.dir);
|
|
662
|
+
const outcome = manifestRemoved && dir !== "removed" ? "config-removed" : dir;
|
|
663
|
+
return { relName: folder.relName, outcome };
|
|
649
664
|
}
|
|
650
665
|
async function cleanupSourceRoot(sourceRoot, providerDirRemoved) {
|
|
651
|
-
if (!providerDirRemoved) return
|
|
666
|
+
if (!providerDirRemoved) return "untouched";
|
|
652
667
|
return removeDirUnlessUserContent(sourceRoot.dir);
|
|
653
668
|
}
|
|
654
669
|
async function cleanupClaudeDir(target) {
|
|
655
|
-
if (!target.hasClaudeDir) return
|
|
670
|
+
if (!target.hasClaudeDir) return "untouched";
|
|
656
671
|
return removeDirUnlessUserContent(target.claudeDir);
|
|
657
672
|
}
|
|
658
673
|
async function removeDirUnlessUserContent(dir) {
|
|
659
|
-
|
|
660
|
-
return
|
|
674
|
+
if (await removeDirIfEmpty(dir)) return "removed";
|
|
675
|
+
return await directoryExists(dir) ? "kept" : "untouched";
|
|
661
676
|
}
|
|
662
677
|
async function listAgentFiles(agentsDir, codec) {
|
|
663
678
|
try {
|