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,19 +1,18 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- SkillAgentSummary
4
- } from "../chunk-PMUZR4XO.js";
5
- import "../chunk-RIK45Q4I.js";
6
2
  import {
7
3
  render
8
4
  } from "../chunk-KIK5EZYD.js";
5
+ import {
6
+ SkillAgentSummary
7
+ } from "../chunk-G7NUK3BF.js";
9
8
  import {
10
9
  otherInstallationsInThisScope,
11
10
  providerFlag,
12
11
  providerNamedBy
13
- } from "../chunk-OCAVW6N5.js";
12
+ } from "../chunk-MBIOZ5LW.js";
14
13
  import {
15
14
  BaseCommand
16
- } from "../chunk-GEMW5RQ2.js";
15
+ } from "../chunk-7ZOWSCAO.js";
17
16
  import {
18
17
  INSTALL_MODE_LABELS,
19
18
  chooseProviderForThisRun,
@@ -22,19 +21,23 @@ import {
22
21
  getInstallationInfo,
23
22
  loadProjectConfig,
24
23
  providerInUse
25
- } from "../chunk-GAKVZNTX.js";
26
- import "../chunk-AUNRHWH4.js";
24
+ } from "../chunk-VILFCMRN.js";
25
+ import "../chunk-7OG635DK.js";
27
26
  import {
28
27
  CLI_COLORS,
29
28
  CLI_INVOKE_COMMAND,
30
29
  DEFAULT_BRANDING
31
- } from "../chunk-7C3PFRBU.js";
30
+ } from "../chunk-MHAQWMNJ.js";
32
31
  import "../chunk-GHHJYNAN.js";
33
32
 
34
33
  // src/cli/commands/list.tsx
35
34
  import { useEffect } from "react";
36
35
  import { Box, Text, useApp } from "ink";
37
36
  import { jsx, jsxs } from "react/jsx-runtime";
37
+ var HeaderRow = ({ label, value }) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", columnGap: 1, children: [
38
+ /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, bold: true, children: label }) }),
39
+ /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: value })
40
+ ] });
38
41
  var ListView = ({ mode, source, skillConfigs, agentConfigs }) => {
39
42
  const { exit } = useApp();
40
43
  useEffect(() => {
@@ -43,14 +46,8 @@ var ListView = ({ mode, source, skillConfigs, agentConfigs }) => {
43
46
  }, [exit]);
44
47
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [
45
48
  /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
46
- /* @__PURE__ */ jsxs(Box, { flexDirection: "row", columnGap: 1, children: [
47
- /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, bold: true, children: "Mode" }),
48
- /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: mode })
49
- ] }),
50
- source && /* @__PURE__ */ jsxs(Box, { flexDirection: "row", columnGap: 1, children: [
51
- /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, bold: true, children: "Marketplace" }),
52
- /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: source })
53
- ] })
49
+ /* @__PURE__ */ jsx(HeaderRow, { label: "Mode", value: mode }),
50
+ source && /* @__PURE__ */ jsx(HeaderRow, { label: "Marketplace", value: source })
54
51
  ] }),
