agents-inc 0.156.0 → 0.158.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/{chunk-4A4L3YIW.js → chunk-2PN4QXON.js} +6 -7
  3. package/dist/chunk-2PN4QXON.js.map +1 -0
  4. package/dist/{chunk-QWVXOCXO.js → chunk-3NBXQSW2.js} +7 -9
  5. package/dist/{chunk-QWVXOCXO.js.map → chunk-3NBXQSW2.js.map} +1 -1
  6. package/dist/{chunk-WCAUUBHO.js → chunk-3PJLLBUS.js} +14597 -14536
  7. package/dist/chunk-3PJLLBUS.js.map +1 -0
  8. package/dist/{chunk-6RLV45HN.js → chunk-3Q2N7CSY.js} +6 -6
  9. package/dist/chunk-3Q2N7CSY.js.map +1 -0
  10. package/dist/{chunk-LJCNUP6M.js → chunk-4ABNXKAR.js} +2 -2
  11. package/dist/{chunk-D2CAV7MG.js → chunk-4DMFK67G.js} +2 -2
  12. package/dist/{chunk-MO5FGLVS.js → chunk-54QLV3OH.js} +11 -12
  13. package/dist/chunk-54QLV3OH.js.map +1 -0
  14. package/dist/{chunk-5F2YR5XV.js → chunk-6DBE562W.js} +15 -5
  15. package/dist/chunk-6DBE562W.js.map +1 -0
  16. package/dist/{chunk-RWOYPOMR.js → chunk-7Z4N4JWQ.js} +19 -245
  17. package/dist/chunk-7Z4N4JWQ.js.map +1 -0
  18. package/dist/{chunk-H6UTKTLK.js → chunk-DAUY2SB3.js} +98 -34
  19. package/dist/chunk-DAUY2SB3.js.map +1 -0
  20. package/dist/{chunk-2H7UWE2G.js → chunk-DP6YQFVO.js} +13 -12
  21. package/dist/chunk-DP6YQFVO.js.map +1 -0
  22. package/dist/{chunk-ILUVL7WM.js → chunk-DZD25NHW.js} +2 -2
  23. package/dist/{chunk-PCC4LBKB.js → chunk-EEAX7E2X.js} +2 -2
  24. package/dist/{chunk-IO5YBKHV.js → chunk-G6G2FT2G.js} +10 -8
  25. package/dist/chunk-G6G2FT2G.js.map +1 -0
  26. package/dist/{chunk-5QZAK6J7.js → chunk-H25VRR2T.js} +50 -18
  27. package/dist/chunk-H25VRR2T.js.map +1 -0
  28. package/dist/chunk-H2DHTJKW.js +1352 -0
  29. package/dist/chunk-H2DHTJKW.js.map +1 -0
  30. package/dist/{chunk-MHRC3KRX.js → chunk-H4CL23HG.js} +3 -3
  31. package/dist/chunk-H4CL23HG.js.map +1 -0
  32. package/dist/{chunk-F5T6TV4Z.js → chunk-IK6YOXZH.js} +40 -14
  33. package/dist/chunk-IK6YOXZH.js.map +1 -0
  34. package/dist/{chunk-HG4JPXJT.js → chunk-JG3B47P3.js} +23 -10
  35. package/dist/chunk-JG3B47P3.js.map +1 -0
  36. package/dist/{chunk-SY4X2LND.js → chunk-KUZBMEWR.js} +3 -3
  37. package/dist/{chunk-5OKLCVM4.js → chunk-KVVXINCJ.js} +3 -3
  38. package/dist/{chunk-PNMM5HNX.js → chunk-L4FHSOL5.js} +9 -10
  39. package/dist/chunk-L4FHSOL5.js.map +1 -0
  40. package/dist/{chunk-PMUABBPG.js → chunk-LKI3ENGQ.js} +9 -13
  41. package/dist/chunk-LKI3ENGQ.js.map +1 -0
  42. package/dist/{chunk-CLFHC2DK.js → chunk-OQB2CKBT.js} +17 -18
  43. package/dist/chunk-OQB2CKBT.js.map +1 -0
  44. package/dist/{chunk-HXKOIWLU.js → chunk-P6OKOH62.js} +2 -6
  45. package/dist/chunk-P6OKOH62.js.map +1 -0
  46. package/dist/{chunk-TNGMF4UX.js → chunk-PNRLBPGS.js} +12 -12
  47. package/dist/chunk-PNRLBPGS.js.map +1 -0
  48. package/dist/{chunk-Y5Y7XHVU.js → chunk-PZNXBORZ.js} +4 -4
  49. package/dist/{chunk-HTYH7CKN.js → chunk-Q7CAE5NN.js} +3 -3
  50. package/dist/{chunk-G47TDUK3.js → chunk-QNAMXQKF.js} +2 -2
  51. package/dist/{chunk-GS2NZ3GD.js → chunk-SJ4T5YLG.js} +5 -5
  52. package/dist/chunk-SJ4T5YLG.js.map +1 -0
  53. package/dist/{chunk-UMH2YZKG.js → chunk-TPQ5M3BW.js} +4 -6
  54. package/dist/{chunk-UMH2YZKG.js.map → chunk-TPQ5M3BW.js.map} +1 -1
  55. package/dist/{chunk-4G2YHZIM.js → chunk-TUXXBEBB.js} +4 -6
  56. package/dist/{chunk-4G2YHZIM.js.map → chunk-TUXXBEBB.js.map} +1 -1
  57. package/dist/{chunk-WFRTHH3A.js → chunk-TZRXWFF5.js} +3 -3
  58. package/dist/{chunk-TBOVYLQJ.js → chunk-VTIDLRNA.js} +2 -2
  59. package/dist/{chunk-OKH64JZE.js → chunk-WCZNQECQ.js} +2 -2
  60. package/dist/{chunk-ZUAZHDKP.js → chunk-WMVOJY6V.js} +277 -40
  61. package/dist/chunk-WMVOJY6V.js.map +1 -0
  62. package/dist/{chunk-YO2LTXB4.js → chunk-X52QUV4U.js} +115 -10
  63. package/dist/chunk-X52QUV4U.js.map +1 -0
  64. package/dist/{chunk-IXRZAHZF.js → chunk-XNYHMRVJ.js} +4 -4
  65. package/dist/{chunk-VPASBA7P.js → chunk-YXI3BTQQ.js} +2 -2
  66. package/dist/commands/build/marketplace.js +9 -12
  67. package/dist/commands/build/marketplace.js.map +1 -1
  68. package/dist/commands/build/plugins.js +9 -12
  69. package/dist/commands/build/plugins.js.map +1 -1
  70. package/dist/commands/compile.js +15 -19
  71. package/dist/commands/compile.js.map +1 -1
  72. package/dist/commands/doctor.js +75 -54
  73. package/dist/commands/doctor.js.map +1 -1
  74. package/dist/commands/edit.js +154 -109
  75. package/dist/commands/edit.js.map +1 -1
  76. package/dist/commands/eject.js +68 -38
  77. package/dist/commands/eject.js.map +1 -1
  78. package/dist/commands/init.js +36 -39
  79. package/dist/commands/list.js +8 -10
  80. package/dist/commands/list.js.map +1 -1
  81. package/dist/commands/new/marketplace.js +8 -11
  82. package/dist/commands/new/marketplace.js.map +1 -1
  83. package/dist/commands/search.js +10 -13
  84. package/dist/commands/search.js.map +1 -1
  85. package/dist/commands/share.js +8 -10
  86. package/dist/commands/share.js.map +1 -1
  87. package/dist/commands/uninstall.js +39 -28
  88. package/dist/commands/uninstall.js.map +1 -1
  89. package/dist/commands/update.js +7 -10
  90. package/dist/commands/update.js.map +1 -1
  91. package/dist/components/common/removal-plan-confirm.js +2 -2
  92. package/dist/components/common/select-list.js +2 -2
  93. package/dist/components/wizard/category-grid.js +4 -5
  94. package/dist/components/wizard/checkbox-grid.js +4 -4
  95. package/dist/components/wizard/domain-selection.js +9 -11
  96. package/dist/components/wizard/run-wizard-session.js +26 -28
  97. package/dist/components/wizard/scroll-affordance.js +2 -2
  98. package/dist/components/wizard/skill-agent-summary.js +5 -7
  99. package/dist/components/wizard/source-grid.js +5 -6
  100. package/dist/components/wizard/stack-selection.js +7 -9
  101. package/dist/components/wizard/step-agents.js +8 -10
  102. package/dist/components/wizard/step-build.js +7 -9
  103. package/dist/components/wizard/step-confirm.js +9 -11
  104. package/dist/components/wizard/step-sources.js +8 -10
  105. package/dist/components/wizard/step-stack.js +8 -10
  106. package/dist/components/wizard/summary-panel.js +8 -10
  107. package/dist/components/wizard/toast.js +2 -2
  108. package/dist/components/wizard/wizard-layout.js +12 -14
  109. package/dist/components/wizard/wizard-tabs.js +2 -4
  110. package/dist/components/wizard/wizard.js +25 -27
  111. package/dist/hooks/init.js +36 -39
  112. package/dist/hooks/init.js.map +1 -1
  113. package/dist/load-agent-defs-2VYAV5GL.js +13 -0
  114. package/dist/recompile-project-agents-NG5DCPHJ.js +17 -0
  115. package/dist/{source-loader-3DL3NYUX.js → source-loader-CO2FZ3OO.js} +4 -8
  116. package/dist/src/agents/_templates/agent.liquid +2 -2
  117. package/dist/stores/wizard-store.js +6 -6
  118. package/package.json +2 -4
  119. package/src/agents/_templates/agent.liquid +2 -2
  120. package/src/schemas/custom-metadata.schema.json +1 -1
  121. package/src/schemas/marketplace.schema.json +2 -1
  122. package/dist/chunk-2H7UWE2G.js.map +0 -1
  123. package/dist/chunk-4A4L3YIW.js.map +0 -1
  124. package/dist/chunk-5F2YR5XV.js.map +0 -1
  125. package/dist/chunk-5QZAK6J7.js.map +0 -1
  126. package/dist/chunk-6RLV45HN.js.map +0 -1
  127. package/dist/chunk-CLFHC2DK.js.map +0 -1
  128. package/dist/chunk-F2AMBBIA.js +0 -64
  129. package/dist/chunk-F2AMBBIA.js.map +0 -1
  130. package/dist/chunk-F5T6TV4Z.js.map +0 -1
  131. package/dist/chunk-GS2NZ3GD.js.map +0 -1
  132. package/dist/chunk-H6UTKTLK.js.map +0 -1
  133. package/dist/chunk-HG4JPXJT.js.map +0 -1
  134. package/dist/chunk-HXKOIWLU.js.map +0 -1
  135. package/dist/chunk-IO5YBKHV.js.map +0 -1
  136. package/dist/chunk-MHRC3KRX.js.map +0 -1
  137. package/dist/chunk-MO5FGLVS.js.map +0 -1
  138. package/dist/chunk-PMUABBPG.js.map +0 -1
  139. package/dist/chunk-PNMM5HNX.js.map +0 -1
  140. package/dist/chunk-RWOYPOMR.js.map +0 -1
  141. package/dist/chunk-TNGMF4UX.js.map +0 -1
  142. package/dist/chunk-VASLW636.js +0 -23
  143. package/dist/chunk-VASLW636.js.map +0 -1
  144. package/dist/chunk-WCAUUBHO.js.map +0 -1
  145. package/dist/chunk-WUQ3MTPF.js +0 -173
  146. package/dist/chunk-WUQ3MTPF.js.map +0 -1
  147. package/dist/chunk-XAXJWXI4.js +0 -1667
  148. package/dist/chunk-XAXJWXI4.js.map +0 -1
  149. package/dist/chunk-YO2LTXB4.js.map +0 -1
  150. package/dist/chunk-ZUAZHDKP.js.map +0 -1
  151. package/dist/copy-local-skills-NSUTBVLJ.js +0 -14
  152. package/dist/load-agent-defs-X4E57I2U.js +0 -15
  153. package/dist/loader-G6BFG2VA.js +0 -24
  154. package/dist/recompile-project-agents-JE4MM72I.js +0 -20
  155. package/dist/recompile-project-agents-JE4MM72I.js.map +0 -1
  156. package/dist/source-loader-3DL3NYUX.js.map +0 -1
  157. /package/dist/{chunk-LJCNUP6M.js.map → chunk-4ABNXKAR.js.map} +0 -0
  158. /package/dist/{chunk-D2CAV7MG.js.map → chunk-4DMFK67G.js.map} +0 -0
  159. /package/dist/{chunk-ILUVL7WM.js.map → chunk-DZD25NHW.js.map} +0 -0
  160. /package/dist/{chunk-PCC4LBKB.js.map → chunk-EEAX7E2X.js.map} +0 -0
  161. /package/dist/{chunk-SY4X2LND.js.map → chunk-KUZBMEWR.js.map} +0 -0
  162. /package/dist/{chunk-5OKLCVM4.js.map → chunk-KVVXINCJ.js.map} +0 -0
  163. /package/dist/{chunk-Y5Y7XHVU.js.map → chunk-PZNXBORZ.js.map} +0 -0
  164. /package/dist/{chunk-HTYH7CKN.js.map → chunk-Q7CAE5NN.js.map} +0 -0
  165. /package/dist/{chunk-G47TDUK3.js.map → chunk-QNAMXQKF.js.map} +0 -0
  166. /package/dist/{chunk-WFRTHH3A.js.map → chunk-TZRXWFF5.js.map} +0 -0
  167. /package/dist/{chunk-TBOVYLQJ.js.map → chunk-VTIDLRNA.js.map} +0 -0
  168. /package/dist/{chunk-OKH64JZE.js.map → chunk-WCZNQECQ.js.map} +0 -0
  169. /package/dist/{chunk-IXRZAHZF.js.map → chunk-XNYHMRVJ.js.map} +0 -0
  170. /package/dist/{chunk-VPASBA7P.js.map → chunk-YXI3BTQQ.js.map} +0 -0
  171. /package/dist/{copy-local-skills-NSUTBVLJ.js.map → load-agent-defs-2VYAV5GL.js.map} +0 -0
  172. /package/dist/{load-agent-defs-X4E57I2U.js.map → recompile-project-agents-NG5DCPHJ.js.map} +0 -0
  173. /package/dist/{loader-G6BFG2VA.js.map → source-loader-CO2FZ3OO.js.map} +0 -0
