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
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BaseCommand,
4
4
  EXIT_CODES
5
- } from "../../chunk-IAQFZFWD.js";
5
+ } from "../../chunk-37QFHJUW.js";
6
6
  import {
7
7
  NO_VALID_DEFAULT_EXPORT,
8
8
  configLoadFailure,
@@ -23,10 +23,10 @@ import {
23
23
  warn,
24
24
  writeFile,
25
25
  writeMarketplace
26
- } from "../../chunk-E45IT3HC.js";
26
+ } from "../../chunk-YM3VEDAP.js";
27
27
  import {
28
28
  plural
29
- } from "../../chunk-AIBVAYHS.js";
29
+ } from "../../chunk-TG3SPPZY.js";
30
30
  import {
31
31
  CATALOG_JSON,
32
32
  CLI_INVOKE_COMMAND,
@@ -35,7 +35,7 @@ import {
35
35
  PLUGINS_DIST_PATH,
36
36
  PLUGIN_MANIFEST_DIR,
37
37
  STANDARD_FILES
38
- } from "../../chunk-WUSEZFER.js";
38
+ } from "../../chunk-U46LYYRA.js";
39
39
  import "../../chunk-GHHJYNAN.js";
40
40
 
41
41
  // src/cli/commands/build/marketplace.ts
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  compileAllAgentPlugins,
4
4
  printAgentCompilationSummary
5
- } from "../../chunk-IXVGBUWI.js";
6
- import "../../chunk-EFXVYQGT.js";
5
+ } from "../../chunk-SI2LLEIR.js";
6
+ import "../../chunk-GNMRXXRY.js";
7
7
  import {
8
8
  BaseCommand
9
- } from "../../chunk-IAQFZFWD.js";
9
+ } from "../../chunk-37QFHJUW.js";
10
10
  import {
11
11
  compileAllSkillPlugins,
12
12
  compileSkillPlugin,
@@ -15,14 +15,14 @@ import {
15
15
  readPluginManifest,
16
16
  remove,
17
17
  setVerbose
18
- } from "../../chunk-E45IT3HC.js";
18
+ } from "../../chunk-YM3VEDAP.js";
19
19
  import {
20
20
  plural
21
- } from "../../chunk-AIBVAYHS.js";
21
+ } from "../../chunk-TG3SPPZY.js";
22
22
  import {
23
23
  DIRS,
24
24
  PLUGINS_DIST_PATH
25
- } from "../../chunk-WUSEZFER.js";
25
+ } from "../../chunk-U46LYYRA.js";
26
26
  import "../../chunk-GHHJYNAN.js";
27
27
 
28
28
  // src/cli/commands/build/plugins.ts
@@ -1,32 +1,30 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  unofferablePlacementsFound
4
- } from "../chunk-ECPFYHDX.js";
4
+ } from "../chunk-YLFKFVQP.js";
5
5
  import {
6
6
  hostCompileNotices
7
- } from "../chunk-6PGXTLA4.js";
7
+ } from "../chunk-EHEBN4NB.js";
8
8
  import {
9
9
  detectBothInstallations,
10
10
  reconcileTypesFromDisk
11
- } from "../chunk-R7GKQBZJ.js";
11
+ } from "../chunk-SNXEYAFP.js";
12
12
  import {
13
13
  compileAgents,
14
14
  discoverInstalledSkills
15
- } from "../chunk-REHVGFJE.js";
15
+ } from "../chunk-Q4NWATGH.js";
16
16
  import {
17
17
  loadAgentDefs
18
- } from "../chunk-7BHDKEGK.js";
19
- import "../chunk-IXVGBUWI.js";
20
- import "../chunk-EFXVYQGT.js";
18
+ } from "../chunk-DQB3E2SX.js";
19
+ import "../chunk-SI2LLEIR.js";
20
+ import "../chunk-GNMRXXRY.js";
21
21
  import {
22
+ BaseCommand,
23
+ EXIT_CODES,
22
24
  providerFlag,
23
25
  providerNamedBy,
24
26
  refuseAnAmbiguousInstallation
25
- } from "../chunk-ORO2T4K2.js";
26
- import {
27
- BaseCommand,
28
- EXIT_CODES
29
- } from "../chunk-IAQFZFWD.js";
27
+ } from "../chunk-37QFHJUW.js";
30
28
  import {
31
29
  ConfigLoadError,
32
30
  ERROR_MESSAGES,
@@ -49,15 +47,15 @@ import {
49
47
  skillMetadataUnusableDetail,
50
48
  skillMetadataUnusableError,
51
49
  verbose
52
- } from "../chunk-E45IT3HC.js";
50
+ } from "../chunk-YM3VEDAP.js";
53
51
  import {
54
52
  plural
55
- } from "../chunk-AIBVAYHS.js";
53
+ } from "../chunk-TG3SPPZY.js";
56
54
  import {
57
55
  STANDARD_FILES,
58
56
  effectivelyExcludedSkillIds,
59
57
  isActiveAt
60
- } from "../chunk-WUSEZFER.js";
58
+ } from "../chunk-U46LYYRA.js";
61
59
  import "../chunk-GHHJYNAN.js";
62
60
 
63
61
  // src/cli/commands/compile.ts
