agents-inc 0.170.2 → 0.172.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/{chunk-PSUTNOQ2.js → chunk-255DGUCH.js} +2 -2
  3. package/dist/chunk-33JICQD5.js +196 -0
  4. package/dist/chunk-33JICQD5.js.map +1 -0
  5. package/dist/{chunk-3ED3KHHD.js → chunk-3R3LHA4Q.js} +2 -2
  6. package/dist/{chunk-YXKTY5WM.js → chunk-5MGRHS2G.js} +94 -58
  7. package/dist/chunk-5MGRHS2G.js.map +1 -0
  8. package/dist/{chunk-PLFANHRZ.js → chunk-5PPB6HT6.js} +2 -2
  9. package/dist/{chunk-66AEVERM.js → chunk-6CRA46YO.js} +14 -14
  10. package/dist/{chunk-ELV5WDS3.js → chunk-6LUTY35Q.js} +25 -14
  11. package/dist/chunk-6LUTY35Q.js.map +1 -0
  12. package/dist/{chunk-AUNRHWH4.js → chunk-7OG635DK.js} +26 -4
  13. package/dist/chunk-7OG635DK.js.map +1 -0
  14. package/dist/{chunk-GEMW5RQ2.js → chunk-7ZOWSCAO.js} +29 -102
  15. package/dist/chunk-7ZOWSCAO.js.map +1 -0
  16. package/dist/{chunk-YGDWHDOY.js → chunk-A3ZAXL5T.js} +4 -5
  17. package/dist/{chunk-YGDWHDOY.js.map → chunk-A3ZAXL5T.js.map} +1 -1
  18. package/dist/chunk-G7NUK3BF.js +253 -0
  19. package/dist/chunk-G7NUK3BF.js.map +1 -0
  20. package/dist/{chunk-THO7LO5B.js → chunk-KCLBLK3F.js} +3 -3
  21. package/dist/{chunk-2YA4DDRM.js → chunk-LUKDDHSI.js} +8 -6
  22. package/dist/{chunk-2YA4DDRM.js.map → chunk-LUKDDHSI.js.map} +1 -1
  23. package/dist/{chunk-OCAVW6N5.js → chunk-MBIOZ5LW.js} +12 -3
  24. package/dist/{chunk-OCAVW6N5.js.map → chunk-MBIOZ5LW.js.map} +1 -1
  25. package/dist/{chunk-7C3PFRBU.js → chunk-MHAQWMNJ.js} +35 -5
  26. package/dist/{chunk-7C3PFRBU.js.map → chunk-MHAQWMNJ.js.map} +1 -1
  27. package/dist/{chunk-HACRR422.js → chunk-MOL2J5HS.js} +2 -2
  28. package/dist/{chunk-BBDGYJHX.js → chunk-N33AKFLR.js} +2 -2
  29. package/dist/{chunk-5BNX73OU.js → chunk-NISWBQNS.js} +52 -31
  30. package/dist/chunk-NISWBQNS.js.map +1 -0
  31. package/dist/{chunk-GAKVZNTX.js → chunk-VILFCMRN.js} +420 -316
  32. package/dist/chunk-VILFCMRN.js.map +1 -0
  33. package/dist/{chunk-IWY5IR4F.js → chunk-Y23MP2OC.js} +8 -8
  34. package/dist/commands/build/marketplace.js +16 -14
  35. package/dist/commands/build/marketplace.js.map +1 -1
  36. package/dist/commands/build/plugins.js +6 -6
  37. package/dist/commands/compile.js +12 -12
  38. package/dist/commands/doctor.js +64 -81
  39. package/dist/commands/doctor.js.map +1 -1
  40. package/dist/commands/edit.js +150 -152
  41. package/dist/commands/edit.js.map +1 -1
  42. package/dist/commands/eject.js +10 -10
  43. package/dist/commands/init.js +19 -16
  44. package/dist/commands/list.js +14 -17
  45. package/dist/commands/list.js.map +1 -1
  46. package/dist/commands/new/marketplace.js +4 -4
  47. package/dist/commands/search.js +15 -13
  48. package/dist/commands/search.js.map +1 -1
  49. package/dist/commands/share.js +11 -11
  50. package/dist/commands/uninstall.js +109 -98
  51. package/dist/commands/uninstall.js.map +1 -1
  52. package/dist/commands/update.js +6 -6
  53. package/dist/components/common/scroll-affordance.js +2 -2
  54. package/dist/components/common/select-list.js +2 -2
  55. package/dist/components/common/skill-agent-summary.js +3 -4
  56. package/dist/components/common/summary-panel.js +11 -146
  57. package/dist/components/common/summary-panel.js.map +1 -1
  58. package/dist/hooks/init.js +22 -19
  59. package/dist/hooks/init.js.map +1 -1
  60. package/dist/load-agent-defs-54VIKN4T.js +14 -0
  61. package/dist/{recompile-project-agents-I33KQJFB.js → recompile-project-agents-5A44NJRD.js} +8 -8
  62. package/dist/{source-loader-TTJVW2ER.js → source-loader-LQNRI5UZ.js} +4 -4
  63. package/dist/src/agents/tester/web-tester/playbook.md +1 -1
  64. package/package.json +1 -1
  65. package/src/agents/tester/web-tester/playbook.md +1 -1
  66. package/dist/chunk-5BNX73OU.js.map +0 -1
  67. package/dist/chunk-AUNRHWH4.js.map +0 -1
  68. package/dist/chunk-ELV5WDS3.js.map +0 -1
  69. package/dist/chunk-GAKVZNTX.js.map +0 -1
  70. package/dist/chunk-GEMW5RQ2.js.map +0 -1
  71. package/dist/chunk-O4LN3HFI.js +0 -69
  72. package/dist/chunk-O4LN3HFI.js.map +0 -1
  73. package/dist/chunk-PMUZR4XO.js +0 -108
  74. package/dist/chunk-PMUZR4XO.js.map +0 -1
  75. package/dist/chunk-RIK45Q4I.js +0 -103
  76. package/dist/chunk-RIK45Q4I.js.map +0 -1
  77. package/dist/chunk-YXKTY5WM.js.map +0 -1
  78. package/dist/components/common/removal-plan-confirm.js +0 -10
  79. package/dist/load-agent-defs-6QUUMGHK.js +0 -14
  80. package/dist/source-loader-TTJVW2ER.js.map +0 -1
  81. /package/dist/{chunk-PSUTNOQ2.js.map → chunk-255DGUCH.js.map} +0 -0
  82. /package/dist/{chunk-3ED3KHHD.js.map → chunk-3R3LHA4Q.js.map} +0 -0
  83. /package/dist/{chunk-PLFANHRZ.js.map → chunk-5PPB6HT6.js.map} +0 -0
  84. /package/dist/{chunk-66AEVERM.js.map → chunk-6CRA46YO.js.map} +0 -0
  85. /package/dist/{chunk-THO7LO5B.js.map → chunk-KCLBLK3F.js.map} +0 -0
  86. /package/dist/{chunk-HACRR422.js.map → chunk-MOL2J5HS.js.map} +0 -0
  87. /package/dist/{chunk-BBDGYJHX.js.map → chunk-N33AKFLR.js.map} +0 -0
  88. /package/dist/{chunk-IWY5IR4F.js.map → chunk-Y23MP2OC.js.map} +0 -0
  89. /package/dist/{components/common/removal-plan-confirm.js.map → load-agent-defs-54VIKN4T.js.map} +0 -0
  90. /package/dist/{recompile-project-agents-I33KQJFB.js.map → recompile-project-agents-5A44NJRD.js.map} +0 -0
  91. /package/dist/{load-agent-defs-6QUUMGHK.js.map → source-loader-LQNRI5UZ.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\nimport { unique } from \"remeda\";\nimport path from \"path\";\n\nimport { Flags } from \"@oclif/core\";\n\nimport { BaseCommand } from \"../base-command\";\nimport {\n RemovalPlanConfirm,\n type RemovalPlanSection,\n} from \"../components/common/removal-plan-confirm.js\";\nimport { promptConfirm } from \"../components/common/prompt-confirm.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 ForkedFromMetadata, readForkedFromMetadata } from \"../lib/skills/index\";\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 { EXIT_CODES } from \"../lib/exit-codes\";\nimport {\n SUCCESS_MESSAGES,\n INFO_MESSAGES,\n UNINSTALL_PLAN,\n compiledAgentsRemoval,\n localSkillsRemoval,\n notInstalledHere,\n pluginLeftRegistered,\n unmarkedAgentsKept,\n registeredProjectsUpdated,\n registeredProjectUpdateSkipped,\n registeredProjectsUpdateFailed,\n uninstallConfigUnreadable,\n uninstallNeedsTerminal,\n uninstallSkillMetadataUnreadable,\n} from \"../utils/messages\";\nimport type { AgentDefinition, AgentName, MergedSkillsMatrix, ProjectConfig } from \"../types/index\";\nimport type { 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\nfunction hasAnythingToRemove(plan: RemovalPlan): boolean {\n return plan.entries.length > 0;\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 [{ kind: \"skills\", skillsDir: target.skillsDir, skillNames: [...target.cliSkills] }];\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\nfunction describeEntry(entry: RemovalEntry): RemovalPlanSection {\n switch (entry.kind) {\n case \"plugins\":\n return { label: UNINSTALL_PLAN.PLUGINS_HEADING, items: entry.names };\n case \"skills\":\n return {\n label: UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,\n items: [localSkillsRemoval(entry.skillsDir)],\n };\n case \"agents\":\n return {\n label: UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,\n items: [compiledAgentsRemoval(entry.agentsDir)],\n };\n case \"config\":\n return {\n label: UNINSTALL_PLAN.CONFIG_HEADING,\n items: entry.fileNames.map((fileName) => `${entry.sourceDir}/${fileName}`),\n };\n default: {\n const _exhaustive: never = entry;\n return _exhaustive;\n }\n }\n}\n\nconst PLAN_SECTION_ORDER = [\n UNINSTALL_PLAN.PLUGINS_HEADING,\n UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,\n UNINSTALL_PLAN.CONFIG_HEADING,\n] as const;\n\n/** Skills and compiled agents share a heading; a heading with no items is not printed. */\nfunction planSections(entries: readonly RemovalEntry[]): RemovalPlanSection[] {\n const described = entries.map(describeEntry);\n\n return PLAN_SECTION_ORDER.flatMap((label) =>\n sectionWithItems(label, itemsUnder(described, label)),\n );\n}\n\nfunction itemsUnder(described: readonly RemovalPlanSection[], label: string): string[] {\n return described.filter((section) => section.label === label).flatMap((section) => section.items);\n}\n\nfunction sectionWithItems(label: string, items: string[]): RemovalPlanSection[] {\n if (items.length === 0) return [];\n return [{ label, items }];\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, 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 private async removalApproved(\n plan: RemovalPlan,\n skipConfirmation: boolean,\n namedProvider: Provider | undefined,\n ): Promise<boolean> {\n if (!skipConfirmation) return this.confirmRemoval(plan, namedProvider);\n\n this.printRemovalPlan(plan);\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 printRemovalPlan(plan: RemovalPlan): void {\n this.log(UNINSTALL_PLAN.PREVIEW_HEADING);\n this.log(\"\");\n\n for (const section of planSections(plan.entries)) {\n this.log(` ${section.label}`);\n for (const item of section.items) {\n this.log(` ${item}`);\n }\n }\n\n for (const statement of plan.kept) {\n this.log(\"\");\n this.log(statement);\n }\n\n this.log(\"\");\n }\n\n private async confirmRemoval(\n plan: RemovalPlan,\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 const outcome = await promptConfirm(({ onConfirm, onCancel }) => (\n <RemovalPlanConfirm\n heading={UNINSTALL_PLAN.PREVIEW_HEADING}\n sections={planSections(plan.entries)}\n statements={plan.kept}\n message={UNINSTALL_CONFIRM_MESSAGE}\n onConfirm={onConfirm}\n onCancel={onCancel}\n />\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\ntype UninstallTarget = {\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: string[];\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 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<string[]> {\n const dirNames = await listDirectories(skillsDir);\n const skills = await Promise.all(\n dirNames.map(async (name) => ({\n name,\n forkedFrom: await readSkillProvenance(skillsDir, name, onMetadataUnreadable),\n })),\n );\n return skills.filter((skill) => skill.forkedFrom !== null).map((skill) => skill.name);\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 readSkillProvenance(\n skillsDir: string,\n dirName: string,\n onUnreadable: (metadataPath: string) => never,\n): Promise<ForkedFromMetadata | null> {\n const skillDir = path.join(skillsDir, dirName);\n try {\n return await readForkedFromMetadata(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);\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,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  unofferablePlacementsFound
4
- } from "../chunk-HACRR422.js";
4
+ } from "../chunk-MOL2J5HS.js";
5
5
  import {
6
6
  providerFlag,
7
7
  providerNamedBy,
8
8
  refuseAnAmbiguousInstallation
9
- } from "../chunk-OCAVW6N5.js";
9
+ } from "../chunk-MBIOZ5LW.js";
10
10
  import {
11
11
  BaseCommand,
12
12
  EXIT_CODES
13
- } from "../chunk-GEMW5RQ2.js";
13
+ } from "../chunk-7ZOWSCAO.js";
14
14
  import {
15
15
  ERROR_MESSAGES,
16
16
  INFO_MESSAGES,
@@ -21,11 +21,11 @@ import {
21
21
  marketplaceRefreshFailed,
22
22
  marketplacesRefreshFailed,
23
23
  marketplacesRefreshed
24
- } from "../chunk-GAKVZNTX.js";
25
- import "../chunk-AUNRHWH4.js";
24
+ } from "../chunk-VILFCMRN.js";
25
+ import "../chunk-7OG635DK.js";
26
26
  import {
27
27
  EJECT_SOURCE
28
- } from "../chunk-7C3PFRBU.js";
28
+ } from "../chunk-MHAQWMNJ.js";
29
29
  import "../chunk-GHHJYNAN.js";