@@ -1,26 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ScrollAffordance
4
- } from "./chunk-VPASBA7P.js";
4
+ } from "./chunk-YXI3BTQQ.js";
5
5
  import {
6
6
  getStackName
7
- } from "./chunk-5OKLCVM4.js";
7
+ } from "./chunk-KVVXINCJ.js";
8
8
  import {
9
9
  useMeasuredHeight
10
10
  } from "./chunk-TSIU7DME.js";
11
11
  import {
12
12
  SkillAgentSummary
13
- } from "./chunk-Y5Y7XHVU.js";
13
+ } from "./chunk-PZNXBORZ.js";
14
14
  import {
15
15
  useWizardStore
16
- } from "./chunk-F5T6TV4Z.js";
16
+ } from "./chunk-IK6YOXZH.js";
17
17
  import {
18
18
  ALL_SKILLS_EJECTED_LABEL,
19
19
  CLI_COLORS,
20
20
  DEFAULT_PUBLIC_SOURCE_NAME,
21
21
  EJECT_SOURCE,
22
22
  formatSourceDisplayName
23
- } from "./chunk-IO5YBKHV.js";
23
+ } from "./chunk-G6G2FT2G.js";
24
24
 
25
25
  // src/cli/components/wizard/summary-panel.tsx
26
26
  import { Box, Text } from "ink";