@@ -83,10 +81,12 @@ var Compile = class _Compile extends BaseCommand {
83
81
  const { flags } = await this.parse(_Compile);
84
82
  setVerbose(flags.verbose);
85
83
  const cwd = process.cwd();
84
+ const namedProvider = providerNamedBy(flags.provider);
85
+ await this.sayWhenTheGlobalInstallationStandsIn(namedProvider);
86
86
  await refuseAnAmbiguousInstallation(
87
87
  cwd,
88
88
  "compile",
89
- providerNamedBy(flags.provider),
89
+ namedProvider,
90
90
  (message) => this.error(message, { exit: EXIT_CODES.INVALID_ARGS })
91
91
  );
92
92
  await this.ensureConfigReadable(cwd);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/compile.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport os from \"os\";\nimport { unique } from \"remeda\";\nimport { BaseCommand } from \"../base-command\";\nimport { setVerbose, verbose } from \"../utils/logger\";\nimport {\n detectBothInstallations,\n type BothInstallations,\n loadAgentDefs,\n type AgentDefs,\n compileAgents,\n type CompilationResult,\n discoverInstalledSkills,\n type DiscoveredSkills,\n} from \"../lib/operations\";\nimport {\n ConfigLoadError,\n effectivelyExcludedSkillIds,\n isActiveAt,\n loadProjectConfig,\n loadInstalledConfig,\n resolveSource,\n} from \"../lib/configuration\";\nimport { getStackSkillIds, resolveAgentConfigToSkills } from \"../lib/stacks\";\nimport { loadSkillsMatrixFromSource, type UnusableSkillMetadata } from \"../lib/loading\";\nimport { STANDARD_FILES } from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { plural } from \"../utils/string\";\nimport {\n ERROR_MESSAGES,\n STATUS_MESSAGES,\n INFO_MESSAGES,\n configTypesRefreshFailed,\n globalScopedAgentsHint,\n recompileSummary,\n registeredProjectUpdateFailed,\n scopeBlockedStackAssignment,\n skillMetadataUnusableDetail,\n skillMetadataUnusableError,\n} from \"../utils/messages\";\nimport { reconcileTypesFromDisk, type GateReport } from \"../lib/config-gate/index.js\";\nimport { unofferablePlacementsFound } from \"../lib/hosts/configured-placements.js\";\nimport { providerInUse } from \"../lib/installation/install-layout.js\";\nimport {\n providerFlag,\n providerNamedBy,\n refuseAnAmbiguousInstallation,\n} from \"../lib/installation/provider-flag.js\";\nimport { hostCompileNotices } from \"../lib/hosts/host-compile-notices.js\";\nimport type { Installation } from \"../lib/installation\";\nimport type { SkillScope } from \"../types/config\";\nimport type {\n AgentDefinition,\n AgentName,\n MergedSkillsMatrix,\n ProjectConfig,\n SkillDefinitionMap,\n SkillId,\n StackAgentConfig,\n} from \"../types\";\n\nexport default class Compile extends BaseCommand {\n static summary = \"Compile agents using local skills and agent definitions\";\n\n static description =\n \"Compile agents with resolved skill references. Compiles to the Claude plugin directory.\";\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --verbose\",\n ];\n\n static flags = {\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Enable verbose logging\",\n default: false,\n }),\n provider: providerFlag(),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Compile);\n setVerbose(flags.verbose);\n const cwd = process.cwd();\n\n // First: `providerInUse` below picks by roster order when a scope holds both providers.\n await refuseAnAmbiguousInstallation(\n cwd,\n \"compile\",\n providerNamedBy(flags.provider),\n (message) => this.error(message, { exit: EXIT_CODES.INVALID_ARGS }),\n );\n await this.ensureConfigReadable(cwd);\n const installations = await this.detectInstallations(cwd);\n await this.refuseUnofferablePlacements(cwd);\n await this.resolveAndLogSource(cwd);\n const agentDefs = await this.loadAgentDefsOrFail();\n await this.runCompilePasses(installations, agentDefs, cwd);\n await this.reportWhatThisHostCannotCarry(installations, cwd);\n }\n\n /** Runs after the passes, so the trust notice describes the tree this run wrote. */\n private async reportWhatThisHostCannotCarry(\n installations: BothInstallations,\n cwd: string,\n ): Promise<void> {\n const root = rootThisRunCompiled(installations, cwd);\n\n for (const notice of await hostCompileNotices(providerInUse(root), cwd)) {\n this.log(notice);\n }\n }\n\n private async detectInstallations(cwd: string): Promise<BothInstallations> {\n let installations: BothInstallations;\n try {\n installations = await detectBothInstallations(cwd);\n } catch (error) {\n // Compiling config-less would resurrect every deselected agent.\n if (error instanceof ConfigLoadError) {\n this.error(error.message, { exit: EXIT_CODES.ERROR });\n }\n throw error;\n }\n\n if (!installations.global && !installations.project) {\n this.error(ERROR_MESSAGES.NO_INSTALLATION, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n return installations;\n }\n\n /**\n * Re-checked here because config.ts names no provider, so a copied installation folder can hold\n * a configuration its host never vetted at install.\n */\n private async refuseUnofferablePlacements(cwd: string): Promise<void> {\n const [finding] = await unofferablePlacementsFound(cwd);\n if (finding !== undefined) this.error(finding, { exit: EXIT_CODES.ERROR });\n }\n\n /** No `--marketplace`: an installation recompiles against the marketplace config.ts recorded. */\n private async resolveAndLogSource(projectDir: string): Promise<void> {\n this.log(STATUS_MESSAGES.RESOLVING_SOURCE);\n try {\n // ABORT on an unreadable config (already refused earlier by `detectInstallations`).\n const sourceConfig = await resolveSource({ caller: \"stored\", projectDir });\n this.log(`Marketplace: ${sourceConfig.sourceOrigin}`);\n } catch (error) {\n this.log(ERROR_MESSAGES.FAILED_RESOLVE_SOURCE);\n this.handleError(error);\n }\n }\n\n private async loadAgentDefsOrFail(): Promise<AgentDefs> {\n this.log(STATUS_MESSAGES.LOADING_AGENT_PARTIALS);\n try {\n const defs = await loadAgentDefs();\n this.log(\"Agent partials loaded\");\n verbose(` Agents: ${defs.agentSourcePaths.agentsDir}`);\n return defs;\n } catch (error) {\n this.log(ERROR_MESSAGES.FAILED_LOAD_AGENT_PARTIALS);\n this.handleError(error);\n }\n }\n\n private async runCompilePasses(\n installations: BothInstallations,\n agentDefs: AgentDefs,\n cwd: string,\n ): Promise<void> {\n const passes = buildCompilePasses(installations, cwd, agentDefs);\n\n let passesCompiled = 0;\n for (const pass of passes) {\n const compiled = await this.runCompilePass(pass, cwd);\n if (compiled) passesCompiled++;\n }\n\n if (passesCompiled === 0) {\n this.error(ERROR_MESSAGES.NO_SKILLS_TO_COMPILE, { exit: EXIT_CODES.ERROR });\n }\n }\n\n /** Refuses the run, before anything is written, when an installed skill's metadata is unusable. */\n private async discoverAllSkills(projectDir: string): Promise<DiscoveredSkills> {\n this.log(STATUS_MESSAGES.DISCOVERING_SKILLS);\n const result = await discoverInstalledSkills(projectDir);\n if (result.unusableMetadata.length > 0) {\n this.refuseUnusableSkillMetadata(result.unusableMetadata);\n }\n if (result.totalSkillCount === 0) return result;\n this.log(formatDiscoveryMessage(result));\n return result;\n }\n\n /** Detail is logged, not raised: oclif hard-wraps error text, which breaks copyable paths. */\n private refuseUnusableSkillMetadata(entries: UnusableSkillMetadata[]): never {\n for (const entry of entries) {\n this.log(skillMetadataUnusableDetail(entry));\n }\n this.error(skillMetadataUnusableError(entries), { exit: EXIT_CODES.ERROR });\n }\n\n /** The resolver drops a missing stack skill silently except at verbose level. */\n private async warnUnresolvedStackSkills(\n projectDir: string,\n allSkills: SkillDefinitionMap,\n ): Promise<void> {\n const loaded = await loadProjectConfig(projectDir);\n if (!loaded?.config.stack) return;\n\n const excludedIds = effectivelyExcludedSkillIds(loaded.config.skills);\n const unresolved = getStackSkillIds(loaded.config.stack).filter(\n (id) => !excludedIds.has(id) && !(id in allSkills),\n );\n\n for (const id of unresolved) {\n this.warn(\n `Skill '${id}' is configured but was not found — agents will be compiled without it.`,\n );\n }\n }\n\n /**\n * A hand-edited config.ts can give a global sub-agent a project-scoped skill, which the compile\n * filter silently drops on every run.\n */\n private async warnScopeDroppedStackPairs(projectDir: string): Promise<void> {\n const loaded = await loadProjectConfig(projectDir);\n if (!loaded?.config.stack) return;\n\n for (const [skillId, agentNames] of findScopeDroppedStackPairs(loaded.config)) {\n this.warn(scopeBlockedStackAssignment(agentNames, skillId));\n }\n }\n\n /** Points at global-scope agents so \"No agents to recompile\" doesn't read as a silent no-op. */\n private async hintGlobalScopedAgents(projectDir: string): Promise<void> {\n const loaded = await loadInstalledConfig(projectDir);\n if (!loaded) return;\n\n const globalAgentCount = loaded.config.agents.filter((agent) =>\n isActiveAt(agent, \"global\"),\n ).length;\n if (globalAgentCount === 0) return;\n\n this.log(globalScopedAgentsHint(globalAgentCount));\n }\n\n /**\n * Seats the matrix singleton the render reads (else local skills lose their stated usage), and\n * returns it, `null` on failure: the render degrades, the type refresh skips. Extra sources only\n * annotate skills, so skipping them keeps output identical and the path offline.\n */\n private async seatMatrixForPass(projectDir: string): Promise<MergedSkillsMatrix | null> {\n try {\n const { matrix: seated } = await loadSkillsMatrixFromSource({\n projectDir,\n skipExtraSources: true,\n matrixOnly: true,\n });\n return seated;\n } catch (error) {\n this.warn(`Failed to load skills matrix for ${projectDir}: ${getErrorMessage(error)}`);\n return null;\n }\n }\n\n /**\n * Regenerates config-types.ts after a hand-edit; failure only warns, as the agents are written.\n * Skipped without a catalogue, since unions derived from none would be wrong, not just stale.\n */\n private async refreshConfigTypes(\n pass: CompilePass,\n cwd: string,\n seatedMatrix: MergedSkillsMatrix | null,\n ): Promise<void> {\n if (!seatedMatrix) {\n this.warn(\n configTypesRefreshFailed(`no skills catalogue could be loaded for ${pass.projectDir}`),\n );\n return;\n }\n\n let report: GateReport;\n try {\n const loaded = await loadInstalledConfig(pass.projectDir);\n if (!loaded) {\n verbose(\n `No config found at ${pass.projectDir} — skipping ${STANDARD_FILES.CONFIG_TYPES_TS} refresh`,\n );\n return;\n }\n\n // A global pass's fan-out must not reach back into the invoking directory.\n report = await reconcileTypesFromDisk(\n pass.projectDir,\n loaded.config,\n { matrix: seatedMatrix, agents: pass.agents },\n { currentProjectDir: cwd },\n );\n this.log(INFO_MESSAGES.CONFIG_TYPES_REFRESHED);\n } catch (error) {\n this.warn(configTypesRefreshFailed(getErrorMessage(error)));\n return;\n }\n\n this.reportPropagation(report);\n }\n\n /** Outside the refresh's catch: an unreachable project is not a failed refresh. */\n private reportPropagation(report: GateReport): void {\n this.reportProjectsOutOfReach(report.propagated);\n for (const projectPath of report.propagated.failed) {\n this.warn(registeredProjectUpdateFailed(projectPath));\n }\n this.reportFanOut(report);\n }\n\n private async runCompilePass(pass: CompilePass, cwd: string): Promise<boolean> {\n const { projectDir } = pass;\n this.announcePass(pass);\n\n const seatedMatrix = await this.seatMatrixForPass(projectDir);\n const { allSkills, totalSkillCount } = await this.discoverAllSkills(projectDir);\n const compiles = await this.announceWhetherPassCompiles(pass, totalSkillCount);\n // A skipped pass is a refused run, which writes nothing, config-types.ts included.\n if (!compiles) return false;\n\n await this.warnUnresolvedStackSkills(projectDir, allSkills);\n await this.warnScopeDroppedStackPairs(projectDir);\n await this.recompilePassAgents(pass, allSkills);\n await this.refreshConfigTypes(pass, cwd, seatedMatrix);\n\n this.log(\"\");\n this.logSuccess(`${pass.label} compile complete!`);\n this.log(\"\");\n return true;\n }\n\n private announcePass({ label, projectDir, installation }: CompilePass): void {\n this.log(\"\");\n this.log(`Compiling ${label.toLowerCase()} agents...`);\n this.log(\"\");\n\n verbose(` Project: ${projectDir}`);\n verbose(` Agents: ${installation.agentsDir}`);\n }\n\n /** A pass with no skills still compiles when its config declares base agents only. */\n private async announceWhetherPassCompiles(\n pass: CompilePass,\n totalSkillCount: number,\n ): Promise<boolean> {\n if (totalSkillCount > 0) return true;\n\n const passName = pass.label.toLowerCase();\n if (await declaresOnlyBaseAgents(pass)) {\n this.log(`No skills configured for ${passName} pass, compiling base agents`);\n return true;\n }\n\n this.log(`No skills found for ${passName} pass, skipping`);\n return false;\n }\n\n private async recompilePassAgents(pass: CompilePass, skills: SkillDefinitionMap): Promise<void> {\n const { projectDir, installation, sourcePath, scopeFilter } = pass;\n\n this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);\n try {\n const recompileResult = await compileAgents({\n projectDir,\n sourcePath,\n skills,\n pluginDir: projectDir,\n outputDir: installation.agentsDir,\n ...(scopeFilter !== undefined && { scopeFilter }),\n });\n await this.reportRecompile(recompileResult, pass);\n } catch (error) {\n this.log(ERROR_MESSAGES.FAILED_COMPILE_AGENTS);\n this.handleError(error);\n }\n }\n\n private async reportRecompile(\n { compiled, rewritten, failed, warnings }: CompilationResult,\n { label, projectDir }: CompilePass,\n ): Promise<void> {\n const summary = recompileSummary(\n rewritten.length,\n compiled.length - rewritten.length,\n `${label.toLowerCase()} agent`,\n );\n\n if (failed.length > 0) {\n this.log(`${summary} (${failed.length} failed)`);\n for (const warning of warnings) {\n this.warn(warning);\n }\n } else if (compiled.length > 0) {\n this.log(summary);\n } else {\n this.log(INFO_MESSAGES.NO_AGENTS_TO_RECOMPILE);\n if (label === \"Project\") {\n await this.hintGlobalScopedAgents(projectDir);\n }\n }\n\n if (compiled.length > 0) {\n verbose(` Compiled: ${compiled.join(\", \")}`);\n }\n }\n}\n\ntype CompilePass = {\n label: \"Global\" | \"Project\";\n projectDir: string;\n installation: Installation;\n sourcePath: string;\n agents: Partial<Record<AgentName, AgentDefinition>>;\n scopeFilter?: SkillScope;\n};\n\n/**\n * One pass: the project's when there is one (writing nothing outside it), else the global's.\n * `scopeFilter` keeps inlined global agents out of the project's agents directory.\n */\nfunction buildCompilePasses(\n installations: BothInstallations,\n cwd: string,\n agentDefs: AgentDefs,\n): CompilePass[] {\n const { sourcePath, agents } = agentDefs;\n\n if (installations.project) {\n return [\n {\n label: \"Project\",\n projectDir: cwd,\n installation: installations.project,\n sourcePath,\n agents,\n ...(installations.hasBoth && { scopeFilter: \"project\" as const }),\n },\n ];\n }\n\n if (installations.global) {\n return [\n {\n label: \"Global\",\n projectDir: os.homedir(),\n installation: installations.global,\n sourcePath,\n agents,\n },\n ];\n }\n\n return [];\n}\n\n/** Mirrors the root {@link buildCompilePasses} picks. */\nfunction rootThisRunCompiled(installations: BothInstallations, cwd: string): string {\n return installations.project ? cwd : os.homedir();\n}\n\n/**\n * A skill-less pass still compiles a config of base agents only. One that declares skills none of\n * which are on disk lost them, and is skipped rather than recompiled without them.\n */\nasync function declaresOnlyBaseAgents(pass: CompilePass): Promise<boolean> {\n const loaded = await loadInstalledConfig(pass.projectDir);\n if (!loaded) return false;\n\n const { skills, agents } = loaded.config;\n const declaresASkill = skills.some((skill) => !skill.excluded);\n const compilesAnAgent = agents.some((agent) =>\n pass.scopeFilter === undefined ? !agent.excluded : isActiveAt(agent, pass.scopeFilter),\n );\n return !declaresASkill && compilesAnAgent;\n}\n\n/** Project-scoped skills a global sub-agent's stack names, grouped by skill. */\nfunction findScopeDroppedStackPairs(config: ProjectConfig): [SkillId, AgentName[]][] {\n const stack = config.stack ?? {};\n const globalAgentNames = config.agents\n .filter((agent) => isActiveAt(agent, \"global\"))\n .map((agent) => agent.name);\n const projectScopedIds = unique(\n config.skills.filter((skill) => isActiveAt(skill, \"project\")).map((skill) => skill.id),\n );\n\n return projectScopedIds\n .map((skillId): [SkillId, AgentName[]] => [\n skillId,\n globalAgentNames.filter((agentName) => stackAssignsSkill(stack[agentName], skillId)),\n ])\n .filter(([, agentNames]) => agentNames.length > 0);\n}\n\nfunction stackAssignsSkill(agentStack: StackAgentConfig | undefined, skillId: SkillId): boolean {\n if (!agentStack) return false;\n return resolveAgentConfigToSkills(agentStack).some((ref) => ref.id === skillId);\n}\n\nfunction formatDiscoveryMessage(result: DiscoveredSkills): string {\n const { totalSkillCount, pluginSkillCount } = result;\n const localCount = totalSkillCount - pluginSkillCount;\n\n if (pluginSkillCount > 0 && localCount > 0) {\n return `Discovered ${plural(totalSkillCount, \"skill\")} (${pluginSkillCount} from plugins, ${localCount} local)`;\n }\n\n return pluginSkillCount > 0\n ? `Discovered ${plural(pluginSkillCount, \"skill\")} from plugins`\n : `Discovered ${plural(totalSkillCount, \"local skill\")}`;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/compile.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport os from \"os\";\nimport { unique } from \"remeda\";\nimport { BaseCommand } from \"../base-command\";\nimport { setVerbose, verbose } from \"../utils/logger\";\nimport {\n detectBothInstallations,\n type BothInstallations,\n loadAgentDefs,\n type AgentDefs,\n compileAgents,\n type CompilationResult,\n discoverInstalledSkills,\n type DiscoveredSkills,\n} from \"../lib/operations\";\nimport {\n ConfigLoadError,\n effectivelyExcludedSkillIds,\n isActiveAt,\n loadProjectConfig,\n loadInstalledConfig,\n resolveSource,\n} from \"../lib/configuration\";\nimport { getStackSkillIds, resolveAgentConfigToSkills } from \"../lib/stacks\";\nimport { loadSkillsMatrixFromSource, type UnusableSkillMetadata } from \"../lib/loading\";\nimport { STANDARD_FILES } from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { plural } from \"../utils/string\";\nimport {\n ERROR_MESSAGES,\n STATUS_MESSAGES,\n INFO_MESSAGES,\n configTypesRefreshFailed,\n globalScopedAgentsHint,\n recompileSummary,\n registeredProjectUpdateFailed,\n scopeBlockedStackAssignment,\n skillMetadataUnusableDetail,\n skillMetadataUnusableError,\n} from \"../utils/messages\";\nimport { reconcileTypesFromDisk, type GateReport } from \"../lib/config-gate/index.js\";\nimport { unofferablePlacementsFound } from \"../lib/hosts/configured-placements.js\";\nimport { providerInUse } from \"../lib/installation/install-layout.js\";\nimport {\n providerFlag,\n providerNamedBy,\n refuseAnAmbiguousInstallation,\n} from \"../lib/installation/provider-flag.js\";\nimport { hostCompileNotices } from \"../lib/hosts/host-compile-notices.js\";\nimport type { Installation } from \"../lib/installation\";\nimport type { SkillScope } from \"../types/config\";\nimport type {\n AgentDefinition,\n AgentName,\n MergedSkillsMatrix,\n ProjectConfig,\n SkillDefinitionMap,\n SkillId,\n StackAgentConfig,\n} from \"../types\";\n\nexport default class Compile extends BaseCommand {\n static summary = \"Compile agents using local skills and agent definitions\";\n\n static description =\n \"Compile agents with resolved skill references. Compiles to the Claude plugin directory.\";\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --verbose\",\n ];\n\n static flags = {\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Enable verbose logging\",\n default: false,\n }),\n provider: providerFlag(),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Compile);\n setVerbose(flags.verbose);\n const cwd = process.cwd();\n const namedProvider = providerNamedBy(flags.provider);\n\n await this.sayWhenTheGlobalInstallationStandsIn(namedProvider);\n // First: `providerInUse` below picks by roster order when a scope holds both providers.\n await refuseAnAmbiguousInstallation(cwd, \"compile\", namedProvider, (message) =>\n this.error(message, { exit: EXIT_CODES.INVALID_ARGS }),\n );\n await this.ensureConfigReadable(cwd);\n const installations = await this.detectInstallations(cwd);\n await this.refuseUnofferablePlacements(cwd);\n await this.resolveAndLogSource(cwd);\n const agentDefs = await this.loadAgentDefsOrFail();\n await this.runCompilePasses(installations, agentDefs, cwd);\n await this.reportWhatThisHostCannotCarry(installations, cwd);\n }\n\n /** Runs after the passes, so the trust notice describes the tree this run wrote. */\n private async reportWhatThisHostCannotCarry(\n installations: BothInstallations,\n cwd: string,\n ): Promise<void> {\n const root = rootThisRunCompiled(installations, cwd);\n\n for (const notice of await hostCompileNotices(providerInUse(root), cwd)) {\n this.log(notice);\n }\n }\n\n private async detectInstallations(cwd: string): Promise<BothInstallations> {\n let installations: BothInstallations;\n try {\n installations = await detectBothInstallations(cwd);\n } catch (error) {\n // Compiling config-less would resurrect every deselected agent.\n if (error instanceof ConfigLoadError) {\n this.error(error.message, { exit: EXIT_CODES.ERROR });\n }\n throw error;\n }\n\n if (!installations.global && !installations.project) {\n this.error(ERROR_MESSAGES.NO_INSTALLATION, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n return installations;\n }\n\n /**\n * Re-checked here because config.ts names no provider, so a copied installation folder can hold\n * a configuration its host never vetted at install.\n */\n private async refuseUnofferablePlacements(cwd: string): Promise<void> {\n const [finding] = await unofferablePlacementsFound(cwd);\n if (finding !== undefined) this.error(finding, { exit: EXIT_CODES.ERROR });\n }\n\n /** No `--marketplace`: an installation recompiles against the marketplace config.ts recorded. */\n private async resolveAndLogSource(projectDir: string): Promise<void> {\n this.log(STATUS_MESSAGES.RESOLVING_SOURCE);\n try {\n // ABORT on an unreadable config (already refused earlier by `detectInstallations`).\n const sourceConfig = await resolveSource({ caller: \"stored\", projectDir });\n this.log(`Marketplace: ${sourceConfig.sourceOrigin}`);\n } catch (error) {\n this.log(ERROR_MESSAGES.FAILED_RESOLVE_SOURCE);\n this.handleError(error);\n }\n }\n\n private async loadAgentDefsOrFail(): Promise<AgentDefs> {\n this.log(STATUS_MESSAGES.LOADING_AGENT_PARTIALS);\n try {\n const defs = await loadAgentDefs();\n this.log(\"Agent partials loaded\");\n verbose(` Agents: ${defs.agentSourcePaths.agentsDir}`);\n return defs;\n } catch (error) {\n this.log(ERROR_MESSAGES.FAILED_LOAD_AGENT_PARTIALS);\n this.handleError(error);\n }\n }\n\n private async runCompilePasses(\n installations: BothInstallations,\n agentDefs: AgentDefs,\n cwd: string,\n ): Promise<void> {\n const passes = buildCompilePasses(installations, cwd, agentDefs);\n\n let passesCompiled = 0;\n for (const pass of passes) {\n const compiled = await this.runCompilePass(pass, cwd);\n if (compiled) passesCompiled++;\n }\n\n if (passesCompiled === 0) {\n this.error(ERROR_MESSAGES.NO_SKILLS_TO_COMPILE, { exit: EXIT_CODES.ERROR });\n }\n }\n\n /** Refuses the run, before anything is written, when an installed skill's metadata is unusable. */\n private async discoverAllSkills(projectDir: string): Promise<DiscoveredSkills> {\n this.log(STATUS_MESSAGES.DISCOVERING_SKILLS);\n const result = await discoverInstalledSkills(projectDir);\n if (result.unusableMetadata.length > 0) {\n this.refuseUnusableSkillMetadata(result.unusableMetadata);\n }\n if (result.totalSkillCount === 0) return result;\n this.log(formatDiscoveryMessage(result));\n return result;\n }\n\n /** Detail is logged, not raised: oclif hard-wraps error text, which breaks copyable paths. */\n private refuseUnusableSkillMetadata(entries: UnusableSkillMetadata[]): never {\n for (const entry of entries) {\n this.log(skillMetadataUnusableDetail(entry));\n }\n this.error(skillMetadataUnusableError(entries), { exit: EXIT_CODES.ERROR });\n }\n\n /** The resolver drops a missing stack skill silently except at verbose level. */\n private async warnUnresolvedStackSkills(\n projectDir: string,\n allSkills: SkillDefinitionMap,\n ): Promise<void> {\n const loaded = await loadProjectConfig(projectDir);\n if (!loaded?.config.stack) return;\n\n const excludedIds = effectivelyExcludedSkillIds(loaded.config.skills);\n const unresolved = getStackSkillIds(loaded.config.stack).filter(\n (id) => !excludedIds.has(id) && !(id in allSkills),\n );\n\n for (const id of unresolved) {\n this.warn(\n `Skill '${id}' is configured but was not found — agents will be compiled without it.`,\n );\n }\n }\n\n /**\n * A hand-edited config.ts can give a global sub-agent a project-scoped skill, which the compile\n * filter silently drops on every run.\n */\n private async warnScopeDroppedStackPairs(projectDir: string): Promise<void> {\n const loaded = await loadProjectConfig(projectDir);\n if (!loaded?.config.stack) return;\n\n for (const [skillId, agentNames] of findScopeDroppedStackPairs(loaded.config)) {\n this.warn(scopeBlockedStackAssignment(agentNames, skillId));\n }\n }\n\n /** Points at global-scope agents so \"No agents to recompile\" doesn't read as a silent no-op. */\n private async hintGlobalScopedAgents(projectDir: string): Promise<void> {\n const loaded = await loadInstalledConfig(projectDir);\n if (!loaded) return;\n\n const globalAgentCount = loaded.config.agents.filter((agent) =>\n isActiveAt(agent, \"global\"),\n ).length;\n if (globalAgentCount === 0) return;\n\n this.log(globalScopedAgentsHint(globalAgentCount));\n }\n\n /**\n * Seats the matrix singleton the render reads (else local skills lose their stated usage), and\n * returns it, `null` on failure: the render degrades, the type refresh skips. Extra sources only\n * annotate skills, so skipping them keeps output identical and the path offline.\n */\n private async seatMatrixForPass(projectDir: string): Promise<MergedSkillsMatrix | null> {\n try {\n const { matrix: seated } = await loadSkillsMatrixFromSource({\n projectDir,\n skipExtraSources: true,\n matrixOnly: true,\n });\n return seated;\n } catch (error) {\n this.warn(`Failed to load skills matrix for ${projectDir}: ${getErrorMessage(error)}`);\n return null;\n }\n }\n\n /**\n * Regenerates config-types.ts after a hand-edit; failure only warns, as the agents are written.\n * Skipped without a catalogue, since unions derived from none would be wrong, not just stale.\n */\n private async refreshConfigTypes(\n pass: CompilePass,\n cwd: string,\n seatedMatrix: MergedSkillsMatrix | null,\n ): Promise<void> {\n if (!seatedMatrix) {\n this.warn(\n configTypesRefreshFailed(`no skills catalogue could be loaded for ${pass.projectDir}`),\n );\n return;\n }\n\n let report: GateReport;\n try {\n const loaded = await loadInstalledConfig(pass.projectDir);\n if (!loaded) {\n verbose(\n `No config found at ${pass.projectDir} — skipping ${STANDARD_FILES.CONFIG_TYPES_TS} refresh`,\n );\n return;\n }\n\n // A global pass's fan-out must not reach back into the invoking directory.\n report = await reconcileTypesFromDisk(\n pass.projectDir,\n loaded.config,\n { matrix: seatedMatrix, agents: pass.agents },\n { currentProjectDir: cwd },\n );\n this.log(INFO_MESSAGES.CONFIG_TYPES_REFRESHED);\n } catch (error) {\n this.warn(configTypesRefreshFailed(getErrorMessage(error)));\n return;\n }\n\n this.reportPropagation(report);\n }\n\n /** Outside the refresh's catch: an unreachable project is not a failed refresh. */\n private reportPropagation(report: GateReport): void {\n this.reportProjectsOutOfReach(report.propagated);\n for (const projectPath of report.propagated.failed) {\n this.warn(registeredProjectUpdateFailed(projectPath));\n }\n this.reportFanOut(report);\n }\n\n private async runCompilePass(pass: CompilePass, cwd: string): Promise<boolean> {\n const { projectDir } = pass;\n this.announcePass(pass);\n\n const seatedMatrix = await this.seatMatrixForPass(projectDir);\n const { allSkills, totalSkillCount } = await this.discoverAllSkills(projectDir);\n const compiles = await this.announceWhetherPassCompiles(pass, totalSkillCount);\n // A skipped pass is a refused run, which writes nothing, config-types.ts included.\n if (!compiles) return false;\n\n await this.warnUnresolvedStackSkills(projectDir, allSkills);\n await this.warnScopeDroppedStackPairs(projectDir);\n await this.recompilePassAgents(pass, allSkills);\n await this.refreshConfigTypes(pass, cwd, seatedMatrix);\n\n this.log(\"\");\n this.logSuccess(`${pass.label} compile complete!`);\n this.log(\"\");\n return true;\n }\n\n private announcePass({ label, projectDir, installation }: CompilePass): void {\n this.log(\"\");\n this.log(`Compiling ${label.toLowerCase()} agents...`);\n this.log(\"\");\n\n verbose(` Project: ${projectDir}`);\n verbose(` Agents: ${installation.agentsDir}`);\n }\n\n /** A pass with no skills still compiles when its config declares base agents only. */\n private async announceWhetherPassCompiles(\n pass: CompilePass,\n totalSkillCount: number,\n ): Promise<boolean> {\n if (totalSkillCount > 0) return true;\n\n const passName = pass.label.toLowerCase();\n if (await declaresOnlyBaseAgents(pass)) {\n this.log(`No skills configured for ${passName} pass, compiling base agents`);\n return true;\n }\n\n this.log(`No skills found for ${passName} pass, skipping`);\n return false;\n }\n\n private async recompilePassAgents(pass: CompilePass, skills: SkillDefinitionMap): Promise<void> {\n const { projectDir, installation, sourcePath, scopeFilter } = pass;\n\n this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);\n try {\n const recompileResult = await compileAgents({\n projectDir,\n sourcePath,\n skills,\n pluginDir: projectDir,\n outputDir: installation.agentsDir,\n ...(scopeFilter !== undefined && { scopeFilter }),\n });\n await this.reportRecompile(recompileResult, pass);\n } catch (error) {\n this.log(ERROR_MESSAGES.FAILED_COMPILE_AGENTS);\n this.handleError(error);\n }\n }\n\n private async reportRecompile(\n { compiled, rewritten, failed, warnings }: CompilationResult,\n { label, projectDir }: CompilePass,\n ): Promise<void> {\n const summary = recompileSummary(\n rewritten.length,\n compiled.length - rewritten.length,\n `${label.toLowerCase()} agent`,\n );\n\n if (failed.length > 0) {\n this.log(`${summary} (${failed.length} failed)`);\n for (const warning of warnings) {\n this.warn(warning);\n }\n } else if (compiled.length > 0) {\n this.log(summary);\n } else {\n this.log(INFO_MESSAGES.NO_AGENTS_TO_RECOMPILE);\n if (label === \"Project\") {\n await this.hintGlobalScopedAgents(projectDir);\n }\n }\n\n if (compiled.length > 0) {\n verbose(` Compiled: ${compiled.join(\", \")}`);\n }\n }\n}\n\ntype CompilePass = {\n label: \"Global\" | \"Project\";\n projectDir: string;\n installation: Installation;\n sourcePath: string;\n agents: Partial<Record<AgentName, AgentDefinition>>;\n scopeFilter?: SkillScope;\n};\n\n/**\n * One pass: the project's when there is one (writing nothing outside it), else the global's.\n * `scopeFilter` keeps inlined global agents out of the project's agents directory.\n */\nfunction buildCompilePasses(\n installations: BothInstallations,\n cwd: string,\n agentDefs: AgentDefs,\n): CompilePass[] {\n const { sourcePath, agents } = agentDefs;\n\n if (installations.project) {\n return [\n {\n label: \"Project\",\n projectDir: cwd,\n installation: installations.project,\n sourcePath,\n agents,\n ...(installations.hasBoth && { scopeFilter: \"project\" as const }),\n },\n ];\n }\n\n if (installations.global) {\n return [\n {\n label: \"Global\",\n projectDir: os.homedir(),\n installation: installations.global,\n sourcePath,\n agents,\n },\n ];\n }\n\n return [];\n}\n\n/** Mirrors the root {@link buildCompilePasses} picks. */\nfunction rootThisRunCompiled(installations: BothInstallations, cwd: string): string {\n return installations.project ? cwd : os.homedir();\n}\n\n/**\n * A skill-less pass still compiles a config of base agents only. One that declares skills none of\n * which are on disk lost them, and is skipped rather than recompiled without them.\n */\nasync function declaresOnlyBaseAgents(pass: CompilePass): Promise<boolean> {\n const loaded = await loadInstalledConfig(pass.projectDir);\n if (!loaded) return false;\n\n const { skills, agents } = loaded.config;\n const declaresASkill = skills.some((skill) => !skill.excluded);\n const compilesAnAgent = agents.some((agent) =>\n pass.scopeFilter === undefined ? !agent.excluded : isActiveAt(agent, pass.scopeFilter),\n );\n return !declaresASkill && compilesAnAgent;\n}\n\n/** Project-scoped skills a global sub-agent's stack names, grouped by skill. */\nfunction findScopeDroppedStackPairs(config: ProjectConfig): [SkillId, AgentName[]][] {\n const stack = config.stack ?? {};\n const globalAgentNames = config.agents\n .filter((agent) => isActiveAt(agent, \"global\"))\n .map((agent) => agent.name);\n const projectScopedIds = unique(\n config.skills.filter((skill) => isActiveAt(skill, \"project\")).map((skill) => skill.id),\n );\n\n return projectScopedIds\n .map((skillId): [SkillId, AgentName[]] => [\n skillId,\n globalAgentNames.filter((agentName) => stackAssignsSkill(stack[agentName], skillId)),\n ])\n .filter(([, agentNames]) => agentNames.length > 0);\n}\n\nfunction stackAssignsSkill(agentStack: StackAgentConfig | undefined, skillId: SkillId): boolean {\n if (!agentStack) return false;\n return resolveAgentConfigToSkills(agentStack).some((ref) => ref.id === skillId);\n}\n\nfunction formatDiscoveryMessage(result: DiscoveredSkills): string {\n const { totalSkillCount, pluginSkillCount } = result;\n const localCount = totalSkillCount - pluginSkillCount;\n\n if (pluginSkillCount > 0 && localCount > 0) {\n return `Discovered ${plural(totalSkillCount, \"skill\")} (${pluginSkillCount} from plugins, ${localCount} local)`;\n }\n\n return pluginSkillCount > 0\n ? `Discovered ${plural(pluginSkillCount, \"skill\")} from plugins`\n : `Discovered ${plural(totalSkillCount, \"local skill\")}`;\n}\n"],"mappings":"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","names":[]}
