agents-inc 0.167.0 → 0.170.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 (200) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +18 -15
  3. package/dist/{chunk-ZR4YPKXQ.js → chunk-3G7X2WKI.js} +4 -4
  4. package/dist/{chunk-JOEA52NR.js → chunk-44TE3RKH.js} +46 -2
  5. package/dist/chunk-44TE3RKH.js.map +1 -0
  6. package/dist/{chunk-V5WXIM2F.js → chunk-52HDHJ7I.js} +11 -19
  7. package/dist/chunk-52HDHJ7I.js.map +1 -0
  8. package/dist/{chunk-V3I7VQ7N.js → chunk-6HNXYYVF.js} +39 -22
  9. package/dist/chunk-6HNXYYVF.js.map +1 -0
  10. package/dist/{chunk-MAWNVT2C.js → chunk-6ZRH5RHC.js} +10 -11
  11. package/dist/chunk-6ZRH5RHC.js.map +1 -0
  12. package/dist/{chunk-G6UREQ4V.js → chunk-7RDMTR64.js} +14 -34
  13. package/dist/chunk-7RDMTR64.js.map +1 -0
  14. package/dist/{chunk-GE3WKJ6Q.js → chunk-BMRUNMPV.js} +4 -4
  15. package/dist/{chunk-VAPTVR3J.js → chunk-CLPUWOSA.js} +4 -4
  16. package/dist/{chunk-VAPTVR3J.js.map → chunk-CLPUWOSA.js.map} +1 -1
  17. package/dist/{chunk-HWEKHVLE.js → chunk-F2BHT5C4.js} +9 -7
  18. package/dist/chunk-F2BHT5C4.js.map +1 -0
  19. package/dist/{chunk-ZXKBERQU.js → chunk-F5EBEATU.js} +2 -2
  20. package/dist/{chunk-PMJWD27C.js → chunk-HED2DAXZ.js} +3 -3
  21. package/dist/{chunk-SAYZWCH6.js → chunk-KOLDW6SF.js} +3 -3
  22. package/dist/{chunk-SAYZWCH6.js.map → chunk-KOLDW6SF.js.map} +1 -1
  23. package/dist/{chunk-A4KDXNOT.js → chunk-MQ6CGZNJ.js} +171 -522
  24. package/dist/chunk-MQ6CGZNJ.js.map +1 -0
  25. package/dist/{chunk-G4JK7WVO.js → chunk-NCWDK6L7.js} +115 -196
  26. package/dist/chunk-NCWDK6L7.js.map +1 -0
  27. package/dist/{chunk-VRXX4D6K.js → chunk-NEZ4OAOL.js} +1 -1
  28. package/dist/chunk-NEZ4OAOL.js.map +1 -0
  29. package/dist/chunk-NIHUOWE4.js +106 -0
  30. package/dist/chunk-NIHUOWE4.js.map +1 -0
  31. package/dist/{chunk-OI2H6M5I.js → chunk-NQW25DCF.js} +2 -2
  32. package/dist/chunk-NQW25DCF.js.map +1 -0
  33. package/dist/{chunk-25MPBIK3.js → chunk-OYJQUA3D.js} +3 -3
  34. package/dist/{chunk-25MPBIK3.js.map → chunk-OYJQUA3D.js.map} +1 -1
  35. package/dist/{chunk-ENGYJCTF.js → chunk-PJWGTNOX.js} +220 -254
  36. package/dist/chunk-PJWGTNOX.js.map +1 -0
  37. package/dist/{chunk-NBXXFIIW.js → chunk-RIPSGNLU.js} +3 -3
  38. package/dist/chunk-RIPSGNLU.js.map +1 -0
  39. package/dist/{chunk-Y47EV74W.js → chunk-SZYQISA2.js} +10 -13
  40. package/dist/chunk-SZYQISA2.js.map +1 -0
  41. package/dist/{chunk-TODCQFRB.js → chunk-USVBYQSQ.js} +2 -2
  42. package/dist/{chunk-Y3VIRVVE.js → chunk-V3KTSP3Q.js} +50 -42
  43. package/dist/chunk-V3KTSP3Q.js.map +1 -0
  44. package/dist/{chunk-PXWG7KFO.js → chunk-WTWMGH2C.js} +2 -2
  45. package/dist/commands/build/marketplace.js +23 -22
  46. package/dist/commands/build/marketplace.js.map +1 -1
  47. package/dist/commands/build/plugins.js +8 -9
  48. package/dist/commands/build/plugins.js.map +1 -1
  49. package/dist/commands/compile.js +19 -20
  50. package/dist/commands/compile.js.map +1 -1
  51. package/dist/commands/doctor.js +17 -18
  52. package/dist/commands/doctor.js.map +1 -1
  53. package/dist/commands/edit.js +138 -488
  54. package/dist/commands/edit.js.map +1 -1
  55. package/dist/commands/eject.js +21 -33
  56. package/dist/commands/eject.js.map +1 -1
  57. package/dist/commands/init.js +17 -45
  58. package/dist/commands/list.js +19 -17
  59. package/dist/commands/list.js.map +1 -1
  60. package/dist/commands/new/marketplace.js +11 -11
  61. package/dist/commands/new/marketplace.js.map +1 -1
  62. package/dist/commands/search.js +12 -13
  63. package/dist/commands/search.js.map +1 -1
  64. package/dist/commands/share.js +11 -12
  65. package/dist/commands/share.js.map +1 -1
  66. package/dist/commands/uninstall.js +18 -20
  67. package/dist/commands/uninstall.js.map +1 -1
  68. package/dist/commands/update.js +8 -9
  69. package/dist/commands/update.js.map +1 -1
  70. package/dist/components/common/removal-plan-confirm.js +2 -2
  71. package/dist/components/common/scroll-affordance.js +9 -0
  72. package/dist/components/common/select-list.js +2 -3
  73. package/dist/components/common/skill-agent-summary.js +11 -0
  74. package/dist/components/common/spinner.js +1 -1
  75. package/dist/{chunk-2VUYFTUB.js → components/common/summary-panel.js} +57 -31
  76. package/dist/components/common/summary-panel.js.map +1 -0
  77. package/dist/config-exports.js +1 -1
  78. package/dist/hooks/init.js +18 -46
  79. package/dist/hooks/init.js.map +1 -1
  80. package/dist/load-agent-defs-YMDWBFDP.js +14 -0
  81. package/dist/recompile-project-agents-SZ76WNTW.js +18 -0
  82. package/dist/{source-loader-7KZ3MD5O.js → source-loader-C5SQXZXI.js} +5 -5
  83. package/dist/src/agents/meta/codex-keeper/playbook.md +2 -3
  84. package/package.json +6 -4
  85. package/src/agents/meta/codex-keeper/playbook.md +2 -3
  86. package/src/schemas/project-config.schema.json +1 -1
  87. package/assets/demo.tape +0 -266
  88. package/dist/chunk-2VUYFTUB.js.map +0 -1
  89. package/dist/chunk-4NDBUJHK.js +0 -237
  90. package/dist/chunk-4NDBUJHK.js.map +0 -1
  91. package/dist/chunk-6L75SQZU.js +0 -168
  92. package/dist/chunk-6L75SQZU.js.map +0 -1
  93. package/dist/chunk-6LF4CQBY.js +0 -51
  94. package/dist/chunk-6LF4CQBY.js.map +0 -1
  95. package/dist/chunk-7JNJ52CD.js +0 -1179
  96. package/dist/chunk-7JNJ52CD.js.map +0 -1
  97. package/dist/chunk-A4KDXNOT.js.map +0 -1
  98. package/dist/chunk-DAIEQJIF.js +0 -48
  99. package/dist/chunk-DAIEQJIF.js.map +0 -1
  100. package/dist/chunk-ENGYJCTF.js.map +0 -1
  101. package/dist/chunk-G4JK7WVO.js.map +0 -1
  102. package/dist/chunk-G6UREQ4V.js.map +0 -1
  103. package/dist/chunk-HHIYT3PI.js +0 -53
  104. package/dist/chunk-HHIYT3PI.js.map +0 -1
  105. package/dist/chunk-HWEKHVLE.js.map +0 -1
  106. package/dist/chunk-JOEA52NR.js.map +0 -1
  107. package/dist/chunk-JQRJQ4SS.js +0 -118
  108. package/dist/chunk-JQRJQ4SS.js.map +0 -1
  109. package/dist/chunk-LFWLEDUG.js +0 -59
  110. package/dist/chunk-LFWLEDUG.js.map +0 -1
  111. package/dist/chunk-MAWNVT2C.js.map +0 -1
  112. package/dist/chunk-MPTNC32T.js +0 -92
  113. package/dist/chunk-MPTNC32T.js.map +0 -1
  114. package/dist/chunk-NBXXFIIW.js.map +0 -1
  115. package/dist/chunk-OI2H6M5I.js.map +0 -1
  116. package/dist/chunk-PNB3524H.js +0 -197
  117. package/dist/chunk-PNB3524H.js.map +0 -1
  118. package/dist/chunk-QHDPLLK6.js +0 -35
  119. package/dist/chunk-QHDPLLK6.js.map +0 -1
  120. package/dist/chunk-RAHSOJQ2.js +0 -25
  121. package/dist/chunk-RAHSOJQ2.js.map +0 -1
  122. package/dist/chunk-RZDXDMT6.js +0 -23
  123. package/dist/chunk-RZDXDMT6.js.map +0 -1
  124. package/dist/chunk-SCOQ34YM.js +0 -17
  125. package/dist/chunk-SCOQ34YM.js.map +0 -1
  126. package/dist/chunk-SXVHSOTH.js +0 -268
  127. package/dist/chunk-SXVHSOTH.js.map +0 -1
  128. package/dist/chunk-T6UWJAB3.js +0 -28
  129. package/dist/chunk-T6UWJAB3.js.map +0 -1
  130. package/dist/chunk-TSIU7DME.js +0 -43
  131. package/dist/chunk-TSIU7DME.js.map +0 -1
  132. package/dist/chunk-TTY6DPJN.js +0 -27
  133. package/dist/chunk-TTY6DPJN.js.map +0 -1
  134. package/dist/chunk-TZ2YJJKK.js +0 -292
  135. package/dist/chunk-TZ2YJJKK.js.map +0 -1
  136. package/dist/chunk-V3I7VQ7N.js.map +0 -1
  137. package/dist/chunk-V5WXIM2F.js.map +0 -1
  138. package/dist/chunk-VRXX4D6K.js.map +0 -1
  139. package/dist/chunk-WTJ3AY33.js +0 -31
  140. package/dist/chunk-WTJ3AY33.js.map +0 -1
  141. package/dist/chunk-WVUDLKIO.js +0 -121
  142. package/dist/chunk-WVUDLKIO.js.map +0 -1
  143. package/dist/chunk-WWIFNPJG.js +0 -317
  144. package/dist/chunk-WWIFNPJG.js.map +0 -1
  145. package/dist/chunk-XQHZPINL.js +0 -89
  146. package/dist/chunk-XQHZPINL.js.map +0 -1
  147. package/dist/chunk-XZEVWPX6.js +0 -230
  148. package/dist/chunk-XZEVWPX6.js.map +0 -1
  149. package/dist/chunk-Y3VIRVVE.js.map +0 -1
  150. package/dist/chunk-Y47EV74W.js.map +0 -1
  151. package/dist/components/wizard/category-grid.js +0 -13
  152. package/dist/components/wizard/checkbox-grid.js +0 -12
  153. package/dist/components/wizard/domain-selection.js +0 -18
  154. package/dist/components/wizard/run-wizard-session.js +0 -40
  155. package/dist/components/wizard/run-wizard-session.js.map +0 -1
  156. package/dist/components/wizard/scroll-affordance.js +0 -9
  157. package/dist/components/wizard/skill-agent-summary.js +0 -13
  158. package/dist/components/wizard/source-grid.js +0 -16
  159. package/dist/components/wizard/source-grid.js.map +0 -1
  160. package/dist/components/wizard/stack-selection.js +0 -17
  161. package/dist/components/wizard/stack-selection.js.map +0 -1
  162. package/dist/components/wizard/step-agents.js +0 -18
  163. package/dist/components/wizard/step-agents.js.map +0 -1
  164. package/dist/components/wizard/step-build.js +0 -18
  165. package/dist/components/wizard/step-build.js.map +0 -1
  166. package/dist/components/wizard/step-confirm.js +0 -18
  167. package/dist/components/wizard/step-confirm.js.map +0 -1
  168. package/dist/components/wizard/step-sources.js +0 -19
  169. package/dist/components/wizard/step-sources.js.map +0 -1
  170. package/dist/components/wizard/step-stack.js +0 -18
  171. package/dist/components/wizard/step-stack.js.map +0 -1
  172. package/dist/components/wizard/summary-panel.js +0 -17
  173. package/dist/components/wizard/summary-panel.js.map +0 -1
  174. package/dist/components/wizard/toast.js +0 -9
  175. package/dist/components/wizard/toast.js.map +0 -1
  176. package/dist/components/wizard/wizard-layout.js +0 -22
  177. package/dist/components/wizard/wizard-layout.js.map +0 -1
  178. package/dist/components/wizard/wizard-tabs.js +0 -11
  179. package/dist/components/wizard/wizard-tabs.js.map +0 -1
  180. package/dist/components/wizard/wizard.js +0 -39
  181. package/dist/components/wizard/wizard.js.map +0 -1
  182. package/dist/load-agent-defs-3C27ENC7.js +0 -14
  183. package/dist/load-agent-defs-3C27ENC7.js.map +0 -1
  184. package/dist/recompile-project-agents-DGNBCU3N.js +0 -18
  185. package/dist/recompile-project-agents-DGNBCU3N.js.map +0 -1
  186. package/dist/source-loader-7KZ3MD5O.js.map +0 -1
  187. package/dist/stores/wizard-store.js +0 -24
  188. package/dist/stores/wizard-store.js.map +0 -1
  189. /package/assets/{demo.gif → legacy-wizard.gif} +0 -0
  190. /package/dist/{chunk-ZR4YPKXQ.js.map → chunk-3G7X2WKI.js.map} +0 -0
  191. /package/dist/{chunk-GE3WKJ6Q.js.map → chunk-BMRUNMPV.js.map} +0 -0
  192. /package/dist/{chunk-ZXKBERQU.js.map → chunk-F5EBEATU.js.map} +0 -0
  193. /package/dist/{chunk-PMJWD27C.js.map → chunk-HED2DAXZ.js.map} +0 -0
  194. /package/dist/{chunk-TODCQFRB.js.map → chunk-USVBYQSQ.js.map} +0 -0
  195. /package/dist/{chunk-PXWG7KFO.js.map → chunk-WTWMGH2C.js.map} +0 -0
  196. /package/dist/components/{wizard → common}/scroll-affordance.js.map +0 -0
  197. /package/dist/components/{wizard → common}/skill-agent-summary.js.map +0 -0
  198. /package/dist/{components/wizard/category-grid.js.map → load-agent-defs-YMDWBFDP.js.map} +0 -0
  199. /package/dist/{components/wizard/checkbox-grid.js.map → recompile-project-agents-SZ76WNTW.js.map} +0 -0
  200. /package/dist/{components/wizard/domain-selection.js.map → source-loader-C5SQXZXI.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/components/common/summary-panel.tsx","../../../src/cli/components/hooks/use-panel-scroll.ts","../../../src/cli/components/hooks/use-measured-height.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 type { SkillConfig } from \"../../types/config.js\";\nimport { usePanelScroll } from \"../hooks/use-panel-scroll.js\";\nimport { ScrollAffordance } from \"./scroll-affordance.js\";\nimport { SkillAgentSummary, type SkillAgentSummaryProps } from \"./skill-agent-summary.js\";\n\nexport type SummaryPanelProps = SkillAgentSummaryProps & {\n /** `undefined` when the configuration was built from no stack. */\n stackName: string | undefined;\n};\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.** 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 `SkillAgentSummary`.\n *\n * It owns the `↑`/`↓` keys through `usePanelScroll`. A host that needs other\n * keys adds its own `useInput` alongside it.\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<SummaryPanelProps> = ({ stackName, ...summary }) => {\n const { viewportRef, contentRef, contentMarginTop, hiddenAbove, hiddenBelow } = usePanelScroll();\n\n const sourceNames = formatSkillMarketplaces(summary.skillConfigs);\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 {...summary} />\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","import { useRef, useState, useEffect } from \"react\";\nimport { type DOMElement, measureElement, useStdout } from \"ink\";\n\n/**\n * Measures the computed height of a Box element using Ink's Yoga layout engine.\n *\n * Returns a ref to attach to a Box with `flexGrow={1}` and the measured height.\n * The Box must be inside a parent chain with a constrained height (e.g., an\n * explicit `height` prop on an ancestor) so Yoga can compute the remaining space.\n *\n * Returns 0 before the first layout pass. Re-measures on terminal resize.\n */\nexport function useMeasuredHeight(): {\n ref: React.Ref<DOMElement>;\n measuredHeight: number;\n} {\n const ref = useRef<DOMElement>(null);\n const [measuredHeight, setMeasuredHeight] = useState(0);\n const { stdout } = useStdout();\n\n const measure = () => {\n if (ref.current) {\n const { height } = measureElement(ref.current);\n setMeasuredHeight((prev) => (prev !== height ? height : prev));\n }\n };\n\n // Re-measure after every render so late-mounted refs get picked up.\n // The state setter avoids unnecessary updates when height is unchanged.\n useEffect(() => {\n measure();\n });\n\n // Yoga may not have computed the layout on the first render, so\n // measureElement() returns 0. Retry with increasing delays to give\n // Yoga time to resolve the full flex constraint chain.\n useEffect(() => {\n const RETRY_DELAYS_MS = [0, 16, 50];\n const timers: ReturnType<typeof setTimeout>[] = [];\n\n for (const delay of RETRY_DELAYS_MS) {\n timers.push(setTimeout(measure, delay));\n }\n\n return () => {\n for (const timer of timers) {\n clearTimeout(timer);\n }\n };\n // Deps are deliberately empty: this is a mount-only retry ladder. `measure`\n // is re-created every render, so listing it would re-arm the timers on every\n // render instead of once.\n }, []);\n\n useEffect(() => {\n stdout.on(\"resize\", measure);\n return () => {\n stdout.off(\"resize\", measure);\n };\n }, [stdout]);\n\n return { ref, measuredHeight };\n}\n"],"mappings":"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","names":["useEffect","useRef","useState","measureElement","useRef","useState","useEffect","measureElement"]}