@@ -121,4 +121,4 @@ var SummaryPanel = () => {
121
121
  export {
122
122
  SummaryPanel
123
123
  };
124
- //# sourceMappingURL=chunk-6RLV45HN.js.map
124
+ //# sourceMappingURL=chunk-3Q2N7CSY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/summary-panel.tsx","../src/cli/components/hooks/use-panel-scroll.ts"],"sourcesContent":["import { Box, Text } from \"ink\";\nimport React from \"react\";\nimport { unique } from \"remeda\";\nimport {\n ALL_SKILLS_EJECTED_LABEL,\n CLI_COLORS,\n DEFAULT_PUBLIC_SOURCE_NAME,\n EJECT_SOURCE,\n formatSourceDisplayName,\n} from \"../../consts.js\";\nimport { useWizardStore } from \"../../stores/wizard-store.js\";\nimport type { SkillConfig } from \"../../types/config.js\";\nimport { usePanelScroll } from \"../hooks/use-panel-scroll.js\";\nimport { ScrollAffordance } from \"./scroll-affordance.js\";\nimport { SkillAgentSummary } from \"./skill-agent-summary.js\";\nimport { getStackName } from \"./utils.js\";\n\n/**\n * The Marketplace row's value: the distinct marketplaces the summarised skills come from.\n *\n * `SkillConfig.origin` is authoritative for where a skill came from, and holds exactly one\n * of two things: {@link EJECT_SOURCE}, meaning the files were copied locally, or the marketplace's\n * own name as its `marketplace.json` declares it — which is why a project initialised from a\n * different marketplace names that marketplace here without any extra plumbing.\n *\n * Three cases, and the two zero-marketplace ones are NOT the same state:\n * - **No skills at all.** Reachable — the `I` overlay opens from the stack step before anything is\n * selected. Nothing is claimed yet, so the default public marketplace stands in.\n * - **Skills, but every one ejected.** \"eject\" names no marketplace, so there is none to list;\n * naming the default would assert an origin none of those skills has.\n * - **Any marketplace-sourced skill.** Its marketplace is named. Ejected siblings contribute no\n * name but do not suppress the ones that do.\n *\n * Tombstoned (`excluded`) entries count. One still records a real global install and the\n * marketplace it came from, and `computeScopeDiff` renders it as a row in the summary below, so\n * dropping it here would leave the header disowning a row it sits above.\n *\n * Sorted, so the row cannot reorder between renders on config iteration order alone.\n */\nfunction formatSkillMarketplaces(skillConfigs: SkillConfig[]): string {\n if (skillConfigs.length === 0) return formatSourceDisplayName(DEFAULT_PUBLIC_SOURCE_NAME);\n\n const marketplaceNames = unique(\n skillConfigs.map((config) => config.origin).filter((origin) => origin !== EJECT_SOURCE),\n );\n if (marketplaceNames.length === 0) return ALL_SKILLS_EJECTED_LABEL;\n\n return marketplaceNames\n .map((name) => formatSourceDisplayName(name))\n .sort()\n .join(\" · \");\n}\n\ntype PanelHeaderProps = {\n sourceNames: string;\n stackName: string | undefined;\n};\n\n/**\n * Which marketplaces and which stack the summary below was built from.\n *\n * Rendered inside the scrolled content, so its `marginBottom` scrolls away\n * rather than permanently costing the viewport a row.\n *\n * `flexShrink={0}` is load-bearing: Ink defaults every box to `flexShrink: 1`,\n * so on a short terminal Yoga squeezes this block to fit instead of letting the\n * viewport clip it, and the Marketplace and Stack rows overprint into one\n * unreadable line. Clipping is the panel's job; the header must keep its height.\n */\nconst PanelHeader: React.FC<PanelHeaderProps> = ({ sourceNames, stackName }) => (\n <Box\n flexDirection=\"column\"\n flexShrink={0}\n borderStyle=\"single\"\n borderBottom={true}\n borderTop={false}\n borderLeft={false}\n borderRight={false}\n borderColor={CLI_COLORS.NEUTRAL}\n borderBottomDimColor\n paddingBottom={1}\n marginBottom={1}\n >\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Marketplace\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{sourceNames}</Text>\n </Box>\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Stack\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{stackName ?? \"none\"}</Text>\n </Box>\n </Box>\n);\n\n/**\n * Marketplace/stack header above a clipped, arrow-scrollable\n * `SkillAgentSummary` — the one panel both summary surfaces render: the `I`\n * overlay in `wizard-layout.tsx` and the confirm step.\n *\n * It owns the `↑`/`↓` keys through `usePanelScroll`. A host that needs other\n * keys adds its own `useInput` alongside it — `StepConfirm` claims `Enter` and\n * `Esc` that way.\n *\n * Horizontal padding only. Vertical padding is unshrinkable, so on a short\n * terminal it claims the last row the viewport has and the content measures 0\n * before it has ever been laid out — the panel then paints neither a summary\n * row nor the affordance that would say rows are missing.\n */\nexport const SummaryPanel: React.FC = () => {\n const skillConfigs = useWizardStore((s) => s.skillConfigs);\n const agentConfigs = useWizardStore((s) => s.agentConfigs);\n const selectedStackId = useWizardStore((s) => s.selectedStackId);\n const { viewportRef, contentRef, contentMarginTop, hiddenAbove, hiddenBelow } = usePanelScroll();\n\n const sourceNames = formatSkillMarketplaces(skillConfigs);\n const stackName = getStackName(selectedStackId);\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n flexBasis={0}\n borderStyle=\"single\"\n borderColor={CLI_COLORS.NEUTRAL}\n paddingX={2}\n >\n <Box ref={viewportRef} flexDirection=\"column\" flexGrow={1} flexBasis={0} overflow=\"hidden\">\n <Box ref={contentRef} flexDirection=\"column\" flexShrink={0} marginTop={contentMarginTop}>\n <PanelHeader sourceNames={sourceNames} stackName={stackName} />\n\n <Box width=\"100%\">\n <SkillAgentSummary skillConfigs={skillConfigs} agentConfigs={agentConfigs} />\n </Box>\n </Box>\n </Box>\n <ScrollAffordance hiddenAbove={hiddenAbove} hiddenBelow={hiddenBelow} />\n </Box>\n );\n};\n","import { useEffect, useRef, useState } from \"react\";\nimport type { Ref, RefObject } from \"react\";\nimport { type DOMElement, measureElement, useInput } from \"ink\";\nimport { useMeasuredHeight } from \"./use-measured-height.js\";\n\nexport type UsePanelScrollResult = {\n /** Attach to the clipping box — the one with `overflow=\"hidden\"`. */\n viewportRef: Ref<DOMElement>;\n /** Attach to the scrolled content box inside the viewport. */\n contentRef: RefObject<DOMElement | null>;\n /** Apply as the content box's `marginTop`; negative by the number of lines scrolled off the top. */\n contentMarginTop: number;\n /** Content lines scrolled off the top of the viewport. */\n hiddenAbove: number;\n /** Content lines clipped below the viewport. */\n hiddenBelow: number;\n};\n\n/**\n * Line scrolling for a single clipped viewport, driven by the `↑`/`↓` keys.\n *\n * The caller renders viewport, content and a `ScrollAffordance` sibling; this\n * owns the offset those three agree on. Distinct from `useSectionScroll`, which\n * moves a viewport to follow focus across variable-height sections — here there\n * is no focus, only the arrow keys.\n *\n * A host that needs other keys adds its own `useInput` alongside it, on keys\n * disjoint from `↑`/`↓`.\n */\nexport function usePanelScroll(): UsePanelScrollResult {\n // Measured on the clipping box itself, inside the border and padding, so it\n // is the height the content actually gets.\n const { ref: viewportRef, measuredHeight: viewportHeight } = useMeasuredHeight();\n const contentRef = useRef<DOMElement>(null);\n const [contentHeight, setContentHeight] = useState(0);\n const [scrollOffset, setScrollOffset] = useState(0);\n\n // Ink's measurement idiom: re-measure on every render, no dependency array\n // on purpose. The setState inside is guarded to fire only when the measured\n // height actually changed, so the chain converges instead of looping — a\n // dependency array here would skip re-measures after layout changes React\n // cannot see.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => {\n if (!contentRef.current) return;\n const { height } = measureElement(contentRef.current);\n // Yoga under-reports a wrapped subtree measured inside a viewport too\n // short to lay it out, and reports 0 inside a zero-height one, so the\n // tallest reading is the trustworthy one. Believing a squeezed reading\n // would shrink the hidden-line count until the affordance disappeared,\n // which hands its row back and grows the count again — a render loop.\n setContentHeight((prev) => Math.max(prev, height));\n });\n\n // contentHeight only ever sizes the scroll range and the affordance count.\n // It must never gate the clip — which is why it is not returned: a viewport\n // that stops clipping when it looks too small grows to content height, which\n // makes it look big enough to stop clipping — a stable wrong answer that\n // paints the content over the border.\n const maxScroll = Math.max(0, contentHeight - viewportHeight);\n const hiddenBelow = Math.max(0, maxScroll - scrollOffset);\n\n useInput((_input, key) => {\n if (key.upArrow) setScrollOffset((prev) => Math.max(0, prev - 1));\n if (key.downArrow) setScrollOffset((prev) => Math.min(maxScroll, prev + 1));\n });\n\n return {\n viewportRef,\n contentRef,\n contentMarginTop: scrollOffset > 0 ? -scrollOffset : 0,\n hiddenAbove: scrollOffset,\n hiddenBelow,\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  SummaryPanel
4
- } from "./chunk-6RLV45HN.js";
4
+ } from "./chunk-3Q2N7CSY.js";
5
5
 