@@ -1,18 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import "../chunk-IXVGBUWI.js";
2
+ import "../chunk-SI2LLEIR.js";
3
3
  import {
4
4
  filterExcludedEntries,
5
5
  listAgentFilesOf,
6
6
  listAgentMdFiles,
7
7
  splitAgentsByProvenance
8
- } from "../chunk-EFXVYQGT.js";
9
- import {
10
- ambiguityFinding
11
- } from "../chunk-ORO2T4K2.js";
8
+ } from "../chunk-GNMRXXRY.js";
12
9
  import {
13
10
  BaseCommand,
14
- EXIT_CODES
15
- } from "../chunk-IAQFZFWD.js";
11
+ EXIT_CODES,
12
+ ambiguityFinding
13
+ } from "../chunk-37QFHJUW.js";
16
14
  import {
17
15
  ConfigDefaultExportError,
18
16
  ConfigLoadError,
@@ -26,7 +24,8 @@ import {
26
24
  agentYamlGenerationSchema,
27
25
  agentsDir,
28
26
  askingEachMarketplaceItself,
29
- configDirsInPlay,
27
+ configsDeclaringNothing,
28
+ configsInPlay,
30
29
  declaresNoContent,
31
30
  detectInstallations,
32
31
  directoryExists,
@@ -34,15 +33,16 @@ import {
34
33
  findConfigLoadFailures,
35
34
  formatZodErrors,
36
35
  getErrorMessage,
37
- getInstalledConfigPath,
38
36
  getInstalledPluginsRegistryPath,
39
- getPluginManifestPath,
37
+ getProjectConfigPath,
40
38
  getProjectPluginsDir,
41
39
  getStackSkillIds,
42
40
  getUserPluginsDir,
41
+ getVerifiedPluginInstallPaths,
43
42
  glob,
44
43
  hostCompilesAgent,
45
44
  hostFor,
45
+ inheritedGlobalProvider,
46
46
  installBaseDir,
47
47
  invalidResult,
48
48
  isHomeDirectory,
@@ -53,7 +53,6 @@ import {
53
53
  listPluginDirNames,
54
54
  listRegisteredPluginInstalls,
55
55
  loadConfig,
56
- loadInstalledConfig,
57
56
  loadProjectConfigFromDir,
58
57
  loadSkillsMatrixFromSource,
59
58
  loadSourceRepoConfig,
@@ -89,14 +88,13 @@ import {
89
88
  validatePlugin,
90
89
  validateProjectConfig,
91
90
  validateSkillFrontmatter,
92
- validateSkillMetadata,
93
- verbose
94
- } from "../chunk-E45IT3HC.js";
91
+ validateSkillMetadata
92
+ } from "../chunk-YM3VEDAP.js";
95
93
  import {
96
94
  matrix,
97
95
  plural,
98
96
  typedValues
99
- } from "../chunk-AIBVAYHS.js";
97
+ } from "../chunk-TG3SPPZY.js";
100
98
  import {
101
99
  CLI_INVOKE_COMMAND,
102
100
  DEFAULT_BRANDING,
@@ -111,7 +109,7 @@ import {
111
109
  STANDARD_FILES,
112
110
  UI_SYMBOLS,
113
111
  effectivelyExcludedSkillIds
114
- } from "../chunk-WUSEZFER.js";
112
+ } from "../chunk-U46LYYRA.js";
115
113
  import "../chunk-GHHJYNAN.js";
116
114
 
117
115
  // src/cli/commands/doctor.ts
@@ -123,18 +121,11 @@ import os from "os";
123
121
  async function hostsOnDisk(projectDir) {
124
122
  const found = await detectInstallations(projectDir);
125
123
  if (inheritsTheGlobalInstallation(found)) return hostsOf(providerInUse(os.homedir()));
126
- const project = providerInUse(projectDir);
127
- return { project, global: globalBeside(project, found) };
124
+ return { project: providerInUse(projectDir), global: inheritedGlobalProvider(projectDir) };
128
125
  }
129
126
  function inheritsTheGlobalInstallation(found) {
130
127
  return found.length > 0 && found.every((installation) => installation.scope === "global");
131
128
  }
132
- function globalBeside(project, found) {
133
- const inherited = found.some(
134
- (installation) => installation.scope === "global" && installation.provider === project
135
- );
136
- return inherited ? project : providerInUse(os.homedir());
137
- }
138
129
  function hostsOf(provider) {
139
130
  return { project: provider, global: provider };
140
131
  }
@@ -162,29 +153,23 @@ async function readConfigState(projectDir, hosts) {
162
153
  }
163
154
  const inherited = isHomeDirectory(projectDir) ? null : await loadProjectConfigFromDir(os.homedir(), hosts.global);
164
155
  if (inherited && !declaresNoContent(inherited.config)) {
165
- return { kind: "loaded", config: inherited.config, inherited: true };
156
+ return {
157
+ kind: "loaded",
158
+ config: inherited.config,
159
+ inherited: true,
160
+ declaringNothingIn: await providerDeclaringNothingIn(projectDir)
161
+ };
166
162
  }
167
163
  return own ? { kind: "declares-nothing", config: own.config } : { kind: "absent" };
168
164
  }
165
+ async function providerDeclaringNothingIn(projectDir) {
166
+ const [leftover] = await configsDeclaringNothing(projectDir);
167
+ return leftover === void 0 ? null : leftover.provider;
168
+ }
169
169
  async function installedPluginSkillIds(baseDir, provider) {
170
- const plugins = await verifiedPlugins(baseDir, provider);
170
+ const plugins = await getVerifiedPluginInstallPaths(baseDir, provider);
171
171
  return new Set(plugins.map((plugin) => parseMarketplacePluginRef(plugin.pluginKey)));
172
172
  }
173
- async function verifiedPlugins(baseDir, provider) {
174
- const enabled = (await pluginsListedBy(provider, baseDir)).filter((plugin) => plugin.enabled);
175
- const onDisk = await Promise.all(
176
- enabled.map((plugin) => fileExists(getPluginManifestPath(plugin.installPath)))
177
- );
178
- return enabled.filter((_, index) => onDisk[index] === true);
179
- }
180
- async function pluginsListedBy(provider, baseDir) {
181
- try {
182
- return await hostFor(provider).listPlugins(baseDir);
183
- } catch (error) {
184
- verbose(`Failed to list installed plugins: ${getErrorMessage(error)}`);
185
- return [];
186
- }
187
- }
188
173
  async function unofferablePlacements({
189
174
  projectDir,
190
175
  hosts
@@ -572,7 +557,9 @@ function toUnreadableConfigIssue(failure) {
572
557
  }
573
558
  async function countExistingConfigs(projectDir) {
574
559
  const present = await Promise.all(
575
- configDirsInPlay(projectDir).map((dir) => fileExists(getInstalledConfigPath(dir)))
560
+ configsInPlay(projectDir).map(
561
+ ({ dir, provider }) => fileExists(getProjectConfigPath(dir, provider))
562
+ )
576
563
  );
577
564
  return present.filter(Boolean).length;
578
565
  }
@@ -676,7 +663,7 @@ async function validateInstalledSkills(projectDir) {
676
663
  }
677
664
  async function configuredSkillIds(projectDir) {
678
665
  const loaded = await Promise.all(
679
- configDirsInPlay(projectDir).map((dir) => loadInstalledConfig(dir))
666
+ configsInPlay(projectDir).map(({ dir, provider }) => loadProjectConfigFromDir(dir, provider))
680
667
  );
681
668
  return new Set(loaded.flatMap(configuredIdsOf));
682
669
  }
@@ -863,39 +850,45 @@ async function unclaimedAgentFiles({ dir, codec, claimed: claimed2 }) {
863
850
  import { countBy, unique as unique2 } from "remeda";
864
851
  function checkConfigValid(state, installation) {
865
852
  const theConfig = (verdict) => configRowMessage(state, installation, verdict);
866
- if (state.kind === "absent") {
867
- return {
868
- result: {
869
- kind: "config",
870
- status: "fail",
871
- message: theConfig("not found"),
872
- details: [`Run '${CLI_INVOKE_COMMAND} init' to create a configuration`]
873
- },
874
- config: null
875
- };
876
- }
877
- if (state.kind === "unreadable") {
878
- return {
879
- result: {
880
- kind: "config",
881
- status: "fail",
882
- message: theConfig("exists but could not be loaded"),
883
- details: [state.failure.reason]
884
- },
885
- config: null
886
- };
887
- }
888
- if (state.kind === "declares-nothing") {
889
- return {
890
- result: {
891
- kind: "config-empty",
892
- status: "warn",
893
- message: theConfig("is valid but declares no skills and no agents")
894
- },
895
- config: state.config
896
- };
853
+ switch (state.kind) {
854
+ case "absent":
855
+ return {
856
+ result: {
857
+ kind: "config",
858
+ status: "fail",
859
+ message: theConfig("not found"),
860
+ details: [`Run '${CLI_INVOKE_COMMAND} init' to create a configuration`]
861
+ },
862
+ config: null
863
+ };
864
+ case "unreadable":
865
+ return {
866
+ result: {
867
+ kind: "config",
868
+ status: "fail",
869
+ message: theConfig("exists but could not be loaded"),
870
+ details: [state.failure.reason]
871
+ },
872
+ config: null
873
+ };
874
+ case "declares-nothing":
875
+ return {
876
+ result: {
877
+ kind: "config-empty",
878
+ status: "warn",
879
+ message: theConfig("is valid but declares no skills and no agents")
880
+ },
881
+ config: state.config
882
+ };
883
+ case "loaded":
884
+ return checkLoadedConfig(state.config, theConfig);
885
+ default: {
886
+ const _exhaustive = state;
887
+ return _exhaustive;
888
+ }
897
889
  }
898
- const { config } = state;
890
+ }
891
+ function checkLoadedConfig(config, theConfig) {
899
892
  const validation = validateProjectConfig(config);
900
893
  if (!validation.valid) {
901
894
  return {
@@ -930,7 +923,7 @@ function checkConfigValid(state, installation) {
930
923
  }
931
924
  function configRowMessage(state, { projectDir, hosts }, verdict) {
932
925
  if (state.kind === "loaded" && state.inherited)
933
- return `${theInheritedConfig(hosts.global)}, which ${verdict}`;
926
+ return `${theInheritedConfig(projectDir, state.declaringNothingIn, hosts.global)}, which ${verdict}`;
934
927
  if (state.kind === "unreadable") {
935
928
  const { scopeRoot, scope } = state.failure;
936
929
  return `${theConfigAt(scopeRoot, hosts[scope])} ${verdict}`;
@@ -940,8 +933,9 @@ function configRowMessage(state, { projectDir, hosts }, verdict) {
940
933
  function theConfigAt(root, provider) {
941
934
  return `${scopeLabel(scopeOf(root))}: ${configNamedFrom(root, provider)}`;
942
935
  }
943
- function theInheritedConfig(provider) {
944
- return `${scopeLabel("project")}: no ${STANDARD_FILES.CONFIG_TS}, using ${scopeNoun("global")}'s (${configNamedFrom(os3.homedir(), provider)})`;
936
+ function theInheritedConfig(projectDir, declaringNothingIn, provider) {
937
+ const projectHolds = declaringNothingIn === null ? `no ${STANDARD_FILES.CONFIG_TS}` : `${relativeConfigPath(projectDir, declaringNothingIn)} declares nothing`;
938
+ return `${scopeLabel("project")}: ${projectHolds}, using ${scopeNoun("global")}'s (${configNamedFrom(os3.homedir(), provider)})`;
945
939
  }
946
940
  function scopeOf(dir) {
947
941
  return isHomeDirectory(dir) ? "global" : "project";
@@ -1466,6 +1460,7 @@ var Doctor = class _Doctor extends BaseCommand {
1466
1460
  async run() {
1467
1461
  await this.parse(_Doctor);
1468
1462
  const projectDir = process.cwd();
1463
+ await this.sayWhenTheGlobalInstallationStandsIn(void 0);
1469
1464
  this.printHeader(await this.resolveBrandingName(projectDir));
1470
1465
  const contentResults = await this.runContentChecks(projectDir);
1471
1466
  const operationalResults = await this.runOperationalChecks(projectDir, contentResults);