55
52
  /* @__PURE__ */ jsx(
56
53
  SkillAgentSummary,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/list.tsx"],"sourcesContent":["import React, { useEffect } from \"react\";\n\nimport { Box, Text, useApp } from \"ink\";\nimport { render } from \"../components/render.js\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { CLI_INVOKE_COMMAND, CLI_COLORS, DEFAULT_BRANDING } from \"../consts.js\";\nimport { chooseProviderForThisRun, providerInUse } from \"../lib/installation/install-layout.js\";\nimport {\n otherInstallationsInThisScope,\n providerFlag,\n providerNamedBy,\n} from \"../lib/installation/provider-flag.js\";\nimport { getInstallationInfo, formatInstallationDisplay } from \"../lib/plugins/index.js\";\nimport {\n detectInstallation,\n INSTALL_MODE_LABELS,\n type Installation,\n} from \"../lib/installation/installation.js\";\nimport { loadProjectConfig } from \"../lib/configuration/project-config.js\";\nimport { SkillAgentSummary } from \"../components/common/skill-agent-summary.js\";\nimport type { AgentScopeConfig, ProjectConfig, SkillConfig } from \"../types/config.js\";\n\ntype ListViewProps = {\n mode: string;\n source?: string | undefined;\n skillConfigs: SkillConfig[];\n agentConfigs: AgentScopeConfig[];\n};\n\nconst ListView: React.FC<ListViewProps> = ({ mode, source, skillConfigs, agentConfigs }) => {\n const { exit } = useApp();\n\n useEffect(() => {\n const timer = setTimeout(() => exit(), 0);\n return () => clearTimeout(timer);\n }, [exit]);\n\n return (\n <Box flexDirection=\"column\" paddingX={1} paddingY={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Mode\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{mode}</Text>\n </Box>\n {source && (\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Marketplace\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{source}</Text>\n </Box>\n )}\n </Box>\n\n {/* Installed and current are one configuration, so every row reads unchanged. */}\n <SkillAgentSummary\n skillConfigs={skillConfigs}\n agentConfigs={agentConfigs}\n installedSkillConfigs={skillConfigs}\n installedAgentConfigs={agentConfigs}\n isInitMode={false}\n />\n </Box>\n );\n};\n\nexport default class List extends BaseCommand {\n static summary = \"Show installation information\";\n static description = `Display details about the ${DEFAULT_BRANDING.NAME} installation (local or plugin mode)`;\n static aliases = [\"ls\"];\n\n static flags = { provider: providerFlag() };\n\n static examples = [\n {\n description: \"Show current installation details\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n ];\n\n /** Names the other installation in this scope; reports rather than refuses, like `doctor`. */\n private async sayWhichInstallationThisIs(providerFlagValue: string | undefined): Promise<void> {\n const named = providerNamedBy(providerFlagValue);\n if (named !== undefined) {\n chooseProviderForThisRun(named);\n return;\n }\n\n const cwd = process.cwd();\n const line = await otherInstallationsInThisScope(cwd, providerInUse(cwd));\n if (line !== null) this.log(line);\n }\n\n async run(): Promise<void> {\n const { flags } = await this.parse(List);\n await this.sayWhichInstallationThisIs(flags.provider);\n await this.ensureConfigReadable(process.cwd());\n\n const installation = await detectInstallation();\n if (!installation) return this.reportNoInstallation();\n\n const loaded = await loadProjectConfig(installation.projectDir);\n if (!loaded?.config || !process.stdin.isTTY) return this.printInstallationInfo();\n\n await showListView(installation, loaded.config);\n }\n\n private reportNoInstallation(): void {\n this.log(\"No installation found.\");\n this.log(`Run '${CLI_INVOKE_COMMAND} init' to create one.`);\n }\n\n private async printInstallationInfo(): Promise<void> {\n const info = await getInstallationInfo();\n if (!info) return;\n\n this.log(\"\");\n this.log(formatInstallationDisplay(info));\n this.log(\"\");\n }\n}\n\nasync function showListView(installation: Installation, config: ProjectConfig): Promise<void> {\n const { waitUntilExit, clear } = render(\n <ListView\n mode={INSTALL_MODE_LABELS[installation.mode]}\n source={config.marketplace}\n skillConfigs={config.skills.filter((skill) => !skill.excluded)}\n agentConfigs={config.agents.filter((agent) => !agent.excluded)}\n />,\n );\n\n await waitUntilExit();\n clear();\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/list.tsx"],"sourcesContent":["import React, { useEffect } from \"react\";\n\nimport { Box, Text, useApp } from \"ink\";\nimport { render } from \"../components/render.js\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { CLI_INVOKE_COMMAND, CLI_COLORS, DEFAULT_BRANDING } from \"../consts.js\";\nimport { chooseProviderForThisRun, providerInUse } from \"../lib/installation/install-layout.js\";\nimport {\n otherInstallationsInThisScope,\n providerFlag,\n providerNamedBy,\n} from \"../lib/installation/provider-flag.js\";\nimport { getInstallationInfo, formatInstallationDisplay } from \"../lib/plugins/index.js\";\nimport {\n detectInstallation,\n INSTALL_MODE_LABELS,\n type Installation,\n} from \"../lib/installation/installation.js\";\nimport { loadProjectConfig } from \"../lib/configuration/project-config.js\";\nimport { SkillAgentSummary } from \"../components/common/skill-agent-summary.js\";\nimport type { AgentScopeConfig, ProjectConfig, SkillConfig } from \"../types/config.js\";\n\ntype ListViewProps = {\n mode: string;\n source?: string | undefined;\n skillConfigs: SkillConfig[];\n agentConfigs: AgentScopeConfig[];\n};\n\n/** The label never shrinks: a value too long for the line wraps beside it instead. */\nconst HeaderRow: React.FC<{ label: string; value: string }> = ({ label, value }) => (\n <Box flexDirection=\"row\" columnGap={1}>\n <Box flexShrink={0}>\n <Text color={CLI_COLORS.WARNING} bold>\n {label}\n </Text>\n </Box>\n <Text color={CLI_COLORS.NEUTRAL}>{value}</Text>\n </Box>\n);\n\nconst ListView: React.FC<ListViewProps> = ({ mode, source, skillConfigs, agentConfigs }) => {\n const { exit } = useApp();\n\n useEffect(() => {\n const timer = setTimeout(() => exit(), 0);\n return () => clearTimeout(timer);\n }, [exit]);\n\n return (\n <Box flexDirection=\"column\" paddingX={1} paddingY={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <HeaderRow label=\"Mode\" value={mode} />\n {source && <HeaderRow label=\"Marketplace\" value={source} />}\n </Box>\n\n {/* Installed and current are one configuration, so every row reads unchanged. */}\n <SkillAgentSummary\n skillConfigs={skillConfigs}\n agentConfigs={agentConfigs}\n installedSkillConfigs={skillConfigs}\n installedAgentConfigs={agentConfigs}\n isInitMode={false}\n />\n </Box>\n );\n};\n\nexport default class List extends BaseCommand {\n static summary = \"Show installation information\";\n static description = `Display details about the ${DEFAULT_BRANDING.NAME} installation (local or plugin mode)`;\n static aliases = [\"ls\"];\n\n static flags = { provider: providerFlag() };\n\n static examples = [\n {\n description: \"Show current installation details\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n ];\n\n /** Names the other installation in this scope; reports rather than refuses, like `doctor`. */\n private async sayWhichInstallationThisIs(providerFlagValue: string | undefined): Promise<void> {\n const named = providerNamedBy(providerFlagValue);\n if (named !== undefined) {\n chooseProviderForThisRun(named);\n return;\n }\n\n const cwd = process.cwd();\n const line = await otherInstallationsInThisScope(cwd, providerInUse(cwd));\n if (line !== null) this.log(line);\n }\n\n async run(): Promise<void> {\n const { flags } = await this.parse(List);\n await this.sayWhichInstallationThisIs(flags.provider);\n await this.ensureConfigReadable(process.cwd());\n\n const installation = await detectInstallation();\n if (!installation) return this.reportNoInstallation();\n\n const loaded = await loadProjectConfig(installation.projectDir);\n if (!loaded?.config || !process.stdin.isTTY) return this.printInstallationInfo();\n\n await showListView(installation, loaded.config);\n }\n\n private reportNoInstallation(): void {\n this.log(\"No installation found.\");\n this.log(`Run '${CLI_INVOKE_COMMAND} init' to create one.`);\n }\n\n private async printInstallationInfo(): Promise<void> {\n const info = await getInstallationInfo();\n if (!info) return;\n\n this.log(\"\");\n this.log(formatInstallationDisplay(info));\n this.log(\"\");\n }\n}\n\nasync function showListView(installation: Installation, config: ProjectConfig): Promise<void> {\n const { waitUntilExit, clear } = render(\n <ListView\n mode={INSTALL_MODE_LABELS[installation.mode]}\n source={config.marketplace}\n skillConfigs={config.skills.filter((skill) => !skill.excluded)}\n agentConfigs={config.agents.filter((agent) => !agent.excluded)}\n />,\n );\n\n await waitUntilExit();\n clear();\n}\n"],"mappings":"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","names":[]}
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  BaseCommand,
4
4
  EXIT_CODES