6
6
  // src/cli/components/wizard/step-confirm.tsx
7
7
  import { useInput } from "ink";
@@ -22,4 +22,4 @@ var StepConfirm = ({ onComplete, onBack }) => {
22
22
  export {
23
23
  StepConfirm
24
24
  };
25
- //# sourceMappingURL=chunk-LJCNUP6M.js.map
25
+ //# sourceMappingURL=chunk-4ABNXKAR.js.map
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-OZXAJNLA.js";
5
5
  import {
6
6
  CLI_COLORS
7
- } from "./chunk-IO5YBKHV.js";
7
+ } from "./chunk-G6G2FT2G.js";
8
8
 
9
9
  // src/cli/components/common/removal-plan-confirm.tsx
10
10
  import "react";
@@ -58,4 +58,4 @@ var RemovalPlanConfirm = ({
58
58
  export {
59
59
  RemovalPlanConfirm
60
60
  };
61
- //# sourceMappingURL=chunk-D2CAV7MG.js.map
61
+ //# sourceMappingURL=chunk-4DMFK67G.js.map
@@ -1,21 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  orderDomains
4
- } from "./chunk-F5T6TV4Z.js";
4
+ } from "./chunk-IK6YOXZH.js";
5
5
  import {
6
- DEFAULT_SELECTION_OPTIONS,
6
+ AGENT_NAMES,
7
7
  isScopePairCompatible,
8
+ seedAgentScope,
8
9
  validateSelection
9
- } from "./chunk-WCAUUBHO.js";
10
- import {
11
- AGENT_NAMES
12
- } from "./chunk-XAXJWXI4.js";
10
+ } from "./chunk-3PJLLBUS.js";
13
11
  import {
14
12
  getCategoryDomain
15
- } from "./chunk-RWOYPOMR.js";
13
+ } from "./chunk-7Z4N4JWQ.js";
16
14
  import {
17
15
  DEFAULT_PUBLIC_SOURCE_NAME
18
- } from "./chunk-IO5YBKHV.js";
16
+ } from "./chunk-G6G2FT2G.js";
19
17
 
20
18
  // src/cli/lib/seed/seed-to-wizard.ts
21
19
  var KNOWN_AGENTS = new Set(AGENT_NAMES);
@@ -46,9 +44,6 @@ function readAgentMap(agents) {
46
44
  }
47
45
  return { known, switchedOff, unknown };
48
46
  }