@@ -4,7 +4,7 @@ import {
4
4
  defaultRules,
5
5
  defaultStacks,
6
6
  defineConfig
7
- } from "./chunk-OI2H6M5I.js";
7
+ } from "./chunk-NQW25DCF.js";
8
8
  export {
9
9
  defaultCategories,
10
10
  defaultRules,
@@ -1,61 +1,33 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDashboardFlow
4
- } from "../chunk-G4JK7WVO.js";
5
- import "../chunk-6LF4CQBY.js";
6
- import "../chunk-V3I7VQ7N.js";
7
- import "../chunk-HHIYT3PI.js";
8
- import "../chunk-WWIFNPJG.js";
9
- import "../chunk-RAHSOJQ2.js";
10
- import "../chunk-DAIEQJIF.js";
11
- import "../chunk-SCOQ34YM.js";
12
- import "../chunk-4NDBUJHK.js";
13
- import "../chunk-2VUYFTUB.js";
14
- import "../chunk-T6UWJAB3.js";
15
- import "../chunk-6L75SQZU.js";
16
- import "../chunk-LFWLEDUG.js";
17
- import "../chunk-TZ2YJJKK.js";
18
- import "../chunk-SAYZWCH6.js";
19
- import "../chunk-PNB3524H.js";
20
- import "../chunk-XZEVWPX6.js";
21
- import "../chunk-QHDPLLK6.js";
22
- import "../chunk-MPTNC32T.js";
23
- import "../chunk-TSIU7DME.js";
24
- import "../chunk-JOEA52NR.js";
25
- import "../chunk-VRXX4D6K.js";
26
- import "../chunk-SXVHSOTH.js";
27
- import "../chunk-XQHZPINL.js";
28
- import "../chunk-JQRJQ4SS.js";
29
- import "../chunk-TTY6DPJN.js";
30
- import "../chunk-WTJ3AY33.js";
31
- import "../chunk-WVUDLKIO.js";
32
- import "../chunk-25MPBIK3.js";
4
+ } from "../chunk-NCWDK6L7.js";
5
+ import "../chunk-44TE3RKH.js";
6
+ import "../chunk-6HNXYYVF.js";
7
+ import "../chunk-OYJQUA3D.js";
33
8
  import "../chunk-4AAOOAIN.js";