5
- } from "../../chunk-GEMW5RQ2.js";
5
+ } from "../../chunk-7ZOWSCAO.js";
6
6
  import {
7
7
  isDirectoryEmpty,
8
8
  validateKebabCaseName,
9
9
  validateMarketplaceName,
10
10
  writeFile
11
- } from "../../chunk-GAKVZNTX.js";
12
- import "../../chunk-AUNRHWH4.js";
11
+ } from "../../chunk-VILFCMRN.js";
12
+ import "../../chunk-7OG635DK.js";
13
13
  import {
14
14
  CLI_INVOKE_COMMAND,
15
15
  DEFAULT_VERSION,
@@ -19,7 +19,7 @@ import {
19
19
  SKILL_RULES_PATH,
20
20
  STACKS_FILE_PATH,
21
21
  STANDARD_FILES
22
- } from "../../chunk-7C3PFRBU.js";
22
+ } from "../../chunk-MHAQWMNJ.js";
23
23
  import "../../chunk-GHHJYNAN.js";
24
24
 
25
25
  // src/cli/commands/new/marketplace.ts
@@ -1,24 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  loadSource
4
- } from "../chunk-66AEVERM.js";
5
- import "../chunk-IWY5IR4F.js";
6
- import "../chunk-THO7LO5B.js";
7
- import "../chunk-5BNX73OU.js";
8
- import "../chunk-2YA4DDRM.js";
4
+ } from "../chunk-6CRA46YO.js";
5
+ import "../chunk-Y23MP2OC.js";
6
+ import "../chunk-KCLBLK3F.js";
7
+ import "../chunk-NISWBQNS.js";
8
+ import "../chunk-LUKDDHSI.js";
9
9
  import {
10
10
  BaseCommand
11
- } from "../chunk-GEMW5RQ2.js";
11
+ } from "../chunk-7ZOWSCAO.js";
12
12
  import {
13
- STATUS_MESSAGES,
14
- typedValues
15
- } from "../chunk-GAKVZNTX.js";
13
+ STATUS_MESSAGES
14
+ } from "../chunk-VILFCMRN.js";
16
15
  import {
17
16
  plural,
18
17
  stripTerminalControls,
19
- truncateText
20
- } from "../chunk-AUNRHWH4.js";
21
- import "../chunk-7C3PFRBU.js";
18
+ truncateText,
19
+ typedValues
20
+ } from "../chunk-7OG635DK.js";
21
+ import {
22
+ EDITOR_ADDRESS
23
+ } from "../chunk-MHAQWMNJ.js";
22
24
  import "../chunk-GHHJYNAN.js";
23
25
 
24
26
  // src/cli/commands/search.ts
@@ -28,7 +30,7 @@ import { sortBy } from "remeda";
28
30
  var MAX_DESCRIPTION_WIDTH = 50;
