agents-inc 0.174.0 → 0.175.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 (82) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/{chunk-IAQFZFWD.js → chunk-37QFHJUW.js} +142 -13
  3. package/dist/chunk-37QFHJUW.js.map +1 -0
  4. package/dist/{chunk-H5E6IO2L.js → chunk-6HJVH27C.js} +9 -11
  5. package/dist/chunk-6HJVH27C.js.map +1 -0
  6. package/dist/{chunk-7BHDKEGK.js → chunk-DQB3E2SX.js} +3 -3
  7. package/dist/{chunk-APWMMZOK.js → chunk-EGC7PNDI.js} +31 -24
  8. package/dist/chunk-EGC7PNDI.js.map +1 -0
  9. package/dist/{chunk-6PGXTLA4.js → chunk-EHEBN4NB.js} +2 -2
  10. package/dist/{chunk-EFXVYQGT.js → chunk-GNMRXXRY.js} +39 -40
  11. package/dist/chunk-GNMRXXRY.js.map +1 -0
  12. package/dist/{chunk-FQF6VHO3.js → chunk-ICHWAFAC.js} +3 -3
  13. package/dist/{chunk-FQF6VHO3.js.map → chunk-ICHWAFAC.js.map} +1 -1
  14. package/dist/{chunk-3PJZ4QNJ.js → chunk-MFCZARV2.js} +9 -9
  15. package/dist/chunk-MFCZARV2.js.map +1 -0
  16. package/dist/{chunk-TVEDNGVP.js → chunk-P5XEK7HC.js} +2 -2
  17. package/dist/{chunk-REHVGFJE.js → chunk-Q4NWATGH.js} +31 -27
  18. package/dist/chunk-Q4NWATGH.js.map +1 -0
  19. package/dist/{chunk-IXVGBUWI.js → chunk-SI2LLEIR.js} +5 -5
  20. package/dist/{chunk-R7GKQBZJ.js → chunk-SNXEYAFP.js} +44 -30
  21. package/dist/chunk-SNXEYAFP.js.map +1 -0
  22. package/dist/{chunk-QCX66KBM.js → chunk-SRII2GMF.js} +3 -3
  23. package/dist/{chunk-AIBVAYHS.js → chunk-TG3SPPZY.js} +2 -2
  24. package/dist/{chunk-WUSEZFER.js → chunk-U46LYYRA.js} +3 -2
  25. package/dist/{chunk-WUSEZFER.js.map → chunk-U46LYYRA.js.map} +1 -1
  26. package/dist/{chunk-I3WF6L43.js → chunk-XYBHH3M5.js} +2 -2
  27. package/dist/{chunk-ECPFYHDX.js → chunk-YLFKFVQP.js} +11 -11
  28. package/dist/chunk-YLFKFVQP.js.map +1 -0
  29. package/dist/{chunk-E45IT3HC.js → chunk-YM3VEDAP.js} +585 -307
  30. package/dist/chunk-YM3VEDAP.js.map +1 -0
  31. package/dist/commands/build/marketplace.js +4 -4
  32. package/dist/commands/build/plugins.js +6 -6
  33. package/dist/commands/compile.js +16 -16
  34. package/dist/commands/compile.js.map +1 -1
  35. package/dist/commands/doctor.js +73 -78
  36. package/dist/commands/doctor.js.map +1 -1
  37. package/dist/commands/edit.js +45 -38
  38. package/dist/commands/edit.js.map +1 -1
  39. package/dist/commands/eject.js +27 -18
  40. package/dist/commands/eject.js.map +1 -1
  41. package/dist/commands/init.js +16 -17
  42. package/dist/commands/list.js +7 -8
  43. package/dist/commands/list.js.map +1 -1
  44. package/dist/commands/new/marketplace.js +4 -4
  45. package/dist/commands/search.js +9 -9
  46. package/dist/commands/share.js +13 -13
  47. package/dist/commands/share.js.map +1 -1
  48. package/dist/commands/uninstall.js +16 -15
  49. package/dist/commands/uninstall.js.map +1 -1
  50. package/dist/commands/update.js +17 -18
  51. package/dist/commands/update.js.map +1 -1
  52. package/dist/components/common/select-list.js +2 -2
  53. package/dist/components/common/skill-agent-summary.js +3 -3
  54. package/dist/components/common/summary-panel.js +4 -4
  55. package/dist/hooks/init.js +23 -25
  56. package/dist/hooks/init.js.map +1 -1
  57. package/dist/load-agent-defs-BJ4KBKBA.js +14 -0
  58. package/dist/{recompile-project-agents-KYK44C24.js → recompile-project-agents-2QTFMYDC.js} +8 -8
  59. package/dist/{source-loader-G5I4RNUP.js → source-loader-I6SWWDUF.js} +4 -4
  60. package/package.json +1 -1
  61. package/dist/chunk-3PJZ4QNJ.js.map +0 -1
  62. package/dist/chunk-APWMMZOK.js.map +0 -1
  63. package/dist/chunk-E45IT3HC.js.map +0 -1
  64. package/dist/chunk-ECPFYHDX.js.map +0 -1
  65. package/dist/chunk-EFXVYQGT.js.map +0 -1
  66. package/dist/chunk-H5E6IO2L.js.map +0 -1
  67. package/dist/chunk-IAQFZFWD.js.map +0 -1
  68. package/dist/chunk-ORO2T4K2.js +0 -96
  69. package/dist/chunk-ORO2T4K2.js.map +0 -1
  70. package/dist/chunk-R7GKQBZJ.js.map +0 -1
  71. package/dist/chunk-REHVGFJE.js.map +0 -1
  72. package/dist/load-agent-defs-5U5KAURA.js +0 -14
  73. /package/dist/{chunk-7BHDKEGK.js.map → chunk-DQB3E2SX.js.map} +0 -0
  74. /package/dist/{chunk-6PGXTLA4.js.map → chunk-EHEBN4NB.js.map} +0 -0
  75. /package/dist/{chunk-TVEDNGVP.js.map → chunk-P5XEK7HC.js.map} +0 -0
  76. /package/dist/{chunk-IXVGBUWI.js.map → chunk-SI2LLEIR.js.map} +0 -0
  77. /package/dist/{chunk-QCX66KBM.js.map → chunk-SRII2GMF.js.map} +0 -0
  78. /package/dist/{chunk-AIBVAYHS.js.map → chunk-TG3SPPZY.js.map} +0 -0
  79. /package/dist/{chunk-I3WF6L43.js.map → chunk-XYBHH3M5.js.map} +0 -0
  80. /package/dist/{load-agent-defs-5U5KAURA.js.map → load-agent-defs-BJ4KBKBA.js.map} +0 -0
  81. /package/dist/{recompile-project-agents-KYK44C24.js.map → recompile-project-agents-2QTFMYDC.js.map} +0 -0
  82. /package/dist/{source-loader-G5I4RNUP.js.map → source-loader-I6SWWDUF.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,54 @@ Each release has detailed notes in its own file under [`changelogs/`](./changelo
7
7
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
8
8
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
9
9
 
10
+ ## [0.175.0] - 2026-10-27
11
+
12
+ **A project config that declares nothing is no longer an installation, a project under a home holding both tools reads only its own tool's global installation, `init --from` and `edit --from` refuse two more broken links before they ask, and an account refuses a second stack under a name it already holds**
13
+
14
+ - CLI-971: a project `config.ts` that declares nothing is not an installation; `compile`, `edit`, `list`, `share`, `update` and `doctor` say the global installation stands in, and `uninstall` leaves the file alone.
15
+ - CLI-984: a Codex project under a home holding both tools' global installations reads only the Codex one.
16
+ - CLI-934: a skill the marketplace ships and could not load is skipped as one it `could not load`, and a skill folder with no `SKILL.md` is warned on every load.
17
+ - CLI-972: the notices under the `init --from` and `edit --from` panel name each skill as the panel does.
18
+ - CLI-935: `init --from` and `edit --from` refuse a project-only skill on a global sub-agent whether or not the skill loads, writing nothing.
19
+ - CLI-936: they refuse a carried skill id longer than a folder name can be, before the panel, instead of crashing half-way.
20
+ - CLI-987: the confirm panel keeps its `Marketplace` and `Stack` labels whole beside a name too long for the line.
21
+ - CLI-988: a marketplace document's value written across lines stays on its one error line.
22
+ - CLI-933: `eject skills --force` and `eject all --force` restore every skill an earlier eject wrote.
23
+ - CLI-938: `doctor` keeps a download made in the same second as giget's saved copy, and other commands stop warning about a cached copy they just downloaded.
24
+ - CLI-930: a source checkout under a folder whose name starts with `dist` finds its own files.
25
+ - CLI-957: reading a marketplace folder no longer replaces the catalogue the rest of the run names skills from.
26
+ - CLI-939: the docs say a saved marketplace copy with no version stamp is checked only by `doctor`, and how to refresh it.
27
+ - CLI-941: `doctor`'s config check names every state of the config; its verdicts are unchanged.
28
+ - CLI-942: four metadata keys nothing read are gone.
29
+ - CLI-985: the detected installation no longer carries `skillsDir`.
30
+ - CLI-940: the e2e config writer accepts a project config carrying its global inline.
31
+ - CLI-981: the `edit --from` plugin-switch specs pin every plugin-host call, and the old-folder specs share one writer.
32
+ - CLI-983: `init --from`'s specs run behind a stand-in `claude`.
33
+ - CLI-989: no spec reaches the developer's real `claude`.
34
+ - CLI-986: a command spec's first Ink render in a test worker no longer fails its first attempt.
35
+ - CLI-990: `list` and the startup config check are pinned for a Codex project under a home holding both tools.
36
+ - SERVER-10: the worker refuses a stack save or rename under a name the account already holds, in any case, with a 409.
37
+ - SERVER-11: an editor sign-in lasts 90 days, renewed on use.
38
+ - SERVER-07: the worker's CORS check runs once per request.
39
+ - SERVER-09: the server dev spec no longer depends on the developer's `wrangler` cache.
40
+ - SERVER-12: the id-hashing spec finds its own qualifying stack id.
41
+ - EDITOR-111: while the account's stacks cannot be read, Save sends nothing and says `Saving needs your account's stacks first.`, with Retry; a name the account holds is refused in place.
42
+ - EDITOR-112: a failed read of the account's stack list reaches error monitoring.
43
+ - EDITOR-113: a sign-in that ends mid-read is treated as a list that could not be read.
44
+ - EDITOR-98: the Switch marketplace refusal reads as two sentences and offers a token only for 401, 403 or 404.
45
+ - EDITOR-100: the Switch marketplace dialog no longer says "loses nothing" when a waiting link or stack would replace the screen.
46
+ - EDITOR-114: leaving a shared link by loading another marketplace keeps the notice of what could not be placed.
47
+ - EDITOR-99: the accounts specs pass reliably, and the e2e dev server runs without live reload.
48
+ - EDITOR-115: the rail's six sign-in and sign-out refusal lines are pinned word for word.
49
+ - WWW-17: the site's tests fail on a new-tab link without `rel="noopener noreferrer"`.
50
+ - REPO-42: a spec runs the real pre-push hook and fails if it stops running a suite it must.
51
+ - REPO-46: CI's Node setup steps use `actions/setup-node@v7`.
52
+ - REPO-47: how two stack names compare has one definition, in `@workspace/matrix`.
53
+ - REPO-48: a change to a file outside `packages/cli` that a CLI spec reads reruns the CLI's tests.
54
+ - REPO-44: the standards, the journey page and the findings follow the code.
55
+
56
+ See [changelogs/0.175.0.md](./changelogs/0.175.0.md) for full details.
57
+
10
58
  ## [0.174.0] - 2026-10-24
11
59
 
12
60
  **Every summary names a skill by the display name its install recorded, `init --from` and `edit --from` stop when a marketplace refuses the version check, every command says an old `.claude-src/` is ignored, and the editor says when an account's stacks could not be read, with Retry**
@@ -1,12 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ INFO_MESSAGES,
3
4
  STATUS_MESSAGES,
4
5
  addedToGlobalSubAgents,
5
6
  buildMarketplacePluginRef,
7
+ chooseProviderForThisRun,
6
8
  claimSlug,
7
9
  completedWithFailures,
8
10
  copy,
9
11
  defaultUsageGuidance,
12
+ detectInstallations,
10
13
  directoryExists,
11
14
  fetchMarketplace,
12
15
  fileExists,
@@ -16,6 +19,7 @@ import {
16
19
  getErrorMessage,
17
20
  getStackSkillIds,
18
21
  glob,
22
+ holdsAConfigDeclaringNothing,
19
23
  hostAt,
20
24
  installationConfigsUnreadable,
21
25
  isHomeDirectory,
@@ -44,13 +48,13 @@ import {
44
48
  sharedConfigProjectScopeAtHome,
45
49
  skillAssignedToNoAgent,
46
50
  skillMetadataUnusableDetail,
51
+ skippedSkills,
47
52
  skippedUnknownAgents,
48
- skippedUnknownSkills,
49
53
  validateSkillPath,
50
54
  verbose,
51
55
  warn,
52
56
  writeFile
53
- } from "./chunk-E45IT3HC.js";
57
+ } from "./chunk-YM3VEDAP.js";
54
58
  import {
55
59
  BUILT_IN_MATRIX,
56
60
  getCategoryDomain,
@@ -60,22 +64,24 @@ import {
60
64
  typedEntries,
61
65
  typedKeys,
62
66
  typedValues
63
- } from "./chunk-AIBVAYHS.js";
67
+ } from "./chunk-TG3SPPZY.js";
64
68
  import {
65
69
  CLI_COLORS,
66
70
  CLI_INVOKE_COMMAND,
67
71
  DEFAULT_BRANDING,
72
+ EDITOR_URL,
68
73
  EJECT_SOURCE,
69
74
  GITHUB_PREFIX,
70
75
  GITHUB_SOURCE,
71
76
  LOCAL_SKILLS_PATH,
72
77
  MIN_TERMINAL_SIZE,
78
+ PROVIDERS,
73
79
  STANDARD_FILES,
74
80
  externalIdsNamingNoDirectory,
75
81
  isActiveAt,
76
82
  orderDomains,
77
83
  seedExternalSkillSchema
78
- } from "./chunk-WUSEZFER.js";
84
+ } from "./chunk-U46LYYRA.js";
79
85
 
80
86
  // src/cli/utils/terminal.ts
81
87
  function clearTerminalScreen() {
@@ -103,8 +109,90 @@ var EXIT_CODES = {
103
109
  COMPLETED_WITH_FAILURES: 5
104
110
  };
105
111
 
106
- // src/cli/lib/seed/external-skills.ts
112
+ // src/cli/lib/installation/provider-flag.ts
107
113
  import os from "os";
114
+ import { Flags } from "@oclif/core";
115
+ function providerFlag() {
116
+ return Flags.string({
117
+ description: "Which provider's installation this run is about",
118
+ helpValue: `<${PROVIDERS.join("|")}>`,
119
+ options: [...PROVIDERS]
120
+ });
121
+ }
122
+ function providerNamedBy(flagValue) {
123
+ if (flagValue === void 0) return void 0;
124
+ return PROVIDERS.find((provider) => provider === flagValue);
125
+ }
126
+ var PROVIDER_FLAG = "--provider";
127
+ var PROVIDER_FLAG_WITH_ITS_VALUE = `${PROVIDER_FLAG}=`;
128
+ var END_OF_FLAGS = "--";
129
+ function providerNamedIn(argv) {
130
+ const end = argv.indexOf(END_OF_FLAGS);
131
+ const flags = end === -1 ? argv : argv.slice(0, end);
132
+ const spaced = flags.indexOf(PROVIDER_FLAG);
133
+ if (spaced !== -1) return providerNamedBy(flags[spaced + 1]);
134
+ const joined = flags.find((token) => token.startsWith(PROVIDER_FLAG_WITH_ITS_VALUE));
135
+ return providerNamedBy(joined?.slice(PROVIDER_FLAG_WITH_ITS_VALUE.length));
136
+ }
137
+ function providerNeedsAConfigurationToInstall() {
138
+ return `--provider names which installation to create and needs the configuration to create it from, so it is only meaningful beside --from. Build one at ${EDITOR_URL}, then run '${CLI_INVOKE_COMMAND} init --from <id> --provider <provider>'.`;
139
+ }
140
+ function ambiguousInstallation(subject, providers, scopeRoot) {
141
+ return `${scopeRoot} holds ${providers.length} installations \u2014 ${providers.join(" and ")} \u2014 so ${subject} cannot tell which one you mean. Name it with --provider <${providers.join("|")}>. Nothing has been changed.`;
142
+ }
143
+ async function installationsInPlay(cwd) {
144
+ const found = await detectInstallations(cwd);
145
+ const inTheProject = atScope(found, "project");
146
+ if (inTheProject.length > 0) return { scopeRoot: cwd, providers: providersOf(inTheProject) };
147
+ return { scopeRoot: os.homedir(), providers: providersOf(atScope(found, "global")) };
148
+ }
149
+ function atScope(found, scope) {
150
+ return found.filter((installation) => installation.scope === scope);
151
+ }
152
+ function providersOf(installations) {
153
+ return installations.map((installation) => installation.provider);
154
+ }
155
+ async function refuseAnAmbiguousInstallation(cwd, subject, named, onAmbiguous) {
156
+ if (named !== void 0) {
157
+ chooseProviderForThisRun(named);
158
+ return;
159
+ }
160
+ const { scopeRoot, providers } = await installationsInPlay(cwd);
161
+ if (providers.length <= 1) return;
162
+ onAmbiguous(ambiguousInstallation(subject, providers, scopeRoot));
163
+ }
164
+ async function globalInstallationStandsIn(cwd, named) {
165
+ if (!await holdsAConfigDeclaringNothing(cwd)) return false;
166
+ const { scopeRoot, providers } = await installationsInPlay(cwd);
167
+ const theProjectHoldsNone = scopeRoot !== cwd;
168
+ const homeHoldsOneToWorkOn = providers.some(
169
+ (provider) => named === void 0 || provider === named
170
+ );
171
+ return theProjectHoldsNone && homeHoldsOneToWorkOn;
172
+ }
173
+ async function providersInPlay(cwd) {
174
+ return (await installationsInPlay(cwd)).providers;
175
+ }
176
+ async function installationToName(cwd, named) {
177
+ if (named !== void 0) return named;
178
+ const providers = await providersInPlay(cwd);
179
+ return providers.length > 1 ? providers : void 0;
180
+ }
181
+ async function ambiguityFinding(cwd) {
182
+ const { scopeRoot, providers } = await installationsInPlay(cwd);
183
+ if (providers.length <= 1) return null;
184
+ return ambiguousInstallation("every command that acts on one", providers, scopeRoot);
185
+ }
186
+ async function otherInstallationsInThisScope(cwd) {
187
+ const { scopeRoot, providers } = await installationsInPlay(cwd);
188
+ const showing = providerInUse(scopeRoot);
189
+ const others = providers.filter((provider) => provider !== showing);
190
+ if (others.length === 0) return null;
191
+ return `${scopeRoot} holds ${providers.length} installations \u2014 ${providers.join(" and ")} \u2014 and this is the ${showing} one. Show another with --provider <${providers.join("|")}>.`;
192
+ }
193
+
194
+ // src/cli/lib/seed/external-skills.ts
195
+ import os2 from "os";
108
196
  import path from "path";
109
197
  import { mkdtemp } from "fs/promises";
110
198
 
@@ -326,9 +414,25 @@ function notADirectoryNameError(ids) {
326
414
  "A skill id is the directory the skill is written into, so an id holding a path separator, or naming '.' or '..', would be written somewhere other than a directory of its own, and one holding a control character would hand it to the terminal wherever that directory is named. Re-share it with each skill above added again, which mints an id \u2014 'external-<category>-<name>' \u2014 that names one directory."
327
415
  ].join("\n");
328
416
  }
417
+ var DIRECTORY_NAME_MAX_BYTES = 255;
418
+ function overrunsADirectoryName(id) {
419
+ return Buffer.byteLength(id, "utf8") > DIRECTORY_NAME_MAX_BYTES;
420
+ }
421
+ function externalIdsTooLongForADirectory(payload) {
422
+ return Object.keys(payload.external ?? {}).filter(overrunsADirectoryName);
423
+ }
424
+ function tooLongForADirectoryError(ids) {
425
+ return [
426
+ "This configuration cannot be installed: these skills travel inside it under ids longer than a directory name may be:",
427
+ ...ids.map((id) => ` ${JSON.stringify(id)}`),
428
+ `A skill id is the directory the skill is written into, and a directory name may hold at most ${String(DIRECTORY_NAME_MAX_BYTES)} bytes, so none of these could be written. Re-share it without each skill above.`
429
+ ].join("\n");
430
+ }
329
431
  function registerExternalSkills(payload, matrix2, projectDir) {
330
432
  const notDirectoryNames = externalIdsNamingNoDirectory(payload);
331
433
  if (notDirectoryNames.length > 0) throw new Error(notADirectoryNameError(notDirectoryNames));
434
+ const tooLong = externalIdsTooLongForADirectory(payload);
435
+ if (tooLong.length > 0) throw new Error(tooLongForADirectoryError(tooLong));
332
436
  const externals = selectedExternals(payload);
333
437
  const asPlugin = askedForAsPlugin(externals);
334
438
  const colliding = claimingACatalogueId(externals, matrix2);
@@ -344,7 +448,7 @@ async function writeExternalSkills(installs) {
344
448
  var SCRATCH_DIR_PREFIX = "agents-inc-carried-";
345
449
  async function carriedSkillsThatDiffer(installs) {
346
450
  if (installs.length === 0) return [];
347
- const scratch = await mkdtemp(path.join(os.tmpdir(), SCRATCH_DIR_PREFIX));
451
+ const scratch = await mkdtemp(path.join(os2.tmpdir(), SCRATCH_DIR_PREFIX));
348
452
  try {
349
453
  const written = await Promise.all(
350
454
  installs.map(async (install) => writeExternalSkill(await scratchCopyOf(install, scratch)))
@@ -495,8 +599,8 @@ async function readCarriedSkills(owned) {
495
599
  }
496
600
 
497
601
  // src/cli/lib/seed/seed-apply.ts
498
- import os2 from "os";
499
- import { isDeepEqual, omit, partition, pick } from "remeda";
602
+ import os3 from "os";
603
+ import { indexBy, isDeepEqual, omit, partition, pick } from "remeda";
500
604
  var NOTHING_KEPT = {
501
605
  authoredSkillIds: [],
502
606
  unplaceableSkillIds: []
@@ -572,7 +676,7 @@ function withAgentKeptRows(carried, agent, keptRows, payloadRows) {
572
676
  };
573
677
  }
574
678
  async function readInstalledGlobal(projectDir) {
575
- const loaded = await loadProjectConfigFromDir(os2.homedir(), providerInUse(projectDir));
679
+ const loaded = await loadProjectConfigFromDir(os3.homedir(), providerInUse(projectDir));
576
680
  return loaded?.config ?? null;
577
681
  }
578
682
  var NO_GLOBAL_ENTRIES = { skillIds: [], agentNames: [] };
@@ -750,8 +854,13 @@ function entriesActiveAt(skills, agents, scope) {
750
854
  agentNames: agents.filter((agent) => isActiveAt(agent, scope)).map((agent) => agent.name)
751
855
  };
752
856
  }
857
+ function panelRowEntries(held) {
858
+ const active = held.result.skills.filter((skill) => !skill.excluded);
859
+ return indexBy(active, (skill) => skill.id);
860
+ }
753
861
  function joinedStatement(held) {
754
- return held.joined.length === 0 ? [] : [addedToGlobalSubAgents(held.joined)];
862
+ if (held.joined.length === 0) return [];
863
+ return [addedToGlobalSubAgents(held.joined, panelRowEntries(held))];
755
864
  }
756
865
  function projectScopedContent(result) {
757
866
  return entriesActiveAt(result.skills, result.agentConfigs, "project");
@@ -876,6 +985,16 @@ var BaseCommand = class extends Command {
876
985
  await super.init();
877
986
  await this.ensureTerminalSize();
878
987
  }
988
+ /**
989
+ * Called first where a command starts work on the installation in play, which for a project whose
990
+ * config declares nothing is the global one. On stderr, as the init hook's old-folder lines are,
991
+ * so piped output is unchanged.
992
+ */
993
+ async sayWhenTheGlobalInstallationStandsIn(named) {
994
+ if (!await globalInstallationStandsIn(process.cwd(), named)) return;
995
+ process.stderr.write(`${INFO_MESSAGES.GLOBAL_INSTALLATION_STANDS_IN}
996
+ `);
997
+ }
879
998
  async ensureTerminalSize() {
880
999
  if (isTerminalBigEnough()) return;
881
1000
  clearTerminalScreen();
@@ -1018,10 +1137,11 @@ var BaseCommand = class extends Command {
1018
1137
  exit: EXIT_CODES.ERROR
1019
1138
  });
1020
1139
  }
1021
- warnOfSkippedEntries(mapping) {
1140
+ /** `unloadedSkillIds`: skills the marketplace ships and could not load, never unknown ones. */
1141
+ warnOfSkippedEntries(mapping, unloadedSkillIds) {
1022
1142
  const { skippedSkillIds, skippedAgentNames, agentsOnlySkippedSkillsCarried } = mapping;
1023
1143
  if (skippedSkillIds.length > 0) {
1024
- this.warn(skippedUnknownSkills(skippedSkillIds, agentsOnlySkippedSkillsCarried));
1144
+ this.warn(skippedSkills(skippedSkillIds, agentsOnlySkippedSkillsCarried, unloadedSkillIds));
1025
1145
  }
1026
1146
  if (skippedAgentNames.length > 0) this.warn(skippedUnknownAgents(skippedAgentNames));
1027
1147
  }
@@ -1079,6 +1199,14 @@ ${chalk.hex(CLI_COLORS.WARNING)(completedWithFailures(this.incompleteWork))}
1079
1199
  export {
1080
1200
  clearTerminalScreen,
1081
1201
  EXIT_CODES,
1202
+ providerFlag,
1203
+ providerNamedBy,
1204
+ providerNamedIn,
1205
+ providerNeedsAConfigurationToInstall,
1206
+ refuseAnAmbiguousInstallation,
1207
+ installationToName,
1208
+ ambiguityFinding,
1209
+ otherInstallationsInThisScope,
1082
1210
  registerExternalSkills,
1083
1211
  writeExternalSkills,
1084
1212
  carriedSkillsThatDiffer,
@@ -1089,8 +1217,9 @@ export {
1089
1217
  restoreInstalledGlobal,
1090
1218
  sameAssignments,
1091
1219
  notInstalledGlobally,
1220
+ panelRowEntries,
1092
1221
  joinedStatement,
1093
1222
  installsAtHome,
1094
1223
  BaseCommand
1095
1224
  };
1096
- //# sourceMappingURL=chunk-IAQFZFWD.js.map
1225
+ //# sourceMappingURL=chunk-37QFHJUW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/utils/terminal.ts","../src/cli/lib/exit-codes.ts","../src/cli/lib/installation/provider-flag.ts","../src/cli/lib/seed/external-skills.ts","../../compile/src/carried-skill.ts","../src/cli/lib/seed/seed-apply.ts","../src/cli/base-command.ts","../src/cli/lib/operations/source/ensure-marketplace.ts","../src/cli/lib/operations/source/require-marketplace.ts","../src/cli/lib/operations/skills/install-plugin-skills.ts"],"sourcesContent":["import { MIN_TERMINAL_SIZE } from \"../consts.js\";\n\n/** Clears screen and scrollback. */\nexport function clearTerminalScreen(): void {\n process.stdout.write(\"\\x1b[H\\x1b[2J\\x1b[3J\");\n}\n\nexport function isTerminalLargeEnough(columns: number, rows: number): boolean {\n return columns >= MIN_TERMINAL_SIZE.COLS && rows >= MIN_TERMINAL_SIZE.ROWS;\n}\n\n/**\n * E2E `STEP_TEXT.TOO_NARROW` / `TOO_SHORT` key off this text. Precondition: the terminal is too\n * small; width is reported first, so not-too-narrow means too-short.\n */\nexport function formatTerminalTooSmallMessage(columns: number): string {\n const issue =\n columns < MIN_TERMINAL_SIZE.COLS\n ? `too narrow (need ${MIN_TERMINAL_SIZE.COLS})`\n : `too short (need ${MIN_TERMINAL_SIZE.ROWS})`;\n return `Terminal ${issue}. Please resize.`;\n}\n","export const EXIT_CODES = {\n SUCCESS: 0,\n ERROR: 1,\n INVALID_ARGS: 2,\n NETWORK_ERROR: 3,\n CANCELLED: 4,\n /**\n * Ran to the end but part of the work failed. Unlike ERROR the work landed, so repeating the run\n * is wrong; the output names the remedy. Raised at the end of a command, never mid-flight.\n */\n COMPLETED_WITH_FAILURES: 5,\n} as const;\n","/**\n * `--provider`: names the installation where the folder cannot — a greenfield `init --from`, or a\n * scope holding both providers, where acting commands refuse until it is given.\n */\n\nimport os from \"os\";\n\nimport { Flags } from \"@oclif/core\";\n\nimport { PROVIDERS, EDITOR_URL, CLI_INVOKE_COMMAND, type Provider } from \"../../consts.js\";\nimport {\n detectInstallations,\n holdsAConfigDeclaringNothing,\n type DetectedInstallation,\n} from \"./detect-installations.js\";\nimport { chooseProviderForThisRun, providerInUse } from \"./install-layout.js\";\n\n/** A factory because oclif mutates flag definitions, so commands must not share one. */\nexport function providerFlag() {\n return Flags.string({\n description: \"Which provider's installation this run is about\",\n helpValue: `<${PROVIDERS.join(\"|\")}>`,\n options: [...PROVIDERS],\n });\n}\n\n/** oclif has already rejected unlisted values; this only narrows. */\nexport function providerNamedBy(flagValue: string | undefined): Provider | undefined {\n if (flagValue === undefined) return undefined;\n return PROVIDERS.find((provider) => provider === flagValue);\n}\n\nconst PROVIDER_FLAG = \"--provider\";\nconst PROVIDER_FLAG_WITH_ITS_VALUE = `${PROVIDER_FLAG}=`;\nconst END_OF_FLAGS = \"--\";\n\n/**\n * For a run oclif has not parsed yet: `--provider <name>` or `--provider=<name>`, ahead of any\n * `--`; a value naming no provider names none.\n */\nexport function providerNamedIn(argv: readonly string[]): Provider | undefined {\n const end = argv.indexOf(END_OF_FLAGS);\n const flags = end === -1 ? argv : argv.slice(0, end);\n\n const spaced = flags.indexOf(PROVIDER_FLAG);\n if (spaced !== -1) return providerNamedBy(flags[spaced + 1]);\n\n const joined = flags.find((token) => token.startsWith(PROVIDER_FLAG_WITH_ITS_VALUE));\n return providerNamedBy(joined?.slice(PROVIDER_FLAG_WITH_ITS_VALUE.length));\n}\n\nexport function providerNeedsAConfigurationToInstall(): string {\n return (\n `--provider names which installation to create and needs the configuration to create it ` +\n `from, so it is only meaningful beside --from. Build one at ${EDITOR_URL}, then run ` +\n `'${CLI_INVOKE_COMMAND} init --from <id> --provider <provider>'.`\n );\n}\n\nfunction ambiguousInstallation(\n subject: string,\n providers: readonly Provider[],\n scopeRoot: string,\n): string {\n return (\n `${scopeRoot} holds ${providers.length} installations — ${providers.join(\" and \")} — so ` +\n `${subject} cannot tell which one you mean. Name it with --provider <${providers.join(\"|\")}>. ` +\n `Nothing has been changed.`\n );\n}\n\ntype InstallationsInPlay = {\n scopeRoot: string;\n providers: Provider[];\n};\n\n/** The project's installations, or the global ones only when the project has none. */\nasync function installationsInPlay(cwd: string): Promise<InstallationsInPlay> {\n const found = await detectInstallations(cwd);\n const inTheProject = atScope(found, \"project\");\n\n if (inTheProject.length > 0) return { scopeRoot: cwd, providers: providersOf(inTheProject) };\n return { scopeRoot: os.homedir(), providers: providersOf(atScope(found, \"global\")) };\n}\n\nfunction atScope(\n found: readonly DetectedInstallation[],\n scope: DetectedInstallation[\"scope\"],\n): DetectedInstallation[] {\n return found.filter((installation) => installation.scope === scope);\n}\n\nfunction providersOf(installations: readonly DetectedInstallation[]): Provider[] {\n return installations.map((installation) => installation.provider);\n}\n\n/**\n * A named provider is committed for the run; two installations and no flag call `onAmbiguous`\n * (the command's `this.error`); otherwise nothing happens.\n */\nexport async function refuseAnAmbiguousInstallation(\n cwd: string,\n subject: string,\n named: Provider | undefined,\n onAmbiguous: (message: string) => never,\n): Promise<void> {\n if (named !== undefined) {\n chooseProviderForThisRun(named);\n return;\n }\n\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n if (providers.length <= 1) return;\n\n onAmbiguous(ambiguousInstallation(subject, providers, scopeRoot));\n}\n\n/**\n * Whether a run here works on a global installation because the project's own config declares\n * nothing, which such a run says first. Not where HOME holds none the run could work on.\n */\nexport async function globalInstallationStandsIn(\n cwd: string,\n named: Provider | undefined,\n): Promise<boolean> {\n if (!(await holdsAConfigDeclaringNothing(cwd))) return false;\n\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n const theProjectHoldsNone = scopeRoot !== cwd;\n const homeHoldsOneToWorkOn = providers.some(\n (provider) => named === undefined || provider === named,\n );\n return theProjectHoldsNone && homeHoldsOneToWorkOn;\n}\n\n/** The non-refusing read the remedies hand a command out from, so they and the refusal agree. */\nexport async function providersInPlay(cwd: string): Promise<Provider[]> {\n return (await installationsInPlay(cwd)).providers;\n}\n\n/**\n * Which installation a handed-out acting command must name: the one the run named, else the choice\n * where two are in play, since a bare one refuses there.\n */\nexport async function installationToName(\n cwd: string,\n named: Provider | undefined,\n): Promise<Provider | Provider[] | undefined> {\n if (named !== undefined) return named;\n\n const providers = await providersInPlay(cwd);\n return providers.length > 1 ? providers : undefined;\n}\n\n/** The non-refusing form, for `doctor`. */\nexport async function ambiguityFinding(cwd: string): Promise<string | null> {\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n if (providers.length <= 1) return null;\n\n return ambiguousInstallation(\"every command that acts on one\", providers, scopeRoot);\n}\n\n/**\n * For `list`: names the other installation in the scope, or `null` when there is none. The one\n * shown is read off the scope the roster came from, as `detectInstallation` reads it.\n */\nexport async function otherInstallationsInThisScope(cwd: string): Promise<string | null> {\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n const showing = providerInUse(scopeRoot);\n const others = providers.filter((provider) => provider !== showing);\n if (others.length === 0) return null;\n\n return (\n `${scopeRoot} holds ${providers.length} installations — ${providers.join(\" and \")} — and this ` +\n `is the ${showing} one. Show another with --provider <${providers.join(\"|\")}>.`\n );\n}\n","import os from \"os\";\nimport path from \"path\";\nimport { mkdtemp } from \"fs/promises\";\n\nimport { externalIdsNamingNoDirectory, seedExternalSkillSchema } from \"@workspace/matrix/seed\";\nimport { carriedSkillAuthor, installedSkillTree } from \"@workspace/compile/carried-skill\";\n\nimport { GITHUB_SOURCE, LOCAL_SKILLS_PATH, STANDARD_FILES } from \"../../consts.js\";\nimport { resolveInstallPaths } from \"../installation/install-base-dir.js\";\nimport { parseFrontmatter, readSkillMetadata } from \"../loading/loader.js\";\nimport { getCategoryDomain } from \"../matrix/matrix-provider.js\";\nimport { claimSlug } from \"../matrix/skill-resolution.js\";\nimport { validateSkillPath } from \"../skills/skill-copier.js\";\nimport { readForkedFromMetadata } from \"../skills/skill-metadata.js\";\nimport { defaultUsageGuidance } from \"../stacks/stacks-loader.js\";\nimport { BUILT_IN_MATRIX } from \"../../types/generated/matrix.js\";\nimport { getCurrentDate } from \"../versioning.js\";\nimport {\n copy,\n directoryExists,\n fileExists,\n glob,\n readFile,\n remove,\n writeFile,\n} from \"../../utils/fs.js\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object.js\";\n\nimport type { SkillScope } from \"../../types/config.js\";\nimport type { Domain, MergedSkillsMatrix, ResolvedSkill } from \"../../types/matrix.js\";\nimport type { CategoryPath, SkillId, SkillSlug } from \"../../types/skills.js\";\nimport type { ForkedFromMetadata } from \"../skills/skill-metadata.js\";\nimport type {\n SeedExternalSkill,\n SeedPayload,\n SeedSkill,\n SeedSkillTree,\n} from \"@workspace/matrix/seed\";\n\n/** One skill the payload carries rather than names, seated and ready to be written. */\nexport type ExternalSkillInstall = {\n id: SkillId;\n scope: SkillScope;\n skill: SeedExternalSkill;\n domain: Domain;\n skillDir: string;\n};\n\ntype SelectedExternal = { id: SkillId; skill: SeedExternalSkill; entry: SeedSkill };\n\n/** No marketplace serves a carried skill, and coercing it to eject would defy the payload. */\nfunction pluginInstallError(ids: SkillId[]): string {\n return [\n \"This configuration cannot be installed: these skills travel inside it, so no marketplace \" +\n \"serves them and they cannot be installed as plugins:\",\n ...ids.map((id) => ` ${id}`),\n \"Re-share it with each skill above set to eject, which is the only way a carried skill installs.\",\n ].join(\"\\n\");\n}\n\n/** Presence in `skills` is selection; `external` content nobody picked installs nothing. */\nfunction selectedExternals(payload: SeedPayload): SelectedExternal[] {\n return typedEntries<SkillId, SeedExternalSkill>(payload.external ?? {}).flatMap(([id, skill]) => {\n const entry = payload.skills[id];\n return entry ? [{ id, skill, entry }] : [];\n });\n}\n\nfunction askedForAsPlugin(externals: SelectedExternal[]): SkillId[] {\n return externals.filter(({ entry }) => entry.install !== \"eject\").map(({ id }) => id);\n}\n\n/**\n * A carried skill on a catalogue id would overwrite that catalogue's copy. Checks the loaded matrix\n * and the shipped catalogue, since the payload chooses which marketplace gets loaded.\n */\nfunction claimingACatalogueId(\n externals: SelectedExternal[],\n matrix: MergedSkillsMatrix,\n): SkillId[] {\n return externals.filter(({ id }) => heldByEitherCatalogue(id, matrix)).map(({ id }) => id);\n}\n\nconst CATALOGUE_SKILL_IDS: ReadonlySet<SkillId> = new Set(typedKeys(BUILT_IN_MATRIX.skills));\n\nfunction heldByEitherCatalogue(id: SkillId, matrix: MergedSkillsMatrix): boolean {\n return heldByLoadedCatalogue(matrix.skills[id]) || CATALOGUE_SKILL_IDS.has(id);\n}\n\n/**\n * A `local` incumbent is exempt so a re-apply works; whether its directory may be overwritten is\n * settled on disk by {@link refuseUncarriedDestinations}.\n */\nfunction heldByLoadedCatalogue(incumbent: ResolvedSkill | undefined): boolean {\n return incumbent !== undefined && incumbent.local !== true;\n}\n\nfunction catalogueIdCollisionError(ids: SkillId[]): string {\n return [\n \"This configuration cannot be installed: these skills travel inside it under ids a \" +\n \"catalogue already owns:\",\n ...ids.map((id) => ` ${id}`),\n \"A skill id is the directory the skill installs into, so each would be written over the \" +\n \"catalogue's own copy of that skill. Re-share it with each skill above added again, which \" +\n \"mints an id — 'external-<category>-<name>' — that no catalogue owns.\",\n ].join(\"\\n\");\n}\n\n/** Boundary cast: a carried skill's id is in no generated union, and is its own slug. */\nfunction externalSlug(id: SkillId): SkillSlug {\n return id as SkillSlug;\n}\n\nfunction externalSkillDir(id: SkillId, scope: SkillScope, projectDir: string): string {\n return path.join(resolveInstallPaths(projectDir, scope).skillsDir, id);\n}\n\nfunction externalCatalogueEntry(install: ExternalSkillInstall): ResolvedSkill {\n return {\n id: install.id,\n slug: externalSlug(install.id),\n displayName: install.skill.displayName,\n description: install.skill.description,\n // Boundary cast: seatExternalSkill has confirmed this catalogue declares the category.\n category: install.skill.categoryId as CategoryPath,\n author: carriedSkillAuthor(install.skill.repo),\n path: `${LOCAL_SKILLS_PATH}/${install.id}/`,\n conflictsWith: [],\n requires: [],\n alternatives: [],\n discourages: [],\n local: true,\n custom: true,\n localPath: install.skillDir,\n };\n}\n\n/** An unknown category leaves the skill unseated, so the decode skips and reports it. */\nfunction seatExternalSkill(\n { id, skill, entry }: SelectedExternal,\n matrix: MergedSkillsMatrix,\n projectDir: string,\n): ExternalSkillInstall[] {\n const domain = getCategoryDomain(skill.categoryId);\n if (domain === undefined) return [];\n\n const install: ExternalSkillInstall = {\n id,\n skill,\n domain,\n scope: entry.scope,\n skillDir: externalSkillDir(id, entry.scope, projectDir),\n };\n\n matrix.skills[id] = externalCatalogueEntry(install);\n claimSlug(matrix.slugMap, externalSlug(id), id);\n\n return [install];\n}\n\n/** Quoted, so an empty id prints as something and an escape is spelled out rather than sent. */\nfunction notADirectoryNameError(ids: string[]): string {\n return [\n \"This configuration cannot be installed: these skills travel inside it under ids that are \" +\n \"not a single directory name:\",\n ...ids.map((id) => ` ${JSON.stringify(id)}`),\n \"A skill id is the directory the skill is written into, so an id holding a path separator, \" +\n \"or naming '.' or '..', would be written somewhere other than a directory of its own, \" +\n \"and one holding a control character would hand it to the terminal wherever that \" +\n \"directory is named. Re-share it with each skill above added again, which mints an id — \" +\n \"'external-<category>-<name>' — that names one directory.\",\n ].join(\"\\n\");\n}\n\n/** ext4's `NAME_MAX`, in UTF-8 bytes; a name within it fits Windows' 255 UTF-16 units too. */\nconst DIRECTORY_NAME_MAX_BYTES = 255;\n\nfunction overrunsADirectoryName(id: string): boolean {\n return Buffer.byteLength(id, \"utf8\") > DIRECTORY_NAME_MAX_BYTES;\n}\n\nfunction externalIdsTooLongForADirectory(payload: SeedPayload): string[] {\n return Object.keys(payload.external ?? {}).filter(overrunsADirectoryName);\n}\n\nfunction tooLongForADirectoryError(ids: string[]): string {\n return [\n \"This configuration cannot be installed: these skills travel inside it under ids longer \" +\n \"than a directory name may be:\",\n ...ids.map((id) => ` ${JSON.stringify(id)}`),\n \"A skill id is the directory the skill is written into, and a directory name may hold at \" +\n `most ${String(DIRECTORY_NAME_MAX_BYTES)} bytes, so none of these could be written. ` +\n \"Re-share it without each skill above.\",\n ].join(\"\\n\");\n}\n\n/**\n * Writes carried skills into `matrix` in place so the decode can resolve them. Every refusal runs\n * before anything is seated, so a refused run leaves the matrix untouched. The id is checked first:\n * every path a carried skill is written to, scratch copies included, is joined from it.\n */\nexport function registerExternalSkills(\n payload: SeedPayload,\n matrix: MergedSkillsMatrix,\n projectDir: string,\n): ExternalSkillInstall[] {\n const notDirectoryNames = externalIdsNamingNoDirectory(payload);\n if (notDirectoryNames.length > 0) throw new Error(notADirectoryNameError(notDirectoryNames));\n\n const tooLong = externalIdsTooLongForADirectory(payload);\n if (tooLong.length > 0) throw new Error(tooLongForADirectoryError(tooLong));\n\n const externals = selectedExternals(payload);\n const asPlugin = askedForAsPlugin(externals);\n const colliding = claimingACatalogueId(externals, matrix);\n\n if (asPlugin.length > 0) throw new Error(pluginInstallError(asPlugin));\n if (colliding.length > 0) throw new Error(catalogueIdCollisionError(colliding));\n\n return externals.flatMap((external) => seatExternalSkill(external, matrix, projectDir));\n}\n\n/**\n * Answers the ids whose directories changed. Refuses destinations again, since a directory may have\n * appeared while the user read the prompt.\n */\nexport async function writeExternalSkills(installs: ExternalSkillInstall[]): Promise<SkillId[]> {\n await refuseUncarriedDestinations(installs);\n\n const written = await Promise.all(installs.map(writeExternalSkill));\n return changedIds(written);\n}\n\nconst SCRATCH_DIR_PREFIX = \"agents-inc-carried-\";\n\n/** What {@link writeExternalSkills} would change, by running the write against scratch copies. */\nexport async function carriedSkillsThatDiffer(\n installs: ExternalSkillInstall[],\n): Promise<SkillId[]> {\n if (installs.length === 0) return [];\n\n const scratch = await mkdtemp(path.join(os.tmpdir(), SCRATCH_DIR_PREFIX));\n try {\n const written = await Promise.all(\n installs.map(async (install) => writeExternalSkill(await scratchCopyOf(install, scratch))),\n );\n return changedIds(written);\n } finally {\n await remove(scratch);\n }\n}\n\nasync function scratchCopyOf(\n install: ExternalSkillInstall,\n scratch: string,\n): Promise<ExternalSkillInstall> {\n const skillDir = path.join(scratch, install.id);\n if (await directoryExists(install.skillDir)) await copy(install.skillDir, skillDir);\n return { ...install, skillDir };\n}\n\ntype WrittenSkill = { id: SkillId; changed: boolean };\n\nfunction changedIds(written: WrittenSkill[]): SkillId[] {\n return written.filter(({ changed }) => changed).map(({ id }) => id);\n}\n\n/** Writes only the files whose bytes differ, so an unchanged skill keeps its mtimes. */\nasync function writeExternalSkill(install: ExternalSkillInstall): Promise<WrittenSkill> {\n const files = typedEntries<string, string>(await treeToWrite(install));\n refuseEscapingPaths(install.skillDir, files);\n\n const written = await Promise.all(\n files.map(([relativePath, contents]) =>\n writeIfChanged(path.join(install.skillDir, relativePath), contents),\n ),\n );\n return { id: install.id, changed: written.some(Boolean) };\n}\n\n/** The keys came off the wire, so every path is refused before any file is written. */\nfunction refuseEscapingPaths(skillDir: string, files: [string, string][]): void {\n for (const [relativePath] of files) {\n validateSkillPath(path.join(skillDir, relativePath), skillDir, relativePath);\n }\n}\n\n/** The bytes the editor previews, dated today unless nothing in them would change. */\nasync function treeToWrite(install: ExternalSkillInstall): Promise<SeedSkillTree> {\n const shipped = await withShippedMetadata(install);\n const unchanged = await treeAsInstalled(install, shipped);\n return unchanged ?? carriedTree(install, shipped, getCurrentDate());\n}\n\n/**\n * The tree dated as the stamp on disk is, where that makes its metadata the bytes already there:\n * a fresh date would otherwise make an unchanged skill look rewritten.\n */\nasync function treeAsInstalled(\n install: ExternalSkillInstall,\n shipped: SeedExternalSkill,\n): Promise<SeedSkillTree | null> {\n const recorded = (await readForkedFromMetadata(install.skillDir))?.date;\n if (recorded === undefined) return null;\n\n const tree = await carriedTree(install, shipped, recorded);\n const onDisk = await bytesOnDisk(path.join(install.skillDir, STANDARD_FILES.METADATA_YAML));\n return tree[STANDARD_FILES.METADATA_YAML] === onDisk ? tree : null;\n}\n\nfunction carriedTree(\n install: ExternalSkillInstall,\n skill: SeedExternalSkill,\n date: string,\n): Promise<SeedSkillTree> {\n return installedSkillTree({\n id: install.id,\n skill,\n domain: install.domain,\n usageGuidance: defaultUsageGuidance(install.skill.categoryId),\n date,\n });\n}\n\n/** Where the payload carries no metadata, the copy on disk stands for what was shipped. */\nasync function withShippedMetadata(install: ExternalSkillInstall): Promise<SeedExternalSkill> {\n if (Object.hasOwn(install.skill.files, STANDARD_FILES.METADATA_YAML)) return install.skill;\n\n const onDisk = await bytesOnDisk(path.join(install.skillDir, STANDARD_FILES.METADATA_YAML));\n if (onDisk === null) return install.skill;\n\n return {\n ...install.skill,\n files: { ...install.skill.files, [STANDARD_FILES.METADATA_YAML]: onDisk },\n };\n}\n\nasync function bytesOnDisk(filePath: string): Promise<string | null> {\n return (await fileExists(filePath)) ? readFile(filePath) : null;\n}\n\nasync function writeIfChanged(filePath: string, contents: string): Promise<boolean> {\n if ((await bytesOnDisk(filePath)) === contents) return false;\n await writeFile(filePath, contents);\n return true;\n}\n\ntype BlockedDestination = { id: SkillId; skillDir: string };\n\n/**\n * Refuses when a destination holds content no shared configuration carried. Only a carried skill's\n * install writes `forkedFrom.path`, so its presence marks a carried directory.\n */\nexport async function refuseUncarriedDestinations(installs: ExternalSkillInstall[]): Promise<void> {\n const judged = await Promise.all(installs.map(judgeDestination));\n const blocked = judged.filter((destination) => destination !== null);\n\n if (blocked.length > 0) throw new Error(uncarriedDestinationError(blocked));\n}\n\nasync function judgeDestination(install: ExternalSkillInstall): Promise<BlockedDestination | null> {\n const { id, skillDir } = install;\n if (!(await directoryExists(skillDir))) return null;\n if ((await readForkedFromMetadata(skillDir))?.path !== undefined) return null;\n return { id, skillDir };\n}\n\nfunction uncarriedDestinationError(blocked: BlockedDestination[]): string {\n return [\n \"This configuration cannot be installed: these skills travel inside it under ids this \" +\n \"installation already keeps a skill directory for, and no shared configuration put those \" +\n \"directories there:\",\n ...blocked.map(({ id, skillDir }) => ` ${id} -> ${skillDir}`),\n \"A skill id is the directory the skill installs into, so each would be written over a skill \" +\n \"written here by hand or ejected from a marketplace. Move or rename the directory above, \" +\n \"or re-share the configuration with each skill added again, which mints an id — \" +\n \"'external-<category>-<name>' — that nothing here holds.\",\n ].join(\"\\n\");\n}\n\nexport type OwnedSkillDir = { id: string; skillDir: string; provenance: ForkedFromMetadata };\n\nexport type ContentReading = {\n external: Record<string, SeedExternalSkill>;\n uncarryable: string[];\n};\n\ntype CarriedRead =\n | { carries: \"content\"; id: string; skill: SeedExternalSkill }\n | { carries: \"nothing\" }\n | { carries: \"unshareable\"; line: string };\n\nfunction unnameableRepoMessage(id: string): string {\n return `${id} travels inside a shared configuration, and this installation does not record the repository its content came from`;\n}\n\nfunction uncarryableContentMessage(id: string, reason: string): string {\n return `${id} travels inside a shared configuration, and ${reason}`;\n}\n\n/** The inverse of the stamp's `github:` source; any other ref answers nothing, to be refused. */\nfunction repoFromRef(ref: string | undefined): string | undefined {\n if (ref === undefined || !ref.startsWith(GITHUB_SOURCE.GITHUB_PREFIX)) return undefined;\n return ref.slice(GITHUB_SOURCE.GITHUB_PREFIX.length);\n}\n\nconst NO_MANIFEST_DESCRIPTION = `no description can be read from its ${STANDARD_FILES.SKILL_MD}`;\n\nfunction manifestDescription(files: SeedSkillTree, skillDir: string): string | null {\n const manifest = files[STANDARD_FILES.SKILL_MD];\n if (manifest === undefined) return null;\n\n const frontmatter = parseFrontmatter(manifest, path.join(skillDir, STANDARD_FILES.SKILL_MD));\n return frontmatter === null ? null : frontmatter.description;\n}\n\nasync function readSkillTree(skillDir: string): Promise<SeedSkillTree> {\n const files = await glob(\"**/*\", skillDir, { dot: true });\n const entries = await Promise.all(\n files.map(async (file) => [file, await readFile(path.join(skillDir, file))] as const),\n );\n return Object.fromEntries(entries);\n}\n\n/**\n * Rebuilds the carried entry from the bytes as installed. The description is the manifest's, not\n * the truncated `cliDescription`, which would shorten the skill on every round trip.\n */\nasync function readCarriedSkill({ id, skillDir, provenance }: OwnedSkillDir): Promise<CarriedRead> {\n // No path means a catalogue serves this id, so the bytes need not travel.\n if (provenance.path === undefined) return { carries: \"nothing\" };\n\n const repo = repoFromRef(provenance.source);\n if (repo === undefined) return { carries: \"unshareable\", line: unnameableRepoMessage(id) };\n\n const described = await readSkillMetadata(path.join(skillDir, STANDARD_FILES.METADATA_YAML));\n if (!described.usable) {\n return { carries: \"unshareable\", line: uncarryableContentMessage(id, described.reason) };\n }\n\n const files = await readSkillTree(skillDir);\n const description = manifestDescription(files, skillDir);\n if (description === null) {\n return { carries: \"unshareable\", line: uncarryableContentMessage(id, NO_MANIFEST_DESCRIPTION) };\n }\n\n const parsed = seedExternalSkillSchema.safeParse({\n displayName: described.metadata.displayName,\n description,\n categoryId: described.metadata.category,\n repo,\n path: provenance.path,\n files,\n });\n if (!parsed.success) {\n const reason = parsed.error.issues.map((issue) => issue.message).join(\"; \");\n return { carries: \"unshareable\", line: uncarryableContentMessage(id, reason) };\n }\n\n return { carries: \"content\", id, skill: parsed.data };\n}\n\n/** The mirror of {@link registerExternalSkills}: reads installed bytes back into entries. */\nexport async function readCarriedSkills(owned: OwnedSkillDir[]): Promise<ContentReading> {\n const reads = await Promise.all(owned.map(readCarriedSkill));\n\n return {\n external: Object.fromEntries(\n reads.flatMap((read) => (read.carries === \"content\" ? [[read.id, read.skill]] : [])),\n ),\n uncarryable: reads.flatMap((read) => (read.carries === \"unshareable\" ? [read.line] : [])),\n };\n}\n","import { parse as parseYaml, stringify as stringifyYaml } from \"yaml\"\n\nimport { GITHUB_PREFIX, STANDARD_FILES } from \"./paths.js\"\n\nimport type { SeedExternalSkill, SeedSkillTree } from \"@workspace/matrix\"\n\n// What an install does to a skill the configuration carries (its whole directory travels in the\n// payload). The CLI writes {@link installedSkillTree}'s bytes; the editor preview draws them.\n\nconst FRONTMATTER_BLOCK = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/\nconst NAME_FIELD = /^name:.*$/m\n\nexport type InstalledSkillIdentity = { id: string; description: string }\n\n/**\n * Names the skill by the id it installs under, which compiled sub-agents reference; the rest of\n * the frontmatter is the author's and travels untouched.\n */\nexport function withInstalledName(\n manifest: string,\n { id, description }: InstalledSkillIdentity\n): string {\n const named = `name: ${id}`\n const block = FRONTMATTER_BLOCK.exec(manifest)\n\n // No frontmatter describes no skill, so one is given from the payload.\n if (!block) {\n return `---\\n${named}\\ndescription: ${description}\\n---\\n\\n${manifest}`\n }\n\n const [whole, fields = \"\"] = block\n const renamed = NAME_FIELD.test(fields)\n ? fields.replace(NAME_FIELD, named)\n : `${named}\\n${fields}`\n\n return `---\\n${renamed}\\n---${manifest.slice(whole.length)}`\n}\n\nexport function carriedSkillAuthor(repo: string): string {\n const [owner = repo] = repo.split(\"/\")\n return `@${owner}`\n}\n\nexport type CarriedSkillPlacement = {\n id: string\n skill: Pick<\n SeedExternalSkill,\n \"displayName\" | \"description\" | \"categoryId\" | \"repo\"\n >\n domain: string\n /** The CLI's `defaultUsageGuidance`, passed in so it is spelled once. */\n usageGuidance: string\n shipped: Readonly<Record<string, unknown>> | null\n}\n\n/**\n * The payload's taxonomy wins over what the repository shipped, which wins over defaults. The\n * defaults keep `doctor` from flagging a file the user cannot fix.\n */\nexport function carriedSkillMetadata({\n id,\n skill,\n domain,\n usageGuidance,\n shipped,\n}: CarriedSkillPlacement): Record<string, unknown> {\n return {\n author: carriedSkillAuthor(skill.repo),\n usageGuidance,\n ...shipped,\n displayName: skill.displayName,\n slug: id,\n category: skill.categoryId,\n domain,\n cliDescription: shortLabel(skill.description),\n custom: true,\n }\n}\n\n// `CLI_DESCRIPTION_MAX_LENGTH` in the CLI's `schemas.ts`.\nconst CLI_DESCRIPTION_MAX_LENGTH = 60\n\nconst ELLIPSIS = \"…\"\n\n/** Cut at the last whole word that fits `doctor`'s limit; sub-agents read the full SKILL.md. */\nfunction shortLabel(description: string): string {\n if (description.length <= CLI_DESCRIPTION_MAX_LENGTH) return description\n\n const roomLength = CLI_DESCRIPTION_MAX_LENGTH - ELLIPSIS.length\n const room = description.slice(0, roomLength)\n // A break right after the room means its last word is whole and fits.\n const endsOnAWord = description[roomLength] === \" \"\n\n return `${endsOnAWord ? room.trimEnd() : toLastWholeWord(room)}${ELLIPSIS}`\n}\n\nfunction toLastWholeWord(text: string): string {\n const lastBreak = text.lastIndexOf(\" \")\n return (lastBreak > 0 ? text.slice(0, lastBreak) : text).trimEnd()\n}\n\nexport type CarriedSkillInstall = Omit<\n CarriedSkillPlacement,\n \"shipped\" | \"skill\"\n> & {\n skill: SeedExternalSkill\n date: string\n}\n\nexport async function installedSkillTree(\n install: CarriedSkillInstall\n): Promise<SeedSkillTree> {\n const manifest = withInstalledName(manifestOf(install.skill.files), {\n id: install.id,\n description: install.skill.description,\n })\n\n return {\n ...install.skill.files,\n [STANDARD_FILES.SKILL_MD]: manifest,\n [STANDARD_FILES.METADATA_YAML]: await metadataYaml(install, manifest),\n }\n}\n\n// `yamlSchemaComment(SCHEMA_PATHS.metadata)` in the CLI's `consts.ts`.\nconst METADATA_SCHEMA_COMMENT =\n \"# yaml-language-server: $schema=https://raw.githubusercontent.com/agents-inc/agents-inc/main/packages/cli/src/schemas/metadata.schema.json\"\n\n// `YAML_FORMATTING.LINE_WIDTH_NONE`.\nconst NO_LINE_FOLDING = 0\n\n/** The shared metadata, then the `forkedFrom` stamp. */\nasync function metadataYaml(\n install: CarriedSkillInstall,\n manifest: string\n): Promise<string> {\n const metadata = carriedSkillMetadata({\n ...install,\n shipped: shippedMetadata(install.skill.files),\n })\n const stamp = await provenanceStamp(install, manifest)\n\n return asMetadataFile(withForkedFrom(metadata, stamp))\n}\n\nasync function provenanceStamp(\n install: CarriedSkillInstall,\n manifest: string\n): Promise<Record<string, string>> {\n return {\n skillId: install.id,\n contentHash: await contentHashOf(manifest),\n date: install.date,\n source: `${GITHUB_PREFIX}${install.skill.repo}`,\n path: install.skill.path,\n }\n}\n\n/** The bytes `writeMetadataYaml` writes. */\nconst asMetadataFile = (metadata: Record<string, unknown>): string =>\n `${METADATA_SCHEMA_COMMENT}\\n${stringifyYaml(metadata, {\n lineWidth: NO_LINE_FOLDING,\n })}`\n\n/**\n * Always last, in place of any shipped stamp: a re-install reads its own earlier output as what\n * was shipped, so any other place would move the stamp on every write.\n */\nfunction withForkedFrom(\n metadata: Record<string, unknown>,\n forkedFrom: Record<string, string>\n): Record<string, unknown> {\n const { forkedFrom: _replaced, ...rest } = metadata\n return { ...rest, forkedFrom }\n}\n\n/** Read as `readLocalSkillMetadata` does: unparseable, non-mapping or bad `forkedFrom` is none. */\nfunction shippedMetadata(files: SeedSkillTree): Record<string, unknown> | null {\n const shipped = files[STANDARD_FILES.METADATA_YAML]\n if (shipped === undefined) return null\n\n const parsed = parsedYaml(shipped)\n return isMapping(parsed) && hasReadableProvenance(parsed) ? parsed : null\n}\n\nfunction parsedYaml(text: string): unknown {\n try {\n return parseYaml(text)\n } catch {\n // The CLI warns and reads no metadata; there is nobody here to warn.\n return undefined\n }\n}\n\nconst isMapping = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\nconst PROVENANCE_REQUIRED = [\"skillId\", \"contentHash\", \"date\"] as const\nconst PROVENANCE_OPTIONAL = [\"source\", \"path\"] as const\n\nfunction hasReadableProvenance(metadata: Record<string, unknown>): boolean {\n if (!Object.hasOwn(metadata, \"forkedFrom\")) return true\n\n const provenance = metadata.forkedFrom\n return (\n isMapping(provenance) &&\n PROVENANCE_REQUIRED.every((key) => typeof provenance[key] === \"string\") &&\n PROVENANCE_OPTIONAL.every(\n (key) =>\n !Object.hasOwn(provenance, key) || typeof provenance[key] === \"string\"\n )\n )\n}\n\nfunction manifestOf(files: SeedSkillTree): string {\n const manifest = files[STANDARD_FILES.SKILL_MD]\n if (manifest === undefined) {\n throw new Error(\n `A carried skill's directory holds no ${STANDARD_FILES.SKILL_MD}, which seedSkillTreeSchema refuses`\n )\n }\n return manifest\n}\n\n// `HASH_PREFIX_LENGTH` in the CLI's `computeStringHash`.\nconst CONTENT_HASH_LENGTH = 7\n\n// The CLI's `computeStringHash`, via Web Crypto because this package runs in a browser.\nasync function contentHashOf(text: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(text)\n )\n return hexOf(new Uint8Array(digest)).slice(0, CONTENT_HASH_LENGTH)\n}\n\nconst hexOf = (bytes: Uint8Array): string =>\n Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\")\n","import os from \"os\";\n\nimport { indexBy, isDeepEqual, omit, partition, pick } from \"remeda\";\n\nimport { loadProjectConfigFromDir } from \"../configuration/project-config.js\";\nimport { isActiveAt } from \"../configuration/scope-predicates.js\";\nimport { providerInUse } from \"../installation/install-layout.js\";\nimport { getCategoryDomain, matrix } from \"../matrix/matrix-provider.js\";\nimport { orderDomains } from \"@workspace/compile\";\nimport { addedToGlobalSubAgents } from \"../../utils/messages.js\";\nimport { typedEntries, typedValues } from \"../../utils/typed-object.js\";\n\nimport type { InstallSelection } from \"@workspace/compile/seed-to-config\";\nimport type { NamedBy } from \"../configuration/scope-diff.js\";\nimport type { AgentName } from \"../../types/agents.js\";\nimport type {\n AgentScopeConfig,\n ProjectConfig,\n SkillConfig,\n SkillScope,\n} from \"../../types/config.js\";\nimport type { Category, Domain } from \"../../types/matrix.js\";\nimport type { SkillAssignment, SkillId } from \"../../types/skills.js\";\nimport type { StackAgentConfig } from \"../../types/stacks.js\";\n\n/** What applying a shared configuration may not take away, split by reason. */\nexport type KeptFromRoundTrip = {\n /** Written here, so no shared configuration ever carried them. */\n authoredSkillIds: SkillId[];\n /** Named by the configuration but unplaceable by this catalogue. */\n unplaceableSkillIds: SkillId[];\n};\n\n/**\n * A kept skill's row displaced by the payload's own skill in a one-skill category. The skill stays\n * installed; the row goes.\n */\nexport type UnassignedRow = { skillId: SkillId; agentName: AgentName; category: Category };\n\nexport type ReconciledSharedConfig = {\n result: InstallSelection;\n kept: KeptFromRoundTrip;\n unassigned: UnassignedRow[];\n};\n\nexport type ReconcileOptions = {\n decoded: InstallSelection;\n installed: ProjectConfig | null;\n authoredHere: ReadonlySet<SkillId>;\n /** `SeedMapping.skippedSkillIds` as the caller already reported them. */\n unplaceable: ReadonlySet<string>;\n};\n\nconst NOTHING_KEPT: KeptFromRoundTrip = {\n authoredSkillIds: [],\n unplaceableSkillIds: [],\n};\n\n/**\n * Puts back skills written here and ids this catalogue cannot place. Restored into the result,\n * not excused at the writer, because the removal diff drives deletion; rows and domain come too.\n */\nexport function reconcileSharedConfig(options: ReconcileOptions): ReconciledSharedConfig {\n const { decoded, installed } = options;\n if (!installed) return nothingToReconcile(decoded);\n\n const keptSkills = skillsToKeep(options, installed);\n if (keptSkills.length === 0) return nothingToReconcile(decoded);\n\n const { result, unassigned } = withKeptEntries(decoded, installed, keptSkills);\n return { result, kept: describeKept(options, keptSkills), unassigned };\n}\n\nfunction nothingToReconcile(decoded: InstallSelection): ReconciledSharedConfig {\n return { result: decoded, kept: NOTHING_KEPT, unassigned: [] };\n}\n\n/** A tombstone is neither: nothing is installed, so nothing needs protecting. */\nfunction skillsToKeep(options: ReconcileOptions, installed: ProjectConfig): SkillConfig[] {\n const named = new Set(options.decoded.skills.map((skill) => skill.id));\n\n return installed.skills.filter(\n (skill) => !skill.excluded && !named.has(skill.id) && mayNotRemove(skill, options),\n );\n}\n\nfunction mayNotRemove(skill: SkillConfig, options: ReconcileOptions): boolean {\n return options.authoredHere.has(skill.id) || options.unplaceable.has(skill.id);\n}\n\ntype KeptReason = \"authored\" | \"unplaceable\";\n\nfunction describeKept(options: ReconcileOptions, keptSkills: SkillConfig[]): KeptFromRoundTrip {\n const idsKeptFor = (reason: KeptReason): SkillId[] =>\n keptSkills.filter((skill) => reasonKept(skill, options) === reason).map((skill) => skill.id);\n\n return {\n authoredSkillIds: idsKeptFor(\"authored\"),\n unplaceableSkillIds: idsKeptFor(\"unplaceable\"),\n };\n}\n\n/** Where both apply, authorship wins: `update` can resolve an unplaceable id. */\nfunction reasonKept(skill: SkillConfig, options: ReconcileOptions): KeptReason {\n return options.authoredHere.has(skill.id) ? \"authored\" : \"unplaceable\";\n}\n\nfunction withKeptEntries(\n decoded: InstallSelection,\n installed: ProjectConfig,\n keptSkills: SkillConfig[],\n): Pick<ReconciledSharedConfig, \"result\" | \"unassigned\"> {\n const withSkills: InstallSelection = {\n ...decoded,\n skills: [...decoded.skills, ...keptSkills],\n selectedDomains: withKeptDomains(decoded.selectedDomains, keptSkills),\n };\n const { assignedStack, unassigned } = withKeptStackRows(decoded.assignedStack, installed.stack, {\n keptSkillIds: new Set(keptSkills.map((skill) => skill.id)),\n survivingAgents: new Set(decoded.selectedAgents),\n });\n return { result: { ...withSkills, assignedStack }, unassigned };\n}\n\nfunction withKeptDomains(selected: Domain[], keptSkills: SkillConfig[]): Domain[] {\n const keptDomains = keptSkills.flatMap((skill) => domainOfSkill(skill.id) ?? []);\n const missing = keptDomains.filter((domain) => !selected.includes(domain));\n if (missing.length === 0) return selected;\n\n return orderDomains([...selected, ...new Set(missing)]);\n}\n\n/** Undefined for an entry the loaded source cannot resolve; `edit` reports those itself. */\nfunction domainOfSkill(skillId: SkillId): Domain | undefined {\n const category = matrix.skills[skillId]?.category;\n return category === undefined ? undefined : getCategoryDomain(category);\n}\n\ntype KeptRowFilter = {\n keptSkillIds: ReadonlySet<SkillId>;\n survivingAgents: ReadonlySet<AgentName>;\n};\n\ntype KeptRows = {\n assignedStack: Partial<Record<AgentName, StackAgentConfig>>;\n unassigned: UnassignedRow[];\n};\n\n/**\n * A kept row joins the payload's under its category, except in a one-skill category the payload\n * fills, where it is returned as unassigned.\n */\nfunction withKeptStackRows(\n assigned: Partial<Record<AgentName, StackAgentConfig>>,\n installedStack: Partial<Record<AgentName, StackAgentConfig>> | undefined,\n filter: KeptRowFilter,\n): KeptRows {\n const isKept = (_category: Category, row: SkillAssignment): boolean =>\n filter.keptSkillIds.has(row.id);\n\n return typedEntries<AgentName, StackAgentConfig>(installedStack ?? {})\n .filter(([agent]) => filter.survivingAgents.has(agent))\n .reduce<KeptRows>(\n (carried, [agent, agentStack]) =>\n withAgentKeptRows(carried, agent, rowsWhere(agentStack, isKept), assigned[agent]),\n { assignedStack: assigned, unassigned: [] },\n );\n}\n\nfunction withAgentKeptRows(\n carried: KeptRows,\n agent: AgentName,\n keptRows: [Category, SkillAssignment][],\n payloadRows: StackAgentConfig | undefined,\n): KeptRows {\n const filled = filledExclusiveCategories(payloadRows);\n const [displaced, joining] = partition(keptRows, ([category]) => filled.has(category));\n\n return {\n assignedStack: withAppendedRows(carried.assignedStack, agent, joining),\n unassigned: [\n ...carried.unassigned,\n ...displaced.map(([category, row]) => ({ skillId: row.id, agentName: agent, category })),\n ],\n };\n}\n\nexport type InstalledGlobal = Pick<ProjectConfig, \"skills\" | \"agents\" | \"stack\">;\n\n/** Read from the global config itself, not a project's possibly older inlined copy. */\nexport async function readInstalledGlobal(projectDir: string): Promise<InstalledGlobal | null> {\n const loaded = await loadProjectConfigFromDir(os.homedir(), providerInUse(projectDir));\n return loaded?.config ?? null;\n}\n\ntype Entries = { skillIds: SkillId[]; agentNames: AgentName[] };\n\n/** A held global sub-agent an arriving skill's row joins, and the skills those rows bring. */\nexport type JoinedAgent = { agentName: AgentName; skillIds: SkillId[] };\n\nexport type HeldGlobal = {\n result: InstallSelection;\n installed: Entries;\n keptAsInstalled: Entries;\n joined: JoinedAgent[];\n};\n\nconst NO_GLOBAL_ENTRIES: Entries = { skillIds: [], agentNames: [] };\n\n/** A project `--from` only adds to the global install: every global entry it holds stays as held. */\nexport function holdInstalledGlobal(\n decoded: InstallSelection,\n installed: InstalledGlobal | null,\n): HeldGlobal {\n if (!installed) {\n return {\n result: decoded,\n installed: NO_GLOBAL_ENTRIES,\n keptAsInstalled: NO_GLOBAL_ENTRIES,\n joined: [],\n };\n }\n\n const heldSkills = activeGlobalById(installed.skills, (skill) => skill.id);\n const heldAgents = activeGlobalById(installed.agents, (agent) => agent.name);\n const skills = pairWithHeld(decoded.skills, heldSkills, (skill) => skill.id);\n const agents = pairWithHeld(decoded.agentConfigs, heldAgents, (agent) => agent.name);\n const namedSkillIds = skills.map(({ named }) => named.id);\n const namedAgentNames = agents.map(({ named }) => named.name);\n const { assignedStack, joined } = withHeldRows(decoded.assignedStack, installed.stack, {\n agentNames: namedAgentNames,\n skippedSkillIds: new Set(namedSkillIds),\n });\n\n return {\n result: {\n ...decoded,\n skills: decoded.skills.map(asHeld(skills)),\n agentConfigs: decoded.agentConfigs.map(asHeld(agents)),\n assignedStack,\n },\n installed: { skillIds: namedSkillIds, agentNames: namedAgentNames },\n keptAsInstalled: {\n skillIds: skillsKeptAsInstalled(skills),\n agentNames: agentsKeptAsInstalled(agents, {\n stated: decoded.assignedStack,\n held: assignedStack,\n joined,\n }),\n },\n joined,\n };\n}\n\nfunction skillsKeptAsInstalled(pairs: Held<SkillConfig>[]): SkillId[] {\n return pairs.filter((pair) => !restatesSkill(pair)).map(({ named }) => named.id);\n}\n\nfunction restatesSkill({ named, held }: Held<SkillConfig>): boolean {\n return named.origin === held.origin;\n}\n\ntype HeldAgentRows = {\n stated: Partial<Record<AgentName, StackAgentConfig>>;\n held: Partial<Record<AgentName, StackAgentConfig>>;\n joined: JoinedAgent[];\n};\n\n/** A sub-agent a row joins is changed, so it is named as added to rather than as kept. */\nfunction agentsKeptAsInstalled(pairs: Held<AgentScopeConfig>[], rows: HeldAgentRows): AgentName[] {\n const joinedNames = new Set(rows.joined.map(({ agentName }) => agentName));\n const keptAsIs = (pair: Held<AgentScopeConfig>): boolean =>\n !restatesAgent(pair, rows) && !joinedNames.has(pair.named.name);\n\n return pairs.filter(keptAsIs).map(({ named }) => named.name);\n}\n\nfunction restatesAgent({ named, held }: Held<AgentScopeConfig>, rows: HeldAgentRows): boolean {\n return (\n named.model === held.model &&\n named.codexModel === held.codexModel &&\n named.effort === held.effort &&\n sameAssignments(rows.stated[named.name], rows.held[named.name])\n );\n}\n\n/** For the destructive `edit --from`: a project may not remove global entries. */\nexport function restoreInstalledGlobal(\n decoded: InstallSelection,\n installed: InstalledGlobal | null,\n): HeldGlobal {\n const held = holdInstalledGlobal(decoded, installed);\n if (!installed) return held;\n\n const omitted = omittedGlobal(held.result, installed);\n const { skillIds, agentNames } = held.keptAsInstalled;\n return {\n ...held,\n result: withOmittedGlobal(held.result, installed, omitted),\n keptAsInstalled: {\n skillIds: [...skillIds, ...omitted.skills.map((skill) => skill.id)],\n agentNames: [...agentNames, ...omitted.agents.map((agent) => agent.name)],\n },\n };\n}\n\nfunction activeGlobalById<Entry extends SkillConfig | AgentScopeConfig, Key extends string>(\n entries: Entry[],\n keyOf: (entry: Entry) => Key,\n): Map<Key, Entry> {\n return new Map(\n entries.filter((entry) => isActiveAt(entry, \"global\")).map((entry) => [keyOf(entry), entry]),\n );\n}\n\ntype Held<Entry> = { named: Entry; held: Entry };\n\nfunction asHeld<Entry>(pairs: Held<Entry>[]): (entry: Entry) => Entry {\n const heldFor = new Map(pairs.map(({ named, held }) => [named, held]));\n return (entry) => heldFor.get(entry) ?? entry;\n}\n\nfunction pairWithHeld<Entry extends SkillConfig | AgentScopeConfig, Key extends string>(\n decoded: Entry[],\n heldByKey: ReadonlyMap<Key, Entry>,\n keyOf: (entry: Entry) => Key,\n): Held<Entry>[] {\n return decoded.flatMap((named) => {\n const held = heldByKey.get(keyOf(named));\n return held !== undefined && isActiveAt(named, \"global\") ? [{ named, held }] : [];\n });\n}\n\n/** Row order is not part of what a sub-agent loads. */\nexport function sameAssignments(\n left: StackAgentConfig | undefined,\n right: StackAgentConfig | undefined,\n): boolean {\n return isDeepEqual(assignmentKeys(left), assignmentKeys(right));\n}\n\nfunction assignmentKeys(agentStack: StackAgentConfig | undefined): string[] {\n return typedEntries<Category, SkillAssignment[]>(agentStack ?? {})\n .flatMap(([category, assignments]) =>\n assignments.map((row) => `${category}/${row.id}/${row.preloaded === true}`),\n )\n .sort();\n}\n\nfunction withInstalledRows(\n assigned: Partial<Record<AgentName, StackAgentConfig>>,\n installedStack: InstalledGlobal[\"stack\"],\n agentNames: AgentName[],\n): Partial<Record<AgentName, StackAgentConfig>> {\n return { ...omit(assigned, agentNames), ...pick(installedStack ?? {}, agentNames) };\n}\n\ntype HeldAgents = { agentNames: AgentName[]; skippedSkillIds: ReadonlySet<SkillId> };\n\ntype HeldStack = Pick<HeldGlobal, \"joined\"> & {\n assignedStack: Partial<Record<AgentName, StackAgentConfig>>;\n};\n\ntype AgentArrival = { agentName: AgentName; rows: [Category, SkillAssignment][] };\n\n/** Existing rows stay first and unchanged; arriving skills bring their rows after them. */\nfunction withHeldRows(\n assigned: Partial<Record<AgentName, StackAgentConfig>>,\n installedStack: InstalledGlobal[\"stack\"],\n held: HeldAgents,\n): HeldStack {\n const asInstalled = withInstalledRows(assigned, installedStack, held.agentNames);\n const arrivals = held.agentNames.map((agentName): AgentArrival => ({\n agentName,\n rows: arrivingRows(assigned[agentName], asInstalled[agentName], held.skippedSkillIds),\n }));\n\n return {\n assignedStack: arrivals.reduce(\n (stack, { agentName, rows }) => withAppendedRows(stack, agentName, rows),\n asInstalled,\n ),\n joined: arrivals.filter(({ rows }) => rows.length > 0).map(asJoined),\n };\n}\n\nfunction asJoined({ agentName, rows }: AgentArrival): JoinedAgent {\n return { agentName, skillIds: rows.map(([, row]) => row.id) };\n}\n\nfunction arrivingRows(\n stated: StackAgentConfig | undefined,\n installed: StackAgentConfig | undefined,\n skippedSkillIds: ReadonlySet<SkillId>,\n): [Category, SkillAssignment][] {\n const alreadyLoaded = new Set(rowIds(installed));\n const filled = filledExclusiveCategories(installed);\n const arrives = (category: Category, row: SkillAssignment): boolean =>\n !skippedSkillIds.has(row.id) && !alreadyLoaded.has(row.id) && !filled.has(category);\n\n return rowsWhere(stated, arrives);\n}\n\nfunction rowIds(agentStack: StackAgentConfig | undefined): SkillId[] {\n return typedValues<Category, SkillAssignment[]>(agentStack ?? {}).flatMap((rows) =>\n rows.map((row) => row.id),\n );\n}\n\n/** An undeclared category is not exclusive (see `propagate.ts`). */\nfunction filledExclusiveCategories(agentStack: StackAgentConfig | undefined): Set<Category> {\n const isExclusive = (category: Category): boolean =>\n matrix.categories[category]?.exclusive === true;\n\n return new Set(\n typedEntries<Category, SkillAssignment[]>(agentStack ?? {})\n .filter(([category, rows]) => rows.length > 0 && isExclusive(category))\n .map(([category]) => category),\n );\n}\n\nfunction withAppendedRows(\n stack: Partial<Record<AgentName, StackAgentConfig>>,\n agentName: AgentName,\n added: [Category, SkillAssignment][],\n): Partial<Record<AgentName, StackAgentConfig>> {\n if (added.length === 0) return stack;\n return { ...stack, [agentName]: appendRows(stack[agentName] ?? {}, added) };\n}\n\nfunction rowsWhere(\n agentStack: StackAgentConfig | undefined,\n keep: (category: Category, row: SkillAssignment) => boolean,\n): [Category, SkillAssignment][] {\n return typedEntries<Category, SkillAssignment[]>(agentStack ?? {}).flatMap(([category, rows]) =>\n rows\n .filter((row) => keep(category, row))\n .map((row): [Category, SkillAssignment] => [category, row]),\n );\n}\n\nfunction appendRows(\n agentStack: StackAgentConfig,\n added: [Category, SkillAssignment][],\n): StackAgentConfig {\n return added.reduce<StackAgentConfig>(\n (rows, [category, row]) => ({ ...rows, [category]: [...(rows[category] ?? []), row] }),\n agentStack,\n );\n}\n\ntype OmittedGlobal = { skills: SkillConfig[]; agents: AgentScopeConfig[] };\n\nfunction omittedGlobal(result: InstallSelection, installed: InstalledGlobal): OmittedGlobal {\n const namedSkillIds = new Set(result.skills.map((skill) => skill.id));\n const namedAgentNames = new Set(result.agentConfigs.map((agent) => agent.name));\n\n return {\n skills: [...activeGlobalById(installed.skills, (skill) => skill.id).values()].filter(\n (skill) => !namedSkillIds.has(skill.id),\n ),\n agents: [...activeGlobalById(installed.agents, (agent) => agent.name).values()].filter(\n (agent) => !namedAgentNames.has(agent.name),\n ),\n };\n}\n\nfunction withOmittedGlobal(\n result: InstallSelection,\n installed: InstalledGlobal,\n omitted: OmittedGlobal,\n): InstallSelection {\n const omittedAgentNames = omitted.agents.map((agent) => agent.name);\n\n return {\n ...result,\n skills: [...result.skills, ...omitted.skills],\n agentConfigs: [...result.agentConfigs, ...omitted.agents],\n selectedAgents: [...new Set([...result.selectedAgents, ...omittedAgentNames])],\n selectedDomains: withKeptDomains(result.selectedDomains, omitted.skills),\n assignedStack: withInstalledRows(result.assignedStack, installed.stack, omittedAgentNames),\n };\n}\n\nexport function notInstalledGlobally<Entry extends { id: SkillId }>(\n entries: Entry[],\n held: HeldGlobal,\n): Entry[] {\n const installed = new Set(held.installed.skillIds);\n return entries.filter((entry) => !installed.has(entry.id));\n}\n\nfunction entriesActiveAt(\n skills: SkillConfig[],\n agents: AgentScopeConfig[],\n scope: SkillScope,\n): Entries {\n return {\n skillIds: skills.filter((skill) => isActiveAt(skill, scope)).map((skill) => skill.id),\n agentNames: agents.filter((agent) => isActiveAt(agent, scope)).map((agent) => agent.name),\n };\n}\n\n/**\n * The entry the panel draws each skill's row from, which a notice under it names the skill by: the\n * global install's for one held, the installed one for one kept, the configuration's for the rest.\n */\nexport function panelRowEntries(held: HeldGlobal): NamedBy {\n const active = held.result.skills.filter((skill) => !skill.excluded);\n return indexBy(active, (skill) => skill.id);\n}\n\nexport function joinedStatement(held: HeldGlobal): string[] {\n if (held.joined.length === 0) return [];\n return [addedToGlobalSubAgents(held.joined, panelRowEntries(held))];\n}\n\n/** Split by kind: skill and sub-agent scopes are independent, so a refusal names each. */\nexport function projectScopedContent(result: InstallSelection): Entries {\n return entriesActiveAt(result.skills, result.agentConfigs, \"project\");\n}\n\n/** The home directory is the global scope, so it refuses anything project-scoped. */\nexport function installsAtHome(result: InstallSelection): boolean {\n const { skillIds, agentNames } = projectScopedContent(result);\n return skillIds.length === 0 && agentNames.length === 0;\n}\n","import { Command } from \"@oclif/core\";\n\nimport chalk from \"chalk\";\nimport { unique } from \"remeda\";\n\nimport { CLI_COLORS, DEFAULT_BRANDING, MIN_TERMINAL_SIZE, type Provider } from \"./consts.js\";\nimport { getErrorMessage } from \"./utils/errors.js\";\nimport { inertLine, stripTerminalControls } from \"./utils/string.js\";\nimport { verbose } from \"./utils/logger.js\";\nimport {\n completedWithFailures,\n INFO_MESSAGES,\n installationConfigsUnreadable,\n type IncompleteWork,\n pluginsInstalled,\n propagatedRecompileSummary,\n registeredProjectConfigUnreadable,\n registeredProjectGone,\n registeredProjectOnAnotherProvider,\n savedSkillMetadataUnusableError,\n scopeBlockedStackAssignment,\n sharedConfigProjectScopeAtHome,\n skillAssignedToNoAgent,\n skillMetadataUnusableDetail,\n skippedUnknownAgents,\n skippedSkills,\n STATUS_MESSAGES,\n} from \"./utils/messages.js\";\nimport {\n clearTerminalScreen,\n formatTerminalTooSmallMessage,\n isTerminalLargeEnough,\n} from \"./utils/terminal.js\";\nimport { EXIT_CODES } from \"./lib/exit-codes.js\";\nimport { isActiveAt } from \"./lib/configuration/scope-predicates.js\";\nimport { resolveBranding } from \"./lib/configuration/config.js\";\nimport { isHomeDirectory, refuseUnofferedStack } from \"./lib/installation/index.js\";\nimport { providerInUse } from \"./lib/installation/install-layout.js\";\nimport { globalInstallationStandsIn } from \"./lib/installation/provider-flag.js\";\nimport { providerToNameAt } from \"./lib/installation/provider-to-name.js\";\nimport type { InstallSelection } from \"@workspace/compile/seed-to-config\";\nimport { getStackSkillIds, loadStackById } from \"./lib/stacks/index.js\";\nimport type {\n AgentName,\n MergedSkillsMatrix,\n ProjectConfig,\n SelectionValidation,\n SkillConfig,\n SkillId,\n} from \"./types/index.js\";\nimport { findConfigLoadFailures } from \"./lib/configuration/project-config.js\";\nimport { findUnusableSavedSkillMetadata } from \"./lib/skills/index.js\";\nimport type { PluginHost } from \"./lib/hosts/plugin-host.js\";\nimport { hostAt } from \"./lib/hosts/host-for.js\";\nimport { refuseUnofferedPlacements } from \"./lib/hosts/offered-placements.js\";\nimport {\n refuseUncarriedDestinations,\n type ExternalSkillInstall,\n} from \"./lib/seed/external-skills.js\";\nimport { installsAtHome, projectScopedContent } from \"./lib/seed/seed-apply.js\";\nimport type { SeedMapping } from \"./lib/seed/seed-to-selection.js\";\nimport { refuseUnwritableStack } from \"@workspace/compile/config-source\";\nimport { requireMarketplace } from \"./lib/operations/source/require-marketplace.js\";\nimport {\n installPluginSkills,\n pluginInstallFailureError,\n unbackedPluginInstallError,\n unbackedPluginSkillIds,\n type PluginInstallResult,\n} from \"./lib/operations/skills/install-plugin-skills.js\";\nimport type { GateReport } from \"./lib/config-gate/index.js\";\nimport type { SourceLoadResult } from \"./lib/loading/source-loader.js\";\nimport type { UnusableSkillMetadata } from \"./lib/loading/index.js\";\n\n/** Polled because some terminals and multiplexers resize without emitting `resize`. */\nconst TERMINAL_RESIZE_POLL_MS = 500;\n\n// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- @types/node declares this as `number`; it is undefined whenever stdout is not a TTY\nconst terminalColumns = (): number => process.stdout.columns ?? MIN_TERMINAL_SIZE.COLS;\n\n// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- @types/node declares this as `number`; it is undefined whenever stdout is not a TTY\nconst terminalRows = (): number => process.stdout.rows ?? MIN_TERMINAL_SIZE.ROWS;\n\nfunction isTerminalBigEnough(): boolean {\n return isTerminalLargeEnough(terminalColumns(), terminalRows());\n}\n\nfunction waitForTerminal(isSatisfied: () => boolean): Promise<void> {\n return new Promise<void>((resolve) => {\n const check = () => {\n if (!isSatisfied()) return;\n clearInterval(interval);\n process.stdout.off(\"resize\", check);\n resolve();\n };\n const interval = setInterval(check, TERMINAL_RESIZE_POLL_MS);\n process.stdout.on(\"resize\", check);\n });\n}\n\ntype UnassignedSkill = { skillId: SkillId; blockedBy: AgentName[] };\n\n/**\n * Only the selection is judged: inherited global skills are absent from this stack without being\n * unassigned. `blockedBy` is empty for a global-scoped skill, since the scope rule is not why.\n */\nfunction findUnassignedSkills(\n config: ProjectConfig,\n selected: readonly SkillConfig[],\n): UnassignedSkill[] {\n const assignedIds = new Set(config.stack ? getStackSkillIds(config.stack) : []);\n const selectedIds = new Set(selected.map((skill) => skill.id));\n const globalAgentNames = config.agents\n .filter((agent) => isActiveAt(agent, \"global\"))\n .map((agent) => agent.name);\n\n const unassignedIds = unique(\n config.skills\n .filter((skill) => !skill.excluded && selectedIds.has(skill.id))\n .map((skill) => skill.id)\n .filter((skillId) => !assignedIds.has(skillId)),\n );\n\n return unassignedIds.map((skillId) => ({\n skillId,\n blockedBy: hasActiveProjectEntry(config.skills, skillId) ? globalAgentNames : [],\n }));\n}\n\nfunction hasActiveProjectEntry(skills: readonly SkillConfig[], skillId: SkillId): boolean {\n return skills.some((skill) => skill.id === skillId && isActiveAt(skill, \"project\"));\n}\n\nexport abstract class BaseCommand extends Command {\n /** Non-empty decides the exit code; see {@link exitIfWorkIncomplete}. */\n private readonly incompleteWork: IncompleteWork[] = [];\n\n async init(): Promise<void> {\n await super.init();\n await this.ensureTerminalSize();\n }\n\n /**\n * Called first where a command starts work on the installation in play, which for a project whose\n * config declares nothing is the global one. On stderr, as the init hook's old-folder lines are,\n * so piped output is unchanged.\n */\n protected async sayWhenTheGlobalInstallationStandsIn(named: Provider | undefined): Promise<void> {\n if (!(await globalInstallationStandsIn(process.cwd(), named))) return;\n\n process.stderr.write(`${INFO_MESSAGES.GLOBAL_INSTALLATION_STANDS_IN}\\n`);\n }\n\n protected async ensureTerminalSize(): Promise<void> {\n if (isTerminalBigEnough()) return;\n\n clearTerminalScreen();\n this.log(chalk.hex(CLI_COLORS.WARNING)(formatTerminalTooSmallMessage(terminalColumns())));\n\n await waitForTerminal(isTerminalBigEnough);\n }\n\n protected handleError(error: unknown): never {\n const message = getErrorMessage(error);\n this.error(message, { exit: EXIT_CODES.ERROR });\n }\n\n /**\n * Degrades on an unreadable config: `doctor` and `uninstall` must survive one, and a heading is\n * not worth refusing over. The command's own config reader reports the cause.\n */\n protected async resolveBrandingName(projectDir: string): Promise<string> {\n try {\n const branding = await resolveBranding(projectDir);\n return branding.name;\n } catch (error) {\n verbose(`Could not read branding from the config: ${getErrorMessage(error)}`);\n return DEFAULT_BRANDING.NAME;\n }\n }\n\n protected logSuccess(message: string): void {\n this.log(`✓ ${message}`);\n }\n\n /** `onRegistered` fires only when the marketplace had to be registered. */\n protected async requireMarketplaceOrExit(\n sourceResult: SourceLoadResult,\n purpose: string,\n host: PluginHost,\n onRegistered?: (marketplace: string) => void,\n ): Promise<string> {\n const required = await requireMarketplace(sourceResult, purpose, host);\n if (!required.ok) {\n this.error(required.error, { exit: EXIT_CODES.ERROR });\n }\n if (required.registered) {\n onRegistered?.(required.marketplace);\n }\n return required.marketplace;\n }\n\n /** Advisory: the selection installs either way. A message can quote a payload's own ids. */\n protected reportValidationErrors(validation: SelectionValidation): void {\n for (const error of validation.errors) {\n this.warn(stripTerminalControls(error.message));\n }\n }\n\n /** Refuses skills no marketplace carries before the host's CLI is asked. */\n protected async installPluginSkillsReported(\n skills: SkillConfig[],\n marketplace: string,\n projectDir: string,\n matrix: MergedSkillsMatrix,\n ): Promise<PluginInstallResult> {\n const unbacked = unbackedPluginSkillIds(skills, matrix);\n if (unbacked.length > 0) {\n this.error(unbackedPluginInstallError(unbacked), { exit: EXIT_CODES.ERROR });\n }\n\n this.announcePluginInstall();\n const result = await installPluginSkills(skills, marketplace, projectDir);\n this.reportPluginInstalls(result);\n return result;\n }\n\n /** Split out for the eject-to-plugin migration, which runs its own installs. */\n protected announcePluginInstall(): void {\n this.log(STATUS_MESSAGES.INSTALLING_PLUGINS);\n }\n\n /** Hard-errors on any failure, before a config can record an origin for an uninstalled plugin. */\n protected reportPluginInstalls(result: PluginInstallResult): void {\n for (const item of result.installed) {\n this.log(` Installed ${item.ref}`);\n }\n for (const item of result.failed) {\n this.warn(`Failed to install plugin ${item.id}: ${item.error}`);\n }\n if (result.failed.length > 0) {\n this.error(pluginInstallFailureError(result.failed.length), { exit: EXIT_CODES.ERROR });\n }\n this.log(`${pluginsInstalled(result.installed.length)}\\n`);\n }\n\n protected reportFanOut(report: GateReport): void {\n for (const projectPath of report.propagated.unreadable) {\n this.warn(registeredProjectConfigUnreadable(projectPath));\n }\n this.reportPropagatedRecompile(report);\n }\n\n protected reportProjectsOutOfReach(propagated: GateReport[\"propagated\"]): void {\n for (const projectPath of propagated.gone) {\n this.warn(registeredProjectGone(projectPath));\n }\n for (const projectPath of propagated.notOurs) {\n this.warn(registeredProjectOnAnotherProvider(projectPath));\n }\n }\n\n protected reportPropagatedRecompile(report: GateReport): void {\n if (report.propagated.updated.length === 0) return;\n\n const { rewrittenCount, unchangedCount, failedCount, warnings } = report.recompile;\n for (const warning of warnings) {\n this.warn(warning);\n }\n this.log(propagatedRecompileSummary(rewrittenCount + unchangedCount, failedCount));\n }\n\n protected reportUnassignedSkills(config: ProjectConfig, selected: readonly SkillConfig[]): void {\n for (const { skillId, blockedBy } of findUnassignedSkills(config, selected)) {\n this.warn(skillAssignedToNoAgent(skillId));\n if (blockedBy.length > 0) {\n this.warn(scopeBlockedStackAssignment(blockedBy, skillId));\n }\n }\n }\n\n /**\n * Aborts up front when the project or global config exists but cannot be loaded, so nothing is\n * installed before the config write fails. A missing config passes.\n */\n protected async ensureConfigReadable(projectDir: string): Promise<void> {\n const failures = await findConfigLoadFailures(projectDir);\n if (failures.length > 0) {\n this.error(installationConfigsUnreadable(failures), { exit: EXIT_CODES.ERROR });\n }\n }\n\n /** Only entries the catalogue lacks are checked; one whose files are gone is not refused. */\n protected async ensureSavedSkillsReadable(\n savedSkills: readonly SkillConfig[],\n matrix: MergedSkillsMatrix,\n projectDir: string,\n ): Promise<void> {\n const unresolved = savedSkills.filter((saved) => !matrix.skills[saved.id]);\n await this.refuseUnusableSavedSkillMetadata(\n unresolved,\n projectDir,\n savedSkillMetadataUnusableError,\n );\n }\n\n protected async refuseUnusableSavedSkillMetadata(\n savedSkills: readonly SkillConfig[],\n projectDir: string,\n refusal: (unusable: UnusableSkillMetadata[]) => string,\n ): Promise<void> {\n const unusable = await findUnusableSavedSkillMetadata(savedSkills, projectDir);\n if (unusable.length === 0) return;\n\n // Logged, not raised: oclif hard-wraps error text, which breaks copyable paths.\n for (const entry of unusable) {\n this.log(skillMetadataUnusableDetail(entry));\n }\n this.error(refusal(unusable), { exit: EXIT_CODES.ERROR });\n }\n\n /**\n * The home directory is the global scope, so project-scoped content there would land in the\n * global config mislabelled. Needs the decoded selection; callers run it before any write.\n * `installedHere`: the run applies to the global install rather than creating it.\n */\n protected refuseProjectScopedContentAtHome(\n result: InstallSelection,\n projectDir: string,\n installedHere: boolean,\n ): void {\n if (!isHomeDirectory(projectDir) || installsAtHome(result)) return;\n\n const { skillIds, agentNames } = projectScopedContent(result);\n const provider = providerToNameAt(projectDir, providerInUse(projectDir));\n this.error(sharedConfigProjectScopeAtHome(skillIds, agentNames, installedHere, provider), {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n /** `unloadedSkillIds`: skills the marketplace ships and could not load, never unknown ones. */\n protected warnOfSkippedEntries(\n mapping: SeedMapping,\n unloadedSkillIds: SourceLoadResult[\"unloadedSkillIds\"],\n ): void {\n const { skippedSkillIds, skippedAgentNames, agentsOnlySkippedSkillsCarried } = mapping;\n\n if (skippedSkillIds.length > 0) {\n this.warn(skippedSkills(skippedSkillIds, agentsOnlySkippedSkillsCarried, unloadedSkillIds));\n }\n if (skippedAgentNames.length > 0) this.warn(skippedUnknownAgents(skippedAgentNames));\n }\n\n /** For the panel's header; `undefined` for a configuration built from no stack. */\n protected async stackNameOf(\n stackId: InstallSelection[\"selectedStackId\"],\n sourceResult: SourceLoadResult,\n ): Promise<string | undefined> {\n if (!stackId) return undefined;\n\n const { sourcePath, sourceConfig } = sourceResult;\n const stack = await loadStackById(stackId, sourcePath, sourceConfig.source);\n return stack === null ? undefined : inertLine(stack.name);\n }\n\n /** The `--from` refusals that need the decoded selection, asked before the confirm. */\n protected async refuseSharedConfigBeforeAsking(\n selection: InstallSelection,\n carried: ExternalSkillInstall[],\n root: string,\n sourceResult: SourceLoadResult,\n ): Promise<void> {\n this.refuseUnofferablePlacementsBeforeWriting(selection.skills, root);\n try {\n await refuseUnofferedStack(selection.selectedStackId, sourceResult);\n await refuseUncarriedDestinations(carried);\n refuseUnwritableStack(selection.assignedStack, sourceResult.matrix);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Pre-flight over every row, ejected included: the per-plugin guard in `installPlugin` fires\n * mid-loop, after earlier plugins are already installed.\n */\n protected refuseUnofferablePlacementsBeforeWriting(\n skills: readonly SkillConfig[],\n root: string,\n ): void {\n try {\n refuseUnofferedPlacements(skills, hostAt(root));\n } catch (error) {\n this.error(getErrorMessage(error), { exit: EXIT_CODES.ERROR });\n }\n }\n\n protected get hasIncompleteWork(): boolean {\n return this.incompleteWork.length > 0;\n }\n\n /** Never aborts: every caller is past a mutation that has already landed. */\n protected reportIncompleteWork(what: string, recovery: string): void {\n this.warn(what);\n this.recordIncompleteWork(what, recovery);\n }\n\n /** For a caller that has already warned. */\n protected recordIncompleteWork(what: string, recovery: string): void {\n this.incompleteWork.push({ what, recovery });\n }\n\n /** Every command that records must call this; `this.exit` skips the `Error:` framing. */\n protected exitIfWorkIncomplete(): void {\n if (!this.hasIncompleteWork) return;\n\n this.log(`\\n${chalk.hex(CLI_COLORS.WARNING)(completedWithFailures(this.incompleteWork))}\\n`);\n this.exit(EXIT_CODES.COMPLETED_WITH_FAILURES);\n }\n}\n","import type { PluginHost } from \"../../hosts/plugin-host.js\";\nimport { fetchMarketplace } from \"../../loading/index.js\";\nimport { warn } from \"../../../utils/logger.js\";\nimport { getErrorMessage } from \"../../../utils/errors.js\";\nimport type { SourceLoadResult } from \"../../loading/source-loader.js\";\n\nexport type MarketplaceResult = {\n marketplace: string | null;\n registered: boolean;\n};\n\n/**\n * Registers the marketplace, or refreshes it when it exists. A resolution failure is warned here\n * because `requireMarketplace`'s error cannot tell its cause.\n */\nexport async function ensureMarketplace(\n sourceResult: SourceLoadResult,\n host: PluginHost,\n): Promise<MarketplaceResult> {\n const marketplace = await resolveMarketplaceName(sourceResult);\n if (marketplace === null) return { marketplace: null, registered: false };\n\n const exists = await host.marketplaceExists(marketplace);\n\n if (!exists) {\n const marketplaceSource = sourceResult.sourceConfig.source.replace(/^github:/, \"\");\n await host.addMarketplace(marketplaceSource);\n return { marketplace, registered: true };\n }\n\n try {\n await host.refreshMarketplace(marketplace);\n } catch {\n warn(\"Could not update marketplace — continuing with cached version\");\n }\n\n return { marketplace, registered: false };\n}\n\n/** Fetched, and recorded on `sourceResult`, when the load left it unresolved. */\nasync function resolveMarketplaceName(sourceResult: SourceLoadResult): Promise<string | null> {\n if (sourceResult.marketplace) return sourceResult.marketplace;\n\n const source = sourceResult.sourceConfig.source;\n try {\n const marketplaceResult = await fetchMarketplace(source);\n sourceResult.marketplace = marketplaceResult.marketplace.name;\n return sourceResult.marketplace;\n } catch (error) {\n warn(`Could not resolve a marketplace from '${source}': ${getErrorMessage(error)}`);\n return null;\n }\n}\n","import { ensureMarketplace } from \"./ensure-marketplace.js\";\nimport type { PluginHost } from \"../../hosts/plugin-host.js\";\nimport type { SourceLoadResult } from \"../../loading/source-loader.js\";\n\nexport type MarketplaceRequirement =\n { ok: true; marketplace: string; registered: boolean } | { ok: false; error: string };\n\n/** Callers must hard-error on `ok: false`, never fall back to eject, before touching disk. */\nexport async function requireMarketplace(\n sourceResult: SourceLoadResult,\n purpose: string,\n host: PluginHost,\n): Promise<MarketplaceRequirement> {\n const mpResult = await ensureMarketplace(sourceResult, host);\n if (!mpResult.marketplace) {\n return {\n ok: false,\n error:\n `Cannot ${purpose}: marketplace could not be resolved from '${sourceResult.sourceConfig.source}'. ` +\n `Plugin install mode requires a marketplace — fix the marketplace or switch the affected skills to eject mode.`,\n };\n }\n return { ok: true, marketplace: mpResult.marketplace, registered: mpResult.registered };\n}\n","import { hostAt } from \"../../hosts/host-for.js\";\nimport { isLocalOnlySkill } from \"../../loading/multi-source-loader.js\";\nimport { buildMarketplacePluginRef } from \"../../plugins/index.js\";\nimport { getErrorMessage } from \"../../../utils/errors.js\";\nimport { CLI_INVOKE_COMMAND, EJECT_SOURCE } from \"../../../consts.js\";\nimport type { MergedSkillsMatrix, SkillId } from \"../../../types/index.js\";\nimport type { SkillConfig } from \"../../../types/config.js\";\n\nexport type PluginInstallResult = {\n installed: Array<{ id: SkillId; ref: string }>;\n failed: Array<{ id: SkillId; error: string }>;\n};\n\n/** Callers must error with this BEFORE config is written, or config.ts gains orphan entries. */\nexport function pluginInstallFailureError(failedCount: number): string {\n return `Failed to install ${failedCount} plugin skill(s). Plugin install intent could not be honored. Verify the skill id matches the marketplace, run '${CLI_INVOKE_COMMAND} update' to refresh the marketplace, or switch affected skills to eject mode.`;\n}\n\n/** Plugin-mode skills no marketplace carries, refusable before any install is attempted. */\nexport function unbackedPluginSkillIds(\n skills: SkillConfig[],\n matrix: MergedSkillsMatrix,\n): SkillId[] {\n return skills\n .filter((skill) => skill.origin !== EJECT_SOURCE)\n .filter((skill) => isLocalOnlySkill(matrix.skills[skill.id]))\n .map((skill) => skill.id);\n}\n\nexport function unbackedPluginInstallError(ids: SkillId[]): string {\n return `Cannot install ${ids.length} skill(s) as plugins — no marketplace carries them: ${ids.join(\", \")}. A skill that exists only in this project can only be installed as a local copy. Set its Install mode to eject in the editor, or publish it to a marketplace first.`;\n}\n\n/** The host is read off the folder under `projectDir`, so that folder must already exist. */\nexport async function installPluginSkills(\n skills: SkillConfig[],\n marketplace: string,\n projectDir: string,\n): Promise<PluginInstallResult> {\n const host = hostAt(projectDir);\n const pluginSkills = skills.filter((s) => s.origin !== EJECT_SOURCE);\n const installed: PluginInstallResult[\"installed\"] = [];\n const failed: PluginInstallResult[\"failed\"] = [];\n\n for (const skill of pluginSkills) {\n const pluginRef = buildMarketplacePluginRef(skill.id, marketplace);\n try {\n await host.installPlugin(pluginRef, skill.scope, projectDir);\n installed.push({ id: skill.id, ref: pluginRef });\n } catch (error) {\n failed.push({ id: skill.id, error: getErrorMessage(error) });\n }\n }\n\n return { installed, failed };\n}\n"],"mappings":"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","names":["os","matrix","os","os","os","matrix","matrix"]}