34
9
  import "../chunk-OZXAJNLA.js";
35
- import "../chunk-ZXKBERQU.js";
36
- import "../chunk-G6UREQ4V.js";
37
- import "../chunk-HWEKHVLE.js";
38
- import "../chunk-PMJWD27C.js";
39
- import "../chunk-ZR4YPKXQ.js";
40
- import "../chunk-GE3WKJ6Q.js";
41
- import "../chunk-MAWNVT2C.js";
10
+ import "../chunk-F5EBEATU.js";
11
+ import "../chunk-7RDMTR64.js";
12
+ import "../chunk-F2BHT5C4.js";
13
+ import "../chunk-HED2DAXZ.js";
14
+ import "../chunk-3G7X2WKI.js";
15
+ import "../chunk-BMRUNMPV.js";
42
16
  import "../chunk-JFLVEFFP.js";
43
- import "../chunk-7JNJ52CD.js";
44
- import "../chunk-NBXXFIIW.js";
17
+ import "../chunk-RIPSGNLU.js";
45
18
  import {
46
19
  EXIT_CODES
47
- } from "../chunk-Y3VIRVVE.js";
48
- import "../chunk-VAPTVR3J.js";
49
- import "../chunk-RZDXDMT6.js";
20
+ } from "../chunk-V3KTSP3Q.js";
21
+ import "../chunk-CLPUWOSA.js";
50
22
  import {
51
23
  findConfigLoadFailures,
52
24
  installationConfigsUnreadable,
53
25
  retiredSourceFolderIn,
54
26
  retiredSourceFolderUnsupported
55
- } from "../chunk-A4KDXNOT.js";
56
- import "../chunk-V5WXIM2F.js";
57
- import "../chunk-ENGYJCTF.js";
58
- import "../chunk-OI2H6M5I.js";
27
+ } from "../chunk-MQ6CGZNJ.js";
28
+ import "../chunk-52HDHJ7I.js";
29
+ import "../chunk-PJWGTNOX.js";
30
+ import "../chunk-NQW25DCF.js";
59
31
 