29
31
  var Search = class _Search extends BaseCommand {
30
32
  static summary = "Search the catalog of available skills";
31
- static description = "Read-only catalog browse. Searches the marketplace this installation reads from, plus the local skills already on disk, by id, displayName, slug, description, or category. To install one, add it in agentsinc.sh/editor.";
33
+ static description = `Read-only catalog browse. Searches the marketplace this installation reads from, plus the local skills already on disk, by id, displayName, slug, description, or category. To install one, add it in ${EDITOR_ADDRESS}.`;
32
34
  static examples = [
33
35
  {
34
36
  description: "Search for React skills",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/search.ts"],"sourcesContent":["import { Args } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { loadSource } from \"../lib/operations/index.js\";\nimport type { ResolvedSkill } from \"../types/index.js\";\nimport { STATUS_MESSAGES } from \"../utils/messages.js\";\nimport { plural, stripTerminalControls, truncateText } from \"../utils/string.js\";\nimport { typedValues } from \"../utils/typed-object.js\";\n\nconst MAX_DESCRIPTION_WIDTH = 50;\n\n/** Plain strings: sanitised values are no longer known to be in their unions. */\ntype ResultRow = {\n id: string;\n name: string;\n source: string;\n category: string;\n description: string;\n};\n\nexport default class Search extends BaseCommand {\n static summary = \"Search the catalog of available skills\";\n static description =\n \"Read-only catalog browse. Searches the marketplace this installation reads from, \" +\n \"plus the local skills already on disk, by id, displayName, slug, description, or \" +\n \"category. To install one, add it in agentsinc.sh/editor.\";\n\n static examples = [\n {\n description: \"Search for React skills\",\n command: \"<%= config.bin %> search react\",\n },\n {\n description: \"Search by any keyword (matches id, name, description, category)\",\n command: \"<%= config.bin %> search state\",\n },\n ];\n\n static args = {\n query: Args.string({\n description: \"Search query (matches id, displayName, slug, description, category)\",\n required: true,\n }),\n };\n\n static flags = {};\n\n async run(): Promise<void> {\n const { args } = await this.parse(Search);\n // The configs name the marketplace searched, so an unreadable one is not read past.\n await this.ensureConfigReadable(process.cwd());\n await this.runSearch(args.query);\n }\n\n private async runSearch(query: string): Promise<void> {\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n const results = skillsMatching(await loadSearchableSkills(), query);\n\n this.log(\"\");\n if (results.length === 0) {\n this.warn(`No skills found matching \"${query}\"`);\n return;\n }\n\n this.log(`Found ${plural(results.length, \"skill\")} matching \"${query}\"`);\n this.log(\"\");\n printResultsTable(results);\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n\n/** The marketplace matrix, with on-disk local skills already merged in by `loadSource`. */\nasync function loadSearchableSkills(): Promise<ResolvedSkill[]> {\n const { sourceResult } = await loadSource({ projectDir: process.cwd() });\n\n return typedValues(sourceResult.matrix.skills);\n}\n\n/** In display-name order, case aside. */\nfunction skillsMatching(skills: ResolvedSkill[], query: string): ResolvedSkill[] {\n return sortBy(\n skills.filter((skill) => matchesQuery(skill, query)),\n (skill) => skill.displayName.toLowerCase(),\n );\n}\n\nfunction printResultsTable(results: ResolvedSkill[]): void {\n printTable({\n data: results.map(toResultRow),\n columns: [\n { key: \"id\", name: \"ID\" },\n { key: \"name\", name: \"Name\" },\n { key: \"source\", name: \"Origin\" },\n { key: \"category\", name: \"Category\" },\n { key: \"description\", name: \"Description\" },\n ],\n headerOptions: { bold: true },\n });\n}\n\n/** Strips terminal controls: a third-party marketplace's text could otherwise repaint the table. */\nfunction toResultRow(skill: ResolvedSkill): ResultRow {\n return {\n id: stripTerminalControls(skill.id),\n name: stripTerminalControls(skill.displayName),\n source: stripTerminalControls(activeSourceName(skill)),\n category: stripTerminalControls(skill.category),\n description: truncateText(skill.description, MAX_DESCRIPTION_WIDTH),\n };\n}\n\n/** `loadSource` always tags an origin, so an untagged skill is a bug, not a fallback case. */\nfunction activeSourceName(skill: ResolvedSkill): string {\n const { activeSource } = skill;\n if (!activeSource) {\n throw new Error(\n `Skill \"${skill.id}\" was loaded with no origin, so where it comes from is unknown`,\n );\n }\n return activeSource.name;\n}\n\nfunction matchesQuery(skill: ResolvedSkill, query: string): boolean {\n const lowerQuery = query.toLowerCase();\n return [skill.id, skill.displayName, skill.slug, skill.description, skill.category].some(\n (field) => field.toLowerCase().includes(lowerQuery),\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/search.ts"],"sourcesContent":["import { Args } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { EDITOR_ADDRESS } from \"../consts.js\";\nimport { loadSource } from \"../lib/operations/index.js\";\nimport type { ResolvedSkill } from \"../types/index.js\";\nimport { STATUS_MESSAGES } from \"../utils/messages.js\";\nimport { plural, stripTerminalControls, truncateText } from \"../utils/string.js\";\nimport { typedValues } from \"../utils/typed-object.js\";\n\nconst MAX_DESCRIPTION_WIDTH = 50;\n\n/** Plain strings: sanitised values are no longer known to be in their unions. */\ntype ResultRow = {\n id: string;\n name: string;\n source: string;\n category: string;\n description: string;\n};\n\nexport default class Search extends BaseCommand {\n static summary = \"Search the catalog of available skills\";\n static description =\n \"Read-only catalog browse. Searches the marketplace this installation reads from, \" +\n \"plus the local skills already on disk, by id, displayName, slug, description, or \" +\n `category. To install one, add it in ${EDITOR_ADDRESS}.`;\n\n static examples = [\n {\n description: \"Search for React skills\",\n command: \"<%= config.bin %> search react\",\n },\n {\n description: \"Search by any keyword (matches id, name, description, category)\",\n command: \"<%= config.bin %> search state\",\n },\n ];\n\n static args = {\n query: Args.string({\n description: \"Search query (matches id, displayName, slug, description, category)\",\n required: true,\n }),\n };\n\n static flags = {};\n\n async run(): Promise<void> {\n const { args } = await this.parse(Search);\n // The configs name the marketplace searched, so an unreadable one is not read past.\n await this.ensureConfigReadable(process.cwd());\n await this.runSearch(args.query);\n }\n\n private async runSearch(query: string): Promise<void> {\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n const results = skillsMatching(await loadSearchableSkills(), query);\n\n this.log(\"\");\n if (results.length === 0) {\n this.warn(`No skills found matching \"${query}\"`);\n return;\n }\n\n this.log(`Found ${plural(results.length, \"skill\")} matching \"${query}\"`);\n this.log(\"\");\n printResultsTable(results);\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n\n/** The marketplace matrix, with on-disk local skills already merged in by `loadSource`. */\nasync function loadSearchableSkills(): Promise<ResolvedSkill[]> {\n const { sourceResult } = await loadSource({ projectDir: process.cwd() });\n\n return typedValues(sourceResult.matrix.skills);\n}\n\n/** In display-name order, case aside. */\nfunction skillsMatching(skills: ResolvedSkill[], query: string): ResolvedSkill[] {\n return sortBy(\n skills.filter((skill) => matchesQuery(skill, query)),\n (skill) => skill.displayName.toLowerCase(),\n );\n}\n\nfunction printResultsTable(results: ResolvedSkill[]): void {\n printTable({\n data: results.map(toResultRow),\n columns: [\n { key: \"id\", name: \"ID\" },\n { key: \"name\", name: \"Name\" },\n { key: \"source\", name: \"Origin\" },\n { key: \"category\", name: \"Category\" },\n { key: \"description\", name: \"Description\" },\n ],\n headerOptions: { bold: true },\n });\n}\n\n/** Strips terminal controls: a third-party marketplace's text could otherwise repaint the table. */\nfunction toResultRow(skill: ResolvedSkill): ResultRow {\n return {\n id: stripTerminalControls(skill.id),\n name: stripTerminalControls(skill.displayName),\n source: stripTerminalControls(activeSourceName(skill)),\n category: stripTerminalControls(skill.category),\n description: truncateText(skill.description, MAX_DESCRIPTION_WIDTH),\n };\n}\n\n/** `loadSource` always tags an origin, so an untagged skill is a bug, not a fallback case. */\nfunction activeSourceName(skill: ResolvedSkill): string {\n const { activeSource } = skill;\n if (!activeSource) {\n throw new Error(\n `Skill \"${skill.id}\" was loaded with no origin, so where it comes from is unknown`,\n );\n }\n return activeSource.name;\n}\n\nfunction matchesQuery(skill: ResolvedSkill, query: string): boolean {\n const lowerQuery = query.toLowerCase();\n return [skill.id, skill.displayName, skill.slug, skill.description, skill.category].some(\n (field) => field.toLowerCase().includes(lowerQuery),\n );\n}\n"],"mappings":"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","names":[]}
@@ -2,21 +2,21 @@
2
2
  import {
3
3
  publishSeedConfig,
4
4
  seedPayloadForInstallation
5
- } from "../chunk-ELV5WDS3.js";
5
+ } from "../chunk-6LUTY35Q.js";
6
6
  import {
7
7
  unofferablePlacementsFound
8
- } from "../chunk-HACRR422.js";
9
- import "../chunk-YGDWHDOY.js";
10
- import "../chunk-2YA4DDRM.js";
8
+ } from "../chunk-MOL2J5HS.js";
9
+ import "../chunk-A3ZAXL5T.js";
10
+ import "../chunk-LUKDDHSI.js";
11
11
  import {
12
12
  providerFlag,
13
13
  providerNamedBy,
14
14
  refuseAnAmbiguousInstallation
15
- } from "../chunk-OCAVW6N5.js";
15
+ } from "../chunk-MBIOZ5LW.js";
16
16
  import {
17
17
  BaseCommand,
18
18
  EXIT_CODES
19
- } from "../chunk-GEMW5RQ2.js";
19
+ } from "../chunk-7ZOWSCAO.js";
20
20
  import {
21
21
  formatZodErrors,
22
22
  getErrorMessage,
@@ -25,16 +25,16 @@ import {
25
25
  sharedConfigDestinations,
26
26
  sharedIdNamesAFolder,
27
27
  sharedSkillsLeftBehind,
28
- typedEntries,
29
28
  warn
30
- } from "../chunk-GAKVZNTX.js";
29
+ } from "../chunk-VILFCMRN.js";
31
30
  import {
32
31
  stripTerminalControls,
33
- truncateText
34
- } from "../chunk-AUNRHWH4.js";
32
+ truncateText,
33
+ typedEntries
34
+ } from "../chunk-7OG635DK.js";
35
35
  import {
36
36
  installableSeedPayloadSchema
37
- } from "../chunk-7C3PFRBU.js";
37
+ } from "../chunk-MHAQWMNJ.js";
38
38
  import "../chunk-GHHJYNAN.js";
