agents-inc 0.174.0 → 0.176.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +115 -0
- package/dist/{chunk-APWMMZOK.js → chunk-3F5LT433.js} +157 -53
- package/dist/chunk-3F5LT433.js.map +1 -0
- package/dist/chunk-5CFHP6Z5.js +109 -0
- package/dist/chunk-5CFHP6Z5.js.map +1 -0
- package/dist/{chunk-3PJZ4QNJ.js → chunk-B7AVWSK2.js} +21 -11
- package/dist/chunk-B7AVWSK2.js.map +1 -0
- package/dist/{chunk-H5E6IO2L.js → chunk-C2BSCEDN.js} +9 -11
- package/dist/chunk-C2BSCEDN.js.map +1 -0
- package/dist/{chunk-R7GKQBZJ.js → chunk-CKBWEWHZ.js} +96 -52
- package/dist/chunk-CKBWEWHZ.js.map +1 -0
- package/dist/{chunk-IXVGBUWI.js → chunk-EC3JXT23.js} +5 -5
- package/dist/{chunk-E45IT3HC.js → chunk-ENET4IF6.js} +998 -472
- package/dist/chunk-ENET4IF6.js.map +1 -0
- package/dist/{chunk-FQF6VHO3.js → chunk-FACDJH6O.js} +12 -105
- package/dist/chunk-FACDJH6O.js.map +1 -0
- package/dist/{chunk-TVEDNGVP.js → chunk-H6WUOW5F.js} +2 -2
- package/dist/{chunk-7BHDKEGK.js → chunk-JNRACLNS.js} +3 -3
- package/dist/{chunk-IAQFZFWD.js → chunk-JTMSFBCA.js} +231 -24
- package/dist/chunk-JTMSFBCA.js.map +1 -0
- package/dist/{chunk-EFXVYQGT.js → chunk-MQZNDK5F.js} +39 -40
- package/dist/chunk-MQZNDK5F.js.map +1 -0
- package/dist/{chunk-QCX66KBM.js → chunk-SN64WNWE.js} +3 -3
- package/dist/{chunk-WUSEZFER.js → chunk-U46LYYRA.js} +3 -2
- package/dist/{chunk-WUSEZFER.js.map → chunk-U46LYYRA.js.map} +1 -1
- package/dist/{chunk-6PGXTLA4.js → chunk-U672FZVC.js} +2 -2
- package/dist/{chunk-AIBVAYHS.js → chunk-UE4Z3YMB.js} +2 -2
- package/dist/chunk-UE4Z3YMB.js.map +1 -0
- package/dist/{chunk-REHVGFJE.js → chunk-XMQIWPIR.js} +84 -32
- package/dist/chunk-XMQIWPIR.js.map +1 -0
- package/dist/{chunk-I3WF6L43.js → chunk-XYBHH3M5.js} +2 -2
- package/dist/{chunk-ECPFYHDX.js → chunk-ZBI6GFJD.js} +11 -11
- package/dist/chunk-ZBI6GFJD.js.map +1 -0
- package/dist/commands/build/marketplace.js +5 -4
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +7 -6
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/compile.js +20 -16
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +106 -87
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +76 -48
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +31 -18
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +17 -17
- package/dist/commands/list.js +10 -9
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +5 -4
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/search.js +14 -9
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +20 -22
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/uninstall.js +24 -19
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +110 -31
- package/dist/commands/update.js.map +1 -1
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/common/skill-agent-summary.js +4 -3
- package/dist/components/common/summary-panel.js +5 -4
- package/dist/hooks/init.js +24 -25
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-5BSECHE6.js +14 -0
- package/dist/{recompile-project-agents-KYK44C24.js → recompile-project-agents-U3UGHPWG.js} +8 -8
- package/dist/{source-loader-G5I4RNUP.js → source-loader-E2Y5MMN5.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-3PJZ4QNJ.js.map +0 -1
- package/dist/chunk-AIBVAYHS.js.map +0 -1
- package/dist/chunk-APWMMZOK.js.map +0 -1
- package/dist/chunk-E45IT3HC.js.map +0 -1
- package/dist/chunk-ECPFYHDX.js.map +0 -1
- package/dist/chunk-EFXVYQGT.js.map +0 -1
- package/dist/chunk-FQF6VHO3.js.map +0 -1
- package/dist/chunk-H5E6IO2L.js.map +0 -1
- package/dist/chunk-IAQFZFWD.js.map +0 -1
- package/dist/chunk-ORO2T4K2.js +0 -96
- package/dist/chunk-ORO2T4K2.js.map +0 -1
- package/dist/chunk-R7GKQBZJ.js.map +0 -1
- package/dist/chunk-REHVGFJE.js.map +0 -1
- package/dist/load-agent-defs-5U5KAURA.js +0 -14
- /package/dist/{chunk-IXVGBUWI.js.map → chunk-EC3JXT23.js.map} +0 -0
- /package/dist/{chunk-TVEDNGVP.js.map → chunk-H6WUOW5F.js.map} +0 -0
- /package/dist/{chunk-7BHDKEGK.js.map → chunk-JNRACLNS.js.map} +0 -0
- /package/dist/{chunk-QCX66KBM.js.map → chunk-SN64WNWE.js.map} +0 -0
- /package/dist/{chunk-6PGXTLA4.js.map → chunk-U672FZVC.js.map} +0 -0
- /package/dist/{chunk-I3WF6L43.js.map → chunk-XYBHH3M5.js.map} +0 -0
- /package/dist/{load-agent-defs-5U5KAURA.js.map → load-agent-defs-5BSECHE6.js.map} +0 -0
- /package/dist/{recompile-project-agents-KYK44C24.js.map → recompile-project-agents-U3UGHPWG.js.map} +0 -0
- /package/dist/{source-loader-G5I4RNUP.js.map → source-loader-E2Y5MMN5.js.map} +0 -0
package/dist/commands/compile.js
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
unofferablePlacementsFound
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-ZBI6GFJD.js";
|
|
5
5
|
import {
|
|
6
6
|
hostCompileNotices
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-U672FZVC.js";
|
|
8
8
|
import {
|
|
9
9
|
detectBothInstallations,
|
|
10
10
|
reconcileTypesFromDisk
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-CKBWEWHZ.js";
|
|
12
12
|
import {
|
|
13
13
|
compileAgents,
|
|
14
14
|
discoverInstalledSkills
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-XMQIWPIR.js";
|
|
16
16
|
import {
|
|
17
17
|
loadAgentDefs
|
|
18
|
-
} from "../chunk-
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
18
|
+
} from "../chunk-JNRACLNS.js";
|
|
19
|
+
import "../chunk-EC3JXT23.js";
|
|
20
|
+
import "../chunk-MQZNDK5F.js";
|
|
21
21
|
import {
|
|
22
|
+
BaseCommand,
|
|
23
|
+
EXIT_CODES,
|
|
22
24
|
providerFlag,
|
|
23
25
|
providerNamedBy,
|
|
24
26
|
refuseAnAmbiguousInstallation
|
|
25
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-JTMSFBCA.js";
|
|
26
28
|
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
} from "../chunk-IAQFZFWD.js";
|
|
29
|
+
namedByActiveEntries
|
|
30
|
+
} from "../chunk-FACDJH6O.js";
|
|
30
31
|
import {
|
|
31
32
|
ConfigLoadError,
|
|
32
33
|
ERROR_MESSAGES,
|
|
@@ -49,15 +50,15 @@ import {
|
|
|
49
50
|
skillMetadataUnusableDetail,
|
|
50
51
|
skillMetadataUnusableError,
|
|
51
52
|
verbose
|
|
52
|
-
} from "../chunk-
|
|
53
|
+
} from "../chunk-ENET4IF6.js";
|
|
53
54
|
import {
|
|
54
55
|
plural
|
|
55
|
-
} from "../chunk-
|
|
56
|
+
} from "../chunk-UE4Z3YMB.js";
|
|
56
57
|
import {
|
|
57
58
|
STANDARD_FILES,
|
|
58
59
|
effectivelyExcludedSkillIds,
|
|
59
60
|
isActiveAt
|
|
60
|
-
} from "../chunk-
|
|
61
|
+
} from "../chunk-U46LYYRA.js";
|
|
61
62
|
import "../chunk-GHHJYNAN.js";
|
|
62
63
|
|
|
63
64
|
// src/cli/commands/compile.ts
|
|
@@ -83,10 +84,12 @@ var Compile = class _Compile extends BaseCommand {
|
|
|
83
84
|
const { flags } = await this.parse(_Compile);
|
|
84
85
|
setVerbose(flags.verbose);
|
|
85
86
|
const cwd = process.cwd();
|
|
87
|
+
const namedProvider = providerNamedBy(flags.provider);
|
|
88
|
+
await this.sayWhenTheGlobalInstallationStandsIn(namedProvider);
|
|
86
89
|
await refuseAnAmbiguousInstallation(
|
|
87
90
|
cwd,
|
|
88
91
|
"compile",
|
|
89
|
-
|
|
92
|
+
namedProvider,
|
|
90
93
|
(message) => this.error(message, { exit: EXIT_CODES.INVALID_ARGS })
|
|
91
94
|
);
|
|
92
95
|
await this.ensureConfigReadable(cwd);
|
|
@@ -202,8 +205,9 @@ var Compile = class _Compile extends BaseCommand {
|
|
|
202
205
|
async warnScopeDroppedStackPairs(projectDir) {
|
|
203
206
|
const loaded = await loadProjectConfig(projectDir);
|
|
204
207
|
if (!loaded?.config.stack) return;
|
|
208
|
+
const namedBy = namedByActiveEntries(loaded.config.skills);
|
|
205
209
|
for (const [skillId, agentNames] of findScopeDroppedStackPairs(loaded.config)) {
|
|
206
|
-
this.warn(scopeBlockedStackAssignment(agentNames, skillId));
|
|
210
|
+
this.warn(scopeBlockedStackAssignment(agentNames, skillId, namedBy));
|
|
207
211
|
}
|
|
208
212
|
}
|
|
209
213
|
/** Points at global-scope agents so "No agents to recompile" doesn't read as a silent no-op. */
|
|
@@ -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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,aAAa;AACtB,OAAO,QAAQ;AACf,SAAS,cAAc;AA4DvB,IAAqB,UAArB,MAAqB,iBAAgB,YAAY;AAAA,EAC/C,OAAO,UAAU;AAAA,EAEjB,OAAO,cACL;AAAA,EAEF,OAAO,WAAW;AAAA,IAChB;AAAA,IACA;AAAA,EACF;AAAA,EAEA,OAAO,QAAQ;AAAA,IACb,SAAS,MAAM,QAAQ;AAAA,MACrB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,IACD,UAAU,aAAa;AAAA,EACzB;AAAA,EAEA,MAAM,MAAqB;AACzB,UAAM,EAAE,MAAM,IAAI,MAAM,KAAK,MAAM,QAAO;AAC1C,eAAW,MAAM,OAAO;AACxB,UAAM,MAAM,QAAQ,IAAI;AAGxB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,gBAAgB,MAAM,QAAQ;AAAA,MAC9B,CAAC,YAAY,KAAK,MAAM,SAAS,EAAE,MAAM,WAAW,aAAa,CAAC;AAAA,IACpE;AACA,UAAM,KAAK,qBAAqB,GAAG;AACnC,UAAM,gBAAgB,MAAM,KAAK,oBAAoB,GAAG;AACxD,UAAM,KAAK,4BAA4B,GAAG;AAC1C,UAAM,KAAK,oBAAoB,GAAG;AAClC,UAAM,YAAY,MAAM,KAAK,oBAAoB;AACjD,UAAM,KAAK,iBAAiB,eAAe,WAAW,GAAG;AACzD,UAAM,KAAK,8BAA8B,eAAe,GAAG;AAAA,EAC7D;AAAA;AAAA,EAGA,MAAc,8BACZ,eACA,KACe;AACf,UAAM,OAAO,oBAAoB,eAAe,GAAG;AAEnD,eAAW,UAAU,MAAM,mBAAmB,cAAc,IAAI,GAAG,GAAG,GAAG;AACvE,WAAK,IAAI,MAAM;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAc,oBAAoB,KAAyC;AACzE,QAAI;AACJ,QAAI;AACF,sBAAgB,MAAM,wBAAwB,GAAG;AAAA,IACnD,SAAS,OAAO;AAEd,UAAI,iBAAiB,iBAAiB;AACpC,aAAK,MAAM,MAAM,SAAS,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,MACtD;AACA,YAAM;AAAA,IACR;AAEA,QAAI,CAAC,cAAc,UAAU,CAAC,cAAc,SAAS;AACnD,WAAK,MAAM,eAAe,iBAAiB;AAAA,QACzC,MAAM,WAAW;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,4BAA4B,KAA4B;AACpE,UAAM,CAAC,OAAO,IAAI,MAAM,2BAA2B,GAAG;AACtD,QAAI,YAAY,OAAW,MAAK,MAAM,SAAS,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,EAC3E;AAAA;AAAA,EAGA,MAAc,oBAAoB,YAAmC;AACnE,SAAK,IAAI,gBAAgB,gBAAgB;AACzC,QAAI;AAEF,YAAM,eAAe,MAAM,cAAc,EAAE,QAAQ,UAAU,WAAW,CAAC;AACzE,WAAK,IAAI,gBAAgB,aAAa,YAAY,EAAE;AAAA,IACtD,SAAS,OAAO;AACd,WAAK,IAAI,eAAe,qBAAqB;AAC7C,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,sBAA0C;AACtD,SAAK,IAAI,gBAAgB,sBAAsB;AAC/C,QAAI;AACF,YAAM,OAAO,MAAM,cAAc;AACjC,WAAK,IAAI,uBAAuB;AAChC,cAAQ,aAAa,KAAK,iBAAiB,SAAS,EAAE;AACtD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,IAAI,eAAe,0BAA0B;AAClD,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,iBACZ,eACA,WACA,KACe;AACf,UAAM,SAAS,mBAAmB,eAAe,KAAK,SAAS;AAE/D,QAAI,iBAAiB;AACrB,eAAW,QAAQ,QAAQ;AACzB,YAAM,WAAW,MAAM,KAAK,eAAe,MAAM,GAAG;AACpD,UAAI,SAAU;AAAA,IAChB;AAEA,QAAI,mBAAmB,GAAG;AACxB,WAAK,MAAM,eAAe,sBAAsB,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,IAC5E;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,kBAAkB,YAA+C;AAC7E,SAAK,IAAI,gBAAgB,kBAAkB;AAC3C,UAAM,SAAS,MAAM,wBAAwB,UAAU;AACvD,QAAI,OAAO,iBAAiB,SAAS,GAAG;AACtC,WAAK,4BAA4B,OAAO,gBAAgB;AAAA,IAC1D;AACA,QAAI,OAAO,oBAAoB,EAAG,QAAO;AACzC,SAAK,IAAI,uBAAuB,MAAM,CAAC;AACvC,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,4BAA4B,SAAyC;AAC3E,eAAW,SAAS,SAAS;AAC3B,WAAK,IAAI,4BAA4B,KAAK,CAAC;AAAA,IAC7C;AACA,SAAK,MAAM,2BAA2B,OAAO,GAAG,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,EAC5E;AAAA;AAAA,EAGA,MAAc,0BACZ,YACA,WACe;AACf,UAAM,SAAS,MAAM,kBAAkB,UAAU;AACjD,QAAI,CAAC,QAAQ,OAAO,MAAO;AAE3B,UAAM,cAAc,4BAA4B,OAAO,OAAO,MAAM;AACpE,UAAM,aAAa,iBAAiB,OAAO,OAAO,KAAK,EAAE;AAAA,MACvD,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,KAAK,EAAE,MAAM;AAAA,IAC1C;AAEA,eAAW,MAAM,YAAY;AAC3B,WAAK;AAAA,QACH,UAAU,EAAE;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,2BAA2B,YAAmC;AAC1E,UAAM,SAAS,MAAM,kBAAkB,UAAU;AACjD,QAAI,CAAC,QAAQ,OAAO,MAAO;AAE3B,eAAW,CAAC,SAAS,UAAU,KAAK,2BAA2B,OAAO,MAAM,GAAG;AAC7E,WAAK,KAAK,4BAA4B,YAAY,OAAO,CAAC;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,uBAAuB,YAAmC;AACtE,UAAM,SAAS,MAAM,oBAAoB,UAAU;AACnD,QAAI,CAAC,OAAQ;AAEb,UAAM,mBAAmB,OAAO,OAAO,OAAO;AAAA,MAAO,CAAC,UACpD,WAAW,OAAO,QAAQ;AAAA,IAC5B,EAAE;AACF,QAAI,qBAAqB,EAAG;AAE5B,SAAK,IAAI,uBAAuB,gBAAgB,CAAC;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,kBAAkB,YAAwD;AACtF,QAAI;AACF,YAAM,EAAE,QAAQ,OAAO,IAAI,MAAM,2BAA2B;AAAA,QAC1D;AAAA,QACA,kBAAkB;AAAA,QAClB,YAAY;AAAA,MACd,CAAC;AACD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,KAAK,oCAAoC,UAAU,KAAK,gBAAgB,KAAK,CAAC,EAAE;AACrF,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,mBACZ,MACA,KACA,cACe;AACf,QAAI,CAAC,cAAc;AACjB,WAAK;AAAA,QACH,yBAAyB,2CAA2C,KAAK,UAAU,EAAE;AAAA,MACvF;AACA;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,YAAM,SAAS,MAAM,oBAAoB,KAAK,UAAU;AACxD,UAAI,CAAC,QAAQ;AACX;AAAA,UACE,sBAAsB,KAAK,UAAU,oBAAe,eAAe,eAAe;AAAA,QACpF;AACA;AAAA,MACF;AAGA,eAAS,MAAM;AAAA,QACb,KAAK;AAAA,QACL,OAAO;AAAA,QACP,EAAE,QAAQ,cAAc,QAAQ,KAAK,OAAO;AAAA,QAC5C,EAAE,mBAAmB,IAAI;AAAA,MAC3B;AACA,WAAK,IAAI,cAAc,sBAAsB;AAAA,IAC/C,SAAS,OAAO;AACd,WAAK,KAAK,yBAAyB,gBAAgB,KAAK,CAAC,CAAC;AAC1D;AAAA,IACF;AAEA,SAAK,kBAAkB,MAAM;AAAA,EAC/B;AAAA;AAAA,EAGQ,kBAAkB,QAA0B;AAClD,SAAK,yBAAyB,OAAO,UAAU;AAC/C,eAAW,eAAe,OAAO,WAAW,QAAQ;AAClD,WAAK,KAAK,8BAA8B,WAAW,CAAC;AAAA,IACtD;AACA,SAAK,aAAa,MAAM;AAAA,EAC1B;AAAA,EAEA,MAAc,eAAe,MAAmB,KAA+B;AAC7E,UAAM,EAAE,WAAW,IAAI;AACvB,SAAK,aAAa,IAAI;AAEtB,UAAM,eAAe,MAAM,KAAK,kBAAkB,UAAU;AAC5D,UAAM,EAAE,WAAW,gBAAgB,IAAI,MAAM,KAAK,kBAAkB,UAAU;AAC9E,UAAM,WAAW,MAAM,KAAK,4BAA4B,MAAM,eAAe;AAE7E,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,KAAK,0BAA0B,YAAY,SAAS;AAC1D,UAAM,KAAK,2BAA2B,UAAU;AAChD,UAAM,KAAK,oBAAoB,MAAM,SAAS;AAC9C,UAAM,KAAK,mBAAmB,MAAM,KAAK,YAAY;AAErD,SAAK,IAAI,EAAE;AACX,SAAK,WAAW,GAAG,KAAK,KAAK,oBAAoB;AACjD,SAAK,IAAI,EAAE;AACX,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,EAAE,OAAO,YAAY,aAAa,GAAsB;AAC3E,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,aAAa,MAAM,YAAY,CAAC,YAAY;AACrD,SAAK,IAAI,EAAE;AAEX,YAAQ,cAAc,UAAU,EAAE;AAClC,YAAQ,aAAa,aAAa,SAAS,EAAE;AAAA,EAC/C;AAAA;AAAA,EAGA,MAAc,4BACZ,MACA,iBACkB;AAClB,QAAI,kBAAkB,EAAG,QAAO;AAEhC,UAAM,WAAW,KAAK,MAAM,YAAY;AACxC,QAAI,MAAM,uBAAuB,IAAI,GAAG;AACtC,WAAK,IAAI,4BAA4B,QAAQ,8BAA8B;AAC3E,aAAO;AAAA,IACT;AAEA,SAAK,IAAI,uBAAuB,QAAQ,iBAAiB;AACzD,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,oBAAoB,MAAmB,QAA2C;AAC9F,UAAM,EAAE,YAAY,cAAc,YAAY,YAAY,IAAI;AAE9D,SAAK,IAAI,gBAAgB,kBAAkB;AAC3C,QAAI;AACF,YAAM,kBAAkB,MAAM,cAAc;AAAA,QAC1C;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,WAAW,aAAa;AAAA,QACxB,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,MACjD,CAAC;AACD,YAAM,KAAK,gBAAgB,iBAAiB,IAAI;AAAA,IAClD,SAAS,OAAO;AACd,WAAK,IAAI,eAAe,qBAAqB;AAC7C,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,gBACZ,EAAE,UAAU,WAAW,QAAQ,SAAS,GACxC,EAAE,OAAO,WAAW,GACL;AACf,UAAM,UAAU;AAAA,MACd,UAAU;AAAA,MACV,SAAS,SAAS,UAAU;AAAA,MAC5B,GAAG,MAAM,YAAY,CAAC;AAAA,IACxB;AAEA,QAAI,OAAO,SAAS,GAAG;AACrB,WAAK,IAAI,GAAG,OAAO,KAAK,OAAO,MAAM,UAAU;AAC/C,iBAAW,WAAW,UAAU;AAC9B,aAAK,KAAK,OAAO;AAAA,MACnB;AAAA,IACF,WAAW,SAAS,SAAS,GAAG;AAC9B,WAAK,IAAI,OAAO;AAAA,IAClB,OAAO;AACL,WAAK,IAAI,cAAc,sBAAsB;AAC7C,UAAI,UAAU,WAAW;AACvB,cAAM,KAAK,uBAAuB,UAAU;AAAA,MAC9C;AAAA,IACF;AAEA,QAAI,SAAS,SAAS,GAAG;AACvB,cAAQ,eAAe,SAAS,KAAK,IAAI,CAAC,EAAE;AAAA,IAC9C;AAAA,EACF;AACF;AAeA,SAAS,mBACP,eACA,KACA,WACe;AACf,QAAM,EAAE,YAAY,OAAO,IAAI;AAE/B,MAAI,cAAc,SAAS;AACzB,WAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,cAAc,cAAc;AAAA,QAC5B;AAAA,QACA;AAAA,QACA,GAAI,cAAc,WAAW,EAAE,aAAa,UAAmB;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AAEA,MAAI,cAAc,QAAQ;AACxB,WAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP,YAAY,GAAG,QAAQ;AAAA,QACvB,cAAc,cAAc;AAAA,QAC5B;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,CAAC;AACV;AAGA,SAAS,oBAAoB,eAAkC,KAAqB;AAClF,SAAO,cAAc,UAAU,MAAM,GAAG,QAAQ;AAClD;AAMA,eAAe,uBAAuB,MAAqC;AACzE,QAAM,SAAS,MAAM,oBAAoB,KAAK,UAAU;AACxD,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,EAAE,QAAQ,OAAO,IAAI,OAAO;AAClC,QAAM,iBAAiB,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,QAAQ;AAC7D,QAAM,kBAAkB,OAAO;AAAA,IAAK,CAAC,UACnC,KAAK,gBAAgB,SAAY,CAAC,MAAM,WAAW,WAAW,OAAO,KAAK,WAAW;AAAA,EACvF;AACA,SAAO,CAAC,kBAAkB;AAC5B;AAGA,SAAS,2BAA2B,QAAiD;AACnF,QAAM,QAAQ,OAAO,SAAS,CAAC;AAC/B,QAAM,mBAAmB,OAAO,OAC7B,OAAO,CAAC,UAAU,WAAW,OAAO,QAAQ,CAAC,EAC7C,IAAI,CAAC,UAAU,MAAM,IAAI;AAC5B,QAAM,mBAAmB;AAAA,IACvB,OAAO,OAAO,OAAO,CAAC,UAAU,WAAW,OAAO,SAAS,CAAC,EAAE,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,EACvF;AAEA,SAAO,iBACJ,IAAI,CAAC,YAAoC;AAAA,IACxC;AAAA,IACA,iBAAiB,OAAO,CAAC,cAAc,kBAAkB,MAAM,SAAS,GAAG,OAAO,CAAC;AAAA,EACrF,CAAC,EACA,OAAO,CAAC,CAAC,EAAE,UAAU,MAAM,WAAW,SAAS,CAAC;AACrD;AAEA,SAAS,kBAAkB,YAA0C,SAA2B;AAC9F,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,2BAA2B,UAAU,EAAE,KAAK,CAAC,QAAQ,IAAI,OAAO,OAAO;AAChF;AAEA,SAAS,uBAAuB,QAAkC;AAChE,QAAM,EAAE,iBAAiB,iBAAiB,IAAI;AAC9C,QAAM,aAAa,kBAAkB;AAErC,MAAI,mBAAmB,KAAK,aAAa,GAAG;AAC1C,WAAO,cAAc,OAAO,iBAAiB,OAAO,CAAC,KAAK,gBAAgB,kBAAkB,UAAU;AAAA,EACxG;AAEA,SAAO,mBAAmB,IACtB,cAAc,OAAO,kBAAkB,OAAO,CAAC,kBAC/C,cAAc,OAAO,iBAAiB,aAAa,CAAC;AAC1D;","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 { namedByActiveEntries } from \"../lib/configuration/scope-diff.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 const namedBy = namedByActiveEntries(loaded.config.skills);\n for (const [skillId, agentNames] of findScopeDroppedStackPairs(loaded.config)) {\n this.warn(scopeBlockedStackAssignment(agentNames, skillId, namedBy));\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":[]}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "../chunk-
|
|
2
|
+
import "../chunk-EC3JXT23.js";
|
|
3
3
|
import {
|
|
4
4
|
filterExcludedEntries,
|
|
5
5
|
listAgentFilesOf,
|
|
6
6
|
listAgentMdFiles,
|
|
7
7
|
splitAgentsByProvenance
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import {
|
|
10
|
-
ambiguityFinding
|
|
11
|
-
} from "../chunk-ORO2T4K2.js";
|
|
8
|
+
} from "../chunk-MQZNDK5F.js";
|
|
12
9
|
import {
|
|
13
10
|
BaseCommand,
|
|
14
|
-
EXIT_CODES
|
|
15
|
-
|
|
11
|
+
EXIT_CODES,
|
|
12
|
+
ambiguityFinding
|
|
13
|
+
} from "../chunk-JTMSFBCA.js";
|
|
14
|
+
import "../chunk-FACDJH6O.js";
|
|
16
15
|
import {
|
|
17
16
|
ConfigDefaultExportError,
|
|
17
|
+
ConfigEvaluationError,
|
|
18
18
|
ConfigLoadError,
|
|
19
|
+
ConfigSchemaError,
|
|
19
20
|
INFO_MESSAGES,
|
|
20
21
|
MarketplaceManifestRequiredError,
|
|
21
22
|
MarketplaceNameRefusedError,
|
|
22
23
|
MarketplaceRefusedError,
|
|
23
24
|
MarketplaceUnreachableError,
|
|
25
|
+
NoSkillRulesError,
|
|
24
26
|
SOURCE_ENV_VAR,
|
|
27
|
+
StacksLoadError,
|
|
25
28
|
agentCodec,
|
|
26
29
|
agentYamlGenerationSchema,
|
|
27
30
|
agentsDir,
|
|
28
31
|
askingEachMarketplaceItself,
|
|
29
|
-
|
|
32
|
+
configsDeclaringNothing,
|
|
33
|
+
configsInPlay,
|
|
30
34
|
declaresNoContent,
|
|
31
35
|
detectInstallations,
|
|
32
36
|
directoryExists,
|
|
@@ -34,15 +38,16 @@ import {
|
|
|
34
38
|
findConfigLoadFailures,
|
|
35
39
|
formatZodErrors,
|
|
36
40
|
getErrorMessage,
|
|
37
|
-
getInstalledConfigPath,
|
|
38
41
|
getInstalledPluginsRegistryPath,
|
|
39
|
-
|
|
42
|
+
getProjectConfigPath,
|
|
40
43
|
getProjectPluginsDir,
|
|
41
44
|
getStackSkillIds,
|
|
42
45
|
getUserPluginsDir,
|
|
46
|
+
getVerifiedPluginInstallPaths,
|
|
43
47
|
glob,
|
|
44
48
|
hostCompilesAgent,
|
|
45
49
|
hostFor,
|
|
50
|
+
inheritedGlobalProvider,
|
|
46
51
|
installBaseDir,
|
|
47
52
|
invalidResult,
|
|
48
53
|
isHomeDirectory,
|
|
@@ -53,7 +58,6 @@ import {
|
|
|
53
58
|
listPluginDirNames,
|
|
54
59
|
listRegisteredPluginInstalls,
|
|
55
60
|
loadConfig,
|
|
56
|
-
loadInstalledConfig,
|
|
57
61
|
loadProjectConfigFromDir,
|
|
58
62
|
loadSkillsMatrixFromSource,
|
|
59
63
|
loadSourceRepoConfig,
|
|
@@ -89,14 +93,13 @@ import {
|
|
|
89
93
|
validatePlugin,
|
|
90
94
|
validateProjectConfig,
|
|
91
95
|
validateSkillFrontmatter,
|
|
92
|
-
validateSkillMetadata
|
|
93
|
-
|
|
94
|
-
} from "../chunk-E45IT3HC.js";
|
|
96
|
+
validateSkillMetadata
|
|
97
|
+
} from "../chunk-ENET4IF6.js";
|
|
95
98
|
import {
|
|
96
99
|
matrix,
|
|
97
100
|
plural,
|
|
98
101
|
typedValues
|
|
99
|
-
} from "../chunk-
|
|
102
|
+
} from "../chunk-UE4Z3YMB.js";
|
|
100
103
|
import {
|
|
101
104
|
CLI_INVOKE_COMMAND,
|
|
102
105
|
DEFAULT_BRANDING,
|
|
@@ -111,7 +114,7 @@ import {
|
|
|
111
114
|
STANDARD_FILES,
|
|
112
115
|
UI_SYMBOLS,
|
|
113
116
|
effectivelyExcludedSkillIds
|
|
114
|
-
} from "../chunk-
|
|
117
|
+
} from "../chunk-U46LYYRA.js";
|
|
115
118
|
import "../chunk-GHHJYNAN.js";
|
|
116
119
|
|
|
117
120
|
// src/cli/commands/doctor.ts
|
|
@@ -123,18 +126,11 @@ import os from "os";
|
|
|
123
126
|
async function hostsOnDisk(projectDir) {
|
|
124
127
|
const found = await detectInstallations(projectDir);
|
|
125
128
|
if (inheritsTheGlobalInstallation(found)) return hostsOf(providerInUse(os.homedir()));
|
|
126
|
-
|
|
127
|
-
return { project, global: globalBeside(project, found) };
|
|
129
|
+
return { project: providerInUse(projectDir), global: inheritedGlobalProvider(projectDir) };
|
|
128
130
|
}
|
|
129
131
|
function inheritsTheGlobalInstallation(found) {
|
|
130
132
|
return found.length > 0 && found.every((installation) => installation.scope === "global");
|
|
131
133
|
}
|
|
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
134
|
function hostsOf(provider) {
|
|
139
135
|
return { project: provider, global: provider };
|
|
140
136
|
}
|
|
@@ -162,29 +158,23 @@ async function readConfigState(projectDir, hosts) {
|
|
|
162
158
|
}
|
|
163
159
|
const inherited = isHomeDirectory(projectDir) ? null : await loadProjectConfigFromDir(os.homedir(), hosts.global);
|
|
164
160
|
if (inherited && !declaresNoContent(inherited.config)) {
|
|
165
|
-
return {
|
|
161
|
+
return {
|
|
162
|
+
kind: "loaded",
|
|
163
|
+
config: inherited.config,
|
|
164
|
+
inherited: true,
|
|
165
|
+
declaringNothingIn: await providerDeclaringNothingIn(projectDir)
|
|
166
|
+
};
|
|
166
167
|
}
|
|
167
168
|
return own ? { kind: "declares-nothing", config: own.config } : { kind: "absent" };
|
|
168
169
|
}
|
|
170
|
+
async function providerDeclaringNothingIn(projectDir) {
|
|
171
|
+
const [leftover] = await configsDeclaringNothing(projectDir);
|
|
172
|
+
return leftover === void 0 ? null : leftover.provider;
|
|
173
|
+
}
|
|
169
174
|
async function installedPluginSkillIds(baseDir, provider) {
|
|
170
|
-
const plugins = await
|
|
175
|
+
const plugins = await getVerifiedPluginInstallPaths(baseDir, provider);
|
|
171
176
|
return new Set(plugins.map((plugin) => parseMarketplacePluginRef(plugin.pluginKey)));
|
|
172
177
|
}
|
|
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
178
|
async function unofferablePlacements({
|
|
189
179
|
projectDir,
|
|
190
180
|
hosts
|
|
@@ -302,6 +292,7 @@ async function validateSource(sourcePath, reader = "author") {
|
|
|
302
292
|
}
|
|
303
293
|
const sourceProjectConfig = await loadSourceRepoConfig(resolvedPath);
|
|
304
294
|
const skillsDirRelPath = sourceProjectConfig?.skillsDir ?? SKILLS_DIR_PATH;
|
|
295
|
+
const stacksRelFile = sourceProjectConfig?.stacksFile ?? STACKS_FILE_PATH;
|
|
305
296
|
const skillsDir2 = path.join(resolvedPath, skillsDirRelPath);
|
|
306
297
|
if (!await directoryExists(skillsDir2)) {
|
|
307
298
|
return buildResult(
|
|
@@ -311,11 +302,11 @@ async function validateSource(sourcePath, reader = "author") {
|
|
|
311
302
|
}
|
|
312
303
|
const { pairIssues, validMetadataFiles } = await pairSkillFiles(skillsDir2);
|
|
313
304
|
const skillIssues = await validateSkillsInTurn(skillsDir2, skillsDirRelPath, validMetadataFiles);
|
|
314
|
-
const crossReferenceIssues = await checkCrossReferences(resolvedPath, reader);
|
|
305
|
+
const crossReferenceIssues = await checkCrossReferences(resolvedPath, stacksRelFile, reader);
|
|
315
306
|
const extraIssues = await Promise.all([
|
|
316
307
|
validateStacks(resolvedPath),
|
|
317
308
|
validateAgents(resolvedPath),
|
|
318
|
-
validateConfigFiles(resolvedPath)
|
|
309
|
+
validateConfigFiles(resolvedPath, stacksRelFile)
|
|
319
310
|
]);
|
|
320
311
|
return buildResult(
|
|
321
312
|
[...pairIssues, ...skillIssues, ...crossReferenceIssues, ...extraIssues.flat()],
|
|
@@ -371,17 +362,31 @@ var MANIFEST_REQUIRED_SEVERITY = {
|
|
|
371
362
|
author: "warning",
|
|
372
363
|
consumer: "error"
|
|
373
364
|
};
|
|
374
|
-
async function checkCrossReferences(resolvedPath, reader) {
|
|
365
|
+
async function checkCrossReferences(resolvedPath, stacksRelFile, reader) {
|
|
375
366
|
try {
|
|
376
367
|
await loadSkillsMatrixFromSource({ sourceFlag: resolvedPath, skipExtraSources: true });
|
|
377
368
|
return matrixHealthIssues(matrix).map(
|
|
378
369
|
(healthIssue) => toSourceIssue(healthIssue, resolvedPath, reader)
|
|
379
370
|
);
|
|
380
371
|
} catch (error) {
|
|
381
|
-
|
|
372
|
+
const failedFile = fileThatFailedToLoad(error, resolvedPath, stacksRelFile);
|
|
373
|
+
return [matrixLoadFailure(error, reader, failedFile)];
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
function fileThatFailedToLoad(error, resolvedPath, stacksRelFile) {
|
|
377
|
+
if (error instanceof StacksLoadError) return stacksRelFile;
|
|
378
|
+
if (configThatFailedToLoad(error) === path.join(resolvedPath, SKILL_RULES_PATH)) {
|
|
379
|
+
return SKILL_RULES_PATH;
|
|
380
|
+
}
|
|
381
|
+
return void 0;
|
|
382
|
+
}
|
|
383
|
+
function configThatFailedToLoad(error) {
|
|
384
|
+
if (error instanceof ConfigEvaluationError || error instanceof ConfigDefaultExportError || error instanceof ConfigSchemaError || error instanceof NoSkillRulesError) {
|
|
385
|
+
return error.configPath;
|
|
382
386
|
}
|
|
387
|
+
return void 0;
|
|
383
388
|
}
|
|
384
|
-
function matrixLoadFailure(error, reader) {
|
|
389
|
+
function matrixLoadFailure(error, reader, failedFile) {
|
|
385
390
|
if (error instanceof MarketplaceManifestRequiredError) {
|
|
386
391
|
return {
|
|
387
392
|
severity: MANIFEST_REQUIRED_SEVERITY[reader],
|
|
@@ -396,10 +401,14 @@ function matrixLoadFailure(error, reader) {
|
|
|
396
401
|
message: getErrorMessage(error)
|
|
397
402
|
};
|
|
398
403
|
}
|
|
404
|
+
if (failedFile !== void 0) return crossReferenceSkipped(failedFile, failedFile, error);
|
|
405
|
+
return crossReferenceSkipped(SKILL_CATEGORIES_PATH, "categories/rules", error);
|
|
406
|
+
}
|
|
407
|
+
function crossReferenceSkipped(file, whatFailed, error) {
|
|
399
408
|
return {
|
|
400
409
|
severity: "warning",
|
|
401
|
-
file
|
|
402
|
-
message: `Cross-reference validation skipped: failed to load
|
|
410
|
+
file,
|
|
411
|
+
message: `Cross-reference validation skipped: failed to load ${whatFailed}: ${getErrorMessage(error)}`
|
|
403
412
|
};
|
|
404
413
|
}
|
|
405
414
|
var SKILL_AUDIT_PATH = "src/cli/lib/configuration/skill-audit.ts";
|
|
@@ -467,11 +476,11 @@ async function validateAgents(resolvedPath) {
|
|
|
467
476
|
schema: agentYamlGenerationSchema
|
|
468
477
|
});
|
|
469
478
|
}
|
|
470
|
-
async function validateConfigFiles(resolvedPath) {
|
|
479
|
+
async function validateConfigFiles(resolvedPath, stacksRelFile) {
|
|
471
480
|
const results = await Promise.all([
|
|
472
481
|
validateTsConfig(resolvedPath, SKILL_CATEGORIES_PATH, skillCategoriesFileSchema),
|
|
473
482
|
validateTsConfig(resolvedPath, SKILL_RULES_PATH, skillRulesFileSchema),
|
|
474
|
-
validateTsConfig(resolvedPath,
|
|
483
|
+
validateTsConfig(resolvedPath, stacksRelFile, stacksConfigSchema)
|
|
475
484
|
]);
|
|
476
485
|
return results.flat();
|
|
477
486
|
}
|
|
@@ -572,7 +581,9 @@ function toUnreadableConfigIssue(failure) {
|
|
|
572
581
|
}
|
|
573
582
|
async function countExistingConfigs(projectDir) {
|
|
574
583
|
const present = await Promise.all(
|
|
575
|
-
|
|
584
|
+
configsInPlay(projectDir).map(
|
|
585
|
+
({ dir, provider }) => fileExists(getProjectConfigPath(dir, provider))
|
|
586
|
+
)
|
|
576
587
|
);
|
|
577
588
|
return present.filter(Boolean).length;
|
|
578
589
|
}
|
|
@@ -676,7 +687,7 @@ async function validateInstalledSkills(projectDir) {
|
|
|
676
687
|
}
|
|
677
688
|
async function configuredSkillIds(projectDir) {
|
|
678
689
|
const loaded = await Promise.all(
|
|
679
|
-
|
|
690
|
+
configsInPlay(projectDir).map(({ dir, provider }) => loadProjectConfigFromDir(dir, provider))
|
|
680
691
|
);
|
|
681
692
|
return new Set(loaded.flatMap(configuredIdsOf));
|
|
682
693
|
}
|
|
@@ -863,39 +874,45 @@ async function unclaimedAgentFiles({ dir, codec, claimed: claimed2 }) {
|
|
|
863
874
|
import { countBy, unique as unique2 } from "remeda";
|
|
864
875
|
function checkConfigValid(state, installation) {
|
|
865
876
|
const theConfig = (verdict) => configRowMessage(state, installation, verdict);
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
877
|
+
switch (state.kind) {
|
|
878
|
+
case "absent":
|
|
879
|
+
return {
|
|
880
|
+
result: {
|
|
881
|
+
kind: "config",
|
|
882
|
+
status: "fail",
|
|
883
|
+
message: theConfig("not found"),
|
|
884
|
+
details: [`Run '${CLI_INVOKE_COMMAND} init' to create a configuration`]
|
|
885
|
+
},
|
|
886
|
+
config: null
|
|
887
|
+
};
|
|
888
|
+
case "unreadable":
|
|
889
|
+
return {
|
|
890
|
+
result: {
|
|
891
|
+
kind: "config",
|
|
892
|
+
status: "fail",
|
|
893
|
+
message: theConfig("exists but could not be loaded"),
|
|
894
|
+
details: [state.failure.reason]
|
|
895
|
+
},
|
|
896
|
+
config: null
|
|
897
|
+
};
|
|
898
|
+
case "declares-nothing":
|
|
899
|
+
return {
|
|
900
|
+
result: {
|
|
901
|
+
kind: "config-empty",
|
|
902
|
+
status: "warn",
|
|
903
|
+
message: theConfig("is valid but declares no skills and no agents")
|
|
904
|
+
},
|
|
905
|
+
config: state.config
|
|
906
|
+
};
|
|
907
|
+
case "loaded":
|
|
908
|
+
return checkLoadedConfig(state.config, theConfig);
|
|
909
|
+
default: {
|
|
910
|
+
const _exhaustive = state;
|
|
911
|
+
return _exhaustive;
|
|
912
|
+
}
|
|
897
913
|
}
|
|
898
|
-
|
|
914
|
+
}
|
|
915
|
+
function checkLoadedConfig(config, theConfig) {
|
|
899
916
|
const validation = validateProjectConfig(config);
|
|
900
917
|
if (!validation.valid) {
|
|
901
918
|
return {
|
|
@@ -930,7 +947,7 @@ function checkConfigValid(state, installation) {
|
|
|
930
947
|
}
|
|
931
948
|
function configRowMessage(state, { projectDir, hosts }, verdict) {
|
|
932
949
|
if (state.kind === "loaded" && state.inherited)
|
|
933
|
-
return `${theInheritedConfig(hosts.global)}, which ${verdict}`;
|
|
950
|
+
return `${theInheritedConfig(projectDir, state.declaringNothingIn, hosts.global)}, which ${verdict}`;
|
|
934
951
|
if (state.kind === "unreadable") {
|
|
935
952
|
const { scopeRoot, scope } = state.failure;
|
|
936
953
|
return `${theConfigAt(scopeRoot, hosts[scope])} ${verdict}`;
|
|
@@ -940,8 +957,9 @@ function configRowMessage(state, { projectDir, hosts }, verdict) {
|
|
|
940
957
|
function theConfigAt(root, provider) {
|
|
941
958
|
return `${scopeLabel(scopeOf(root))}: ${configNamedFrom(root, provider)}`;
|
|
942
959
|
}
|
|
943
|
-
function theInheritedConfig(provider) {
|
|
944
|
-
|
|
960
|
+
function theInheritedConfig(projectDir, declaringNothingIn, provider) {
|
|
961
|
+
const projectHolds = declaringNothingIn === null ? `no ${STANDARD_FILES.CONFIG_TS}` : `${relativeConfigPath(projectDir, declaringNothingIn)} declares nothing`;
|
|
962
|
+
return `${scopeLabel("project")}: ${projectHolds}, using ${scopeNoun("global")}'s (${configNamedFrom(os3.homedir(), provider)})`;
|
|
945
963
|
}
|
|
946
964
|
function scopeOf(dir) {
|
|
947
965
|
return isHomeDirectory(dir) ? "global" : "project";
|
|
@@ -1466,6 +1484,7 @@ var Doctor = class _Doctor extends BaseCommand {
|
|
|
1466
1484
|
async run() {
|
|
1467
1485
|
await this.parse(_Doctor);
|
|
1468
1486
|
const projectDir = process.cwd();
|
|
1487
|
+
await this.sayWhenTheGlobalInstallationStandsIn(void 0);
|
|
1469
1488
|
this.printHeader(await this.resolveBrandingName(projectDir));
|
|
1470
1489
|
const contentResults = await this.runContentChecks(projectDir);
|
|
1471
1490
|
const operationalResults = await this.runOperationalChecks(projectDir, contentResults);
|