60
32
  // src/cli/hooks/init.ts
61
33
  import os from "os";
@@ -68,7 +40,7 @@ var hook = async function(options) {
68
40
  if (unreadable.length > 0) {
69
41
  this.error(installationConfigsUnreadable(unreadable), { exit: EXIT_CODES.ERROR });
70
42
  }
71
- const dashboard = await runDashboardFlow(projectDir, options.config, "standalone");
43
+ const dashboard = await runDashboardFlow(projectDir, options.config);
72
44
  if (dashboard === "cancelled") this.error("Cancelled", { exit: EXIT_CODES.CANCELLED });
73
45
  if (dashboard === "shown") await endRun(EXIT_CODES.SUCCESS);
74
46
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/hooks/init.ts"],"sourcesContent":["import os from \"os\";\n\nimport { flush, type Hook } from \"@oclif/core\";\nimport { runDashboardFlow } from \"../commands/init.js\";\nimport { findConfigLoadFailures } from \"../lib/configuration/project-config.js\";\nimport { retiredSourceFolderIn } from \"../lib/installation/install-layout.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n installationConfigsUnreadable,\n retiredSourceFolderUnsupported,\n} from \"../utils/messages.js\";\n\nconst hook: Hook<\"init\"> = async function (options) {\n sayTheRetiredSourceFolderIsUnsupported(process.cwd());\n\n // When no command is given and project is already initialized, show dashboard\n if (options.id === undefined) {\n const projectDir = process.cwd();\n // Refused as every command refuses it (`BaseCommand.ensureConfigReadable`). Left to the\n // dashboard, the load error was swallowed by oclif's hook runner and the run printed the root\n // help, as though nothing were installed.\n const unreadable = await findConfigLoadFailures(projectDir);\n if (unreadable.length > 0) {\n this.error(installationConfigsUnreadable(unreadable), { exit: EXIT_CODES.ERROR });\n }\n\n const dashboard = await runDashboardFlow(projectDir, options.config, \"standalone\");\n if (dashboard === \"cancelled\") this.error(\"Cancelled\", { exit: EXIT_CODES.CANCELLED });\n if (dashboard === \"shown\") await endRun(EXIT_CODES.SUCCESS);\n }\n};\n\n/**\n * One bare line, once per run, while the project or HOME holds the retired source folder.\n *\n * Here because every command passes through this hook exactly once, before it runs — so the line\n * is said once however many scopes hold the folder, and by every command alike. It is a notice\n * and nothing more: the run goes on exactly as it would without the folder, which no command\n * reads or writes. On stderr, so a command whose output is piped somewhere is not changed by it.\n */\nfunction sayTheRetiredSourceFolderIsUnsupported(cwd: string): void {\n const replacement = retiredSourceFolderIn([cwd, os.homedir()]);\n if (replacement === null) return;\n process.stderr.write(`${retiredSourceFolderUnsupported(replacement)}\\n`);\n}\n\n/**\n * Ends the run here, once the dashboard is done with it.\n *\n * `this.exit(0)` cannot: oclif swallows an exit 0 thrown from a hook and carries on with the run\n * the hook interrupted — and a run with no command is a request for the root help, so the full help\n * listing printed under every dashboard that was left with Escape or a chosen command. A non-zero\n * exit is not swallowed, which is why Ctrl+C's `this.error` already ended the run. This is the\n * ending oclif's own error handler gives a command's `this.exit()`, with the output flushed first.\n */\nasync function endRun(code: number): Promise<never> {\n await flush();\n process.exit(code);\n}\n\nexport default hook;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,QAAQ;AAEf,SAAS,aAAwB;AAUjC,IAAM,OAAqB,eAAgB,SAAS;AAClD,yCAAuC,QAAQ,IAAI,CAAC;AAGpD,MAAI,QAAQ,OAAO,QAAW;AAC5B,UAAM,aAAa,QAAQ,IAAI;AAI/B,UAAM,aAAa,MAAM,uBAAuB,UAAU;AAC1D,QAAI,WAAW,SAAS,GAAG;AACzB,WAAK,MAAM,8BAA8B,UAAU,GAAG,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,IAClF;AAEA,UAAM,YAAY,MAAM,iBAAiB,YAAY,QAAQ,QAAQ,YAAY;AACjF,QAAI,cAAc,YAAa,MAAK,MAAM,aAAa,EAAE,MAAM,WAAW,UAAU,CAAC;AACrF,QAAI,cAAc,QAAS,OAAM,OAAO,WAAW,OAAO;AAAA,EAC5D;AACF;AAUA,SAAS,uCAAuC,KAAmB;AACjE,QAAM,cAAc,sBAAsB,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC;AAC7D,MAAI,gBAAgB,KAAM;AAC1B,UAAQ,OAAO,MAAM,GAAG,+BAA+B,WAAW,CAAC;AAAA,CAAI;AACzE;AAWA,eAAe,OAAO,MAA8B;AAClD,QAAM,MAAM;AACZ,UAAQ,KAAK,IAAI;AACnB;AAEA,IAAO,eAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/cli/hooks/init.ts"],"sourcesContent":["import os from \"os\";\n\nimport { flush, type Hook } from \"@oclif/core\";\nimport { runDashboardFlow } from \"../commands/init.js\";\nimport { findConfigLoadFailures } from \"../lib/configuration/project-config.js\";\nimport { retiredSourceFolderIn } from \"../lib/installation/install-layout.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n installationConfigsUnreadable,\n retiredSourceFolderUnsupported,\n} from \"../utils/messages.js\";\n\nconst hook: Hook<\"init\"> = async function (options) {\n sayTheRetiredSourceFolderIsUnsupported(process.cwd());\n\n // No command: the dashboard, over the project's installation or else the global one\n if (options.id === undefined) {\n const projectDir = process.cwd();\n // Left to the dashboard, the load error was swallowed by oclif's hook runner and the run\n // printed the root help, as though nothing were installed.\n const unreadable = await findConfigLoadFailures(projectDir);\n if (unreadable.length > 0) {\n this.error(installationConfigsUnreadable(unreadable), { exit: EXIT_CODES.ERROR });\n }\n\n const dashboard = await runDashboardFlow(projectDir, options.config);\n if (dashboard === \"cancelled\") this.error(\"Cancelled\", { exit: EXIT_CODES.CANCELLED });\n if (dashboard === \"shown\") await endRun(EXIT_CODES.SUCCESS);\n }\n};\n\n/**\n * One bare line, once per run, while the project or HOME holds the retired source folder.\n *\n * Here because every command passes through this hook exactly once, before it runs — so the line\n * is said once however many scopes hold the folder, and by every command alike. It is a notice\n * and nothing more: the run goes on exactly as it would without the folder, which no command\n * reads or writes. On stderr, so a command whose output is piped somewhere is not changed by it.\n */\nfunction sayTheRetiredSourceFolderIsUnsupported(cwd: string): void {\n const replacement = retiredSourceFolderIn([cwd, os.homedir()]);\n if (replacement === null) return;\n process.stderr.write(`${retiredSourceFolderUnsupported(replacement)}\\n`);\n}\n\n/**\n * Ends the run here, once the dashboard is done with it.\n *\n * `this.exit(0)` cannot: oclif swallows an exit 0 thrown from a hook and carries on with the run\n * the hook interrupted — and a run with no command is a request for the root help, so the full help\n * listing printed under every dashboard that was left with Escape or a chosen command. A non-zero\n * exit is not swallowed, which is why Ctrl+C's `this.error` already ended the run. This is the\n * ending oclif's own error handler gives a command's `this.exit()`, with the output flushed first.\n */\nasync function endRun(code: number): Promise<never> {\n await flush();\n process.exit(code);\n}\n\nexport default hook;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,QAAQ;AAEf,SAAS,aAAwB;AAUjC,IAAM,OAAqB,eAAgB,SAAS;AAClD,yCAAuC,QAAQ,IAAI,CAAC;AAGpD,MAAI,QAAQ,OAAO,QAAW;AAC5B,UAAM,aAAa,QAAQ,IAAI;AAG/B,UAAM,aAAa,MAAM,uBAAuB,UAAU;AAC1D,QAAI,WAAW,SAAS,GAAG;AACzB,WAAK,MAAM,8BAA8B,UAAU,GAAG,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,IAClF;AAEA,UAAM,YAAY,MAAM,iBAAiB,YAAY,QAAQ,MAAM;AACnE,QAAI,cAAc,YAAa,MAAK,MAAM,aAAa,EAAE,MAAM,WAAW,UAAU,CAAC;AACrF,QAAI,cAAc,QAAS,OAAM,OAAO,WAAW,OAAO;AAAA,EAC5D;AACF;AAUA,SAAS,uCAAuC,KAAmB;AACjE,QAAM,cAAc,sBAAsB,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC;AAC7D,MAAI,gBAAgB,KAAM;AAC1B,UAAQ,OAAO,MAAM,GAAG,+BAA+B,WAAW,CAAC;AAAA,CAAI;AACzE;AAWA,eAAe,OAAO,MAA8B;AAClD,QAAM,MAAM;AACZ,UAAQ,KAAK,IAAI;AACnB;AAEA,IAAO,eAAQ;","names":[]}
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ loadAgentDefs
4
+ } from "./chunk-HED2DAXZ.js";
5
+ import "./chunk-3G7X2WKI.js";
6
+ import "./chunk-BMRUNMPV.js";
7
+ import "./chunk-MQ6CGZNJ.js";
8
+ import "./chunk-52HDHJ7I.js";
9
+ import "./chunk-PJWGTNOX.js";
10
+ import "./chunk-NQW25DCF.js";
11
+ export {
12
+ loadAgentDefs
13
+ };
14
+ //# sourceMappingURL=load-agent-defs-YMDWBFDP.js.map
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ recompilePropagatedProjectAgents,
4
+ recompileRegisteredProjectAgents
5
+ } from "./chunk-F2BHT5C4.js";
6
+ import "./chunk-HED2DAXZ.js";
7
+ import "./chunk-3G7X2WKI.js";
8
+ import "./chunk-BMRUNMPV.js";
9
+ import "./chunk-CLPUWOSA.js";
10
+ import "./chunk-MQ6CGZNJ.js";
11
+ import "./chunk-52HDHJ7I.js";
12
+ import "./chunk-PJWGTNOX.js";
13
+ import "./chunk-NQW25DCF.js";
14
+ export {
15
+ recompilePropagatedProjectAgents,
16
+ recompileRegisteredProjectAgents
17
+ };
18
+ //# sourceMappingURL=recompile-project-agents-SZ76WNTW.js.map
@@ -5,10 +5,10 @@ import {
5
5
  loadMarketplaceMatrix,
6
6
  loadSkillsMatrixFromSource,
7
7
  mergeLocalSkillsIntoMatrix
8
- } from "./chunk-A4KDXNOT.js";
9
- import "./chunk-V5WXIM2F.js";
10
- import "./chunk-ENGYJCTF.js";
11
- import "./chunk-OI2H6M5I.js";
8
+ } from "./chunk-MQ6CGZNJ.js";
9
+ import "./chunk-52HDHJ7I.js";
10
+ import "./chunk-PJWGTNOX.js";
11
+ import "./chunk-NQW25DCF.js";
12
12
  export {
13
13
  MarketplaceManifestRequiredError,
14
14
  convertStackToResolvedStack,
@@ -16,4 +16,4 @@ export {
16
16
  loadSkillsMatrixFromSource,
17
17
  mergeLocalSkillsIntoMatrix
18
18
  };
19
- //# sourceMappingURL=source-loader-7KZ3MD5O.js.map
19
+ //# sourceMappingURL=source-loader-C5SQXZXI.js.map
@@ -71,8 +71,7 @@ rather than restating it; a second copy of a count can only drift from the first
71
71
  removed, and a corrected "covers" description where a document's scope moved.
72
72
  6. **Check your own output** before reporting: every path and symbol resolves, every pattern names
73
73
  an instance, every relationship is traceable in an import or a call, every cross-reference points
74
- at a document that exists, and no line number appears anywhere. This is the check the completion
75
- gate cannot make — it runs the project's typecheck, which never reads what you wrote.
74
+ at a document that exists, and no line number appears anywhere.
76
75
  7. **Point the project's `CLAUDE.md` at the map**, once, where nothing there does. A single line
77
76
  naming `.ai-docs/DOCUMENTATION_MAP.md` as the documentation index is the whole edit — no date,
78
77
  because the frontmatter of each document owns that and a second copy goes stale unread.
@@ -206,7 +205,7 @@ area you have not scoped spends the context the document needs on files it will
206
205
  ## Documenting a Monorepo
207
206
 
208
207
  Read the workspace configuration first, and let the package boundaries decide the document
209
- boundaries. Beyond the per-area documents, three things are worth their own:
208
+ boundaries. Beyond the per-area documents, these are worth their own:
210
209
 
211
210
  - **Package relationships** — each package, what it exports, and which apps consume it. This is the
212
211
  question a cross-package change opens with.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents-inc",
3
- "version": "0.167.0",
3
+ "version": "0.170.0",
4
4
  "description": "CLI for managing Agents Inc. skills, stacks, and agents for Claude Code",
5
5
  "//generate": "The write path for all four generators, in dependency order: generate:types reads the skills marketplace and writes src/cli/types/generated/, then generate:schemas copies SKILL_SLUGS and CATEGORIES out of it into metadata.schema.json's enums, then generate:matrix vendors the same directory into packages/matrix, then generate:compile vendors this package's own src/agents/ partials and templates into packages/compile. A marketplace change drifts the first three, and .github/workflows/regenerate-catalog.yml runs those three step by step; generate:compile is not on that chain, because an agent-partial edit drifts it and a marketplace change does not. It replaces the write path only: the :check variants stay separate because CI deliberately runs different subsets of them in different jobs.",
6
6
  "//no-shared-vitest-config": "A three-project suite — unit, integration and commands, each with its own include and the retry that separates them — behind one root config that also carries vitest.setup.ts, disableConsoleIntercept for @oclif/test and ink-testing-library, and its own timeouts. @workspace/vitest-config is a single-project node config that turns globals off, which this suite needs on, so merging it in would contradict as much as it contributed. e2e/vitest.config.ts stands under the same decision. Read by scripts/check-shared-vitest-config.ts in packages/cli.",
@@ -44,7 +44,10 @@
44
44
  "prompt-engineering",
45
45
  "ai-tools"
46
46
  ],