39
39
 
40
40
  // src/cli/commands/share.ts
@@ -1,59 +1,62 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- RemovalPlanConfirm
4
- } from "../chunk-O4LN3HFI.js";
3
+ Confirm
4
+ } from "../chunk-OZXAJNLA.js";
5
5
  import {
6
6
  promptConfirm
7
7
  } from "../chunk-P6CYS4JK.js";
8
- import "../chunk-OZXAJNLA.js";
8
+ import {
9
+ summaryPanelBlock
10
+ } from "../chunk-33JICQD5.js";
11
+ import "../chunk-N33AKFLR.js";
9
12
  import {
10
13
  lazyGateDeps,
11
14
  mutateGlobal,
12
15
  propagateGlobalRemoval
13
- } from "../chunk-66AEVERM.js";
14
- import "../chunk-IWY5IR4F.js";
16
+ } from "../chunk-6CRA46YO.js";
17
+ import "../chunk-Y23MP2OC.js";
15
18
  import {
16
19
  loadAgentDefs
17
- } from "../chunk-THO7LO5B.js";
18
- import "../chunk-5BNX73OU.js";
20
+ } from "../chunk-KCLBLK3F.js";
21
+ import "../chunk-NISWBQNS.js";
19
22
  import {
20
23
  listAgentFilesOf,
21
24
  splitAgentsByProvenance
22
- } from "../chunk-2YA4DDRM.js";
25
+ } from "../chunk-LUKDDHSI.js";
23
26
  import "../chunk-KIK5EZYD.js";