49
- function seedAgentScope(entry) {
50
- return entry?.scope ?? DEFAULT_SELECTION_OPTIONS.scope;
51
- }
52
47
  function agentScopeConfig(name, entry) {
53
48
  return {
54
49
  name,
@@ -116,6 +111,10 @@ function seedToWizardResult(payload, matrix) {
116
111
  agentConfigs: selectedAgents.map((name) => agentScopeConfig(name, agentMap.known.get(name))),
117
112
  assignedStack,
118
113
  selectedStackId: payload.stackId,
114
+ // Spread-conditional rather than passed through, because absent and present-holding-undefined
115
+ // are different files on disk: a config describing itself with no key is not one describing
116
+ // itself with an empty sentence, and the writer emits whichever key it is handed.
117
+ ...payload.description !== void 0 && { description: payload.description },
119
118
  domainSelections,
120
119
  selectedDomains: orderDomains(Object.keys(domainSelections)),
121
120
  // Nothing was dropped from a *saved config* — the skipped ids came off the wire and are
@@ -139,4 +138,4 @@ function seedToWizardResult(payload, matrix) {
139
138
  export {
140
139
  seedToWizardResult
141
140
  };
142
- //# sourceMappingURL=chunk-MO5FGLVS.js.map
141
+ //# sourceMappingURL=chunk-54QLV3OH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/lib/seed/seed-to-wizard.ts"],"sourcesContent":["import { seedAgentScope } from \"@workspace/matrix\";\n\nimport { AGENT_NAMES } from \"../../types/agents.js\";\nimport { DEFAULT_PUBLIC_SOURCE_NAME } from \"../../consts.js\";\nimport { isScopePairCompatible } from \"../configuration/config-generator.js\";\nimport { getCategoryDomain } from \"../matrix/matrix-provider.js\";\nimport { validateSelection } from \"../matrix/matrix-resolver.js\";\nimport { orderDomains } from \"../wizard/domain-order.js\";\n\nimport type { WizardResultV2 } from \"../../components/wizard/wizard.js\";\nimport type { AgentName } from \"../../types/agents.js\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config.js\";\nimport type {\n Category,\n Domain,\n DomainSelections,\n MergedSkillsMatrix,\n ResolvedSkill,\n} from \"../../types/matrix.js\";\nimport type { SkillAssignment, SkillId } from \"../../types/skills.js\";\nimport type { StackAgentConfig } from \"../../types/stacks.js\";\nimport type { SeedAgent, SeedLoadState, SeedPayload } from \"@workspace/matrix/seed\";\n\nexport type SeedMapping = {\n result: WizardResultV2;\n /** Ids this matrix does not know. Reported, never fatal — see the decode policy. */\n skippedSkillIds: string[];\n skippedAgentNames: string[];\n};\n\nconst KNOWN_AGENTS = new Set<string>(AGENT_NAMES);\n\n/** A skill's primary source, or the default marketplace. Mirrors the wizard's own resolution. */\nfunction sourceForSkill(skill: ResolvedSkill | undefined): string {\n return skill?.availableSources?.find((s) => s.primary)?.name ?? DEFAULT_PUBLIC_SOURCE_NAME;\n}\n\nfunction addToDomainSelections(\n selections: DomainSelections,\n domain: Domain,\n category: Category,\n skillId: SkillId,\n): void {\n const categorySelections = (selections[domain] ??= {});\n const skillList = (categorySelections[category] ??= []);\n if (!skillList.includes(skillId)) skillList.push(skillId);\n}\n\n/**\n * The stack mirror of {@link addToDomainSelections}: one sub-agent's own category lists, appended\n * in payload order. A `(skill, sub-agent)` pair can only occur once — `skills` is keyed by id — so\n * there is nothing to de-duplicate here.\n */\nfunction addToAgentStack(\n stack: Partial<Record<AgentName, StackAgentConfig>>,\n agent: AgentName,\n category: Category,\n assignment: SkillAssignment,\n): void {\n const agentStack = (stack[agent] ??= {});\n const assignments = (agentStack[category] ??= []);\n assignments.push(assignment);\n}\n\n/** A load state is per `(skill, sub-agent)`; `preloaded` is the stack's word for the same thing. */\nfunction toSkillAssignment(skillId: SkillId, load: SeedLoadState): SkillAssignment {\n return { id: skillId, preloaded: load === \"preloaded\" };\n}\n\n/** The payload's `agents` map, split by what this catalog can do with each entry. */\ntype SeedAgentMap = {\n /** Known agents the map has something to say about, keyed by name. */\n known: Map<AgentName, SeedAgent>;\n /** Names explicitly switched off — dropped, and their assignment rows ignored with them. */\n switchedOff: Set<string>;\n /** Names this catalog does not know. Reported, never fatal — same policy as unknown skill ids. */\n unknown: string[];\n};\n\nfunction readAgentMap(agents: SeedPayload[\"agents\"]): SeedAgentMap {\n const known = new Map<AgentName, SeedAgent>();\n const switchedOff = new Set<string>();\n const unknown: string[] = [];\n\n for (const [name, entry] of Object.entries(agents)) {\n if (!KNOWN_AGENTS.has(name)) unknown.push(name);\n else if (entry.on === false) switchedOff.add(name);\n else known.set(name as AgentName, entry);\n }\n\n return { known, switchedOff, unknown };\n}\n\n/**\n * A sub-agent's own row. Model and effort ride along on the same terms as its scope — an absent\n * key means \"keep whatever the agent's metadata says\".\n */\nfunction agentScopeConfig(name: AgentName, entry: SeedAgent | undefined): AgentScopeConfig {\n return {\n name,\n scope: seedAgentScope(entry),\n ...(entry?.model !== undefined && { model: entry.model }),\n ...(entry?.effort !== undefined && { effort: entry.effort }),\n };\n}\n\n/** A `(skill, sub-agent)` assignment the config model has nowhere to write. */\ntype UnwritableAssignment = { skillId: SkillId; agent: AgentName };\n\n/**\n * Names every unwritable pair, not just the first: a sharer who fixes one only to be refused for\n * the next learns nothing the first message could not have told them. Both halves of each pair are\n * named because neither alone says what to change — the skill can move to global scope, or the\n * sub-agent can be pinned to the project, and only the sharer knows which they meant.\n */\nfunction unwritableAssignmentsError(assignments: UnwritableAssignment[]): string {\n return [\n \"This configuration cannot be installed: a project-scoped skill never reaches a sub-agent \" +\n \"that rests at global scope, so these assignments have nowhere to be written:\",\n ...assignments.map(({ skillId, agent }) => ` ${skillId} -> ${agent}`),\n \"Re-share it with each sub-agent above pinned to the project, or each skill above at global scope.\",\n ].join(\"\\n\");\n}\n\n/**\n * Turns a shared configuration into the shape the install pipeline already consumes, so\n * `init --from` reuses `writeProjectConfig` -> skill install -> `compileAgentsAllScopes`\n * unchanged rather than growing a second path that can drift from the wizard's.\n *\n * Unknown ids are skipped, never fatal. Payloads carry catalog slugs precisely so they survive\n * catalog churn: a config shared before a skill was renamed should still install everything else,\n * and failing the whole decode would make every rename retroactively break every shared id.\n *\n * A sub-agent reaches the roster two ways: named by a surviving skill's assignment, or switched on\n * in the `agents` map. The map is the only place a configuration can say anything about an agent\n * no skill mentions, which is what makes a bare (skill-less) agent shareable at all; it also\n * carries that agent's model and effort onto its `AgentScopeConfig`.\n *\n * The `assignments` map is per `(skill, sub-agent)` and carries a load state, so it decides three\n * things the wizard cannot express separately: which sub-agents are selected, which skills land in\n * each one's stack entry, and which of those preload. That is why the result carries an\n * `assignedStack` — the install pipeline's ownership rules broadcast every scope-compatible skill\n * to every selected agent, which would hand a bare sub-agent someone else's skills.\n *\n * An unwritable `(skill, sub-agent)` pair is the one thing here that IS fatal, and it is fatal for\n * the opposite reason to the skips: an unknown id is content this catalog does not have, while an\n * unwritable pair is content it has and cannot place. Because `assignedStack` replaces the derived\n * stack wholesale, no scope filter runs on these rows downstream — they reach the writers, which\n * put them in neither half of the split config and say nothing. Refusing at the decode is what\n * keeps a payload from installing as a quieter configuration than the one that was shared.\n */\nexport function seedToWizardResult(payload: SeedPayload, matrix: MergedSkillsMatrix): SeedMapping {\n const domainSelections: DomainSelections = {};\n const assignedStack: Partial<Record<AgentName, StackAgentConfig>> = {};\n const skills: SkillConfig[] = [];\n const skippedSkillIds: string[] = [];\n const unwritable: UnwritableAssignment[] = [];\n const agentNames = new Set<AgentName>();\n const agentMap = readAgentMap(payload.agents);\n const skippedAgentNames = new Set<string>(agentMap.unknown);\n\n for (const [skillId, entry] of Object.entries(payload.skills)) {\n const skill = matrix.skills[skillId as SkillId];\n const domain = skill?.category ? getCategoryDomain(skill.category) : undefined;\n\n if (!skill?.category || !domain) {\n skippedSkillIds.push(skillId);\n continue;\n }\n\n // Past the guard the matrix knows this id, and its category is a real one: the `local`\n // pseudo-category has no domain, so it left with the skips.\n const id = skillId as SkillId;\n const category = skill.category as Category;\n\n addToDomainSelections(domainSelections, domain, category, id);\n\n skills.push({\n id,\n scope: entry.scope,\n // \"eject\" is an origin in its own right; anything else names the marketplace it came from.\n origin: entry.install === \"eject\" ? \"eject\" : sourceForSkill(skill),\n });\n\n // Only assignments on skills that survived — an agent should not be switched on by a skill\n // this catalog cannot install.\n for (const [agentName, load] of Object.entries(entry.assignments)) {\n if (agentMap.switchedOff.has(agentName)) continue;\n if (!KNOWN_AGENTS.has(agentName)) {\n skippedAgentNames.add(agentName);\n continue;\n }\n\n const agent = agentName as AgentName;\n // Rows the decode was going to ignore anyway have already left, so what reaches here is a\n // pair the payload really asked for — and the config model's one rule about pairs applies.\n if (!isScopePairCompatible(entry.scope, seedAgentScope(agentMap.known.get(agent)))) {\n unwritable.push({ skillId: id, agent });\n continue;\n }\n\n agentNames.add(agent);\n // The assignment is the curation: this sub-agent holds this skill, at this load state, and\n // no sub-agent the payload did not name holds it at all.\n addToAgentStack(assignedStack, agent, category, toSkillAssignment(id, load));\n }\n }\n\n if (unwritable.length > 0) throw new Error(unwritableAssignmentsError(unwritable));\n\n // Bare agents: switched on by the map alone, with no skill to carry them in.\n for (const [name, entry] of agentMap.known) {\n if (entry.on === true) agentNames.add(name);\n }\n\n const selectedAgents = [...agentNames];\n\n return {\n result: {\n skills,\n selectedAgents,\n agentConfigs: selectedAgents.map((name) => agentScopeConfig(name, agentMap.known.get(name))),\n assignedStack,\n selectedStackId: payload.stackId,\n // Spread-conditional rather than passed through, because absent and present-holding-undefined\n // are different files on disk: a config describing itself with no key is not one describing\n // itself with an empty sentence, and the writer emits whichever key it is handed.\n ...(payload.description !== undefined && { description: payload.description }),\n domainSelections,\n selectedDomains: orderDomains(Object.keys(domainSelections) as Domain[]),\n // Nothing was dropped from a *saved config* — the skipped ids came off the wire and are\n // reported to the user directly, so there is no config removal to explain.\n unresolvableSkillIds: [],\n cancelled: false,\n // Revalidated here rather than taken on trust from the app that built the payload. That app\n // validated against ITS catalog; this one skips ids it does not know and carries its own\n // relationship rules, so a configuration that was consistent where it was authored can\n // arrive with a requirement genuinely unmet. Running the same validator the wizard runs\n // makes that this catalog's verdict on what it can install — reported through the spine\n // `init` already has, beside the skips that explain it — rather than a fault in what was\n // shared.\n validation: validateSelection(skills.map((skill) => skill.id)),\n },\n skippedSkillIds,\n skippedAgentNames: [...skippedAgentNames],\n };\n}\n"],"mappings":"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","names":[]}
@@ -4,11 +4,12 @@ import {
4
4
  } from "./chunk-TSIU7DME.js";
5
5
  import {
6
6
  CategoryGrid
7
- } from "./chunk-4A4L3YIW.js";
7
+ } from "./chunk-2PN4QXON.js";
8
8
  import {
9
9
  buildCategoriesForDomain,
10
- useWizardStore
11
- } from "./chunk-F5T6TV4Z.js";
10
+ useWizardStore,
11
+ validateBuildStep
12
+ } from "./chunk-IK6YOXZH.js";
12
13
 
13
14
  // src/cli/components/wizard/step-build.tsx
14
15
  import { Box, useInput } from "ink";
@@ -42,6 +43,8 @@ var StepBuild = ({
42
43
  }) => {
43
44
  const { ref: gridRef, measuredHeight: gridHeight } = useMeasuredHeight();
44
45
  const skillConfigs = useWizardStore((s) => s.skillConfigs);
46
+ const setToastMessage = useWizardStore((s) => s.setToastMessage);
47
+ const activeDomainSelections = useWizardStore((s) => s.domainSelections[activeDomain]);
45
48
  const handleFocusedSkillChange = useCallback(
46
49
  (id) => useWizardStore.getState().setFocusedSkillId(id),
47
50
  []
@@ -63,9 +66,16 @@ var StepBuild = ({
63
66
  initialCol: focusedCategory.options.findIndex((o) => o.id === skillId)
64
67
  };
65
68
  }, [categories]);
69
+ const handleContinue = useCallback(() => {
70
+ const validation = validateBuildStep(categories, activeDomainSelections ?? {});
71
+ if (!validation.valid) {
72
+ setToastMessage(validation.message);
73
+ }
74
+ onContinue();
75
+ }, [categories, activeDomainSelections, setToastMessage, onContinue]);
66
76
  useInput((_input, key) => {
67
77
  if (key.return) {
68
- onContinue();
78
+ handleContinue();
69
79
  } else if (key.escape) {
70
80
  onBack();
71
81
  }
@@ -89,4 +99,4 @@ var StepBuild = ({
89
99
  export {
90
100
  StepBuild
91
101
  };
92
- //# sourceMappingURL=chunk-5F2YR5XV.js.map
102
+ //# sourceMappingURL=chunk-6DBE562W.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/step-build.tsx","../src/cli/components/hooks/use-category-rows.ts"],"sourcesContent":["import { Box, useInput } from \"ink\";\nimport React, { useCallback, useMemo } from \"react\";\nimport type { Domain, SkillId, Category } from \"../../types/index.js\";\nimport { useCategoryRows } from \"../hooks/use-category-rows.js\";\nimport { useMeasuredHeight } from \"../hooks/use-measured-height.js\";\nimport { useWizardStore } from \"../../stores/wizard-store.js\";\nimport { validateBuildStep } from \"../../lib/wizard/index.js\";\nimport { CategoryGrid } from \"./category-grid.js\";\n\nexport type StepBuildProps = {\n domain: Domain;\n selectedDomains: Domain[];\n allSelections: SkillId[];\n showLabels: boolean;\n /** Skill IDs already installed on disk, shown with a dimmed checkmark */\n installedSkillIds?: SkillId[] | undefined;\n onToggle: (categoryId: Category, technologyId: SkillId) => void;\n onToggleLabels: () => void;\n onContinue: () => void;\n onBack: () => void;\n};\n\nexport const StepBuild: React.FC<StepBuildProps> = ({\n domain: activeDomain,\n allSelections,\n showLabels,\n installedSkillIds,\n onToggle,\n onToggleLabels,\n onContinue,\n onBack,\n}) => {\n const { ref: gridRef, measuredHeight: gridHeight } = useMeasuredHeight();\n const skillConfigs = useWizardStore((s) => s.skillConfigs);\n const setToastMessage = useWizardStore((s) => s.setToastMessage);\n // A domain nobody has opened yet holds no entry at all, which is the same state as one\n // opened and left empty — both are \"nothing selected here\" and both are what the advisory\n // below is about.\n const activeDomainSelections = useWizardStore((s) => s.domainSelections[activeDomain]);\n\n const handleFocusedSkillChange = useCallback(\n (id: SkillId | null) => useWizardStore.getState().setFocusedSkillId(id),\n [],\n );\n\n const categories = useCategoryRows({\n domain: activeDomain,\n allSelections,\n ...(installedSkillIds !== undefined && { installedSkillIds }),\n skillConfigs,\n });\n\n const { initialRow, initialCol } = useMemo(() => {\n const skillId = useWizardStore.getState().focusedSkillId;\n if (!skillId) return { initialRow: 0, initialCol: 0 };\n const row = categories.findIndex((cat) => cat.options.some((o) => o.id === skillId));\n const focusedCategory = categories[row];\n if (!focusedCategory) return { initialRow: 0, initialCol: 0 };\n return {\n initialRow: row,\n initialCol: focusedCategory.options.findIndex((o) => o.id === skillId),\n };\n }, [categories]);\n\n /**\n * Leaves the domain, naming any required category it leaves empty on the way out.\n *\n * The toast is set BEFORE `onContinue`, and survives it: `WizardLayout` paints the toast\n * outside `renderStep`, so unmounting this grid to move to the next domain — or to the\n * sources step — does not take the message with it.\n */\n const handleContinue = useCallback(() => {\n const validation = validateBuildStep(categories, activeDomainSelections ?? {});\n if (!validation.valid) {\n setToastMessage(validation.message);\n }\n onContinue();\n }, [categories, activeDomainSelections, setToastMessage, onContinue]);\n\n useInput((_input, key) => {\n if (key.return) {\n handleContinue();\n } else if (key.escape) {\n onBack();\n }\n });\n\n return (\n <Box flexDirection=\"column\" width=\"100%\" flexGrow={1} flexBasis={0}>\n <Box ref={gridRef} flexGrow={1} flexBasis={0}>\n <CategoryGrid\n key={activeDomain}\n categories={categories}\n availableHeight={gridHeight}\n showLabels={showLabels}\n defaultFocusedRow={initialRow}\n defaultFocusedCol={initialCol}\n onToggle={onToggle}\n onToggleLabels={onToggleLabels}\n onFocusedSkillChange={handleFocusedSkillChange}\n />\n </Box>\n </Box>\n );\n};\n","import { useMemo } from \"react\";\nimport type { Domain, SkillId } from \"../../types/index.js\";\nimport type { SkillConfig } from \"../../types/config.js\";\nimport { buildCategoriesForDomain } from \"../../lib/wizard/index.js\";\nimport type { CategoryRow } from \"../wizard/category-grid.js\";\n\ntype UseCategoryRowsOptions = {\n domain: Domain;\n allSelections: SkillId[];\n installedSkillIds?: SkillId[];\n skillConfigs?: SkillConfig[];\n};\n\n/** The build-step grid's rows for `domain`, rebuilt only when an input changes. */\nexport function useCategoryRows({\n domain,\n allSelections,\n installedSkillIds,\n skillConfigs,\n}: UseCategoryRowsOptions): CategoryRow[] {\n return useMemo(\n () => buildCategoriesForDomain(domain, allSelections, installedSkillIds, skillConfigs),\n [domain, allSelections, installedSkillIds, skillConfigs],\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAS,KAAK,gBAAgB;AAC9B,SAAgB,aAAa,WAAAA,gBAAe;;;ACD5C,SAAS,eAAe;AAcjB,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0C;AACxC,SAAO;AAAA,IACL,MAAM,yBAAyB,QAAQ,eAAe,mBAAmB,YAAY;AAAA,IACrF,CAAC,QAAQ,eAAe,mBAAmB,YAAY;AAAA,EACzD;AACF;;;ADkEQ;AApED,IAAM,YAAsC,CAAC;AAAA,EAClD,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,KAAK,SAAS,gBAAgB,WAAW,IAAI,kBAAkB;AACvE,QAAM,eAAe,eAAe,CAAC,MAAM,EAAE,YAAY;AACzD,QAAM,kBAAkB,eAAe,CAAC,MAAM,EAAE,eAAe;AAI/D,QAAM,yBAAyB,eAAe,CAAC,MAAM,EAAE,iBAAiB,YAAY,CAAC;AAErF,QAAM,2BAA2B;AAAA,IAC/B,CAAC,OAAuB,eAAe,SAAS,EAAE,kBAAkB,EAAE;AAAA,IACtE,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,gBAAgB;AAAA,IACjC,QAAQ;AAAA,IACR;AAAA,IACA,GAAI,sBAAsB,UAAa,EAAE,kBAAkB;AAAA,IAC3D;AAAA,EACF,CAAC;AAED,QAAM,EAAE,YAAY,WAAW,IAAIC,SAAQ,MAAM;AAC/C,UAAM,UAAU,eAAe,SAAS,EAAE;AAC1C,QAAI,CAAC,QAAS,QAAO,EAAE,YAAY,GAAG,YAAY,EAAE;AACpD,UAAM,MAAM,WAAW,UAAU,CAAC,QAAQ,IAAI,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,CAAC;AACnF,UAAM,kBAAkB,WAAW,GAAG;AACtC,QAAI,CAAC,gBAAiB,QAAO,EAAE,YAAY,GAAG,YAAY,EAAE;AAC5D,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,YAAY,gBAAgB,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,OAAO;AAAA,IACvE;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AASf,QAAM,iBAAiB,YAAY,MAAM;AACvC,UAAM,aAAa,kBAAkB,YAAY,0BAA0B,CAAC,CAAC;AAC7E,QAAI,CAAC,WAAW,OAAO;AACrB,sBAAgB,WAAW,OAAO;AAAA,IACpC;AACA,eAAW;AAAA,EACb,GAAG,CAAC,YAAY,wBAAwB,iBAAiB,UAAU,CAAC;AAEpE,WAAS,CAAC,QAAQ,QAAQ;AACxB,QAAI,IAAI,QAAQ;AACd,qBAAe;AAAA,IACjB,WAAW,IAAI,QAAQ;AACrB,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,SACE,oBAAC,OAAI,eAAc,UAAS,OAAM,QAAO,UAAU,GAAG,WAAW,GAC/D,8BAAC,OAAI,KAAK,SAAS,UAAU,GAAG,WAAW,GACzC;AAAA,IAAC;AAAA;AAAA,MAEC;AAAA,MACA,iBAAiB;AAAA,MACjB;AAAA,MACA,mBAAmB;AAAA,MACnB,mBAAmB;AAAA,MACnB;AAAA,MACA;AAAA,MACA,sBAAsB;AAAA;AAAA,IARjB;AAAA,EASP,GACF,GACF;AAEJ;","names":["useMemo","useMemo"]}
@@ -1,8 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- typedKeys,
4
- typedValues
5
- } from "./chunk-VASLW636.js";
6
2
 
7
3
  // src/cli/types/generated/matrix.ts
8
4
  var BUILT_IN_MATRIX = {
@@ -9405,251 +9401,25 @@ var BUILT_IN_MATRIX = {
9405
9401
  "native-js": "web-utilities-native-js",
9406
9402
  rxjs: "web-utilities-rxjs",
9407
9403
  vueuse: "web-utilities-vueuse"
9408
- },
9409
- idToSlug: {
9410
- "ai-infrastructure-huggingface-inference": "huggingface-inference",
9411
- "ai-infrastructure-litellm": "litellm",
9412
- "ai-infrastructure-modal": "modal",
9413
- "ai-infrastructure-ollama": "ollama",
9414
- "ai-infrastructure-replicate": "replicate",
9415
- "ai-infrastructure-together-ai": "together-ai",
9416
- "ai-observability-langfuse": "langfuse",
9417
- "ai-observability-promptfoo": "promptfoo",
9418
- "ai-orchestration-langchain": "langchain",
9419
- "ai-orchestration-llamaindex": "llamaindex",
9420
- "ai-orchestration-vercel-ai-sdk": "vercel-ai-sdk",
9421
- "ai-patterns-tool-use-patterns": "tool-use-patterns",
9422
- "ai-provider-anthropic-sdk": "anthropic-sdk",
9423
- "ai-provider-claude-vision": "claude-vision",
9424
- "ai-provider-cohere-sdk": "cohere-sdk",
9425
- "ai-provider-elevenlabs": "elevenlabs",
9426
- "ai-provider-google-gemini-sdk": "google-gemini-sdk",
9427
- "ai-provider-mistral-sdk": "mistral-sdk",
9428
- "ai-provider-openai-sdk": "openai-sdk",
9429
- "ai-provider-openai-whisper": "openai-whisper",
9430
- "api-analytics-posthog-analytics": "posthog-analytics",
9431
- "api-analytics-setup-posthog": "setup-posthog",
9432
- "api-auth-better-auth-drizzle-hono": "better-auth-drizzle-hono",
9433
- "api-auth-clerk": "clerk",
9434
- "api-auth-nextauth": "nextauth",
9435
- "api-baas-appwrite": "appwrite",
9436
- "api-baas-firebase": "firebase",
9437
- "api-baas-neon": "neon",
9438
- "api-baas-planetscale": "planetscale",
9439
- "api-baas-supabase": "supabase",
9440
- "api-baas-turso": "turso",
9441
- "api-caching-strategies": "strategies",
9442
- "api-cms-payload": "payload",
9443
- "api-cms-sanity": "sanity",
9444
- "api-cms-strapi": "strapi",
9445
- "api-commerce-stripe": "stripe",
9446
- "api-database-cockroachdb": "cockroachdb",
9447
- "api-database-drizzle": "drizzle",
9448
- "api-database-edgedb": "edgedb",
9449
- "api-database-knex": "knex",
9450
- "api-database-mongodb": "mongodb",
9451
- "api-database-mongoose": "mongoose",
9452
- "api-database-mysql": "mysql",
9453
- "api-database-postgresql": "postgresql",
9454
- "api-database-prisma": "prisma",
9455
- "api-database-redis": "redis",
9456
- "api-database-sequelize": "sequelize",
9457
- "api-database-surrealdb": "surrealdb",
9458
- "api-database-typeorm": "typeorm",
9459
- "api-database-upstash": "upstash",
9460
- "api-database-vercel-kv": "vercel-kv",
9461
- "api-database-vercel-postgres": "vercel-postgres",
9462
- "api-email-resend-react-email": "resend-react-email",
9463
- "api-email-setup-resend": "setup-resend",
9464
- "api-flags-posthog-flags": "posthog-flags",
9465
- "api-framework-elysia": "elysia",
9466
- "api-framework-express": "express",
9467
- "api-framework-fastify": "fastify",
9468
- "api-framework-hono": "hono",
9469
- "api-framework-nestjs": "nestjs",
9470
- "api-graphql-apollo-server": "apollo-server",
9471
- "api-graphql-mercurius": "mercurius",
9472
- "api-graphql-yoga": "yoga",
9473
- "api-messaging-webhooks": "webhooks",
9474
- "api-observability-axiom-pino-sentry": "axiom-pino-sentry",
9475
- "api-observability-setup-axiom-pino-sentry": "setup-axiom-pino-sentry",
9476
- "api-performance-api-performance": "api-performance",
9477
- "api-queue-bullmq": "bullmq",
9478
- "api-search-elasticsearch": "elasticsearch",
9479
- "api-search-meilisearch": "meilisearch",
9480
- "api-search-xquik": "xquik",
9481
- "api-specs-openapi": "openapi",
9482
- "api-vector-db-chroma": "chroma",
9483
- "api-vector-db-pinecone": "pinecone",
9484
- "api-vector-db-qdrant": "qdrant",
9485
- "api-vector-db-weaviate": "weaviate",
9486
- "cli-framework-cli-commander": "cli-commander",
9487
- "cli-framework-oclif-ink": "oclif-ink",
9488
- "cli-prompts-clack": "clack",
9489
- "desktop-backend-tauri": "tauri-backend",
9490
- "desktop-framework-electron": "electron",
9491
- "desktop-framework-tauri": "tauri",
9492
- "desktop-ipc-electron": "electron-ipc",
9493
- "desktop-mobile-tauri": "tauri-mobile",
9494
- "desktop-multiwindow-electron": "electron-multiwindow",
9495
- "desktop-multiwindow-tauri": "tauri-multiwindow",
9496
- "desktop-packaging-electron-forge": "electron-forge",
9497
- "desktop-packaging-tauri": "tauri-bundling",
9498
- "desktop-plugins-tauri": "tauri-plugins",
9499
- "desktop-security-electron": "electron-security",
9500
- "desktop-security-tauri": "tauri-security",
9501
- "desktop-storage-electron": "electron-storage",
9502
- "desktop-testing-electron": "electron-testing",
9503
- "desktop-ui-electron": "electron-ui",
9504
- "desktop-updates-electron-updater": "electron-updater",
9505
- "infra-ci-cd-docker": "docker",
9506
- "infra-ci-cd-github-actions": "github-actions",
9507
- "infra-ci-cd-turborepo-ci": "turborepo-ci",
9508
- "infra-config-setup-env": "setup-env",
9509
- "infra-containers-kubernetes": "kubernetes",
9510
- "infra-iac-pulumi": "pulumi",
9511
- "infra-iac-sst": "sst",
9512
- "infra-iac-terraform": "terraform",
9513
- "infra-platform-aws-sdk": "aws-sdk",
9514
- "infra-platform-cloudflare-workers": "cloudflare-workers",
9515
- "infra-platform-netlify": "netlify",
9516
- "infra-platform-vercel": "vercel",
9517
- "meta-config-stack-detect": "stack-detect",
9518
- "meta-design-composable-components": "composable-components",
9519
- "meta-design-expressive-typescript": "expressive-typescript",
9520
- "meta-methodology-research-methodology": "research-methodology",
9521
- "meta-planning-ai-planning": "ai-planning",
9522
- "meta-planning-api-planning": "api-planning",
9523
- "meta-planning-cli-planning": "cli-planning",
9524
- "meta-planning-web-planning": "web-planning",
9525
- "meta-reviewing-ai-reviewing": "ai-reviewing",
9526
- "meta-reviewing-api-reviewing": "api-reviewing",
9527
- "meta-reviewing-cli-reviewing": "cli-reviewing",
9528
- "meta-reviewing-infra-reviewing": "infra-reviewing",
9529
- "meta-reviewing-reviewing": "reviewing",
9530
- "meta-reviewing-web-reviewing": "web-reviewing",
9531
- "mobile-animation-gesture-handler": "gesture-handler",
9532
- "mobile-animation-reanimated": "reanimated",
9533
- "mobile-animation-skia": "skia",
9534
- "mobile-background-tasks": "tasks",
9535
- "mobile-camera-vision-camera": "vision-camera",
9536
- "mobile-deep-linking-app-links": "app-links",
9537
- "mobile-deployment-eas": "eas",
9538
- "mobile-framework-expo": "expo",
9539
- "mobile-framework-react-native": "react-native",
9540
- "mobile-hardware-ble-nfc": "ble-nfc",
9541
- "mobile-navigation-expo-router": "expo-router",
9542
- "mobile-navigation-react-navigation": "react-navigation",
9543
- "mobile-notifications-push": "push",
9544
- "mobile-performance-react-native": "react-native-performance",
9545
- "mobile-security-react-native": "react-native-security",
9546
- "mobile-storage-mmkv": "mmkv",
9547
- "mobile-storage-sqlite-powersync": "sqlite-powersync",
9548
- "mobile-storage-watermelondb": "watermelondb",
9549
- "mobile-styling-nativewind": "nativewind",
9550
- "mobile-styling-unistyles": "unistyles",
9551
- "mobile-testing-detox": "detox",
9552
- "mobile-testing-maestro": "maestro",
9553
- "mobile-ui-components-react-native-paper": "react-native-paper",
9554
- "mobile-ui-components-tamagui": "tamagui",
9555
- "shared-monorepo-nx": "nx",
9556
- "shared-monorepo-pnpm-workspaces": "pnpm-workspaces",
9557
- "shared-monorepo-turborepo": "turborepo",
9558
- "shared-security-auth-security": "auth-security",
9559
- "shared-tooling-biome": "biome",
9560
- "shared-tooling-changesets": "changesets",
9561
- "shared-tooling-eslint-prettier": "eslint-prettier",
9562
- "shared-tooling-git-hooks": "git-hooks",
9563
- "shared-tooling-typescript-config": "typescript-config",
9564
- "web-3d-react-three-fiber": "react-three-fiber",
9565
- "web-accessibility-web-accessibility": "web-accessibility",
9566
- "web-animation-css-animations": "css-animations",
9567
- "web-animation-framer-motion": "framer-motion",
9568
- "web-animation-view-transitions": "view-transitions",
9569
- "web-data-fetching-graphql-apollo": "graphql-apollo",
9570
- "web-data-fetching-graphql-urql": "graphql-urql",
9571
- "web-data-fetching-swr": "swr",
9572
- "web-data-fetching-trpc": "trpc",
9573
- "web-dataviz-d3": "d3",
9574
- "web-dataviz-recharts": "recharts",
9575
- "web-dnd-dnd-kit": "dnd-kit",
9576
- "web-editor-lexical": "lexical",
9577
- "web-editor-tiptap": "tiptap",
9578
- "web-error-handling-error-boundaries": "error-boundaries",
9579
- "web-error-handling-result-types": "result-types",
9580
- "web-files-file-upload-patterns": "file-upload-patterns",
9581
- "web-files-image-handling": "image-handling",
9582
- "web-forms-react-hook-form": "react-hook-form",
9583
- "web-forms-tanstack-form": "tanstack-form",
9584
- "web-forms-vee-validate": "vee-validate",
9585
- "web-forms-zod-validation": "zod-validation",
9586
- "web-framework-angular-standalone": "angular-standalone",
9587
- "web-framework-react": "react",
9588
- "web-framework-solidjs": "solidjs",
9589
- "web-framework-svelte": "svelte",
9590
- "web-framework-vue-composition-api": "vue-composition-api",
9591
- "web-i18n-next-intl": "next-intl",
9592
- "web-i18n-react-intl": "react-intl",
9593
- "web-i18n-vue-i18n": "vue-i18n",
9594
- "web-maps-leaflet": "leaflet",
9595
- "web-maps-mapbox": "mapbox",
9596
- "web-meta-framework-astro": "astro",
9597
- "web-meta-framework-docusaurus": "docusaurus",
9598
- "web-meta-framework-nextjs": "nextjs",
9599
- "web-meta-framework-nuxt": "nuxt",
9600
- "web-meta-framework-qwik": "qwik",
9601
- "web-meta-framework-remix": "remix",
9602
- "web-meta-framework-sveltekit": "sveltekit",
9603
- "web-meta-framework-vitepress": "vitepress",
9604
- "web-mocks-msw": "msw",
9605
- "web-performance-web-performance": "web-performance",
9606
- "web-pwa-offline-first": "offline-first",
9607
- "web-pwa-service-workers": "service-workers",
9608
- "web-realtime-socket-io": "socket-io",
9609
- "web-realtime-sse": "sse",
9610
- "web-realtime-websockets": "websockets",
9611
- "web-routing-react-router": "react-router",
9612
- "web-routing-tanstack-router": "tanstack-router",
9613
- "web-server-state-react-query": "react-query",
9614
- "web-state-jotai": "jotai",
9615
- "web-state-mobx": "mobx",
9616
- "web-state-ngrx-signalstore": "ngrx-signalstore",
9617
- "web-state-pinia": "pinia",
9618
- "web-state-redux-toolkit": "redux-toolkit",
9619
- "web-state-zustand": "zustand",
9620
- "web-styling-cva": "cva",
9621
- "web-styling-design-tokens": "design-tokens",
9622
- "web-styling-scss-modules": "scss-modules",
9623
- "web-styling-tailwind": "tailwind",
9624
- "web-styling-theming": "theming",
9625
- "web-testing-cypress-e2e": "cypress-e2e",
9626
- "web-testing-playwright-e2e": "playwright-e2e",
9627
- "web-testing-react-testing-library": "react-testing-library",
9628
- "web-testing-visual-regression": "visual-regression",
9629
- "web-testing-vitest": "vitest",
9630
- "web-testing-vue-test-utils": "vue-test-utils",
9631
- "web-tooling-component-library": "component-library",
9632
- "web-tooling-storybook": "storybook",
9633
- "web-tooling-vite": "vite",
9634
- "web-ui-ant-design": "ant-design",
9635
- "web-ui-base-ui": "base-ui",
9636
- "web-ui-chakra-ui": "chakra-ui",
9637
- "web-ui-headless-ui": "headless-ui",
9638
- "web-ui-mantine": "mantine",
9639
- "web-ui-mui": "mui",
9640
- "web-ui-radix-ui": "radix-ui",
9641
- "web-ui-shadcn-ui": "shadcn-ui",
9642
- "web-ui-tanstack-table": "tanstack-table",
9643
- "web-ui-vuetify": "vuetify",
9644
- "web-utilities-date-fns": "date-fns",
9645
- "web-utilities-native-js": "native-js",
9646
- "web-utilities-rxjs": "rxjs",
9647
- "web-utilities-vueuse": "vueuse"
9648
9404
  }
9649
9405
  },
9650
9406
  generatedAt: "build"
9651
9407
  };
9652
9408
 
9409
+ // src/cli/utils/typed-object.ts
9410
+ function typedEntries(obj) {
9411
+ return Object.entries(obj);
9412
+ }
9413
+ function typedKeys(obj) {
9414
+ return Object.keys(obj);
9415
+ }
9416
+ function typedFromEntries(entries) {
9417
+ return Object.fromEntries(entries);
9418
+ }
9419
+ function typedValues(obj) {
9420
+ return Object.values(obj).filter((value) => value !== void 0);
9421
+ }
9422
+
9653
9423
  // src/cli/lib/matrix/matrix-provider.ts
9654
9424
  var matrix = BUILT_IN_MATRIX;
9655
9425
  function initializeMatrix(merged) {
@@ -9686,6 +9456,10 @@ function byCategoryDeclarationOrder() {
9686
9456
 
9687
9457
  export {
9688
9458
  BUILT_IN_MATRIX,
9459
+ typedEntries,
9460
+ typedKeys,
9461
+ typedFromEntries,
9462
+ typedValues,
9689
9463
  matrix,
9690
9464
  initializeMatrix,
9691
9465
  getSkillById,
@@ -9696,4 +9470,4 @@ export {
9696
9470
  findStack,
9697
9471
  byCategoryDeclarationOrder
9698
9472
  };
9699
- //# sourceMappingURL=chunk-RWOYPOMR.js.map
9473
+ //# sourceMappingURL=chunk-7Z4N4JWQ.js.map