30
30
 
31
31
  // src/cli/commands/update.ts
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ScrollAffordance
4
- } from "../../chunk-BBDGYJHX.js";
5
- import "../../chunk-7C3PFRBU.js";
4
+ } from "../../chunk-N33AKFLR.js";
5
+ import "../../chunk-MHAQWMNJ.js";
6
6
  export {
7
7
  ScrollAffordance
8
8
  };
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  SelectList
4
- } from "../../chunk-3ED3KHHD.js";
5
- import "../../chunk-7C3PFRBU.js";
4
+ } from "../../chunk-3R3LHA4Q.js";
5
+ import "../../chunk-MHAQWMNJ.js";
6
6
  export {
7
7
  SelectList
8
8
  };
@@ -1,10 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  SkillAgentSummary
4
- } from "../../chunk-PMUZR4XO.js";
5
- import "../../chunk-RIK45Q4I.js";
6
- import "../../chunk-AUNRHWH4.js";
7
- import "../../chunk-7C3PFRBU.js";
4
+ } from "../../chunk-G7NUK3BF.js";
5
+ import "../../chunk-7OG635DK.js";
6
+ import "../../chunk-MHAQWMNJ.js";
8
7
  export {
9
8
  SkillAgentSummary
10
9
  };
@@ -1,151 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- ScrollAffordance
4
- } from "../../chunk-BBDGYJHX.js";
5
- import {
6
- SkillAgentSummary
7
- } from "../../chunk-PMUZR4XO.js";
8
- import "../../chunk-RIK45Q4I.js";
9
- import "../../chunk-AUNRHWH4.js";
10
- import {
11
- ALL_SKILLS_EJECTED_LABEL,
12
- CLI_COLORS,
13
- DEFAULT_PUBLIC_SOURCE_NAME,
14
- EJECT_SOURCE,
15
- formatSourceDisplayName
16
- } from "../../chunk-7C3PFRBU.js";
17
-
18
- // src/cli/components/common/summary-panel.tsx
19
- import { Box, Text } from "ink";
20
- import "react";
21
- import { unique } from "remeda";
22
-
23
- // src/cli/components/hooks/use-panel-scroll.ts
24
- import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
25
- import { measureElement as measureElement2, useInput } from "ink";
26
-
27
- // src/cli/components/hooks/use-measured-height.ts
28
- import { useRef, useState, useEffect } from "react";
29
- import { measureElement, useStdout } from "ink";
30
- function useMeasuredHeight() {
31
- const ref = useRef(null);
32
- const [measuredHeight, setMeasuredHeight] = useState(0);
33
- const { stdout } = useStdout();
34
- const measure = () => {
35
- if (ref.current) {
36
- const { height } = measureElement(ref.current);
37
- setMeasuredHeight((prev) => prev !== height ? height : prev);
38
- }
39
- };
40
- useEffect(() => {
41
- measure();
42
- });
43
- useEffect(() => {
44
- const RETRY_DELAYS_MS = [0, 16, 50];
45
- const timers = [];
46
- for (const delay of RETRY_DELAYS_MS) {
47
- timers.push(setTimeout(measure, delay));
48
- }
49
- return () => {
50
- for (const timer of timers) {
51
- clearTimeout(timer);
52
- }
53
- };
54
- }, []);
55
- useEffect(() => {
56
- stdout.on("resize", measure);
57
- return () => {
58
- stdout.off("resize", measure);
59
- };
60
- }, [stdout]);
61
- return { ref, measuredHeight };
62
- }
63
-
64
- // src/cli/components/hooks/use-panel-scroll.ts
65
- function usePanelScroll() {
66
- const { ref: viewportRef, measuredHeight: viewportHeight } = useMeasuredHeight();
67
- const contentRef = useRef2(null);
68
- const [contentHeight, setContentHeight] = useState2(0);
69
- const [scrollOffset, setScrollOffset] = useState2(0);
70
- useEffect2(() => {
71
- if (!contentRef.current) return;
72
- const { height } = measureElement2(contentRef.current);
73
- setContentHeight((prev) => Math.max(prev, height));
74
- });
75
- const maxScroll = Math.max(0, contentHeight - viewportHeight);
76
- const hiddenBelow = Math.max(0, maxScroll - scrollOffset);
77
- useInput((_input, key) => {
78
- if (key.upArrow) setScrollOffset((prev) => Math.max(0, prev - 1));
79
- if (key.downArrow) setScrollOffset((prev) => Math.min(maxScroll, prev + 1));
80
- });
81
- return {
82
- viewportRef,
83
- contentRef,
84
- contentMarginTop: scrollOffset > 0 ? -scrollOffset : 0,
85
- hiddenAbove: scrollOffset,
86
- hiddenBelow
87
- };
88
- }
89
-
90
- // src/cli/components/common/summary-panel.tsx
91
- import { jsx, jsxs } from "react/jsx-runtime";
92
- function formatSkillMarketplaces(skillConfigs) {
93
- if (skillConfigs.length === 0) return formatSourceDisplayName(DEFAULT_PUBLIC_SOURCE_NAME);
94
- const marketplaceNames = unique(
95
- skillConfigs.map((config) => config.origin).filter((origin) => origin !== EJECT_SOURCE)
96
- );
97
- if (marketplaceNames.length === 0) return ALL_SKILLS_EJECTED_LABEL;
98
- return marketplaceNames.map((name) => formatSourceDisplayName(name)).sort().join(" \xB7 ");
99
- }
100
- var PanelHeader = ({ sourceNames, stackName }) => /* @__PURE__ */ jsxs(
101
- Box,
102
- {
103
- flexDirection: "column",
104
- flexShrink: 0,
105
- borderStyle: "single",
106
- borderBottom: true,
107
- borderTop: false,
108
- borderLeft: false,
109
- borderRight: false,
110
- borderColor: CLI_COLORS.NEUTRAL,
111
- borderBottomDimColor: true,
112
- paddingBottom: 1,
113
- marginBottom: 1,
114
- children: [
115
- /* @__PURE__ */ jsxs(Box, { flexDirection: "row", columnGap: 1, children: [
116
- /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, bold: true, children: "Marketplace" }),
117
- /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: sourceNames })
118
- ] }),
119
- /* @__PURE__ */ jsxs(Box, { flexDirection: "row", columnGap: 1, children: [
120
- /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, bold: true, children: "Stack" }),
121
- /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: stackName ?? "none" })
122
- ] })
123
- ]
124
- }
125
- );
126
- var SummaryPanel = ({ stackName, ...summary }) => {
127
- const { viewportRef, contentRef, contentMarginTop, hiddenAbove, hiddenBelow } = usePanelScroll();
128
- const sourceNames = formatSkillMarketplaces(summary.skillConfigs);
129
- return /* @__PURE__ */ jsxs(
130
- Box,
131
- {
132
- flexDirection: "column",
133
- flexGrow: 1,
134
- flexBasis: 0,
135
- borderStyle: "single",
136
- borderColor: CLI_COLORS.NEUTRAL,
137
- paddingX: 2,
138
- children: [
139
- /* @__PURE__ */ jsx(Box, { ref: viewportRef, flexDirection: "column", flexGrow: 1, flexBasis: 0, overflow: "hidden", children: /* @__PURE__ */ jsxs(Box, { ref: contentRef, flexDirection: "column", flexShrink: 0, marginTop: contentMarginTop, children: [
140
- /* @__PURE__ */ jsx(PanelHeader, { sourceNames, stackName }),
141
- /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(SkillAgentSummary, { ...summary }) })
142
- ] }) }),
143
- /* @__PURE__ */ jsx(ScrollAffordance, { hiddenAbove, hiddenBelow })
144
- ]
145
- }
146
- );
147
- };
3
+ SummaryPanel,
4
+ summaryPanelBlock,
5
+ summaryPanelText
6
+ } from "../../chunk-33JICQD5.js";
7
+ import "../../chunk-N33AKFLR.js";
8
+ import "../../chunk-G7NUK3BF.js";
9
+ import "../../chunk-7OG635DK.js";
10
+ import "../../chunk-MHAQWMNJ.js";
148
11
  export {
149
- SummaryPanel
12
+ SummaryPanel,
13
+ summaryPanelBlock,
14
+ summaryPanelText
150
15
  };
