@agents-inc/cli 0.45.0 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/{chunk-V43QDMYQ.js → chunk-2RQYJFKA.js} +2 -2
  3. package/dist/{chunk-ABE55TEU.js → chunk-3APMMQUA.js} +11 -3
  4. package/dist/chunk-3APMMQUA.js.map +1 -0
  5. package/dist/{chunk-KWWLPPHF.js → chunk-B4QYXVPZ.js} +2 -2
  6. package/dist/{chunk-473YHDYQ.js → chunk-C4QI54PN.js} +147 -52
  7. package/dist/chunk-C4QI54PN.js.map +1 -0
  8. package/dist/{chunk-CLHBKFHU.js → chunk-CJFWO46A.js} +2 -2
  9. package/dist/{chunk-M2XPTQDT.js → chunk-DC333ZDC.js} +4 -4
  10. package/dist/{chunk-M3AGB4TR.js → chunk-DVW6ASTO.js} +4 -4
  11. package/dist/{chunk-ARET3NYO.js → chunk-EZ46ZTAQ.js} +3 -3
  12. package/dist/{chunk-VTDEENSP.js → chunk-FMQ3A7W4.js} +5 -5
  13. package/dist/{chunk-VTDEENSP.js.map → chunk-FMQ3A7W4.js.map} +1 -1
  14. package/dist/{chunk-FVN5PFFY.js → chunk-FTD5Z6QD.js} +5 -1
  15. package/dist/chunk-FTD5Z6QD.js.map +1 -0
  16. package/dist/{chunk-YQFU2KZ5.js → chunk-FXQYEXLS.js} +3 -3
  17. package/dist/{chunk-ZECXM7LP.js → chunk-GFDGYQ6M.js} +3553 -3497
  18. package/dist/chunk-GFDGYQ6M.js.map +1 -0
  19. package/dist/chunk-HLTJK3XB.js +71 -0
  20. package/dist/chunk-HLTJK3XB.js.map +1 -0
  21. package/dist/{chunk-KVHLKPYB.js → chunk-HPJP3HFD.js} +7 -7
  22. package/dist/{chunk-KZNPPUQG.js → chunk-INKJBMPJ.js} +5 -3
  23. package/dist/chunk-INKJBMPJ.js.map +1 -0
  24. package/dist/{chunk-SBWMSNS2.js → chunk-IRJADQM7.js} +2 -2
  25. package/dist/{chunk-SYGEV3KV.js → chunk-JTTTXGHX.js} +4 -4
  26. package/dist/{chunk-ELRGSZHZ.js → chunk-JZHIF3K7.js} +5 -5
  27. package/dist/{chunk-OALQWRLG.js → chunk-KQ27IDYL.js} +2 -2
  28. package/dist/{chunk-OLZBZAW4.js → chunk-LJ5E4GXC.js} +2 -2
  29. package/dist/{chunk-SRFNNOLC.js → chunk-LNA6M2IE.js} +2 -2
  30. package/dist/{chunk-GUIRWCKI.js → chunk-M4P5YJ45.js} +3 -3
  31. package/dist/{chunk-3S4GIO4B.js → chunk-MVEYK55V.js} +2 -2
  32. package/dist/{chunk-HKRLWERR.js → chunk-N5OCAAXY.js} +2 -2
  33. package/dist/{chunk-YRVTXSXP.js → chunk-NRCKIHND.js} +9 -15
  34. package/dist/chunk-NRCKIHND.js.map +1 -0
  35. package/dist/{chunk-DAVOSI4M.js → chunk-OEJDFGAF.js} +5 -5
  36. package/dist/{chunk-ENWMWIHP.js → chunk-QR2TM4OY.js} +5 -12
  37. package/dist/chunk-QR2TM4OY.js.map +1 -0
  38. package/dist/{chunk-FYNMNY4P.js → chunk-SPSGZWTZ.js} +25 -12
  39. package/dist/chunk-SPSGZWTZ.js.map +1 -0
  40. package/dist/{chunk-3JRWNWBF.js → chunk-TBB3THSL.js} +38 -4
  41. package/dist/chunk-TBB3THSL.js.map +1 -0
  42. package/dist/chunk-TWDVLTU6.js +132 -0
  43. package/dist/chunk-TWDVLTU6.js.map +1 -0
  44. package/dist/{chunk-KCYNTAAF.js → chunk-VAQJLHUW.js} +12 -10
  45. package/dist/chunk-VAQJLHUW.js.map +1 -0
  46. package/dist/{chunk-F3O5YHSI.js → chunk-VSZ5GDET.js} +2 -2
  47. package/dist/{chunk-Q5BSIARS.js → chunk-XTRPYUWK.js} +15 -15
  48. package/dist/chunk-XTRPYUWK.js.map +1 -0
  49. package/dist/{chunk-WWSKP5SR.js → chunk-YTRFL3MR.js} +70 -24
  50. package/dist/chunk-YTRFL3MR.js.map +1 -0
  51. package/dist/{chunk-NTPHCNJO.js → chunk-ZWAL2ZY7.js} +2 -2
  52. package/dist/commands/build/marketplace.js +12 -126
  53. package/dist/commands/build/marketplace.js.map +1 -1
  54. package/dist/commands/build/plugins.js +5 -5
  55. package/dist/commands/build/stack.js +5 -5
  56. package/dist/commands/compile.js +6 -6
  57. package/dist/commands/config/get.js +4 -4
  58. package/dist/commands/config/index.js +5 -5
  59. package/dist/commands/config/path.js +4 -4
  60. package/dist/commands/config/set-project.js +4 -4
  61. package/dist/commands/config/show.js +5 -5
  62. package/dist/commands/config/unset-project.js +4 -4
  63. package/dist/commands/diff.js +4 -4
  64. package/dist/commands/doctor.js +4 -4
  65. package/dist/commands/edit.js +29 -29
  66. package/dist/commands/eject.js +19 -23
  67. package/dist/commands/eject.js.map +1 -1
  68. package/dist/commands/import/skill.js +5 -5
  69. package/dist/commands/info.js +5 -5
  70. package/dist/commands/init.js +30 -29
  71. package/dist/commands/init.js.map +1 -1
  72. package/dist/commands/list.js +4 -4
  73. package/dist/commands/new/agent.js +52 -38
  74. package/dist/commands/new/agent.js.map +1 -1
  75. package/dist/commands/new/marketplace.js +252 -0
  76. package/dist/commands/new/marketplace.js.map +1 -0
  77. package/dist/commands/new/skill.js +35 -16
  78. package/dist/commands/new/skill.js.map +1 -1
  79. package/dist/commands/outdated.js +4 -4
  80. package/dist/commands/search.js +7 -7
  81. package/dist/commands/uninstall.js +6 -6
  82. package/dist/commands/update.js +6 -6
  83. package/dist/commands/validate.js +229 -19
  84. package/dist/commands/validate.js.map +1 -1
  85. package/dist/components/skill-search/skill-search.js +3 -3
  86. package/dist/components/wizard/category-grid.js +2 -2
  87. package/dist/components/wizard/category-grid.test.js +122 -2
  88. package/dist/components/wizard/category-grid.test.js.map +1 -1
  89. package/dist/components/wizard/checkbox-grid.js +3 -3
  90. package/dist/components/wizard/checkbox-grid.test.js +3 -3
  91. package/dist/components/wizard/domain-selection.js +9 -8
  92. package/dist/components/wizard/help-modal.js +2 -2
  93. package/dist/components/wizard/menu-item.js +1 -1
  94. package/dist/components/wizard/search-modal.js +2 -2
  95. package/dist/components/wizard/search-modal.test.js +2 -2
  96. package/dist/components/wizard/section-progress.js +2 -2
  97. package/dist/components/wizard/section-progress.test.js +2 -2
  98. package/dist/components/wizard/selection-card.js +2 -2
  99. package/dist/components/wizard/source-grid.js +3 -3
  100. package/dist/components/wizard/source-grid.test.js +3 -3
  101. package/dist/components/wizard/stack-selection.js +8 -9
  102. package/dist/components/wizard/step-agents.js +8 -7
  103. package/dist/components/wizard/step-agents.test.js +25 -20
  104. package/dist/components/wizard/step-agents.test.js.map +1 -1
  105. package/dist/components/wizard/step-build.js +8 -8
  106. package/dist/components/wizard/step-build.test.js +78 -46
  107. package/dist/components/wizard/step-build.test.js.map +1 -1
  108. package/dist/components/wizard/step-confirm.js +4 -4
  109. package/dist/components/wizard/step-confirm.test.js +8 -8
  110. package/dist/components/wizard/step-refine.js +2 -2
  111. package/dist/components/wizard/step-refine.test.js +2 -2
  112. package/dist/components/wizard/step-settings.js +5 -5
  113. package/dist/components/wizard/step-settings.test.js +8 -8
  114. package/dist/components/wizard/step-sources.js +10 -10
  115. package/dist/components/wizard/step-sources.test.js +11 -11
  116. package/dist/components/wizard/step-stack.js +12 -12
  117. package/dist/components/wizard/step-stack.test.js +27 -15
  118. package/dist/components/wizard/step-stack.test.js.map +1 -1
  119. package/dist/components/wizard/view-title.js +2 -2
  120. package/dist/components/wizard/wizard-layout.js +8 -8
  121. package/dist/components/wizard/wizard-tabs.js +2 -2
  122. package/dist/components/wizard/wizard-tabs.test.js +2 -2
  123. package/dist/components/wizard/wizard.js +25 -25
  124. package/dist/hooks/init.js +3 -5
  125. package/dist/hooks/init.js.map +1 -1
  126. package/dist/{source-manager-HXFXBZJU.js → source-manager-Q34LTUVM.js} +4 -4
  127. package/dist/src/agents/meta/documentor/examples.md +35 -36
  128. package/dist/src/agents/meta/documentor/workflow.md +91 -105
  129. package/dist/stores/wizard-store.js +5 -5
  130. package/dist/stores/wizard-store.test.js +48 -6
  131. package/dist/stores/wizard-store.test.js.map +1 -1
  132. package/package.json +1 -1
  133. package/src/agents/meta/documentor/examples.md +35 -36
  134. package/src/agents/meta/documentor/workflow.md +91 -105
  135. package/src/schemas/agent.schema.json +6 -0
  136. package/src/schemas/metadata.schema.json +7 -41
  137. package/src/schemas/project-config.schema.json +8 -4
  138. package/src/schemas/skills-matrix.schema.json +11 -298
  139. package/src/schemas/stacks.schema.json +2 -4
  140. package/dist/chunk-3JRWNWBF.js.map +0 -1
  141. package/dist/chunk-473YHDYQ.js.map +0 -1
  142. package/dist/chunk-5BDYODWP.js +0 -45
  143. package/dist/chunk-5BDYODWP.js.map +0 -1
  144. package/dist/chunk-ABE55TEU.js.map +0 -1
  145. package/dist/chunk-ENWMWIHP.js.map +0 -1
  146. package/dist/chunk-FVN5PFFY.js.map +0 -1
  147. package/dist/chunk-FYNMNY4P.js.map +0 -1
  148. package/dist/chunk-KCYNTAAF.js.map +0 -1
  149. package/dist/chunk-KZNPPUQG.js.map +0 -1
  150. package/dist/chunk-Q5BSIARS.js.map +0 -1
  151. package/dist/chunk-WWSKP5SR.js.map +0 -1
  152. package/dist/chunk-YRVTXSXP.js.map +0 -1
  153. package/dist/chunk-ZECXM7LP.js.map +0 -1
  154. package/dist/cli/defaults/agent-mappings.yaml +0 -215
  155. /package/dist/{chunk-V43QDMYQ.js.map → chunk-2RQYJFKA.js.map} +0 -0
  156. /package/dist/{chunk-KWWLPPHF.js.map → chunk-B4QYXVPZ.js.map} +0 -0
  157. /package/dist/{chunk-CLHBKFHU.js.map → chunk-CJFWO46A.js.map} +0 -0
  158. /package/dist/{chunk-M2XPTQDT.js.map → chunk-DC333ZDC.js.map} +0 -0
  159. /package/dist/{chunk-M3AGB4TR.js.map → chunk-DVW6ASTO.js.map} +0 -0
  160. /package/dist/{chunk-ARET3NYO.js.map → chunk-EZ46ZTAQ.js.map} +0 -0
  161. /package/dist/{chunk-YQFU2KZ5.js.map → chunk-FXQYEXLS.js.map} +0 -0
  162. /package/dist/{chunk-KVHLKPYB.js.map → chunk-HPJP3HFD.js.map} +0 -0
  163. /package/dist/{chunk-SBWMSNS2.js.map → chunk-IRJADQM7.js.map} +0 -0
  164. /package/dist/{chunk-SYGEV3KV.js.map → chunk-JTTTXGHX.js.map} +0 -0
  165. /package/dist/{chunk-ELRGSZHZ.js.map → chunk-JZHIF3K7.js.map} +0 -0
  166. /package/dist/{chunk-OALQWRLG.js.map → chunk-KQ27IDYL.js.map} +0 -0
  167. /package/dist/{chunk-OLZBZAW4.js.map → chunk-LJ5E4GXC.js.map} +0 -0
  168. /package/dist/{chunk-SRFNNOLC.js.map → chunk-LNA6M2IE.js.map} +0 -0
  169. /package/dist/{chunk-GUIRWCKI.js.map → chunk-M4P5YJ45.js.map} +0 -0
  170. /package/dist/{chunk-3S4GIO4B.js.map → chunk-MVEYK55V.js.map} +0 -0
  171. /package/dist/{chunk-HKRLWERR.js.map → chunk-N5OCAAXY.js.map} +0 -0
  172. /package/dist/{chunk-DAVOSI4M.js.map → chunk-OEJDFGAF.js.map} +0 -0
  173. /package/dist/{chunk-F3O5YHSI.js.map → chunk-VSZ5GDET.js.map} +0 -0
  174. /package/dist/{chunk-NTPHCNJO.js.map → chunk-ZWAL2ZY7.js.map} +0 -0
  175. /package/dist/{source-manager-HXFXBZJU.js.map → source-manager-Q34LTUVM.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/wizard.tsx","../src/cli/components/hooks/use-wizard-initialization.ts","../src/cli/components/hooks/use-build-step-props.ts"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { Box, Text, useApp, useInput, useStdout } from \"ink\";\nimport { ThemeProvider } from \"@inkjs/ui\";\nimport { useWizardStore, type WizardStep } from \"../../stores/wizard-store.js\";\nimport { CLI_COLORS } from \"../../consts.js\";\nimport { cliTheme } from \"../themes/default.js\";\nimport { WizardLayout } from \"./wizard-layout.js\";\nimport { StepStack } from \"./step-stack.js\";\nimport { StepBuild } from \"./step-build.js\";\nimport { StepConfirm } from \"./step-confirm.js\";\nimport { StepSources } from \"./step-sources.js\";\nimport { StepSettings } from \"./step-settings.js\";\nimport { StepAgents } from \"./step-agents.js\";\nimport { resolveAlias, validateSelection } from \"../../lib/matrix/index.js\";\nimport type {\n AgentName,\n Domain,\n DomainSelections,\n MergedSkillsMatrix,\n SkillId,\n} from \"../../types/index.js\";\nimport { getStackName } from \"./utils.js\";\nimport { warn } from \"../../utils/logger.js\";\nimport { useWizardInitialization } from \"../hooks/use-wizard-initialization.js\";\nimport { useBuildStepProps } from \"../hooks/use-build-step-props.js\";\n\nexport type WizardResultV2 = {\n selectedSkills: SkillId[];\n selectedAgents: AgentName[];\n selectedStackId: string | null;\n domainSelections: DomainSelections;\n selectedDomains: Domain[];\n sourceSelections: Partial<Record<SkillId, string>>;\n expertMode: boolean;\n installMode: \"plugin\" | \"local\";\n cancelled: boolean;\n validation: {\n valid: boolean;\n errors: Array<{ message: string }>;\n warnings: Array<{ message: string }>;\n };\n};\n\ntype WizardProps = {\n matrix: MergedSkillsMatrix;\n onComplete: (result: WizardResultV2) => void;\n onCancel: () => void;\n version?: string;\n marketplaceLabel?: string;\n logo?: string;\n initialStep?: WizardStep;\n initialInstallMode?: \"plugin\" | \"local\";\n initialExpertMode?: boolean;\n initialDomains?: Domain[];\n initialAgents?: AgentName[];\n installedSkillIds?: SkillId[];\n projectDir?: string;\n};\n\nconst MIN_TERMINAL_WIDTH = 80;\nconst MIN_TERMINAL_HEIGHT = 15;\n\nexport const Wizard: React.FC<WizardProps> = ({\n matrix,\n onComplete,\n onCancel,\n version,\n marketplaceLabel,\n logo,\n initialStep,\n initialInstallMode,\n initialExpertMode,\n initialDomains,\n initialAgents,\n installedSkillIds,\n projectDir,\n}) => {\n const store = useWizardStore();\n const { exit } = useApp();\n const { stdout } = useStdout();\n\n const terminalWidth = stdout.columns || MIN_TERMINAL_WIDTH;\n const terminalHeight = stdout.rows || MIN_TERMINAL_HEIGHT;\n const isNarrowTerminal = terminalWidth < MIN_TERMINAL_WIDTH;\n const isShortTerminal = terminalHeight < MIN_TERMINAL_HEIGHT;\n\n useWizardInitialization({\n matrix,\n initialStep,\n initialInstallMode,\n initialExpertMode,\n initialDomains,\n initialAgents,\n installedSkillIds,\n });\n\n const buildStepProps = useBuildStepProps({ store, matrix, installedSkillIds });\n\n useInput((input, key) => {\n // ESC is handled by step-settings.tsx's own useKeyboardNavigation hook\n if (store.showSettings) {\n if (input === \"g\" || input === \"G\") {\n store.toggleSettings();\n }\n return;\n }\n\n if (store.showHelp) {\n if (key.escape || input === \"?\") {\n store.toggleHelp();\n }\n return;\n }\n\n if (input === \"?\") {\n store.toggleHelp();\n return;\n }\n\n if (key.escape) {\n // At the initial stack/scratch selection (approach not yet set), ESC cancels the wizard.\n // StackSelection handles its own ESC via the onCancel prop.\n // Other steps that don't have their own escape handler use goBack.\n if (\n store.step !== \"build\" &&\n store.step !== \"confirm\" &&\n store.step !== \"sources\" &&\n store.step !== \"agents\" &&\n store.step !== \"stack\"\n ) {\n store.goBack();\n }\n return;\n }\n\n if ((input === \"a\" || input === \"A\") && store.step === \"build\" && store.selectedStackId) {\n store.setStackAction(\"defaults\");\n store.setStep(\"confirm\");\n return;\n }\n\n if ((input === \"g\" || input === \"G\") && store.step === \"sources\") {\n store.toggleSettings();\n return;\n }\n\n if (input === \"e\" || input === \"E\") {\n store.toggleExpertMode();\n return;\n }\n if (input === \"p\" || input === \"P\") {\n store.toggleInstallMode();\n }\n });\n\n const handleComplete = useCallback(() => {\n let allSkills: SkillId[];\n\n if (store.selectedStackId && store.stackAction === \"defaults\") {\n const stack = matrix.suggestedStacks.find((s) => s.id === store.selectedStackId);\n if (!stack) {\n warn(`Stack not found in matrix: '${store.selectedStackId}'`);\n }\n allSkills = [...(stack?.allSkillIds || [])];\n } else {\n const techNames = store.getAllSelectedTechnologies();\n allSkills = techNames.map((tech) => {\n const resolved = resolveAlias(tech, matrix);\n if (!matrix.skills[resolved]) {\n warn(\n `Technology '${tech}' could not be resolved to a skill ID - it may be missing from skill_aliases`,\n );\n }\n return resolved;\n });\n }\n\n const methodologySkills = store.getDefaultMethodologySkills();\n for (const skill of methodologySkills) {\n if (!allSkills.includes(skill)) {\n allSkills.push(skill);\n }\n }\n\n const validation = validateSelection(allSkills, matrix);\n\n const result: WizardResultV2 = {\n selectedSkills: allSkills,\n selectedAgents: store.selectedAgents,\n selectedStackId: store.selectedStackId,\n domainSelections: store.domainSelections,\n selectedDomains: store.selectedDomains,\n sourceSelections: store.sourceSelections,\n expertMode: store.expertMode,\n installMode: store.installMode,\n cancelled: false,\n validation,\n };\n\n onComplete(result);\n exit();\n }, [store, matrix, onComplete, exit]);\n\n const handleCancel = useCallback(() => {\n onCancel();\n exit();\n }, [onCancel, exit]);\n\n const renderStep = () => {\n switch (store.step) {\n case \"stack\":\n return <StepStack matrix={matrix} onCancel={handleCancel} />;\n\n case \"build\":\n return <StepBuild {...buildStepProps} />;\n\n case \"sources\": {\n if (store.showSettings) {\n return (\n <StepSettings\n projectDir={projectDir || process.cwd()}\n onClose={() => store.toggleSettings()}\n />\n );\n }\n return (\n <StepSources\n matrix={matrix}\n projectDir={projectDir}\n onContinue={() => {\n if (!initialAgents?.length) {\n store.preselectAgentsFromDomains();\n }\n store.setStep(\"agents\");\n }}\n onBack={store.goBack}\n />\n );\n }\n\n case \"agents\":\n return <StepAgents matrix={matrix} />;\n\n case \"confirm\": {\n const stackName = getStackName(store.selectedStackId, matrix);\n const technologyCount = store.getTechnologyCount();\n return (\n <StepConfirm\n onComplete={handleComplete}\n stackName={stackName}\n selectedDomains={store.selectedDomains}\n domainSelections={store.domainSelections}\n technologyCount={technologyCount}\n skillCount={technologyCount}\n agentCount={store.selectedAgents.length}\n installMode={store.installMode}\n onBack={store.goBack}\n />\n );\n }\n\n default:\n return null;\n }\n };\n\n if (isNarrowTerminal || isShortTerminal) {\n const issue = isNarrowTerminal\n ? `too narrow (${terminalWidth} columns, need ${MIN_TERMINAL_WIDTH})`\n : `too short (${terminalHeight} rows, need ${MIN_TERMINAL_HEIGHT})`;\n\n return (\n <ThemeProvider theme={cliTheme}>\n <Box flexDirection=\"column\" padding={1}>\n <Text color={CLI_COLORS.WARNING}>Terminal {issue}. Please resize your terminal.</Text>\n </Box>\n </ThemeProvider>\n );\n }\n\n return (\n <ThemeProvider theme={cliTheme}>\n <WizardLayout version={version} marketplaceLabel={marketplaceLabel} logo={logo}>\n {renderStep()}\n </WizardLayout>\n </ThemeProvider>\n );\n};\n","import { useRef } from \"react\";\nimport { useWizardStore, type WizardStep } from \"../../stores/wizard-store.js\";\nimport type { AgentName, Domain, MergedSkillsMatrix, SkillId } from \"../../types/index.js\";\n\ntype UseWizardInitializationOptions = {\n matrix: MergedSkillsMatrix;\n initialStep?: WizardStep;\n initialInstallMode?: \"plugin\" | \"local\";\n initialExpertMode?: boolean;\n initialDomains?: Domain[];\n initialAgents?: AgentName[];\n installedSkillIds?: SkillId[];\n};\n\n/**\n * Runs one-time wizard store initialization before the first render.\n * Populates step, approach, install mode, and skill selections from props.\n */\nexport function useWizardInitialization({\n matrix,\n initialStep,\n initialInstallMode,\n initialExpertMode,\n initialDomains,\n initialAgents,\n installedSkillIds,\n}: UseWizardInitializationOptions): void {\n const initialized = useRef(false);\n\n if (!initialized.current) {\n initialized.current = true;\n\n if (initialStep) {\n if (installedSkillIds?.length) {\n useWizardStore\n .getState()\n .populateFromSkillIds(installedSkillIds, matrix.skills, matrix.categories);\n }\n useWizardStore.setState({ step: initialStep, approach: \"scratch\" });\n }\n if (initialInstallMode) {\n useWizardStore.setState({ installMode: initialInstallMode });\n }\n if (initialExpertMode) {\n useWizardStore.setState({ expertMode: initialExpertMode });\n }\n // Restore saved domains from config, overriding the domains\n // derived by populateFromSkillIds\n if (initialDomains?.length) {\n useWizardStore.setState({ selectedDomains: initialDomains });\n }\n // Restore saved agents from config, overriding the default empty array\n if (initialAgents?.length) {\n useWizardStore.setState({ selectedAgents: initialAgents });\n }\n }\n}\n","import { useCallback } from \"react\";\nimport type { Domain, MergedSkillsMatrix, SkillId } from \"../../types/index.js\";\nimport type { WizardState } from \"../../stores/wizard-store.js\";\nimport type { StepBuildProps } from \"../wizard/step-build.js\";\n\ntype UseBuildStepPropsOptions = {\n store: WizardState;\n matrix: MergedSkillsMatrix;\n installedSkillIds?: SkillId[];\n};\n\nexport function useBuildStepProps({\n store,\n matrix,\n installedSkillIds,\n}: UseBuildStepPropsOptions): StepBuildProps {\n const currentDomain = store.getCurrentDomain();\n const defaultDomains: Domain[] = [\"web\"];\n const effectiveDomains =\n store.selectedDomains.length > 0 ? store.selectedDomains : defaultDomains;\n\n const allSelections = store.getAllSelectedTechnologies();\n\n const activeDomain: Domain = currentDomain || effectiveDomains[0] || \"web\";\n\n const onToggle = useCallback(\n (subcategoryId: Parameters<StepBuildProps[\"onToggle\"]>[0], techId: SkillId) => {\n const domain: Domain = store.getCurrentDomain() || \"web\";\n const cat = matrix.categories[subcategoryId];\n store.toggleTechnology(domain, subcategoryId, techId, cat?.exclusive ?? true);\n },\n [store, matrix],\n );\n\n const onContinue = useCallback(() => {\n if (!store.nextDomain()) {\n store.setStep(\"sources\");\n }\n }, [store]);\n\n const onBack = useCallback(() => {\n if (!store.prevDomain()) {\n store.goBack();\n }\n }, [store]);\n\n return {\n matrix,\n domain: activeDomain,\n selectedDomains: effectiveDomains,\n selections: store.domainSelections[activeDomain] || {},\n allSelections,\n showLabels: store.showLabels,\n expertMode: store.expertMode,\n installedSkillIds,\n onToggle,\n onToggleLabels: store.toggleShowLabels,\n onContinue,\n onBack,\n };\n}\n"],"mappings":"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","names":["useCallback","useCallback"]}