27
+ import "../chunk-G7NUK3BF.js";
24
28
  import {
25
29
  providerFlag,
26
30
  providerNamedBy,
27
31
  refuseAnAmbiguousInstallation
28
- } from "../chunk-OCAVW6N5.js";
32
+ } from "../chunk-MBIOZ5LW.js";
29
33
  import {
30
34
  BaseCommand,
31
35
  EXIT_CODES
32
- } from "../chunk-GEMW5RQ2.js";
36
+ } from "../chunk-7ZOWSCAO.js";
33
37
  import {
34
38
  ConfigLoadError,
35
39
  INFO_MESSAGES,
36
40
  SUCCESS_MESSAGES,
37
- UNINSTALL_PLAN,
38
41
  agentCodec,
39
42
  buildMarketplacePluginRef,
40
- compiledAgentsRemoval,
43
+ configFileRemoved,
41
44
  directoryExists,
42
45
  fileExists,
43
46
  getErrorMessage,
44
47
  getProjectPluginsDir,
45
48
  hostAt,
49
+ isAgentName,
46
50
  isHomeDirectory,
47
51
  listDirectories,
48
52
  listPluginNames,
49
53
  loadProjectConfigAt,
50
54
  loadSkillsMatrixFromSource,
51
- localSkillsRemoval,
52
55
  notInstalledHere,
53
56
  parseMarketplacePluginRef,
54
57
  pluginLeftRegistered,
55
58
  providerInUse,
56
- readForkedFromMetadata,
59
+ readLocalSkillMetadata,
57
60
  registeredProjectUpdateSkipped,
58
61
  registeredProjectsUpdateFailed,
59
62
  registeredProjectsUpdated,
@@ -66,21 +69,22 @@ import {
66
69
  uninstallNeedsTerminal,
67
70
  uninstallSkillMetadataUnreadable,
68
71
  unmarkedAgentsKept
69
- } from "../chunk-GAKVZNTX.js";
72
+ } from "../chunk-VILFCMRN.js";
70
73
  import {
71
74
  plural
72
- } from "../chunk-AUNRHWH4.js";
75
+ } from "../chunk-7OG635DK.js";
73
76
  import {
74
77
  CLAUDE_DIR,
75
78
  DEFAULT_BRANDING,
76
79
  EJECT_SOURCE,
77
- STANDARD_FILES
78
- } from "../chunk-7C3PFRBU.js";
80
+ STANDARD_FILES,
81
+ isActiveAt
82
+ } from "../chunk-MHAQWMNJ.js";
79
83
  import "../chunk-GHHJYNAN.js";
80
84
 
81
85
  // src/cli/commands/uninstall.tsx
82
86
  import "react";
83
- import { unique } from "remeda";
87
+ import { unique, uniqueBy } from "remeda";
84
88
  import path from "path";
85
89
  import { Flags } from "@oclif/core";
86
90
  import { jsx } from "react/jsx-runtime";
@@ -96,16 +100,73 @@ function buildRemovalPlan(target) {
96
100
  kept: keptStatements(target, agents)
97
101
  };
98
102
  }