47
- "sideEffects": false,
47
+ "//sideEffects": "compile-seat.ts is imported bare to seat @workspace/compile's warnings; with plain false, esbuild drops that import and every warning the compile package raises goes nowhere.",
48
+ "sideEffects": [
49
+ "./src/cli/lib/compile-seat.ts"
50
+ ],
48
51
  "publishConfig": {
49
52
  "registry": "https://registry.npmjs.org/"
50
53
  },
@@ -126,8 +129,7 @@
126
129
  "react": "^19.2.6",
127
130
  "remeda": "^2.33.6",
128
131
  "yaml": "^2.9.0",
129
- "zod": "^4.4.3",
130
- "zustand": "^5.0.14"
132
+ "zod": "^4.4.3"
131
133
  },
132
134
  "//devDependencies": "@workspace/matrix, @workspace/compile and @workspace/api are private and never installed by a consumer, so all three are devDependencies and tsup bundles them (see `noExternal`). matrix is the one home of the seed wire contract, which src/cli/lib/seed/ used to hand-vendor; compile is the one home of the config-pair and compiled-agent renderers, which the editor's output preview draws with; api is the one home of the typed client both front doors reach the worker through, which src/cli/lib/seed/fetch-seed.ts used to hand-write a fetch for. api pulls `hono/client` in with it, and `hono` is deliberately NOT a dependency here: tsup externalises exactly what `dependencies` names, so leaving it out is what inlines it into the bundle rather than adding a runtime install to a CLI that makes one GET. The cost of that was measured before it was accepted — `find dist -name '*.js' -not -name '*.map' | xargs du -cb | tail -1` is the number. @workspace/api-mocks and msw are a different case and are named in neither `noExternal` nor this rule: nothing under src/cli/ imports them, so they reach no bundle at all — they are the one description of the worker this suite's network mocks are resolved from, and the editor's suites read the same one.",