@@ -2,17 +2,23 @@
2
2
  import {
3
3
  useMeasuredHeight
4
4
  } from "./chunk-K77I4XGL.js";
5
+ import {
6
+ getDomainDisplayName
7
+ } from "./chunk-NRCKIHND.js";
5
8
  import {
6
9
  ViewTitle
7
- } from "./chunk-KWWLPPHF.js";
10
+ } from "./chunk-B4QYXVPZ.js";
8
11
  import {
9
12
  useWizardStore
10
- } from "./chunk-FYNMNY4P.js";
13
+ } from "./chunk-SPSGZWTZ.js";
14
+ import {
15
+ typedKeys
16
+ } from "./chunk-T4EXUIBY.js";
11
17
  import {
12
18
  CLI_COLORS,
13
19
  SCROLL_VIEWPORT,
14
20
  UI_SYMBOLS
15
- } from "./chunk-FVN5PFFY.js";
21
+ } from "./chunk-FTD5Z6QD.js";
16
22
  import {
17
23
  init_esm_shims
18
24
  } from "./chunk-DHET7RCE.js";
@@ -20,9 +26,9 @@ import {
20
26
  // src/cli/components/wizard/step-agents.tsx
21
27
  init_esm_shims();
22
28
  import { Box, Text, useInput } from "ink";
23
- import { useRef, useState } from "react";
29
+ import { useMemo, useRef, useState } from "react";
24
30
  import { jsx, jsxs } from "react/jsx-runtime";
25
- var AGENT_GROUPS = [
31
+ var BUILT_IN_AGENT_GROUPS = [
26
32
  {
27
33
  label: "Web",
28
34
  items: [
@@ -94,23 +100,63 @@ var AGENT_GROUPS = [
94
100
  ]
95
101
  }
96
102
  ];
97
- var FOCUSABLE_IDS = [
98
- ...AGENT_GROUPS.flatMap((group) => group.items.map((a) => a.id)),
99
- "continue"
100
- ];
101
- var FLAT_ROWS = AGENT_GROUPS.flatMap((group, groupIndex) => [
102
- ...groupIndex > 0 ? [{ type: "spacer" }] : [],
103
- { type: "header", label: group.label },
104
- ...group.items.map((agent) => ({ type: "agent", agent }))
105
- ]);
106
- var StepAgents = () => {
103
+ var BUILT_IN_AGENT_IDS = new Set(
104
+ BUILT_IN_AGENT_GROUPS.flatMap((group) => group.items.map((a) => a.id))
105
+ );
106
+ function agentIdToLabel(id) {
107
+ return id.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
108
+ }
109
+ function buildAgentGroups(matrix) {
110
+ const customAgentIds = [];
111
+ for (const stack of matrix.suggestedStacks) {
112
+ for (const agentName of typedKeys(stack.skills)) {
113
+ if (!BUILT_IN_AGENT_IDS.has(agentName) && !customAgentIds.includes(agentName)) {
114
+ customAgentIds.push(agentName);
115
+ }
116
+ }
117
+ }
118
+ if (customAgentIds.length === 0) return BUILT_IN_AGENT_GROUPS;
119
+ const customGroupMap = /* @__PURE__ */ new Map();
120
+ for (const agentId of customAgentIds) {
121
+ const explicitDomain = matrix.agentDefinedDomains?.[agentId];
122
+ const domainKey = explicitDomain ?? (agentId.split("-")[0] || "custom");
123
+ const groupLabel = getDomainDisplayName(domainKey);
124
+ if (!customGroupMap.has(groupLabel)) {
125
+ customGroupMap.set(groupLabel, []);
126
+ }
127
+ customGroupMap.get(groupLabel).push({
128
+ id: agentId,
129
+ label: agentIdToLabel(agentId),
130
+ description: "Custom agent"
131
+ });
132
+ }
133
+ const customGroups = [];
134
+ for (const [label, items] of customGroupMap) {
135
+ customGroups.push({ label, items });
136
+ }
137
+ return [...BUILT_IN_AGENT_GROUPS, ...customGroups];
138
+ }
139
+ function buildFlatRows(groups) {
140
+ return groups.flatMap((group, groupIndex) => [
141
+ ...groupIndex > 0 ? [{ type: "spacer" }] : [],
142
+ { type: "header", label: group.label },
143
+ ...group.items.map((agent) => ({ type: "agent", agent }))
144
+ ]);
145
+ }
146
+ function buildFocusableIds(groups) {
147
+ return [...groups.flatMap((group) => group.items.map((a) => a.id)), "continue"];
148
+ }
149
+ var StepAgents = ({ matrix }) => {
107
150
  const store = useWizardStore();
108
- const [focusedId, setFocusedId] = useState(FOCUSABLE_IDS[0]);
151
+ const agentGroups = useMemo(() => buildAgentGroups(matrix), [matrix]);
152
+ const flatRows = useMemo(() => buildFlatRows(agentGroups), [agentGroups]);
153
+ const focusableIds = useMemo(() => buildFocusableIds(agentGroups), [agentGroups]);
154
+ const [focusedId, setFocusedId] = useState(focusableIds[0]);
109
155
  const { ref: listRef, measuredHeight: listHeight } = useMeasuredHeight();
110
156
  const scrollTopRef = useRef(0);
111
157
  const scrollEnabled = listHeight > 0 && listHeight >= SCROLL_VIEWPORT.MIN_VIEWPORT_ROWS;
112
158
  if (scrollEnabled && focusedId !== "continue") {
113
- const rowIndex = FLAT_ROWS.findIndex(
159
+ const rowIndex = flatRows.findIndex(
114
160
  (row) => row.type === "agent" && row.agent.id === focusedId
115
161
  );
116
162
  if (rowIndex >= 0) {
@@ -126,15 +172,15 @@ var StepAgents = () => {
126
172
  store.goBack();
127
173
  return;
128
174
  }
129
- const currentIdx = FOCUSABLE_IDS.indexOf(focusedId);
175
+ const currentIdx = focusableIds.indexOf(focusedId);
130
176
  if (key.upArrow || input === "k") {
131
- const nextIdx = currentIdx <= 0 ? FOCUSABLE_IDS.length - 1 : currentIdx - 1;
132
- setFocusedId(FOCUSABLE_IDS[nextIdx]);
177
+ const nextIdx = currentIdx <= 0 ? focusableIds.length - 1 : currentIdx - 1;
178
+ setFocusedId(focusableIds[nextIdx]);
133
179
  return;
134
180
  }
135
181
  if (key.downArrow || input === "j") {
136
- const nextIdx = currentIdx >= FOCUSABLE_IDS.length - 1 ? 0 : currentIdx + 1;
137
- setFocusedId(FOCUSABLE_IDS[nextIdx]);
182
+ const nextIdx = currentIdx >= focusableIds.length - 1 ? 0 : currentIdx + 1;
183
+ setFocusedId(focusableIds[nextIdx]);
138
184
  return;
139
185
  }
140
186
  if (key.return) {
@@ -148,7 +194,7 @@ var StepAgents = () => {
148
194
  const selectedCount = store.selectedAgents.length;
149
195
  const continueLabel = selectedCount > 0 ? `Continue with ${selectedCount} agent(s)` : "Continue without agents";
150
196
  const isContinueFocused = focusedId === "continue";
151
- const rowElements = FLAT_ROWS.map((row, index) => {
197
+ const rowElements = flatRows.map((row, index) => {
152
198
  switch (row.type) {
153
199
  case "header":
154
200
  return /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsxs(Text, { dimColor: true, bold: true, children: [
@@ -209,4 +255,4 @@ var StepAgents = () => {
209
255
  export {
210
256
  StepAgents
211
257
  };
212
- //# sourceMappingURL=chunk-WWSKP5SR.js.map
258
+ //# sourceMappingURL=chunk-YTRFL3MR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/step-agents.tsx"],"sourcesContent":["import { Box, Text, useInput } from \"ink\";\nimport React, { useMemo, useRef, useState } from \"react\";\nimport { CLI_COLORS, SCROLL_VIEWPORT, UI_SYMBOLS } from \"../../consts.js\";\nimport { useWizardStore } from \"../../stores/wizard-store.js\";\nimport type { AgentName, MergedSkillsMatrix } from \"../../types/index.js\";\nimport { typedKeys } from \"../../utils/typed-object.js\";\nimport { useMeasuredHeight } from \"../hooks/use-measured-height.js\";\nimport { getDomainDisplayName } from \"./utils.js\";\nimport { ViewTitle } from \"./view-title.js\";\n\ntype AgentItem = {\n id: AgentName;\n label: string;\n description: string;\n};\n\ntype AgentGroup = {\n label: string;\n items: AgentItem[];\n};\n\nconst BUILT_IN_AGENT_GROUPS: AgentGroup[] = [\n {\n label: \"Web\",\n items: [\n {\n id: \"web-developer\",\n label: \"Web Developer\",\n description: \"Frontend features, components, TypeScript\",\n },\n { id: \"web-reviewer\", label: \"Web Reviewer\", description: \"UI component code review\" },\n { id: \"web-researcher\", label: \"Web Researcher\", description: \"Frontend pattern discovery\" },\n {\n id: \"web-tester\",\n label: \"Web Tester\",\n description: \"Frontend tests, E2E, component tests\",\n },\n { id: \"web-pm\", label: \"Web PM\", description: \"Implementation specs and planning\" },\n {\n id: \"web-architecture\",\n label: \"Web Architecture\",\n description: \"App scaffolding, foundational patterns\",\n },\n {\n id: \"web-pattern-critique\",\n label: \"Web Pattern Critique\",\n description: \"Critique patterns against industry standards\",\n },\n ],\n },\n {\n label: \"API\",\n items: [\n {\n id: \"api-developer\",\n label: \"API Developer\",\n description: \"Backend routes, database, middleware\",\n },\n { id: \"api-reviewer\", label: \"API Reviewer\", description: \"Backend and config code review\" },\n { id: \"api-researcher\", label: \"API Researcher\", description: \"Backend pattern discovery\" },\n ],\n },\n {\n label: \"CLI\",\n items: [\n {\n id: \"cli-developer\",\n label: \"CLI Developer\",\n description: \"CLI commands, interactive prompts\",\n },\n { id: \"cli-tester\", label: \"CLI Tester\", description: \"CLI application tests\" },\n { id: \"cli-reviewer\", label: \"CLI Reviewer\", description: \"CLI code review\" },\n { id: \"cli-migrator\", label: \"CLI Migrator\", description: \"Commander.js to oclif migration\" },\n ],\n },\n {\n label: \"Meta\",\n items: [\n {\n id: \"pattern-scout\",\n label: \"Pattern Scout\",\n description: \"Extract codebase patterns and standards\",\n },\n { id: \"agent-summoner\", label: \"Agent Summoner\", description: \"Create and improve agents\" },\n {\n id: \"skill-summoner\",\n label: \"Skill Summoner\",\n description: \"Create technology-specific skills\",\n },\n { id: \"documentor\", label: \"Documentor\", description: \"AI-focused documentation\" },\n ],\n },\n];\n\n/** IDs of all built-in agents for fast lookup. */\nconst BUILT_IN_AGENT_IDS = new Set<string>(\n BUILT_IN_AGENT_GROUPS.flatMap((group) => group.items.map((a) => a.id)),\n);\n\n/** Convert a kebab-case agent ID to a title-case label. */\nfunction agentIdToLabel(id: string): string {\n return id\n .split(\"-\")\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(\" \");\n}\n\ntype FocusId = AgentName | \"continue\";\n\ntype ListRow =\n | { type: \"header\"; label: string }\n | { type: \"spacer\" }\n | { type: \"agent\"; agent: AgentItem };\n\nfunction buildAgentGroups(matrix: MergedSkillsMatrix): AgentGroup[] {\n const customAgentIds: string[] = [];\n for (const stack of matrix.suggestedStacks) {\n for (const agentName of typedKeys(stack.skills)) {\n if (!BUILT_IN_AGENT_IDS.has(agentName) && !customAgentIds.includes(agentName)) {\n customAgentIds.push(agentName);\n }\n }\n }\n\n if (customAgentIds.length === 0) return BUILT_IN_AGENT_GROUPS;\n\n // Group custom agents by explicit domain (from agent.yaml) or kebab prefix fallback\n const customGroupMap = new Map<string, AgentItem[]>();\n for (const agentId of customAgentIds) {\n // Boundary cast: custom agent names from matrix stacks are not in the AgentName union\n const explicitDomain = matrix.agentDefinedDomains?.[agentId as AgentName];\n const domainKey = explicitDomain ?? (agentId.split(\"-\")[0] || \"custom\");\n const groupLabel = getDomainDisplayName(domainKey);\n if (!customGroupMap.has(groupLabel)) {\n customGroupMap.set(groupLabel, []);\n }\n customGroupMap.get(groupLabel)!.push({\n id: agentId as AgentName,\n label: agentIdToLabel(agentId),\n description: \"Custom agent\",\n });\n }\n\n const customGroups: AgentGroup[] = [];\n for (const [label, items] of customGroupMap) {\n customGroups.push({ label, items });\n }\n\n return [...BUILT_IN_AGENT_GROUPS, ...customGroups];\n}\n\nfunction buildFlatRows(groups: AgentGroup[]): ListRow[] {\n return groups.flatMap((group, groupIndex): ListRow[] => [\n ...(groupIndex > 0 ? [{ type: \"spacer\" as const }] : []),\n { type: \"header\" as const, label: group.label },\n ...group.items.map((agent): ListRow => ({ type: \"agent\", agent })),\n ]);\n}\n\nfunction buildFocusableIds(groups: AgentGroup[]): FocusId[] {\n return [...groups.flatMap((group) => group.items.map((a) => a.id)), \"continue\"];\n}\n\ntype StepAgentsProps = {\n matrix: MergedSkillsMatrix;\n};\n\nexport const StepAgents: React.FC<StepAgentsProps> = ({ matrix }) => {\n const store = useWizardStore();\n\n const agentGroups = useMemo(() => buildAgentGroups(matrix), [matrix]);\n const flatRows = useMemo(() => buildFlatRows(agentGroups), [agentGroups]);\n const focusableIds = useMemo(() => buildFocusableIds(agentGroups), [agentGroups]);\n\n const [focusedId, setFocusedId] = useState<FocusId>(focusableIds[0]!);\n const { ref: listRef, measuredHeight: listHeight } = useMeasuredHeight();\n\n const scrollTopRef = useRef(0);\n const scrollEnabled = listHeight > 0 && listHeight >= SCROLL_VIEWPORT.MIN_VIEWPORT_ROWS;\n\n if (scrollEnabled && focusedId !== \"continue\") {\n const rowIndex = flatRows.findIndex(\n (row) => row.type === \"agent\" && row.agent.id === focusedId,\n );\n if (rowIndex >= 0) {\n if (rowIndex < scrollTopRef.current) {\n scrollTopRef.current = rowIndex;\n } else if (rowIndex + 1 > scrollTopRef.current + listHeight) {\n scrollTopRef.current = rowIndex + 1 - listHeight;\n }\n }\n }\n\n useInput((input, key) => {\n if (key.escape) {\n store.goBack();\n return;\n }\n\n const currentIdx = focusableIds.indexOf(focusedId);\n\n if (key.upArrow || input === \"k\") {\n const nextIdx = currentIdx <= 0 ? focusableIds.length - 1 : currentIdx - 1;\n setFocusedId(focusableIds[nextIdx]!);\n return;\n }\n\n if (key.downArrow || input === \"j\") {\n const nextIdx = currentIdx >= focusableIds.length - 1 ? 0 : currentIdx + 1;\n setFocusedId(focusableIds[nextIdx]!);\n return;\n }\n\n if (key.return) {\n store.setStep(\"confirm\");\n return;\n }\n\n if (input === \" \" && focusedId !== \"continue\") {\n store.toggleAgent(focusedId);\n }\n });\n\n const selectedCount = store.selectedAgents.length;\n const continueLabel =\n selectedCount > 0 ? `Continue with ${selectedCount} agent(s)` : \"Continue without agents\";\n\n const isContinueFocused = focusedId === \"continue\";\n\n const rowElements = flatRows.map((row, index) => {\n switch (row.type) {\n case \"header\":\n return (\n <Box key={`header-${row.label}`} flexShrink={0}>\n <Text dimColor bold>\n {\" \"}\n {row.label}\n </Text>\n </Box>\n );\n case \"spacer\":\n return (\n <Box key={`spacer-${index}`} flexShrink={0}>\n <Text> </Text>\n </Box>\n );\n case \"agent\": {\n const isFocused = row.agent.id === focusedId;\n const isSelected = store.selectedAgents.includes(row.agent.id);\n const checkbox = isSelected ? \"[\\u2713]\" : \"[ ]\";\n const pointer = isFocused ? UI_SYMBOLS.CURRENT : \" \";\n return (\n <Box key={row.agent.id} flexShrink={0}>\n <Text>\n <Text color={isFocused ? CLI_COLORS.PRIMARY : undefined}>{pointer}</Text>\n <Text\n color={isSelected || isFocused ? CLI_COLORS.PRIMARY : undefined}\n bold={isFocused}\n >\n {\" \"}\n {checkbox} {row.agent.label}\n </Text>\n <Text dimColor> - {row.agent.description}</Text>\n </Text>\n </Box>\n );\n }\n }\n });\n\n return (\n <Box flexDirection=\"column\" width=\"100%\" flexGrow={1} flexBasis={0}>\n <ViewTitle>Select agents to compile:</ViewTitle>\n\n {!scrollEnabled ? (\n <Box ref={listRef} flexDirection=\"column\" flexGrow={1} flexBasis={0} overflow=\"hidden\">\n {rowElements}\n </Box>\n ) : (\n <Box ref={listRef} flexDirection=\"column\" flexGrow={1} flexBasis={0}>\n <Box flexDirection=\"column\" overflow=\"hidden\" flexGrow={1}>\n <Box\n flexDirection=\"column\"\n marginTop={scrollTopRef.current > 0 ? -scrollTopRef.current : 0}\n flexShrink={0}\n >\n {rowElements}\n </Box>\n </Box>\n </Box>\n )}\n\n <Text color={isContinueFocused ? CLI_COLORS.PRIMARY : undefined} bold={isContinueFocused}>\n {isContinueFocused ? UI_SYMBOLS.CURRENT : \" \"} {\"\\u2192\"} {continueLabel}\n </Text>\n </Box>\n );\n};\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  CLI_COLORS,
4
4
  UI_SYMBOLS
5
- } from "./chunk-FVN5PFFY.js";
5
+ } from "./chunk-FTD5Z6QD.js";
6
6
  import {
7
7
  init_esm_shims
8
8
  } from "./chunk-DHET7RCE.js";
@@ -37,4 +37,4 @@ var SelectionCard = ({
37
37
  export {
38
38
  SelectionCard
39
39
  };
40
- //# sourceMappingURL=chunk-NTPHCNJO.js.map
40
+ //# sourceMappingURL=chunk-ZWAL2ZY7.js.map
@@ -1,25 +1,21 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ generateMarketplace,
4
+ getMarketplaceStats,
5
+ writeMarketplace
6
+ } from "../../chunk-TWDVLTU6.js";
2
7
  import {
3
8
  BaseCommand
4
- } from "../../chunk-SRFNNOLC.js";
9
+ } from "../../chunk-LNA6M2IE.js";
5
10
  import {
6
- ensureDir,
7
- getErrorMessage,
8
- glob,
9
- pluginManifestSchema,
10
- readFileSafe,
11
- setVerbose,
12
- verbose,
13
- warn,
14
- writeFile
15
- } from "../../chunk-473YHDYQ.js";
11
+ setVerbose
12
+ } from "../../chunk-C4QI54PN.js";
16
13
  import {
17
14
  DEFAULT_BRANDING,
18
15
  DEFAULT_PLUGIN_NAME,
19
16
  DEFAULT_VERSION,
20
- MAX_PLUGIN_FILE_SIZE,
21
17
  PLUGIN_MANIFEST_DIR
22
- } from "../../chunk-FVN5PFFY.js";
18
+ } from "../../chunk-FTD5Z6QD.js";
23
19
  import {
24
20
  init_esm_shims
25
21
  } from "../../chunk-DHET7RCE.js";
@@ -27,118 +23,8 @@ import {
27
23
  // src/cli/commands/build/marketplace.ts
28
24
  init_esm_shims();
29
25
  import { Flags } from "@oclif/core";
30
- import path2 from "path";
31
- import { sortBy as sortBy2 } from "remeda";
32
-
33
- // src/cli/lib/marketplace-generator.ts
34
- init_esm_shims();
35
26
  import path from "path";
36
27
  import { sortBy } from "remeda";
37
- var PLUGIN_MANIFEST_PATH = ".claude-plugin/plugin.json";
38
- var MARKETPLACE_SCHEMA_URL = "https://anthropic.com/claude-code/marketplace.schema.json";
39
- var CATEGORY_PATTERNS = [
40
- { pattern: /^web-/, category: "web" },
41
- { pattern: /^api-/, category: "api" },
42
- { pattern: /^cli-/, category: "cli" },
43
- { pattern: /^meta-/, category: "methodology" },
44
- { pattern: /^infra-/, category: "infra" },
45
- { pattern: /^mobile-/, category: "mobile" },
46
- { pattern: /^security-/, category: "security" }
47
- ];
48
- function inferCategoryFromPluginName(pluginName) {
49
- for (const { pattern, category } of CATEGORY_PATTERNS) {
50
- if (pattern.test(pluginName)) {
51
- return category;
52
- }
53
- }
54
- return void 0;
55
- }
56
- async function readPluginManifest(pluginDir) {
57
- const manifestPath = path.join(pluginDir, PLUGIN_MANIFEST_PATH);
58
- try {
59
- const content = await readFileSafe(manifestPath, MAX_PLUGIN_FILE_SIZE);
60
- return pluginManifestSchema.parse(JSON.parse(content));
61
- } catch (error) {
62
- verbose(`Failed to read plugin manifest at '${manifestPath}': ${getErrorMessage(error)}`);
63
- return null;
64
- }
65
- }
66
- function convertManifestToMarketplacePlugin(manifest, pluginRoot, pluginDirName) {
67
- const category = inferCategoryFromPluginName(manifest.name);
68
- const plugin = {
69
- name: manifest.name,
70
- source: `./${pluginRoot}/${pluginDirName}`,
71
- description: manifest.description,
72
- version: manifest.version,
73
- author: manifest.author,
74
- keywords: manifest.keywords
75
- };
76
- if (category) {
77
- plugin.category = category;
78
- }
79
- return plugin;
80
- }
81
- async function generateMarketplace(pluginsDir, options) {
82
- verbose(`Scanning plugins directory: ${pluginsDir}`);
83
- const manifestFiles = await glob(`**/${PLUGIN_MANIFEST_PATH}`, pluginsDir);
84
- verbose(`Found ${manifestFiles.length} plugin manifests`);
85
- const plugins = [];
86
- for (const manifestFile of manifestFiles) {
87
- const pluginDirName = manifestFile.split("/")[0];
88
- const pluginDir = path.join(pluginsDir, pluginDirName);
89
- const manifest = await readPluginManifest(pluginDir);
90
- if (!manifest) {
91
- warn(`Could not read plugin manifest: '${manifestFile}'`);
92
- continue;
93
- }
94
- const plugin = convertManifestToMarketplacePlugin(
95
- manifest,
96
- options.pluginRoot.replace(/^\.\//, ""),
97
- pluginDirName
98
- );
99
- plugins.push(plugin);
100
- verbose(` [OK] ${plugin.name}`);
101
- }
102
- const sortedPlugins = sortBy(plugins, (p) => p.name);
103
- const marketplace = {
104
- $schema: MARKETPLACE_SCHEMA_URL,
105
- name: options.name,
106
- version: options.version ?? "1.0.0",
107
- owner: {
108
- name: options.ownerName
109
- },
110
- metadata: {
111
- pluginRoot: options.pluginRoot
112
- },
113
- plugins: sortedPlugins
114
- };
115
- if (options.description) {
116
- marketplace.description = options.description;
117
- }
118
- if (options.ownerEmail) {
119
- marketplace.owner.email = options.ownerEmail;
120
- }
121
- return marketplace;
122
- }
123
- async function writeMarketplace(outputPath, marketplace) {
124
- await ensureDir(path.dirname(outputPath));
125
- const content = `${JSON.stringify(marketplace, null, 2)}
126
- `;
127
- await writeFile(outputPath, content);
128
- }
129
- function getMarketplaceStats(marketplace) {
130
- const byCategory = {};
131
- for (const plugin of marketplace.plugins) {
132
- const category = plugin.category ?? "uncategorized";
133
- byCategory[category] = (byCategory[category] ?? 0) + 1;
134
- }
135
- return {
136
- total: marketplace.plugins.length,
137
- byCategory
138
- };
139
- }
140
-
141
- // src/cli/commands/build/marketplace.ts
142
28
  var DEFAULT_PLUGINS_DIR = "dist/plugins";
143
29
  var DEFAULT_OUTPUT_FILE = `${PLUGIN_MANIFEST_DIR}/marketplace.json`;
144
30
  var DEFAULT_DESCRIPTION = "Community skills and stacks for Claude Code";
@@ -195,8 +81,8 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
195
81
  const { flags } = await this.parse(_BuildMarketplace);
196
82
  setVerbose(flags.verbose);
197
83
  const projectRoot = process.cwd();
198
- const pluginsDir = path2.resolve(projectRoot, flags["plugins-dir"]);
199
- const outputPath = path2.resolve(projectRoot, flags.output);
84
+ const pluginsDir = path.resolve(projectRoot, flags["plugins-dir"]);
85
+ const outputPath = path.resolve(projectRoot, flags.output);
200
86
  this.log("");
201
87
  this.log("Generating marketplace.json");
202
88
  this.log(` Plugins directory: ${pluginsDir}`);
@@ -216,7 +102,7 @@ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
216
102
  this.log(`Found ${stats.total} plugins`);
217
103
  this.log("");
218
104
  this.log("Category breakdown:");
219
- const sortedCategories = sortBy2(Object.entries(stats.byCategory), ([, count]) => -count);
105
+ const sortedCategories = sortBy(Object.entries(stats.byCategory), ([, count]) => -count);
220
106
  for (const [category, count] of sortedCategories) {
221
107
  this.log(` ${category}: ${count}`);
222
108
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/commands/build/marketplace.ts","../../../src/cli/lib/marketplace-generator.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../../base-command\";\nimport { setVerbose } from \"../../utils/logger\";\nimport {\n generateMarketplace,\n writeMarketplace,\n getMarketplaceStats,\n} from \"../../lib/marketplace-generator\";\nimport {\n DEFAULT_BRANDING,\n DEFAULT_PLUGIN_NAME,\n DEFAULT_VERSION,\n PLUGIN_MANIFEST_DIR,\n} from \"../../consts\";\n\nconst DEFAULT_PLUGINS_DIR = \"dist/plugins\";\nconst DEFAULT_OUTPUT_FILE = `${PLUGIN_MANIFEST_DIR}/marketplace.json`;\nconst DEFAULT_DESCRIPTION = \"Community skills and stacks for Claude Code\";\nconst DEFAULT_OWNER_NAME = DEFAULT_BRANDING.NAME;\nconst DEFAULT_OWNER_EMAIL = `hello@${DEFAULT_PLUGIN_NAME}.com`;\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.\";\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --plugins-dir dist/stacks\",\n \"<%= config.bin %> <%= command.id %> --output .claude-plugin/market.json\",\n \"<%= config.bin %> <%= command.id %> --name my-marketplace --version 2.0.0\",\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n \"plugins-dir\": Flags.string({\n char: \"p\",\n description: \"Plugins directory\",\n default: DEFAULT_PLUGINS_DIR,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output file\",\n default: DEFAULT_OUTPUT_FILE,\n }),\n name: Flags.string({\n description: \"Marketplace name\",\n default: DEFAULT_PLUGIN_NAME,\n }),\n version: Flags.string({\n description: \"Marketplace version\",\n default: DEFAULT_VERSION,\n }),\n description: Flags.string({\n description: \"Marketplace description\",\n default: DEFAULT_DESCRIPTION,\n }),\n \"owner-name\": Flags.string({\n description: \"Owner name\",\n default: DEFAULT_OWNER_NAME,\n }),\n \"owner-email\": Flags.string({\n description: \"Owner email\",\n default: DEFAULT_OWNER_EMAIL,\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\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\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 try {\n this.log(\"Scanning plugins...\");\n\n const marketplace = await generateMarketplace(pluginsDir, {\n name: flags.name,\n version: flags.version,\n description: flags.description,\n ownerName: flags[\"owner-name\"],\n ownerEmail: flags[\"owner-email\"],\n pluginRoot: `./${flags[\"plugins-dir\"]}`,\n });\n\n const stats = getMarketplaceStats(marketplace);\n this.log(`Found ${stats.total} plugins`);\n\n this.log(\"\");\n this.log(\"Category breakdown:\");\n const sortedCategories = sortBy(Object.entries(stats.byCategory), ([, count]) => -count);\n for (const [category, count] of sortedCategories) {\n this.log(` ${category}: ${count}`);\n }\n\n this.log(\"Writing marketplace.json...\");\n await writeMarketplace(outputPath, marketplace);\n this.log(`Wrote ${outputPath}`);\n\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 this.log(\"\");\n this.logSuccess(`Marketplace generated with ${stats.total} plugins!`);\n this.log(\"\");\n } catch (error) {\n this.log(\"Generation failed\");\n this.handleError(error);\n }\n }\n}\n","import path from \"path\";\nimport { sortBy } from \"remeda\";\n\nimport { MAX_PLUGIN_FILE_SIZE } from \"../consts\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { readFileSafe, writeFile, glob, ensureDir } from \"../utils/fs\";\nimport { verbose, warn } from \"../utils/logger\";\nimport type { Marketplace, MarketplacePlugin, PluginManifest } from \"../types\";\nimport { pluginManifestSchema } from \"./schemas\";\n\nconst PLUGIN_MANIFEST_PATH = \".claude-plugin/plugin.json\";\nconst MARKETPLACE_SCHEMA_URL = \"https://anthropic.com/claude-code/marketplace.schema.json\";\n\n/**\n * Category patterns for marketplace plugins.\n *\n * Plugin names match skill IDs directly (e.g., \"web-framework-react\").\n * The category is the first segment of the ID:\n * - web-* -> web\n * - api-* -> api\n * - cli-* -> cli\n * - meta-* -> methodology\n * - infra-* -> infra\n * - mobile-* -> mobile\n * - security-* -> security\n */\nconst CATEGORY_PATTERNS: Array<{ pattern: RegExp; category: string }> = [\n { pattern: /^web-/, category: \"web\" },\n { pattern: /^api-/, category: \"api\" },\n { pattern: /^cli-/, category: \"cli\" },\n { pattern: /^meta-/, category: \"methodology\" },\n { pattern: /^infra-/, category: \"infra\" },\n { pattern: /^mobile-/, category: \"mobile\" },\n { pattern: /^security-/, category: \"security\" },\n];\n\ntype MarketplaceOptions = {\n name: string;\n version?: string;\n description?: string;\n ownerName: string;\n ownerEmail?: string;\n pluginRoot: string;\n};\n\nfunction inferCategoryFromPluginName(pluginName: string): string | undefined {\n for (const { pattern, category } of CATEGORY_PATTERNS) {\n if (pattern.test(pluginName)) {\n return category;\n }\n }\n return undefined;\n}\n\nasync function readPluginManifest(pluginDir: string): Promise<PluginManifest | null> {\n const manifestPath = path.join(pluginDir, PLUGIN_MANIFEST_PATH);\n\n try {\n const content = await readFileSafe(manifestPath, MAX_PLUGIN_FILE_SIZE);\n return pluginManifestSchema.parse(JSON.parse(content));\n } catch (error) {\n verbose(`Failed to read plugin manifest at '${manifestPath}': ${getErrorMessage(error)}`);\n return null;\n }\n}\n\nfunction convertManifestToMarketplacePlugin(\n manifest: PluginManifest,\n pluginRoot: string,\n pluginDirName: string,\n): MarketplacePlugin {\n const category = inferCategoryFromPluginName(manifest.name);\n\n const plugin: MarketplacePlugin = {\n name: manifest.name,\n source: `./${pluginRoot}/${pluginDirName}`,\n description: manifest.description,\n version: manifest.version,\n author: manifest.author,\n keywords: manifest.keywords,\n };\n\n if (category) {\n plugin.category = category;\n }\n\n return plugin;\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 pluginDirName = manifestFile.split(\"/\")[0];\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 const marketplace: Marketplace = {\n $schema: MARKETPLACE_SCHEMA_URL,\n name: options.name,\n version: options.version ?? \"1.0.0\",\n owner: {\n name: options.ownerName,\n },\n metadata: {\n pluginRoot: options.pluginRoot,\n },\n plugins: sortedPlugins,\n };\n\n if (options.description) {\n marketplace.description = options.description;\n }\n\n if (options.ownerEmail) {\n marketplace.owner.email = options.ownerEmail;\n }\n\n return marketplace;\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 const byCategory: Record<string, number> = {};\n\n for (const plugin of marketplace.plugins) {\n const category = plugin.category ?? \"uncategorized\";\n byCategory[category] = (byCategory[category] ?? 0) + 1;\n }\n\n return {\n total: marketplace.plugins.length,\n byCategory,\n };\n}\n"],"mappings":"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","names":["path","sortBy","path","sortBy"]}
1
+ {"version":3,"sources":["../../../src/cli/commands/build/marketplace.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../../base-command\";\nimport { setVerbose } from \"../../utils/logger\";\nimport {\n generateMarketplace,\n writeMarketplace,\n getMarketplaceStats,\n} from \"../../lib/marketplace-generator\";\nimport {\n DEFAULT_BRANDING,\n DEFAULT_PLUGIN_NAME,\n DEFAULT_VERSION,\n PLUGIN_MANIFEST_DIR,\n} from \"../../consts\";\n\nconst DEFAULT_PLUGINS_DIR = \"dist/plugins\";\nconst DEFAULT_OUTPUT_FILE = `${PLUGIN_MANIFEST_DIR}/marketplace.json`;\nconst DEFAULT_DESCRIPTION = \"Community skills and stacks for Claude Code\";\nconst DEFAULT_OWNER_NAME = DEFAULT_BRANDING.NAME;\nconst DEFAULT_OWNER_EMAIL = `hello@${DEFAULT_PLUGIN_NAME}.com`;\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.\";\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --plugins-dir dist/stacks\",\n \"<%= config.bin %> <%= command.id %> --output .claude-plugin/market.json\",\n \"<%= config.bin %> <%= command.id %> --name my-marketplace --version 2.0.0\",\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n \"plugins-dir\": Flags.string({\n char: \"p\",\n description: \"Plugins directory\",\n default: DEFAULT_PLUGINS_DIR,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output file\",\n default: DEFAULT_OUTPUT_FILE,\n }),\n name: Flags.string({\n description: \"Marketplace name\",\n default: DEFAULT_PLUGIN_NAME,\n }),\n version: Flags.string({\n description: \"Marketplace version\",\n default: DEFAULT_VERSION,\n }),\n description: Flags.string({\n description: \"Marketplace description\",\n default: DEFAULT_DESCRIPTION,\n }),\n \"owner-name\": Flags.string({\n description: \"Owner name\",\n default: DEFAULT_OWNER_NAME,\n }),\n \"owner-email\": Flags.string({\n description: \"Owner email\",\n default: DEFAULT_OWNER_EMAIL,\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\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\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 try {\n this.log(\"Scanning plugins...\");\n\n const marketplace = await generateMarketplace(pluginsDir, {\n name: flags.name,\n version: flags.version,\n description: flags.description,\n ownerName: flags[\"owner-name\"],\n ownerEmail: flags[\"owner-email\"],\n pluginRoot: `./${flags[\"plugins-dir\"]}`,\n });\n\n const stats = getMarketplaceStats(marketplace);\n this.log(`Found ${stats.total} plugins`);\n\n this.log(\"\");\n this.log(\"Category breakdown:\");\n const sortedCategories = sortBy(Object.entries(stats.byCategory), ([, count]) => -count);\n for (const [category, count] of sortedCategories) {\n this.log(` ${category}: ${count}`);\n }\n\n this.log(\"Writing marketplace.json...\");\n await writeMarketplace(outputPath, marketplace);\n this.log(`Wrote ${outputPath}`);\n\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 this.log(\"\");\n this.logSuccess(`Marketplace generated with ${stats.total} plugins!`);\n this.log(\"\");\n } catch (error) {\n this.log(\"Generation failed\");\n this.handleError(error);\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -2,22 +2,22 @@
2
2
  import {
3
3
  compileAllAgentPlugins,
4
4
  printAgentCompilationSummary
5
- } from "../../chunk-SYGEV3KV.js";
5
+ } from "../../chunk-JTTTXGHX.js";
6
6
  import {
7
7
  BaseCommand
8
- } from "../../chunk-SRFNNOLC.js";
8
+ } from "../../chunk-LNA6M2IE.js";
9
9
  import {
10
10
  compileAllSkillPlugins,
11
11
  compileSkillPlugin,
12
12
  printCompilationSummary
13
- } from "../../chunk-ZECXM7LP.js";
13
+ } from "../../chunk-GFDGYQ6M.js";
14
14
  import "../../chunk-T4EXUIBY.js";
15
15
  import {
16
16
  setVerbose
17
- } from "../../chunk-473YHDYQ.js";
17
+ } from "../../chunk-C4QI54PN.js";
18
18
  import {
19
19
  DIRS
20
- } from "../../chunk-FVN5PFFY.js";
20
+ } from "../../chunk-FTD5Z6QD.js";
21
21
  import {
22
22
  init_esm_shims
23
23
  } from "../../chunk-DHET7RCE.js";
@@ -1,23 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getAgentDefinitions
4
- } from "../../chunk-SYGEV3KV.js";
4
+ } from "../../chunk-JTTTXGHX.js";
5
5
  import {
6
6
  BaseCommand,
7
7
  EXIT_CODES
8
- } from "../../chunk-SRFNNOLC.js";
8
+ } from "../../chunk-LNA6M2IE.js";
9
9
  import {
10
10
  compileStackPlugin,
11
11
  loadStacks,
12
12
  printStackCompilationSummary
13
- } from "../../chunk-ZECXM7LP.js";
13
+ } from "../../chunk-GFDGYQ6M.js";
14
14
  import "../../chunk-T4EXUIBY.js";
15
15
  import {
16
16
  setVerbose
17
- } from "../../chunk-473YHDYQ.js";
17
+ } from "../../chunk-C4QI54PN.js";
18
18
  import {
19
19
  PROJECT_ROOT
20
- } from "../../chunk-FVN5PFFY.js";
20
+ } from "../../chunk-FTD5Z6QD.js";
21
21
  import {
22
22
  init_esm_shims
23
23
  } from "../../chunk-DHET7RCE.js";
@@ -2,18 +2,18 @@
2
2
  import {
3
3
  getAgentDefinitions,
4
4
  recompileAgents
5
- } from "../chunk-SYGEV3KV.js";
5
+ } from "../chunk-JTTTXGHX.js";
6
6
  import {
7
7
  DRY_RUN_MESSAGES,
8
8
  ERROR_MESSAGES,
9
9
  INFO_MESSAGES,
10
10
  STATUS_MESSAGES,
11
11
  SUCCESS_MESSAGES
12
- } from "../chunk-V43QDMYQ.js";
12
+ } from "../chunk-2RQYJFKA.js";
13
13
  import {
14
14
  BaseCommand,
15
15
  EXIT_CODES
16
- } from "../chunk-SRFNNOLC.js";
16
+ } from "../chunk-LNA6M2IE.js";
17
17
  import {
18
18
  detectInstallation,
19
19
  discoverAllPluginSkills,
@@ -21,7 +21,7 @@ import {
21
21
  normalizeStackRecord,
22
22
  parseFrontmatter,
23
23
  resolveSource
24
- } from "../chunk-ZECXM7LP.js";
24
+ } from "../chunk-GFDGYQ6M.js";
25
25
  import {
26
26
  typedEntries,
27
27
  typedKeys
@@ -36,12 +36,12 @@ import {
36
36
  setVerbose,
37
37
  verbose,
38
38
  warn
39
- } from "../chunk-473YHDYQ.js";
39
+ } from "../chunk-C4QI54PN.js";
40
40
  import {
41
41
  CLI_BIN_NAME,
42
42
  LOCAL_SKILLS_PATH,
43
43
  STANDARD_FILES
44
- } from "../chunk-FVN5PFFY.js";
44
+ } from "../chunk-FTD5Z6QD.js";
45
45
  import {
46
46
  init_esm_shims
47
47
  } from "../chunk-DHET7RCE.js";
@@ -2,15 +2,15 @@
2
2
  import {
3
3
  BaseCommand,
4
4
  EXIT_CODES
5
- } from "../../chunk-SRFNNOLC.js";
5
+ } from "../../chunk-LNA6M2IE.js";
6
6
  import {
7
7
  loadProjectSourceConfig,
8
8
  resolveAgentsSource,
9
9
  resolveSource
10
- } from "../../chunk-ZECXM7LP.js";
10
+ } from "../../chunk-GFDGYQ6M.js";
11
11
  import "../../chunk-T4EXUIBY.js";
12
- import "../../chunk-473YHDYQ.js";
13
- import "../../chunk-FVN5PFFY.js";
12
+ import "../../chunk-C4QI54PN.js";
13
+ import "../../chunk-FTD5Z6QD.js";
14
14
  import {
15
15
  init_esm_shims
16
16
  } from "../../chunk-DHET7RCE.js";
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigShow
4
- } from "../../chunk-M2XPTQDT.js";
5
- import "../../chunk-SRFNNOLC.js";
6
- import "../../chunk-ZECXM7LP.js";
4
+ } from "../../chunk-DC333ZDC.js";
5
+ import "../../chunk-LNA6M2IE.js";
6
+ import "../../chunk-GFDGYQ6M.js";
7
7
  import "../../chunk-T4EXUIBY.js";
8
- import "../../chunk-473YHDYQ.js";
9
- import "../../chunk-FVN5PFFY.js";
8
+ import "../../chunk-C4QI54PN.js";
9
+ import "../../chunk-FTD5Z6QD.js";
10
10
  import {
11
11
  init_esm_shims
12
12
  } from "../../chunk-DHET7RCE.js";
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  BaseCommand
4
- } from "../../chunk-SRFNNOLC.js";
4
+ } from "../../chunk-LNA6M2IE.js";
5
5
  import {
6
6
  getProjectConfigPath
7
- } from "../../chunk-ZECXM7LP.js";
7
+ } from "../../chunk-GFDGYQ6M.js";
8
8
  import "../../chunk-T4EXUIBY.js";
9
- import "../../chunk-473YHDYQ.js";
10
- import "../../chunk-FVN5PFFY.js";
9
+ import "../../chunk-C4QI54PN.js";
10
+ import "../../chunk-FTD5Z6QD.js";
11
11
  import {
12
12
  init_esm_shims
13
13
  } from "../../chunk-DHET7RCE.js";