agents-inc 0.172.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 +14 -0
- package/dist/{chunk-MBIOZ5LW.js → chunk-2RTBSLSR.js} +2 -2
- package/dist/{chunk-255DGUCH.js → chunk-3N4FSTVX.js} +12 -6
- package/dist/{chunk-255DGUCH.js.map → chunk-3N4FSTVX.js.map} +1 -1
- package/dist/{chunk-5MGRHS2G.js → chunk-AARQBW5L.js} +22 -12
- package/dist/chunk-AARQBW5L.js.map +1 -0
- package/dist/{chunk-NISWBQNS.js → chunk-BRZA7ZCX.js} +3 -3
- package/dist/{chunk-LUKDDHSI.js → chunk-EHJIQDXR.js} +2 -2
- package/dist/{chunk-MOL2J5HS.js → chunk-F437ICEG.js} +2 -2
- package/dist/{chunk-KCLBLK3F.js → chunk-ITQF35UQ.js} +3 -3
- package/dist/{chunk-7ZOWSCAO.js → chunk-LJQXQTFC.js} +2 -2
- package/dist/{chunk-6LUTY35Q.js → chunk-Q4UNHVPX.js} +4 -4
- package/dist/{chunk-33JICQD5.js → chunk-Q6WRR4BN.js} +4 -5
- package/dist/{chunk-33JICQD5.js.map → chunk-Q6WRR4BN.js.map} +1 -1
- package/dist/{chunk-5PPB6HT6.js → chunk-SPQSNZMM.js} +2 -2
- package/dist/{chunk-Y23MP2OC.js → chunk-VR6QTK5Z.js} +3 -3
- package/dist/{chunk-6CRA46YO.js → chunk-VSPC74SS.js} +41 -19
- package/dist/chunk-VSPC74SS.js.map +1 -0
- package/dist/{chunk-VILFCMRN.js → chunk-WVFBBZEP.js} +252 -102
- package/dist/chunk-WVFBBZEP.js.map +1 -0
- package/dist/commands/build/marketplace.js +2 -2
- package/dist/commands/build/plugins.js +4 -4
- package/dist/commands/compile.js +10 -10
- package/dist/commands/doctor.js +31 -13
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +13 -13
- package/dist/commands/eject.js +23 -28
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +12 -12
- package/dist/commands/list.js +3 -3
- package/dist/commands/new/marketplace.js +2 -2
- package/dist/commands/search.js +7 -7
- package/dist/commands/share.js +6 -6
- package/dist/commands/uninstall.js +45 -41
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +4 -4
- package/dist/components/common/summary-panel.js +1 -1
- package/dist/hooks/init.js +29 -20
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-E67DSYTN.js +14 -0
- package/dist/{recompile-project-agents-5A44NJRD.js → recompile-project-agents-6G6M2RS6.js} +6 -6
- package/dist/{source-loader-LQNRI5UZ.js → source-loader-W7XCNKNA.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-5MGRHS2G.js.map +0 -1
- package/dist/chunk-6CRA46YO.js.map +0 -1
- package/dist/chunk-VILFCMRN.js.map +0 -1
- package/dist/load-agent-defs-54VIKN4T.js +0 -14
- /package/dist/{chunk-MBIOZ5LW.js.map → chunk-2RTBSLSR.js.map} +0 -0
- /package/dist/{chunk-NISWBQNS.js.map → chunk-BRZA7ZCX.js.map} +0 -0
- /package/dist/{chunk-LUKDDHSI.js.map → chunk-EHJIQDXR.js.map} +0 -0
- /package/dist/{chunk-MOL2J5HS.js.map → chunk-F437ICEG.js.map} +0 -0
- /package/dist/{chunk-KCLBLK3F.js.map → chunk-ITQF35UQ.js.map} +0 -0
- /package/dist/{chunk-7ZOWSCAO.js.map → chunk-LJQXQTFC.js.map} +0 -0
- /package/dist/{chunk-6LUTY35Q.js.map → chunk-Q4UNHVPX.js.map} +0 -0
- /package/dist/{chunk-5PPB6HT6.js.map → chunk-SPQSNZMM.js.map} +0 -0
- /package/dist/{chunk-Y23MP2OC.js.map → chunk-VR6QTK5Z.js.map} +0 -0
- /package/dist/{load-agent-defs-54VIKN4T.js.map → load-agent-defs-E67DSYTN.js.map} +0 -0
- /package/dist/{recompile-project-agents-5A44NJRD.js.map → recompile-project-agents-6G6M2RS6.js.map} +0 -0
- /package/dist/{source-loader-LQNRI5UZ.js.map → source-loader-W7XCNKNA.js.map} +0 -0
|
@@ -7,33 +7,33 @@ import {
|
|
|
7
7
|
} from "../chunk-P6CYS4JK.js";
|
|
8
8
|
import {
|
|
9
9
|
summaryPanelBlock
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-Q6WRR4BN.js";
|
|
11
11
|
import "../chunk-N33AKFLR.js";
|
|
12
12
|
import {
|
|
13
13
|
lazyGateDeps,
|
|
14
14
|
mutateGlobal,
|
|
15
15
|
propagateGlobalRemoval
|
|
16
|
-
} from "../chunk-
|
|
17
|
-
import "../chunk-
|
|
16
|
+
} from "../chunk-VSPC74SS.js";
|
|
17
|
+
import "../chunk-VR6QTK5Z.js";
|
|
18
18
|
import {
|
|
19
19
|
loadAgentDefs
|
|
20
|
-
} from "../chunk-
|
|
21
|
-
import "../chunk-
|
|
20
|
+
} from "../chunk-ITQF35UQ.js";
|
|
21
|
+
import "../chunk-BRZA7ZCX.js";
|
|
22
22
|
import {
|
|
23
23
|
listAgentFilesOf,
|
|
24
24
|
splitAgentsByProvenance
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-EHJIQDXR.js";
|
|
26
26
|
import "../chunk-KIK5EZYD.js";
|
|
27
27
|
import "../chunk-G7NUK3BF.js";
|
|
28
28
|
import {
|
|
29
29
|
providerFlag,
|
|
30
30
|
providerNamedBy,
|
|
31
31
|
refuseAnAmbiguousInstallation
|
|
32
|
-
} from "../chunk-
|
|
32
|
+
} from "../chunk-2RTBSLSR.js";
|
|
33
33
|
import {
|
|
34
34
|
BaseCommand,
|
|
35
35
|
EXIT_CODES
|
|
36
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-LJQXQTFC.js";
|
|
37
37
|
import {
|
|
38
38
|
ConfigLoadError,
|
|
39
39
|
INFO_MESSAGES,
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
uninstallNeedsTerminal,
|
|
70
70
|
uninstallSkillMetadataUnreadable,
|
|
71
71
|
unmarkedAgentsKept
|
|
72
|
-
} from "../chunk-
|
|
72
|
+
} from "../chunk-WVFBBZEP.js";
|
|
73
73
|
import {
|
|
74
74
|
plural
|
|
75
75
|
} from "../chunk-7OG635DK.js";
|
|
@@ -293,15 +293,18 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
293
293
|
await this.removePlannedPlugins(planEntry(plan, "plugins"), target.config, projectDir);
|
|
294
294
|
await this.removeLocalFilesOrFail(plan, target);
|
|
295
295
|
if (!isGlobalUninstall) {
|
|
296
|
-
await this.deregisterProject(projectDir);
|
|
296
|
+
await this.deregisterProject(projectDir, target.provider);
|
|
297
297
|
return;
|
|
298
298
|
}
|
|
299
299
|
if (propagation) await this.updateRegisteredProjects(propagation);
|
|
300
300
|
}
|
|
301
301
|
/** Degrades: a missing or corrupt global config must never fail the uninstall. */
|
|
302
|
-
async deregisterProject(projectDir) {
|
|
302
|
+
async deregisterProject(projectDir, provider) {
|
|
303
303
|
try {
|
|
304
|
-
await mutateGlobal(
|
|
304
|
+
await mutateGlobal(
|
|
305
|
+
{ kind: "deregister-project", projectDir, provider },
|
|
306
|
+
lazyGateDeps(projectDir)
|
|
307
|
+
);
|
|
305
308
|
} catch (error) {
|
|
306
309
|
this.warn(`Could not update the global project registry: ${getErrorMessage(error)}`);
|
|
307
310
|
}
|
|
@@ -385,22 +388,27 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
385
388
|
this.reportDirCleanup(target.sourceRoot.relName, cleanup.sourceRoot);
|
|
386
389
|
this.reportDirCleanup(CLAUDE_DIR, cleanup.claudeDir);
|
|
387
390
|
}
|
|
388
|
-
reportSourceFolderCleanup(
|
|
389
|
-
if (
|
|
390
|
-
this.logSuccess(`Removed ${
|
|
391
|
-
|
|
392
|
-
this.logSuccess(`Removed CLI config from ${folder.relName}/`);
|
|
393
|
-
} else if (folder.kept) {
|
|
394
|
-
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;
|
|
395
395
|
}
|
|
396
|
+
this.reportDirCleanup(relName, outcome);
|
|
396
397
|
}
|
|
397
398
|
reportDirCleanup(relName, cleanup) {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
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
|
+
}
|
|
404
412
|
}
|
|
405
413
|
}
|
|
406
414
|
async removePlannedPlugins(entry, config, projectDir) {
|
|
@@ -514,6 +522,7 @@ async function detectUninstallTarget(projectDir, handlers) {
|
|
|
514
522
|
const cliPluginNames = await pluginsThisRunRemoves(projectDir, activeConfig);
|
|
515
523
|
return {
|
|
516
524
|
scope: isHomeDirectory(projectDir) ? "global" : "project",
|
|
525
|
+
provider,
|
|
517
526
|
hasPlugins: cliPluginNames.length > 0,
|
|
518
527
|
cliPluginNames,
|
|
519
528
|
cliSkills,
|
|
@@ -630,11 +639,11 @@ function nothingWasObserved() {
|
|
|
630
639
|
return "absent";
|
|
631
640
|
}
|
|
632
641
|
async function removeConfigManifest(entry) {
|
|
633
|
-
if (!entry) return
|
|
642
|
+
if (!entry) return false;
|
|
634
643
|
await Promise.all(
|
|
635
644
|
entry.fileNames.map((fileName) => remove(path.join(entry.sourceDir, fileName)))
|
|
636
645
|
);
|
|
637
|
-
return
|
|
646
|
+
return true;
|
|
638
647
|
}
|
|
639
648
|
async function cleanupEmptyDirs(target, manifestEntries) {
|
|
640
649
|
await removeDirIfEmpty(target.skillsDir);
|
|
@@ -643,32 +652,27 @@ async function cleanupEmptyDirs(target, manifestEntries) {
|
|
|
643
652
|
target.sourceFolder,
|
|
644
653
|
manifestEntries.find((entry) => entry.sourceDir === target.sourceFolder.dir)
|
|
645
654
|
);
|
|
646
|
-
const sourceRoot = await cleanupSourceRoot(target.sourceRoot, sourceFolder.
|
|
655
|
+
const sourceRoot = await cleanupSourceRoot(target.sourceRoot, sourceFolder.outcome === "removed");
|
|
647
656
|
const claudeDir = await cleanupClaudeDir(target);
|
|
648
657
|
return { sourceFolder, sourceRoot, claudeDir };
|
|
649
658
|
}
|
|
650
659
|
async function cleanupSourceFolder(folder, entry) {
|
|
651
|
-
const
|
|
652
|
-
const
|
|
653
|
-
const
|
|
654
|
-
return {
|
|
655
|
-
relName: folder.relName,
|
|
656
|
-
manifestRemoved: manifest.manifestRemoved,
|
|
657
|
-
dirRemoved,
|
|
658
|
-
kept
|
|
659
|
-
};
|
|
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 };
|
|
660
664
|
}
|
|
661
665
|
async function cleanupSourceRoot(sourceRoot, providerDirRemoved) {
|
|
662
|
-
if (!providerDirRemoved) return
|
|
666
|
+
if (!providerDirRemoved) return "untouched";
|
|
663
667
|
return removeDirUnlessUserContent(sourceRoot.dir);
|
|
664
668
|
}
|
|
665
669
|
async function cleanupClaudeDir(target) {
|
|
666
|
-
if (!target.hasClaudeDir) return
|
|
670
|
+
if (!target.hasClaudeDir) return "untouched";
|
|
667
671
|
return removeDirUnlessUserContent(target.claudeDir);
|
|
668
672
|
}
|
|
669
673
|
async function removeDirUnlessUserContent(dir) {
|
|
670
|
-
|
|
671
|
-
return
|
|
674
|
+
if (await removeDirIfEmpty(dir)) return "removed";
|
|
675
|
+
return await directoryExists(dir) ? "kept" : "untouched";
|
|
672
676
|
}
|
|
673
677
|
async function listAgentFiles(agentsDir, codec) {
|
|
674
678
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\nimport { unique, uniqueBy } from \"remeda\";\nimport path from \"path\";\n\nimport { Flags } from \"@oclif/core\";\n\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm.js\";\nimport { promptConfirm } from \"../components/common/prompt-confirm.js\";\nimport { summaryPanelBlock, type SummaryPanelProps } from \"../components/common/summary-panel.js\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport {\n directoryExists,\n fileExists,\n listDirectories,\n remove,\n removeDirIfEmpty,\n} from \"../utils/fs\";\nimport { plural } from \"../utils/string\";\nimport { listAgentFilesOf, splitAgentsByProvenance } from \"../lib/agents\";\nimport { hostAt } from \"../lib/hosts/host-for.js\";\nimport type { PluginHost, PluginRemovalOutcome } from \"../lib/hosts/plugin-host.js\";\nimport {\n listPluginNames,\n getProjectPluginsDir,\n buildMarketplacePluginRef,\n parseMarketplacePluginRef,\n} from \"../lib/plugins/index\";\nimport { type LocalSkillMetadata, readLocalSkillMetadata } from \"../lib/skills/skill-metadata\";\nimport { isHomeDirectory, resolveInstallPaths } from \"../lib/installation/index\";\nimport {\n lazyGateDeps,\n mutateGlobal,\n propagateGlobalRemoval,\n type GateReport,\n} from \"../lib/config-gate/index.js\";\nimport { loadSkillsMatrixFromSource } from \"../lib/loading\";\nimport { loadAgentDefs } from \"../lib/operations\";\nimport { ConfigLoadError, loadProjectConfigAt } from \"../lib/configuration/project-config\";\nimport type { Provider } from \"../consts\";\nimport { CLAUDE_DIR, DEFAULT_BRANDING, EJECT_SOURCE, STANDARD_FILES } from \"../consts\";\nimport {\n providerInUse,\n agentCodec,\n type AgentCodec,\n sourceFolderInUse,\n sourceRootOf,\n type SourceRoot,\n} from \"../lib/installation/install-layout.js\";\nimport {\n providerFlag,\n providerNamedBy,\n refuseAnAmbiguousInstallation,\n} from \"../lib/installation/provider-flag.js\";\nimport { isActiveAt } from \"../lib/configuration/scope-predicates.js\";\nimport { isAgentName } from \"../utils/type-guards.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport {\n SUCCESS_MESSAGES,\n INFO_MESSAGES,\n configFileRemoved,\n notInstalledHere,\n pluginLeftRegistered,\n unmarkedAgentsKept,\n registeredProjectsUpdated,\n registeredProjectUpdateSkipped,\n registeredProjectsUpdateFailed,\n uninstallConfigUnreadable,\n uninstallNeedsTerminal,\n uninstallSkillMetadataUnreadable,\n} from \"../utils/messages\";\nimport type {\n AgentDefinition,\n AgentName,\n MergedSkillsMatrix,\n ProjectConfig,\n SkillId,\n} from \"../types/index\";\nimport type { AgentScopeConfig, SkillConfig, SkillScope } from \"../types/config\";\n\n/** Paths and names, never display strings, so the preview and the removal read one value. */\ntype RemovalEntry =\n | { kind: \"plugins\"; pluginsDir: string; names: string[] }\n | { kind: \"skills\"; skillsDir: string; skillNames: string[] }\n | { kind: \"agents\"; agentsDir: string; agentNames: string[]; codec: AgentCodec }\n | { kind: \"config\"; sourceDir: string; fileNames: string[] };\n\ntype PluginRemoval = Extract<RemovalEntry, { kind: \"plugins\" }>;\ntype SkillsRemoval = Extract<RemovalEntry, { kind: \"skills\" }>;\ntype AgentsRemoval = Extract<RemovalEntry, { kind: \"agents\" }>;\ntype ConfigManifestRemoval = Extract<RemovalEntry, { kind: \"config\" }>;\n\ntype RemovalPlan = {\n entries: RemovalEntry[];\n kept: string[];\n};\n\nfunction buildRemovalPlan(target: UninstallTarget): RemovalPlan {\n const agents = compiledAgentsEntry(target);\n\n return {\n entries: [\n ...pluginsEntry(target),\n ...localSkillsEntry(target),\n ...agents,\n ...configManifestEntries(target),\n ],\n kept: keptStatements(target, agents),\n };\n}\n\n/**\n * Its rows are the plan's, never the config's, so the panel names no removal the run will not\n * make. In a project the global entries its config copies stay, so they show as kept.\n */\nfunction removalPanel(plan: RemovalPlan, target: UninstallTarget): SummaryPanelProps {\n const kept = target.scope === \"project\" ? globalEntriesOf(target.config) : NOTHING_KEPT;\n return {\n skillConfigs: kept.skills,\n agentConfigs: kept.agents,\n installedSkillConfigs: [...removedSkills(plan, target), ...kept.skills],\n installedAgentConfigs: [...namedAgentRemovals(plan, target.scope).named, ...kept.agents],\n isInitMode: false,\n skillNames: namesTheCopiesRecord(target.cliSkills),\n stackName: undefined,\n };\n}\n\n/** Uninstall loads no marketplace, so a skill the built-in catalogue lacks is named by its copy. */\nfunction namesTheCopiesRecord(cliSkills: CliSkill[]): ReadonlyMap<SkillId, string> {\n return new Map(\n cliSkills.flatMap(({ skillId, displayName }): [SkillId, string][] =>\n displayName === undefined ? [] : [[skillId, displayName]],\n ),\n );\n}\n\ntype PanelEntries = { skills: SkillConfig[]; agents: AgentScopeConfig[] };\n\nconst NOTHING_KEPT: PanelEntries = { skills: [], agents: [] };\n\nfunction globalEntriesOf(config: ProjectConfig | null): PanelEntries {\n if (config === null) return NOTHING_KEPT;\n return {\n skills: config.skills.filter((skill) => isActiveAt(skill, \"global\")),\n agents: config.agents.filter((agent) => isActiveAt(agent, \"global\")),\n };\n}\n\n/**\n * A copy by the skill its provenance records; a plugin by the config skill it was matched against.\n * One row a skill: a skill registered under two marketplaces' names is still one skill.\n */\nfunction removedSkills(plan: RemovalPlan, target: UninstallTarget): SkillConfig[] {\n const copied = new Set(planEntries(plan, \"skills\").flatMap((entry) => entry.skillNames));\n const plugins = new Set(planEntries(plan, \"plugins\").flatMap((entry) => entry.names));\n const marketplaceName = target.config?.marketplaceName;\n const copies = target.cliSkills\n .filter(({ dirName }) => copied.has(dirName))\n .map(({ skillId }) => ({ id: skillId, scope: target.scope, origin: EJECT_SOURCE }));\n const pluginSkills = (target.config?.skills ?? [])\n .filter((skill) => !skill.excluded)\n .filter((skill) => pluginRefsOf(skill, marketplaceName).some((ref) => plugins.has(ref)))\n .map((skill) => ({ ...skill, scope: target.scope }));\n\n return uniqueBy([...copies, ...pluginSkills], (skill) => skill.id);\n}\n\n/** A compiled file whose name no sub-agent carries is named by its path instead. */\nfunction namedAgentRemovals(\n plan: RemovalPlan,\n scope: SkillScope,\n): { named: AgentScopeConfig[]; files: string[] } {\n const entries = planEntries(plan, \"agents\");\n const names = entries.flatMap((entry) => entry.agentNames);\n return {\n named: names.filter(isAgentName).map((name) => ({ name, scope })),\n files: entries.flatMap((entry) =>\n entry.agentNames\n .filter((name) => !isAgentName(name))\n .map((name) => path.join(entry.agentsDir, `${name}${entry.codec.extension}`)),\n ),\n };\n}\n\nfunction hasAnythingToRemove(plan: RemovalPlan): boolean {\n return plan.entries.length > 0;\n}\n\n/** The files the plan deletes that the panel has no row for, marked as it marks a removal. */\nfunction removedFileLines(plan: RemovalPlan, scope: SkillScope): string[] {\n const configFiles = planEntries(plan, \"config\").flatMap((entry) =>\n entry.fileNames.map((fileName) => `${entry.sourceDir}/${fileName}`),\n );\n return [...namedAgentRemovals(plan, scope).files, ...configFiles].map(configFileRemoved);\n}\n\nfunction pluginsEntry(target: UninstallTarget): PluginRemoval[] {\n if (!target.hasPlugins) return [];\n return [{ kind: \"plugins\", pluginsDir: target.pluginsDir, names: [...target.cliPluginNames] }];\n}\n\nfunction localSkillsEntry(target: UninstallTarget): SkillsRemoval[] {\n if (target.cliSkills.length === 0) return [];\n return [\n {\n kind: \"skills\",\n skillsDir: target.skillsDir,\n skillNames: target.cliSkills.map(({ dirName }) => dirName),\n },\n ];\n}\n\nfunction compiledAgentsEntry(target: UninstallTarget): AgentsRemoval[] {\n const agentNames = identifiableAgents(target);\n if (agentNames.length === 0) return [];\n\n return [{ kind: \"agents\", agentsDir: target.agentsDir, agentNames, codec: target.agentCodec }];\n}\n\n/**\n * Only those with a file here, so the plan names no removal the run will not make: the config's\n * roster (pre-marker installs carry no marker) and every provenance-marked file, each once.\n */\nfunction identifiableAgents(target: UninstallTarget): string[] {\n const agentFiles = new Set([...target.markedAgents, ...target.unmarkedAgents]);\n const configuredWithAFile = target.configuredAgents.filter((name) => agentFiles.has(name));\n return unique([...configuredWithAFile, ...target.markedAgents]);\n}\n\nfunction configManifestEntries(target: UninstallTarget): ConfigManifestRemoval[] {\n const { dir, manifestFiles } = target.sourceFolder;\n if (manifestFiles.length === 0) return [];\n return [{ kind: \"config\", sourceDir: dir, fileNames: manifestFiles }];\n}\n\n/** Derived from the removal, so no agent can be both removed and kept. */\nfunction keptStatements(target: UninstallTarget, agentRemovals: AgentsRemoval[]): string[] {\n const removing = new Set(agentRemovals.flatMap((entry) => entry.agentNames));\n const kept = target.unmarkedAgents.filter((name) => !removing.has(name));\n if (kept.length === 0) return [];\n return [unmarkedAgentsKept(target.agentsDir, kept.length)];\n}\n\nfunction planEntries<K extends RemovalEntry[\"kind\"]>(\n plan: RemovalPlan,\n kind: K,\n): Extract<RemovalEntry, { kind: K }>[] {\n return plan.entries.filter(\n (entry): entry is Extract<RemovalEntry, { kind: K }> => entry.kind === kind,\n );\n}\n\nfunction planEntry<K extends RemovalEntry[\"kind\"]>(\n plan: RemovalPlan,\n kind: K,\n): Extract<RemovalEntry, { kind: K }> | undefined {\n return plan.entries.find(\n (entry): entry is Extract<RemovalEntry, { kind: K }> => entry.kind === kind,\n );\n}\n\nconst UNINSTALL_CONFIRM_MESSAGE = \"Are you sure you want to uninstall?\";\n\nexport default class Uninstall extends BaseCommand {\n /** Replaced in `run` before anything prints. */\n private brandingName: string = DEFAULT_BRANDING.NAME;\n\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 marketplace), compiled agents, plugins, and the config manifest (config.ts + config-types.ts) this project keeps. User-created content is preserved.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n ];\n\n static flags = {\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n provider: providerFlag(),\n };\n\n protected async ensureTerminalSize(): Promise<void> {\n // Any size: uninstall is the way out of every state.\n }\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Uninstall);\n const projectDir = process.cwd();\n const namedProvider = providerNamedBy(flags.provider);\n\n // Before anything is detected: removing the wrong one of two installations is destructive.\n await refuseAnAmbiguousInstallation(projectDir, \"uninstall\", namedProvider, (message) =>\n this.error(message, { exit: EXIT_CODES.INVALID_ARGS }),\n );\n\n this.brandingName = await this.resolveBrandingName(projectDir);\n\n this.printHeader();\n\n const target = await detectUninstallTarget(projectDir, {\n onConfigLoadFailed: (failure) => this.warn(uninstallConfigUnreadable(failure)),\n // Aborts: guessing would either remove the user's skill or keep this CLI's.\n onSkillMetadataUnreadable: (metadataPath) =>\n this.error(uninstallSkillMetadataUnreadable(metadataPath), { exit: EXIT_CODES.ERROR }),\n });\n const plan = buildRemovalPlan(target);\n if (!hasAnythingToRemove(plan)) {\n this.reportNothingToUninstall();\n return;\n }\n\n const approved = await this.removalApproved(plan, target, flags.yes, namedProvider);\n if (!approved) this.cancelUninstall();\n\n await this.executeUninstall(plan, target, projectDir);\n this.reportSuccess();\n }\n\n private printHeader(): void {\n this.log(\"\");\n this.log(`${this.brandingName} Uninstall`);\n this.log(\"\");\n }\n\n private reportNothingToUninstall(): void {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n this.log(notInstalledHere(this.brandingName));\n this.log(\"\");\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n }\n\n /** With `--yes` nothing is asked, so the plan prints where the question would be. */\n private async removalApproved(\n plan: RemovalPlan,\n target: UninstallTarget,\n skipConfirmation: boolean,\n namedProvider: Provider | undefined,\n ): Promise<boolean> {\n if (!skipConfirmation) return this.confirmRemoval(plan, target, namedProvider);\n\n this.showRemovalPlan(plan, target);\n return true;\n }\n\n private cancelUninstall(): never {\n this.log(\"\");\n this.log(\"Uninstall cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n private showRemovalPlan(plan: RemovalPlan, target: UninstallTarget): void {\n const lines = summaryPanelBlock(\n removalPanel(plan, target),\n removedFileLines(plan, target.scope),\n plan.kept,\n );\n for (const line of lines) {\n this.log(line);\n }\n }\n\n private async confirmRemoval(\n plan: RemovalPlan,\n target: UninstallTarget,\n namedProvider: Provider | undefined,\n ): Promise<boolean> {\n // A confirm nobody can answer must never become a yes.\n if (!process.stdin.isTTY) {\n this.error(uninstallNeedsTerminal(namedProvider), { exit: EXIT_CODES.ERROR });\n }\n\n this.showRemovalPlan(plan, target);\n const outcome = await promptConfirm(({ onConfirm, onCancel }) => (\n <Confirm message={UNINSTALL_CONFIRM_MESSAGE} onConfirm={onConfirm} onCancel={onCancel} />\n ));\n return outcome === \"confirmed\";\n }\n\n private async executeUninstall(\n plan: RemovalPlan,\n target: UninstallTarget,\n projectDir: string,\n ): Promise<void> {\n const isGlobalUninstall = isHomeDirectory(projectDir);\n // Before any removal: the registry and source live in the global config about to be deleted.\n const propagation = isGlobalUninstall\n ? await this.prepareGlobalPropagation(target, projectDir)\n : null;\n\n await this.removePlannedPlugins(planEntry(plan, \"plugins\"), target.config, projectDir);\n await this.removeLocalFilesOrFail(plan, target);\n\n if (!isGlobalUninstall) {\n await this.deregisterProject(projectDir);\n return;\n }\n if (propagation) await this.updateRegisteredProjects(propagation);\n }\n\n /** Degrades: a missing or corrupt global config must never fail the uninstall. */\n private async deregisterProject(projectDir: string): Promise<void> {\n try {\n // Lazy deps: deregistering inlines nothing, so the uninstall stays offline.\n await mutateGlobal({ kind: \"deregister-project\", projectDir }, lazyGateDeps(projectDir));\n } catch (error) {\n this.warn(`Could not update the global project registry: ${getErrorMessage(error)}`);\n }\n }\n\n /**\n * A load failure warns and never aborts. `skipExtraSources` cannot change the output (extra\n * sources only annotate skills) and keeps the uninstall off the network.\n */\n private async prepareGlobalPropagation(\n target: UninstallTarget,\n projectDir: string,\n ): Promise<GlobalPropagationData | null> {\n if (target.config === null || target.registeredProjects.length === 0) return null;\n const globalConfig = target.config;\n\n try {\n const [sourceResult, agentDefs] = await Promise.all([\n loadSkillsMatrixFromSource({\n projectDir,\n purpose: \"upkeep\",\n skipExtraSources: true,\n matrixOnly: true,\n }),\n loadAgentDefs(),\n ]);\n return {\n globalConfig,\n matrix: sourceResult.matrix,\n agents: agentDefs.agents,\n provider: providerInUse(projectDir),\n };\n } catch (error) {\n this.warn(registeredProjectsUpdateFailed(getErrorMessage(error)));\n return null;\n }\n }\n\n /** Runs after the global manifest is gone, so regenerated types use the standalone form. */\n private async updateRegisteredProjects(propagation: GlobalPropagationData): Promise<void> {\n try {\n const report = await propagateGlobalRemoval(\n propagation.globalConfig,\n { matrix: propagation.matrix, agents: propagation.agents },\n propagation.provider,\n );\n this.reportRegisteredProjectsUpdate(report);\n } catch (error) {\n this.warn(registeredProjectsUpdateFailed(getErrorMessage(error)));\n }\n }\n\n private reportRegisteredProjectsUpdate(report: GateReport): void {\n const { updated, unreadable, failed } = report.propagated;\n this.reportProjectsOutOfReach(report.propagated);\n for (const skippedPath of [...unreadable, ...failed]) {\n this.warn(registeredProjectUpdateSkipped(skippedPath));\n }\n if (updated.length === 0) return;\n\n this.logSuccess(registeredProjectsUpdated(updated.length));\n this.reportPropagatedRecompile(report);\n }\n\n private reportSuccess(): void {\n this.log(\"\");\n this.log(`${this.brandingName} has been uninstalled.`);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);\n this.log(\"\");\n }\n\n private async removeLocalFilesOrFail(plan: RemovalPlan, target: UninstallTarget): Promise<void> {\n try {\n await this.removeLocalFiles(plan, target);\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 async removeLocalFiles(plan: RemovalPlan, target: UninstallTarget): Promise<void> {\n await this.removePlannedSkills(planEntry(plan, \"skills\"));\n await this.removePlannedAgents(planEntry(plan, \"agents\"));\n\n for (const statement of plan.kept) {\n this.log(statement);\n }\n\n const cleanup = await cleanupEmptyDirs(target, planEntries(plan, \"config\"));\n\n this.reportSourceFolderCleanup(cleanup.sourceFolder);\n this.reportDirCleanup(target.sourceRoot.relName, cleanup.sourceRoot);\n this.reportDirCleanup(CLAUDE_DIR, cleanup.claudeDir);\n }\n\n private reportSourceFolderCleanup(folder: SourceFolderCleanup): void {\n if (folder.dirRemoved) {\n this.logSuccess(`Removed ${folder.relName}/`);\n } else if (folder.manifestRemoved) {\n this.logSuccess(`Removed CLI config from ${folder.relName}/`);\n } else if (folder.kept) {\n this.log(`Kept ${folder.relName}/ (contains user content)`);\n }\n }\n\n private reportDirCleanup(relName: string, cleanup: DirCleanup): void {\n if (cleanup.removed) {\n this.logSuccess(`Removed ${relName}/`);\n return;\n }\n if (cleanup.kept) {\n this.log(`Kept ${relName}/ (contains user content)`);\n }\n }\n\n private async removePlannedPlugins(\n entry: PluginRemoval | undefined,\n config: ProjectConfig | null,\n projectDir: string,\n ): Promise<void> {\n if (!entry) return;\n\n this.log(\"Uninstalling plugins...\");\n\n try {\n const pluginResult = await uninstallPlugins(entry, config, projectDir, {\n onUninstalled: (name) => this.log(` Uninstalled plugin '${name}'`),\n onLeftRegistered: (name, provider) => this.warn(pluginLeftRegistered(name, provider)),\n });\n\n // Silent on zero: \"0\" beside a plan that named one reads as a failure, and is not one.\n if (pluginResult.totalUninstalled > 0) {\n this.logSuccess(`Uninstalled ${plural(pluginResult.totalUninstalled, \"plugin\")}`);\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 private async removePlannedSkills(entry: SkillsRemoval | undefined): Promise<void> {\n if (!entry) return;\n\n const removedNames = await removeMatchingSkills(entry, (dirName) =>\n this.log(` Uninstalled skill '${dirName}'`),\n );\n if (removedNames.length === 0) return;\n\n this.logSuccess(`Removed ${plural(removedNames.length, \"CLI-installed skill\")}`);\n }\n\n private async removePlannedAgents(entry: AgentsRemoval | undefined): Promise<void> {\n if (!entry) return;\n\n const removedNames = await removeMatchingAgents(entry, (agentName) =>\n this.log(` Uninstalled agent '${agentName}'`),\n );\n if (removedNames.length === 0) return;\n\n this.logSuccess(`Removed ${plural(removedNames.length, \"compiled agent\")}`);\n }\n}\n\n/** A skill folder this CLI installed: removed by its folder, shown by the skill and name it records. */\ntype CliSkill = { dirName: string; skillId: SkillId; displayName: string | undefined };\n\ntype UninstallTarget = {\n /** Home is the global scope, so a run there removes global entries. */\n scope: SkillScope;\n hasPlugins: boolean;\n /** Only those this CLI installed, matched against config skills. */\n cliPluginNames: string[];\n /** Carrying `forkedFrom`: this CLI installed them. The rest are the user's, never removed. */\n cliSkills: CliSkill[];\n hasClaudeDir: boolean;\n pluginsDir: string;\n skillsDir: string;\n agentsDir: string;\n agentCodec: AgentCodec;\n claudeDir: string;\n sourceFolder: ScopeSourceFolder;\n sourceRoot: SourceRoot;\n config: ProjectConfig | null;\n registeredProjects: string[];\n configuredAgents: AgentName[];\n markedAgents: string[];\n /** The user's, unless the config claims them. */\n unmarkedAgents: string[];\n};\n\ntype ScopeSourceFolder = {\n dir: string;\n relName: string;\n manifestFiles: string[];\n /** `null` when absent or unreadable. */\n config: ProjectConfig | null;\n};\n\n/** Captured before removal: all of it comes from the config and folder being deleted. */\ntype GlobalPropagationData = {\n globalConfig: ProjectConfig;\n matrix: MergedSkillsMatrix;\n agents: Partial<Record<AgentName, AgentDefinition>>;\n provider: Provider;\n};\n\ntype UninstallPluginsResult = {\n totalUninstalled: number;\n};\n\ntype PluginRemovalReporter = {\n onUninstalled?: (pluginName: string) => void;\n /** No host CLI to ask, so the plugin's registration outlives its folder. */\n onLeftRegistered?: (pluginName: string, provider: Provider) => void;\n};\n\ntype SourceFolderCleanup = {\n relName: string;\n manifestRemoved: boolean;\n dirRemoved: boolean;\n /** Still there because of content this CLI never wrote. */\n kept: boolean;\n};\n\ntype DirCleanup = { removed: boolean; kept: boolean };\n\ntype CleanupResult = {\n sourceFolder: SourceFolderCleanup;\n sourceRoot: DirCleanup;\n claudeDir: DirCleanup;\n};\n\nfunction collectConfiguredAgents(config: Partial<ProjectConfig> | null): AgentName[] {\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 const { marketplaceName } = config;\n return new Set(config.skills.flatMap((skill) => pluginRefsOf(skill, marketplaceName)));\n}\n\nfunction pluginRefsOf(skill: SkillConfig, marketplaceName: string | undefined): string[] {\n const ownRef = buildMarketplacePluginRef(skill.id, skill.origin);\n if (!marketplaceName || skill.origin === marketplaceName || skill.origin === EJECT_SOURCE) {\n return [ownRef];\n }\n // Installed via the marketplace while `origin` names something else.\n return [ownRef, buildMarketplacePluginRef(skill.id, marketplaceName)];\n}\n\n/**\n * Degrades: a `ConfigLoadError` is reported and treated as a missing config, since that is when a\n * user needs to uninstall. Any other failure propagates.\n */\nasync function loadUninstallConfig(\n configPath: string,\n projectDir: string,\n provider: Provider,\n onLoadFailed: (failure: ConfigLoadError) => void,\n): Promise<ProjectConfig | null> {\n try {\n const result = await loadProjectConfigAt(configPath, projectDir, provider);\n return result?.config ?? null;\n } catch (error) {\n if (!(error instanceof ConfigLoadError)) throw error;\n onLoadFailed(error);\n return null;\n }\n}\n\n/** Its config is read under {@link loadUninstallConfig}'s degrade posture. */\nasync function readSourceFolder(\n folder: Pick<ScopeSourceFolder, \"dir\" | \"relName\">,\n projectDir: string,\n provider: Provider,\n onConfigLoadFailed: (failure: ConfigLoadError) => void,\n): Promise<ScopeSourceFolder> {\n const [manifestFiles, config] = await Promise.all([\n manifestFilesIn(folder.dir),\n loadUninstallConfig(\n path.join(folder.dir, STANDARD_FILES.CONFIG_TS),\n projectDir,\n provider,\n onConfigLoadFailed,\n ),\n ]);\n return { ...folder, manifestFiles, config };\n}\n\nasync function manifestFilesIn(dir: string): Promise<string[]> {\n const manifest = [STANDARD_FILES.CONFIG_TS, STANDARD_FILES.CONFIG_TYPES_TS];\n const present = await Promise.all(\n manifest.map((fileName) => fileExists(path.join(dir, fileName))),\n );\n return manifest.filter((_, index) => present[index]);\n}\n\nfunction activeConfigOf(config: ProjectConfig): ProjectConfig {\n return {\n ...config,\n skills: config.skills.filter((s) => !s.excluded),\n agents: config.agents.filter((a) => !a.excluded),\n };\n}\n\ntype DetectionFailureHandlers = {\n /** Degrades: see {@link loadUninstallConfig}. */\n onConfigLoadFailed: (failure: ConfigLoadError) => void;\n onSkillMetadataUnreadable: (metadataPath: string) => never;\n};\n\nasync function detectUninstallTarget(\n projectDir: string,\n handlers: DetectionFailureHandlers,\n): Promise<UninstallTarget> {\n const pluginsDir = getProjectPluginsDir(projectDir);\n const { skillsDir, agentsDir } = resolveInstallPaths(projectDir);\n const claudeDir = path.join(projectDir, CLAUDE_DIR);\n const provider = providerInUse(projectDir);\n const codec = agentCodec(provider);\n\n const [cliSkills, hasClaudeDir, sourceFolder, agentProvenance] = await Promise.all([\n skillsThisCliInstalled(skillsDir, handlers.onSkillMetadataUnreadable),\n directoryExists(claudeDir),\n readSourceFolder(\n sourceFolderInUse(projectDir, provider),\n projectDir,\n provider,\n handlers.onConfigLoadFailed,\n ),\n splitAgentsByProvenance(agentsDir, codec),\n ]);\n\n const { config } = sourceFolder;\n const activeConfig = config === null ? null : activeConfigOf(config);\n const cliPluginNames = await pluginsThisRunRemoves(projectDir, activeConfig);\n\n return {\n scope: isHomeDirectory(projectDir) ? \"global\" : \"project\",\n hasPlugins: cliPluginNames.length > 0,\n cliPluginNames,\n cliSkills,\n hasClaudeDir,\n pluginsDir,\n skillsDir,\n agentsDir,\n claudeDir,\n sourceFolder,\n sourceRoot: sourceRootOf(projectDir),\n config,\n registeredProjects: config?.projects ?? [],\n configuredAgents: collectConfiguredAgents(activeConfig),\n agentCodec: codec,\n markedAgents: agentProvenance.marked,\n unmarkedAgents: agentProvenance.unmarked,\n };\n}\n\nasync function pluginsThisRunRemoves(\n projectDir: string,\n activeConfig: ProjectConfig | null,\n): Promise<string[]> {\n const installed = await listPluginNames(projectDir);\n if (!thisRunOwnsAnyPlugin(projectDir)) return [];\n\n const cliInstalledKeys = getCliInstalledPluginKeys(activeConfig);\n return installed.filter((name) => cliInstalledKeys.has(name));\n}\n\n/**\n * A host without project-scoped plugins (Codex) shares them machine-wide, so a project uninstall\n * there must not sweep them. A global uninstall owns them on any host.\n */\nfunction thisRunOwnsAnyPlugin(projectDir: string): boolean {\n if (isHomeDirectory(projectDir)) return true;\n return hostAt(projectDir).installsProjectScopedPlugins;\n}\n\n/** Read before the plan is built, so the plan and the removal read one classification. */\nasync function skillsThisCliInstalled(\n skillsDir: string,\n onMetadataUnreadable: (metadataPath: string) => never,\n): Promise<CliSkill[]> {\n const dirNames = await listDirectories(skillsDir);\n const skills = await Promise.all(\n dirNames.map(async (dirName) => ({\n dirName,\n metadata: await readCopyMetadata(skillsDir, dirName, onMetadataUnreadable),\n })),\n );\n return skills.flatMap(({ dirName, metadata }) =>\n metadata?.forkedFrom === undefined\n ? []\n : [{ dirName, skillId: metadata.forkedFrom.skillId, displayName: recordedName(metadata) }],\n );\n}\n\n/** Only for the panel: a copy naming itself no way is drawn by the catalogue's name, or its id. */\nfunction recordedName(metadata: LocalSkillMetadata): string | undefined {\n return typeof metadata.displayName === \"string\" ? metadata.displayName : undefined;\n}\n\n/**\n * A metadata.yaml that reads but does not parse is the user's (warned); one found but unreadable\n * aborts. A skill folder that cannot be opened hides its metadata.yaml (`fileExists` answers\n * false on EACCES), so that skill reads as the user's and is kept, even when this CLI made it.\n */\nasync function readCopyMetadata(\n skillsDir: string,\n dirName: string,\n onUnreadable: (metadataPath: string) => never,\n): Promise<LocalSkillMetadata | null> {\n const skillDir = path.join(skillsDir, dirName);\n try {\n return await readLocalSkillMetadata(skillDir);\n } catch {\n // Cause dropped on purpose: the stop names the file and the fix only, and uninstall has no\n // --verbose to carry it.\n return onUnreadable(path.join(skillDir, STANDARD_FILES.METADATA_YAML));\n }\n}\n\n/** The planned skills still there: the count is what the run removed, not what it planned. */\nasync function removeMatchingSkills(\n entry: SkillsRemoval,\n onRemoved: (dirName: string) => void,\n): Promise<string[]> {\n const present = await listDirectories(entry.skillsDir);\n const removedNames = present.filter((name) => entry.skillNames.includes(name));\n\n for (const name of removedNames) {\n await remove(path.join(entry.skillsDir, name));\n onRemoved(name);\n }\n return removedNames;\n}\n\nasync function removeMatchingAgents(\n entry: AgentsRemoval,\n onRemoved: (agentName: string) => void,\n): Promise<string[]> {\n const agentFiles = await listAgentFiles(entry.agentsDir, entry.codec);\n const removedNames = agentFiles\n .map((agentFile) => path.basename(agentFile, entry.codec.extension))\n .filter((agentName) => entry.agentNames.includes(agentName));\n\n for (const agentName of removedNames) {\n await remove(path.join(entry.agentsDir, `${agentName}${entry.codec.extension}`));\n onRemoved(agentName);\n }\n return removedNames;\n}\n\nconst SCOPE_OF_AN_UNRECORDED_SKILL: SkillScope = \"project\";\n\n/** Every offered plugin scope, the config's first: a re-scoped skill stays where installed. */\nfunction pluginScopesToSweep(host: PluginHost, primary: SkillScope): SkillScope[] {\n const offered = host.offeredPlacements\n .filter((placement) => placement.mode === \"plugin\")\n .map((placement) => placement.scope);\n\n if (!offered.includes(primary)) return offered;\n return [primary, ...offered.filter((scope) => scope !== primary)];\n}\n\n/** Failures are swallowed: the directory is deleted either way and files are already gone. */\nasync function removePluginWhereverItIsFiled(\n host: PluginHost,\n pluginRef: string,\n primaryScope: SkillScope,\n projectDir: string,\n): Promise<PluginRemovalOutcome> {\n let outcome: PluginRemovalOutcome = \"absent\";\n\n for (const scope of pluginScopesToSweep(host, primaryScope)) {\n try {\n const swept = await host.uninstallPlugin(pluginRef, scope, projectDir);\n if (swept === \"removed\") outcome = \"removed\";\n } catch {\n // A throw is neither outcome, so `outcome` stays as the other scopes left it.\n }\n }\n\n return outcome;\n}\n\n/** `config` only supplies the scope each plugin is filed under; the entry decides which go. */\nasync function uninstallPlugins(\n entry: PluginRemoval,\n config: ProjectConfig | null,\n projectDir: string,\n { onUninstalled, onLeftRegistered }: PluginRemovalReporter = {},\n): Promise<UninstallPluginsResult> {\n const host = hostAt(projectDir);\n const hostAvailable = await host.isAvailable();\n const observed: string[] = [];\n\n if (!hostAvailable) {\n for (const pluginName of entry.names) onLeftRegistered?.(pluginName, host.provider);\n }\n\n for (const pluginName of entry.names) {\n const removal = hostAvailable\n ? await removePluginWhereverItIsFiled(\n host,\n pluginName,\n scopeThePluginIsFiledUnder(config, pluginName),\n projectDir,\n )\n : nothingWasObserved();\n\n await remove(path.join(entry.pluginsDir, pluginName));\n\n if (removal === \"removed\") {\n observed.push(pluginName);\n onUninstalled?.(pluginName);\n }\n }\n\n // Observed, not intended: Codex `plugin remove` exits 0 whether or not the plugin existed.\n return { totalUninstalled: observed.length };\n}\n\nfunction scopeThePluginIsFiledUnder(config: ProjectConfig | null, pluginName: string): SkillScope {\n const skillId = parseMarketplacePluginRef(pluginName);\n return (\n config?.skills.find((skill) => skill.id === skillId)?.scope ?? SCOPE_OF_AN_UNRECORDED_SKILL\n );\n}\n\nfunction nothingWasObserved(): PluginRemovalOutcome {\n return \"absent\";\n}\n\nasync function removeConfigManifest(\n entry: ConfigManifestRemoval | undefined,\n): Promise<{ manifestRemoved: boolean; dirRemoved: boolean }> {\n if (!entry) return { manifestRemoved: false, dirRemoved: false };\n\n await Promise.all(\n entry.fileNames.map((fileName) => remove(path.join(entry.sourceDir, fileName))),\n );\n\n return { manifestRemoved: true, dirRemoved: await removeDirIfEmpty(entry.sourceDir) };\n}\n\n/** Directories are not plan entries: each goes only once nothing of the user's is left in it. */\nasync function cleanupEmptyDirs(\n target: Pick<\n UninstallTarget,\n \"skillsDir\" | \"agentsDir\" | \"hasClaudeDir\" | \"claudeDir\" | \"sourceRoot\" | \"sourceFolder\"\n >,\n manifestEntries: readonly ConfigManifestRemoval[],\n): Promise<CleanupResult> {\n // Whether or not the plan named a removal there: a folder holding nothing is no one's.\n await removeDirIfEmpty(target.skillsDir);\n await removeDirIfEmpty(target.agentsDir);\n\n const sourceFolder = await cleanupSourceFolder(\n target.sourceFolder,\n manifestEntries.find((entry) => entry.sourceDir === target.sourceFolder.dir),\n );\n const sourceRoot = await cleanupSourceRoot(target.sourceRoot, sourceFolder.dirRemoved);\n const claudeDir = await cleanupClaudeDir(target);\n\n return { sourceFolder, sourceRoot, claudeDir };\n}\n\nasync function cleanupSourceFolder(\n folder: ScopeSourceFolder,\n entry: ConfigManifestRemoval | undefined,\n): Promise<SourceFolderCleanup> {\n const manifest = await removeConfigManifest(entry);\n const dirRemoved = manifest.dirRemoved || (await removeDirIfEmpty(folder.dir));\n const kept = !dirRemoved && (await directoryExists(folder.dir));\n return {\n relName: folder.relName,\n manifestRemoved: manifest.manifestRemoved,\n dirRemoved,\n kept,\n };\n}\n\n/**\n * Only once the provider folder went, and only when empty: consuming repositories keep their own\n * state under `.agents-inc/`.\n */\nasync function cleanupSourceRoot(\n sourceRoot: SourceRoot,\n providerDirRemoved: boolean,\n): Promise<DirCleanup> {\n if (!providerDirRemoved) return { removed: false, kept: false };\n return removeDirUnlessUserContent(sourceRoot.dir);\n}\n\nasync function cleanupClaudeDir(\n target: Pick<UninstallTarget, \"hasClaudeDir\" | \"claudeDir\">,\n): Promise<DirCleanup> {\n if (!target.hasClaudeDir) return { removed: false, kept: false };\n return removeDirUnlessUserContent(target.claudeDir);\n}\n\n/** `kept` when it is still there: something of the user's is in it. */\nasync function removeDirUnlessUserContent(dir: string): Promise<DirCleanup> {\n const removed = await removeDirIfEmpty(dir);\n return { removed, kept: !removed && (await directoryExists(dir)) };\n}\n\nasync function listAgentFiles(agentsDir: string, codec: AgentCodec): Promise<string[]> {\n try {\n return await listAgentFilesOf(agentsDir, codec);\n } catch {\n return [];\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\nimport { unique, uniqueBy } from \"remeda\";\nimport path from \"path\";\n\nimport { Flags } from \"@oclif/core\";\n\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm.js\";\nimport { promptConfirm } from \"../components/common/prompt-confirm.js\";\nimport { summaryPanelBlock, type SummaryPanelProps } from \"../components/common/summary-panel.js\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport {\n directoryExists,\n fileExists,\n listDirectories,\n remove,\n removeDirIfEmpty,\n} from \"../utils/fs\";\nimport { plural } from \"../utils/string\";\nimport { listAgentFilesOf, splitAgentsByProvenance } from \"../lib/agents\";\nimport { hostAt } from \"../lib/hosts/host-for.js\";\nimport type { PluginHost, PluginRemovalOutcome } from \"../lib/hosts/plugin-host.js\";\nimport {\n listPluginNames,\n getProjectPluginsDir,\n buildMarketplacePluginRef,\n parseMarketplacePluginRef,\n} from \"../lib/plugins/index\";\nimport { type LocalSkillMetadata, readLocalSkillMetadata } from \"../lib/skills/skill-metadata\";\nimport { isHomeDirectory, resolveInstallPaths } from \"../lib/installation/index\";\nimport {\n lazyGateDeps,\n mutateGlobal,\n propagateGlobalRemoval,\n type GateReport,\n} from \"../lib/config-gate/index.js\";\nimport { loadSkillsMatrixFromSource } from \"../lib/loading\";\nimport { loadAgentDefs } from \"../lib/operations\";\nimport { ConfigLoadError, loadProjectConfigAt } from \"../lib/configuration/project-config\";\nimport type { Provider } from \"../consts\";\nimport { CLAUDE_DIR, DEFAULT_BRANDING, EJECT_SOURCE, STANDARD_FILES } from \"../consts\";\nimport {\n providerInUse,\n agentCodec,\n type AgentCodec,\n sourceFolderInUse,\n sourceRootOf,\n type SourceRoot,\n} from \"../lib/installation/install-layout.js\";\nimport {\n providerFlag,\n providerNamedBy,\n refuseAnAmbiguousInstallation,\n} from \"../lib/installation/provider-flag.js\";\nimport { isActiveAt } from \"../lib/configuration/scope-predicates.js\";\nimport { isAgentName } from \"../utils/type-guards.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport {\n SUCCESS_MESSAGES,\n INFO_MESSAGES,\n configFileRemoved,\n notInstalledHere,\n pluginLeftRegistered,\n unmarkedAgentsKept,\n registeredProjectsUpdated,\n registeredProjectUpdateSkipped,\n registeredProjectsUpdateFailed,\n uninstallConfigUnreadable,\n uninstallNeedsTerminal,\n uninstallSkillMetadataUnreadable,\n} from \"../utils/messages\";\nimport type {\n AgentDefinition,\n AgentName,\n MergedSkillsMatrix,\n ProjectConfig,\n SkillId,\n} from \"../types/index\";\nimport type { AgentScopeConfig, SkillConfig, SkillScope } from \"../types/config\";\n\n/** Paths and names, never display strings, so the preview and the removal read one value. */\ntype RemovalEntry =\n | { kind: \"plugins\"; pluginsDir: string; names: string[] }\n | { kind: \"skills\"; skillsDir: string; skillNames: string[] }\n | { kind: \"agents\"; agentsDir: string; agentNames: string[]; codec: AgentCodec }\n | { kind: \"config\"; sourceDir: string; fileNames: string[] };\n\ntype PluginRemoval = Extract<RemovalEntry, { kind: \"plugins\" }>;\ntype SkillsRemoval = Extract<RemovalEntry, { kind: \"skills\" }>;\ntype AgentsRemoval = Extract<RemovalEntry, { kind: \"agents\" }>;\ntype ConfigManifestRemoval = Extract<RemovalEntry, { kind: \"config\" }>;\n\ntype RemovalPlan = {\n entries: RemovalEntry[];\n kept: string[];\n};\n\nfunction buildRemovalPlan(target: UninstallTarget): RemovalPlan {\n const agents = compiledAgentsEntry(target);\n\n return {\n entries: [\n ...pluginsEntry(target),\n ...localSkillsEntry(target),\n ...agents,\n ...configManifestEntries(target),\n ],\n kept: keptStatements(target, agents),\n };\n}\n\n/**\n * Its rows are the plan's, never the config's, so the panel names no removal the run will not\n * make. In a project the global entries its config copies stay, so they show as kept.\n */\nfunction removalPanel(plan: RemovalPlan, target: UninstallTarget): SummaryPanelProps {\n const kept = target.scope === \"project\" ? globalEntriesOf(target.config) : NOTHING_KEPT;\n return {\n skillConfigs: kept.skills,\n agentConfigs: kept.agents,\n installedSkillConfigs: [...removedSkills(plan, target), ...kept.skills],\n installedAgentConfigs: [...namedAgentRemovals(plan, target.scope).named, ...kept.agents],\n isInitMode: false,\n skillNames: namesTheCopiesRecord(target.cliSkills),\n stackName: undefined,\n };\n}\n\n/** Uninstall loads no marketplace, so a skill the built-in catalogue lacks is named by its copy. */\nfunction namesTheCopiesRecord(cliSkills: CliSkill[]): ReadonlyMap<SkillId, string> {\n return new Map(\n cliSkills.flatMap(({ skillId, displayName }): [SkillId, string][] =>\n displayName === undefined ? [] : [[skillId, displayName]],\n ),\n );\n}\n\ntype PanelEntries = { skills: SkillConfig[]; agents: AgentScopeConfig[] };\n\nconst NOTHING_KEPT: PanelEntries = { skills: [], agents: [] };\n\nfunction globalEntriesOf(config: ProjectConfig | null): PanelEntries {\n if (config === null) return NOTHING_KEPT;\n return {\n skills: config.skills.filter((skill) => isActiveAt(skill, \"global\")),\n agents: config.agents.filter((agent) => isActiveAt(agent, \"global\")),\n };\n}\n\n/**\n * A copy by the skill its provenance records; a plugin by the config skill it was matched against.\n * One row a skill: a skill registered under two marketplaces' names is still one skill.\n */\nfunction removedSkills(plan: RemovalPlan, target: UninstallTarget): SkillConfig[] {\n const copied = new Set(planEntries(plan, \"skills\").flatMap((entry) => entry.skillNames));\n const plugins = new Set(planEntries(plan, \"plugins\").flatMap((entry) => entry.names));\n const marketplaceName = target.config?.marketplaceName;\n const copies = target.cliSkills\n .filter(({ dirName }) => copied.has(dirName))\n .map(({ skillId }) => ({ id: skillId, scope: target.scope, origin: EJECT_SOURCE }));\n const pluginSkills = (target.config?.skills ?? [])\n .filter((skill) => !skill.excluded)\n .filter((skill) => pluginRefsOf(skill, marketplaceName).some((ref) => plugins.has(ref)))\n .map((skill) => ({ ...skill, scope: target.scope }));\n\n return uniqueBy([...copies, ...pluginSkills], (skill) => skill.id);\n}\n\n/** A compiled file whose name no sub-agent carries is named by its path instead. */\nfunction namedAgentRemovals(\n plan: RemovalPlan,\n scope: SkillScope,\n): { named: AgentScopeConfig[]; files: string[] } {\n const entries = planEntries(plan, \"agents\");\n const names = entries.flatMap((entry) => entry.agentNames);\n return {\n named: names.filter(isAgentName).map((name) => ({ name, scope })),\n files: entries.flatMap((entry) =>\n entry.agentNames\n .filter((name) => !isAgentName(name))\n .map((name) => path.join(entry.agentsDir, `${name}${entry.codec.extension}`)),\n ),\n };\n}\n\nfunction hasAnythingToRemove(plan: RemovalPlan): boolean {\n return plan.entries.length > 0;\n}\n\n/** The files the plan deletes that the panel has no row for, marked as it marks a removal. */\nfunction removedFileLines(plan: RemovalPlan, scope: SkillScope): string[] {\n const configFiles = planEntries(plan, \"config\").flatMap((entry) =>\n entry.fileNames.map((fileName) => `${entry.sourceDir}/${fileName}`),\n );\n return [...namedAgentRemovals(plan, scope).files, ...configFiles].map(configFileRemoved);\n}\n\nfunction pluginsEntry(target: UninstallTarget): PluginRemoval[] {\n if (!target.hasPlugins) return [];\n return [{ kind: \"plugins\", pluginsDir: target.pluginsDir, names: [...target.cliPluginNames] }];\n}\n\nfunction localSkillsEntry(target: UninstallTarget): SkillsRemoval[] {\n if (target.cliSkills.length === 0) return [];\n return [\n {\n kind: \"skills\",\n skillsDir: target.skillsDir,\n skillNames: target.cliSkills.map(({ dirName }) => dirName),\n },\n ];\n}\n\nfunction compiledAgentsEntry(target: UninstallTarget): AgentsRemoval[] {\n const agentNames = identifiableAgents(target);\n if (agentNames.length === 0) return [];\n\n return [{ kind: \"agents\", agentsDir: target.agentsDir, agentNames, codec: target.agentCodec }];\n}\n\n/**\n * Only those with a file here, so the plan names no removal the run will not make: the config's\n * roster (pre-marker installs carry no marker) and every provenance-marked file, each once.\n */\nfunction identifiableAgents(target: UninstallTarget): string[] {\n const agentFiles = new Set([...target.markedAgents, ...target.unmarkedAgents]);\n const configuredWithAFile = target.configuredAgents.filter((name) => agentFiles.has(name));\n return unique([...configuredWithAFile, ...target.markedAgents]);\n}\n\nfunction configManifestEntries(target: UninstallTarget): ConfigManifestRemoval[] {\n const { dir, manifestFiles } = target.sourceFolder;\n if (manifestFiles.length === 0) return [];\n return [{ kind: \"config\", sourceDir: dir, fileNames: manifestFiles }];\n}\n\n/** Derived from the removal, so no agent can be both removed and kept. */\nfunction keptStatements(target: UninstallTarget, agentRemovals: AgentsRemoval[]): string[] {\n const removing = new Set(agentRemovals.flatMap((entry) => entry.agentNames));\n const kept = target.unmarkedAgents.filter((name) => !removing.has(name));\n if (kept.length === 0) return [];\n return [unmarkedAgentsKept(target.agentsDir, kept.length)];\n}\n\nfunction planEntries<K extends RemovalEntry[\"kind\"]>(\n plan: RemovalPlan,\n kind: K,\n): Extract<RemovalEntry, { kind: K }>[] {\n return plan.entries.filter(\n (entry): entry is Extract<RemovalEntry, { kind: K }> => entry.kind === kind,\n );\n}\n\nfunction planEntry<K extends RemovalEntry[\"kind\"]>(\n plan: RemovalPlan,\n kind: K,\n): Extract<RemovalEntry, { kind: K }> | undefined {\n return plan.entries.find(\n (entry): entry is Extract<RemovalEntry, { kind: K }> => entry.kind === kind,\n );\n}\n\nconst UNINSTALL_CONFIRM_MESSAGE = \"Are you sure you want to uninstall?\";\n\nexport default class Uninstall extends BaseCommand {\n /** Replaced in `run` before anything prints. */\n private brandingName: string = DEFAULT_BRANDING.NAME;\n\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 marketplace), compiled agents, plugins, and the config manifest (config.ts + config-types.ts) this project keeps. User-created content is preserved.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n ];\n\n static flags = {\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n provider: providerFlag(),\n };\n\n protected async ensureTerminalSize(): Promise<void> {\n // Any size: uninstall is the way out of every state.\n }\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Uninstall);\n const projectDir = process.cwd();\n const namedProvider = providerNamedBy(flags.provider);\n\n // Before anything is detected: removing the wrong one of two installations is destructive.\n await refuseAnAmbiguousInstallation(projectDir, \"uninstall\", namedProvider, (message) =>\n this.error(message, { exit: EXIT_CODES.INVALID_ARGS }),\n );\n\n this.brandingName = await this.resolveBrandingName(projectDir);\n\n this.printHeader();\n\n const target = await detectUninstallTarget(projectDir, {\n onConfigLoadFailed: (failure) => this.warn(uninstallConfigUnreadable(failure)),\n // Aborts: guessing would either remove the user's skill or keep this CLI's.\n onSkillMetadataUnreadable: (metadataPath) =>\n this.error(uninstallSkillMetadataUnreadable(metadataPath), { exit: EXIT_CODES.ERROR }),\n });\n const plan = buildRemovalPlan(target);\n if (!hasAnythingToRemove(plan)) {\n this.reportNothingToUninstall();\n return;\n }\n\n const approved = await this.removalApproved(plan, target, flags.yes, namedProvider);\n if (!approved) this.cancelUninstall();\n\n await this.executeUninstall(plan, target, projectDir);\n this.reportSuccess();\n }\n\n private printHeader(): void {\n this.log(\"\");\n this.log(`${this.brandingName} Uninstall`);\n this.log(\"\");\n }\n\n private reportNothingToUninstall(): void {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n this.log(notInstalledHere(this.brandingName));\n this.log(\"\");\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n }\n\n /** With `--yes` nothing is asked, so the plan prints where the question would be. */\n private async removalApproved(\n plan: RemovalPlan,\n target: UninstallTarget,\n skipConfirmation: boolean,\n namedProvider: Provider | undefined,\n ): Promise<boolean> {\n if (!skipConfirmation) return this.confirmRemoval(plan, target, namedProvider);\n\n this.showRemovalPlan(plan, target);\n return true;\n }\n\n private cancelUninstall(): never {\n this.log(\"\");\n this.log(\"Uninstall cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n private showRemovalPlan(plan: RemovalPlan, target: UninstallTarget): void {\n const lines = summaryPanelBlock(\n removalPanel(plan, target),\n removedFileLines(plan, target.scope),\n plan.kept,\n );\n for (const line of lines) {\n this.log(line);\n }\n }\n\n private async confirmRemoval(\n plan: RemovalPlan,\n target: UninstallTarget,\n namedProvider: Provider | undefined,\n ): Promise<boolean> {\n // A confirm nobody can answer must never become a yes.\n if (!process.stdin.isTTY) {\n this.error(uninstallNeedsTerminal(namedProvider), { exit: EXIT_CODES.ERROR });\n }\n\n this.showRemovalPlan(plan, target);\n const outcome = await promptConfirm(({ onConfirm, onCancel }) => (\n <Confirm message={UNINSTALL_CONFIRM_MESSAGE} onConfirm={onConfirm} onCancel={onCancel} />\n ));\n return outcome === \"confirmed\";\n }\n\n private async executeUninstall(\n plan: RemovalPlan,\n target: UninstallTarget,\n projectDir: string,\n ): Promise<void> {\n const isGlobalUninstall = isHomeDirectory(projectDir);\n // Before any removal: the registry and source live in the global config about to be deleted.\n const propagation = isGlobalUninstall\n ? await this.prepareGlobalPropagation(target, projectDir)\n : null;\n\n await this.removePlannedPlugins(planEntry(plan, \"plugins\"), target.config, projectDir);\n await this.removeLocalFilesOrFail(plan, target);\n\n if (!isGlobalUninstall) {\n await this.deregisterProject(projectDir, target.provider);\n return;\n }\n if (propagation) await this.updateRegisteredProjects(propagation);\n }\n\n /** Degrades: a missing or corrupt global config must never fail the uninstall. */\n private async deregisterProject(projectDir: string, provider: Provider): Promise<void> {\n try {\n // Lazy deps: deregistering inlines nothing, so the uninstall stays offline.\n await mutateGlobal(\n { kind: \"deregister-project\", projectDir, provider },\n lazyGateDeps(projectDir),\n );\n } catch (error) {\n this.warn(`Could not update the global project registry: ${getErrorMessage(error)}`);\n }\n }\n\n /**\n * A load failure warns and never aborts. `skipExtraSources` cannot change the output (extra\n * sources only annotate skills) and keeps the uninstall off the network.\n */\n private async prepareGlobalPropagation(\n target: UninstallTarget,\n projectDir: string,\n ): Promise<GlobalPropagationData | null> {\n if (target.config === null || target.registeredProjects.length === 0) return null;\n const globalConfig = target.config;\n\n try {\n const [sourceResult, agentDefs] = await Promise.all([\n loadSkillsMatrixFromSource({\n projectDir,\n purpose: \"upkeep\",\n skipExtraSources: true,\n matrixOnly: true,\n }),\n loadAgentDefs(),\n ]);\n return {\n globalConfig,\n matrix: sourceResult.matrix,\n agents: agentDefs.agents,\n provider: providerInUse(projectDir),\n };\n } catch (error) {\n this.warn(registeredProjectsUpdateFailed(getErrorMessage(error)));\n return null;\n }\n }\n\n /** Runs after the global manifest is gone, so regenerated types use the standalone form. */\n private async updateRegisteredProjects(propagation: GlobalPropagationData): Promise<void> {\n try {\n const report = await propagateGlobalRemoval(\n propagation.globalConfig,\n { matrix: propagation.matrix, agents: propagation.agents },\n propagation.provider,\n );\n this.reportRegisteredProjectsUpdate(report);\n } catch (error) {\n this.warn(registeredProjectsUpdateFailed(getErrorMessage(error)));\n }\n }\n\n private reportRegisteredProjectsUpdate(report: GateReport): void {\n const { updated, unreadable, failed } = report.propagated;\n this.reportProjectsOutOfReach(report.propagated);\n for (const skippedPath of [...unreadable, ...failed]) {\n this.warn(registeredProjectUpdateSkipped(skippedPath));\n }\n if (updated.length === 0) return;\n\n this.logSuccess(registeredProjectsUpdated(updated.length));\n this.reportPropagatedRecompile(report);\n }\n\n private reportSuccess(): void {\n this.log(\"\");\n this.log(`${this.brandingName} has been uninstalled.`);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);\n this.log(\"\");\n }\n\n private async removeLocalFilesOrFail(plan: RemovalPlan, target: UninstallTarget): Promise<void> {\n try {\n await this.removeLocalFiles(plan, target);\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 async removeLocalFiles(plan: RemovalPlan, target: UninstallTarget): Promise<void> {\n await this.removePlannedSkills(planEntry(plan, \"skills\"));\n await this.removePlannedAgents(planEntry(plan, \"agents\"));\n\n for (const statement of plan.kept) {\n this.log(statement);\n }\n\n const cleanup = await cleanupEmptyDirs(target, planEntries(plan, \"config\"));\n\n this.reportSourceFolderCleanup(cleanup.sourceFolder);\n this.reportDirCleanup(target.sourceRoot.relName, cleanup.sourceRoot);\n this.reportDirCleanup(CLAUDE_DIR, cleanup.claudeDir);\n }\n\n private reportSourceFolderCleanup({ relName, outcome }: SourceFolderCleanup): void {\n if (outcome === \"config-removed\") {\n this.logSuccess(`Removed CLI config from ${relName}/`);\n return;\n }\n this.reportDirCleanup(relName, outcome);\n }\n\n private reportDirCleanup(relName: string, cleanup: DirCleanup): void {\n switch (cleanup) {\n case \"removed\":\n this.logSuccess(`Removed ${relName}/`);\n return;\n case \"kept\":\n this.log(`Kept ${relName}/ (contains user content)`);\n return;\n case \"untouched\":\n return;\n default: {\n const _exhaustive: never = cleanup;\n return _exhaustive;\n }\n }\n }\n\n private async removePlannedPlugins(\n entry: PluginRemoval | undefined,\n config: ProjectConfig | null,\n projectDir: string,\n ): Promise<void> {\n if (!entry) return;\n\n this.log(\"Uninstalling plugins...\");\n\n try {\n const pluginResult = await uninstallPlugins(entry, config, projectDir, {\n onUninstalled: (name) => this.log(` Uninstalled plugin '${name}'`),\n onLeftRegistered: (name, provider) => this.warn(pluginLeftRegistered(name, provider)),\n });\n\n // Silent on zero: \"0\" beside a plan that named one reads as a failure, and is not one.\n if (pluginResult.totalUninstalled > 0) {\n this.logSuccess(`Uninstalled ${plural(pluginResult.totalUninstalled, \"plugin\")}`);\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 private async removePlannedSkills(entry: SkillsRemoval | undefined): Promise<void> {\n if (!entry) return;\n\n const removedNames = await removeMatchingSkills(entry, (dirName) =>\n this.log(` Uninstalled skill '${dirName}'`),\n );\n if (removedNames.length === 0) return;\n\n this.logSuccess(`Removed ${plural(removedNames.length, \"CLI-installed skill\")}`);\n }\n\n private async removePlannedAgents(entry: AgentsRemoval | undefined): Promise<void> {\n if (!entry) return;\n\n const removedNames = await removeMatchingAgents(entry, (agentName) =>\n this.log(` Uninstalled agent '${agentName}'`),\n );\n if (removedNames.length === 0) return;\n\n this.logSuccess(`Removed ${plural(removedNames.length, \"compiled agent\")}`);\n }\n}\n\n/** A skill folder this CLI installed: removed by its folder, shown by the skill and name it records. */\ntype CliSkill = { dirName: string; skillId: SkillId; displayName: string | undefined };\n\ntype UninstallTarget = {\n /** Home is the global scope, so a run there removes global entries. */\n scope: SkillScope;\n /** Read before removal, which deletes the folder that says which. */\n provider: Provider;\n hasPlugins: boolean;\n /** Only those this CLI installed, matched against config skills. */\n cliPluginNames: string[];\n /** Carrying `forkedFrom`: this CLI installed them. The rest are the user's, never removed. */\n cliSkills: CliSkill[];\n hasClaudeDir: boolean;\n pluginsDir: string;\n skillsDir: string;\n agentsDir: string;\n agentCodec: AgentCodec;\n claudeDir: string;\n sourceFolder: ScopeSourceFolder;\n sourceRoot: SourceRoot;\n config: ProjectConfig | null;\n registeredProjects: string[];\n configuredAgents: AgentName[];\n markedAgents: string[];\n /** The user's, unless the config claims them. */\n unmarkedAgents: string[];\n};\n\ntype ScopeSourceFolder = {\n dir: string;\n relName: string;\n manifestFiles: string[];\n /** `null` when absent or unreadable. */\n config: ProjectConfig | null;\n};\n\n/** Captured before removal: all of it comes from the config and folder being deleted. */\ntype GlobalPropagationData = {\n globalConfig: ProjectConfig;\n matrix: MergedSkillsMatrix;\n agents: Partial<Record<AgentName, AgentDefinition>>;\n provider: Provider;\n};\n\ntype UninstallPluginsResult = {\n totalUninstalled: number;\n};\n\ntype PluginRemovalReporter = {\n onUninstalled?: (pluginName: string) => void;\n /** No host CLI to ask, so the plugin's registration outlives its folder. */\n onLeftRegistered?: (pluginName: string, provider: Provider) => void;\n};\n\n/** `kept`: still there because of content this CLI never wrote. */\ntype DirCleanup = \"removed\" | \"kept\" | \"untouched\";\n\n/** `config-removed`: the manifest went, and the folder stayed for what else it holds. */\ntype SourceFolderCleanup = { relName: string; outcome: DirCleanup | \"config-removed\" };\n\ntype CleanupResult = {\n sourceFolder: SourceFolderCleanup;\n sourceRoot: DirCleanup;\n claudeDir: DirCleanup;\n};\n\nfunction collectConfiguredAgents(config: Partial<ProjectConfig> | null): AgentName[] {\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 const { marketplaceName } = config;\n return new Set(config.skills.flatMap((skill) => pluginRefsOf(skill, marketplaceName)));\n}\n\nfunction pluginRefsOf(skill: SkillConfig, marketplaceName: string | undefined): string[] {\n const ownRef = buildMarketplacePluginRef(skill.id, skill.origin);\n if (!marketplaceName || skill.origin === marketplaceName || skill.origin === EJECT_SOURCE) {\n return [ownRef];\n }\n // Installed via the marketplace while `origin` names something else.\n return [ownRef, buildMarketplacePluginRef(skill.id, marketplaceName)];\n}\n\n/**\n * Degrades: a `ConfigLoadError` is reported and treated as a missing config, since that is when a\n * user needs to uninstall. Any other failure propagates.\n */\nasync function loadUninstallConfig(\n configPath: string,\n projectDir: string,\n provider: Provider,\n onLoadFailed: (failure: ConfigLoadError) => void,\n): Promise<ProjectConfig | null> {\n try {\n const result = await loadProjectConfigAt(configPath, projectDir, provider);\n return result?.config ?? null;\n } catch (error) {\n if (!(error instanceof ConfigLoadError)) throw error;\n onLoadFailed(error);\n return null;\n }\n}\n\n/** Its config is read under {@link loadUninstallConfig}'s degrade posture. */\nasync function readSourceFolder(\n folder: Pick<ScopeSourceFolder, \"dir\" | \"relName\">,\n projectDir: string,\n provider: Provider,\n onConfigLoadFailed: (failure: ConfigLoadError) => void,\n): Promise<ScopeSourceFolder> {\n const [manifestFiles, config] = await Promise.all([\n manifestFilesIn(folder.dir),\n loadUninstallConfig(\n path.join(folder.dir, STANDARD_FILES.CONFIG_TS),\n projectDir,\n provider,\n onConfigLoadFailed,\n ),\n ]);\n return { ...folder, manifestFiles, config };\n}\n\nasync function manifestFilesIn(dir: string): Promise<string[]> {\n const manifest = [STANDARD_FILES.CONFIG_TS, STANDARD_FILES.CONFIG_TYPES_TS];\n const present = await Promise.all(\n manifest.map((fileName) => fileExists(path.join(dir, fileName))),\n );\n return manifest.filter((_, index) => present[index]);\n}\n\nfunction activeConfigOf(config: ProjectConfig): ProjectConfig {\n return {\n ...config,\n skills: config.skills.filter((s) => !s.excluded),\n agents: config.agents.filter((a) => !a.excluded),\n };\n}\n\ntype DetectionFailureHandlers = {\n /** Degrades: see {@link loadUninstallConfig}. */\n onConfigLoadFailed: (failure: ConfigLoadError) => void;\n onSkillMetadataUnreadable: (metadataPath: string) => never;\n};\n\nasync function detectUninstallTarget(\n projectDir: string,\n handlers: DetectionFailureHandlers,\n): Promise<UninstallTarget> {\n const pluginsDir = getProjectPluginsDir(projectDir);\n const { skillsDir, agentsDir } = resolveInstallPaths(projectDir);\n const claudeDir = path.join(projectDir, CLAUDE_DIR);\n const provider = providerInUse(projectDir);\n const codec = agentCodec(provider);\n\n const [cliSkills, hasClaudeDir, sourceFolder, agentProvenance] = await Promise.all([\n skillsThisCliInstalled(skillsDir, handlers.onSkillMetadataUnreadable),\n directoryExists(claudeDir),\n readSourceFolder(\n sourceFolderInUse(projectDir, provider),\n projectDir,\n provider,\n handlers.onConfigLoadFailed,\n ),\n splitAgentsByProvenance(agentsDir, codec),\n ]);\n\n const { config } = sourceFolder;\n const activeConfig = config === null ? null : activeConfigOf(config);\n const cliPluginNames = await pluginsThisRunRemoves(projectDir, activeConfig);\n\n return {\n scope: isHomeDirectory(projectDir) ? \"global\" : \"project\",\n provider,\n hasPlugins: cliPluginNames.length > 0,\n cliPluginNames,\n cliSkills,\n hasClaudeDir,\n pluginsDir,\n skillsDir,\n agentsDir,\n claudeDir,\n sourceFolder,\n sourceRoot: sourceRootOf(projectDir),\n config,\n registeredProjects: config?.projects ?? [],\n configuredAgents: collectConfiguredAgents(activeConfig),\n agentCodec: codec,\n markedAgents: agentProvenance.marked,\n unmarkedAgents: agentProvenance.unmarked,\n };\n}\n\nasync function pluginsThisRunRemoves(\n projectDir: string,\n activeConfig: ProjectConfig | null,\n): Promise<string[]> {\n const installed = await listPluginNames(projectDir);\n if (!thisRunOwnsAnyPlugin(projectDir)) return [];\n\n const cliInstalledKeys = getCliInstalledPluginKeys(activeConfig);\n return installed.filter((name) => cliInstalledKeys.has(name));\n}\n\n/**\n * A host without project-scoped plugins (Codex) shares them machine-wide, so a project uninstall\n * there must not sweep them. A global uninstall owns them on any host.\n */\nfunction thisRunOwnsAnyPlugin(projectDir: string): boolean {\n if (isHomeDirectory(projectDir)) return true;\n return hostAt(projectDir).installsProjectScopedPlugins;\n}\n\n/** Read before the plan is built, so the plan and the removal read one classification. */\nasync function skillsThisCliInstalled(\n skillsDir: string,\n onMetadataUnreadable: (metadataPath: string) => never,\n): Promise<CliSkill[]> {\n const dirNames = await listDirectories(skillsDir);\n const skills = await Promise.all(\n dirNames.map(async (dirName) => ({\n dirName,\n metadata: await readCopyMetadata(skillsDir, dirName, onMetadataUnreadable),\n })),\n );\n return skills.flatMap(({ dirName, metadata }) =>\n metadata?.forkedFrom === undefined\n ? []\n : [{ dirName, skillId: metadata.forkedFrom.skillId, displayName: recordedName(metadata) }],\n );\n}\n\n/** Only for the panel: a copy naming itself no way is drawn by the catalogue's name, or its id. */\nfunction recordedName(metadata: LocalSkillMetadata): string | undefined {\n return typeof metadata.displayName === \"string\" ? metadata.displayName : undefined;\n}\n\n/**\n * A metadata.yaml that reads but does not parse is the user's (warned); one found but unreadable\n * aborts. A skill folder that cannot be opened hides its metadata.yaml (`fileExists` answers\n * false on EACCES), so that skill reads as the user's and is kept, even when this CLI made it.\n */\nasync function readCopyMetadata(\n skillsDir: string,\n dirName: string,\n onUnreadable: (metadataPath: string) => never,\n): Promise<LocalSkillMetadata | null> {\n const skillDir = path.join(skillsDir, dirName);\n try {\n return await readLocalSkillMetadata(skillDir);\n } catch {\n // Cause dropped on purpose: the stop names the file and the fix only, and uninstall has no\n // --verbose to carry it.\n return onUnreadable(path.join(skillDir, STANDARD_FILES.METADATA_YAML));\n }\n}\n\n/** The planned skills still there: the count is what the run removed, not what it planned. */\nasync function removeMatchingSkills(\n entry: SkillsRemoval,\n onRemoved: (dirName: string) => void,\n): Promise<string[]> {\n const present = await listDirectories(entry.skillsDir);\n const removedNames = present.filter((name) => entry.skillNames.includes(name));\n\n for (const name of removedNames) {\n await remove(path.join(entry.skillsDir, name));\n onRemoved(name);\n }\n return removedNames;\n}\n\nasync function removeMatchingAgents(\n entry: AgentsRemoval,\n onRemoved: (agentName: string) => void,\n): Promise<string[]> {\n const agentFiles = await listAgentFiles(entry.agentsDir, entry.codec);\n const removedNames = agentFiles\n .map((agentFile) => path.basename(agentFile, entry.codec.extension))\n .filter((agentName) => entry.agentNames.includes(agentName));\n\n for (const agentName of removedNames) {\n await remove(path.join(entry.agentsDir, `${agentName}${entry.codec.extension}`));\n onRemoved(agentName);\n }\n return removedNames;\n}\n\nconst SCOPE_OF_AN_UNRECORDED_SKILL: SkillScope = \"project\";\n\n/** Every offered plugin scope, the config's first: a re-scoped skill stays where installed. */\nfunction pluginScopesToSweep(host: PluginHost, primary: SkillScope): SkillScope[] {\n const offered = host.offeredPlacements\n .filter((placement) => placement.mode === \"plugin\")\n .map((placement) => placement.scope);\n\n if (!offered.includes(primary)) return offered;\n return [primary, ...offered.filter((scope) => scope !== primary)];\n}\n\n/** Failures are swallowed: the directory is deleted either way and files are already gone. */\nasync function removePluginWhereverItIsFiled(\n host: PluginHost,\n pluginRef: string,\n primaryScope: SkillScope,\n projectDir: string,\n): Promise<PluginRemovalOutcome> {\n let outcome: PluginRemovalOutcome = \"absent\";\n\n for (const scope of pluginScopesToSweep(host, primaryScope)) {\n try {\n const swept = await host.uninstallPlugin(pluginRef, scope, projectDir);\n if (swept === \"removed\") outcome = \"removed\";\n } catch {\n // A throw is neither outcome, so `outcome` stays as the other scopes left it.\n }\n }\n\n return outcome;\n}\n\n/** `config` only supplies the scope each plugin is filed under; the entry decides which go. */\nasync function uninstallPlugins(\n entry: PluginRemoval,\n config: ProjectConfig | null,\n projectDir: string,\n { onUninstalled, onLeftRegistered }: PluginRemovalReporter = {},\n): Promise<UninstallPluginsResult> {\n const host = hostAt(projectDir);\n const hostAvailable = await host.isAvailable();\n const observed: string[] = [];\n\n if (!hostAvailable) {\n for (const pluginName of entry.names) onLeftRegistered?.(pluginName, host.provider);\n }\n\n for (const pluginName of entry.names) {\n const removal = hostAvailable\n ? await removePluginWhereverItIsFiled(\n host,\n pluginName,\n scopeThePluginIsFiledUnder(config, pluginName),\n projectDir,\n )\n : nothingWasObserved();\n\n await remove(path.join(entry.pluginsDir, pluginName));\n\n if (removal === \"removed\") {\n observed.push(pluginName);\n onUninstalled?.(pluginName);\n }\n }\n\n // Observed, not intended: Codex `plugin remove` exits 0 whether or not the plugin existed.\n return { totalUninstalled: observed.length };\n}\n\nfunction scopeThePluginIsFiledUnder(config: ProjectConfig | null, pluginName: string): SkillScope {\n const skillId = parseMarketplacePluginRef(pluginName);\n return (\n config?.skills.find((skill) => skill.id === skillId)?.scope ?? SCOPE_OF_AN_UNRECORDED_SKILL\n );\n}\n\nfunction nothingWasObserved(): PluginRemovalOutcome {\n return \"absent\";\n}\n\n/** Whether there was a manifest to remove. */\nasync function removeConfigManifest(entry: ConfigManifestRemoval | undefined): Promise<boolean> {\n if (!entry) return false;\n\n await Promise.all(\n entry.fileNames.map((fileName) => remove(path.join(entry.sourceDir, fileName))),\n );\n return true;\n}\n\n/** Directories are not plan entries: each goes only once nothing of the user's is left in it. */\nasync function cleanupEmptyDirs(\n target: Pick<\n UninstallTarget,\n \"skillsDir\" | \"agentsDir\" | \"hasClaudeDir\" | \"claudeDir\" | \"sourceRoot\" | \"sourceFolder\"\n >,\n manifestEntries: readonly ConfigManifestRemoval[],\n): Promise<CleanupResult> {\n // Whether or not the plan named a removal there: a folder holding nothing is no one's.\n await removeDirIfEmpty(target.skillsDir);\n await removeDirIfEmpty(target.agentsDir);\n\n const sourceFolder = await cleanupSourceFolder(\n target.sourceFolder,\n manifestEntries.find((entry) => entry.sourceDir === target.sourceFolder.dir),\n );\n const sourceRoot = await cleanupSourceRoot(target.sourceRoot, sourceFolder.outcome === \"removed\");\n const claudeDir = await cleanupClaudeDir(target);\n\n return { sourceFolder, sourceRoot, claudeDir };\n}\n\n/** `entry` names this folder: the plan's manifest removal for it, if it holds one. */\nasync function cleanupSourceFolder(\n folder: ScopeSourceFolder,\n entry: ConfigManifestRemoval | undefined,\n): Promise<SourceFolderCleanup> {\n const manifestRemoved = await removeConfigManifest(entry);\n const dir = await removeDirUnlessUserContent(folder.dir);\n const outcome = manifestRemoved && dir !== \"removed\" ? \"config-removed\" : dir;\n return { relName: folder.relName, outcome };\n}\n\n/**\n * Only once the provider folder went, and only when empty: consuming repositories keep their own\n * state under `.agents-inc/`.\n */\nasync function cleanupSourceRoot(\n sourceRoot: SourceRoot,\n providerDirRemoved: boolean,\n): Promise<DirCleanup> {\n if (!providerDirRemoved) return \"untouched\";\n return removeDirUnlessUserContent(sourceRoot.dir);\n}\n\nasync function cleanupClaudeDir(\n target: Pick<UninstallTarget, \"hasClaudeDir\" | \"claudeDir\">,\n): Promise<DirCleanup> {\n if (!target.hasClaudeDir) return \"untouched\";\n return removeDirUnlessUserContent(target.claudeDir);\n}\n\n/** `kept` when it is still there: something of the user's is in it. */\nasync function removeDirUnlessUserContent(dir: string): Promise<DirCleanup> {\n if (await removeDirIfEmpty(dir)) return \"removed\";\n return (await directoryExists(dir)) ? \"kept\" : \"untouched\";\n}\n\nasync function listAgentFiles(agentsDir: string, codec: AgentCodec): Promise<string[]> {\n try {\n return await listAgentFilesOf(agentsDir, codec);\n } catch {\n return [];\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/commands/update.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
unofferablePlacementsFound
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-F437ICEG.js";
|
|
5
5
|
import {
|
|
6
6
|
providerFlag,
|
|
7
7
|
providerNamedBy,
|
|
8
8
|
refuseAnAmbiguousInstallation
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-2RTBSLSR.js";
|
|
10
10
|
import {
|
|
11
11
|
BaseCommand,
|
|
12
12
|
EXIT_CODES
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-LJQXQTFC.js";
|
|
14
14
|
import {
|
|
15
15
|
ERROR_MESSAGES,
|
|
16
16
|
INFO_MESSAGES,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
marketplaceRefreshFailed,
|
|
22
22
|
marketplacesRefreshFailed,
|
|
23
23
|
marketplacesRefreshed
|
|
24
|
-
} from "../chunk-
|
|
24
|
+
} from "../chunk-WVFBBZEP.js";
|
|
25
25
|
import "../chunk-7OG635DK.js";
|
|
26
26
|
import {
|
|
27
27
|
EJECT_SOURCE
|
package/dist/hooks/init.js
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runDashboardFlow
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-AARQBW5L.js";
|
|
5
5
|
import "../chunk-3R3LHA4Q.js";
|
|
6
|
-
import "../chunk-
|
|
6
|
+
import "../chunk-SPQSNZMM.js";
|
|
7
7
|
import "../chunk-A3ZAXL5T.js";
|
|
8
8
|
import "../chunk-OZXAJNLA.js";
|
|
9
9
|
import "../chunk-P6CYS4JK.js";
|
|
10
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-Q6WRR4BN.js";
|
|
11
11
|
import "../chunk-N33AKFLR.js";
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-3N4FSTVX.js";
|
|
13
|
+
import "../chunk-VSPC74SS.js";
|
|
14
|
+
import "../chunk-VR6QTK5Z.js";
|
|
15
|
+
import "../chunk-ITQF35UQ.js";
|
|
16
|
+
import "../chunk-BRZA7ZCX.js";
|
|
17
|
+
import "../chunk-EHJIQDXR.js";
|
|
18
18
|
import "../chunk-KIK5EZYD.js";
|
|
19
19
|
import "../chunk-G7NUK3BF.js";
|
|
20
|
-
import "../chunk-
|
|
20
|
+
import "../chunk-2RTBSLSR.js";
|
|
21
21
|
import {
|
|
22
22
|
EXIT_CODES
|
|
23
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-LJQXQTFC.js";
|
|
24
24
|
import {
|
|
25
25
|
findConfigLoadFailures,
|
|
26
26
|
installationConfigsUnreadable,
|
|
27
27
|
retiredSourceFolderIn,
|
|
28
28
|
retiredSourceFolderUnsupported
|
|
29
|
-
} from "../chunk-
|
|
29
|
+
} from "../chunk-WVFBBZEP.js";
|
|
30
30
|
import "../chunk-7OG635DK.js";
|
|
31
31
|
import "../chunk-MHAQWMNJ.js";
|
|
32
32
|
import "../chunk-GHHJYNAN.js";
|
|
@@ -36,15 +36,24 @@ import os from "os";
|
|
|
36
36
|
import { flush } from "@oclif/core";
|
|
37
37
|
var hook = async function(options) {
|
|
38
38
|
sayTheRetiredSourceFolderIsUnsupported(process.cwd());
|
|
39
|
-
if (options.id
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
if (options.id !== void 0) return;
|
|
40
|
+
const projectDir = process.cwd();
|
|
41
|
+
const unreadable = await findConfigLoadFailures(projectDir);
|
|
42
|
+
if (unreadable.length > 0) {
|
|
43
|
+
this.error(installationConfigsUnreadable(unreadable), { exit: EXIT_CODES.ERROR });
|
|
44
|
+
}
|
|
45
|
+
const dashboard = await runDashboardFlow(projectDir, options.config);
|
|
46
|
+
switch (dashboard) {
|
|
47
|
+
case "cancelled":
|
|
48
|
+
return this.error("Cancelled", { exit: EXIT_CODES.CANCELLED });
|
|
49
|
+
case "shown":
|
|
50
|
+
return endRun(EXIT_CODES.SUCCESS);
|
|
51
|
+
case "not-installed":
|
|
52
|
+
return;
|
|
53
|
+
default: {
|
|
54
|
+
const _exhaustive = dashboard;
|
|
55
|
+
return _exhaustive;
|
|
44
56
|
}
|
|
45
|
-
const dashboard = await runDashboardFlow(projectDir, options.config);
|
|
46
|
-
if (dashboard === "cancelled") this.error("Cancelled", { exit: EXIT_CODES.CANCELLED });
|
|
47
|
-
if (dashboard === "shown") await endRun(EXIT_CODES.SUCCESS);
|
|
48
57
|
}
|
|
49
58
|
};
|
|
50
59
|
function sayTheRetiredSourceFolderIsUnsupported(cwd) {
|
package/dist/hooks/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/hooks/init.ts"],"sourcesContent":["import os from \"os\";\n\nimport { flush, type Hook } from \"@oclif/core\";\nimport { runDashboardFlow } from \"../commands/init.js\";\nimport { findConfigLoadFailures } from \"../lib/configuration/project-config.js\";\nimport { retiredSourceFolderIn } from \"../lib/installation/install-layout.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n installationConfigsUnreadable,\n retiredSourceFolderUnsupported,\n} from \"../utils/messages.js\";\n\nconst hook: Hook<\"init\"> = async function (options) {\n sayTheRetiredSourceFolderIsUnsupported(process.cwd());\n\n //
|
|
1
|
+
{"version":3,"sources":["../../src/cli/hooks/init.ts"],"sourcesContent":["import os from \"os\";\n\nimport { flush, type Hook } from \"@oclif/core\";\nimport { runDashboardFlow } from \"../commands/init.js\";\nimport { findConfigLoadFailures } from \"../lib/configuration/project-config.js\";\nimport { retiredSourceFolderIn } from \"../lib/installation/install-layout.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n installationConfigsUnreadable,\n retiredSourceFolderUnsupported,\n} from \"../utils/messages.js\";\n\nconst hook: Hook<\"init\"> = async function (options) {\n sayTheRetiredSourceFolderIsUnsupported(process.cwd());\n\n // A named command runs as named; no command is the dashboard.\n if (options.id !== undefined) return;\n\n const projectDir = process.cwd();\n // Checked here: oclif's hook runner swallows a load error thrown inside the dashboard.\n const unreadable = await findConfigLoadFailures(projectDir);\n if (unreadable.length > 0) {\n this.error(installationConfigsUnreadable(unreadable), { exit: EXIT_CODES.ERROR });\n }\n\n const dashboard = await runDashboardFlow(projectDir, options.config);\n switch (dashboard) {\n case \"cancelled\":\n return this.error(\"Cancelled\", { exit: EXIT_CODES.CANCELLED });\n case \"shown\":\n return endRun(EXIT_CODES.SUCCESS);\n case \"not-installed\":\n // oclif goes on to print the root help.\n return;\n default: {\n const _exhaustive: never = dashboard;\n return _exhaustive;\n }\n }\n};\n\n/** Notice only, once per root that holds the folder, home first; stderr so piped output is unchanged. */\nfunction sayTheRetiredSourceFolderIsUnsupported(cwd: string): void {\n for (const root of retiredSourceFolderIn([os.homedir(), cwd])) {\n process.stderr.write(`${retiredSourceFolderUnsupported(root)}\\n`);\n }\n}\n\n/** Not `this.exit(0)`: oclif swallows an exit 0 from a hook and goes on to print the root help. */\nasync function endRun(code: number): Promise<never> {\n await flush();\n process.exit(code);\n}\n\nexport default hook;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,QAAQ;AAEf,SAAS,aAAwB;AAUjC,IAAM,OAAqB,eAAgB,SAAS;AAClD,yCAAuC,QAAQ,IAAI,CAAC;AAGpD,MAAI,QAAQ,OAAO,OAAW;AAE9B,QAAM,aAAa,QAAQ,IAAI;AAE/B,QAAM,aAAa,MAAM,uBAAuB,UAAU;AAC1D,MAAI,WAAW,SAAS,GAAG;AACzB,SAAK,MAAM,8BAA8B,UAAU,GAAG,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,EAClF;AAEA,QAAM,YAAY,MAAM,iBAAiB,YAAY,QAAQ,MAAM;AACnE,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO,KAAK,MAAM,aAAa,EAAE,MAAM,WAAW,UAAU,CAAC;AAAA,IAC/D,KAAK;AACH,aAAO,OAAO,WAAW,OAAO;AAAA,IAClC,KAAK;AAEH;AAAA,IACF,SAAS;AACP,YAAM,cAAqB;AAC3B,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAGA,SAAS,uCAAuC,KAAmB;AACjE,aAAW,QAAQ,sBAAsB,CAAC,GAAG,QAAQ,GAAG,GAAG,CAAC,GAAG;AAC7D,YAAQ,OAAO,MAAM,GAAG,+BAA+B,IAAI,CAAC;AAAA,CAAI;AAAA,EAClE;AACF;AAGA,eAAe,OAAO,MAA8B;AAClD,QAAM,MAAM;AACZ,UAAQ,KAAK,IAAI;AACnB;AAEA,IAAO,eAAQ;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
loadAgentDefs
|
|
4
|
+
} from "./chunk-ITQF35UQ.js";
|
|
5
|
+
import "./chunk-BRZA7ZCX.js";
|
|
6
|
+
import "./chunk-EHJIQDXR.js";
|
|
7
|
+
import "./chunk-WVFBBZEP.js";
|
|
8
|
+
import "./chunk-7OG635DK.js";
|
|
9
|
+
import "./chunk-MHAQWMNJ.js";
|
|
10
|
+
import "./chunk-GHHJYNAN.js";
|
|
11
|
+
export {
|
|
12
|
+
loadAgentDefs
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=load-agent-defs-E67DSYTN.js.map
|
|
@@ -3,16 +3,16 @@ import {
|
|
|
3
3
|
compileAgents,
|
|
4
4
|
discoverInstalledSkills,
|
|
5
5
|
withCatalogueSeatedFor
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VR6QTK5Z.js";
|
|
7
7
|
import {
|
|
8
8
|
loadAgentDefs
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-ITQF35UQ.js";
|
|
10
|
+
import "./chunk-BRZA7ZCX.js";
|
|
11
|
+
import "./chunk-EHJIQDXR.js";
|
|
12
12
|
import {
|
|
13
13
|
getErrorMessage,
|
|
14
14
|
resolveInstallPaths
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-WVFBBZEP.js";
|
|
16
16
|
import "./chunk-7OG635DK.js";
|
|
17
17
|
import "./chunk-MHAQWMNJ.js";
|
|
18
18
|
import "./chunk-GHHJYNAN.js";
|
|
@@ -62,4 +62,4 @@ function summarizeRecompiles(outcomes) {
|
|
|
62
62
|
export {
|
|
63
63
|
recompilePropagatedProjectAgents
|
|
64
64
|
};
|
|
65
|
-
//# sourceMappingURL=recompile-project-agents-
|
|
65
|
+
//# sourceMappingURL=recompile-project-agents-6G6M2RS6.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
loadMarketplaceMatrix,
|
|
6
6
|
loadSkillsMatrixFromSource,
|
|
7
7
|
mergeLocalSkillsIntoMatrix
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WVFBBZEP.js";
|
|
9
9
|
import "./chunk-7OG635DK.js";
|
|
10
10
|
import "./chunk-MHAQWMNJ.js";
|
|
11
11
|
import "./chunk-GHHJYNAN.js";
|
|
@@ -16,4 +16,4 @@ export {
|
|
|
16
16
|
loadSkillsMatrixFromSource,
|
|
17
17
|
mergeLocalSkillsIntoMatrix
|
|
18
18
|
};
|
|
19
|
-
//# sourceMappingURL=source-loader-
|
|
19
|
+
//# sourceMappingURL=source-loader-W7XCNKNA.js.map
|