agents-inc 0.154.0 → 0.156.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 +55 -0
- package/dist/chunk-2H7UWE2G.js +246 -0
- package/dist/chunk-2H7UWE2G.js.map +1 -0
- package/dist/{chunk-LA3JPESW.js → chunk-4A4L3YIW.js} +5 -5
- package/dist/chunk-4G2YHZIM.js +132 -0
- package/dist/chunk-4G2YHZIM.js.map +1 -0
- package/dist/{chunk-BZ4CZBOM.js → chunk-5F2YR5XV.js} +3 -3
- package/dist/{chunk-CHNA5RVS.js → chunk-5OKLCVM4.js} +3 -3
- package/dist/{chunk-ZU6DAR4S.js → chunk-5QZAK6J7.js} +7 -7
- package/dist/{chunk-ZU6DAR4S.js.map → chunk-5QZAK6J7.js.map} +1 -1
- package/dist/{chunk-NFH6SA62.js → chunk-6RLV45HN.js} +10 -10
- package/dist/{chunk-NFH6SA62.js.map → chunk-6RLV45HN.js.map} +1 -1
- package/dist/{chunk-GUDGCFSF.js → chunk-CLFHC2DK.js} +15 -106
- package/dist/chunk-CLFHC2DK.js.map +1 -0
- package/dist/chunk-D2CAV7MG.js +61 -0
- package/dist/chunk-D2CAV7MG.js.map +1 -0
- package/dist/{chunk-UW44KSYL.js → chunk-F2AMBBIA.js} +6 -6
- package/dist/{chunk-UW44KSYL.js.map → chunk-F2AMBBIA.js.map} +1 -1
- package/dist/{chunk-QQTYMW7N.js → chunk-F5T6TV4Z.js} +206 -73
- package/dist/chunk-F5T6TV4Z.js.map +1 -0
- package/dist/{chunk-K3O3YQYG.js → chunk-G47TDUK3.js} +2 -2
- package/dist/{chunk-AURY6RT6.js → chunk-GS2NZ3GD.js} +8 -8
- package/dist/chunk-GS2NZ3GD.js.map +1 -0
- package/dist/{chunk-5MFJ24VM.js → chunk-H6UTKTLK.js} +104 -250
- package/dist/chunk-H6UTKTLK.js.map +1 -0
- package/dist/{chunk-MJFIO5SX.js → chunk-HG4JPXJT.js} +11 -11
- package/dist/chunk-HG4JPXJT.js.map +1 -0
- package/dist/{chunk-IXEDSKMH.js → chunk-HTYH7CKN.js} +3 -3
- package/dist/{chunk-JC7DBPRD.js → chunk-HXKOIWLU.js} +2 -2
- package/dist/chunk-HXKOIWLU.js.map +1 -0
- package/dist/{chunk-NSJ2S7R5.js → chunk-ILUVL7WM.js} +2 -2
- package/dist/{chunk-R54KIGN2.js → chunk-IO5YBKHV.js} +13 -2
- package/dist/chunk-IO5YBKHV.js.map +1 -0
- package/dist/chunk-IXRZAHZF.js +53 -0
- package/dist/chunk-IXRZAHZF.js.map +1 -0
- package/dist/chunk-JCPANDNR.js +35 -0
- package/dist/chunk-JCPANDNR.js.map +1 -0
- package/dist/{chunk-NKCY2ULI.js → chunk-LJCNUP6M.js} +2 -2
- package/dist/{chunk-PRJD5MMQ.js → chunk-MHRC3KRX.js} +5 -5
- package/dist/chunk-MHRC3KRX.js.map +1 -0
- package/dist/chunk-MO5FGLVS.js +142 -0
- package/dist/chunk-MO5FGLVS.js.map +1 -0
- package/dist/{chunk-Q5FLW4JG.js → chunk-OKH64JZE.js} +2 -2
- package/dist/{chunk-WRRP47PY.js → chunk-PCC4LBKB.js} +2 -2
- package/dist/chunk-PMUABBPG.js +258 -0
- package/dist/chunk-PMUABBPG.js.map +1 -0
- package/dist/{chunk-2IMYK4WN.js → chunk-PNMM5HNX.js} +5 -5
- package/dist/{chunk-AKQ5QISO.js → chunk-QWVXOCXO.js} +6 -6
- package/dist/{chunk-IPJOMAWC.js → chunk-RWOYPOMR.js} +12 -2
- package/dist/{chunk-IPJOMAWC.js.map → chunk-RWOYPOMR.js.map} +1 -1
- package/dist/{chunk-ONWEOS77.js → chunk-SY4X2LND.js} +4 -4
- package/dist/{chunk-XGMOXMS4.js → chunk-TBOVYLQJ.js} +2 -2
- package/dist/{chunk-R7JV22QK.js → chunk-TNGMF4UX.js} +20 -20
- package/dist/{chunk-R7JV22QK.js.map → chunk-TNGMF4UX.js.map} +1 -1
- package/dist/{chunk-7VZV4O6B.js → chunk-UMH2YZKG.js} +14 -5
- package/dist/chunk-UMH2YZKG.js.map +1 -0
- package/dist/{chunk-6CNRMCFM.js → chunk-VPASBA7P.js} +2 -2
- package/dist/{chunk-CBF4ZYV3.js → chunk-WCAUUBHO.js} +1376 -741
- package/dist/chunk-WCAUUBHO.js.map +1 -0
- package/dist/{chunk-V3ENMW7G.js → chunk-WFRTHH3A.js} +3 -3
- package/dist/{chunk-DRKSYJZ2.js → chunk-WTJ3AY33.js} +1 -1
- package/dist/{chunk-DRKSYJZ2.js.map → chunk-WTJ3AY33.js.map} +1 -1
- package/dist/{chunk-XMEIVWAS.js → chunk-WUQ3MTPF.js} +11 -5
- package/dist/{chunk-XMEIVWAS.js.map → chunk-WUQ3MTPF.js.map} +1 -1
- package/dist/{chunk-4VCWL2IG.js → chunk-XAXJWXI4.js} +92 -59
- package/dist/chunk-XAXJWXI4.js.map +1 -0
- package/dist/{chunk-B66SC72V.js → chunk-Y5Y7XHVU.js} +4 -4
- package/dist/{chunk-FMYHWKGG.js → chunk-YO2LTXB4.js} +66 -16
- package/dist/chunk-YO2LTXB4.js.map +1 -0
- package/dist/{chunk-TUQF577Z.js → chunk-ZUAZHDKP.js} +40 -41
- package/dist/chunk-ZUAZHDKP.js.map +1 -0
- package/dist/commands/build/marketplace.js +98 -121
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +8 -8
- package/dist/commands/compile.js +19 -24
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +220 -79
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +549 -75
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +26 -21
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +41 -39
- package/dist/commands/list.js +11 -11
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +243 -0
- package/dist/commands/new/marketplace.js.map +1 -0
- package/dist/commands/search.js +16 -14
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +67 -0
- package/dist/commands/share.js.map +1 -0
- package/dist/commands/uninstall.js +61 -74
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +9 -9
- package/dist/commands/update.js.map +1 -1
- package/dist/components/common/prompt-confirm.js +1 -1
- package/dist/components/common/removal-plan-confirm.js +10 -0
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/wizard/category-grid.js +5 -5
- package/dist/components/wizard/checkbox-grid.js +5 -5
- package/dist/components/wizard/domain-selection.js +11 -11
- package/dist/components/wizard/run-wizard-session.js +29 -28
- package/dist/components/wizard/scroll-affordance.js +2 -2
- package/dist/components/wizard/skill-agent-summary.js +6 -6
- package/dist/components/wizard/source-grid.js +6 -6
- package/dist/components/wizard/stack-selection.js +8 -8
- package/dist/components/wizard/step-agents.js +10 -11
- package/dist/components/wizard/step-build.js +9 -9
- package/dist/components/wizard/step-confirm.js +10 -10
- package/dist/components/wizard/step-sources.js +10 -10
- package/dist/components/wizard/step-stack.js +9 -9
- package/dist/components/wizard/summary-panel.js +9 -9
- package/dist/components/wizard/toast.js +2 -2
- package/dist/components/wizard/wizard-layout.js +14 -14
- package/dist/components/wizard/wizard-tabs.js +2 -2
- package/dist/components/wizard/wizard.js +27 -27
- package/dist/copy-local-skills-NSUTBVLJ.js +14 -0
- package/dist/hooks/init.js +42 -62
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-X4E57I2U.js +15 -0
- package/dist/{loader-JIZDTR4G.js → loader-G6BFG2VA.js} +3 -3
- package/dist/recompile-project-agents-JE4MM72I.js +20 -0
- package/dist/{source-loader-OE6EJFPU.js → source-loader-3DL3NYUX.js} +7 -5
- package/dist/source-loader-3DL3NYUX.js.map +1 -0
- package/dist/src/agents/developer/ai-developer/critical-reminders.md +1 -1
- package/dist/src/agents/developer/ai-developer/critical-requirements.md +1 -1
- package/dist/src/agents/developer/ai-developer/identity.md +1 -1
- package/dist/src/agents/developer/ai-developer/playbook.md +1 -1
- package/dist/src/agents/developer/api-developer/identity.md +1 -1
- package/dist/src/agents/developer/cli-developer/identity.md +1 -1
- package/dist/src/agents/developer/web-developer/identity.md +1 -1
- package/dist/src/agents/meta/codex-keeper/identity.md +1 -1
- package/dist/src/agents/meta/convention-keeper/identity.md +1 -1
- package/dist/src/agents/meta/skill-summoner/identity.md +1 -1
- package/dist/src/agents/researcher/ai-researcher/identity.md +1 -1
- package/dist/src/agents/researcher/api-researcher/identity.md +1 -1
- package/dist/src/agents/researcher/cli-researcher/identity.md +1 -1
- package/dist/src/agents/researcher/web-researcher/identity.md +1 -1
- package/dist/src/agents/reviewer/reviewer/playbook.md +1 -1
- package/dist/src/agents/tester/ai-tester/identity.md +1 -1
- package/dist/src/agents/tester/api-tester/critical-reminders.md +1 -1
- package/dist/src/agents/tester/api-tester/critical-requirements.md +1 -1
- package/dist/src/agents/tester/api-tester/identity.md +2 -2
- package/dist/src/agents/tester/cli-tester/identity.md +1 -1
- package/dist/src/agents/tester/web-tester/identity.md +3 -3
- package/dist/stores/wizard-store.js +7 -5
- package/package.json +10 -7
- package/src/agents/developer/ai-developer/critical-reminders.md +1 -1
- package/src/agents/developer/ai-developer/critical-requirements.md +1 -1
- package/src/agents/developer/ai-developer/identity.md +1 -1
- package/src/agents/developer/ai-developer/playbook.md +1 -1
- package/src/agents/developer/api-developer/identity.md +1 -1
- package/src/agents/developer/cli-developer/identity.md +1 -1
- package/src/agents/developer/web-developer/identity.md +1 -1
- package/src/agents/meta/codex-keeper/identity.md +1 -1
- package/src/agents/meta/convention-keeper/identity.md +1 -1
- package/src/agents/meta/skill-summoner/identity.md +1 -1
- package/src/agents/researcher/ai-researcher/identity.md +1 -1
- package/src/agents/researcher/api-researcher/identity.md +1 -1
- package/src/agents/researcher/cli-researcher/identity.md +1 -1
- package/src/agents/researcher/web-researcher/identity.md +1 -1
- package/src/agents/reviewer/reviewer/playbook.md +1 -1
- package/src/agents/tester/ai-tester/identity.md +1 -1
- package/src/agents/tester/api-tester/critical-reminders.md +1 -1
- package/src/agents/tester/api-tester/critical-requirements.md +1 -1
- package/src/agents/tester/api-tester/identity.md +2 -2
- package/src/agents/tester/cli-tester/identity.md +1 -1
- package/src/agents/tester/web-tester/identity.md +3 -3
- package/src/schemas/custom-metadata.schema.json +3 -0
- package/src/schemas/metadata.schema.json +3 -0
- package/src/schemas/project-config.schema.json +4 -8
- package/src/schemas/project-source-config.schema.json +2 -2
- package/dist/chunk-4VCWL2IG.js.map +0 -1
- package/dist/chunk-5MFJ24VM.js.map +0 -1
- package/dist/chunk-7VZV4O6B.js.map +0 -1
- package/dist/chunk-AURY6RT6.js.map +0 -1
- package/dist/chunk-CBF4ZYV3.js.map +0 -1
- package/dist/chunk-FMYHWKGG.js.map +0 -1
- package/dist/chunk-GUDGCFSF.js.map +0 -1
- package/dist/chunk-JC7DBPRD.js.map +0 -1
- package/dist/chunk-MJFIO5SX.js.map +0 -1
- package/dist/chunk-OJJLYHM3.js +0 -34
- package/dist/chunk-OJJLYHM3.js.map +0 -1
- package/dist/chunk-PRJD5MMQ.js.map +0 -1
- package/dist/chunk-QQTYMW7N.js.map +0 -1
- package/dist/chunk-QUDQTO3O.js +0 -41
- package/dist/chunk-QUDQTO3O.js.map +0 -1
- package/dist/chunk-R54KIGN2.js.map +0 -1
- package/dist/chunk-TUQF577Z.js.map +0 -1
- package/dist/copy-local-skills-WVHJFRPK.js +0 -14
- package/dist/load-agent-defs-5OT54J5M.js +0 -15
- package/dist/recompile-project-agents-VREEPBDV.js +0 -20
- /package/dist/{chunk-LA3JPESW.js.map → chunk-4A4L3YIW.js.map} +0 -0
- /package/dist/{chunk-BZ4CZBOM.js.map → chunk-5F2YR5XV.js.map} +0 -0
- /package/dist/{chunk-CHNA5RVS.js.map → chunk-5OKLCVM4.js.map} +0 -0
- /package/dist/{chunk-K3O3YQYG.js.map → chunk-G47TDUK3.js.map} +0 -0
- /package/dist/{chunk-IXEDSKMH.js.map → chunk-HTYH7CKN.js.map} +0 -0
- /package/dist/{chunk-NSJ2S7R5.js.map → chunk-ILUVL7WM.js.map} +0 -0
- /package/dist/{chunk-NKCY2ULI.js.map → chunk-LJCNUP6M.js.map} +0 -0
- /package/dist/{chunk-Q5FLW4JG.js.map → chunk-OKH64JZE.js.map} +0 -0
- /package/dist/{chunk-WRRP47PY.js.map → chunk-PCC4LBKB.js.map} +0 -0
- /package/dist/{chunk-2IMYK4WN.js.map → chunk-PNMM5HNX.js.map} +0 -0
- /package/dist/{chunk-AKQ5QISO.js.map → chunk-QWVXOCXO.js.map} +0 -0
- /package/dist/{chunk-ONWEOS77.js.map → chunk-SY4X2LND.js.map} +0 -0
- /package/dist/{chunk-XGMOXMS4.js.map → chunk-TBOVYLQJ.js.map} +0 -0
- /package/dist/{chunk-6CNRMCFM.js.map → chunk-VPASBA7P.js.map} +0 -0
- /package/dist/{chunk-V3ENMW7G.js.map → chunk-WFRTHH3A.js.map} +0 -0
- /package/dist/{chunk-B66SC72V.js.map → chunk-Y5Y7XHVU.js.map} +0 -0
- /package/dist/{copy-local-skills-WVHJFRPK.js.map → components/common/removal-plan-confirm.js.map} +0 -0
- /package/dist/{load-agent-defs-5OT54J5M.js.map → copy-local-skills-NSUTBVLJ.js.map} +0 -0
- /package/dist/{loader-JIZDTR4G.js.map → load-agent-defs-X4E57I2U.js.map} +0 -0
- /package/dist/{recompile-project-agents-VREEPBDV.js.map → loader-G6BFG2VA.js.map} +0 -0
- /package/dist/{source-loader-OE6EJFPU.js.map → recompile-project-agents-JE4MM72I.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/eject.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport os from \"os\";\nimport { BaseCommand } from \"../base-command.js\";\nimport { copy, ensureDir, directoryExists, fileExists, listDirectories } from \"../utils/fs.js\";\nimport {\n CLAUDE_SRC_DIR,\n DEFAULT_BRANDING,\n DIRS,\n LOCAL_SKILLS_PATH,\n PROJECT_ROOT,\n STANDARD_FILES,\n} from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { loadSource } from \"../lib/operations/index.js\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport {\n resolveSource,\n loadProjectSourceConfig,\n getProjectConfigPath,\n} from \"../lib/configuration/index.js\";\nimport {\n ensureBlankPair,\n lazyGateDeps,\n mutateGlobal,\n writeProjectPartial,\n} from \"../lib/config-gate/index.js\";\nimport { isHomeDirectory } from \"../lib/installation/index.js\";\nimport { copySkillsToLocalFlattened, type CopiedSkill } from \"../lib/skills/index.js\";\nimport type { MergedSkillsMatrix, SkillId } from \"../types/index.js\";\nimport { typedKeys } from \"../utils/typed-object.js\";\n\nconst EJECT_TYPES = [\"agent-partials\", \"templates\", \"skills\", \"all\"] as const;\ntype EjectType = (typeof EJECT_TYPES)[number];\n\nfunction isEjectType(value: string): value is EjectType {\n return (EJECT_TYPES as readonly string[]).includes(value);\n}\n\nexport default class Eject extends BaseCommand {\n static summary = \"Eject skills, agent partials, or templates for local customization\";\n static description =\n \"Copy agent partials, templates, or skills to your project for customization. \" +\n \"Agent partials and templates are always copied from the CLI. \" +\n \"Skills are copied from the source this installation is configured to read \" +\n \"(the public marketplace by default).\";\n\n static examples = [\n {\n description: \"Eject agent partials for customization\",\n command: \"<%= config.bin %> <%= command.id %> agent-partials\",\n },\n {\n description: \"Eject only agent templates\",\n command: \"<%= config.bin %> <%= command.id %> templates\",\n },\n {\n description: \"Eject skills to local directory\",\n command: \"<%= config.bin %> <%= command.id %> skills\",\n },\n {\n description: \"Eject everything with force overwrite\",\n command: \"<%= config.bin %> <%= command.id %> all --force\",\n },\n {\n description: \"Eject to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> skills -o ./custom-dir\",\n },\n ];\n\n static args = {\n type: Args.string({\n description: \"What to eject: agent-partials, templates, skills, all\",\n required: false,\n options: [...EJECT_TYPES],\n }),\n };\n\n static flags = {\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing files\",\n default: false,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output directory (default: .claude/ in current directory)\",\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Eject);\n const projectDir = process.cwd();\n\n const ejectType = this.validateEjectType(args.type);\n const outputBase = await this.resolveOutputBase(flags, projectDir);\n\n this.printHeader(flags.output ? outputBase : undefined);\n\n const sourceResult = await this.loadSourceIfNeeded(ejectType, projectDir);\n await this.executeEject(ejectType, outputBase, flags, projectDir, sourceResult);\n await this.ensureConfig(projectDir, sourceResult);\n\n this.log(\"\");\n this.logSuccess(\"Eject complete!\");\n this.log(\"\");\n }\n\n private validateEjectType(typeArg: string | undefined): EjectType {\n if (!typeArg) {\n this.error(\"Please specify what to eject: agent-partials, templates, skills, or all\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!isEjectType(typeArg)) {\n this.error(`Unknown eject type: ${typeArg}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n return typeArg;\n }\n\n private async resolveOutputBase(\n flags: { output: string | undefined },\n projectDir: string,\n ): Promise<string> {\n if (flags.output) {\n const expandedPath = flags.output.startsWith(\"~\")\n ? path.join(os.homedir(), flags.output.slice(1))\n : flags.output;\n const outputBase = path.resolve(projectDir, expandedPath);\n\n if (await fileExists(outputBase)) {\n this.error(`Output path exists as a file: ${outputBase}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n return outputBase;\n }\n\n return path.join(projectDir, CLAUDE_SRC_DIR);\n }\n\n private printHeader(outputBase?: string): void {\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Eject`);\n this.log(\"\");\n\n if (outputBase) {\n this.log(`Output directory: ${outputBase}`);\n }\n }\n\n private async loadSourceIfNeeded(\n ejectType: EjectType,\n projectDir: string,\n ): Promise<SourceLoadResult | undefined> {\n if (ejectType === \"skills\" || ejectType === \"all\") {\n const loaded = await loadSource({ projectDir });\n return loaded.sourceResult;\n }\n return undefined;\n }\n\n private async executeEject(\n ejectType: EjectType,\n outputBase: string,\n flags: { force: boolean; output: string | undefined },\n projectDir: string,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n const directOutput = !!flags.output;\n\n switch (ejectType) {\n case \"agent-partials\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n break;\n case \"templates\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, true);\n break;\n case \"skills\":\n if (!sourceResult) {\n throw new Error(\"Source must be loaded for skills eject\");\n }\n await this.handleSkills(projectDir, flags.force, sourceResult, directOutput, outputBase);\n break;\n case \"all\":\n if (!sourceResult) {\n throw new Error(\"Source must be loaded for full eject\");\n }\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n await this.handleAgentPartials(outputBase, true, directOutput, true);\n await this.handleSkills(projectDir, flags.force, sourceResult, directOutput, outputBase);\n break;\n default: {\n const _exhaustive: never = ejectType;\n return _exhaustive;\n }\n }\n }\n\n private async ensureConfig(\n projectDir: string,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n const configResult = await ensureMinimalConfig({\n projectDir,\n ...(sourceResult !== undefined && { sourceResult }),\n });\n if (configResult.created) {\n this.logSuccess(`Created ${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS}`);\n }\n }\n\n private async handleAgentPartials(\n outputBase: string,\n force: boolean,\n directOutput: boolean,\n templatesOnly: boolean,\n ): Promise<void> {\n const result = await ejectAgentPartials({\n outputBase,\n force,\n directOutput,\n templatesOnly,\n });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n if (result.templatesSkipped) {\n this.warn(\n \"Agent templates already exist — skipping templates, only ejecting agent partials.\",\n );\n }\n\n this.logSuccess(\n `${templatesOnly ? \"Agent templates\" : \"Agent partials\"} ejected to ${result.destDir}`,\n );\n this.log(\n templatesOnly\n ? \"You can now customize agent templates locally.\"\n : \"You can now customize templates, agent intro, workflow, and examples locally.\",\n );\n }\n\n private async handleSkills(\n projectDir: string,\n force: boolean,\n sourceResult: SourceLoadResult,\n directOutput: boolean,\n outputBase: string,\n ): Promise<void> {\n const result = await ejectSkills({\n projectDir,\n force,\n sourceResult,\n matrix,\n directOutput,\n ...(directOutput && { customOutputBase: outputBase }),\n });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n this.logSuccess(\n `${result.copiedSkills.length} skills ejected to ${result.destDir} from ${result.sourceLabel}`,\n );\n this.log(\"You can now customize skill content locally.\");\n }\n}\n\ntype EjectAgentPartialsOptions = {\n outputBase: string;\n force: boolean;\n /** When true, outputBase is used directly as the destination (no subdirectory nesting). */\n directOutput?: boolean;\n /** When true, ejects only the _templates directory instead of the full agents directory. */\n templatesOnly?: boolean;\n};\n\ntype EjectAgentPartialsResult =\n | {\n skipped: true;\n skipReason: string;\n templatesSkipped: false;\n }\n | {\n skipped: false;\n /** Destination directory that was written to. */\n destDir: string;\n /** Whether templates were skipped during a full agent-partials eject (existing templates preserved). */\n templatesSkipped: boolean;\n };\n\n/**\n * Copies agent partials or templates from the CLI source to a target directory.\n *\n * When `templatesOnly` is true, copies only the _templates subdirectory.\n * When false, copies the full agents directory (optionally skipping existing templates).\n *\n * Returns structured data — the command decides what to log.\n */\n/** Direct output writes to the base itself; otherwise agents/ (plus templates/ in templates-only mode). */\nfunction resolveEjectDestDir(\n outputBase: string,\n directOutput: boolean,\n templatesOnly: boolean,\n): string {\n if (directOutput) return outputBase;\n const agentsDir = path.join(outputBase, path.basename(DIRS.agents));\n return templatesOnly ? path.join(agentsDir, path.basename(DIRS.templates)) : agentsDir;\n}\n\nasync function ejectAgentPartials(\n options: EjectAgentPartialsOptions,\n): Promise<EjectAgentPartialsResult> {\n const { outputBase, force, directOutput = false, templatesOnly = false } = options;\n\n const sourceDir = templatesOnly\n ? path.join(PROJECT_ROOT, DIRS.templates)\n : path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(sourceDir))) {\n return {\n skipped: true,\n skipReason: templatesOnly\n ? \"No agent templates found in CLI.\"\n : \"No agent partials found in CLI.\",\n templatesSkipped: false,\n };\n }\n\n const destDir = resolveEjectDestDir(outputBase, directOutput, templatesOnly);\n\n const templatesBasename = path.basename(DIRS.templates);\n\n if ((await directoryExists(destDir)) && !force) {\n if (templatesOnly) {\n return {\n skipped: true,\n skipReason: `Agent templates already exist at ${destDir}. Use --force to overwrite.`,\n templatesSkipped: false,\n };\n }\n\n const hasTemplates = await directoryExists(path.join(destDir, templatesBasename));\n if ((await hasAgentPartialDirs(destDir)) && !hasTemplates) {\n return {\n skipped: true,\n skipReason: `Agent partials already exist at ${destDir}. Use --force to overwrite.`,\n templatesSkipped: false,\n };\n }\n }\n\n await ensureDir(destDir);\n\n const skipTemplates =\n !templatesOnly && !force && (await directoryExists(path.join(destDir, templatesBasename)));\n\n if (skipTemplates) {\n const sourceEntries = await listDirectories(sourceDir);\n const nonTemplateEntries = sourceEntries.filter((entry) => entry !== templatesBasename);\n for (const entry of nonTemplateEntries) {\n await copy(path.join(sourceDir, entry), path.join(destDir, entry));\n }\n } else {\n await copy(sourceDir, destDir);\n }\n\n return {\n skipped: false,\n destDir,\n templatesSkipped: skipTemplates,\n };\n}\n\ntype EjectSkillsOptions = {\n projectDir: string;\n force: boolean;\n sourceResult: SourceLoadResult;\n matrix: MergedSkillsMatrix;\n /** When true, uses customOutputBase as destination instead of LOCAL_SKILLS_PATH. */\n directOutput?: boolean;\n customOutputBase?: string;\n};\n\ntype EjectSkillsResult =\n | {\n skipped: true;\n skipReason: string;\n copiedSkills: [];\n }\n | {\n skipped: false;\n /** Array of skills that were copied. */\n copiedSkills: CopiedSkill[];\n /** Destination directory that was written to. */\n destDir: string;\n /** Label describing the source that skills were copied from. */\n sourceLabel: string;\n };\n\n/**\n * Copies non-local skills from source to a target directory.\n *\n * Filters out skills already marked as local, then copies the remaining skills\n * using copySkillsToLocalFlattened.\n *\n * Returns structured data — the command decides what to log.\n */\nasync function ejectSkills(options: EjectSkillsOptions): Promise<EjectSkillsResult> {\n const {\n projectDir,\n force,\n sourceResult,\n matrix,\n directOutput = false,\n customOutputBase,\n } = options;\n\n const destDir =\n directOutput && customOutputBase ? customOutputBase : path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if ((await directoryExists(destDir)) && !force) {\n return {\n skipped: true,\n skipReason: `Skills already exist at ${destDir}. Use --force to overwrite.`,\n copiedSkills: [],\n };\n }\n\n const skillIds = typedKeys<SkillId>(matrix.skills).filter(\n (skillId) => !matrix.skills[skillId]?.local,\n );\n\n if (skillIds.length === 0) {\n return {\n skipped: true,\n skipReason: \"No skills found in source to eject.\",\n copiedSkills: [],\n };\n }\n\n await ensureDir(destDir);\n\n const copiedSkills = await copySkillsToLocalFlattened(skillIds, destDir, sourceResult);\n\n const sourceLabel = sourceResult.isLocal\n ? sourceResult.sourcePath\n : sourceResult.marketplace || sourceResult.sourceConfig.source;\n\n return {\n skipped: false,\n copiedSkills,\n destDir,\n sourceLabel,\n };\n}\n\ntype EnsureMinimalConfigOptions = {\n projectDir: string;\n sourceResult?: SourceLoadResult;\n};\n\ntype EnsureMinimalConfigResult = {\n /** Path to the config file. */\n configPath: string;\n /** Whether a new config was created. */\n created: boolean;\n};\n\n/**\n * Ensures a minimal config.ts exists so `npx agents-inc compile` works after eject.\n *\n * If the config already exists, returns immediately with `created: false`.\n * Otherwise generates a minimal config from the resolved source and project metadata.\n *\n * Returns structured data — the command decides what to log.\n */\nasync function ensureMinimalConfig(\n options: EnsureMinimalConfigOptions,\n): Promise<EnsureMinimalConfigResult> {\n const { projectDir, sourceResult } = options;\n\n const tsConfigPath = getProjectConfigPath(projectDir);\n\n if (await fileExists(tsConfigPath)) {\n return { configPath: tsConfigPath, created: false };\n }\n\n const resolvedConfig =\n sourceResult?.sourceConfig ?? (await resolveSource({ caller: \"stored\", projectDir }));\n const existingProjectConfig = await loadProjectSourceConfig(projectDir);\n const source = resolvedConfig.source || undefined;\n\n // At the home directory the invented config IS the global manifest, and the\n // file it opens with `import type { ProjectConfig } from \"./config-types\"`\n // cannot resolve its own types without the sibling. The gate writes the pair.\n if (isHomeDirectory(projectDir)) {\n await ensureBlankPair();\n if (source) await recordSource(projectDir, source);\n return { configPath: tsConfigPath, created: true };\n }\n\n await writeProjectPartial(\n projectDir,\n {\n skills: [],\n agents: [],\n ...(source ? { source } : {}),\n ...(resolvedConfig.marketplace ? { marketplace: resolvedConfig.marketplace } : {}),\n ...(existingProjectConfig?.author ? { author: existingProjectConfig.author } : {}),\n ...(existingProjectConfig?.agentsSource\n ? { agentsSource: existingProjectConfig.agentsSource }\n : {}),\n },\n { fallbackName: path.basename(projectDir) },\n );\n\n return { configPath: tsConfigPath, created: true };\n}\n\n/**\n * Records `source` in whichever scope's config `projectDir` names. At the home\n * directory that config is the global manifest every project's generated types\n * import from, so the write goes through the gate: registered projects inline\n * the scalar and follow it.\n */\nasync function recordSource(projectDir: string, source: string): Promise<void> {\n if (isHomeDirectory(projectDir)) {\n await mutateGlobal(\n { kind: \"set-source\", source, fallbackName: path.basename(projectDir) },\n lazyGateDeps(projectDir),\n );\n return;\n }\n\n const existing = (await loadProjectSourceConfig(projectDir)) ?? {};\n await writeProjectPartial(\n projectDir,\n { ...existing, source },\n { fallbackName: path.basename(projectDir) },\n );\n}\n\n/** Checks whether the agents directory contains any agent subdirectories (not just _templates). */\nasync function hasAgentPartialDirs(agentsDir: string): Promise<boolean> {\n const subdirs = await listDirectories(agentsDir);\n const templatesBasename = path.basename(DIRS.templates);\n return subdirs.some((dir) => dir !== templatesBasename);\n}\n"],"mappings":"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","names":["matrix"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/eject.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport os from \"os\";\nimport { BaseCommand } from \"../base-command.js\";\nimport { copy, ensureDir, directoryExists, fileExists, listDirectories } from \"../utils/fs.js\";\nimport {\n CLAUDE_SRC_DIR,\n DEFAULT_BRANDING,\n DIRS,\n LOCAL_SKILLS_PATH,\n PROJECT_ROOT,\n STANDARD_FILES,\n} from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { loadSource } from \"../lib/operations/index.js\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport {\n resolveSource,\n loadProjectSourceConfig,\n getProjectConfigPath,\n} from \"../lib/configuration/index.js\";\nimport {\n ensureBlankPair,\n lazyGateDeps,\n mutateGlobal,\n writeProjectPartial,\n} from \"../lib/config-gate/index.js\";\nimport { isHomeDirectory } from \"../lib/installation/index.js\";\nimport { copySkillsToLocalFlattened, type CopiedSkill } from \"../lib/skills/index.js\";\nimport { INFO_MESSAGES } from \"../utils/messages.js\";\nimport type { MergedSkillsMatrix, SkillId } from \"../types/index.js\";\nimport { typedKeys } from \"../utils/typed-object.js\";\n\nconst EJECT_TYPES = [\"agent-partials\", \"templates\", \"skills\", \"all\"] as const;\ntype EjectType = (typeof EJECT_TYPES)[number];\n\nfunction isEjectType(value: string): value is EjectType {\n return (EJECT_TYPES as readonly string[]).includes(value);\n}\n\nexport default class Eject extends BaseCommand {\n static summary = \"Eject skills, agent partials, or templates for local customization\";\n static description =\n \"Copy agent partials, templates, or skills to your project for customization. \" +\n \"Agent partials and templates are always copied from the CLI. \" +\n \"Skills are copied from the marketplace this installation is configured to read \" +\n \"(the public one by default).\";\n\n static examples = [\n {\n description: \"Eject agent partials for customization\",\n command: \"<%= config.bin %> <%= command.id %> agent-partials\",\n },\n {\n description: \"Eject only agent templates\",\n command: \"<%= config.bin %> <%= command.id %> templates\",\n },\n {\n description: \"Eject skills to local directory\",\n command: \"<%= config.bin %> <%= command.id %> skills\",\n },\n {\n description: \"Eject everything with force overwrite\",\n command: \"<%= config.bin %> <%= command.id %> all --force\",\n },\n {\n description: \"Eject to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> skills -o ./custom-dir\",\n },\n ];\n\n static args = {\n type: Args.string({\n description: \"What to eject: agent-partials, templates, skills, all\",\n required: false,\n options: [...EJECT_TYPES],\n }),\n };\n\n static flags = {\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing files\",\n default: false,\n }),\n output: Flags.string({\n char: \"o\",\n // No `default:`, and no default named here either: each eject type has its own\n // destination and this flag replaces all three at once. The reference page carries\n // the table; a one-line description that picked one of the three would be wrong\n // about the other two, which is what it was.\n description:\n \"Write everything into this directory instead of each eject type's own destination\",\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Eject);\n const projectDir = process.cwd();\n\n const ejectType = this.validateEjectType(args.type);\n const outputBase = await this.resolveOutputBase(flags, projectDir);\n\n this.printHeader(flags.output ? outputBase : undefined);\n\n const sourceResult = await this.loadSourceIfNeeded(ejectType, projectDir);\n await this.executeEject(ejectType, outputBase, flags, projectDir, sourceResult);\n await this.ensureConfig(projectDir, sourceResult);\n\n this.log(\"\");\n this.logSuccess(\"Eject complete!\");\n this.log(\"\");\n }\n\n private validateEjectType(typeArg: string | undefined): EjectType {\n if (!typeArg) {\n this.error(\"Please specify what to eject: agent-partials, templates, skills, or all\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!isEjectType(typeArg)) {\n this.error(`Unknown eject type: ${typeArg}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n return typeArg;\n }\n\n private async resolveOutputBase(\n flags: { output: string | undefined },\n projectDir: string,\n ): Promise<string> {\n if (flags.output) {\n const expandedPath = flags.output.startsWith(\"~\")\n ? path.join(os.homedir(), flags.output.slice(1))\n : flags.output;\n const outputBase = path.resolve(projectDir, expandedPath);\n\n if (await fileExists(outputBase)) {\n this.error(`Output path exists as a file: ${outputBase}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n return outputBase;\n }\n\n return path.join(projectDir, CLAUDE_SRC_DIR);\n }\n\n private printHeader(outputBase?: string): void {\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Eject`);\n this.log(\"\");\n\n if (outputBase) {\n this.log(`Output directory: ${outputBase}`);\n }\n }\n\n private async loadSourceIfNeeded(\n ejectType: EjectType,\n projectDir: string,\n ): Promise<SourceLoadResult | undefined> {\n if (ejectType === \"skills\" || ejectType === \"all\") {\n const loaded = await loadSource({ projectDir });\n return loaded.sourceResult;\n }\n return undefined;\n }\n\n private async executeEject(\n ejectType: EjectType,\n outputBase: string,\n flags: { force: boolean; output: string | undefined },\n projectDir: string,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n const directOutput = !!flags.output;\n\n switch (ejectType) {\n case \"agent-partials\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n break;\n case \"templates\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, true);\n break;\n case \"skills\":\n if (!sourceResult) {\n throw new Error(\"The marketplace must be loaded for skills eject\");\n }\n await this.handleSkills(projectDir, flags.force, sourceResult, directOutput, outputBase);\n break;\n case \"all\":\n if (!sourceResult) {\n throw new Error(\"The marketplace must be loaded for full eject\");\n }\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n await this.handleAgentPartials(outputBase, true, directOutput, true);\n await this.handleSkills(projectDir, flags.force, sourceResult, directOutput, outputBase);\n break;\n default: {\n const _exhaustive: never = ejectType;\n return _exhaustive;\n }\n }\n }\n\n private async ensureConfig(\n projectDir: string,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n const configResult = await ensureMinimalConfig({\n projectDir,\n ...(sourceResult !== undefined && { sourceResult }),\n });\n if (configResult.created) {\n this.logSuccess(`Created ${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS}`);\n }\n }\n\n private async handleAgentPartials(\n outputBase: string,\n force: boolean,\n directOutput: boolean,\n templatesOnly: boolean,\n ): Promise<void> {\n const result = await ejectAgentPartials({\n outputBase,\n force,\n directOutput,\n templatesOnly,\n });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n if (result.templatesSkipped) {\n this.warn(\n \"Agent templates already exist — skipping templates, only ejecting agent partials.\",\n );\n }\n\n this.logSuccess(\n `${templatesOnly ? \"Agent templates\" : \"Agent partials\"} ejected to ${result.destDir}`,\n );\n this.log(\n templatesOnly\n ? \"You can now customize agent templates locally.\"\n : INFO_MESSAGES.AGENT_PARTIALS_CUSTOMIZABLE,\n );\n }\n\n private async handleSkills(\n projectDir: string,\n force: boolean,\n sourceResult: SourceLoadResult,\n directOutput: boolean,\n outputBase: string,\n ): Promise<void> {\n const result = await ejectSkills({\n projectDir,\n force,\n sourceResult,\n matrix,\n directOutput,\n ...(directOutput && { customOutputBase: outputBase }),\n });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n this.logSuccess(\n `${result.copiedSkills.length} skills ejected to ${result.destDir} from ${result.sourceLabel}`,\n );\n this.log(\"You can now customize skill content locally.\");\n }\n}\n\ntype EjectAgentPartialsOptions = {\n outputBase: string;\n force: boolean;\n /** When true, outputBase is used directly as the destination (no subdirectory nesting). */\n directOutput?: boolean;\n /** When true, ejects only the _templates directory instead of the full agents directory. */\n templatesOnly?: boolean;\n};\n\ntype EjectAgentPartialsResult =\n | {\n skipped: true;\n skipReason: string;\n templatesSkipped: false;\n }\n | {\n skipped: false;\n /** Destination directory that was written to. */\n destDir: string;\n /** Whether templates were skipped during a full agent-partials eject (existing templates preserved). */\n templatesSkipped: boolean;\n };\n\n/**\n * Copies agent partials or templates from the CLI source to a target directory.\n *\n * When `templatesOnly` is true, copies only the _templates subdirectory.\n * When false, copies the full agents directory (optionally skipping existing templates).\n *\n * Returns structured data — the command decides what to log.\n */\n/** Direct output writes to the base itself; otherwise agents/ (plus templates/ in templates-only mode). */\nfunction resolveEjectDestDir(\n outputBase: string,\n directOutput: boolean,\n templatesOnly: boolean,\n): string {\n if (directOutput) return outputBase;\n const agentsDir = path.join(outputBase, path.basename(DIRS.agents));\n return templatesOnly ? path.join(agentsDir, path.basename(DIRS.templates)) : agentsDir;\n}\n\nasync function ejectAgentPartials(\n options: EjectAgentPartialsOptions,\n): Promise<EjectAgentPartialsResult> {\n const { outputBase, force, directOutput = false, templatesOnly = false } = options;\n\n const sourceDir = templatesOnly\n ? path.join(PROJECT_ROOT, DIRS.templates)\n : path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(sourceDir))) {\n return {\n skipped: true,\n skipReason: templatesOnly\n ? \"No agent templates found in CLI.\"\n : \"No agent partials found in CLI.\",\n templatesSkipped: false,\n };\n }\n\n const destDir = resolveEjectDestDir(outputBase, directOutput, templatesOnly);\n\n const templatesBasename = path.basename(DIRS.templates);\n\n if ((await directoryExists(destDir)) && !force) {\n if (templatesOnly) {\n return {\n skipped: true,\n skipReason: `Agent templates already exist at ${destDir}. Use --force to overwrite.`,\n templatesSkipped: false,\n };\n }\n\n const hasTemplates = await directoryExists(path.join(destDir, templatesBasename));\n if ((await hasAgentPartialDirs(destDir)) && !hasTemplates) {\n return {\n skipped: true,\n skipReason: `Agent partials already exist at ${destDir}. Use --force to overwrite.`,\n templatesSkipped: false,\n };\n }\n }\n\n await ensureDir(destDir);\n\n const skipTemplates =\n !templatesOnly && !force && (await directoryExists(path.join(destDir, templatesBasename)));\n\n if (skipTemplates) {\n const sourceEntries = await listDirectories(sourceDir);\n const nonTemplateEntries = sourceEntries.filter((entry) => entry !== templatesBasename);\n for (const entry of nonTemplateEntries) {\n await copy(path.join(sourceDir, entry), path.join(destDir, entry));\n }\n } else {\n await copy(sourceDir, destDir);\n }\n\n return {\n skipped: false,\n destDir,\n templatesSkipped: skipTemplates,\n };\n}\n\ntype EjectSkillsOptions = {\n projectDir: string;\n force: boolean;\n sourceResult: SourceLoadResult;\n matrix: MergedSkillsMatrix;\n /** When true, uses customOutputBase as destination instead of LOCAL_SKILLS_PATH. */\n directOutput?: boolean;\n customOutputBase?: string;\n};\n\ntype EjectSkillsResult =\n | {\n skipped: true;\n skipReason: string;\n copiedSkills: [];\n }\n | {\n skipped: false;\n /** Array of skills that were copied. */\n copiedSkills: CopiedSkill[];\n /** Destination directory that was written to. */\n destDir: string;\n /** Label describing the source that skills were copied from. */\n sourceLabel: string;\n };\n\n/**\n * Copies non-local skills from source to a target directory.\n *\n * Filters out skills already marked as local, then copies the remaining skills\n * using copySkillsToLocalFlattened.\n *\n * Returns structured data — the command decides what to log.\n */\nasync function ejectSkills(options: EjectSkillsOptions): Promise<EjectSkillsResult> {\n const {\n projectDir,\n force,\n sourceResult,\n matrix,\n directOutput = false,\n customOutputBase,\n } = options;\n\n const destDir =\n directOutput && customOutputBase ? customOutputBase : path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if ((await directoryExists(destDir)) && !force) {\n return {\n skipped: true,\n skipReason: `Skills already exist at ${destDir}. Use --force to overwrite.`,\n copiedSkills: [],\n };\n }\n\n const skillIds = typedKeys<SkillId>(matrix.skills).filter(\n (skillId) => !matrix.skills[skillId]?.local,\n );\n\n if (skillIds.length === 0) {\n return {\n skipped: true,\n skipReason: \"No skills found in the marketplace to eject.\",\n copiedSkills: [],\n };\n }\n\n await ensureDir(destDir);\n\n const copiedSkills = await copySkillsToLocalFlattened(skillIds, destDir, sourceResult);\n\n const sourceLabel = sourceResult.isLocal\n ? sourceResult.sourcePath\n : sourceResult.marketplace || sourceResult.sourceConfig.source;\n\n return {\n skipped: false,\n copiedSkills,\n destDir,\n sourceLabel,\n };\n}\n\ntype EnsureMinimalConfigOptions = {\n projectDir: string;\n sourceResult?: SourceLoadResult;\n};\n\ntype EnsureMinimalConfigResult = {\n /** Path to the config file. */\n configPath: string;\n /** Whether a new config was created. */\n created: boolean;\n};\n\n/**\n * Ensures a minimal config.ts exists so `npx agents-inc compile` works after eject.\n *\n * If the config already exists, returns immediately with `created: false`.\n * Otherwise generates a minimal config from the resolved source and project metadata.\n *\n * Returns structured data — the command decides what to log.\n */\nasync function ensureMinimalConfig(\n options: EnsureMinimalConfigOptions,\n): Promise<EnsureMinimalConfigResult> {\n const { projectDir, sourceResult } = options;\n\n const tsConfigPath = getProjectConfigPath(projectDir);\n\n if (await fileExists(tsConfigPath)) {\n return { configPath: tsConfigPath, created: false };\n }\n\n const resolvedConfig =\n sourceResult?.sourceConfig ?? (await resolveSource({ caller: \"stored\", projectDir }));\n const existingProjectConfig = await loadProjectSourceConfig(projectDir);\n const source = resolvedConfig.source || undefined;\n\n // At the home directory the invented config IS the global manifest, and the\n // file it opens with `import type { ProjectConfig } from \"./config-types\"`\n // cannot resolve its own types without the sibling. The gate writes the pair.\n if (isHomeDirectory(projectDir)) {\n await ensureBlankPair();\n if (source) await recordSource(projectDir, source);\n return { configPath: tsConfigPath, created: true };\n }\n\n await writeProjectPartial(\n projectDir,\n {\n skills: [],\n agents: [],\n ...(source ? { marketplace: source } : {}),\n ...(resolvedConfig.marketplace ? { marketplaceName: resolvedConfig.marketplace } : {}),\n ...(existingProjectConfig?.author ? { author: existingProjectConfig.author } : {}),\n ...(existingProjectConfig?.agentsSource\n ? { agentsSource: existingProjectConfig.agentsSource }\n : {}),\n },\n { fallbackName: path.basename(projectDir) },\n );\n\n return { configPath: tsConfigPath, created: true };\n}\n\n/**\n * Records the marketplace ref in whichever scope's config `projectDir` names. At the home\n * directory that config is the global manifest every project's generated types\n * import from, so the write goes through the gate: registered projects inline\n * the scalar and follow it.\n */\nasync function recordSource(projectDir: string, source: string): Promise<void> {\n if (isHomeDirectory(projectDir)) {\n await mutateGlobal(\n { kind: \"set-source\", source, fallbackName: path.basename(projectDir) },\n lazyGateDeps(projectDir),\n );\n return;\n }\n\n const existing = (await loadProjectSourceConfig(projectDir)) ?? {};\n await writeProjectPartial(\n projectDir,\n { ...existing, marketplace: source },\n { fallbackName: path.basename(projectDir) },\n );\n}\n\n/** Checks whether the agents directory contains any agent subdirectories (not just _templates). */\nasync function hasAgentPartialDirs(agentsDir: string): Promise<boolean> {\n const subdirs = await listDirectories(agentsDir);\n const templatesBasename = path.basename(DIRS.templates);\n return subdirs.some((dir) => dir !== templatesBasename);\n}\n"],"mappings":"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","names":["matrix"]}
|
package/dist/commands/init.js
CHANGED
|
@@ -5,50 +5,52 @@ import {
|
|
|
5
5
|
getDashboardData,
|
|
6
6
|
runDashboardFlow,
|
|
7
7
|
showDashboard
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
21
|
-
import "../chunk-
|
|
22
|
-
import "../chunk-
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-
|
|
8
|
+
} from "../chunk-H6UTKTLK.js";
|
|
9
|
+
import "../chunk-TBOVYLQJ.js";
|
|
10
|
+
import "../chunk-MO5FGLVS.js";
|
|
11
|
+
import "../chunk-IXRZAHZF.js";
|
|
12
|
+
import "../chunk-TNGMF4UX.js";
|
|
13
|
+
import "../chunk-LJCNUP6M.js";
|
|
14
|
+
import "../chunk-HTYH7CKN.js";
|
|
15
|
+
import "../chunk-PCC4LBKB.js";
|
|
16
|
+
import "../chunk-HG4JPXJT.js";
|
|
17
|
+
import "../chunk-6RLV45HN.js";
|
|
18
|
+
import "../chunk-ILUVL7WM.js";
|
|
19
|
+
import "../chunk-HXKOIWLU.js";
|
|
20
|
+
import "../chunk-QWVXOCXO.js";
|
|
21
|
+
import "../chunk-GS2NZ3GD.js";
|
|
22
|
+
import "../chunk-VPASBA7P.js";
|
|
23
|
+
import "../chunk-PNMM5HNX.js";
|
|
24
|
+
import "../chunk-CLFHC2DK.js";
|
|
25
|
+
import "../chunk-5OKLCVM4.js";
|
|
26
|
+
import "../chunk-5F2YR5XV.js";
|
|
25
27
|
import "../chunk-TSIU7DME.js";
|
|
26
28
|
import "../chunk-XVAQG2CV.js";
|
|
27
|
-
import "../chunk-
|
|
29
|
+
import "../chunk-ZBPEFQ4G.js";
|
|
30
|
+
import "../chunk-4A4L3YIW.js";
|
|
28
31
|
import "../chunk-J27W6TXS.js";
|
|
29
|
-
import "../chunk-
|
|
30
|
-
import "../chunk-
|
|
31
|
-
import "../chunk-
|
|
32
|
-
import "../chunk-
|
|
33
|
-
import "../chunk-
|
|
34
|
-
import "../chunk-
|
|
35
|
-
import "../chunk-
|
|
36
|
-
import "../chunk-
|
|
37
|
-
import "../chunk-
|
|
38
|
-
import "../chunk-
|
|
39
|
-
import "../chunk-
|
|
40
|
-
import "../chunk-
|
|
41
|
-
import "../chunk-B66SC72V.js";
|
|
32
|
+
import "../chunk-SY4X2LND.js";
|
|
33
|
+
import "../chunk-WFRTHH3A.js";
|
|
34
|
+
import "../chunk-WTJ3AY33.js";
|
|
35
|
+
import "../chunk-OKH64JZE.js";
|
|
36
|
+
import "../chunk-PMUABBPG.js";
|
|
37
|
+
import "../chunk-JCPANDNR.js";
|
|
38
|
+
import "../chunk-WUQ3MTPF.js";
|
|
39
|
+
import "../chunk-5QZAK6J7.js";
|
|
40
|
+
import "../chunk-MHRC3KRX.js";
|
|
41
|
+
import "../chunk-F2AMBBIA.js";
|
|
42
|
+
import "../chunk-ZUAZHDKP.js";
|
|
43
|
+
import "../chunk-Y5Y7XHVU.js";
|
|
42
44
|
import "../chunk-JFLVEFFP.js";
|
|
43
|
-
import "../chunk-
|
|
44
|
-
import "../chunk-
|
|
45
|
-
import "../chunk-
|
|
46
|
-
import "../chunk-
|
|
47
|
-
import "../chunk-
|
|
48
|
-
import "../chunk-
|
|
49
|
-
import "../chunk-
|
|
45
|
+
import "../chunk-F5T6TV4Z.js";
|
|
46
|
+
import "../chunk-YO2LTXB4.js";
|
|
47
|
+
import "../chunk-UMH2YZKG.js";
|
|
48
|
+
import "../chunk-G47TDUK3.js";
|
|
49
|
+
import "../chunk-WCAUUBHO.js";
|
|
50
|
+
import "../chunk-XAXJWXI4.js";
|
|
51
|
+
import "../chunk-RWOYPOMR.js";
|
|
50
52
|
import "../chunk-VASLW636.js";
|
|
51
|
-
import "../chunk-
|
|
53
|
+
import "../chunk-IO5YBKHV.js";
|
|
52
54
|
import "../chunk-VZRO7RYT.js";
|
|
53
55
|
export {
|
|
54
56
|
Init as default,
|
package/dist/commands/list.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SkillAgentSummary
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-Y5Y7XHVU.js";
|
|
5
5
|
import {
|
|
6
6
|
render
|
|
7
7
|
} from "../chunk-JFLVEFFP.js";
|
|
8
8
|
import {
|
|
9
9
|
hydrateWizardStore
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-F5T6TV4Z.js";
|
|
11
11
|
import {
|
|
12
12
|
BaseCommand
|
|
13
|
-
} from "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
13
|
+
} from "../chunk-YO2LTXB4.js";
|
|
14
|
+
import "../chunk-UMH2YZKG.js";
|
|
15
|
+
import "../chunk-G47TDUK3.js";
|
|
16
16
|
import {
|
|
17
17
|
INSTALL_MODE_LABELS,
|
|
18
18
|
detectInstallation,
|
|
19
19
|
formatInstallationDisplay,
|
|
20
20
|
getInstallationInfo,
|
|
21
21
|
loadProjectConfig
|
|
22
|
-
} from "../chunk-
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-
|
|
22
|
+
} from "../chunk-WCAUUBHO.js";
|
|
23
|
+
import "../chunk-XAXJWXI4.js";
|
|
24
|
+
import "../chunk-RWOYPOMR.js";
|
|
25
25
|
import "../chunk-VASLW636.js";
|
|
26
26
|
import {
|
|
27
27
|
CLI_COLORS,
|
|
28
28
|
CLI_INVOKE_COMMAND,
|
|
29
29
|
DEFAULT_BRANDING
|
|
30
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-IO5YBKHV.js";
|
|
31
31
|
import "../chunk-VZRO7RYT.js";
|
|
32
32
|
|
|
33
33
|
// src/cli/commands/list.tsx
|
|
@@ -47,7 +47,7 @@ var ListView = ({ mode, source, skillConfigs, agentConfigs }) => {
|
|
|
47
47
|
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: mode })
|
|
48
48
|
] }),
|
|
49
49
|
source && /* @__PURE__ */ jsxs(Box, { flexDirection: "row", columnGap: 1, children: [
|
|
50
|
-
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, bold: true, children: "
|
|
50
|
+
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, bold: true, children: "Marketplace" }),
|
|
51
51
|
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: source })
|
|
52
52
|
] })
|
|
53
53
|
] }),
|
|
@@ -95,7 +95,7 @@ var List = class _List extends BaseCommand {
|
|
|
95
95
|
ListView,
|
|
96
96
|
{
|
|
97
97
|
mode: modeLabel,
|
|
98
|
-
source: config.
|
|
98
|
+
source: config.marketplace,
|
|
99
99
|
skillConfigs: activeSkills,
|
|
100
100
|
agentConfigs: activeAgents
|
|
101
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/list.tsx"],"sourcesContent":["import React, { useEffect } from \"react\";\n\nimport { Box, Text, useApp } from \"ink\";\nimport { render } from \"../components/render.js\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { CLI_INVOKE_COMMAND, CLI_COLORS, DEFAULT_BRANDING } from \"../consts.js\";\nimport { getInstallationInfo, formatInstallationDisplay } from \"../lib/plugins/index.js\";\nimport { detectInstallation, INSTALL_MODE_LABELS } from \"../lib/installation/installation.js\";\nimport { loadProjectConfig } from \"../lib/configuration/project-config.js\";\nimport { SkillAgentSummary } from \"../components/wizard/skill-agent-summary.js\";\nimport { hydrateWizardStore } from \"../stores/wizard-store.js\";\nimport type { AgentScopeConfig, SkillConfig } from \"../types/config.js\";\n\ntype ListViewProps = {\n mode: string;\n source?: string | undefined;\n skillConfigs: SkillConfig[];\n agentConfigs: AgentScopeConfig[];\n};\n\nconst ListView: React.FC<ListViewProps> = ({ mode, source, skillConfigs, agentConfigs }) => {\n const { exit } = useApp();\n\n useEffect(() => {\n const timer = setTimeout(() => exit(), 0);\n return () => clearTimeout(timer);\n }, [exit]);\n\n return (\n <Box flexDirection=\"column\" paddingX={1} paddingY={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Mode\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{mode}</Text>\n </Box>\n {source && (\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/list.tsx"],"sourcesContent":["import React, { useEffect } from \"react\";\n\nimport { Box, Text, useApp } from \"ink\";\nimport { render } from \"../components/render.js\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { CLI_INVOKE_COMMAND, CLI_COLORS, DEFAULT_BRANDING } from \"../consts.js\";\nimport { getInstallationInfo, formatInstallationDisplay } from \"../lib/plugins/index.js\";\nimport { detectInstallation, INSTALL_MODE_LABELS } from \"../lib/installation/installation.js\";\nimport { loadProjectConfig } from \"../lib/configuration/project-config.js\";\nimport { SkillAgentSummary } from \"../components/wizard/skill-agent-summary.js\";\nimport { hydrateWizardStore } from \"../stores/wizard-store.js\";\nimport type { AgentScopeConfig, SkillConfig } from \"../types/config.js\";\n\ntype ListViewProps = {\n mode: string;\n source?: string | undefined;\n skillConfigs: SkillConfig[];\n agentConfigs: AgentScopeConfig[];\n};\n\nconst ListView: React.FC<ListViewProps> = ({ mode, source, skillConfigs, agentConfigs }) => {\n const { exit } = useApp();\n\n useEffect(() => {\n const timer = setTimeout(() => exit(), 0);\n return () => clearTimeout(timer);\n }, [exit]);\n\n return (\n <Box flexDirection=\"column\" paddingX={1} paddingY={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Mode\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{mode}</Text>\n </Box>\n {source && (\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Marketplace\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{source}</Text>\n </Box>\n )}\n </Box>\n\n <SkillAgentSummary skillConfigs={skillConfigs} agentConfigs={agentConfigs} />\n </Box>\n );\n};\n\nexport default class List extends BaseCommand {\n static summary = \"Show installation information\";\n static description = `Display details about the ${DEFAULT_BRANDING.NAME} installation (local or plugin mode)`;\n static aliases = [\"ls\"];\n\n static examples = [\n {\n description: \"Show current installation details\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n ];\n\n async run(): Promise<void> {\n await this.parse(List);\n\n const installation = await detectInstallation();\n\n if (!installation) {\n this.log(\"No installation found.\");\n this.log(`Run '${CLI_INVOKE_COMMAND} init' to create one.`);\n return;\n }\n\n const loaded = await loadProjectConfig(installation.projectDir);\n\n if (!loaded?.config || !process.stdin.isTTY) {\n const info = await getInstallationInfo();\n if (info) {\n this.log(\"\");\n this.log(formatInstallationDisplay(info));\n this.log(\"\");\n }\n return;\n }\n\n const { config } = loaded;\n const modeLabel = INSTALL_MODE_LABELS[installation.mode];\n const activeSkills = config.skills.filter((s) => !s.excluded);\n const activeAgents = config.agents.filter((a) => !a.excluded);\n\n hydrateWizardStore({\n installedSkillConfigs: activeSkills,\n installedAgentConfigs: activeAgents,\n });\n\n const { waitUntilExit, clear } = render(\n <ListView\n mode={modeLabel}\n source={config.marketplace}\n skillConfigs={activeSkills}\n agentConfigs={activeAgents}\n />,\n );\n\n await waitUntilExit();\n clear();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAgB,iBAAiB;AAEjC,SAAS,KAAK,MAAM,cAAc;AA8B1B,SACE,KADF;AAXR,IAAM,WAAoC,CAAC,EAAE,MAAM,QAAQ,cAAc,aAAa,MAAM;AAC1F,QAAM,EAAE,KAAK,IAAI,OAAO;AAExB,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,KAAK,GAAG,CAAC;AACxC,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,IAAI,CAAC;AAET,SACE,qBAAC,OAAI,eAAc,UAAS,UAAU,GAAG,UAAU,GACjD;AAAA,yBAAC,OAAI,eAAc,UAAS,cAAc,GACxC;AAAA,2BAAC,OAAI,eAAc,OAAM,WAAW,GAClC;AAAA,4BAAC,QAAK,OAAO,WAAW,SAAS,MAAI,MAAC,kBAEtC;AAAA,QACA,oBAAC,QAAK,OAAO,WAAW,SAAU,gBAAK;AAAA,SACzC;AAAA,MACC,UACC,qBAAC,OAAI,eAAc,OAAM,WAAW,GAClC;AAAA,4BAAC,QAAK,OAAO,WAAW,SAAS,MAAI,MAAC,yBAEtC;AAAA,QACA,oBAAC,QAAK,OAAO,WAAW,SAAU,kBAAO;AAAA,SAC3C;AAAA,OAEJ;AAAA,IAEA,oBAAC,qBAAkB,cAA4B,cAA4B;AAAA,KAC7E;AAEJ;AAEA,IAAqB,OAArB,MAAqB,cAAa,YAAY;AAAA,EAC5C,OAAO,UAAU;AAAA,EACjB,OAAO,cAAc,6BAA6B,iBAAiB,IAAI;AAAA,EACvE,OAAO,UAAU,CAAC,IAAI;AAAA,EAEtB,OAAO,WAAW;AAAA,IAChB;AAAA,MACE,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,MAAM,MAAqB;AACzB,UAAM,KAAK,MAAM,KAAI;AAErB,UAAM,eAAe,MAAM,mBAAmB;AAE9C,QAAI,CAAC,cAAc;AACjB,WAAK,IAAI,wBAAwB;AACjC,WAAK,IAAI,QAAQ,kBAAkB,uBAAuB;AAC1D;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,kBAAkB,aAAa,UAAU;AAE9D,QAAI,CAAC,QAAQ,UAAU,CAAC,QAAQ,MAAM,OAAO;AAC3C,YAAM,OAAO,MAAM,oBAAoB;AACvC,UAAI,MAAM;AACR,aAAK,IAAI,EAAE;AACX,aAAK,IAAI,0BAA0B,IAAI,CAAC;AACxC,aAAK,IAAI,EAAE;AAAA,MACb;AACA;AAAA,IACF;AAEA,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,YAAY,oBAAoB,aAAa,IAAI;AACvD,UAAM,eAAe,OAAO,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ;AAC5D,UAAM,eAAe,OAAO,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ;AAE5D,uBAAmB;AAAA,MACjB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,IACzB,CAAC;AAED,UAAM,EAAE,eAAe,MAAM,IAAI;AAAA,MAC/B;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,QAAQ,OAAO;AAAA,UACf,cAAc;AAAA,UACd,cAAc;AAAA;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,cAAc;AACpB,UAAM;AAAA,EACR;AACF;","names":[]}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
validateMarketplaceName
|
|
4
|
+
} from "../../chunk-4G2YHZIM.js";
|
|
5
|
+
import {
|
|
6
|
+
BaseCommand,
|
|
7
|
+
EXIT_CODES
|
|
8
|
+
} from "../../chunk-YO2LTXB4.js";
|
|
9
|
+
import "../../chunk-UMH2YZKG.js";
|
|
10
|
+
import "../../chunk-G47TDUK3.js";
|
|
11
|
+
import {
|
|
12
|
+
validateKebabCaseName
|
|
13
|
+
} from "../../chunk-WCAUUBHO.js";
|
|
14
|
+
import {
|
|
15
|
+
isDirectoryEmpty,
|
|
16
|
+
writeFile
|
|
17
|
+
} from "../../chunk-XAXJWXI4.js";
|
|
18
|
+
import "../../chunk-RWOYPOMR.js";
|
|
19
|
+
import "../../chunk-VASLW636.js";
|
|
20
|
+
import {
|
|
21
|
+
CLI_INVOKE_COMMAND,
|
|
22
|
+
DEFAULT_VERSION,
|
|
23
|
+
SKILLS_DIR_PATH,
|
|
24
|
+
SKILL_CATEGORIES_PATH,
|
|
25
|
+
SKILL_RULES_PATH,
|
|
26
|
+
STACKS_FILE_PATH,
|
|
27
|
+
STANDARD_FILES
|
|
28
|
+
} from "../../chunk-IO5YBKHV.js";
|
|
29
|
+
import "../../chunk-VZRO7RYT.js";
|
|
30
|
+
|
|
31
|
+
// src/cli/commands/new/marketplace.ts
|
|
32
|
+
import { Args } from "@oclif/core";
|
|
33
|
+
import path2 from "path";
|
|
34
|
+
|
|
35
|
+
// src/cli/lib/marketplace-scaffold.ts
|
|
36
|
+
import path from "path";
|
|
37
|
+
var EXAMPLE_SKILL_SUFFIX = "example-skill";
|
|
38
|
+
var EXAMPLE_DOMAIN = "web";
|
|
39
|
+
var EXAMPLE_CATEGORY = `${EXAMPLE_DOMAIN}-example`;
|
|
40
|
+
var EXAMPLE_SLUG = "example-skill";
|
|
41
|
+
var EXAMPLE_CATEGORY_ORDER = 1;
|
|
42
|
+
var INITIAL_PACKAGE_VERSION = "0.1.0";
|
|
43
|
+
var EXAMPLE_STACK_AGENT = "web-developer";
|
|
44
|
+
function exampleSkillId(marketplaceName) {
|
|
45
|
+
return `${marketplaceName}-${EXAMPLE_SKILL_SUFFIX}`;
|
|
46
|
+
}
|
|
47
|
+
async function writeMarketplaceScaffold(marketplaceDir, marketplaceName) {
|
|
48
|
+
const files = scaffoldFiles(marketplaceName);
|
|
49
|
+
await Promise.all(
|
|
50
|
+
files.map((file) => writeFile(path.join(marketplaceDir, file.relPath), file.contents))
|
|
51
|
+
);
|
|
52
|
+
return files.map((file) => file.relPath);
|
|
53
|
+
}
|
|
54
|
+
function scaffoldFiles(marketplaceName) {
|
|
55
|
+
const skillId = exampleSkillId(marketplaceName);
|
|
56
|
+
const skillDir = path.join(SKILLS_DIR_PATH, skillId);
|
|
57
|
+
return [
|
|
58
|
+
{ relPath: STANDARD_FILES.PACKAGE_JSON, contents: packageJson(marketplaceName) },
|
|
59
|
+
{ relPath: SKILL_CATEGORIES_PATH, contents: skillCategoriesModule() },
|
|
60
|
+
{ relPath: SKILL_RULES_PATH, contents: skillRulesModule() },
|
|
61
|
+
{ relPath: STACKS_FILE_PATH, contents: stacksModule(marketplaceName, skillId) },
|
|
62
|
+
{ relPath: path.join(skillDir, STANDARD_FILES.SKILL_MD), contents: skillMd(skillId) },
|
|
63
|
+
{
|
|
64
|
+
relPath: path.join(skillDir, STANDARD_FILES.METADATA_YAML),
|
|
65
|
+
contents: metadataYaml(marketplaceName)
|
|
66
|
+
}
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
function configModule(comment, data) {
|
|
70
|
+
return `${comment}
|
|
71
|
+
export default ${JSON.stringify(data, null, 2)};
|
|
72
|
+
`;
|
|
73
|
+
}
|
|
74
|
+
function packageJson(marketplaceName) {
|
|
75
|
+
return `${JSON.stringify(
|
|
76
|
+
{
|
|
77
|
+
name: marketplaceName,
|
|
78
|
+
version: INITIAL_PACKAGE_VERSION,
|
|
79
|
+
description: `Skills curated for ${marketplaceName}'s conventions`,
|
|
80
|
+
author: { name: authorHandle(marketplaceName) }
|
|
81
|
+
},
|
|
82
|
+
null,
|
|
83
|
+
2
|
|
84
|
+
)}
|
|
85
|
+
`;
|
|
86
|
+
}
|
|
87
|
+
function authorHandle(marketplaceName) {
|
|
88
|
+
return `@${marketplaceName}`;
|
|
89
|
+
}
|
|
90
|
+
function skillCategoriesModule() {
|
|
91
|
+
return configModule("// The categories this marketplace's skills fall into.", {
|
|
92
|
+
version: DEFAULT_VERSION,
|
|
93
|
+
categories: {
|
|
94
|
+
[EXAMPLE_CATEGORY]: {
|
|
95
|
+
id: EXAMPLE_CATEGORY,
|
|
96
|
+
displayName: "Example",
|
|
97
|
+
description: "Replace this with a category of your own",
|
|
98
|
+
domain: EXAMPLE_DOMAIN,
|
|
99
|
+
exclusive: false,
|
|
100
|
+
required: false,
|
|
101
|
+
order: EXAMPLE_CATEGORY_ORDER
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function skillRulesModule() {
|
|
107
|
+
return configModule(
|
|
108
|
+
[
|
|
109
|
+
"// Relationships between skills \u2014 conflicts, requires, alternatives.",
|
|
110
|
+
"//",
|
|
111
|
+
"// Rules may only name skills the public catalogue carries; this marketplace's own",
|
|
112
|
+
"// skills cannot be named here yet, and a rule that names one will not load. The",
|
|
113
|
+
"// file still has to exist, so it ships with a version and no relationships."
|
|
114
|
+
].join("\n"),
|
|
115
|
+
{ version: DEFAULT_VERSION }
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
function stacksModule(marketplaceName, skillId) {
|
|
119
|
+
return configModule("// The stacks this marketplace offers the wizard.", {
|
|
120
|
+
stacks: [
|
|
121
|
+
{
|
|
122
|
+
id: `${marketplaceName}-starter`,
|
|
123
|
+
name: `${marketplaceName} starter`,
|
|
124
|
+
description: `Every skill ${marketplaceName} ships`,
|
|
125
|
+
agents: {
|
|
126
|
+
[EXAMPLE_STACK_AGENT]: {
|
|
127
|
+
[EXAMPLE_CATEGORY]: [{ id: skillId }]
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
]
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function skillMd(skillId) {
|
|
135
|
+
return `---
|
|
136
|
+
name: ${skillId}
|
|
137
|
+
description: A placeholder skill \u2014 replace it with one of your own
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
# Example Skill
|
|
141
|
+
|
|
142
|
+
This is where a skill's content goes: the conventions, patterns and rules you want
|
|
143
|
+
every sub-agent carrying it to follow.
|
|
144
|
+
|
|
145
|
+
Replace this file and the \`${STANDARD_FILES.METADATA_YAML}\` beside it, and rename the
|
|
146
|
+
directory to the id your skill should publish under.
|
|
147
|
+
`;
|
|
148
|
+
}
|
|
149
|
+
function metadataYaml(marketplaceName) {
|
|
150
|
+
return [
|
|
151
|
+
"custom: true",
|
|
152
|
+
`domain: ${EXAMPLE_DOMAIN}`,
|
|
153
|
+
`author: "${authorHandle(marketplaceName)}"`,
|
|
154
|
+
"displayName: Example Skill",
|
|
155
|
+
`category: ${EXAMPLE_CATEGORY}`,
|
|
156
|
+
`slug: ${EXAMPLE_SLUG}`,
|
|
157
|
+
'cliDescription: "A placeholder skill to replace with your own"',
|
|
158
|
+
`usageGuidance: "Use when you need a worked example of this marketplace's skill shape"`,
|
|
159
|
+
""
|
|
160
|
+
].join("\n");
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// src/cli/commands/new/marketplace.ts
|
|
164
|
+
function occupiedDirectoryError(marketplaceDir) {
|
|
165
|
+
return `${marketplaceDir} already holds files. A scaffold writes a whole marketplace, so it will not write into a directory that already has contents. Choose another name, or empty that directory first.`;
|
|
166
|
+
}
|
|
167
|
+
var NewMarketplace = class _NewMarketplace extends BaseCommand {
|
|
168
|
+
static summary = "Scaffold a marketplace of your own";
|
|
169
|
+
static description = "Create a directory holding everything the CLI needs to read a marketplace: a package.json carrying its identity, the three config files, and one example skill already named in the marketplace's own namespace. It scaffolds only \u2014 run 'build plugins' and 'build marketplace' to publish what you have written.";
|
|
170
|
+
static examples = [
|
|
171
|
+
{
|
|
172
|
+
description: "Scaffold a marketplace named acme into ./acme",
|
|
173
|
+
command: "<%= config.bin %> <%= command.id %> acme"
|
|
174
|
+
}
|
|
175
|
+
];
|
|
176
|
+
static args = {
|
|
177
|
+
name: Args.string({
|
|
178
|
+
description: "Name of the marketplace (kebab-case). Becomes the directory, the package.json name, and the prefix every skill id must carry.",
|
|
179
|
+
required: true
|
|
180
|
+
})
|
|
181
|
+
};
|
|
182
|
+
async run() {
|
|
183
|
+
const { args } = await this.parse(_NewMarketplace);
|
|
184
|
+
const marketplaceName = args.name;
|
|
185
|
+
const marketplaceDir = path2.join(process.cwd(), marketplaceName);
|
|
186
|
+
this.refuseUnusableName(marketplaceName);
|
|
187
|
+
await this.refuseOccupiedDirectory(marketplaceDir);
|
|
188
|
+
try {
|
|
189
|
+
const written = await writeMarketplaceScaffold(marketplaceDir, marketplaceName);
|
|
190
|
+
this.reportCreated(marketplaceName, marketplaceDir, written);
|
|
191
|
+
this.reportNextSteps(marketplaceName, marketplaceDir);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
this.handleError(error);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Both name rules `build marketplace` enforces, enforced here instead — failing
|
|
198
|
+
* at creation beats failing at publish, when the name is already the directory,
|
|
199
|
+
* the package name and the prefix on every id.
|
|
200
|
+
*/
|
|
201
|
+
refuseUnusableName(marketplaceName) {
|
|
202
|
+
const kebabError = validateKebabCaseName(marketplaceName, "Marketplace");
|
|
203
|
+
if (kebabError) {
|
|
204
|
+
this.error(kebabError, { exit: EXIT_CODES.INVALID_ARGS });
|
|
205
|
+
}
|
|
206
|
+
const reservedError = validateMarketplaceName(marketplaceName, marketplaceName);
|
|
207
|
+
if (reservedError) {
|
|
208
|
+
this.error(reservedError, { exit: EXIT_CODES.ERROR });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async refuseOccupiedDirectory(marketplaceDir) {
|
|
212
|
+
if (await isDirectoryEmpty(marketplaceDir)) return;
|
|
213
|
+
this.error(occupiedDirectoryError(marketplaceDir), { exit: EXIT_CODES.ERROR });
|
|
214
|
+
}
|
|
215
|
+
reportCreated(marketplaceName, marketplaceDir, written) {
|
|
216
|
+
this.log("");
|
|
217
|
+
this.logSuccess(`Created marketplace '${marketplaceName}' at ${marketplaceDir}`);
|
|
218
|
+
for (const relPath of written) {
|
|
219
|
+
this.log(` ${relPath}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
reportNextSteps(marketplaceName, marketplaceDir) {
|
|
223
|
+
const skillDir = path2.join(SKILLS_DIR_PATH, exampleSkillId(marketplaceName));
|
|
224
|
+
const steps = [
|
|
225
|
+
`cd ${marketplaceName}`,
|
|
226
|
+
"Replace the placeholder 'author' in package.json with your own handle \u2014 it is what 'build marketplace' records as this marketplace's owner",
|
|
227
|
+
`Replace ${skillDir}/ with a skill of your own. Every skill id must begin with '${marketplaceName}-'`,
|
|
228
|
+
`${CLI_INVOKE_COMMAND} build plugins`,
|
|
229
|
+
`${CLI_INVOKE_COMMAND} build marketplace`,
|
|
230
|
+
`${CLI_INVOKE_COMMAND} init --marketplace ${marketplaceDir} (from a project)`
|
|
231
|
+
];
|
|
232
|
+
this.log("");
|
|
233
|
+
this.log("Next steps:");
|
|
234
|
+
for (const [index, step] of steps.entries()) {
|
|
235
|
+
this.log(` ${index + 1}. ${step}`);
|
|
236
|
+
}
|
|
237
|
+
this.log("");
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
export {
|
|
241
|
+
NewMarketplace as default
|
|
242
|
+
};
|
|
243
|
+
//# sourceMappingURL=marketplace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/new/marketplace.ts","../../../src/cli/lib/marketplace-scaffold.ts"],"sourcesContent":["import { Args } from \"@oclif/core\";\nimport path from \"path\";\n\nimport { BaseCommand } from \"../../base-command.js\";\nimport { CLI_INVOKE_COMMAND, SKILLS_DIR_PATH } from \"../../consts.js\";\nimport { EXIT_CODES } from \"../../lib/exit-codes.js\";\nimport { validateMarketplaceName } from \"../../lib/marketplace-generator.js\";\nimport { exampleSkillId, writeMarketplaceScaffold } from \"../../lib/marketplace-scaffold.js\";\nimport { validateKebabCaseName } from \"../../lib/validate-kebab-name.js\";\nimport { isDirectoryEmpty } from \"../../utils/fs.js\";\n\n/**\n * The refusal over a target directory that already holds something.\n *\n * A scaffold writes a whole marketplace, so writing into an occupied directory\n * would mean merging with — or overwriting — work this command did not author.\n * Both ways out are one step, which is why there is no `--force`: a flag that\n * overwrites an author's own files is the destructive half of a silent fallback.\n */\nfunction occupiedDirectoryError(marketplaceDir: string): string {\n return (\n `${marketplaceDir} already holds files. A scaffold writes a whole marketplace, ` +\n `so it will not write into a directory that already has contents. Choose another ` +\n `name, or empty that directory first.`\n );\n}\n\nexport default class NewMarketplace extends BaseCommand {\n static summary = \"Scaffold a marketplace of your own\";\n\n static description =\n \"Create a directory holding everything the CLI needs to read a marketplace: a package.json \" +\n \"carrying its identity, the three config files, and one example skill already named in the \" +\n \"marketplace's own namespace. It scaffolds only — run 'build plugins' and 'build marketplace' \" +\n \"to publish what you have written.\";\n\n static examples = [\n {\n description: \"Scaffold a marketplace named acme into ./acme\",\n command: \"<%= config.bin %> <%= command.id %> acme\",\n },\n ];\n\n static args = {\n name: Args.string({\n description:\n \"Name of the marketplace (kebab-case). Becomes the directory, the package.json name, \" +\n \"and the prefix every skill id must carry.\",\n required: true,\n }),\n };\n\n async run(): Promise<void> {\n const { args } = await this.parse(NewMarketplace);\n const marketplaceName = args.name;\n const marketplaceDir = path.join(process.cwd(), marketplaceName);\n\n this.refuseUnusableName(marketplaceName);\n await this.refuseOccupiedDirectory(marketplaceDir);\n\n try {\n const written = await writeMarketplaceScaffold(marketplaceDir, marketplaceName);\n this.reportCreated(marketplaceName, marketplaceDir, written);\n this.reportNextSteps(marketplaceName, marketplaceDir);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Both name rules `build marketplace` enforces, enforced here instead — failing\n * at creation beats failing at publish, when the name is already the directory,\n * the package name and the prefix on every id.\n */\n private refuseUnusableName(marketplaceName: string): void {\n const kebabError = validateKebabCaseName(marketplaceName, \"Marketplace\");\n if (kebabError) {\n this.error(kebabError, { exit: EXIT_CODES.INVALID_ARGS });\n }\n\n // The package.json this command is about to write names the marketplace after\n // itself, so the marketplace name IS the package name. That is what keeps the\n // public catalogue's exemption out of reach: it belongs to one npm package, and\n // nobody scaffolds that package from here.\n const reservedError = validateMarketplaceName(marketplaceName, marketplaceName);\n if (reservedError) {\n this.error(reservedError, { exit: EXIT_CODES.ERROR });\n }\n }\n\n private async refuseOccupiedDirectory(marketplaceDir: string): Promise<void> {\n if (await isDirectoryEmpty(marketplaceDir)) return;\n\n this.error(occupiedDirectoryError(marketplaceDir), { exit: EXIT_CODES.ERROR });\n }\n\n private reportCreated(\n marketplaceName: string,\n marketplaceDir: string,\n written: readonly string[],\n ): void {\n this.log(\"\");\n this.logSuccess(`Created marketplace '${marketplaceName}' at ${marketplaceDir}`);\n for (const relPath of written) {\n this.log(` ${relPath}`);\n }\n }\n\n private reportNextSteps(marketplaceName: string, marketplaceDir: string): void {\n const skillDir = path.join(SKILLS_DIR_PATH, exampleSkillId(marketplaceName));\n const steps = [\n `cd ${marketplaceName}`,\n \"Replace the placeholder 'author' in package.json with your own handle — it is what 'build marketplace' records as this marketplace's owner\",\n `Replace ${skillDir}/ with a skill of your own. Every skill id must begin with '${marketplaceName}-'`,\n `${CLI_INVOKE_COMMAND} build plugins`,\n `${CLI_INVOKE_COMMAND} build marketplace`,\n `${CLI_INVOKE_COMMAND} init --marketplace ${marketplaceDir} (from a project)`,\n ];\n\n this.log(\"\");\n this.log(\"Next steps:\");\n for (const [index, step] of steps.entries()) {\n this.log(` ${index + 1}. ${step}`);\n }\n this.log(\"\");\n }\n}\n","import path from \"path\";\n\nimport {\n DEFAULT_VERSION,\n SKILL_CATEGORIES_PATH,\n SKILL_RULES_PATH,\n SKILLS_DIR_PATH,\n STACKS_FILE_PATH,\n STANDARD_FILES,\n} from \"../consts.js\";\nimport { writeFile } from \"../utils/fs.js\";\n\n/** One file of a scaffolded marketplace: where it goes, and what it holds. */\ntype ScaffoldFile = {\n /** Path relative to the marketplace root. */\n relPath: string;\n contents: string;\n};\n\n/**\n * The bare id of the one skill a scaffold ships. The marketplace's own name is\n * prefixed onto it by {@link exampleSkillId} — this half is the same for every\n * marketplace, and on its own it belongs to none of them.\n */\nconst EXAMPLE_SKILL_SUFFIX = \"example-skill\";\n\n/**\n * The domain the scaffolded category sits under.\n *\n * `web` rather than a placeholder of its own: a domain is a member of a generated\n * union, and one invented for the scaffold appears in no wizard domain view and\n * reaches no sub-agent. It is also one of the domains a from-scratch selection\n * opens with, so the example skill is visible without the author choosing anything.\n */\nconst EXAMPLE_DOMAIN = \"web\";\n\n/**\n * The category the scaffold declares and places its example skill in, named by the\n * `<domain>-<name>` convention every category in the public catalogue follows. No\n * built-in category holds this key, so declaring it adds one rather than redefining\n * somebody else's.\n */\nconst EXAMPLE_CATEGORY = `${EXAMPLE_DOMAIN}-example`;\n\n/**\n * The slug the example skill answers to.\n *\n * Deliberately NOT namespaced: the marketplace-namespace rule governs skill ids,\n * and a marketplace's matrix is built from its own skills alone, so nothing in it\n * can collide with this. Prefixing it would settle a question nobody has ruled on.\n */\nconst EXAMPLE_SLUG = \"example-skill\";\n\n/** Where the scaffolded category sorts among the categories a marketplace grows later. */\nconst EXAMPLE_CATEGORY_ORDER = 1;\n\n/** The version a marketplace starts at — pre-release, because nothing is published yet. */\nconst INITIAL_PACKAGE_VERSION = \"0.1.0\";\n\n/** The sub-agent the scaffolded stack hands its skill to. */\nconst EXAMPLE_STACK_AGENT = \"web-developer\";\n\n/**\n * Composes the id of a scaffolded marketplace's example skill.\n *\n * Every skill id a marketplace publishes begins with that marketplace's name, so an\n * author who edits the scaffold rather than starting from a blank directory falls\n * into the namespace instead of having to remember it — `build marketplace` refuses\n * an id that lacks the prefix, and so does the load side.\n */\nexport function exampleSkillId(marketplaceName: string): string {\n return `${marketplaceName}-${EXAMPLE_SKILL_SUFFIX}`;\n}\n\n/**\n * Writes a complete marketplace into `marketplaceDir` and returns every path it\n * wrote, relative to that directory.\n *\n * What it writes is exactly what `docs/guides/creating-a-marketplace.md` promises a\n * marketplace holds — no more. It deliberately writes no `.claude-src/` pair: a\n * marketplace is a repository of skills, and a config manifest there would make\n * `doctor` diagnose an installation that does not exist.\n */\nexport async function writeMarketplaceScaffold(\n marketplaceDir: string,\n marketplaceName: string,\n): Promise<string[]> {\n const files = scaffoldFiles(marketplaceName);\n\n await Promise.all(\n files.map((file) => writeFile(path.join(marketplaceDir, file.relPath), file.contents)),\n );\n\n return files.map((file) => file.relPath);\n}\n\nfunction scaffoldFiles(marketplaceName: string): ScaffoldFile[] {\n const skillId = exampleSkillId(marketplaceName);\n const skillDir = path.join(SKILLS_DIR_PATH, skillId);\n\n return [\n { relPath: STANDARD_FILES.PACKAGE_JSON, contents: packageJson(marketplaceName) },\n { relPath: SKILL_CATEGORIES_PATH, contents: skillCategoriesModule() },\n { relPath: SKILL_RULES_PATH, contents: skillRulesModule() },\n { relPath: STACKS_FILE_PATH, contents: stacksModule(marketplaceName, skillId) },\n { relPath: path.join(skillDir, STANDARD_FILES.SKILL_MD), contents: skillMd(skillId) },\n {\n relPath: path.join(skillDir, STANDARD_FILES.METADATA_YAML),\n contents: metadataYaml(marketplaceName),\n },\n ];\n}\n\n/**\n * A `config/*.ts` module the CLI's loader can read.\n *\n * The loader unwraps a DEFAULT export and treats a module without one as no config\n * at all, so the export form here is load-bearing rather than stylistic.\n */\nfunction configModule(comment: string, data: unknown): string {\n return `${comment}\\nexport default ${JSON.stringify(data, null, 2)};\\n`;\n}\n\n/**\n * `build marketplace` reads a marketplace's whole identity out of package.json and\n * refuses a file missing any of name, version or description.\n *\n * `author` is the field this command cannot know, and it is written anyway —\n * omitting it is not the neutral choice it looks like. The build turns an absent\n * author into `owner: { name: \"\" }`, and the schema the CLI parses a\n * `marketplace.json` back with requires a non-empty owner name, so a scaffold with\n * no author builds a marketplace that then loads as no marketplace at all. The\n * marketplace's own handle is the least-wrong default: it is derived from what the\n * author typed rather than invented, and the next steps say to replace it.\n */\nfunction packageJson(marketplaceName: string): string {\n return `${JSON.stringify(\n {\n name: marketplaceName,\n version: INITIAL_PACKAGE_VERSION,\n description: `Skills curated for ${marketplaceName}'s conventions`,\n author: { name: authorHandle(marketplaceName) },\n },\n null,\n 2,\n )}\\n`;\n}\n\n/** The placeholder handle the marketplace publishes itself and its example skill under. */\nfunction authorHandle(marketplaceName: string): string {\n return `@${marketplaceName}`;\n}\n\nfunction skillCategoriesModule(): string {\n return configModule(\"// The categories this marketplace's skills fall into.\", {\n version: DEFAULT_VERSION,\n categories: {\n [EXAMPLE_CATEGORY]: {\n id: EXAMPLE_CATEGORY,\n displayName: \"Example\",\n description: \"Replace this with a category of your own\",\n domain: EXAMPLE_DOMAIN,\n exclusive: false,\n required: false,\n order: EXAMPLE_CATEGORY_ORDER,\n },\n },\n });\n}\n\n/**\n * A rules file with a version and nothing else.\n *\n * Relationship rules name skills by slug, and that slug reference is the CLI's own\n * generated union — so a marketplace cannot yet name its OWN skills in a rule, and\n * one that tries fails to load. A marketplace works fully without them; what it\n * loses is the wizard's incompatibility hints between its own skills.\n */\nfunction skillRulesModule(): string {\n return configModule(\n [\n \"// Relationships between skills — conflicts, requires, alternatives.\",\n \"//\",\n \"// Rules may only name skills the public catalogue carries; this marketplace's own\",\n \"// skills cannot be named here yet, and a rule that names one will not load. The\",\n \"// file still has to exist, so it ships with a version and no relationships.\",\n ].join(\"\\n\"),\n { version: DEFAULT_VERSION },\n );\n}\n\nfunction stacksModule(marketplaceName: string, skillId: string): string {\n return configModule(\"// The stacks this marketplace offers the wizard.\", {\n stacks: [\n {\n id: `${marketplaceName}-starter`,\n name: `${marketplaceName} starter`,\n description: `Every skill ${marketplaceName} ships`,\n agents: {\n [EXAMPLE_STACK_AGENT]: {\n [EXAMPLE_CATEGORY]: [{ id: skillId }],\n },\n },\n },\n ],\n });\n}\n\n/**\n * The skill's content, headed by the frontmatter the loader reads its machine id\n * out of. That id is also the directory name — `doctor` compares the two — so both\n * come from {@link exampleSkillId} rather than being spelled twice.\n */\nfunction skillMd(skillId: string): string {\n return `---\nname: ${skillId}\ndescription: A placeholder skill — replace it with one of your own\n---\n\n# Example Skill\n\nThis is where a skill's content goes: the conventions, patterns and rules you want\nevery sub-agent carrying it to follow.\n\nReplace this file and the \\`${STANDARD_FILES.METADATA_YAML}\\` beside it, and rename the\ndirectory to the id your skill should publish under.\n`;\n}\n\nfunction metadataYaml(marketplaceName: string): string {\n return [\n \"custom: true\",\n `domain: ${EXAMPLE_DOMAIN}`,\n `author: \"${authorHandle(marketplaceName)}\"`,\n \"displayName: Example Skill\",\n `category: ${EXAMPLE_CATEGORY}`,\n `slug: ${EXAMPLE_SLUG}`,\n 'cliDescription: \"A placeholder skill to replace with your own\"',\n 'usageGuidance: \"Use when you need a worked example of this marketplace\\'s skill shape\"',\n \"\",\n ].join(\"\\n\");\n}\n"],"mappings":"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","names":["path","path"]}
|