151
16
  //# sourceMappingURL=summary-panel.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/components/common/summary-panel.tsx","../../../src/cli/components/hooks/use-panel-scroll.ts","../../../src/cli/components/hooks/use-measured-height.ts"],"sourcesContent":["import { Box, Text } from \"ink\";\nimport React from \"react\";\nimport { unique } from \"remeda\";\nimport {\n ALL_SKILLS_EJECTED_LABEL,\n CLI_COLORS,\n DEFAULT_PUBLIC_SOURCE_NAME,\n EJECT_SOURCE,\n formatSourceDisplayName,\n} from \"../../consts.js\";\nimport type { SkillConfig } from \"../../types/config.js\";\nimport { usePanelScroll } from \"../hooks/use-panel-scroll.js\";\nimport { ScrollAffordance } from \"./scroll-affordance.js\";\nimport { SkillAgentSummary, type SkillAgentSummaryProps } from \"./skill-agent-summary.js\";\n\nexport type SummaryPanelProps = SkillAgentSummaryProps & {\n /** `undefined` when the configuration was built from no stack. */\n stackName: string | undefined;\n};\n\n/**\n * No skills shows the default marketplace; all-ejected names none. Tombstoned entries count: the\n * summary below renders them as rows.\n */\nfunction formatSkillMarketplaces(skillConfigs: SkillConfig[]): string {\n if (skillConfigs.length === 0) return formatSourceDisplayName(DEFAULT_PUBLIC_SOURCE_NAME);\n\n const marketplaceNames = unique(\n skillConfigs.map((config) => config.origin).filter((origin) => origin !== EJECT_SOURCE),\n );\n if (marketplaceNames.length === 0) return ALL_SKILLS_EJECTED_LABEL;\n\n return marketplaceNames\n .map((name) => formatSourceDisplayName(name))\n .sort()\n .join(\" · \");\n}\n\ntype PanelHeaderProps = {\n sourceNames: string;\n stackName: string | undefined;\n};\n\n/** `flexShrink={0}`: squeezed by Yoga on a short terminal, its two rows overprint. */\nconst PanelHeader: React.FC<PanelHeaderProps> = ({ sourceNames, stackName }) => (\n <Box\n flexDirection=\"column\"\n flexShrink={0}\n borderStyle=\"single\"\n borderBottom={true}\n borderTop={false}\n borderLeft={false}\n borderRight={false}\n borderColor={CLI_COLORS.NEUTRAL}\n borderBottomDimColor\n paddingBottom={1}\n marginBottom={1}\n >\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Marketplace\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{sourceNames}</Text>\n </Box>\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Stack\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{stackName ?? \"none\"}</Text>\n </Box>\n </Box>\n);\n\n/** Horizontal padding only: unshrinkable vertical padding starves the viewport on a short terminal. */\nexport const SummaryPanel: React.FC<SummaryPanelProps> = ({ stackName, ...summary }) => {\n const { viewportRef, contentRef, contentMarginTop, hiddenAbove, hiddenBelow } = usePanelScroll();\n\n const sourceNames = formatSkillMarketplaces(summary.skillConfigs);\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n flexBasis={0}\n borderStyle=\"single\"\n borderColor={CLI_COLORS.NEUTRAL}\n paddingX={2}\n >\n <Box ref={viewportRef} flexDirection=\"column\" flexGrow={1} flexBasis={0} overflow=\"hidden\">\n <Box ref={contentRef} flexDirection=\"column\" flexShrink={0} marginTop={contentMarginTop}>\n <PanelHeader sourceNames={sourceNames} stackName={stackName} />\n\n <Box width=\"100%\">\n <SkillAgentSummary {...summary} />\n </Box>\n </Box>\n </Box>\n <ScrollAffordance hiddenAbove={hiddenAbove} hiddenBelow={hiddenBelow} />\n </Box>\n );\n};\n","import { useEffect, useRef, useState } from \"react\";\nimport type { Ref, RefObject } from \"react\";\nimport { type DOMElement, measureElement, useInput } from \"ink\";\nimport { useMeasuredHeight } from \"./use-measured-height.js\";\n\nexport type UsePanelScrollResult = {\n /** The `overflow=\"hidden\"` box. */\n viewportRef: Ref<DOMElement>;\n contentRef: RefObject<DOMElement | null>;\n contentMarginTop: number;\n hiddenAbove: number;\n hiddenBelow: number;\n};\n\n/** `↑`/`↓` line scrolling for one clipped viewport; hosts add their own `useInput` for other keys. */\nexport function usePanelScroll(): UsePanelScrollResult {\n const { ref: viewportRef, measuredHeight: viewportHeight } = useMeasuredHeight();\n const contentRef = useRef<DOMElement>(null);\n const [contentHeight, setContentHeight] = useState(0);\n const [scrollOffset, setScrollOffset] = useState(0);\n\n // eslint-disable-next-line react-hooks/exhaustive-deps -- re-measures every render; layout changes are invisible to React\n useEffect(() => {\n if (!contentRef.current) return;\n const { height } = measureElement(contentRef.current);\n // Yoga under-reports inside a squeezed viewport; trusting that loops the render.\n setContentHeight((prev) => Math.max(prev, height));\n });\n\n // Not returned: gating the clip on contentHeight paints content over the border.\n const maxScroll = Math.max(0, contentHeight - viewportHeight);\n const hiddenBelow = Math.max(0, maxScroll - scrollOffset);\n\n useInput((_input, key) => {\n if (key.upArrow) setScrollOffset((prev) => Math.max(0, prev - 1));\n if (key.downArrow) setScrollOffset((prev) => Math.min(maxScroll, prev + 1));\n });\n\n return {\n viewportRef,\n contentRef,\n contentMarginTop: scrollOffset > 0 ? -scrollOffset : 0,\n hiddenAbove: scrollOffset,\n hiddenBelow,\n };\n}\n","import { useRef, useState, useEffect } from \"react\";\nimport { type DOMElement, measureElement, useStdout } from \"ink\";\n\n/** Attach to a `flexGrow={1}` Box under an ancestor of constrained height; 0 before first layout. */\nexport function useMeasuredHeight(): {\n ref: React.Ref<DOMElement>;\n measuredHeight: number;\n} {\n const ref = useRef<DOMElement>(null);\n const [measuredHeight, setMeasuredHeight] = useState(0);\n const { stdout } = useStdout();\n\n const measure = () => {\n if (ref.current) {\n const { height } = measureElement(ref.current);\n setMeasuredHeight((prev) => (prev !== height ? height : prev));\n }\n };\n\n // Every render, so late-mounted refs are picked up.\n useEffect(() => {\n measure();\n });\n\n // Yoga may not have laid out yet on first render, so retry a few times.\n useEffect(() => {\n const RETRY_DELAYS_MS = [0, 16, 50];\n const timers: ReturnType<typeof setTimeout>[] = [];\n\n for (const delay of RETRY_DELAYS_MS) {\n timers.push(setTimeout(measure, delay));\n }\n\n return () => {\n for (const timer of timers) {\n clearTimeout(timer);\n }\n };\n // Mount-only: listing `measure` would re-arm the timers every render.\n }, []);\n\n useEffect(() => {\n stdout.on(\"resize\", measure);\n return () => {\n stdout.off(\"resize\", measure);\n };\n }, [stdout]);\n\n return { ref, measuredHeight };\n}\n"],"mappings":"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","names":["useEffect","useRef","useState","measureElement","useRef","useState","useEffect","measureElement"]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,31 +1,34 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDashboardFlow
4
- } from "../chunk-YXKTY5WM.js";
5
- import "../chunk-3ED3KHHD.js";
6
- import "../chunk-PLFANHRZ.js";
7
- import "../chunk-YGDWHDOY.js";
8
- import "../chunk-P6CYS4JK.js";
4
+ } from "../chunk-5MGRHS2G.js";
5
+ import "../chunk-3R3LHA4Q.js";
6
+ import "../chunk-5PPB6HT6.js";
7
+ import "../chunk-A3ZAXL5T.js";
9
8
  import "../chunk-OZXAJNLA.js";
10
- import "../chunk-PSUTNOQ2.js";
11
- import "../chunk-66AEVERM.js";
12
- import "../chunk-IWY5IR4F.js";
13
- import "../chunk-THO7LO5B.js";
14
- import "../chunk-5BNX73OU.js";
15
- import "../chunk-2YA4DDRM.js";
9
+ import "../chunk-P6CYS4JK.js";
10
+ import "../chunk-33JICQD5.js";
11
+ import "../chunk-N33AKFLR.js";
12
+ import "../chunk-255DGUCH.js";
13
+ import "../chunk-6CRA46YO.js";
14
+ import "../chunk-Y23MP2OC.js";
15
+ import "../chunk-KCLBLK3F.js";
16
+ import "../chunk-NISWBQNS.js";
17
+ import "../chunk-LUKDDHSI.js";
16
18
  import "../chunk-KIK5EZYD.js";