133
135
  "devDependencies": {
@@ -71,8 +71,7 @@ rather than restating it; a second copy of a count can only drift from the first
71
71
  removed, and a corrected "covers" description where a document's scope moved.
72
72
  6. **Check your own output** before reporting: every path and symbol resolves, every pattern names
73
73
  an instance, every relationship is traceable in an import or a call, every cross-reference points
74
- at a document that exists, and no line number appears anywhere. This is the check the completion
75
- gate cannot make — it runs the project's typecheck, which never reads what you wrote.
74
+ at a document that exists, and no line number appears anywhere.
76
75
  7. **Point the project's `CLAUDE.md` at the map**, once, where nothing there does. A single line
77
76
  naming `.ai-docs/DOCUMENTATION_MAP.md` as the documentation index is the whole edit — no date,
78
77
  because the frontmatter of each document owns that and a second copy goes stale unread.
@@ -206,7 +205,7 @@ area you have not scoped spends the context the document needs on files it will
206
205
  ## Documenting a Monorepo
207
206
 
208
207
  Read the workspace configuration first, and let the package boundaries decide the document
209
- boundaries. Beyond the per-area documents, three things are worth their own:
208
+ boundaries. Beyond the per-area documents, these are worth their own:
210
209
 
211
210
  - **Package relationships** — each package, what it exports, and which apps consume it. This is the
212
211
  question a cross-package change opens with.
@@ -3,7 +3,7 @@
3
3
  "$id": "schemas/project-config.schema.json",
4
4
  "title": "Project Configuration",
5
5
  "description": "Schema for .agents-inc/<provider>/config.ts consumer project files (name, agents, stack, skills).",
6
- "$comment": "HAND-MAINTAINED. scripts/generate-json-schemas.ts does NOT emit this file (nor project-source-config.schema.json) — its SCHEMA_ENTRIES list has no entry for either, so `generate:schemas` neither emits nor judges them and writes nothing here. Edit this file by hand and keep it prettier-clean — .ai-docs/reference/features/code-generation.md names the gate that enforces that. Three vocabularies below are copied out of src/cli/types/generated/source-types.ts and drift silently, because no generator and no check re-derives any of them: the stack category enum is the CATEGORIES tuple, verbatim and in that tuple's order; the selectedDomains enum is the DOMAINS tuple; and the skill-id pattern's leading alternation is that same DOMAINS tuple, since a skill id is `<domain>-<category>-<name>`. Re-derive all three whenever a category or domain is added, renamed or removed — a missing domain silently rejects every skill id under it.",
6
+ "$comment": "HAND-MAINTAINED. scripts/generate-json-schemas.ts does NOT emit this file (nor project-source-config.schema.json) — its SCHEMA_ENTRIES list has no entry for either, so `generate:schemas` neither emits nor judges them and writes nothing here. Edit this file by hand and keep it prettier-clean. Three vocabularies below are copied out of src/cli/types/generated/source-types.ts and drift silently, because no generator and no check re-derives any of them: the stack category enum is the CATEGORIES tuple, verbatim and in that tuple's order; the selectedDomains enum is the DOMAINS tuple; and the skill-id pattern's leading alternation is that same DOMAINS tuple, since a skill id is `<domain>-<category>-<name>`. Re-derive all three whenever a category or domain is added, renamed or removed — a missing domain silently rejects every skill id under it.",
7
7
  "type": "object",
8
8
  "properties": {
9
9
  "version": {
package/assets/demo.tape DELETED
@@ -1,266 +0,0 @@
1
- Output demo.gif
2
-
3
- Set Shell "zsh"
4
- Set FontSize 26
5
- Set FontFamily "Ubuntu Mono"
6
- Set LineHeight 1.3
7
- Set Width 1400
8
- Set Height 1200
9
- Set Padding 40
10
- Set Margin 20
11
- Set BorderRadius 8
12
- Set WindowBar Colorful
13
- Set WindowBarSize 40
14
- Set TypingSpeed 80ms
15
- Set CursorBlink true
16
- Set Framerate 60
17
- # Set Theme { "name": "One Dark", "black": "#21252b", "red": "#e06c75", "green": "#98c379", "yellow": "#c49a2a", "blue": "#61afef", "purple": "#c678dd", "cyan": "#56b6c2", "white": "#abb2bf", "brightBlack": "#767676", "brightRed": "#e06c75", "brightGreen": "#98c379", "brightYellow": "#e5c07b", "brightBlue": "#61afef", "brightPurple": "#c678dd", "brightCyan": "#56b6c2", "brightWhite": "#abb2bf", "background": "#21252b", "foreground": "#abb2bf", "cursor": "#abb2bf", "selection": "#323844" }
18
- Set Theme "OneDark"
19
-
20
-
21
- Sleep 1s
22
- Type "npx agents-inc init"
23
- Enter
24
- Sleep 3500ms
25
-
26
- # -------------------------------
27
- # STEP STACK
28
-
29
- # select react stack
30
- Down
31
- Sleep 150ms
32
- Down
33
- Sleep 150ms
34
- Down
35
- Sleep 150ms
36
- Down
37
- Sleep 900ms
38
- Enter
39
-
40
- # -------------------------------
41
- # STEP DOMAINS
42
- Sleep 900ms
43
-
44
- # select domain
45
- Down
46
-
47
- # select API
48
- Sleep 600ms
49
- Space
50
- Sleep 600ms
51
-
52
- Down
53
- Sleep 150ms
54
- Down
55
- Sleep 150ms
56
- Down
57
- Sleep 150ms
58
- Down
59
- Sleep 150ms
60
- Down
61
-
62
- # select Infrastructure
63
- Sleep 600ms
64
- Space
65
- Sleep 600ms
66
-
67
- Enter
68
-
69
- # -------------------------------
70
- # STEP SKILLS > WEB
71
- Sleep 900ms
72
-
73
- # select Client State Management > zustand
74
- Down
75
- Sleep 150ms
76
- Down
77
- Sleep 150ms
78
- Down
79
- Sleep 150ms
80
- Down
81
-
82
- Sleep 600ms
83
- Right
84
- Sleep 150ms
85
- Right
86
- Sleep 150ms
87
- Right
88
-
89
- Sleep 600ms
90
- Space
91
- Sleep 600ms
92
-
93
- # select Server State / Data Fetching > React Query
94
- Down
95
-
96
- Sleep 600ms
97
- Left
98
-
99
- Sleep 600ms
100
- Space
101
- Sleep 600ms
102
-
103
- # select Forms & Validation > zod
104
- Down
105
- Sleep 600ms
106
-
107
- Left
108
- Sleep 150ms
109
- Left
110
-
111
- Sleep 600ms
112
- Space
113
- Sleep 600ms
114
-
115
- # select API Mocking > MSW
116
- Down
117
- Sleep 150ms
118
- Down
119
- Sleep 150ms
120
- Down
121
- Sleep 150ms
122
- Down
123
-
124
- Sleep 600ms
125
- Space
126
- Sleep 600ms
127
-
128
- # select Error Handling > Error Boundaries
129
- Down
130
-
131
- Sleep 600ms
132
- Space
133
- Sleep 600ms
134
-
135
- # select Web Performance > Frontend Performance
136
- Down
137
- Sleep 150ms
138
- Down
139
- Sleep 150ms
140
- Down
141
- Sleep 150ms
142
- Down
143
- Sleep 150ms
144
- Down
145
- Sleep 150ms
146
- Down
147
- Sleep 150ms
148
- Down
149
- Sleep 150ms
150
- Down
151
- Sleep 150ms
152
- Down
153
-
154
- Sleep 600ms
155
- Space
156
- Sleep 600ms
157
-
158
- # press enter
159
- Enter
160
-
161
-
162
- # -------------------------------
163
- # STEP SKILLS > API -- SCROLL THROUGH
164
- Sleep 900ms
165
-
166
- Down
167
- Sleep 150ms
168
- Down
169
- Sleep 150ms
170
- Down
171
- Sleep 150ms
172
- Down
173
- Sleep 150ms
174
- Down
175
- Sleep 150ms
176
- Down
177
- Sleep 150ms
178
- Down
179
- Sleep 150ms
180
- Down
181
- Sleep 150ms
182
- Down
183
- Sleep 150ms
184
- Down
185
- Sleep 150ms
186
- Down
187
- Sleep 150ms
188
- Down
189
- Sleep 150ms
190
- Down
191
-
192
- Sleep 600ms
193
-
194
- Enter
195
-
196
-
197
- # -------------------------------
198
- # STEP SKILLS > INFRA
199
- Sleep 900ms
200
-
201
- Right
202
-
203
- # select CI/CD > Github Actions
204
- Sleep 600ms
205
- Space
206
- Sleep 600ms
207
-
208
- Down
209
- Sleep 150ms
210
- Down
211
-
212
- # select Configuration > Environment
213
- Sleep 600ms
214
- Space
215
- Sleep 600ms
216
-
217
- Enter
218
-
219
-
220
- # -------------------------------
221
- # STEP SKILLS > INFRA
222
- Sleep 900ms
223
-
224
- Down
225
- Sleep 150ms
226
- Down
227
-
228
- # select Meta Design > Expressive Typescript
229
- Sleep 600ms
230
- Space
231
- Sleep 600ms
232
-
233
- Enter
234
-
235
-
236
- # -------------------------------
237
- # STEP SKILLS > SHARED
238
- Sleep 900ms
239
-
240
- Enter
241
-
242
-
243
- # -------------------------------
244
- # STEP SOURCES
245
- Sleep 900ms
246
-
247
- Enter
248
-
249
-
250
- # -------------------------------
251
- # STEP AGENTS
252
- Sleep 900ms
253
-
254
- Enter
255
-
256
-
257
- # -------------------------------
258
- # STEP CONFIRM
259
- Sleep 900ms
260
-
261
- Enter
262
-
263
-
264
- # -------------------------------
265
- # POST CONFIRM
266
- Sleep 20000ms
@@ -1 +0,0 @@
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 setupMarketplace = useWizardStore((s) => s.setupMarketplace);\n const { viewportRef, contentRef, contentMarginTop, hiddenAbove, hiddenBelow } = usePanelScroll();\n\n // A project set up from a marketplace named for it is set up from THAT one, whichever the\n // global install's skills it shows come from.\n const sourceNames =\n setupMarketplace === null\n ? formatSkillMarketplaces(skillConfigs)\n : formatSourceDisplayName(setupMarketplace);\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":[]}