agents-inc 0.156.0 → 0.158.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 +51 -0
- package/dist/{chunk-4A4L3YIW.js → chunk-2PN4QXON.js} +6 -7
- package/dist/chunk-2PN4QXON.js.map +1 -0
- package/dist/{chunk-QWVXOCXO.js → chunk-3NBXQSW2.js} +7 -9
- package/dist/{chunk-QWVXOCXO.js.map → chunk-3NBXQSW2.js.map} +1 -1
- package/dist/{chunk-WCAUUBHO.js → chunk-3PJLLBUS.js} +14597 -14536
- package/dist/chunk-3PJLLBUS.js.map +1 -0
- package/dist/{chunk-6RLV45HN.js → chunk-3Q2N7CSY.js} +6 -6
- package/dist/chunk-3Q2N7CSY.js.map +1 -0
- package/dist/{chunk-LJCNUP6M.js → chunk-4ABNXKAR.js} +2 -2
- package/dist/{chunk-D2CAV7MG.js → chunk-4DMFK67G.js} +2 -2
- package/dist/{chunk-MO5FGLVS.js → chunk-54QLV3OH.js} +11 -12
- package/dist/chunk-54QLV3OH.js.map +1 -0
- package/dist/{chunk-5F2YR5XV.js → chunk-6DBE562W.js} +15 -5
- package/dist/chunk-6DBE562W.js.map +1 -0
- package/dist/{chunk-RWOYPOMR.js → chunk-7Z4N4JWQ.js} +19 -245
- package/dist/chunk-7Z4N4JWQ.js.map +1 -0
- package/dist/{chunk-H6UTKTLK.js → chunk-DAUY2SB3.js} +98 -34
- package/dist/chunk-DAUY2SB3.js.map +1 -0
- package/dist/{chunk-2H7UWE2G.js → chunk-DP6YQFVO.js} +13 -12
- package/dist/chunk-DP6YQFVO.js.map +1 -0
- package/dist/{chunk-ILUVL7WM.js → chunk-DZD25NHW.js} +2 -2
- package/dist/{chunk-PCC4LBKB.js → chunk-EEAX7E2X.js} +2 -2
- package/dist/{chunk-IO5YBKHV.js → chunk-G6G2FT2G.js} +10 -8
- package/dist/chunk-G6G2FT2G.js.map +1 -0
- package/dist/{chunk-5QZAK6J7.js → chunk-H25VRR2T.js} +50 -18
- package/dist/chunk-H25VRR2T.js.map +1 -0
- package/dist/chunk-H2DHTJKW.js +1352 -0
- package/dist/chunk-H2DHTJKW.js.map +1 -0
- package/dist/{chunk-MHRC3KRX.js → chunk-H4CL23HG.js} +3 -3
- package/dist/chunk-H4CL23HG.js.map +1 -0
- package/dist/{chunk-F5T6TV4Z.js → chunk-IK6YOXZH.js} +40 -14
- package/dist/chunk-IK6YOXZH.js.map +1 -0
- package/dist/{chunk-HG4JPXJT.js → chunk-JG3B47P3.js} +23 -10
- package/dist/chunk-JG3B47P3.js.map +1 -0
- package/dist/{chunk-SY4X2LND.js → chunk-KUZBMEWR.js} +3 -3
- package/dist/{chunk-5OKLCVM4.js → chunk-KVVXINCJ.js} +3 -3
- package/dist/{chunk-PNMM5HNX.js → chunk-L4FHSOL5.js} +9 -10
- package/dist/chunk-L4FHSOL5.js.map +1 -0
- package/dist/{chunk-PMUABBPG.js → chunk-LKI3ENGQ.js} +9 -13
- package/dist/chunk-LKI3ENGQ.js.map +1 -0
- package/dist/{chunk-CLFHC2DK.js → chunk-OQB2CKBT.js} +17 -18
- package/dist/chunk-OQB2CKBT.js.map +1 -0
- package/dist/{chunk-HXKOIWLU.js → chunk-P6OKOH62.js} +2 -6
- package/dist/chunk-P6OKOH62.js.map +1 -0
- package/dist/{chunk-TNGMF4UX.js → chunk-PNRLBPGS.js} +12 -12
- package/dist/chunk-PNRLBPGS.js.map +1 -0
- package/dist/{chunk-Y5Y7XHVU.js → chunk-PZNXBORZ.js} +4 -4
- package/dist/{chunk-HTYH7CKN.js → chunk-Q7CAE5NN.js} +3 -3
- package/dist/{chunk-G47TDUK3.js → chunk-QNAMXQKF.js} +2 -2
- package/dist/{chunk-GS2NZ3GD.js → chunk-SJ4T5YLG.js} +5 -5
- package/dist/chunk-SJ4T5YLG.js.map +1 -0
- package/dist/{chunk-UMH2YZKG.js → chunk-TPQ5M3BW.js} +4 -6
- package/dist/{chunk-UMH2YZKG.js.map → chunk-TPQ5M3BW.js.map} +1 -1
- package/dist/{chunk-4G2YHZIM.js → chunk-TUXXBEBB.js} +4 -6
- package/dist/{chunk-4G2YHZIM.js.map → chunk-TUXXBEBB.js.map} +1 -1
- package/dist/{chunk-WFRTHH3A.js → chunk-TZRXWFF5.js} +3 -3
- package/dist/{chunk-TBOVYLQJ.js → chunk-VTIDLRNA.js} +2 -2
- package/dist/{chunk-OKH64JZE.js → chunk-WCZNQECQ.js} +2 -2
- package/dist/{chunk-ZUAZHDKP.js → chunk-WMVOJY6V.js} +277 -40
- package/dist/chunk-WMVOJY6V.js.map +1 -0
- package/dist/{chunk-YO2LTXB4.js → chunk-X52QUV4U.js} +115 -10
- package/dist/chunk-X52QUV4U.js.map +1 -0
- package/dist/{chunk-IXRZAHZF.js → chunk-XNYHMRVJ.js} +4 -4
- package/dist/{chunk-VPASBA7P.js → chunk-YXI3BTQQ.js} +2 -2
- package/dist/commands/build/marketplace.js +9 -12
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +9 -12
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/compile.js +15 -19
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +75 -54
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +154 -109
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +68 -38
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +36 -39
- package/dist/commands/list.js +8 -10
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +8 -11
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/search.js +10 -13
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +8 -10
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/uninstall.js +39 -28
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +7 -10
- package/dist/commands/update.js.map +1 -1
- package/dist/components/common/removal-plan-confirm.js +2 -2
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/wizard/category-grid.js +4 -5
- package/dist/components/wizard/checkbox-grid.js +4 -4
- package/dist/components/wizard/domain-selection.js +9 -11
- package/dist/components/wizard/run-wizard-session.js +26 -28
- package/dist/components/wizard/scroll-affordance.js +2 -2
- package/dist/components/wizard/skill-agent-summary.js +5 -7
- package/dist/components/wizard/source-grid.js +5 -6
- package/dist/components/wizard/stack-selection.js +7 -9
- package/dist/components/wizard/step-agents.js +8 -10
- package/dist/components/wizard/step-build.js +7 -9
- package/dist/components/wizard/step-confirm.js +9 -11
- package/dist/components/wizard/step-sources.js +8 -10
- package/dist/components/wizard/step-stack.js +8 -10
- package/dist/components/wizard/summary-panel.js +8 -10
- package/dist/components/wizard/toast.js +2 -2
- package/dist/components/wizard/wizard-layout.js +12 -14
- package/dist/components/wizard/wizard-tabs.js +2 -4
- package/dist/components/wizard/wizard.js +25 -27
- package/dist/hooks/init.js +36 -39
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-2VYAV5GL.js +13 -0
- package/dist/recompile-project-agents-NG5DCPHJ.js +17 -0
- package/dist/{source-loader-3DL3NYUX.js → source-loader-CO2FZ3OO.js} +4 -8
- package/dist/src/agents/_templates/agent.liquid +2 -2
- package/dist/stores/wizard-store.js +6 -6
- package/package.json +2 -4
- package/src/agents/_templates/agent.liquid +2 -2
- package/src/schemas/custom-metadata.schema.json +1 -1
- package/src/schemas/marketplace.schema.json +2 -1
- package/dist/chunk-2H7UWE2G.js.map +0 -1
- package/dist/chunk-4A4L3YIW.js.map +0 -1
- package/dist/chunk-5F2YR5XV.js.map +0 -1
- package/dist/chunk-5QZAK6J7.js.map +0 -1
- package/dist/chunk-6RLV45HN.js.map +0 -1
- package/dist/chunk-CLFHC2DK.js.map +0 -1
- package/dist/chunk-F2AMBBIA.js +0 -64
- package/dist/chunk-F2AMBBIA.js.map +0 -1
- package/dist/chunk-F5T6TV4Z.js.map +0 -1
- package/dist/chunk-GS2NZ3GD.js.map +0 -1
- package/dist/chunk-H6UTKTLK.js.map +0 -1
- package/dist/chunk-HG4JPXJT.js.map +0 -1
- package/dist/chunk-HXKOIWLU.js.map +0 -1
- package/dist/chunk-IO5YBKHV.js.map +0 -1
- package/dist/chunk-MHRC3KRX.js.map +0 -1
- package/dist/chunk-MO5FGLVS.js.map +0 -1
- package/dist/chunk-PMUABBPG.js.map +0 -1
- package/dist/chunk-PNMM5HNX.js.map +0 -1
- package/dist/chunk-RWOYPOMR.js.map +0 -1
- package/dist/chunk-TNGMF4UX.js.map +0 -1
- package/dist/chunk-VASLW636.js +0 -23
- package/dist/chunk-VASLW636.js.map +0 -1
- package/dist/chunk-WCAUUBHO.js.map +0 -1
- package/dist/chunk-WUQ3MTPF.js +0 -173
- package/dist/chunk-WUQ3MTPF.js.map +0 -1
- package/dist/chunk-XAXJWXI4.js +0 -1667
- package/dist/chunk-XAXJWXI4.js.map +0 -1
- package/dist/chunk-YO2LTXB4.js.map +0 -1
- package/dist/chunk-ZUAZHDKP.js.map +0 -1
- package/dist/copy-local-skills-NSUTBVLJ.js +0 -14
- package/dist/load-agent-defs-X4E57I2U.js +0 -15
- package/dist/loader-G6BFG2VA.js +0 -24
- package/dist/recompile-project-agents-JE4MM72I.js +0 -20
- package/dist/recompile-project-agents-JE4MM72I.js.map +0 -1
- package/dist/source-loader-3DL3NYUX.js.map +0 -1
- /package/dist/{chunk-LJCNUP6M.js.map → chunk-4ABNXKAR.js.map} +0 -0
- /package/dist/{chunk-D2CAV7MG.js.map → chunk-4DMFK67G.js.map} +0 -0
- /package/dist/{chunk-ILUVL7WM.js.map → chunk-DZD25NHW.js.map} +0 -0
- /package/dist/{chunk-PCC4LBKB.js.map → chunk-EEAX7E2X.js.map} +0 -0
- /package/dist/{chunk-SY4X2LND.js.map → chunk-KUZBMEWR.js.map} +0 -0
- /package/dist/{chunk-5OKLCVM4.js.map → chunk-KVVXINCJ.js.map} +0 -0
- /package/dist/{chunk-Y5Y7XHVU.js.map → chunk-PZNXBORZ.js.map} +0 -0
- /package/dist/{chunk-HTYH7CKN.js.map → chunk-Q7CAE5NN.js.map} +0 -0
- /package/dist/{chunk-G47TDUK3.js.map → chunk-QNAMXQKF.js.map} +0 -0
- /package/dist/{chunk-WFRTHH3A.js.map → chunk-TZRXWFF5.js.map} +0 -0
- /package/dist/{chunk-TBOVYLQJ.js.map → chunk-VTIDLRNA.js.map} +0 -0
- /package/dist/{chunk-OKH64JZE.js.map → chunk-WCZNQECQ.js.map} +0 -0
- /package/dist/{chunk-IXRZAHZF.js.map → chunk-XNYHMRVJ.js.map} +0 -0
- /package/dist/{chunk-VPASBA7P.js.map → chunk-YXI3BTQQ.js.map} +0 -0
- /package/dist/{copy-local-skills-NSUTBVLJ.js.map → load-agent-defs-2VYAV5GL.js.map} +0 -0
- /package/dist/{load-agent-defs-X4E57I2U.js.map → recompile-project-agents-NG5DCPHJ.js.map} +0 -0
- /package/dist/{loader-G6BFG2VA.js.map → source-loader-CO2FZ3OO.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/build/plugins.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\n\nimport { BaseCommand } from \"../../base-command\";\nimport { setVerbose } from \"../../utils/logger\";\nimport { listDirectories, remove } from \"../../utils/fs\";\nimport { DIRS, PLUGINS_DIST_PATH } from \"../../consts\";\nimport {\n compileAllSkillPlugins,\n compileSkillPlugin,\n printCompilationSummary,\n} from \"../../lib/skills\";\nimport { compileAllAgentPlugins, printAgentCompilationSummary } from \"../../lib/agents\";\nimport { readPluginManifest } from \"../../lib/plugins\";\n\nexport default class BuildPlugins extends BaseCommand {\n static summary = \"Build skills and agents into standalone plugins\";\n\n static description =\n \"Build skills and agents into standalone plugins. By default, compiles all skills. Use --skill to compile a specific skill only. Use --agents-dir to also compile agents.\";\n\n static examples = [\n {\n description: \"Compile every skill into plugins\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Compile a single skill by name\",\n command: \"<%= config.bin %> <%= command.id %> --skill cli-commander\",\n },\n {\n description: \"Write plugins to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> --output-dir ./plugins\",\n },\n {\n description: \"Also compile agents from a directory\",\n command: \"<%= config.bin %> <%= command.id %> --agents-dir ./agents\",\n },\n {\n description: \"Compile with verbose logging\",\n command: \"<%= config.bin %> <%= command.id %> --verbose\",\n },\n ];\n\n static flags = {\n \"agents-dir\": Flags.string({\n char: \"a\",\n description: \"Agents source directory (builds one plugin per agent)\",\n }),\n \"output-dir\": Flags.string({\n char: \"o\",\n description: \"Output directory\",\n default: PLUGINS_DIST_PATH,\n }),\n skill: Flags.string({\n description: \"Compile only a specific skill (path to skill directory)\",\n }),\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Enable verbose logging\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(BuildPlugins);\n setVerbose(flags.verbose);\n\n const projectRoot = process.cwd();\n const skillsDir = path.resolve(projectRoot, DIRS.skills);\n const outputDir = path.resolve(projectRoot, flags[\"output-dir\"]);\n\n this.printHeader(skillsDir, outputDir);\n\n try {\n const expectedSkillPlugins = await this.compileSkills(flags.skill, skillsDir, outputDir);\n\n if (flags[\"agents-dir\"]) {\n await this.compileAgents(projectRoot, flags[\"agents-dir\"], outputDir);\n }\n\n if (expectedSkillPlugins) {\n await this.pruneStaleSkillPlugins(outputDir, expectedSkillPlugins);\n }\n\n this.log(\"\");\n this.logSuccess(\"Plugin compilation complete!\");\n } catch (error) {\n this.log(\"Compilation failed\");\n this.handleError(error);\n }\n }\n\n private printHeader(skillsDir: string, outputDir: string): void {\n this.log(\"\");\n this.log(\"Compiling skill plugins\");\n this.log(` Skills directory: ${skillsDir}`);\n this.log(` Output directory: ${outputDir}`);\n this.log(\"\");\n }\n\n /**\n * Compiles skills and returns the set of plugin directory names that should\n * exist afterward — used to prune stale plugins. Returns `null` when pruning\n * must be skipped: single-skill mode (would wipe every other plugin) or a\n * partial compile failure (a failed skill is indistinguishable from a removed\n * one, so deleting it would be a worse bug than the stale entry).\n */\n private async compileSkills(\n skillFlag: string | undefined,\n skillsDir: string,\n outputDir: string,\n ): Promise<Set<string> | null> {\n if (skillFlag) {\n const skillPath = path.resolve(skillsDir, skillFlag);\n this.log(`Compiling skill at ${skillPath}...`);\n\n const result = await compileSkillPlugin({\n skillPath,\n outputDir,\n });\n\n this.log(`Compiled ${result.skillName}`);\n this.log(` Plugin path: ${result.pluginPath}`);\n return null;\n }\n\n this.log(\"Finding and compiling all skills...\");\n\n const { compiled, failed } = await compileAllSkillPlugins(skillsDir, outputDir);\n\n this.log(`Compiled ${compiled.length} skill plugins`);\n printCompilationSummary(compiled);\n\n if (failed.length > 0) {\n this.warn(\n `Skipping stale-plugin pruning: ${failed.length} skill(s) failed to compile ` +\n `(${failed.join(\", \")}). A failed skill is indistinguishable from a removed one.`,\n );\n return null;\n }\n\n return new Set(compiled.map((result) => result.skillName));\n }\n\n private async compileAgents(\n projectRoot: string,\n agentsDir: string,\n outputDir: string,\n ): Promise<void> {\n const resolvedAgentsDir = path.resolve(projectRoot, agentsDir);\n\n this.log(\"\");\n this.log(\"Compiling agent plugins\");\n this.log(` Agents directory: ${resolvedAgentsDir}`);\n this.log(\"\");\n\n this.log(\"Finding and compiling all agents...\");\n\n const agentResults = await compileAllAgentPlugins(resolvedAgentsDir, outputDir);\n\n this.log(`Compiled ${agentResults.length} agent plugins`);\n printAgentCompilationSummary(agentResults);\n }\n\n /**\n * Removes skill-plugin directories in `outputDir` that no longer correspond to\n * a compiled skill. Only skill plugins are pruned: agent plugins are preserved\n * (this run has no authority over them) and non-plugin directories are left\n * untouched. Callers must only invoke this after a clean full-scan compile.\n */\n private async pruneStaleSkillPlugins(\n outputDir: string,\n expectedSkillPlugins: ReadonlySet<string>,\n ): Promise<void> {\n const dirNames = await listDirectories(outputDir);\n\n for (const dirName of dirNames) {\n if (expectedSkillPlugins.has(dirName)) continue;\n\n const pluginDir = path.join(outputDir, dirName);\n const manifest = await readPluginManifest(pluginDir);\n if (!manifest) continue;\n if (manifest.agents !== undefined) continue;\n\n await remove(pluginDir);\n this.log(` Pruned stale plugin: ${dirName}`);\n }\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/build/plugins.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\n\nimport { BaseCommand } from \"../../base-command\";\nimport { setVerbose } from \"../../utils/logger\";\nimport { listDirectories, remove } from \"../../utils/fs\";\nimport { DIRS, PLUGINS_DIST_PATH } from \"../../consts\";\nimport {\n compileAllSkillPlugins,\n compileSkillPlugin,\n printCompilationSummary,\n} from \"../../lib/skills\";\nimport { compileAllAgentPlugins, printAgentCompilationSummary } from \"../../lib/agents\";\nimport { readPluginManifest } from \"../../lib/plugins\";\n\nexport default class BuildPlugins extends BaseCommand {\n static summary = \"Build skills and agents into standalone plugins\";\n\n static description =\n \"Build skills and agents into standalone plugins. By default, compiles all skills. Use --skill to compile a specific skill only. Use --agents-dir to also compile agents.\";\n\n static examples = [\n {\n description: \"Compile every skill into plugins\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Compile a single skill by name\",\n command: \"<%= config.bin %> <%= command.id %> --skill cli-commander\",\n },\n {\n description: \"Write plugins to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> --output-dir ./plugins\",\n },\n {\n description: \"Also compile agents from a directory\",\n command: \"<%= config.bin %> <%= command.id %> --agents-dir ./agents\",\n },\n {\n description: \"Compile with verbose logging\",\n command: \"<%= config.bin %> <%= command.id %> --verbose\",\n },\n ];\n\n static flags = {\n \"agents-dir\": Flags.string({\n char: \"a\",\n description: \"Agents source directory (builds one plugin per agent)\",\n }),\n \"output-dir\": Flags.string({\n char: \"o\",\n description: \"Output directory\",\n default: PLUGINS_DIST_PATH,\n }),\n skill: Flags.string({\n description: \"Compile only a specific skill (path to skill directory)\",\n }),\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Enable verbose logging\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(BuildPlugins);\n setVerbose(flags.verbose);\n\n const projectRoot = process.cwd();\n const skillsDir = path.resolve(projectRoot, DIRS.skills);\n const outputDir = path.resolve(projectRoot, flags[\"output-dir\"]);\n\n this.printHeader(skillsDir, outputDir);\n\n try {\n const expectedSkillPlugins = await this.compileSkills(flags.skill, skillsDir, outputDir);\n\n if (flags[\"agents-dir\"]) {\n await this.compileAgents(projectRoot, flags[\"agents-dir\"], outputDir);\n }\n\n if (expectedSkillPlugins) {\n await this.pruneStaleSkillPlugins(outputDir, expectedSkillPlugins);\n }\n\n this.log(\"\");\n this.logSuccess(\"Plugin compilation complete!\");\n } catch (error) {\n this.log(\"Compilation failed\");\n this.handleError(error);\n }\n }\n\n private printHeader(skillsDir: string, outputDir: string): void {\n this.log(\"\");\n this.log(\"Compiling skill plugins\");\n this.log(` Skills directory: ${skillsDir}`);\n this.log(` Output directory: ${outputDir}`);\n this.log(\"\");\n }\n\n /**\n * Compiles skills and returns the set of plugin directory names that should\n * exist afterward — used to prune stale plugins. Returns `null` when pruning\n * must be skipped: single-skill mode (would wipe every other plugin) or a\n * partial compile failure (a failed skill is indistinguishable from a removed\n * one, so deleting it would be a worse bug than the stale entry).\n */\n private async compileSkills(\n skillFlag: string | undefined,\n skillsDir: string,\n outputDir: string,\n ): Promise<Set<string> | null> {\n if (skillFlag) {\n const skillPath = path.resolve(skillsDir, skillFlag);\n this.log(`Compiling skill at ${skillPath}...`);\n\n const result = await compileSkillPlugin({\n skillPath,\n outputDir,\n });\n\n this.log(`Compiled ${result.skillName}`);\n this.log(` Plugin path: ${result.pluginPath}`);\n return null;\n }\n\n this.log(\"Finding and compiling all skills...\");\n\n const { compiled, failed } = await compileAllSkillPlugins(skillsDir, outputDir);\n\n this.log(`Compiled ${compiled.length} skill plugins`);\n printCompilationSummary(compiled);\n\n if (failed.length > 0) {\n this.warn(\n `Skipping stale-plugin pruning: ${failed.length} skill(s) failed to compile ` +\n `(${failed.join(\", \")}). A failed skill is indistinguishable from a removed one.`,\n );\n return null;\n }\n\n return new Set(compiled.map((result) => result.skillName));\n }\n\n private async compileAgents(\n projectRoot: string,\n agentsDir: string,\n outputDir: string,\n ): Promise<void> {\n const resolvedAgentsDir = path.resolve(projectRoot, agentsDir);\n\n this.log(\"\");\n this.log(\"Compiling agent plugins\");\n this.log(` Agents directory: ${resolvedAgentsDir}`);\n this.log(\"\");\n\n this.log(\"Finding and compiling all agents...\");\n\n const agentResults = await compileAllAgentPlugins(resolvedAgentsDir, outputDir);\n\n this.log(`Compiled ${agentResults.length} agent plugins`);\n printAgentCompilationSummary(agentResults);\n }\n\n /**\n * Removes skill-plugin directories in `outputDir` that no longer correspond to\n * a compiled skill. Only skill plugins are pruned: agent plugins are preserved\n * (this run has no authority over them) and non-plugin directories are left\n * untouched. Callers must only invoke this after a clean full-scan compile.\n */\n private async pruneStaleSkillPlugins(\n outputDir: string,\n expectedSkillPlugins: ReadonlySet<string>,\n ): Promise<void> {\n const dirNames = await listDirectories(outputDir);\n\n for (const dirName of dirNames) {\n if (expectedSkillPlugins.has(dirName)) continue;\n\n const pluginDir = path.join(outputDir, dirName);\n const manifest = await readPluginManifest(pluginDir);\n if (!manifest) continue;\n if (manifest.agents !== undefined) continue;\n\n await remove(pluginDir);\n this.log(` Pruned stale plugin: ${dirName}`);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/commands/compile.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
detectBothInstallations
|
|
4
|
-
|
|
3
|
+
detectBothInstallations,
|
|
4
|
+
reconcileTypesFromDisk
|
|
5
|
+
} from "../chunk-H2DHTJKW.js";
|
|
5
6
|
import {
|
|
6
7
|
compileAgents,
|
|
7
8
|
discoverInstalledSkills
|
|
8
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-H25VRR2T.js";
|
|
9
10
|
import {
|
|
10
11
|
loadAgentDefs
|
|
11
|
-
} from "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-ZUAZHDKP.js";
|
|
12
|
+
} from "../chunk-H4CL23HG.js";
|
|
13
|
+
import "../chunk-WMVOJY6V.js";
|
|
14
14
|
import {
|
|
15
15
|
BaseCommand,
|
|
16
16
|
EXIT_CODES
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-X52QUV4U.js";
|
|
18
|
+
import "../chunk-TPQ5M3BW.js";
|
|
19
|
+
import "../chunk-QNAMXQKF.js";
|
|
20
20
|
import {
|
|
21
21
|
ConfigLoadError,
|
|
22
22
|
ERROR_MESSAGES,
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
STATUS_MESSAGES,
|
|
25
25
|
configTypesRefreshFailed,
|
|
26
26
|
effectivelyExcludedSkillIds,
|
|
27
|
+
getErrorMessage,
|
|
27
28
|
getStackSkillIds,
|
|
28
29
|
globalScopedAgentsHint,
|
|
29
30
|
isActiveAt,
|
|
@@ -31,24 +32,19 @@ import {
|
|
|
31
32
|
loadProjectConfigFromDir,
|
|
32
33
|
loadSkillsMatrixFromSource,
|
|
33
34
|
recompileSummary,
|
|
34
|
-
reconcileTypesFromDisk,
|
|
35
35
|
registeredProjectUpdateSkipped,
|
|
36
36
|
resolveAgentConfigToSkills,
|
|
37
37
|
resolveSource,
|
|
38
38
|
scopeBlockedStackAssignment,
|
|
39
|
-
skillMetadataUnusableDetail,
|
|
40
|
-
skillMetadataUnusableError
|
|
41
|
-
} from "../chunk-WCAUUBHO.js";
|
|
42
|
-
import {
|
|
43
|
-
getErrorMessage,
|
|
44
39
|
setVerbose,
|
|
40
|
+
skillMetadataUnusableDetail,
|
|
41
|
+
skillMetadataUnusableError,
|
|
45
42
|
verbose
|
|
46
|
-
} from "../chunk-
|
|
47
|
-
import "../chunk-
|
|
48
|
-
import "../chunk-VASLW636.js";
|
|
43
|
+
} from "../chunk-3PJLLBUS.js";
|
|
44
|
+
import "../chunk-7Z4N4JWQ.js";
|
|
49
45
|
import {
|
|
50
46
|
STANDARD_FILES
|
|
51
|
-
} from "../chunk-
|
|
47
|
+
} from "../chunk-G6G2FT2G.js";
|
|
52
48
|
import "../chunk-VZRO7RYT.js";
|
|
53
49
|
|
|
54
50
|
// src/cli/commands/compile.ts
|
|
@@ -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 discoverInstalledSkills,\n type DiscoveredSkills,\n} from \"../lib/operations\";\nimport {\n ConfigLoadError,\n effectivelyExcludedSkillIds,\n isActiveAt,\n loadProjectConfig,\n loadProjectConfigFromDir,\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 {\n ERROR_MESSAGES,\n STATUS_MESSAGES,\n INFO_MESSAGES,\n configTypesRefreshFailed,\n globalScopedAgentsHint,\n recompileSummary,\n registeredProjectUpdateSkipped,\n scopeBlockedStackAssignment,\n skillMetadataUnusableDetail,\n skillMetadataUnusableError,\n} from \"../utils/messages\";\nimport { reconcileTypesFromDisk, type GateReport } from \"../lib/config-gate/index.js\";\nimport type { Installation } from \"../lib/installation\";\nimport type { SkillScope } from \"../types/config\";\nimport type {\n AgentDefinition,\n AgentName,\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 };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Compile);\n setVerbose(flags.verbose);\n const cwd = process.cwd();\n\n const installations = await this.detectInstallations(cwd);\n await this.resolveAndLogSource(cwd);\n const agentDefs = await this.loadAgentDefsOrFail();\n await this.runCompilePasses(installations, agentDefs, cwd);\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 // A corrupt config (file present but unparseable) must not let compile run\n // config-less — that resurrects every deselected agent. Hard-error naming\n // the offending file before any compilation happens.\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 * Names where the marketplace came from — the project's own config first, then the global\n * one, then the default. `compile` takes no `--marketplace`: it recompiles an installation\n * that already recorded which marketplace its skill references answer to, and reading\n * a different one would write agents against a catalogue config.ts does not name.\n */\n private async resolveAndLogSource(projectDir: string): Promise<void> {\n this.log(STATUS_MESSAGES.RESOLVING_SOURCE);\n try {\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 totalPassesWithSkills = 0;\n for (const pass of passes) {\n const hadSkills = await this.runCompilePass(pass, cwd);\n if (hadSkills) totalPassesWithSkills++;\n }\n\n if (totalPassesWithSkills === 0) {\n this.error(ERROR_MESSAGES.NO_SKILLS_TO_COMPILE, { exit: EXIT_CODES.ERROR });\n }\n }\n\n /**\n * Discovers what this pass compiles from, and refuses the run when any installed\n * skill's metadata.yaml exists but describes no skill — before a count is printed,\n * an agent is written or the type unions are regenerated. Skipping such a skill is\n * what the config-types pass already does; loading it anyway is what this pass\n * used to do, so a single run both loaded and skipped the same file.\n */\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 /**\n * Names each offending file and its reason, then exits. The detail is LOGGED and\n * only the refusal is raised: oclif hard-wraps error text at the terminal width,\n * and a path broken across two lines is one nobody can copy.\n */\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 /**\n * A stack skill that is not among the discovered skills is dropped from every\n * agent that references it. The resolver only records that at verbose level, so\n * the default output would claim a successful recompile of an agent that no\n * longer matches config.ts. Name each dropped skill instead.\n */\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 * `config.ts` is the hand-editable half of the pair, so it can declare a pair the scope\n * rule forbids: a GLOBAL sub-agent whose stack carries a PROJECT-scoped skill. The\n * compile-time filter in `buildCompileAgents` drops that reference on the way to the\n * resolver and `compile` rewrites nothing in `config.ts`, so the row survives and is\n * dropped again on every future run — while the recompile summary reports a clean pass\n * over an agent that no longer carries what its own config says it does.\n *\n * The sibling of {@link warnUnresolvedStackSkills} one layer over: there the skill is\n * missing from disk, here it is present and unreachable from that sub-agent.\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 /**\n * The project pass compiled no agents, but the project config may still declare\n * global-scope agents whose stack lives in the global config. Without a pointer\n * the \"No agents to recompile\" line reads as a silent no-op after a global stack\n * change, so name the global context and the count.\n */\n private async hintGlobalScopedAgents(projectDir: string): Promise<void> {\n const loaded = await loadProjectConfigFromDir(projectDir);\n if (!loaded) return;\n\n const globalAgentCount = loaded.config.agents.filter(\n (agent) => !agent.excluded && agent.scope === \"global\",\n ).length;\n if (globalAgentCount === 0) return;\n\n this.log(globalScopedAgentsHint(globalAgentCount));\n }\n\n /**\n * The documented hand-edit workflow is \"edit config.ts, then run compile\", and\n * the type unions in config-types.ts are derived from config.ts — so a compile\n * pass that leaves them untouched strands stale unions after a hand-edit.\n * Regenerates them from the scope's persisted config exactly as the wizard\n * write path would: standalone narrowed unions at global scope, import-and-\n * extend at project scope. `matrixOnly` keeps the default-source path offline.\n * A failed refresh downgrades to a warning — the compiled agents are already\n * written and remain valid; only the type unions may still be stale.\n *\n * `skipExtraSources: true` is NOT a divergence from the wizard's full\n * multi-source load: extra-source loading only annotates each skill's\n * `availableSources`/`activeSource` for wizard UI tagging — it never adds\n * skills or categories to the matrix, and the config-types writer never reads\n * those annotations, so the emitted types are byte-identical either way\n * (pinned by the skipExtraSources parity test in local-installer.test.ts).\n * Skipping avoids fetching every registered extra source (network on a cold\n * cache, plus unreachable-remote warnings) on this offline compile path.\n */\n private async refreshConfigTypes(pass: CompilePass, cwd: string): Promise<void> {\n let report: GateReport;\n try {\n const loaded = await loadProjectConfigFromDir(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 const { matrix } = await loadSkillsMatrixFromSource({\n projectDir: pass.projectDir,\n skipExtraSources: true,\n matrixOnly: true,\n });\n // `cwd` is excluded from the fan-out, which only a global pass can perform:\n // whatever this invocation was run from is this command's own subject, so a\n // fan-out must never reach back into it.\n report = await reconcileTypesFromDisk(\n pass.projectDir,\n loaded.config,\n { matrix, 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 /**\n * Renders the fan-out the refresh above performed. Kept out of the refresh's\n * catch on purpose: a project the fan-out could not reach is reported as that,\n * not as a failure to refresh the type unions — which did succeed.\n */\n private reportPropagation(report: GateReport): void {\n for (const skippedPath of report.propagated.skipped) {\n this.warn(registeredProjectUpdateSkipped(skippedPath));\n }\n this.reportPropagatedRecompile(report);\n }\n\n private async runCompilePass(params: CompilePass, cwd: string): Promise<boolean> {\n const { label, projectDir, installation, sourcePath, scopeFilter } = params;\n\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 const { allSkills, totalSkillCount } = await this.discoverAllSkills(projectDir);\n\n if (totalSkillCount === 0) {\n this.log(`No skills found for ${label.toLowerCase()} pass, skipping`);\n // The config loads independently of discovered skills: a hand-edited\n // config.ts can list skills while nothing is installed for this scope,\n // and its type unions must follow the config rather than stay stale.\n await this.refreshConfigTypes(params, cwd);\n return false;\n }\n\n await this.warnUnresolvedStackSkills(projectDir, allSkills);\n await this.warnScopeDroppedStackPairs(projectDir);\n\n this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);\n try {\n const recompileResult = await compileAgents({\n projectDir,\n sourcePath,\n skills: allSkills,\n pluginDir: projectDir,\n outputDir: installation.agentsDir,\n ...(scopeFilter !== undefined && { scopeFilter }),\n });\n\n const { compiled, rewritten, failed, warnings } = recompileResult;\n const summary = recompileSummary(\n rewritten.length,\n compiled.length - rewritten.length,\n `${label.toLowerCase()} agents`,\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 } catch (error) {\n this.log(ERROR_MESSAGES.FAILED_COMPILE_AGENTS);\n this.handleError(error);\n }\n\n await this.refreshConfigTypes(params, cwd);\n\n this.log(\"\");\n this.logSuccess(`${label} compile complete!`);\n this.log(\"\");\n\n return true;\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 * The single pass this invocation owns.\n *\n * A compile run inside a project is a PROJECT-scope operation and writes nothing\n * outside that project: it compiles the project's own agents and refreshes the\n * project's own type unions, and never the global install's or another\n * registered project's. Propagation is a global operation's consequence — the\n * global config is what every project's config inlines — and a project compile\n * is not one.\n *\n * The global pass is therefore reached only where no project installation is in\n * play: at the home directory (where `detectBothInstallations` returns no\n * project by construction), or in a directory that has no config of its own, so\n * the global install is the only thing there is to compile.\n *\n * `scopeFilter` still narrows the project pass whenever both installations\n * exist: the project's config inlines the global entries, so an unfiltered pass\n * would compile global-scoped agents into the project's own 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/**\n * Every project-scoped skill that a GLOBAL sub-agent's stack assigns to itself, with the\n * sub-agents that assign it — exactly the pairs `buildCompileAgents`' scope filter drops on\n * the way to the resolver.\n *\n * Grouped by skill rather than emitted per pair, so one sentence accounts for every\n * sub-agent one skill was kept away from.\n */\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\n/** True when this sub-agent's stack names the skill, in any of its categories. */\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 ${totalSkillCount} skills (${pluginSkillCount} from plugins, ${localCount} local)`;\n }\n\n return pluginSkillCount > 0\n ? `Discovered ${pluginSkillCount} skills from plugins`\n : `Discovered ${totalSkillCount} local skills`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,aAAa;AACtB,OAAO,QAAQ;AACf,SAAS,cAAc;AAiDvB,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,EACH;AAAA,EAEA,MAAM,MAAqB;AACzB,UAAM,EAAE,MAAM,IAAI,MAAM,KAAK,MAAM,QAAO;AAC1C,eAAW,MAAM,OAAO;AACxB,UAAM,MAAM,QAAQ,IAAI;AAExB,UAAM,gBAAgB,MAAM,KAAK,oBAAoB,GAAG;AACxD,UAAM,KAAK,oBAAoB,GAAG;AAClC,UAAM,YAAY,MAAM,KAAK,oBAAoB;AACjD,UAAM,KAAK,iBAAiB,eAAe,WAAW,GAAG;AAAA,EAC3D;AAAA,EAEA,MAAc,oBAAoB,KAAyC;AACzE,QAAI;AACJ,QAAI;AACF,sBAAgB,MAAM,wBAAwB,GAAG;AAAA,IACnD,SAAS,OAAO;AAId,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;AAAA;AAAA,EAQA,MAAc,oBAAoB,YAAmC;AACnE,SAAK,IAAI,gBAAgB,gBAAgB;AACzC,QAAI;AACF,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,wBAAwB;AAC5B,eAAW,QAAQ,QAAQ;AACzB,YAAM,YAAY,MAAM,KAAK,eAAe,MAAM,GAAG;AACrD,UAAI,UAAW;AAAA,IACjB;AAEA,QAAI,0BAA0B,GAAG;AAC/B,WAAK,MAAM,eAAe,sBAAsB,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,IAC5E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,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;AAAA;AAAA;AAAA;AAAA,EAOQ,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;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,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;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,uBAAuB,YAAmC;AACtE,UAAM,SAAS,MAAM,yBAAyB,UAAU;AACxD,QAAI,CAAC,OAAQ;AAEb,UAAM,mBAAmB,OAAO,OAAO,OAAO;AAAA,MAC5C,CAAC,UAAU,CAAC,MAAM,YAAY,MAAM,UAAU;AAAA,IAChD,EAAE;AACF,QAAI,qBAAqB,EAAG;AAE5B,SAAK,IAAI,uBAAuB,gBAAgB,CAAC;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAc,mBAAmB,MAAmB,KAA4B;AAC9E,QAAI;AACJ,QAAI;AACF,YAAM,SAAS,MAAM,yBAAyB,KAAK,UAAU;AAC7D,UAAI,CAAC,QAAQ;AACX;AAAA,UACE,sBAAsB,KAAK,UAAU,oBAAe,eAAe,eAAe;AAAA,QACpF;AACA;AAAA,MACF;AAEA,YAAM,EAAE,OAAO,IAAI,MAAM,2BAA2B;AAAA,QAClD,YAAY,KAAK;AAAA,QACjB,kBAAkB;AAAA,QAClB,YAAY;AAAA,MACd,CAAC;AAID,eAAS,MAAM;AAAA,QACb,KAAK;AAAA,QACL,OAAO;AAAA,QACP,EAAE,QAAQ,QAAQ,KAAK,OAAO;AAAA,QAC9B,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;AAAA;AAAA;AAAA;AAAA,EAOQ,kBAAkB,QAA0B;AAClD,eAAW,eAAe,OAAO,WAAW,SAAS;AACnD,WAAK,KAAK,+BAA+B,WAAW,CAAC;AAAA,IACvD;AACA,SAAK,0BAA0B,MAAM;AAAA,EACvC;AAAA,EAEA,MAAc,eAAe,QAAqB,KAA+B;AAC/E,UAAM,EAAE,OAAO,YAAY,cAAc,YAAY,YAAY,IAAI;AAErE,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;AAE7C,UAAM,EAAE,WAAW,gBAAgB,IAAI,MAAM,KAAK,kBAAkB,UAAU;AAE9E,QAAI,oBAAoB,GAAG;AACzB,WAAK,IAAI,uBAAuB,MAAM,YAAY,CAAC,iBAAiB;AAIpE,YAAM,KAAK,mBAAmB,QAAQ,GAAG;AACzC,aAAO;AAAA,IACT;AAEA,UAAM,KAAK,0BAA0B,YAAY,SAAS;AAC1D,UAAM,KAAK,2BAA2B,UAAU;AAEhD,SAAK,IAAI,gBAAgB,kBAAkB;AAC3C,QAAI;AACF,YAAM,kBAAkB,MAAM,cAAc;AAAA,QAC1C;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,WAAW,aAAa;AAAA,QACxB,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,MACjD,CAAC;AAED,YAAM,EAAE,UAAU,WAAW,QAAQ,SAAS,IAAI;AAClD,YAAM,UAAU;AAAA,QACd,UAAU;AAAA,QACV,SAAS,SAAS,UAAU;AAAA,QAC5B,GAAG,MAAM,YAAY,CAAC;AAAA,MACxB;AAEA,UAAI,OAAO,SAAS,GAAG;AACrB,aAAK,IAAI,GAAG,OAAO,KAAK,OAAO,MAAM,UAAU;AAC/C,mBAAW,WAAW,UAAU;AAC9B,eAAK,KAAK,OAAO;AAAA,QACnB;AAAA,MACF,WAAW,SAAS,SAAS,GAAG;AAC9B,aAAK,IAAI,OAAO;AAAA,MAClB,OAAO;AACL,aAAK,IAAI,cAAc,sBAAsB;AAC7C,YAAI,UAAU,WAAW;AACvB,gBAAM,KAAK,uBAAuB,UAAU;AAAA,QAC9C;AAAA,MACF;AAEA,UAAI,SAAS,SAAS,GAAG;AACvB,gBAAQ,eAAe,SAAS,KAAK,IAAI,CAAC,EAAE;AAAA,MAC9C;AAAA,IACF,SAAS,OAAO;AACd,WAAK,IAAI,eAAe,qBAAqB;AAC7C,WAAK,YAAY,KAAK;AAAA,IACxB;AAEA,UAAM,KAAK,mBAAmB,QAAQ,GAAG;AAEzC,SAAK,IAAI,EAAE;AACX,SAAK,WAAW,GAAG,KAAK,oBAAoB;AAC5C,SAAK,IAAI,EAAE;AAEX,WAAO;AAAA,EACT;AACF;AA8BA,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;AAUA,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;AAGA,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,eAAe,YAAY,gBAAgB,kBAAkB,UAAU;AAAA,EAC9F;AAEA,SAAO,mBAAmB,IACtB,cAAc,gBAAgB,yBAC9B,cAAc,eAAe;AACnC;","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 discoverInstalledSkills,\n type DiscoveredSkills,\n} from \"../lib/operations\";\nimport {\n ConfigLoadError,\n effectivelyExcludedSkillIds,\n isActiveAt,\n loadProjectConfig,\n loadProjectConfigFromDir,\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 {\n ERROR_MESSAGES,\n STATUS_MESSAGES,\n INFO_MESSAGES,\n configTypesRefreshFailed,\n globalScopedAgentsHint,\n recompileSummary,\n registeredProjectUpdateSkipped,\n scopeBlockedStackAssignment,\n skillMetadataUnusableDetail,\n skillMetadataUnusableError,\n} from \"../utils/messages\";\nimport { reconcileTypesFromDisk, type GateReport } from \"../lib/config-gate/index.js\";\nimport type { Installation } from \"../lib/installation\";\nimport type { SkillScope } from \"../types/config\";\nimport type {\n AgentDefinition,\n AgentName,\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 };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Compile);\n setVerbose(flags.verbose);\n const cwd = process.cwd();\n\n const installations = await this.detectInstallations(cwd);\n await this.resolveAndLogSource(cwd);\n const agentDefs = await this.loadAgentDefsOrFail();\n await this.runCompilePasses(installations, agentDefs, cwd);\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 // A corrupt config (file present but unparseable) must not let compile run\n // config-less — that resurrects every deselected agent. Hard-error naming\n // the offending file before any compilation happens.\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 * Names where the marketplace came from — the project's own config first, then the global\n * one, then the default. `compile` takes no `--marketplace`: it recompiles an installation\n * that already recorded which marketplace its skill references answer to, and reading\n * a different one would write agents against a catalogue config.ts does not name.\n */\n private async resolveAndLogSource(projectDir: string): Promise<void> {\n this.log(STATUS_MESSAGES.RESOLVING_SOURCE);\n try {\n // ABORT on an unreadable config, and unreachable with one: `detectInstallation` reads the\n // same file first and already hard-errors, at both scopes — verified by hand at both.\n // The posture is recorded anyway, because what makes it unreachable is a guard in another\n // command's private helper rather than anything visible from here.\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 totalPassesWithSkills = 0;\n for (const pass of passes) {\n const hadSkills = await this.runCompilePass(pass, cwd);\n if (hadSkills) totalPassesWithSkills++;\n }\n\n if (totalPassesWithSkills === 0) {\n this.error(ERROR_MESSAGES.NO_SKILLS_TO_COMPILE, { exit: EXIT_CODES.ERROR });\n }\n }\n\n /**\n * Discovers what this pass compiles from, and refuses the run when any installed\n * skill's metadata.yaml exists but describes no skill — before a count is printed,\n * an agent is written or the type unions are regenerated. Skipping such a skill is\n * what the config-types pass already does; loading it anyway is what this pass\n * used to do, so a single run both loaded and skipped the same file.\n */\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 /**\n * Names each offending file and its reason, then exits. The detail is LOGGED and\n * only the refusal is raised: oclif hard-wraps error text at the terminal width,\n * and a path broken across two lines is one nobody can copy.\n */\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 /**\n * A stack skill that is not among the discovered skills is dropped from every\n * agent that references it. The resolver only records that at verbose level, so\n * the default output would claim a successful recompile of an agent that no\n * longer matches config.ts. Name each dropped skill instead.\n */\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 * `config.ts` is the hand-editable half of the pair, so it can declare a pair the scope\n * rule forbids: a GLOBAL sub-agent whose stack carries a PROJECT-scoped skill. The\n * compile-time filter in `buildCompileAgents` drops that reference on the way to the\n * resolver and `compile` rewrites nothing in `config.ts`, so the row survives and is\n * dropped again on every future run — while the recompile summary reports a clean pass\n * over an agent that no longer carries what its own config says it does.\n *\n * The sibling of {@link warnUnresolvedStackSkills} one layer over: there the skill is\n * missing from disk, here it is present and unreachable from that sub-agent.\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 /**\n * The project pass compiled no agents, but the project config may still declare\n * global-scope agents whose stack lives in the global config. Without a pointer\n * the \"No agents to recompile\" line reads as a silent no-op after a global stack\n * change, so name the global context and the count.\n */\n private async hintGlobalScopedAgents(projectDir: string): Promise<void> {\n const loaded = await loadProjectConfigFromDir(projectDir);\n if (!loaded) return;\n\n const globalAgentCount = loaded.config.agents.filter(\n (agent) => !agent.excluded && agent.scope === \"global\",\n ).length;\n if (globalAgentCount === 0) return;\n\n this.log(globalScopedAgentsHint(globalAgentCount));\n }\n\n /**\n * The documented hand-edit workflow is \"edit config.ts, then run compile\", and\n * the type unions in config-types.ts are derived from config.ts — so a compile\n * pass that leaves them untouched strands stale unions after a hand-edit.\n * Regenerates them from the scope's persisted config exactly as the wizard\n * write path would: standalone narrowed unions at global scope, import-and-\n * extend at project scope. `matrixOnly` keeps the default-source path offline.\n * A failed refresh downgrades to a warning — the compiled agents are already\n * written and remain valid; only the type unions may still be stale.\n *\n * `skipExtraSources: true` is NOT a divergence from the wizard's full\n * multi-source load: extra-source loading only annotates each skill's\n * `availableSources`/`activeSource` for wizard UI tagging — it never adds\n * skills or categories to the matrix, and the config-types writer never reads\n * those annotations, so the emitted types are byte-identical either way\n * (pinned by the skipExtraSources parity test in local-installer.test.ts).\n * Skipping avoids fetching every registered extra source (network on a cold\n * cache, plus unreachable-remote warnings) on this offline compile path.\n */\n private async refreshConfigTypes(pass: CompilePass, cwd: string): Promise<void> {\n let report: GateReport;\n try {\n const loaded = await loadProjectConfigFromDir(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 const { matrix } = await loadSkillsMatrixFromSource({\n projectDir: pass.projectDir,\n skipExtraSources: true,\n matrixOnly: true,\n });\n // `cwd` is excluded from the fan-out, which only a global pass can perform:\n // whatever this invocation was run from is this command's own subject, so a\n // fan-out must never reach back into it.\n report = await reconcileTypesFromDisk(\n pass.projectDir,\n loaded.config,\n { matrix, 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 /**\n * Renders the fan-out the refresh above performed. Kept out of the refresh's\n * catch on purpose: a project the fan-out could not reach is reported as that,\n * not as a failure to refresh the type unions — which did succeed.\n */\n private reportPropagation(report: GateReport): void {\n for (const skippedPath of report.propagated.skipped) {\n this.warn(registeredProjectUpdateSkipped(skippedPath));\n }\n this.reportPropagatedRecompile(report);\n }\n\n private async runCompilePass(params: CompilePass, cwd: string): Promise<boolean> {\n const { label, projectDir, installation, sourcePath, scopeFilter } = params;\n\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 const { allSkills, totalSkillCount } = await this.discoverAllSkills(projectDir);\n\n if (totalSkillCount === 0) {\n this.log(`No skills found for ${label.toLowerCase()} pass, skipping`);\n // The config loads independently of discovered skills: a hand-edited\n // config.ts can list skills while nothing is installed for this scope,\n // and its type unions must follow the config rather than stay stale.\n await this.refreshConfigTypes(params, cwd);\n return false;\n }\n\n await this.warnUnresolvedStackSkills(projectDir, allSkills);\n await this.warnScopeDroppedStackPairs(projectDir);\n\n this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);\n try {\n const recompileResult = await compileAgents({\n projectDir,\n sourcePath,\n skills: allSkills,\n pluginDir: projectDir,\n outputDir: installation.agentsDir,\n ...(scopeFilter !== undefined && { scopeFilter }),\n });\n\n const { compiled, rewritten, failed, warnings } = recompileResult;\n const summary = recompileSummary(\n rewritten.length,\n compiled.length - rewritten.length,\n `${label.toLowerCase()} agents`,\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 } catch (error) {\n this.log(ERROR_MESSAGES.FAILED_COMPILE_AGENTS);\n this.handleError(error);\n }\n\n await this.refreshConfigTypes(params, cwd);\n\n this.log(\"\");\n this.logSuccess(`${label} compile complete!`);\n this.log(\"\");\n\n return true;\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 * The single pass this invocation owns.\n *\n * A compile run inside a project is a PROJECT-scope operation and writes nothing\n * outside that project: it compiles the project's own agents and refreshes the\n * project's own type unions, and never the global install's or another\n * registered project's. Propagation is a global operation's consequence — the\n * global config is what every project's config inlines — and a project compile\n * is not one.\n *\n * The global pass is therefore reached only where no project installation is in\n * play: at the home directory (where `detectBothInstallations` returns no\n * project by construction), or in a directory that has no config of its own, so\n * the global install is the only thing there is to compile.\n *\n * `scopeFilter` still narrows the project pass whenever both installations\n * exist: the project's config inlines the global entries, so an unfiltered pass\n * would compile global-scoped agents into the project's own 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/**\n * Every project-scoped skill that a GLOBAL sub-agent's stack assigns to itself, with the\n * sub-agents that assign it — exactly the pairs `buildCompileAgents`' scope filter drops on\n * the way to the resolver.\n *\n * Grouped by skill rather than emitted per pair, so one sentence accounts for every\n * sub-agent one skill was kept away from.\n */\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\n/** True when this sub-agent's stack names the skill, in any of its categories. */\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 ${totalSkillCount} skills (${pluginSkillCount} from plugins, ${localCount} local)`;\n }\n\n return pluginSkillCount > 0\n ? `Discovered ${pluginSkillCount} skills from plugins`\n : `Discovered ${totalSkillCount} local skills`;\n}\n"],"mappings":"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","names":[]}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -2,78 +2,75 @@
|
|
|
2
2
|
import {
|
|
3
3
|
detectProject,
|
|
4
4
|
loadSource
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-F2AMBBIA.js";
|
|
5
|
+
} from "../chunk-H2DHTJKW.js";
|
|
6
|
+
import "../chunk-H25VRR2T.js";
|
|
7
|
+
import "../chunk-H4CL23HG.js";
|
|
9
8
|
import {
|
|
10
9
|
filterExcludedEntries,
|
|
11
10
|
listAgentMdFiles,
|
|
12
11
|
splitAgentsByProvenance
|
|
13
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-WMVOJY6V.js";
|
|
14
13
|
import {
|
|
15
14
|
BaseCommand,
|
|
16
15
|
EXIT_CODES
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
16
|
+
} from "../chunk-X52QUV4U.js";
|
|
17
|
+
import "../chunk-TPQ5M3BW.js";
|
|
18
|
+
import "../chunk-QNAMXQKF.js";
|
|
20
19
|
import {
|
|
21
20
|
ConfigDefaultExportError,
|
|
21
|
+
MarketplaceNameRefusedError,
|
|
22
|
+
SOURCE_ENV_VAR,
|
|
23
|
+
agentYamlGenerationSchema,
|
|
22
24
|
checkMatrixHealth,
|
|
23
25
|
configDirsInPlay,
|
|
24
26
|
declaresNoContent,
|
|
27
|
+
directoryExists,
|
|
25
28
|
discoverLocalSkills,
|
|
26
29
|
effectivelyExcludedSkillIds,
|
|
30
|
+
fileExists,
|
|
27
31
|
findConfigLoadFailures,
|
|
32
|
+
formatZodErrors,
|
|
33
|
+
getErrorMessage,
|
|
28
34
|
getInstalledPluginsRegistryPath,
|
|
29
35
|
getProjectConfigPath,
|
|
30
36
|
getProjectPluginsDir,
|
|
31
37
|
getStackSkillIds,
|
|
32
38
|
getUserPluginsDir,
|
|
33
39
|
getVerifiedPluginInstallPaths,
|
|
40
|
+
glob,
|
|
34
41
|
installBaseDir,
|
|
35
42
|
isHomeDirectory,
|
|
36
43
|
isLocalSource,
|
|
44
|
+
isRecord,
|
|
45
|
+
listDirectories,
|
|
37
46
|
listRegisteredPluginInstalls,
|
|
38
47
|
loadConfig,
|
|
39
48
|
loadProjectConfigFromDir,
|
|
40
49
|
loadProjectSourceConfig,
|
|
41
50
|
loadSkillsMatrixFromSource,
|
|
42
|
-
parseMarketplacePluginRef,
|
|
43
|
-
readForkedFromMetadata,
|
|
44
|
-
resolveInstallPaths,
|
|
45
|
-
resolvePrimarySourceEntry,
|
|
46
|
-
validateAgentFrontmatter,
|
|
47
|
-
validateAllPlugins,
|
|
48
|
-
validatePlugin,
|
|
49
|
-
validateProjectConfig,
|
|
50
|
-
validateSkillFrontmatter
|
|
51
|
-
} from "../chunk-WCAUUBHO.js";
|
|
52
|
-
import {
|
|
53
|
-
agentYamlGenerationSchema,
|
|
54
|
-
directoryExists,
|
|
55
|
-
fileExists,
|
|
56
|
-
formatZodErrors,
|
|
57
|
-
getErrorMessage,
|
|
58
|
-
glob,
|
|
59
|
-
isRecord,
|
|
60
|
-
listDirectories,
|
|
61
51
|
metadataValidationSchema,
|
|
62
52
|
parseFrontmatter,
|
|
53
|
+
parseMarketplacePluginRef,
|
|
63
54
|
readFile,
|
|
55
|
+
readForkedFromMetadata,
|
|
64
56
|
readSkillMetadata,
|
|
65
|
-
|
|
57
|
+
resolveInstallPaths,
|
|
58
|
+
resolvePrimarySourceEntry,
|
|
66
59
|
skillCategoriesFileSchema,
|
|
67
60
|
skillRulesFileSchema,
|
|
68
61
|
splitMetadataValidationIssues,
|
|
69
62
|
stackConfigValidationSchema,
|
|
70
63
|
stacksConfigSchema,
|
|
64
|
+
validateAgentFrontmatter,
|
|
65
|
+
validateAllPlugins,
|
|
66
|
+
validatePlugin,
|
|
67
|
+
validateProjectConfig,
|
|
68
|
+
validateSkillFrontmatter,
|
|
71
69
|
validateSkillMetadata
|
|
72
|
-
} from "../chunk-
|
|
70
|
+
} from "../chunk-3PJLLBUS.js";
|
|
73
71
|
import {
|
|
74
72
|
matrix
|
|
75
|
-
} from "../chunk-
|
|
76
|
-
import "../chunk-VASLW636.js";
|
|
73
|
+
} from "../chunk-7Z4N4JWQ.js";
|
|
77
74
|
import {
|
|
78
75
|
CLAUDE_SRC_DIR,
|
|
79
76
|
CLI_INVOKE_COMMAND,
|
|
@@ -81,6 +78,7 @@ import {
|
|
|
81
78
|
DIRS,
|
|
82
79
|
EJECT_SOURCE,
|
|
83
80
|
LOCAL_SKILLS_PATH,
|
|
81
|
+
MARKETPLACE_JSON,
|
|
84
82
|
PLUGIN_MANIFEST_DIR,
|
|
85
83
|
SKILLS_DIR_PATH,
|
|
86
84
|
SKILL_CATEGORIES_PATH,
|
|
@@ -88,7 +86,7 @@ import {
|
|
|
88
86
|
STACKS_FILE_PATH,
|
|
89
87
|
STANDARD_FILES,
|
|
90
88
|
UI_SYMBOLS
|
|
91
|
-
} from "../chunk-
|
|
89
|
+
} from "../chunk-G6G2FT2G.js";
|
|
92
90
|
import "../chunk-VZRO7RYT.js";
|
|
93
91
|
|
|
94
92
|
// src/cli/commands/doctor.ts
|
|
@@ -230,6 +228,7 @@ function checkMetadataSchema(rawMetadata, relPath) {
|
|
|
230
228
|
...warnings.map((message) => ({ severity: "warning", file: relPath, message }))
|
|
231
229
|
];
|
|
232
230
|
}
|
|
231
|
+
var MARKETPLACE_MANIFEST_PATH = path.join(PLUGIN_MANIFEST_DIR, MARKETPLACE_JSON);
|
|
233
232
|
async function checkCrossReferences(resolvedPath, reader) {
|
|
234
233
|
try {
|
|
235
234
|
await loadSkillsMatrixFromSource({ sourceFlag: resolvedPath, skipExtraSources: true });
|
|
@@ -237,15 +236,23 @@ async function checkCrossReferences(resolvedPath, reader) {
|
|
|
237
236
|
(healthIssue) => toSourceIssue(healthIssue, resolvedPath, reader)
|
|
238
237
|
);
|
|
239
238
|
} catch (error) {
|
|
240
|
-
return [
|
|
241
|
-
{
|
|
242
|
-
severity: "warning",
|
|
243
|
-
file: SKILL_CATEGORIES_PATH,
|
|
244
|
-
message: `Cross-reference validation skipped: failed to load categories/rules: ${getErrorMessage(error)}`
|
|
245
|
-
}
|
|
246
|
-
];
|
|
239
|
+
return [matrixLoadFailure(error)];
|
|
247
240
|
}
|
|
248
241
|
}
|
|
242
|
+
function matrixLoadFailure(error) {
|
|
243
|
+
if (error instanceof MarketplaceNameRefusedError) {
|
|
244
|
+
return {
|
|
245
|
+
severity: "error",
|
|
246
|
+
file: MARKETPLACE_MANIFEST_PATH,
|
|
247
|
+
message: getErrorMessage(error)
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
severity: "warning",
|
|
252
|
+
file: SKILL_CATEGORIES_PATH,
|
|
253
|
+
message: `Cross-reference validation skipped: failed to load categories/rules: ${getErrorMessage(error)}`
|
|
254
|
+
};
|
|
255
|
+
}
|
|
249
256
|
var SKILL_AUDIT_PATH = "src/cli/lib/configuration/skill-audit.ts";
|
|
250
257
|
function fileHoldingDefect(finding) {
|
|
251
258
|
switch (finding) {
|
|
@@ -931,19 +938,34 @@ async function checkPluginSkillsInstalled(config, projectDir) {
|
|
|
931
938
|
message: `${pluginSkills.length}/${pluginSkills.length} plugin-mode skills installed`
|
|
932
939
|
};
|
|
933
940
|
}
|
|
941
|
+
var MARKETPLACE_CHOSEN_BY = {
|
|
942
|
+
flag: "named by this run",
|
|
943
|
+
env: `named by ${SOURCE_ENV_VAR}`,
|
|
944
|
+
project: "named by this project's configuration",
|
|
945
|
+
global: "named by the global configuration",
|
|
946
|
+
default: "nothing here names one, so this is the default"
|
|
947
|
+
};
|
|
948
|
+
function howItWasReached(source, isLocal) {
|
|
949
|
+
return isLocal ? `Read ${source} from disk` : `Fetched ${source} over the network`;
|
|
950
|
+
}
|
|
951
|
+
function reachedMarketplace(result) {
|
|
952
|
+
const { source, sourceOrigin } = result.sourceConfig;
|
|
953
|
+
const skillCount = Object.keys(matrix.skills).length;
|
|
954
|
+
const sourceLabel = result.isLocal ? "local" : "remote";
|
|
955
|
+
return {
|
|
956
|
+
kind: "source",
|
|
957
|
+
status: "pass",
|
|
958
|
+
message: `Connected to ${sourceLabel}: ${result.sourcePath}`,
|
|
959
|
+
details: [
|
|
960
|
+
`${plural(skillCount, "skill")} available`,
|
|
961
|
+
`${howItWasReached(source, result.isLocal)} \u2014 ${MARKETPLACE_CHOSEN_BY[sourceOrigin]}`
|
|
962
|
+
]
|
|
963
|
+
};
|
|
964
|
+
}
|
|
934
965
|
async function checkSourceReachable(projectDir) {
|
|
935
966
|
try {
|
|
936
|
-
const { sourceResult
|
|
937
|
-
|
|
938
|
-
});
|
|
939
|
-
const skillCount = Object.keys(matrix.skills).length;
|
|
940
|
-
const sourceLabel = result.isLocal ? "local" : "remote";
|
|
941
|
-
return {
|
|
942
|
-
kind: "source",
|
|
943
|
-
status: "pass",
|
|
944
|
-
message: `Connected to ${sourceLabel}: ${result.sourcePath}`,
|
|
945
|
-
details: [`${skillCount} skills available`]
|
|
946
|
-
};
|
|
967
|
+
const { sourceResult } = await loadSource({ projectDir });
|
|
968
|
+
return reachedMarketplace(sourceResult);
|
|
947
969
|
} catch (error) {
|
|
948
970
|
const message = getErrorMessage(error);
|
|
949
971
|
return {
|
|
@@ -1175,9 +1197,8 @@ var Doctor = class _Doctor extends BaseCommand {
|
|
|
1175
1197
|
static flags = {};
|
|
1176
1198
|
async run() {
|
|
1177
1199
|
await this.parse(_Doctor);
|
|
1178
|
-
setVerbose(true);
|
|
1179
1200
|
const projectDir = process.cwd();
|
|
1180
|
-
this.printHeader();
|
|
1201
|
+
this.printHeader(await this.resolveBrandingName(projectDir));
|
|
1181
1202
|
const contentResults = await this.runContentChecks(projectDir);
|
|
1182
1203
|
const operationalResults = await this.runOperationalChecks(projectDir, contentResults);
|
|
1183
1204
|
const results = [...contentResults, ...operationalResults];
|
|
@@ -1186,9 +1207,9 @@ var Doctor = class _Doctor extends BaseCommand {
|
|
|
1186
1207
|
this.exit(EXIT_CODES.ERROR);
|
|
1187
1208
|
}
|
|
1188
1209
|
}
|
|
1189
|
-
printHeader() {
|
|
1210
|
+
printHeader(brandingName) {
|
|
1190
1211
|
this.log("");
|
|
1191
|
-
this.log(`${
|
|
1212
|
+
this.log(`${brandingName} Doctor`);
|
|
1192
1213
|
this.log("");
|
|
1193
1214
|
this.log(`${SECTION_INDENT}Checking configuration health...`);
|
|
1194
1215
|
this.log("");
|