103
+ function removalPanel(plan, target) {
104
+ const kept = target.scope === "project" ? globalEntriesOf(target.config) : NOTHING_KEPT;
105
+ return {
106
+ skillConfigs: kept.skills,
107
+ agentConfigs: kept.agents,
108
+ installedSkillConfigs: [...removedSkills(plan, target), ...kept.skills],
109
+ installedAgentConfigs: [...namedAgentRemovals(plan, target.scope).named, ...kept.agents],
110
+ isInitMode: false,
111
+ skillNames: namesTheCopiesRecord(target.cliSkills),
112
+ stackName: void 0
113
+ };
114
+ }
115
+ function namesTheCopiesRecord(cliSkills) {
116
+ return new Map(
117
+ cliSkills.flatMap(
118
+ ({ skillId, displayName }) => displayName === void 0 ? [] : [[skillId, displayName]]
119
+ )
120
+ );
121
+ }
122
+ var NOTHING_KEPT = { skills: [], agents: [] };
123
+ function globalEntriesOf(config) {
124
+ if (config === null) return NOTHING_KEPT;
125
+ return {
126
+ skills: config.skills.filter((skill) => isActiveAt(skill, "global")),
127
+ agents: config.agents.filter((agent) => isActiveAt(agent, "global"))
128
+ };
129
+ }
130
+ function removedSkills(plan, target) {
131
+ const copied = new Set(planEntries(plan, "skills").flatMap((entry) => entry.skillNames));
132
+ const plugins = new Set(planEntries(plan, "plugins").flatMap((entry) => entry.names));
133
+ const marketplaceName = target.config?.marketplaceName;
134
+ const copies = target.cliSkills.filter(({ dirName }) => copied.has(dirName)).map(({ skillId }) => ({ id: skillId, scope: target.scope, origin: EJECT_SOURCE }));
135
+ const pluginSkills = (target.config?.skills ?? []).filter((skill) => !skill.excluded).filter((skill) => pluginRefsOf(skill, marketplaceName).some((ref) => plugins.has(ref))).map((skill) => ({ ...skill, scope: target.scope }));
136
+ return uniqueBy([...copies, ...pluginSkills], (skill) => skill.id);
137
+ }
138
+ function namedAgentRemovals(plan, scope) {
139
+ const entries = planEntries(plan, "agents");
140
+ const names = entries.flatMap((entry) => entry.agentNames);
141
+ return {
142
+ named: names.filter(isAgentName).map((name) => ({ name, scope })),
143
+ files: entries.flatMap(
144
+ (entry) => entry.agentNames.filter((name) => !isAgentName(name)).map((name) => path.join(entry.agentsDir, `${name}${entry.codec.extension}`))
145
+ )
146
+ };
147
+ }
99
148
  function hasAnythingToRemove(plan) {
100
149
  return plan.entries.length > 0;
101
150
  }
151
+ function removedFileLines(plan, scope) {
152
+ const configFiles = planEntries(plan, "config").flatMap(
153
+ (entry) => entry.fileNames.map((fileName) => `${entry.sourceDir}/${fileName}`)
154
+ );
155
+ return [...namedAgentRemovals(plan, scope).files, ...configFiles].map(configFileRemoved);
156
+ }
102
157
  function pluginsEntry(target) {
103
158
  if (!target.hasPlugins) return [];
104
159
  return [{ kind: "plugins", pluginsDir: target.pluginsDir, names: [...target.cliPluginNames] }];
105
160
  }
106
161
  function localSkillsEntry(target) {
107
162
  if (target.cliSkills.length === 0) return [];
108
- return [{ kind: "skills", skillsDir: target.skillsDir, skillNames: [...target.cliSkills] }];
163
+ return [
164
+ {
165
+ kind: "skills",
166
+ skillsDir: target.skillsDir,
167
+ skillNames: target.cliSkills.map(({ dirName }) => dirName)
168
+ }
169
+ ];
109
170
  }
110
171
  function compiledAgentsEntry(target) {
111
172
  const agentNames = identifiableAgents(target);
@@ -138,49 +199,6 @@ function planEntry(plan, kind) {
138
199
  (entry) => entry.kind === kind
139
200
  );
140
201
  }
141
- function describeEntry(entry) {
142
- switch (entry.kind) {
143
- case "plugins":
144
- return { label: UNINSTALL_PLAN.PLUGINS_HEADING, items: entry.names };
145
- case "skills":
146
- return {
147
- label: UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,
148
- items: [localSkillsRemoval(entry.skillsDir)]
149
- };
150
- case "agents":
151
- return {
152
- label: UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,
153
- items: [compiledAgentsRemoval(entry.agentsDir)]
154
- };
155
- case "config":
156
- return {
157
- label: UNINSTALL_PLAN.CONFIG_HEADING,
158
- items: entry.fileNames.map((fileName) => `${entry.sourceDir}/${fileName}`)
159
- };
160
- default: {
161
- const _exhaustive = entry;
162
- return _exhaustive;
163
- }
164
- }
165
- }
166
- var PLAN_SECTION_ORDER = [
167
- UNINSTALL_PLAN.PLUGINS_HEADING,
168
- UNINSTALL_PLAN.CLI_MANAGED_FILES_HEADING,
169
- UNINSTALL_PLAN.CONFIG_HEADING
170
- ];
171
- function planSections(entries) {
172
- const described = entries.map(describeEntry);
173
- return PLAN_SECTION_ORDER.flatMap(
174
- (label) => sectionWithItems(label, itemsUnder(described, label))
175
- );
176
- }
177
- function itemsUnder(described, label) {
178
- return described.filter((section) => section.label === label).flatMap((section) => section.items);
179
- }
180
- function sectionWithItems(label, items) {
181
- if (items.length === 0) return [];
182
- return [{ label, items }];
183
- }
184
202
  var UNINSTALL_CONFIRM_MESSAGE = "Are you sure you want to uninstall?";