17
- import "../chunk-OCAVW6N5.js";
19
+ import "../chunk-G7NUK3BF.js";
20
+ import "../chunk-MBIOZ5LW.js";
18
21
  import {
19
22
  EXIT_CODES
20
- } from "../chunk-GEMW5RQ2.js";
23
+ } from "../chunk-7ZOWSCAO.js";
21
24
  import {
22
25
  findConfigLoadFailures,
23
26
  installationConfigsUnreadable,
24
27
  retiredSourceFolderIn,
25
28
  retiredSourceFolderUnsupported
26
- } from "../chunk-GAKVZNTX.js";
27
- import "../chunk-AUNRHWH4.js";
28
- import "../chunk-7C3PFRBU.js";
29
+ } from "../chunk-VILFCMRN.js";
30
+ import "../chunk-7OG635DK.js";
31
+ import "../chunk-MHAQWMNJ.js";
29
32
  import "../chunk-GHHJYNAN.js";
30
33
 
31
34
  // src/cli/hooks/init.ts
@@ -45,10 +48,10 @@ var hook = async function(options) {
45
48
  }
46
49
  };
47
50
  function sayTheRetiredSourceFolderIsUnsupported(cwd) {
48
- const replacement = retiredSourceFolderIn([cwd, os.homedir()]);
49
- if (replacement === null) return;
50
- process.stderr.write(`${retiredSourceFolderUnsupported(replacement)}
51
+ for (const root of retiredSourceFolderIn([os.homedir(), cwd])) {
52
+ process.stderr.write(`${retiredSourceFolderUnsupported(root)}
51
53
  `);
54
+ }
52
55
  }
53
56
  async function endRun(code) {
54
57
  await flush();
@@ -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 // No command: the dashboard.\n if (options.id === undefined) {\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 if (dashboard === \"cancelled\") this.error(\"Cancelled\", { exit: EXIT_CODES.CANCELLED });\n if (dashboard === \"shown\") await endRun(EXIT_CODES.SUCCESS);\n }\n};\n\n/** Notice only, once per run; stderr so piped output is unchanged. */\nfunction sayTheRetiredSourceFolderIsUnsupported(cwd: string): void {\n const replacement = retiredSourceFolderIn([cwd, os.homedir()]);\n if (replacement === null) return;\n process.stderr.write(`${retiredSourceFolderUnsupported(replacement)}\\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,QAAW;AAC5B,UAAM,aAAa,QAAQ,IAAI;AAE/B,UAAM,aAAa,MAAM,uBAAuB,UAAU;AAC1D,QAAI,WAAW,SAAS,GAAG;AACzB,WAAK,MAAM,8BAA8B,UAAU,GAAG,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,IAClF;AAEA,UAAM,YAAY,MAAM,iBAAiB,YAAY,QAAQ,MAAM;AACnE,QAAI,cAAc,YAAa,MAAK,MAAM,aAAa,EAAE,MAAM,WAAW,UAAU,CAAC;AACrF,QAAI,cAAc,QAAS,OAAM,OAAO,WAAW,OAAO;AAAA,EAC5D;AACF;AAGA,SAAS,uCAAuC,KAAmB;AACjE,QAAM,cAAc,sBAAsB,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC;AAC7D,MAAI,gBAAgB,KAAM;AAC1B,UAAQ,OAAO,MAAM,GAAG,+BAA+B,WAAW,CAAC;AAAA,CAAI;AACzE;AAGA,eAAe,OAAO,MAA8B;AAClD,QAAM,MAAM;AACZ,UAAQ,KAAK,IAAI;AACnB;AAEA,IAAO,eAAQ;","names":[]}
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 // No command: the dashboard.\n if (options.id === undefined) {\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 if (dashboard === \"cancelled\") this.error(\"Cancelled\", { exit: EXIT_CODES.CANCELLED });\n if (dashboard === \"shown\") await endRun(EXIT_CODES.SUCCESS);\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,QAAW;AAC5B,UAAM,aAAa,QAAQ,IAAI;AAE/B,UAAM,aAAa,MAAM,uBAAuB,UAAU;AAC1D,QAAI,WAAW,SAAS,GAAG;AACzB,WAAK,MAAM,8BAA8B,UAAU,GAAG,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,IAClF;AAEA,UAAM,YAAY,MAAM,iBAAiB,YAAY,QAAQ,MAAM;AACnE,QAAI,cAAc,YAAa,MAAK,MAAM,aAAa,EAAE,MAAM,WAAW,UAAU,CAAC;AACrF,QAAI,cAAc,QAAS,OAAM,OAAO,WAAW,OAAO;AAAA,EAC5D;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-KCLBLK3F.js";
5
+ import "./chunk-NISWBQNS.js";
6
+ import "./chunk-LUKDDHSI.js";
7
+ import "./chunk-VILFCMRN.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-54VIKN4T.js.map