agents-inc 0.152.1 → 0.153.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 +33 -0
- package/README.md +31 -35
- package/dist/{chunk-LDP5ASDM.js → chunk-2HC2SNRP.js} +2 -15
- package/dist/chunk-2HC2SNRP.js.map +1 -0
- package/dist/{chunk-WKTHWQKM.js → chunk-35VOK7XE.js} +1338 -2573
- package/dist/chunk-35VOK7XE.js.map +1 -0
- package/dist/{chunk-SX5H6TSC.js → chunk-4VYALFQZ.js} +11 -8
- package/dist/chunk-4VYALFQZ.js.map +1 -0
- package/dist/{chunk-KXYVJGJP.js → chunk-6CNRMCFM.js} +3 -2
- package/dist/{chunk-KXYVJGJP.js.map → chunk-6CNRMCFM.js.map} +1 -1
- package/dist/{chunk-LZ52XEPR.js → chunk-ACKC577F.js} +7 -6
- package/dist/chunk-ACKC577F.js.map +1 -0
- package/dist/{chunk-XHUODHZ4.js → chunk-BMGBA6HJ.js} +22 -49
- package/dist/chunk-BMGBA6HJ.js.map +1 -0
- package/dist/{chunk-FVDKAVOL.js → chunk-EFU6P3B7.js} +18 -51
- package/dist/chunk-EFU6P3B7.js.map +1 -0
- package/dist/{chunk-STMHDOZD.js → chunk-F7Z5I6GU.js} +12 -9
- package/dist/chunk-F7Z5I6GU.js.map +1 -0
- package/dist/{chunk-E5X6RJ4E.js → chunk-FIHTAFST.js} +29 -26
- package/dist/chunk-FIHTAFST.js.map +1 -0
- package/dist/{chunk-QZZJFYUQ.js → chunk-FRWKCE6R.js} +3 -3
- package/dist/chunk-FRWKCE6R.js.map +1 -0
- package/dist/{chunk-5UWKOOIS.js → chunk-HEBPKK5L.js} +129 -195
- package/dist/chunk-HEBPKK5L.js.map +1 -0
- package/dist/{chunk-MJ2KHG24.js → chunk-IO4VEW5U.js} +6 -6
- package/dist/{chunk-MJ2KHG24.js.map → chunk-IO4VEW5U.js.map} +1 -1
- package/dist/{chunk-TUPYW2IQ.js → chunk-JC7DBPRD.js} +9 -12
- package/dist/chunk-JC7DBPRD.js.map +1 -0
- package/dist/{chunk-5GUOIJSG.js → chunk-JFAUQDZM.js} +3 -15
- package/dist/chunk-JFAUQDZM.js.map +1 -0
- package/dist/{chunk-ZL7PFNHN.js → chunk-K3O3YQYG.js} +2 -2
- package/dist/{chunk-SKQWRUPX.js → chunk-K7PJDWER.js} +59 -33
- package/dist/chunk-K7PJDWER.js.map +1 -0
- package/dist/{chunk-MVR3SYMN.js → chunk-KET3EVGX.js} +4 -3
- package/dist/{chunk-MVR3SYMN.js.map → chunk-KET3EVGX.js.map} +1 -1
- package/dist/{chunk-MWG4VU64.js → chunk-M5HSTNYU.js} +50 -56
- package/dist/chunk-M5HSTNYU.js.map +1 -0
- package/dist/{chunk-TJJPWUMA.js → chunk-NSJ2S7R5.js} +3 -2
- package/dist/{chunk-TJJPWUMA.js.map → chunk-NSJ2S7R5.js.map} +1 -1
- package/dist/{chunk-IHUY4M22.js → chunk-NXGMM5YN.js} +4 -4
- package/dist/chunk-NXQAY5U7.js +18441 -0
- package/dist/chunk-NXQAY5U7.js.map +1 -0
- package/dist/{chunk-Q2KG7UV3.js → chunk-OJJLYHM3.js} +2 -1
- package/dist/{chunk-Q2KG7UV3.js.map → chunk-OJJLYHM3.js.map} +1 -1
- package/dist/{chunk-PZIZNMHK.js → chunk-ORJ5Y222.js} +159 -138
- package/dist/chunk-ORJ5Y222.js.map +1 -0
- package/dist/{chunk-NR3OZGL4.js → chunk-OZXAJNLA.js} +2 -1
- package/dist/{chunk-NR3OZGL4.js.map → chunk-OZXAJNLA.js.map} +1 -1
- package/dist/{chunk-MM7CTTAV.js → chunk-Q5FLW4JG.js} +2 -2
- package/dist/{chunk-MM7CTTAV.js.map → chunk-Q5FLW4JG.js.map} +1 -1
- package/dist/{chunk-GRVKW3CC.js → chunk-R4SEU3DF.js} +3 -2
- package/dist/{chunk-GRVKW3CC.js.map → chunk-R4SEU3DF.js.map} +1 -1
- package/dist/{chunk-76ADG7LQ.js → chunk-R54KIGN2.js} +8 -22
- package/dist/chunk-R54KIGN2.js.map +1 -0
- package/dist/{chunk-SBHBBZKF.js → chunk-REKOWTIB.js} +25 -120
- package/dist/chunk-REKOWTIB.js.map +1 -0
- package/dist/chunk-TY6CAOL7.js +40 -0
- package/dist/chunk-TY6CAOL7.js.map +1 -0
- package/dist/{chunk-BNSRA6HL.js → chunk-U2DNAHFE.js} +39 -176
- package/dist/chunk-U2DNAHFE.js.map +1 -0
- package/dist/{chunk-PMM2MYMA.js → chunk-U2YSGBHA.js} +624 -349
- package/dist/chunk-U2YSGBHA.js.map +1 -0
- package/dist/{chunk-DTSG5XZB.js → chunk-V3ENMW7G.js} +3 -3
- package/dist/{chunk-L7SZXUBJ.js → chunk-VECFAKM5.js} +7 -6
- package/dist/{chunk-L7SZXUBJ.js.map → chunk-VECFAKM5.js.map} +1 -1
- package/dist/chunk-VGEBYCQZ.js +59 -0
- package/dist/chunk-VGEBYCQZ.js.map +1 -0
- package/dist/chunk-VZRO7RYT.js +3694 -0
- package/dist/chunk-VZRO7RYT.js.map +1 -0
- package/dist/{chunk-LASI35KT.js → chunk-WDAO3RUY.js} +14 -28
- package/dist/chunk-WDAO3RUY.js.map +1 -0
- package/dist/{chunk-MQ7FLIYS.js → chunk-WG6V6VJV.js} +3 -2
- package/dist/{chunk-MQ7FLIYS.js.map → chunk-WG6V6VJV.js.map} +1 -1
- package/dist/chunk-X5XJ6WKO.js +284 -0
- package/dist/chunk-X5XJ6WKO.js.map +1 -0
- package/dist/{chunk-RNJWAKMO.js → chunk-XGMOXMS4.js} +9 -8
- package/dist/chunk-XGMOXMS4.js.map +1 -0
- package/dist/{chunk-IUQBOCSU.js → chunk-ZBPEFQ4G.js} +2 -1
- package/dist/{chunk-IUQBOCSU.js.map → chunk-ZBPEFQ4G.js.map} +1 -1
- package/dist/{chunk-QRDTLVXG.js → chunk-ZNDLUWWD.js} +9 -22
- package/dist/chunk-ZNDLUWWD.js.map +1 -0
- package/dist/commands/build/marketplace.js +114 -35
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +9 -10
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/compile.js +97 -70
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +793 -64
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +169 -208
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +24 -39
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +41 -46
- package/dist/commands/list.js +10 -12
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/search.js +20 -81
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +25 -31
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +82 -332
- package/dist/commands/update.js.map +1 -1
- package/dist/components/common/confirm.js +1 -1
- package/dist/components/common/prompt-confirm.js +1 -1
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/common/spinner.js +1 -1
- package/dist/components/wizard/category-grid.js +5 -6
- package/dist/components/wizard/checkbox-grid.js +5 -6
- package/dist/components/wizard/domain-selection.js +12 -13
- package/dist/components/wizard/run-wizard-session.js +30 -36
- package/dist/components/wizard/scroll-affordance.js +2 -2
- package/dist/components/wizard/skill-agent-summary.js +7 -7
- package/dist/components/wizard/source-grid.js +6 -11
- package/dist/components/wizard/stack-selection.js +9 -9
- package/dist/components/wizard/step-agents.js +12 -12
- package/dist/components/wizard/step-build.js +10 -11
- package/dist/components/wizard/step-confirm.js +11 -11
- package/dist/components/wizard/step-sources.js +11 -17
- package/dist/components/wizard/step-stack.js +10 -10
- package/dist/components/wizard/summary-panel.js +10 -10
- package/dist/components/wizard/toast.js +2 -2
- package/dist/components/wizard/wizard-layout.js +15 -16
- package/dist/components/wizard/wizard-tabs.js +6 -12
- package/dist/components/wizard/wizard.js +29 -35
- package/dist/config-exports.js +1 -1
- package/dist/copy-local-skills-KF2RAVD3.js +14 -0
- package/dist/hooks/init.js +49 -48
- package/dist/hooks/init.js.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/load-agent-defs-DGXGBU3Q.js +15 -0
- package/dist/{loader-5JP4S7CJ.js → loader-4U7UCE2Y.js} +7 -5
- package/dist/recompile-project-agents-CJVBAWDJ.js +20 -0
- package/dist/{source-loader-MZYCPL2S.js → source-loader-ZNSYJJCI.js} +6 -6
- package/dist/src/agents/developer/ai-developer/identity.md +4 -4
- package/dist/src/agents/developer/ai-developer/playbook.md +1 -1
- package/dist/src/agents/developer/api-developer/identity.md +4 -4
- package/dist/src/agents/developer/api-developer/metadata.yaml +1 -1
- package/dist/src/agents/developer/cli-developer/identity.md +4 -4
- package/dist/src/agents/developer/web-developer/identity.md +2 -2
- package/dist/src/agents/developer/web-developer/metadata.yaml +1 -1
- package/dist/src/agents/meta/agent-summoner/identity.md +4 -5
- package/dist/src/agents/meta/agent-summoner/output.md +2 -2
- package/dist/src/agents/meta/agent-summoner/playbook.md +15 -16
- package/dist/src/agents/meta/codex-keeper/identity.md +4 -4
- package/dist/src/agents/meta/codex-keeper/playbook.md +1 -1
- package/dist/src/agents/meta/convention-keeper/identity.md +1 -1
- package/dist/src/agents/meta/skill-summoner/critical-reminders.md +0 -34
- package/dist/src/agents/meta/skill-summoner/critical-requirements.md +27 -3
- package/dist/src/agents/meta/skill-summoner/identity.md +2 -2
- package/{src/agents/planning/web-pm → dist/src/agents/planning/pm}/critical-reminders.md +10 -7
- package/dist/src/agents/planning/{web-pm → pm}/critical-requirements.md +8 -4
- package/dist/src/agents/planning/pm/identity.md +47 -0
- package/dist/src/agents/planning/pm/metadata.yaml +12 -0
- package/dist/src/agents/planning/{web-pm → pm}/output.md +7 -90
- package/dist/src/agents/planning/pm/playbook.md +185 -0
- package/dist/src/agents/researcher/ai-researcher/critical-reminders.md +58 -0
- package/dist/src/agents/researcher/ai-researcher/critical-requirements.md +40 -0
- package/dist/src/agents/researcher/ai-researcher/identity.md +86 -0
- package/dist/src/agents/researcher/ai-researcher/metadata.yaml +10 -0
- package/dist/src/agents/researcher/ai-researcher/output.md +363 -0
- package/dist/src/agents/researcher/ai-researcher/playbook.md +545 -0
- package/dist/src/agents/researcher/api-researcher/critical-reminders.md +16 -0
- package/dist/src/agents/researcher/api-researcher/identity.md +7 -7
- package/dist/src/agents/researcher/cli-researcher/critical-reminders.md +50 -0
- package/dist/src/agents/researcher/cli-researcher/critical-requirements.md +36 -0
- package/dist/src/agents/researcher/cli-researcher/identity.md +87 -0
- package/dist/src/agents/researcher/cli-researcher/metadata.yaml +10 -0
- package/dist/src/agents/researcher/cli-researcher/output.md +343 -0
- package/dist/src/agents/researcher/cli-researcher/playbook.md +370 -0
- package/dist/src/agents/researcher/web-researcher/identity.md +5 -6
- package/dist/src/agents/reviewer/reviewer/critical-reminders.md +29 -0
- package/dist/src/agents/reviewer/reviewer/critical-requirements.md +31 -0
- package/dist/src/agents/reviewer/reviewer/identity.md +41 -0
- package/dist/src/agents/reviewer/reviewer/metadata.yaml +12 -0
- package/dist/src/agents/reviewer/reviewer/output.md +202 -0
- package/dist/src/agents/reviewer/reviewer/playbook.md +141 -0
- package/dist/src/agents/tester/ai-tester/critical-reminders.md +48 -0
- package/dist/src/agents/tester/ai-tester/critical-requirements.md +49 -0
- package/dist/src/agents/tester/ai-tester/identity.md +62 -0
- package/dist/src/agents/tester/ai-tester/metadata.yaml +12 -0
- package/dist/src/agents/tester/ai-tester/output.md +375 -0
- package/dist/src/agents/tester/ai-tester/playbook.md +789 -0
- package/dist/src/agents/tester/api-tester/identity.md +3 -3
- package/dist/src/agents/tester/cli-tester/critical-reminders.md +3 -3
- package/dist/src/agents/tester/cli-tester/critical-requirements.md +2 -2
- package/dist/src/agents/tester/cli-tester/identity.md +3 -3
- package/dist/src/agents/tester/cli-tester/output.md +4 -4
- package/dist/src/agents/tester/cli-tester/playbook.md +3 -3
- package/dist/src/agents/tester/web-tester/identity.md +3 -3
- package/dist/stores/wizard-store.js +8 -6
- package/package.json +13 -2
- package/src/agents/developer/ai-developer/identity.md +4 -4
- package/src/agents/developer/ai-developer/playbook.md +1 -1
- package/src/agents/developer/api-developer/identity.md +4 -4
- package/src/agents/developer/api-developer/metadata.yaml +1 -1
- package/src/agents/developer/cli-developer/identity.md +4 -4
- package/src/agents/developer/web-developer/identity.md +2 -2
- package/src/agents/developer/web-developer/metadata.yaml +1 -1
- package/src/agents/meta/agent-summoner/identity.md +4 -5
- package/src/agents/meta/agent-summoner/output.md +2 -2
- package/src/agents/meta/agent-summoner/playbook.md +15 -16
- package/src/agents/meta/codex-keeper/identity.md +4 -4
- package/src/agents/meta/codex-keeper/playbook.md +1 -1
- package/src/agents/meta/convention-keeper/identity.md +1 -1
- package/src/agents/meta/skill-summoner/critical-reminders.md +0 -34
- package/src/agents/meta/skill-summoner/critical-requirements.md +27 -3
- package/src/agents/meta/skill-summoner/identity.md +2 -2
- package/{dist/src/agents/planning/web-pm → src/agents/planning/pm}/critical-reminders.md +10 -7
- package/src/agents/planning/{web-pm → pm}/critical-requirements.md +8 -4
- package/src/agents/planning/pm/identity.md +47 -0
- package/src/agents/planning/pm/metadata.yaml +12 -0
- package/src/agents/planning/{web-pm → pm}/output.md +7 -90
- package/src/agents/planning/pm/playbook.md +185 -0
- package/src/agents/researcher/ai-researcher/critical-reminders.md +58 -0
- package/src/agents/researcher/ai-researcher/critical-requirements.md +40 -0
- package/src/agents/researcher/ai-researcher/identity.md +86 -0
- package/src/agents/researcher/ai-researcher/metadata.yaml +10 -0
- package/src/agents/researcher/ai-researcher/output.md +363 -0
- package/src/agents/researcher/ai-researcher/playbook.md +545 -0
- package/src/agents/researcher/api-researcher/critical-reminders.md +16 -0
- package/src/agents/researcher/api-researcher/identity.md +7 -7
- package/src/agents/researcher/cli-researcher/critical-reminders.md +50 -0
- package/src/agents/researcher/cli-researcher/critical-requirements.md +36 -0
- package/src/agents/researcher/cli-researcher/identity.md +87 -0
- package/src/agents/researcher/cli-researcher/metadata.yaml +10 -0
- package/src/agents/researcher/cli-researcher/output.md +343 -0
- package/src/agents/researcher/cli-researcher/playbook.md +370 -0
- package/src/agents/researcher/web-researcher/identity.md +5 -6
- package/src/agents/reviewer/reviewer/critical-reminders.md +29 -0
- package/src/agents/reviewer/reviewer/critical-requirements.md +31 -0
- package/src/agents/reviewer/reviewer/identity.md +41 -0
- package/src/agents/reviewer/reviewer/metadata.yaml +12 -0
- package/src/agents/reviewer/reviewer/output.md +202 -0
- package/src/agents/reviewer/reviewer/playbook.md +141 -0
- package/src/agents/tester/ai-tester/critical-reminders.md +48 -0
- package/src/agents/tester/ai-tester/critical-requirements.md +49 -0
- package/src/agents/tester/ai-tester/identity.md +62 -0
- package/src/agents/tester/ai-tester/metadata.yaml +12 -0
- package/src/agents/tester/ai-tester/output.md +375 -0
- package/src/agents/tester/ai-tester/playbook.md +789 -0
- package/src/agents/tester/api-tester/identity.md +3 -3
- package/src/agents/tester/cli-tester/critical-reminders.md +3 -3
- package/src/agents/tester/cli-tester/critical-requirements.md +2 -2
- package/src/agents/tester/cli-tester/identity.md +3 -3
- package/src/agents/tester/cli-tester/output.md +4 -4
- package/src/agents/tester/cli-tester/playbook.md +3 -3
- package/src/agents/tester/web-tester/identity.md +3 -3
- package/src/schemas/metadata.schema.json +31 -2
- package/src/schemas/project-config.schema.json +61 -15
- package/src/schemas/project-source-config.schema.json +0 -47
- package/dist/chunk-5GUOIJSG.js.map +0 -1
- package/dist/chunk-5UWKOOIS.js.map +0 -1
- package/dist/chunk-76ADG7LQ.js.map +0 -1
- package/dist/chunk-BNSRA6HL.js.map +0 -1
- package/dist/chunk-E5X6RJ4E.js.map +0 -1
- package/dist/chunk-EEPELKOM.js +0 -5938
- package/dist/chunk-EEPELKOM.js.map +0 -1
- package/dist/chunk-F7T5AFFN.js +0 -20
- package/dist/chunk-F7T5AFFN.js.map +0 -1
- package/dist/chunk-FVDKAVOL.js.map +0 -1
- package/dist/chunk-KFB5CRXZ.js +0 -377
- package/dist/chunk-KFB5CRXZ.js.map +0 -1
- package/dist/chunk-KR65TPKC.js +0 -664
- package/dist/chunk-KR65TPKC.js.map +0 -1
- package/dist/chunk-LASI35KT.js.map +0 -1
- package/dist/chunk-LDP5ASDM.js.map +0 -1
- package/dist/chunk-LZ52XEPR.js.map +0 -1
- package/dist/chunk-M7HO7NBK.js +0 -88
- package/dist/chunk-M7HO7NBK.js.map +0 -1
- package/dist/chunk-MWG4VU64.js.map +0 -1
- package/dist/chunk-ODNDXQH2.js +0 -77
- package/dist/chunk-ODNDXQH2.js.map +0 -1
- package/dist/chunk-P44SXVH3.js +0 -80
- package/dist/chunk-P44SXVH3.js.map +0 -1
- package/dist/chunk-PMM2MYMA.js.map +0 -1
- package/dist/chunk-PZIZNMHK.js.map +0 -1
- package/dist/chunk-Q45ZU6HD.js +0 -37
- package/dist/chunk-Q45ZU6HD.js.map +0 -1
- package/dist/chunk-QRDTLVXG.js.map +0 -1
- package/dist/chunk-QZZJFYUQ.js.map +0 -1
- package/dist/chunk-R5NOI2LP.js +0 -170
- package/dist/chunk-R5NOI2LP.js.map +0 -1
- package/dist/chunk-RNJWAKMO.js.map +0 -1
- package/dist/chunk-SBHBBZKF.js.map +0 -1
- package/dist/chunk-SKQWRUPX.js.map +0 -1
- package/dist/chunk-STMHDOZD.js.map +0 -1
- package/dist/chunk-SX5H6TSC.js.map +0 -1
- package/dist/chunk-TUPYW2IQ.js.map +0 -1
- package/dist/chunk-UBEDZ4FD.js +0 -4198
- package/dist/chunk-UBEDZ4FD.js.map +0 -1
- package/dist/chunk-VY6MNOXL.js +0 -20
- package/dist/chunk-VY6MNOXL.js.map +0 -1
- package/dist/chunk-WBCPLH66.js +0 -42
- package/dist/chunk-WBCPLH66.js.map +0 -1
- package/dist/chunk-WKTHWQKM.js.map +0 -1
- package/dist/chunk-XHUODHZ4.js.map +0 -1
- package/dist/chunk-ZPPHXXAP.js +0 -252
- package/dist/chunk-ZPPHXXAP.js.map +0 -1
- package/dist/commands/import/skill.js +0 -344
- package/dist/commands/import/skill.js.map +0 -1
- package/dist/commands/new/agent.js +0 -300
- package/dist/commands/new/agent.js.map +0 -1
- package/dist/commands/new/marketplace.js +0 -310
- package/dist/commands/new/marketplace.js.map +0 -1
- package/dist/commands/new/skill.js +0 -26
- package/dist/commands/validate.js +0 -575
- package/dist/commands/validate.js.map +0 -1
- package/dist/components/wizard/search-modal.js +0 -13
- package/dist/components/wizard/selection-card.js +0 -9
- package/dist/components/wizard/step-settings.js +0 -18
- package/dist/copy-local-skills-6EMVN7RB.js +0 -14
- package/dist/load-agent-defs-BWOUVEAR.js +0 -15
- package/dist/load-agent-defs-BWOUVEAR.js.map +0 -1
- package/dist/loader-5JP4S7CJ.js.map +0 -1
- package/dist/recompile-project-agents-6DL45TDI.js +0 -19
- package/dist/recompile-project-agents-6DL45TDI.js.map +0 -1
- package/dist/source-loader-MZYCPL2S.js.map +0 -1
- package/dist/src/agents/developer/web-architecture/critical-reminders.md +0 -48
- package/dist/src/agents/developer/web-architecture/critical-requirements.md +0 -65
- package/dist/src/agents/developer/web-architecture/identity.md +0 -64
- package/dist/src/agents/developer/web-architecture/metadata.yaml +0 -12
- package/dist/src/agents/developer/web-architecture/output.md +0 -449
- package/dist/src/agents/developer/web-architecture/playbook.md +0 -481
- package/dist/src/agents/pattern/pattern-scout/critical-reminders.md +0 -71
- package/dist/src/agents/pattern/pattern-scout/critical-requirements.md +0 -31
- package/dist/src/agents/pattern/pattern-scout/identity.md +0 -25
- package/dist/src/agents/pattern/pattern-scout/metadata.yaml +0 -10
- package/dist/src/agents/pattern/pattern-scout/output.md +0 -290
- package/dist/src/agents/pattern/pattern-scout/playbook.md +0 -1806
- package/dist/src/agents/pattern/web-pattern-critique/critical-reminders.md +0 -30
- package/dist/src/agents/pattern/web-pattern-critique/critical-requirements.md +0 -28
- package/dist/src/agents/pattern/web-pattern-critique/identity.md +0 -41
- package/dist/src/agents/pattern/web-pattern-critique/metadata.yaml +0 -12
- package/dist/src/agents/pattern/web-pattern-critique/output.md +0 -314
- package/dist/src/agents/pattern/web-pattern-critique/playbook.md +0 -572
- package/dist/src/agents/planning/api-pm/critical-reminders.md +0 -48
- package/dist/src/agents/planning/api-pm/critical-requirements.md +0 -41
- package/dist/src/agents/planning/api-pm/identity.md +0 -39
- package/dist/src/agents/planning/api-pm/metadata.yaml +0 -12
- package/dist/src/agents/planning/api-pm/output.md +0 -475
- package/dist/src/agents/planning/api-pm/playbook.md +0 -129
- package/dist/src/agents/planning/web-pm/identity.md +0 -26
- package/dist/src/agents/planning/web-pm/metadata.yaml +0 -12
- package/dist/src/agents/planning/web-pm/playbook.md +0 -318
- package/dist/src/agents/reviewer/ai-reviewer/critical-reminders.md +0 -40
- package/dist/src/agents/reviewer/ai-reviewer/critical-requirements.md +0 -37
- package/dist/src/agents/reviewer/ai-reviewer/identity.md +0 -51
- package/dist/src/agents/reviewer/ai-reviewer/metadata.yaml +0 -10
- package/dist/src/agents/reviewer/ai-reviewer/output.md +0 -395
- package/dist/src/agents/reviewer/ai-reviewer/playbook.md +0 -90
- package/dist/src/agents/reviewer/api-reviewer/critical-reminders.md +0 -31
- package/dist/src/agents/reviewer/api-reviewer/critical-requirements.md +0 -27
- package/dist/src/agents/reviewer/api-reviewer/identity.md +0 -51
- package/dist/src/agents/reviewer/api-reviewer/metadata.yaml +0 -12
- package/dist/src/agents/reviewer/api-reviewer/output.md +0 -343
- package/dist/src/agents/reviewer/api-reviewer/playbook.md +0 -288
- package/dist/src/agents/reviewer/cli-reviewer/critical-reminders.md +0 -33
- package/dist/src/agents/reviewer/cli-reviewer/critical-requirements.md +0 -30
- package/dist/src/agents/reviewer/cli-reviewer/identity.md +0 -44
- package/dist/src/agents/reviewer/cli-reviewer/metadata.yaml +0 -12
- package/dist/src/agents/reviewer/cli-reviewer/output.md +0 -414
- package/dist/src/agents/reviewer/cli-reviewer/playbook.md +0 -218
- package/dist/src/agents/reviewer/infra-reviewer/critical-reminders.md +0 -38
- package/dist/src/agents/reviewer/infra-reviewer/critical-requirements.md +0 -38
- package/dist/src/agents/reviewer/infra-reviewer/identity.md +0 -53
- package/dist/src/agents/reviewer/infra-reviewer/metadata.yaml +0 -10
- package/dist/src/agents/reviewer/infra-reviewer/output.md +0 -364
- package/dist/src/agents/reviewer/infra-reviewer/playbook.md +0 -161
- package/dist/src/agents/reviewer/web-reviewer/critical-reminders.md +0 -31
- package/dist/src/agents/reviewer/web-reviewer/critical-requirements.md +0 -26
- package/dist/src/agents/reviewer/web-reviewer/identity.md +0 -40
- package/dist/src/agents/reviewer/web-reviewer/metadata.yaml +0 -12
- package/dist/src/agents/reviewer/web-reviewer/output.md +0 -333
- package/dist/src/agents/reviewer/web-reviewer/playbook.md +0 -156
- package/src/agents/developer/web-architecture/critical-reminders.md +0 -48
- package/src/agents/developer/web-architecture/critical-requirements.md +0 -65
- package/src/agents/developer/web-architecture/identity.md +0 -64
- package/src/agents/developer/web-architecture/metadata.yaml +0 -12
- package/src/agents/developer/web-architecture/output.md +0 -449
- package/src/agents/developer/web-architecture/playbook.md +0 -481
- package/src/agents/pattern/pattern-scout/critical-reminders.md +0 -71
- package/src/agents/pattern/pattern-scout/critical-requirements.md +0 -31
- package/src/agents/pattern/pattern-scout/identity.md +0 -25
- package/src/agents/pattern/pattern-scout/metadata.yaml +0 -10
- package/src/agents/pattern/pattern-scout/output.md +0 -290
- package/src/agents/pattern/pattern-scout/playbook.md +0 -1806
- package/src/agents/pattern/web-pattern-critique/critical-reminders.md +0 -30
- package/src/agents/pattern/web-pattern-critique/critical-requirements.md +0 -28
- package/src/agents/pattern/web-pattern-critique/identity.md +0 -41
- package/src/agents/pattern/web-pattern-critique/metadata.yaml +0 -12
- package/src/agents/pattern/web-pattern-critique/output.md +0 -314
- package/src/agents/pattern/web-pattern-critique/playbook.md +0 -572
- package/src/agents/planning/api-pm/critical-reminders.md +0 -48
- package/src/agents/planning/api-pm/critical-requirements.md +0 -41
- package/src/agents/planning/api-pm/identity.md +0 -39
- package/src/agents/planning/api-pm/metadata.yaml +0 -12
- package/src/agents/planning/api-pm/output.md +0 -475
- package/src/agents/planning/api-pm/playbook.md +0 -129
- package/src/agents/planning/web-pm/identity.md +0 -26
- package/src/agents/planning/web-pm/metadata.yaml +0 -12
- package/src/agents/planning/web-pm/playbook.md +0 -318
- package/src/agents/reviewer/ai-reviewer/critical-reminders.md +0 -40
- package/src/agents/reviewer/ai-reviewer/critical-requirements.md +0 -37
- package/src/agents/reviewer/ai-reviewer/identity.md +0 -51
- package/src/agents/reviewer/ai-reviewer/metadata.yaml +0 -10
- package/src/agents/reviewer/ai-reviewer/output.md +0 -395
- package/src/agents/reviewer/ai-reviewer/playbook.md +0 -90
- package/src/agents/reviewer/api-reviewer/critical-reminders.md +0 -31
- package/src/agents/reviewer/api-reviewer/critical-requirements.md +0 -27
- package/src/agents/reviewer/api-reviewer/identity.md +0 -51
- package/src/agents/reviewer/api-reviewer/metadata.yaml +0 -12
- package/src/agents/reviewer/api-reviewer/output.md +0 -343
- package/src/agents/reviewer/api-reviewer/playbook.md +0 -288
- package/src/agents/reviewer/cli-reviewer/critical-reminders.md +0 -33
- package/src/agents/reviewer/cli-reviewer/critical-requirements.md +0 -30
- package/src/agents/reviewer/cli-reviewer/identity.md +0 -44
- package/src/agents/reviewer/cli-reviewer/metadata.yaml +0 -12
- package/src/agents/reviewer/cli-reviewer/output.md +0 -414
- package/src/agents/reviewer/cli-reviewer/playbook.md +0 -218
- package/src/agents/reviewer/infra-reviewer/critical-reminders.md +0 -38
- package/src/agents/reviewer/infra-reviewer/critical-requirements.md +0 -38
- package/src/agents/reviewer/infra-reviewer/identity.md +0 -53
- package/src/agents/reviewer/infra-reviewer/metadata.yaml +0 -10
- package/src/agents/reviewer/infra-reviewer/output.md +0 -364
- package/src/agents/reviewer/infra-reviewer/playbook.md +0 -161
- package/src/agents/reviewer/web-reviewer/critical-reminders.md +0 -31
- package/src/agents/reviewer/web-reviewer/critical-requirements.md +0 -26
- package/src/agents/reviewer/web-reviewer/identity.md +0 -40
- package/src/agents/reviewer/web-reviewer/metadata.yaml +0 -12
- package/src/agents/reviewer/web-reviewer/output.md +0 -333
- package/src/agents/reviewer/web-reviewer/playbook.md +0 -156
- /package/dist/{chunk-ZL7PFNHN.js.map → chunk-K3O3YQYG.js.map} +0 -0
- /package/dist/{chunk-IHUY4M22.js.map → chunk-NXGMM5YN.js.map} +0 -0
- /package/dist/{chunk-DTSG5XZB.js.map → chunk-V3ENMW7G.js.map} +0 -0
- /package/dist/{commands/new/skill.js.map → copy-local-skills-KF2RAVD3.js.map} +0 -0
- /package/dist/{components/wizard/search-modal.js.map → load-agent-defs-DGXGBU3Q.js.map} +0 -0
- /package/dist/{components/wizard/selection-card.js.map → loader-4U7UCE2Y.js.map} +0 -0
- /package/dist/{components/wizard/step-settings.js.map → recompile-project-agents-CJVBAWDJ.js.map} +0 -0
- /package/dist/{copy-local-skills-6EMVN7RB.js.map → source-loader-ZNSYJJCI.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/wizard/category-grid.tsx","../src/cli/components/hooks/use-category-grid-input.ts"],"sourcesContent":["import React, { useCallback, useEffect } from \"react\";\n\nimport { Box, Text } from \"ink\";\n\nimport { CLI_COLORS } from \"../../consts.js\";\nimport { getSkillById } from \"../../lib/matrix/matrix-provider.js\";\nimport type { Category, OptionState, SkillId, SkillScope } from \"../../types/index.js\";\nimport { useCategoryGridInput } from \"../hooks/use-category-grid-input.js\";\nimport { useFocusedListItem } from \"../hooks/use-focused-list-item.js\";\nimport { useSectionScroll } from \"../hooks/use-section-scroll.js\";\n\nexport type CategoryOption = {\n id: SkillId;\n state: OptionState;\n selected: boolean;\n local?: boolean;\n installed?: boolean;\n scope?: SkillScope;\n /** Secondary scope badge shown alongside primary (e.g. after G->P toggle, excluded tombstone) */\n secondaryScope?: SkillScope;\n source?: string;\n /** True when selected but has unmet dependency requirements (shown dimmed) */\n hasUnmetRequirements?: boolean;\n /** Explains unmet requirements (shown in label when D pressed) */\n unmetRequirementsReason?: string;\n /** Display name of the skill that requires this one (e.g. \"Next.js\") */\n requiredBy?: string;\n};\n\nexport type CategoryRow = {\n id: Category;\n displayName: string;\n required: boolean;\n exclusive: boolean;\n options: CategoryOption[];\n};\n\nexport type CategoryGridProps = {\n categories: CategoryRow[];\n /** Available height in terminal lines for the scrollable viewport. 0 = no constraint. */\n availableHeight?: number;\n showLabels: boolean;\n onToggle: (categoryId: Category, technologyId: SkillId) => void;\n onToggleLabels: () => void;\n /** Optional initial focus row (default: 0). Use with React `key` to reset. */\n defaultFocusedRow?: number;\n /** Optional initial focus col (default: 0). Use with React `key` to reset. */\n defaultFocusedCol?: number;\n /** Optional callback fired whenever the focused position changes */\n onFocusChange?: (row: number, col: number) => void;\n /** Optional callback fired with the resolved SkillId of the focused cell */\n onFocusedSkillChange?: (skillId: SkillId | null) => void;\n};\n\nconst SYMBOL_REQUIRED = \"*\";\n\n/** Next option index stepping cyclically from `currentIndex`; empty rows stay put. */\nconst wrapOptionIndex = (length: number, currentIndex: number, direction: 1 | -1): number => {\n if (length === 0) return currentIndex;\n return (currentIndex + direction + length) % length;\n};\n\ntype SkillTagProps = {\n option: CategoryOption;\n isFocused: boolean;\n showLabels: boolean;\n};\n\nconst getCompatibilityLabel = (option: CategoryOption): string | null => {\n if (option.selected && option.hasUnmetRequirements && option.unmetRequirementsReason) {\n return `(${option.unmetRequirementsReason})`;\n }\n if (option.selected) return null;\n if (option.requiredBy) return `(required by ${option.requiredBy})`;\n if (option.state.status === \"incompatible\") return \"(incompatible)\";\n if (option.state.status === \"discouraged\") return \"(discouraged)\";\n return null;\n};\n\nconst STATUS_COLORS: Partial<Record<OptionState[\"status\"], string>> = {\n incompatible: CLI_COLORS.ERROR,\n discouraged: CLI_COLORS.WARNING,\n};\n\n/** Selected wins, then advisory status; `fallback` covers the plain \"normal\" state. */\nfunction resolveTagColor(option: CategoryOption, fallback: string): string {\n if (option.selected) return CLI_COLORS.PRIMARY;\n return STATUS_COLORS[option.state.status] ?? fallback;\n}\n\nconst SkillTag: React.FC<SkillTagProps> = ({ option, isFocused, showLabels }) => {\n const textColor = resolveTagColor(option, CLI_COLORS.DIM);\n const hasRequiredBy = option.selected && !!option.requiredBy;\n const hasUnmetDeps = option.selected && !!option.hasUnmetRequirements;\n const isDimmed = hasUnmetDeps || hasRequiredBy;\n const showCompatibility = hasRequiredBy || hasUnmetDeps || (showLabels && isFocused);\n const compatibilityLabel = showCompatibility ? getCompatibilityLabel(option) : null;\n\n return (\n <Box\n marginRight={1}\n borderColor={isFocused ? resolveTagColor(option, CLI_COLORS.UNFOCUSED) : textColor}\n borderDimColor={!isFocused}\n borderStyle=\"single\"\n flexShrink={0}\n paddingLeft={1}\n flexDirection=\"row\"\n >\n <>\n {option.scope && (\n <>\n {[option.scope, option.secondaryScope].filter(Boolean).map((badgeScope, i) => (\n <Text key={i} color={CLI_COLORS.WARNING} backgroundColor={CLI_COLORS.LABEL_BG}>\n {badgeScope === \"global\" ? \" G \" : \" P \"}\n </Text>\n ))}\n <Text> </Text>\n </>\n )}\n <Text color={textColor} bold dimColor={isDimmed}>\n {getSkillById(option.id).displayName}{\" \"}\n </Text>\n {compatibilityLabel && (\n <Text color={textColor} dimColor>\n {compatibilityLabel}{\" \"}\n </Text>\n )}\n </>\n </Box>\n );\n};\n\ntype CategorySectionProps = {\n isFirst: boolean;\n category: CategoryRow;\n isFocused: boolean;\n focusedOptionIndex: number;\n showLabels: boolean;\n};\n\nconst CategorySection: React.FC<CategorySectionProps> = ({\n isFirst,\n category,\n isFocused,\n focusedOptionIndex,\n showLabels,\n}) => {\n const { options } = category;\n const selectedCount = options.filter((o) => o.selected).length;\n\n const selectionCounter = category.exclusive ? `(${selectedCount} of 1)` : null;\n\n return (\n <Box flexDirection=\"column\" marginTop={isFirst ? 0 : 1}>\n <Box flexDirection=\"row\">\n {isFocused ? (\n <Text color={CLI_COLORS.WHITE} backgroundColor={CLI_COLORS.LABEL_BG}>\n {` ${category.displayName}${category.required ? ` ${SYMBOL_REQUIRED}` : \"\"}${selectionCounter ? ` ${selectionCounter}` : \"\"} `}\n </Text>\n ) : (\n <>\n <Text color={CLI_COLORS.NEUTRAL}>{category.displayName}</Text>\n {category.required && <Text color={CLI_COLORS.NEUTRAL}> {SYMBOL_REQUIRED}</Text>}\n {selectionCounter && <Text dimColor> {selectionCounter}</Text>}\n </>\n )}\n </Box>\n\n <Box flexDirection=\"row\" flexWrap=\"wrap\" marginTop={0}>\n {options.map((option, index) => (\n <SkillTag\n key={option.id}\n option={option}\n isFocused={isFocused && index === focusedOptionIndex}\n showLabels={showLabels}\n />\n ))}\n </Box>\n </Box>\n );\n};\n\nexport const CategoryGrid: React.FC<CategoryGridProps> = ({\n categories,\n availableHeight = 0,\n showLabels,\n onToggle,\n onToggleLabels,\n defaultFocusedRow = 0,\n defaultFocusedCol = 0,\n onFocusChange,\n onFocusedSkillChange,\n}) => {\n const getColCount = useCallback(\n (row: number): number => categories[row]?.options.length ?? 0,\n [categories],\n );\n\n const findValidCol = useCallback(\n (row: number, currentCol: number, direction: 1 | -1): number =>\n wrapOptionIndex(categories[row]?.options.length ?? 0, currentCol, direction),\n [categories],\n );\n\n const handleFocusChange = useCallback(\n (row: number, col: number) => {\n if (showLabels) onToggleLabels();\n onFocusChange?.(row, col);\n },\n [showLabels, onToggleLabels, onFocusChange],\n );\n\n const { focusedRow, focusedCol, setFocused, moveFocus } = useFocusedListItem(\n categories.length,\n getColCount,\n {\n wrap: true,\n findValidCol,\n onChange: handleFocusChange,\n initialRow: defaultFocusedRow,\n initialCol: defaultFocusedCol,\n },\n );\n\n useCategoryGridInput({\n categories,\n focusedRow,\n focusedCol,\n setFocused,\n moveFocus,\n onToggle,\n onToggleLabels,\n });\n\n // Report the focused cell's skill on mount and whenever it changes — including\n // category reshapes that shift the cell without a navigation event. useFocusedListItem\n // only fires onChange during navigation, so the initially highlighted cell would\n // otherwise never reach the store, leaving focusedSkillId out of sync with the visual\n // focus and making the `s` scope hotkey no-op until the first arrow key.\n const focusedSkillId = categories[focusedRow]?.options[focusedCol]?.id ?? null;\n useEffect(() => {\n onFocusedSkillChange?.(focusedSkillId);\n }, [focusedSkillId, onFocusedSkillChange]);\n\n // `hiddenAbove` / `hiddenBelow` are discarded ON PURPOSE — the build grid has\n // no `ScrollAffordance` and is not getting one (owner decision). On a grid\n // this dense a half-cut card already says \"there is more\"; a counted hint\n // would be noise, and it would cost the viewport a row to say what the\n // clipped card says for free. Do not add one on the strength of the counts\n // merely being available here.\n const { setSectionRef, scrollEnabled, scrollTopPx } = useSectionScroll({\n sectionCount: categories.length,\n focusedIndex: focusedRow,\n availableHeight,\n });\n\n if (categories.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text dimColor>No categories to display.</Text>\n </Box>\n );\n }\n\n const noShrink = scrollEnabled ? { flexShrink: 0 } : {};\n\n const sectionElements = categories.map((category, index) => (\n <Box key={category.id} ref={(el) => setSectionRef(index, el)} {...noShrink}>\n <CategorySection\n category={category}\n isFocused={index === focusedRow}\n focusedOptionIndex={focusedCol}\n showLabels={showLabels}\n isFirst={index === 0}\n />\n </Box>\n ));\n\n return (\n <Box\n flexDirection=\"column\"\n {...(scrollEnabled\n ? { height: availableHeight, overflow: \"hidden\" as const }\n : { flexGrow: 1 })}\n >\n <Box flexDirection=\"column\" marginTop={scrollTopPx > 0 ? -scrollTopPx : 0} {...noShrink}>\n {sectionElements}\n </Box>\n </Box>\n );\n};\n","import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useInput, type Key } from \"ink\";\n\nimport type { Category, SkillId } from \"../../types/index.js\";\nimport type { CategoryRow } from \"../wizard/category-grid.js\";\nimport type { Direction } from \"./use-focused-list-item.js\";\nimport { HOTKEY_TOGGLE_LABELS, KEY_SPACE, isHotkey } from \"../wizard/hotkeys.js\";\n\n/** Find next section index (wrapping forward) */\nconst findNextIndex = (items: { length: number }, currentIndex: number): number => {\n const length = items.length;\n if (length === 0) return currentIndex;\n return (currentIndex + 1) % length;\n};\n\ntype UseCategoryGridInputOptions = {\n categories: CategoryRow[];\n focusedRow: number;\n focusedCol: number;\n setFocused: (row: number, col: number) => void;\n moveFocus: (direction: Direction) => void;\n onToggle: (categoryId: Category, technologyId: SkillId) => void;\n onToggleLabels: () => void;\n};\n\nexport function useCategoryGridInput({\n categories,\n focusedRow,\n focusedCol,\n setFocused,\n moveFocus,\n onToggle,\n onToggleLabels,\n}: UseCategoryGridInputOptions): void {\n const currentRow = categories[focusedRow];\n // Memoised so the effect below keys on the row actually changing — the `[]`\n // fallback used to be a fresh array every render, re-running the effect for\n // nothing whenever no row was focused.\n const currentOptions = useMemo(() => currentRow?.options ?? [], [currentRow]);\n\n // Adjust column when current row's options change externally (e.g. option becomes disabled)\n useEffect(() => {\n if (!currentRow) return;\n\n const maxCol = currentOptions.length - 1;\n if (focusedCol > maxCol) {\n const newCol = Math.max(0, maxCol);\n setFocused(focusedRow, newCol);\n }\n }, [focusedRow, currentOptions, focusedCol, setFocused, currentRow]);\n\n // Store the latest handler in a ref so that the useInput effect never needs to\n // re-register on the event emitter. This avoids a stale-closure race condition\n // where, after a domain switch (CategoryGrid remount via key={activeDomain}),\n // the useInput effect may not yet have re-registered the updated handler when\n // the first keypress arrives — causing the first space press to be silently lost.\n const handlerRef = useRef<((input: string, key: Key) => void) | null>(null);\n handlerRef.current = (input: string, key: Key) => {\n if (key.tab && key.shift) {\n onToggleLabels();\n return;\n }\n\n if (key.tab && !key.shift) {\n const nextSection = findNextIndex(categories, focusedRow);\n if (nextSection !== focusedRow) {\n setFocused(nextSection, 0);\n }\n return;\n }\n\n if (isHotkey(input, HOTKEY_TOGGLE_LABELS)) {\n onToggleLabels();\n return;\n }\n\n if (input === KEY_SPACE) {\n const currentOption = currentOptions[focusedCol];\n if (currentRow && currentOption) {\n onToggle(currentRow.id, currentOption.id);\n }\n return;\n }\n\n const isLeft = key.leftArrow || input === \"h\";\n const isRight = key.rightArrow || input === \"l\";\n const isUp = key.upArrow || input === \"k\";\n const isDown = key.downArrow || input === \"j\";\n\n if (isLeft) {\n moveFocus(\"left\");\n } else if (isRight) {\n moveFocus(\"right\");\n } else if (isUp) {\n moveFocus(\"up\");\n } else if (isDown) {\n moveFocus(\"down\");\n }\n };\n\n // Stable handler reference — never changes, so useInput's effect registers once\n const stableHandler = useCallback((input: string, key: Key) => {\n handlerRef.current?.(input, key);\n }, []);\n\n useInput(stableHandler);\n}\n"],"mappings":"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","names":["useCallback","useEffect","useCallback","useEffect"]}
|
|
@@ -1,50 +1,131 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
generateMarketplace,
|
|
4
|
-
getMarketplaceStats,
|
|
5
|
-
writeMarketplace
|
|
6
|
-
} from "../../chunk-M7HO7NBK.js";
|
|
7
|
-
import {
|
|
8
|
-
validateKebabCaseName
|
|
9
|
-
} from "../../chunk-VY6MNOXL.js";
|
|
10
2
|
import {
|
|
11
3
|
BaseCommand,
|
|
12
4
|
EXIT_CODES
|
|
13
|
-
} from "../../chunk-
|
|
14
|
-
import "../../chunk-
|
|
15
|
-
import "../../chunk-
|
|
5
|
+
} from "../../chunk-X5XJ6WKO.js";
|
|
6
|
+
import "../../chunk-TY6CAOL7.js";
|
|
7
|
+
import "../../chunk-K3O3YQYG.js";
|
|
8
|
+
import {
|
|
9
|
+
readPluginManifest
|
|
10
|
+
} from "../../chunk-NXQAY5U7.js";
|
|
16
11
|
import {
|
|
12
|
+
ensureDir,
|
|
17
13
|
getErrorMessage,
|
|
14
|
+
glob,
|
|
18
15
|
readFile,
|
|
19
16
|
setVerbose,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
verbose,
|
|
18
|
+
warn,
|
|
19
|
+
writeFile
|
|
20
|
+
} from "../../chunk-U2YSGBHA.js";
|
|
21
|
+
import "../../chunk-35VOK7XE.js";
|
|
23
22
|
import "../../chunk-VASLW636.js";
|
|
24
23
|
import {
|
|
24
|
+
DEFAULT_VERSION,
|
|
25
|
+
KEBAB_CASE_PATTERN,
|
|
25
26
|
MARKETPLACE_JSON,
|
|
26
27
|
PLUGINS_DIST_PATH,
|
|
27
|
-
PLUGIN_MANIFEST_DIR
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
PLUGIN_MANIFEST_DIR,
|
|
29
|
+
PLUGIN_MANIFEST_FILE
|
|
30
|
+
} from "../../chunk-R54KIGN2.js";
|
|
31
|
+
import "../../chunk-VZRO7RYT.js";
|
|
30
32
|
|
|
31
33
|
// src/cli/commands/build/marketplace.ts
|
|
32
34
|
import { Flags } from "@oclif/core";
|
|
33
|
-
import
|
|
34
|
-
import { sortBy } from "remeda";
|
|
35
|
+
import path2 from "path";
|
|
36
|
+
import { sortBy as sortBy2 } from "remeda";
|
|
35
37
|
import { z } from "zod";
|
|
38
|
+
|
|
39
|
+
// src/cli/lib/marketplace-generator.ts
|
|
40
|
+
import path from "path";
|
|
41
|
+
import { countBy, sortBy } from "remeda";
|
|
42
|
+
var PLUGIN_MANIFEST_PATH = `${PLUGIN_MANIFEST_DIR}/${PLUGIN_MANIFEST_FILE}`;
|
|
43
|
+
var MARKETPLACE_SCHEMA_URL = "https://anthropic.com/claude-code/marketplace.schema.json";
|
|
44
|
+
function convertManifestToMarketplacePlugin(manifest, pluginRoot, pluginDirName) {
|
|
45
|
+
return {
|
|
46
|
+
name: manifest.name,
|
|
47
|
+
source: `./${pluginRoot}/${pluginDirName}`,
|
|
48
|
+
...manifest.description !== void 0 && { description: manifest.description },
|
|
49
|
+
...manifest.version !== void 0 && { version: manifest.version },
|
|
50
|
+
...manifest.author !== void 0 && { author: manifest.author },
|
|
51
|
+
...manifest.keywords !== void 0 && { keywords: manifest.keywords }
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async function generateMarketplace(pluginsDir, options) {
|
|
55
|
+
verbose(`Scanning plugins directory: ${pluginsDir}`);
|
|
56
|
+
const manifestFiles = await glob(`**/${PLUGIN_MANIFEST_PATH}`, pluginsDir);
|
|
57
|
+
verbose(`Found ${manifestFiles.length} plugin manifests`);
|
|
58
|
+
const plugins = [];
|
|
59
|
+
for (const manifestFile of manifestFiles) {
|
|
60
|
+
const separator = manifestFile.indexOf("/");
|
|
61
|
+
const pluginDirName = separator === -1 ? manifestFile : manifestFile.slice(0, separator);
|
|
62
|
+
const pluginDir = path.join(pluginsDir, pluginDirName);
|
|
63
|
+
const manifest = await readPluginManifest(pluginDir);
|
|
64
|
+
if (!manifest) {
|
|
65
|
+
warn(`Could not read plugin manifest: '${manifestFile}'`);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const plugin = convertManifestToMarketplacePlugin(
|
|
69
|
+
manifest,
|
|
70
|
+
options.pluginRoot.replace(/^\.\//, ""),
|
|
71
|
+
pluginDirName
|
|
72
|
+
);
|
|
73
|
+
plugins.push(plugin);
|
|
74
|
+
verbose(` [OK] ${plugin.name}`);
|
|
75
|
+
}
|
|
76
|
+
const sortedPlugins = sortBy(plugins, (p) => p.name);
|
|
77
|
+
return {
|
|
78
|
+
$schema: MARKETPLACE_SCHEMA_URL,
|
|
79
|
+
name: options.name,
|
|
80
|
+
version: options.version ?? DEFAULT_VERSION,
|
|
81
|
+
owner: {
|
|
82
|
+
name: options.ownerName,
|
|
83
|
+
...options.ownerEmail ? { email: options.ownerEmail } : {}
|
|
84
|
+
},
|
|
85
|
+
metadata: {
|
|
86
|
+
pluginRoot: options.pluginRoot
|
|
87
|
+
},
|
|
88
|
+
plugins: sortedPlugins,
|
|
89
|
+
...options.description ? { description: options.description } : {}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async function writeMarketplace(outputPath, marketplace) {
|
|
93
|
+
await ensureDir(path.dirname(outputPath));
|
|
94
|
+
const content = `${JSON.stringify(marketplace, null, 2)}
|
|
95
|
+
`;
|
|
96
|
+
await writeFile(outputPath, content);
|
|
97
|
+
}
|
|
98
|
+
function getMarketplaceStats(marketplace) {
|
|
99
|
+
return {
|
|
100
|
+
total: marketplace.plugins.length,
|
|
101
|
+
byCategory: countBy(marketplace.plugins, (p) => p.category ?? "uncategorized")
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/cli/lib/validate-kebab-name.ts
|
|
106
|
+
function validateKebabCaseName(name, noun) {
|
|
107
|
+
if (!name || name.trim() === "") {
|
|
108
|
+
return `${noun} name is required`;
|
|
109
|
+
}
|
|
110
|
+
if (!KEBAB_CASE_PATTERN.test(name)) {
|
|
111
|
+
return `${noun} name must be kebab-case (lowercase letters, numbers, and hyphens, starting with a letter)`;
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/cli/commands/build/marketplace.ts
|
|
36
117
|
var DEFAULT_OUTPUT_FILE = `${PLUGIN_MANIFEST_DIR}/${MARKETPLACE_JSON}`;
|
|
37
118
|
var AUTHOR_STRING_PATTERN = /^(.*?)\s*<([^>]+)>\s*(?:\(([^)]+)\))?\s*$/;
|
|
38
119
|
var packageAuthorObjectSchema = z.object({
|
|
39
120
|
name: z.string(),
|
|
40
|
-
email: z.string().
|
|
41
|
-
url: z.string().
|
|
121
|
+
email: z.string().exactOptional(),
|
|
122
|
+
url: z.string().exactOptional()
|
|
42
123
|
});
|
|
43
124
|
var packageJsonSchema = z.object({
|
|
44
125
|
name: z.string(),
|
|
45
126
|
version: z.string(),
|
|
46
127
|
description: z.string(),
|
|
47
|
-
author: z.union([z.string(), packageAuthorObjectSchema]).
|
|
128
|
+
author: z.union([z.string(), packageAuthorObjectSchema]).exactOptional()
|
|
48
129
|
}).passthrough();
|
|
49
130
|
var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
50
131
|
static summary = "Generate marketplace.json from built plugins (requires skills repo)";
|
|
@@ -67,8 +148,6 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
67
148
|
command: "<%= config.bin %> <%= command.id %> --name my-marketplace"
|
|
68
149
|
}
|
|
69
150
|
];
|
|
70
|
-
// Override parent baseFlags to drop --source (marketplace reads identity from package.json)
|
|
71
|
-
static baseFlags = {};
|
|
72
151
|
static flags = {
|
|
73
152
|
name: Flags.string({
|
|
74
153
|
description: "Override the marketplace name (defaults to package.json 'name'). Must be kebab-case."
|
|
@@ -93,8 +172,8 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
93
172
|
const { flags } = await this.parse(_BuildMarketplace);
|
|
94
173
|
setVerbose(flags.verbose);
|
|
95
174
|
const projectRoot = process.cwd();
|
|
96
|
-
const pluginsDir =
|
|
97
|
-
const outputPath =
|
|
175
|
+
const pluginsDir = path2.resolve(projectRoot, flags["plugins-dir"]);
|
|
176
|
+
const outputPath = path2.resolve(projectRoot, flags.output);
|
|
98
177
|
const identity = await this.loadMarketplaceIdentity(projectRoot, flags.name);
|
|
99
178
|
this.printHeader(pluginsDir, outputPath);
|
|
100
179
|
try {
|
|
@@ -117,7 +196,7 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
117
196
|
}
|
|
118
197
|
}
|
|
119
198
|
async loadMarketplaceIdentity(projectRoot, nameOverride) {
|
|
120
|
-
const packageJsonPath =
|
|
199
|
+
const packageJsonPath = path2.join(projectRoot, "package.json");
|
|
121
200
|
let rawContent;
|
|
122
201
|
try {
|
|
123
202
|
rawContent = await readFile(packageJsonPath);
|
|
@@ -160,7 +239,7 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
160
239
|
version,
|
|
161
240
|
description,
|
|
162
241
|
ownerName: owner.name,
|
|
163
|
-
ownerEmail: owner.email
|
|
242
|
+
...owner.email !== void 0 && { ownerEmail: owner.email }
|
|
164
243
|
};
|
|
165
244
|
}
|
|
166
245
|
printHeader(pluginsDir, outputPath) {
|
|
@@ -177,7 +256,7 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
177
256
|
version: identity.version,
|
|
178
257
|
description: identity.description,
|
|
179
258
|
ownerName: identity.ownerName,
|
|
180
|
-
ownerEmail: identity.ownerEmail,
|
|
259
|
+
...identity.ownerEmail !== void 0 && { ownerEmail: identity.ownerEmail },
|
|
181
260
|
pluginRoot: `./${pluginsDirFlag}`
|
|
182
261
|
});
|
|
183
262
|
const stats = getMarketplaceStats(marketplace);
|
|
@@ -190,7 +269,7 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
|
|
|
190
269
|
printStats(marketplace) {
|
|
191
270
|
this.log("");
|
|
192
271
|
this.log("Category breakdown:");
|
|
193
|
-
const sortedCategories =
|
|
272
|
+
const sortedCategories = sortBy2(
|
|
194
273
|
Object.entries(getMarketplaceStats(marketplace).byCategory),
|
|
195
274
|
([, count]) => -count
|
|
196
275
|
);
|
|
@@ -221,12 +300,12 @@ function parseAuthor(author) {
|
|
|
221
300
|
return { name: "" };
|
|
222
301
|
}
|
|
223
302
|
if (typeof author === "object") {
|
|
224
|
-
return { name: author.name, email: author.email };
|
|
303
|
+
return { name: author.name, ...author.email !== void 0 && { email: author.email } };
|
|
225
304
|
}
|
|
226
|
-
const
|
|
227
|
-
if (
|
|
228
|
-
const name =
|
|
229
|
-
const email =
|
|
305
|
+
const [, matchedName, matchedEmail] = author.match(AUTHOR_STRING_PATTERN) ?? [];
|
|
306
|
+
if (matchedName !== void 0 && matchedEmail !== void 0) {
|
|
307
|
+
const name = matchedName.trim();
|
|
308
|
+
const email = matchedEmail.trim();
|
|
230
309
|
if (name === "") {
|
|
231
310
|
warn(
|
|
232
311
|
`package.json 'author' field "${author}" has no parseable name \u2014 marketplace owner.name will be empty`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/build/marketplace.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\nimport { z } from \"zod\";\n\nimport { BaseCommand } from \"../../base-command\";\nimport { setVerbose, warn } from \"../../utils/logger\";\nimport { readFile } from \"../../utils/fs\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { EXIT_CODES } from \"../../lib/exit-codes\";\nimport {\n generateMarketplace,\n writeMarketplace,\n getMarketplaceStats,\n} from \"../../lib/marketplace-generator\";\nimport { MARKETPLACE_JSON, PLUGIN_MANIFEST_DIR, PLUGINS_DIST_PATH } from \"../../consts\";\nimport type { Marketplace } from \"../../types/plugins\";\nimport { validateKebabCaseName } from \"../../lib/validate-kebab-name.js\";\n\nconst DEFAULT_OUTPUT_FILE = `${PLUGIN_MANIFEST_DIR}/${MARKETPLACE_JSON}`;\n\nconst AUTHOR_STRING_PATTERN = /^(.*?)\\s*<([^>]+)>\\s*(?:\\(([^)]+)\\))?\\s*$/;\n\nconst packageAuthorObjectSchema = z.object({\n name: z.string(),\n email: z.string().optional(),\n url: z.string().optional(),\n});\n\nconst packageJsonSchema = z\n .object({\n name: z.string(),\n version: z.string(),\n description: z.string(),\n author: z.union([z.string(), packageAuthorObjectSchema]).optional(),\n })\n .passthrough();\n\ntype PackageJson = z.infer<typeof packageJsonSchema>;\ntype MarketplaceIdentity = Pick<PackageJson, \"name\" | \"version\" | \"description\"> & {\n ownerName: string;\n ownerEmail?: string;\n};\n\nexport default class BuildMarketplace extends BaseCommand {\n static summary = \"Generate marketplace.json from built plugins (requires skills repo)\";\n\n static description =\n \"Generate marketplace.json from built plugins. This command scans the plugins directory and generates a marketplace manifest file. Reads marketplace identity (name, version, description, author) from package.json in the current working directory. Use --name to override the marketplace name when package.json uses an npm scoped name (e.g. @scope/pkg), which is not a valid marketplace name.\";\n\n static examples = [\n {\n description: \"Generate marketplace.json from the default plugins directory\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Generate marketplace.json from a custom plugins directory\",\n command: \"<%= config.bin %> <%= command.id %> --plugins-dir dist/stacks\",\n },\n {\n description: \"Write marketplace.json to a custom output path\",\n command: \"<%= config.bin %> <%= command.id %> --output .claude-plugin/market.json\",\n },\n {\n description:\n \"Override the marketplace name (use when package.json has an npm scoped name like @scope/pkg)\",\n command: \"<%= config.bin %> <%= command.id %> --name my-marketplace\",\n },\n ];\n\n // Override parent baseFlags to drop --source (marketplace reads identity from package.json)\n static baseFlags = {} as (typeof BaseCommand)[\"baseFlags\"];\n\n static flags = {\n name: Flags.string({\n description:\n \"Override the marketplace name (defaults to package.json 'name'). Must be kebab-case.\",\n }),\n \"plugins-dir\": Flags.string({\n char: \"p\",\n description: \"Plugins directory\",\n default: PLUGINS_DIST_PATH,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output file\",\n default: DEFAULT_OUTPUT_FILE,\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(BuildMarketplace);\n setVerbose(flags.verbose);\n\n const projectRoot = process.cwd();\n const pluginsDir = path.resolve(projectRoot, flags[\"plugins-dir\"]);\n const outputPath = path.resolve(projectRoot, flags.output);\n const identity = await this.loadMarketplaceIdentity(projectRoot, flags.name);\n\n this.printHeader(pluginsDir, outputPath);\n\n try {\n const marketplace = await this.generateAndWrite(\n pluginsDir,\n outputPath,\n flags[\"plugins-dir\"],\n identity,\n );\n this.printStats(marketplace);\n this.printSample(marketplace);\n\n this.log(\"\");\n this.logSuccess(\n `Marketplace generated with ${getMarketplaceStats(marketplace).total} plugins!`,\n );\n this.log(\"\");\n } catch (error) {\n this.log(\"Generation failed\");\n this.handleError(error);\n }\n }\n\n private async loadMarketplaceIdentity(\n projectRoot: string,\n nameOverride?: string,\n ): Promise<MarketplaceIdentity> {\n const packageJsonPath = path.join(projectRoot, \"package.json\");\n\n let rawContent: string;\n try {\n rawContent = await readFile(packageJsonPath);\n } catch {\n this.error(\n `Missing package.json at ${projectRoot}. build marketplace reads marketplace identity from package.json.`,\n { exit: EXIT_CODES.ERROR },\n );\n }\n\n let parsedJson: unknown;\n try {\n parsedJson = JSON.parse(rawContent);\n } catch (error) {\n this.error(`Failed to parse package.json at ${packageJsonPath}: ${getErrorMessage(error)}`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n const parseResult = packageJsonSchema.safeParse(parsedJson);\n if (!parseResult.success) {\n const missingFields = parseResult.error.issues.map((i) => i.path.join(\".\")).join(\", \");\n this.error(\n `package.json at ${packageJsonPath} is missing required fields: ${missingFields}. build marketplace reads marketplace identity from package.json.`,\n { exit: EXIT_CODES.ERROR },\n );\n }\n\n const { name, version, description, author } = parseResult.data;\n const owner = parseAuthor(author);\n\n let resolvedName = name;\n if (nameOverride !== undefined) {\n const validationError = validateKebabCaseName(nameOverride, \"Marketplace\");\n if (validationError) {\n this.error(`Invalid --name '${nameOverride}': ${validationError}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n resolvedName = nameOverride;\n }\n\n return {\n name: resolvedName,\n version,\n description,\n ownerName: owner.name,\n ownerEmail: owner.email,\n };\n }\n\n private printHeader(pluginsDir: string, outputPath: string): void {\n this.log(\"\");\n this.log(\"Generating marketplace.json\");\n this.log(` Plugins directory: ${pluginsDir}`);\n this.log(` Output file: ${outputPath}`);\n this.log(\"\");\n }\n\n private async generateAndWrite(\n pluginsDir: string,\n outputPath: string,\n pluginsDirFlag: string,\n identity: MarketplaceIdentity,\n ): Promise<Marketplace> {\n this.log(\"Scanning plugins...\");\n\n const marketplace = await generateMarketplace(pluginsDir, {\n name: identity.name,\n version: identity.version,\n description: identity.description,\n ownerName: identity.ownerName,\n ownerEmail: identity.ownerEmail,\n pluginRoot: `./${pluginsDirFlag}`,\n });\n\n const stats = getMarketplaceStats(marketplace);\n this.log(`Found ${stats.total} plugins`);\n\n this.log(\"Writing marketplace.json...\");\n await writeMarketplace(outputPath, marketplace);\n this.log(`Wrote ${outputPath}`);\n\n return marketplace;\n }\n\n private printStats(marketplace: Marketplace): void {\n this.log(\"\");\n this.log(\"Category breakdown:\");\n const sortedCategories = sortBy(\n Object.entries(getMarketplaceStats(marketplace).byCategory),\n ([, count]) => -count,\n );\n for (const [category, count] of sortedCategories) {\n this.log(` ${category}: ${count}`);\n }\n }\n\n private printSample(marketplace: Marketplace): void {\n this.log(\"\");\n this.log(\"Sample plugins:\");\n const sampleSize = 5;\n for (const plugin of marketplace.plugins.slice(0, sampleSize)) {\n const version = plugin.version ? `v${plugin.version}` : \"\";\n const category = plugin.category ? `[${plugin.category}]` : \"\";\n this.log(` ${plugin.name} ${version} ${category}`);\n if (plugin.description) {\n this.log(` ${plugin.description}`);\n }\n }\n if (marketplace.plugins.length > sampleSize) {\n this.log(` ... and ${marketplace.plugins.length - sampleSize} more`);\n }\n }\n}\n\ntype ParsedAuthor = {\n name: string;\n email?: string;\n};\n\n/**\n * Parses a package.json `author` field into name + optional email.\n *\n * npm supports both shorthand strings `\"Name <email> (url)\"` and object form\n * `{ name, email, url }`. We emit a warning when a string author has no\n * parseable email so the caller knows the marketplace owner.email will be absent.\n */\nfunction parseAuthor(author: string | { name: string; email?: string } | undefined): ParsedAuthor {\n if (!author) {\n warn(\"package.json is missing 'author' field — marketplace owner.email will be empty\");\n return { name: \"\" };\n }\n\n if (typeof author === \"object\") {\n return { name: author.name, email: author.email };\n }\n\n const match = author.match(AUTHOR_STRING_PATTERN);\n if (match) {\n const name = match[1].trim();\n const email = match[2].trim();\n if (name === \"\") {\n warn(\n `package.json 'author' field \"${author}\" has no parseable name — marketplace owner.name will be empty`,\n );\n }\n return { name, email };\n }\n\n warn(\n `package.json 'author' field \"${author}\" has no parseable email — marketplace owner.email will be empty`,\n );\n return { name: author.trim() };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,aAAa;AACtB,OAAO,UAAU;AACjB,SAAS,cAAc;AACvB,SAAS,SAAS;AAgBlB,IAAM,sBAAsB,GAAG,mBAAmB,IAAI,gBAAgB;AAEtE,IAAM,wBAAwB;AAE9B,IAAM,4BAA4B,EAAE,OAAO;AAAA,EACzC,MAAM,EAAE,OAAO;AAAA,EACf,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,KAAK,EAAE,OAAO,EAAE,SAAS;AAC3B,CAAC;AAED,IAAM,oBAAoB,EACvB,OAAO;AAAA,EACN,MAAM,EAAE,OAAO;AAAA,EACf,SAAS,EAAE,OAAO;AAAA,EAClB,aAAa,EAAE,OAAO;AAAA,EACtB,QAAQ,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,yBAAyB,CAAC,EAAE,SAAS;AACpE,CAAC,EACA,YAAY;AAQf,IAAqB,mBAArB,MAAqB,0BAAyB,YAAY;AAAA,EACxD,OAAO,UAAU;AAAA,EAEjB,OAAO,cACL;AAAA,EAEF,OAAO,WAAW;AAAA,IAChB;AAAA,MACE,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,SAAS;AAAA,IACX;AAAA,EACF;AAAA;AAAA,EAGA,OAAO,YAAY,CAAC;AAAA,EAEpB,OAAO,QAAQ;AAAA,IACb,MAAM,MAAM,OAAO;AAAA,MACjB,aACE;AAAA,IACJ,CAAC;AAAA,IACD,eAAe,MAAM,OAAO;AAAA,MAC1B,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,IACD,QAAQ,MAAM,OAAO;AAAA,MACnB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,IACD,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,iBAAgB;AACnD,eAAW,MAAM,OAAO;AAExB,UAAM,cAAc,QAAQ,IAAI;AAChC,UAAM,aAAa,KAAK,QAAQ,aAAa,MAAM,aAAa,CAAC;AACjE,UAAM,aAAa,KAAK,QAAQ,aAAa,MAAM,MAAM;AACzD,UAAM,WAAW,MAAM,KAAK,wBAAwB,aAAa,MAAM,IAAI;AAE3E,SAAK,YAAY,YAAY,UAAU;AAEvC,QAAI;AACF,YAAM,cAAc,MAAM,KAAK;AAAA,QAC7B;AAAA,QACA;AAAA,QACA,MAAM,aAAa;AAAA,QACnB;AAAA,MACF;AACA,WAAK,WAAW,WAAW;AAC3B,WAAK,YAAY,WAAW;AAE5B,WAAK,IAAI,EAAE;AACX,WAAK;AAAA,QACH,8BAA8B,oBAAoB,WAAW,EAAE,KAAK;AAAA,MACtE;AACA,WAAK,IAAI,EAAE;AAAA,IACb,SAAS,OAAO;AACd,WAAK,IAAI,mBAAmB;AAC5B,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,wBACZ,aACA,cAC8B;AAC9B,UAAM,kBAAkB,KAAK,KAAK,aAAa,cAAc;AAE7D,QAAI;AACJ,QAAI;AACF,mBAAa,MAAM,SAAS,eAAe;AAAA,IAC7C,QAAQ;AACN,WAAK;AAAA,QACH,2BAA2B,WAAW;AAAA,QACtC,EAAE,MAAM,WAAW,MAAM;AAAA,MAC3B;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,mBAAa,KAAK,MAAM,UAAU;AAAA,IACpC,SAAS,OAAO;AACd,WAAK,MAAM,mCAAmC,eAAe,KAAK,gBAAgB,KAAK,CAAC,IAAI;AAAA,QAC1F,MAAM,WAAW;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,UAAM,cAAc,kBAAkB,UAAU,UAAU;AAC1D,QAAI,CAAC,YAAY,SAAS;AACxB,YAAM,gBAAgB,YAAY,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI;AACrF,WAAK;AAAA,QACH,mBAAmB,eAAe,gCAAgC,aAAa;AAAA,QAC/E,EAAE,MAAM,WAAW,MAAM;AAAA,MAC3B;AAAA,IACF;AAEA,UAAM,EAAE,MAAM,SAAS,aAAa,OAAO,IAAI,YAAY;AAC3D,UAAM,QAAQ,YAAY,MAAM;AAEhC,QAAI,eAAe;AACnB,QAAI,iBAAiB,QAAW;AAC9B,YAAM,kBAAkB,sBAAsB,cAAc,aAAa;AACzE,UAAI,iBAAiB;AACnB,aAAK,MAAM,mBAAmB,YAAY,MAAM,eAAe,IAAI;AAAA,UACjE,MAAM,WAAW;AAAA,QACnB,CAAC;AAAA,MACH;AACA,qBAAe;AAAA,IACjB;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,WAAW,MAAM;AAAA,MACjB,YAAY,MAAM;AAAA,IACpB;AAAA,EACF;AAAA,EAEQ,YAAY,YAAoB,YAA0B;AAChE,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,6BAA6B;AACtC,SAAK,IAAI,wBAAwB,UAAU,EAAE;AAC7C,SAAK,IAAI,kBAAkB,UAAU,EAAE;AACvC,SAAK,IAAI,EAAE;AAAA,EACb;AAAA,EAEA,MAAc,iBACZ,YACA,YACA,gBACA,UACsB;AACtB,SAAK,IAAI,qBAAqB;AAE9B,UAAM,cAAc,MAAM,oBAAoB,YAAY;AAAA,MACxD,MAAM,SAAS;AAAA,MACf,SAAS,SAAS;AAAA,MAClB,aAAa,SAAS;AAAA,MACtB,WAAW,SAAS;AAAA,MACpB,YAAY,SAAS;AAAA,MACrB,YAAY,KAAK,cAAc;AAAA,IACjC,CAAC;AAED,UAAM,QAAQ,oBAAoB,WAAW;AAC7C,SAAK,IAAI,SAAS,MAAM,KAAK,UAAU;AAEvC,SAAK,IAAI,6BAA6B;AACtC,UAAM,iBAAiB,YAAY,WAAW;AAC9C,SAAK,IAAI,SAAS,UAAU,EAAE;AAE9B,WAAO;AAAA,EACT;AAAA,EAEQ,WAAW,aAAgC;AACjD,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,qBAAqB;AAC9B,UAAM,mBAAmB;AAAA,MACvB,OAAO,QAAQ,oBAAoB,WAAW,EAAE,UAAU;AAAA,MAC1D,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC;AAAA,IAClB;AACA,eAAW,CAAC,UAAU,KAAK,KAAK,kBAAkB;AAChD,WAAK,IAAI,KAAK,QAAQ,KAAK,KAAK,EAAE;AAAA,IACpC;AAAA,EACF;AAAA,EAEQ,YAAY,aAAgC;AAClD,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,iBAAiB;AAC1B,UAAM,aAAa;AACnB,eAAW,UAAU,YAAY,QAAQ,MAAM,GAAG,UAAU,GAAG;AAC7D,YAAM,UAAU,OAAO,UAAU,IAAI,OAAO,OAAO,KAAK;AACxD,YAAM,WAAW,OAAO,WAAW,IAAI,OAAO,QAAQ,MAAM;AAC5D,WAAK,IAAI,KAAK,OAAO,IAAI,IAAI,OAAO,IAAI,QAAQ,EAAE;AAClD,UAAI,OAAO,aAAa;AACtB,aAAK,IAAI,OAAO,OAAO,WAAW,EAAE;AAAA,MACtC;AAAA,IACF;AACA,QAAI,YAAY,QAAQ,SAAS,YAAY;AAC3C,WAAK,IAAI,aAAa,YAAY,QAAQ,SAAS,UAAU,OAAO;AAAA,IACtE;AAAA,EACF;AACF;AAcA,SAAS,YAAY,QAA6E;AAChG,MAAI,CAAC,QAAQ;AACX,SAAK,qFAAgF;AACrF,WAAO,EAAE,MAAM,GAAG;AAAA,EACpB;AAEA,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO,EAAE,MAAM,OAAO,MAAM,OAAO,OAAO,MAAM;AAAA,EAClD;AAEA,QAAM,QAAQ,OAAO,MAAM,qBAAqB;AAChD,MAAI,OAAO;AACT,UAAM,OAAO,MAAM,CAAC,EAAE,KAAK;AAC3B,UAAM,QAAQ,MAAM,CAAC,EAAE,KAAK;AAC5B,QAAI,SAAS,IAAI;AACf;AAAA,QACE,gCAAgC,MAAM;AAAA,MACxC;AAAA,IACF;AACA,WAAO,EAAE,MAAM,MAAM;AAAA,EACvB;AAEA;AAAA,IACE,gCAAgC,MAAM;AAAA,EACxC;AACA,SAAO,EAAE,MAAM,OAAO,KAAK,EAAE;AAC/B;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/build/marketplace.ts","../../../src/cli/lib/marketplace-generator.ts","../../../src/cli/lib/validate-kebab-name.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\nimport { z } from \"zod\";\n\nimport { BaseCommand } from \"../../base-command\";\nimport { setVerbose, warn } from \"../../utils/logger\";\nimport { readFile } from \"../../utils/fs\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { EXIT_CODES } from \"../../lib/exit-codes\";\nimport {\n generateMarketplace,\n writeMarketplace,\n getMarketplaceStats,\n} from \"../../lib/marketplace-generator\";\nimport { MARKETPLACE_JSON, PLUGIN_MANIFEST_DIR, PLUGINS_DIST_PATH } from \"../../consts\";\nimport type { Marketplace } from \"../../types/plugins\";\nimport { validateKebabCaseName } from \"../../lib/validate-kebab-name.js\";\n\nconst DEFAULT_OUTPUT_FILE = `${PLUGIN_MANIFEST_DIR}/${MARKETPLACE_JSON}`;\n\nconst AUTHOR_STRING_PATTERN = /^(.*?)\\s*<([^>]+)>\\s*(?:\\(([^)]+)\\))?\\s*$/;\n\nconst packageAuthorObjectSchema = z.object({\n name: z.string(),\n email: z.string().exactOptional(),\n url: z.string().exactOptional(),\n});\n\nconst packageJsonSchema = z\n .object({\n name: z.string(),\n version: z.string(),\n description: z.string(),\n author: z.union([z.string(), packageAuthorObjectSchema]).exactOptional(),\n })\n .passthrough();\n\ntype PackageJson = z.infer<typeof packageJsonSchema>;\ntype MarketplaceIdentity = Pick<PackageJson, \"name\" | \"version\" | \"description\"> & {\n ownerName: string;\n ownerEmail?: string;\n};\n\nexport default class BuildMarketplace extends BaseCommand {\n static summary = \"Generate marketplace.json from built plugins (requires skills repo)\";\n\n static description =\n \"Generate marketplace.json from built plugins. This command scans the plugins directory and generates a marketplace manifest file. Reads marketplace identity (name, version, description, author) from package.json in the current working directory. Use --name to override the marketplace name when package.json uses an npm scoped name (e.g. @scope/pkg), which is not a valid marketplace name.\";\n\n static examples = [\n {\n description: \"Generate marketplace.json from the default plugins directory\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Generate marketplace.json from a custom plugins directory\",\n command: \"<%= config.bin %> <%= command.id %> --plugins-dir dist/stacks\",\n },\n {\n description: \"Write marketplace.json to a custom output path\",\n command: \"<%= config.bin %> <%= command.id %> --output .claude-plugin/market.json\",\n },\n {\n description:\n \"Override the marketplace name (use when package.json has an npm scoped name like @scope/pkg)\",\n command: \"<%= config.bin %> <%= command.id %> --name my-marketplace\",\n },\n ];\n\n static flags = {\n name: Flags.string({\n description:\n \"Override the marketplace name (defaults to package.json 'name'). Must be kebab-case.\",\n }),\n \"plugins-dir\": Flags.string({\n char: \"p\",\n description: \"Plugins directory\",\n default: PLUGINS_DIST_PATH,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output file\",\n default: DEFAULT_OUTPUT_FILE,\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(BuildMarketplace);\n setVerbose(flags.verbose);\n\n const projectRoot = process.cwd();\n const pluginsDir = path.resolve(projectRoot, flags[\"plugins-dir\"]);\n const outputPath = path.resolve(projectRoot, flags.output);\n const identity = await this.loadMarketplaceIdentity(projectRoot, flags.name);\n\n this.printHeader(pluginsDir, outputPath);\n\n try {\n const marketplace = await this.generateAndWrite(\n pluginsDir,\n outputPath,\n flags[\"plugins-dir\"],\n identity,\n );\n this.printStats(marketplace);\n this.printSample(marketplace);\n\n this.log(\"\");\n this.logSuccess(\n `Marketplace generated with ${getMarketplaceStats(marketplace).total} plugins!`,\n );\n this.log(\"\");\n } catch (error) {\n this.log(\"Generation failed\");\n this.handleError(error);\n }\n }\n\n private async loadMarketplaceIdentity(\n projectRoot: string,\n nameOverride?: string,\n ): Promise<MarketplaceIdentity> {\n const packageJsonPath = path.join(projectRoot, \"package.json\");\n\n let rawContent: string;\n try {\n rawContent = await readFile(packageJsonPath);\n } catch {\n this.error(\n `Missing package.json at ${projectRoot}. build marketplace reads marketplace identity from package.json.`,\n { exit: EXIT_CODES.ERROR },\n );\n }\n\n let parsedJson: unknown;\n try {\n parsedJson = JSON.parse(rawContent);\n } catch (error) {\n this.error(`Failed to parse package.json at ${packageJsonPath}: ${getErrorMessage(error)}`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n const parseResult = packageJsonSchema.safeParse(parsedJson);\n if (!parseResult.success) {\n const missingFields = parseResult.error.issues.map((i) => i.path.join(\".\")).join(\", \");\n this.error(\n `package.json at ${packageJsonPath} is missing required fields: ${missingFields}. build marketplace reads marketplace identity from package.json.`,\n { exit: EXIT_CODES.ERROR },\n );\n }\n\n const { name, version, description, author } = parseResult.data;\n const owner = parseAuthor(author);\n\n let resolvedName = name;\n if (nameOverride !== undefined) {\n const validationError = validateKebabCaseName(nameOverride, \"Marketplace\");\n if (validationError) {\n this.error(`Invalid --name '${nameOverride}': ${validationError}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n resolvedName = nameOverride;\n }\n\n return {\n name: resolvedName,\n version,\n description,\n ownerName: owner.name,\n ...(owner.email !== undefined && { ownerEmail: owner.email }),\n };\n }\n\n private printHeader(pluginsDir: string, outputPath: string): void {\n this.log(\"\");\n this.log(\"Generating marketplace.json\");\n this.log(` Plugins directory: ${pluginsDir}`);\n this.log(` Output file: ${outputPath}`);\n this.log(\"\");\n }\n\n private async generateAndWrite(\n pluginsDir: string,\n outputPath: string,\n pluginsDirFlag: string,\n identity: MarketplaceIdentity,\n ): Promise<Marketplace> {\n this.log(\"Scanning plugins...\");\n\n const marketplace = await generateMarketplace(pluginsDir, {\n name: identity.name,\n version: identity.version,\n description: identity.description,\n ownerName: identity.ownerName,\n ...(identity.ownerEmail !== undefined && { ownerEmail: identity.ownerEmail }),\n pluginRoot: `./${pluginsDirFlag}`,\n });\n\n const stats = getMarketplaceStats(marketplace);\n this.log(`Found ${stats.total} plugins`);\n\n this.log(\"Writing marketplace.json...\");\n await writeMarketplace(outputPath, marketplace);\n this.log(`Wrote ${outputPath}`);\n\n return marketplace;\n }\n\n private printStats(marketplace: Marketplace): void {\n this.log(\"\");\n this.log(\"Category breakdown:\");\n const sortedCategories = sortBy(\n Object.entries(getMarketplaceStats(marketplace).byCategory),\n ([, count]) => -count,\n );\n for (const [category, count] of sortedCategories) {\n this.log(` ${category}: ${count}`);\n }\n }\n\n private printSample(marketplace: Marketplace): void {\n this.log(\"\");\n this.log(\"Sample plugins:\");\n const sampleSize = 5;\n for (const plugin of marketplace.plugins.slice(0, sampleSize)) {\n const version = plugin.version ? `v${plugin.version}` : \"\";\n const category = plugin.category ? `[${plugin.category}]` : \"\";\n this.log(` ${plugin.name} ${version} ${category}`);\n if (plugin.description) {\n this.log(` ${plugin.description}`);\n }\n }\n if (marketplace.plugins.length > sampleSize) {\n this.log(` ... and ${marketplace.plugins.length - sampleSize} more`);\n }\n }\n}\n\ntype ParsedAuthor = {\n name: string;\n email?: string;\n};\n\n/**\n * Parses a package.json `author` field into name + optional email.\n *\n * npm supports both shorthand strings `\"Name <email> (url)\"` and object form\n * `{ name, email, url }`. We emit a warning when a string author has no\n * parseable email so the caller knows the marketplace owner.email will be absent.\n */\nfunction parseAuthor(author: string | { name: string; email?: string } | undefined): ParsedAuthor {\n if (!author) {\n warn(\"package.json is missing 'author' field — marketplace owner.email will be empty\");\n return { name: \"\" };\n }\n\n if (typeof author === \"object\") {\n return { name: author.name, ...(author.email !== undefined && { email: author.email }) };\n }\n\n const [, matchedName, matchedEmail] = author.match(AUTHOR_STRING_PATTERN) ?? [];\n if (matchedName !== undefined && matchedEmail !== undefined) {\n const name = matchedName.trim();\n const email = matchedEmail.trim();\n if (name === \"\") {\n warn(\n `package.json 'author' field \"${author}\" has no parseable name — marketplace owner.name will be empty`,\n );\n }\n return { name, email };\n }\n\n warn(\n `package.json 'author' field \"${author}\" has no parseable email — marketplace owner.email will be empty`,\n );\n return { name: author.trim() };\n}\n","import path from \"path\";\nimport { countBy, sortBy } from \"remeda\";\n\nimport { DEFAULT_VERSION, PLUGIN_MANIFEST_DIR, PLUGIN_MANIFEST_FILE } from \"../consts\";\nimport { writeFile, glob, ensureDir } from \"../utils/fs\";\nimport { verbose, warn } from \"../utils/logger\";\nimport type { Marketplace, MarketplacePlugin, PluginManifest } from \"../types\";\nimport { readPluginManifest } from \"./plugins\";\n\nconst PLUGIN_MANIFEST_PATH = `${PLUGIN_MANIFEST_DIR}/${PLUGIN_MANIFEST_FILE}`;\nconst MARKETPLACE_SCHEMA_URL = \"https://anthropic.com/claude-code/marketplace.schema.json\";\n\ntype MarketplaceOptions = {\n name: string;\n version?: string;\n description?: string;\n ownerName: string;\n ownerEmail?: string;\n pluginRoot: string;\n};\n\nfunction convertManifestToMarketplacePlugin(\n manifest: PluginManifest,\n pluginRoot: string,\n pluginDirName: string,\n): MarketplacePlugin {\n return {\n name: manifest.name,\n source: `./${pluginRoot}/${pluginDirName}`,\n ...(manifest.description !== undefined && { description: manifest.description }),\n ...(manifest.version !== undefined && { version: manifest.version }),\n ...(manifest.author !== undefined && { author: manifest.author }),\n ...(manifest.keywords !== undefined && { keywords: manifest.keywords }),\n };\n}\n\nexport async function generateMarketplace(\n pluginsDir: string,\n options: MarketplaceOptions,\n): Promise<Marketplace> {\n verbose(`Scanning plugins directory: ${pluginsDir}`);\n\n const manifestFiles = await glob(`**/${PLUGIN_MANIFEST_PATH}`, pluginsDir);\n verbose(`Found ${manifestFiles.length} plugin manifests`);\n\n const plugins: MarketplacePlugin[] = [];\n\n for (const manifestFile of manifestFiles) {\n const separator = manifestFile.indexOf(\"/\");\n const pluginDirName = separator === -1 ? manifestFile : manifestFile.slice(0, separator);\n const pluginDir = path.join(pluginsDir, pluginDirName);\n\n const manifest = await readPluginManifest(pluginDir);\n if (!manifest) {\n warn(`Could not read plugin manifest: '${manifestFile}'`);\n continue;\n }\n\n const plugin = convertManifestToMarketplacePlugin(\n manifest,\n options.pluginRoot.replace(/^\\.\\//, \"\"),\n pluginDirName,\n );\n plugins.push(plugin);\n verbose(` [OK] ${plugin.name}`);\n }\n\n const sortedPlugins = sortBy(plugins, (p) => p.name);\n\n // Field order matters: the object is serialized verbatim into marketplace.json,\n // so conditional fields keep the same positions the previous emissions used.\n return {\n $schema: MARKETPLACE_SCHEMA_URL,\n name: options.name,\n version: options.version ?? DEFAULT_VERSION,\n owner: {\n name: options.ownerName,\n ...(options.ownerEmail ? { email: options.ownerEmail } : {}),\n },\n metadata: {\n pluginRoot: options.pluginRoot,\n },\n plugins: sortedPlugins,\n ...(options.description ? { description: options.description } : {}),\n };\n}\n\nexport async function writeMarketplace(\n outputPath: string,\n marketplace: Marketplace,\n): Promise<void> {\n await ensureDir(path.dirname(outputPath));\n const content = `${JSON.stringify(marketplace, null, 2)}\\n`;\n await writeFile(outputPath, content);\n}\n\nexport function getMarketplaceStats(marketplace: Marketplace): {\n total: number;\n byCategory: Record<string, number>;\n} {\n return {\n total: marketplace.plugins.length,\n byCategory: countBy(marketplace.plugins, (p) => p.category ?? \"uncategorized\"),\n };\n}\n","import { KEBAB_CASE_PATTERN } from \"../consts.js\";\n\n/**\n * Validates a user-supplied entity name against the kebab-case convention.\n * Returns an error message naming the entity (e.g. \"Marketplace\", \"Skill\"),\n * or null when the name is valid.\n */\nexport function validateKebabCaseName(name: string, noun: string): string | null {\n if (!name || name.trim() === \"\") {\n return `${noun} name is required`;\n }\n\n if (!KEBAB_CASE_PATTERN.test(name)) {\n return `${noun} name must be kebab-case (lowercase letters, numbers, and hyphens, starting with a letter)`;\n }\n\n return null;\n}\n"],"mappings":"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","names":["path","sortBy","path","sortBy"]}
|
|
@@ -2,29 +2,30 @@
|
|
|
2
2
|
import {
|
|
3
3
|
compileAllAgentPlugins,
|
|
4
4
|
printAgentCompilationSummary
|
|
5
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-FIHTAFST.js";
|
|
6
6
|
import {
|
|
7
7
|
BaseCommand
|
|
8
|
-
} from "../../chunk-
|
|
9
|
-
import "../../chunk-
|
|
8
|
+
} from "../../chunk-X5XJ6WKO.js";
|
|
9
|
+
import "../../chunk-TY6CAOL7.js";
|
|
10
|
+
import "../../chunk-K3O3YQYG.js";
|
|
10
11
|
import {
|
|
11
12
|
compileAllSkillPlugins,
|
|
12
13
|
compileSkillPlugin,
|
|
13
14
|
printCompilationSummary,
|
|
14
15
|
readPluginManifest
|
|
15
|
-
} from "../../chunk-
|
|
16
|
+
} from "../../chunk-NXQAY5U7.js";
|
|
16
17
|
import {
|
|
17
18
|
listDirectories,
|
|
18
19
|
remove,
|
|
19
20
|
setVerbose
|
|
20
|
-
} from "../../chunk-
|
|
21
|
-
import "../../chunk-
|
|
21
|
+
} from "../../chunk-U2YSGBHA.js";
|
|
22
|
+
import "../../chunk-35VOK7XE.js";
|
|
22
23
|
import "../../chunk-VASLW636.js";
|
|
23
24
|
import {
|
|
24
25
|
DIRS,
|
|
25
26
|
PLUGINS_DIST_PATH
|
|
26
|
-
} from "../../chunk-
|
|
27
|
-
import "../../chunk-
|
|
27
|
+
} from "../../chunk-R54KIGN2.js";
|
|
28
|
+
import "../../chunk-VZRO7RYT.js";
|
|
28
29
|
|
|
29
30
|
// src/cli/commands/build/plugins.ts
|
|
30
31
|
import { Flags } from "@oclif/core";
|
|
@@ -54,8 +55,6 @@ var BuildPlugins = class _BuildPlugins extends BaseCommand {
|
|
|
54
55
|
command: "<%= config.bin %> <%= command.id %> --verbose"
|
|
55
56
|
}
|
|
56
57
|
];
|
|
57
|
-
// Override parent baseFlags to drop --source (build plugins reads from local DIRS.skills, not a remote source)
|
|
58
|
-
static baseFlags = {};
|
|
59
58
|
static flags = {
|
|
60
59
|
"agents-dir": Flags.string({
|
|
61
60
|
char: "a",
|
|
@@ -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
|
|
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":[]}
|