185
203
  var Uninstall = class _Uninstall extends BaseCommand {
186
204
  /** Replaced in `run` before anything prints. */
@@ -223,7 +241,7 @@ var Uninstall = class _Uninstall extends BaseCommand {
223
241
  this.reportNothingToUninstall();
224
242
  return;
225
243
  }
226
- const approved = await this.removalApproved(plan, flags.yes, namedProvider);
244
+ const approved = await this.removalApproved(plan, target, flags.yes, namedProvider);
227
245
  if (!approved) this.cancelUninstall();
228
246
  await this.executeUninstall(plan, target, projectDir);
229
247
  this.reportSuccess();
@@ -240,9 +258,10 @@ var Uninstall = class _Uninstall extends BaseCommand {
240
258
  this.log("");
241
259
  this.log(INFO_MESSAGES.NO_CHANGES_MADE);
242
260
  }
243
- async removalApproved(plan, skipConfirmation, namedProvider) {
244
- if (!skipConfirmation) return this.confirmRemoval(plan, namedProvider);
245
- this.printRemovalPlan(plan);
261
+ /** With `--yes` nothing is asked, so the plan prints where the question would be. */
262
+ async removalApproved(plan, target, skipConfirmation, namedProvider) {
263
+ if (!skipConfirmation) return this.confirmRemoval(plan, target, namedProvider);
264
+ this.showRemovalPlan(plan, target);
246
265
  return true;
247
266
  }
248
267
  cancelUninstall() {
@@ -250,36 +269,22 @@ var Uninstall = class _Uninstall extends BaseCommand {
250
269
  this.log("Uninstall cancelled");
251
270
  this.exit(EXIT_CODES.CANCELLED);
252
271
  }
253
- printRemovalPlan(plan) {
254
- this.log(UNINSTALL_PLAN.PREVIEW_HEADING);
255
- this.log("");
256
- for (const section of planSections(plan.entries)) {
257
- this.log(` ${section.label}`);
258
- for (const item of section.items) {
259
- this.log(` ${item}`);
260
- }
261
- }
262
- for (const statement of plan.kept) {
263
- this.log("");
264
- this.log(statement);
272
+ showRemovalPlan(plan, target) {
273
+ const lines = summaryPanelBlock(
274
+ removalPanel(plan, target),
275
+ removedFileLines(plan, target.scope),
276
+ plan.kept
277
+ );
278
+ for (const line of lines) {
279
+ this.log(line);
265
280
  }
266
- this.log("");
267
281
  }
268
- async confirmRemoval(plan, namedProvider) {
282
+ async confirmRemoval(plan, target, namedProvider) {
269
283
  if (!process.stdin.isTTY) {
270
284
  this.error(uninstallNeedsTerminal(namedProvider), { exit: EXIT_CODES.ERROR });
271
285
  }
272
- const outcome = await promptConfirm(({ onConfirm, onCancel }) => /* @__PURE__ */ jsx(
273
- RemovalPlanConfirm,
274
- {
275
- heading: UNINSTALL_PLAN.PREVIEW_HEADING,
276
- sections: planSections(plan.entries),
277
- statements: plan.kept,
278
- message: UNINSTALL_CONFIRM_MESSAGE,
279
- onConfirm,
280
- onCancel
281
- }
282
- ));
286
+ this.showRemovalPlan(plan, target);
287
+ const outcome = await promptConfirm(({ onConfirm, onCancel }) => /* @__PURE__ */ jsx(Confirm, { message: UNINSTALL_CONFIRM_MESSAGE, onConfirm, onCancel }));
283
288
  return outcome === "confirmed";
284
289
  }
285
290
  async executeUninstall(plan, target, projectDir) {
@@ -508,6 +513,7 @@ async function detectUninstallTarget(projectDir, handlers) {
508
513
  const activeConfig = config === null ? null : activeConfigOf(config);
509
514
  const cliPluginNames = await pluginsThisRunRemoves(projectDir, activeConfig);
510
515
  return {
516
+ scope: isHomeDirectory(projectDir) ? "global" : "project",
511
517
  hasPlugins: cliPluginNames.length > 0,
512
518
  cliPluginNames,
513
519
  cliSkills,
@@ -539,17 +545,22 @@ function thisRunOwnsAnyPlugin(projectDir) {
539
545
  async function skillsThisCliInstalled(skillsDir, onMetadataUnreadable) {
540
546
  const dirNames = await listDirectories(skillsDir);
541
547
  const skills = await Promise.all(
542
- dirNames.map(async (name) => ({
543
- name,
544
- forkedFrom: await readSkillProvenance(skillsDir, name, onMetadataUnreadable)
548
+ dirNames.map(async (dirName) => ({
549
+ dirName,
550
+ metadata: await readCopyMetadata(skillsDir, dirName, onMetadataUnreadable)
545
551
  }))
546
552
  );
547
- return skills.filter((skill) => skill.forkedFrom !== null).map((skill) => skill.name);
553
+ return skills.flatMap(
554
+ ({ dirName, metadata }) => metadata?.forkedFrom === void 0 ? [] : [{ dirName, skillId: metadata.forkedFrom.skillId, displayName: recordedName(metadata) }]
555
+ );
556
+ }
557
+ function recordedName(metadata) {
558
+ return typeof metadata.displayName === "string" ? metadata.displayName : void 0;
548
559
  }
549
- async function readSkillProvenance(skillsDir, dirName, onUnreadable) {
560
+ async function readCopyMetadata(skillsDir, dirName, onUnreadable) {
550
561
  const skillDir = path.join(skillsDir, dirName);
551
562
  try {
552
- return await readForkedFromMetadata(skillDir);
563
+ return await readLocalSkillMetadata(skillDir);
553
564
  } catch {
554
565
  return onUnreadable(path.join(skillDir, STANDARD_FILES.METADATA_YAML));
555
566
  }