@aussieljk/forkbook 0.0.0-stage → 0.0.1-10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +59 -2
- package/assets/addon-vitest/templates/vitest.config.4.template.ts +36 -0
- package/assets/browser/favicon-wrapper.svg +46 -0
- package/assets/browser/favicon.svg +1 -0
- package/assets/browser/inter-LICENSE.txt +92 -0
- package/assets/browser/inter-variable-italic.woff2 +0 -0
- package/assets/browser/inter-variable.woff2 +0 -0
- package/assets/browser/mirror-ball.png +0 -0
- package/assets/builder-vite/iframe.html +83 -0
- package/assets/create/rendererAssets/.eslintrc.json +16 -0
- package/assets/create/rendererAssets/common/Configure.mdx +388 -0
- package/assets/create/rendererAssets/common/assets/accessibility.png +0 -0
- package/assets/create/rendererAssets/common/assets/accessibility.svg +1 -0
- package/assets/create/rendererAssets/common/assets/addon-library.png +0 -0
- package/assets/create/rendererAssets/common/assets/assets.png +0 -0
- package/assets/create/rendererAssets/common/assets/avif-test-image.avif +0 -0
- package/assets/create/rendererAssets/common/assets/context.png +0 -0
- package/assets/create/rendererAssets/common/assets/discord.svg +1 -0
- package/assets/create/rendererAssets/common/assets/docs.png +0 -0
- package/assets/create/rendererAssets/common/assets/figma-plugin.png +0 -0
- package/assets/create/rendererAssets/common/assets/github.svg +1 -0
- package/assets/create/rendererAssets/common/assets/share.png +0 -0
- package/assets/create/rendererAssets/common/assets/styling.png +0 -0
- package/assets/create/rendererAssets/common/assets/testing.png +0 -0
- package/assets/create/rendererAssets/common/assets/theming.png +0 -0
- package/assets/create/rendererAssets/common/assets/tutorials.svg +1 -0
- package/assets/create/rendererAssets/common/assets/youtube.svg +1 -0
- package/assets/create/rendererAssets/common/button.css +30 -0
- package/assets/create/rendererAssets/common/header.css +32 -0
- package/assets/create/rendererAssets/common/page.css +68 -0
- package/assets/create/templates/react-native/index.expo.js +20 -0
- package/assets/create/templates/react-native/index.js +25 -0
- package/assets/docs/addon-backgrounds.gif +0 -0
- package/assets/docs/addon-controls-args-annotated.png +0 -0
- package/assets/docs/addon-controls-args-background-color.png +0 -0
- package/assets/docs/addon-controls-args-background-string.png +0 -0
- package/assets/docs/addon-controls-args-docs.png +0 -0
- package/assets/docs/addon-controls-args-logging.png +0 -0
- package/assets/docs/addon-controls-args-no-annotation.png +0 -0
- package/assets/docs/addon-controls-args-reflow-slider.png +0 -0
- package/assets/docs/addon-controls-args-reflow.png +0 -0
- package/assets/docs/addon-controls-args-template.png +0 -0
- package/assets/docs/addon-controls-expanded.png +0 -0
- package/assets/docs/addon-controls-hero.gif +0 -0
- package/assets/docs/addon-controls-install.png +0 -0
- package/assets/docs/hero.gif +0 -0
- package/assets/docs/highlight.png +0 -0
- package/assets/docs/message-reference.png +0 -0
- package/assets/docs/viewport.png +0 -0
- package/assets/react-native/metro-env.d.ts +69 -0
- package/assets/server/addon.tsconfig.json +6 -0
- package/assets/server/base-preview-body.html +116 -0
- package/assets/server/base-preview-head.html +494 -0
- package/assets/server/openBrowser.applescript +94 -0
- package/assets/server/template.ejs +85 -0
- package/dist/.build-stamp +0 -0
- package/dist/_browser-chunks/Color-X63I7FHI.js +1025 -0
- package/dist/_browser-chunks/DocsRenderer-JXND3PVQ.js +10 -0
- package/dist/_browser-chunks/WithTooltip-5S6F2P7L.js +198 -0
- package/dist/_browser-chunks/chunk-2JDQ35OA.js +247 -0
- package/dist/_browser-chunks/chunk-2JT76G3E.js +104 -0
- package/dist/_browser-chunks/chunk-3HM3VWJS.js +2604 -0
- package/dist/_browser-chunks/chunk-3M5T7BW4.js +43 -0
- package/dist/_browser-chunks/chunk-46Z7NGAS.js +41 -0
- package/dist/_browser-chunks/chunk-4ATQOMJB.js +30 -0
- package/dist/_browser-chunks/chunk-4KIQBRD2.js +17 -0
- package/dist/_browser-chunks/chunk-5H4KFI44.js +386 -0
- package/dist/_browser-chunks/chunk-5I7E4GMO.js +62 -0
- package/dist/_browser-chunks/chunk-5WMXI5GW.js +816 -0
- package/dist/_browser-chunks/chunk-5Z65SURM.js +108 -0
- package/dist/_browser-chunks/chunk-6AKCRYVX.js +6 -0
- package/dist/_browser-chunks/chunk-6ELMKWKX.js +22 -0
- package/dist/_browser-chunks/chunk-76222HQR.js +253 -0
- package/dist/_browser-chunks/chunk-7DQREF4S.js +218 -0
- package/dist/_browser-chunks/chunk-AYRF6EJB.js +36 -0
- package/dist/_browser-chunks/chunk-B4AUNNU4.js +156 -0
- package/dist/_browser-chunks/chunk-BCP2FFXF.js +369 -0
- package/dist/_browser-chunks/chunk-BNP234B4.js +80 -0
- package/dist/_browser-chunks/chunk-C5TKXHTM.js +82 -0
- package/dist/_browser-chunks/chunk-CNED6RYH.js +18 -0
- package/dist/_browser-chunks/chunk-DNJ3OSLB.js +6021 -0
- package/dist/_browser-chunks/chunk-DRQKCCAG.js +136 -0
- package/dist/_browser-chunks/chunk-DS2WQZGO.js +1956 -0
- package/dist/_browser-chunks/chunk-DYNTDJ3O.js +155 -0
- package/dist/_browser-chunks/chunk-ECQ75MKQ.js +0 -0
- package/dist/_browser-chunks/chunk-ENKK74N4.js +12 -0
- package/dist/_browser-chunks/chunk-EQKMUQF3.js +224 -0
- package/dist/_browser-chunks/chunk-FENFYI4X.js +698 -0
- package/dist/_browser-chunks/chunk-FRAOQJDI.js +95 -0
- package/dist/_browser-chunks/chunk-GNZY6LOW.js +10116 -0
- package/dist/_browser-chunks/chunk-GRO2ZYEJ.js +157 -0
- package/dist/_browser-chunks/chunk-I4ATZPNZ.js +34 -0
- package/dist/_browser-chunks/chunk-IE4ULIOQ.js +14 -0
- package/dist/_browser-chunks/chunk-IFADVEQE.js +669 -0
- package/dist/_browser-chunks/chunk-IMSF75WX.js +42 -0
- package/dist/_browser-chunks/chunk-IWQGIXJS.js +14 -0
- package/dist/_browser-chunks/chunk-JPUOQJUI.js +8 -0
- package/dist/_browser-chunks/chunk-JWSKPMPC.js +73 -0
- package/dist/_browser-chunks/chunk-KBK7GKBN.js +35 -0
- package/dist/_browser-chunks/chunk-KYSD26D6.js +1966 -0
- package/dist/_browser-chunks/chunk-LAWXTSXK.js +18 -0
- package/dist/_browser-chunks/chunk-LE2LTDW3.js +14 -0
- package/dist/_browser-chunks/chunk-LEVSOOLQ.js +48 -0
- package/dist/_browser-chunks/chunk-LTCXWKZO.js +2935 -0
- package/dist/_browser-chunks/chunk-LYYXDWR2.js +411 -0
- package/dist/_browser-chunks/chunk-MJIDTL3X.js +78 -0
- package/dist/_browser-chunks/chunk-MLBOOZL4.js +67 -0
- package/dist/_browser-chunks/chunk-N3NRW5XX.js +117 -0
- package/dist/_browser-chunks/chunk-N5WQGLI7.js +11 -0
- package/dist/_browser-chunks/chunk-NA4ITZTK.js +324 -0
- package/dist/_browser-chunks/chunk-NGMQJMCY.js +53 -0
- package/dist/_browser-chunks/chunk-NPNIBOPF.js +18 -0
- package/dist/_browser-chunks/chunk-NQUD4B7H.js +91 -0
- package/dist/_browser-chunks/chunk-NTUHL5NS.js +54 -0
- package/dist/_browser-chunks/chunk-NULBREPZ.js +43 -0
- package/dist/_browser-chunks/chunk-NZMVUW5T.js +7 -0
- package/dist/_browser-chunks/chunk-O24AZJZ7.js +56 -0
- package/dist/_browser-chunks/chunk-ONTSNQON.js +20 -0
- package/dist/_browser-chunks/chunk-OOETBSA7.js +502 -0
- package/dist/_browser-chunks/chunk-OVH3USFB.js +20 -0
- package/dist/_browser-chunks/chunk-OZZPSYQR.js +14 -0
- package/dist/_browser-chunks/chunk-PJSMZ27A.js +13 -0
- package/dist/_browser-chunks/chunk-PZQRXPVR.js +21 -0
- package/dist/_browser-chunks/chunk-QC4HFS6K.js +41 -0
- package/dist/_browser-chunks/chunk-QDXFODK4.js +274 -0
- package/dist/_browser-chunks/chunk-RBCHTR7C.js +28 -0
- package/dist/_browser-chunks/chunk-RMYQ3QN3.js +294 -0
- package/dist/_browser-chunks/chunk-S6TK43XQ.js +836 -0
- package/dist/_browser-chunks/chunk-SC67XZST.js +18 -0
- package/dist/_browser-chunks/chunk-SFVA4SBT.js +683 -0
- package/dist/_browser-chunks/chunk-SZYFOQMT.js +25 -0
- package/dist/_browser-chunks/chunk-TBJCJXK4.js +18 -0
- package/dist/_browser-chunks/chunk-TTBPZQ24.js +3551 -0
- package/dist/_browser-chunks/chunk-UMDO3KB7.js +205 -0
- package/dist/_browser-chunks/chunk-UMGDO2ZM.js +169 -0
- package/dist/_browser-chunks/chunk-V5U45XXZ.js +24 -0
- package/dist/_browser-chunks/chunk-W7NE2JXW.js +84 -0
- package/dist/_browser-chunks/chunk-WGVAAM43.js +1110 -0
- package/dist/_browser-chunks/chunk-WHQRNHXD.js +8 -0
- package/dist/_browser-chunks/chunk-WOSOWBCA.js +12 -0
- package/dist/_browser-chunks/chunk-WZ7KR7SH.js +85 -0
- package/dist/_browser-chunks/chunk-XKTORVEQ.js +255 -0
- package/dist/_browser-chunks/chunk-XTQCLWVH.js +1500 -0
- package/dist/_browser-chunks/chunk-YI2IBIQS.js +7 -0
- package/dist/_browser-chunks/chunk-ZEHRUHTA.js +6 -0
- package/dist/_browser-chunks/chunk-ZHKZKFY4.js +199 -0
- package/dist/_browser-chunks/matchers-YLBYSYAF.js +1263 -0
- package/dist/_browser-chunks/react-dom-client-4OHE3QDV.js +9 -0
- package/dist/_node-chunks/attached-runtime-PDBJ2EGV.js +282 -0
- package/dist/_node-chunks/builder-manager-VLL26RPG.js +1139 -0
- package/dist/_node-chunks/chunk-3CSGIJKG.js +499 -0
- package/dist/_node-chunks/chunk-3W4KR5GX.js +2609 -0
- package/dist/_node-chunks/chunk-5NRWU7S2.js +194 -0
- package/dist/_node-chunks/chunk-5SMIGUYF.js +102 -0
- package/dist/_node-chunks/chunk-63LPGIV4.js +1049 -0
- package/dist/_node-chunks/chunk-6DHTL5G2.js +35 -0
- package/dist/_node-chunks/chunk-6DRVJCYP.js +299 -0
- package/dist/_node-chunks/chunk-7CV4VEA2.js +620 -0
- package/dist/_node-chunks/chunk-7KD5DKGZ.js +79 -0
- package/dist/_node-chunks/chunk-7O2UIVID.js +82 -0
- package/dist/_node-chunks/chunk-7OY4VMAT.js +90 -0
- package/dist/_node-chunks/chunk-AAL6X7YG.js +1986 -0
- package/dist/_node-chunks/chunk-ACSO4HQP.js +32 -0
- package/dist/_node-chunks/chunk-BDU3ZUMK.js +98 -0
- package/dist/_node-chunks/chunk-BMJPOQ2S.js +11 -0
- package/dist/_node-chunks/chunk-BNEC3EBC.js +28 -0
- package/dist/_node-chunks/chunk-BPL3ERBH.js +347 -0
- package/dist/_node-chunks/chunk-BXDMSX3D.js +30600 -0
- package/dist/_node-chunks/chunk-C3PLG47Q.js +25 -0
- package/dist/_node-chunks/chunk-CEDR5CNM.js +74 -0
- package/dist/_node-chunks/chunk-CKE4R4NL.js +26 -0
- package/dist/_node-chunks/chunk-CSFNS7HA.js +21 -0
- package/dist/_node-chunks/chunk-CZ3V3HHK.js +223 -0
- package/dist/_node-chunks/chunk-DNV3LPV3.js +33 -0
- package/dist/_node-chunks/chunk-DPILYJH4.js +33 -0
- package/dist/_node-chunks/chunk-DQ44ZAEM.js +25 -0
- package/dist/_node-chunks/chunk-DR7NW2MI.js +104 -0
- package/dist/_node-chunks/chunk-DRCP3DQF.js +209 -0
- package/dist/_node-chunks/chunk-EBWZKN2I.js +1297 -0
- package/dist/_node-chunks/chunk-ECOW63CV.js +92 -0
- package/dist/_node-chunks/chunk-ENBDAHOV.js +18 -0
- package/dist/_node-chunks/chunk-FAEOR2AW.js +40 -0
- package/dist/_node-chunks/chunk-FERXOKZY.js +80 -0
- package/dist/_node-chunks/chunk-FJFB7TWU.js +495 -0
- package/dist/_node-chunks/chunk-FQGQ5KHN.js +63 -0
- package/dist/_node-chunks/chunk-FR2ZDWKJ.js +45 -0
- package/dist/_node-chunks/chunk-FRBE7ES4.js +59 -0
- package/dist/_node-chunks/chunk-FWAF5NBL.js +20 -0
- package/dist/_node-chunks/chunk-FXBZWUW3.js +7044 -0
- package/dist/_node-chunks/chunk-FZ453CHY.js +25 -0
- package/dist/_node-chunks/chunk-G2ZUFOHU.js +68 -0
- package/dist/_node-chunks/chunk-GBVWRZHP.js +23 -0
- package/dist/_node-chunks/chunk-GGE7TBVX.js +121 -0
- package/dist/_node-chunks/chunk-GJSYGBI5.js +47 -0
- package/dist/_node-chunks/chunk-GKHLTHYM.js +4744 -0
- package/dist/_node-chunks/chunk-GQYATLH6.js +3708 -0
- package/dist/_node-chunks/chunk-HCP5DG52.js +2743 -0
- package/dist/_node-chunks/chunk-HVOSLI2K.js +20 -0
- package/dist/_node-chunks/chunk-ID3WA6WR.js +171 -0
- package/dist/_node-chunks/chunk-IGOX6TUG.js +95 -0
- package/dist/_node-chunks/chunk-IL7YA7QJ.js +148 -0
- package/dist/_node-chunks/chunk-IUPE4SU2.js +688 -0
- package/dist/_node-chunks/chunk-JVWXCB3L.js +7179 -0
- package/dist/_node-chunks/chunk-K4O2ZAMU.js +57 -0
- package/dist/_node-chunks/chunk-KRWR44KT.js +25 -0
- package/dist/_node-chunks/chunk-KWNBN3DV.js +132 -0
- package/dist/_node-chunks/chunk-LG3NMXCM.js +20 -0
- package/dist/_node-chunks/chunk-LH5QBX2U.js +1001 -0
- package/dist/_node-chunks/chunk-LX2XSPPL.js +59 -0
- package/dist/_node-chunks/chunk-M4QNXI37.js +21 -0
- package/dist/_node-chunks/chunk-MBPHOLXB.js +1218 -0
- package/dist/_node-chunks/chunk-MIWBXEUH.js +26 -0
- package/dist/_node-chunks/chunk-MKUA4ZCG.js +1193 -0
- package/dist/_node-chunks/chunk-MQC7ZY6L.js +5468 -0
- package/dist/_node-chunks/chunk-MRCPS4S3.js +48 -0
- package/dist/_node-chunks/chunk-MY7UVHPL.js +153 -0
- package/dist/_node-chunks/chunk-ND323XCC.js +33 -0
- package/dist/_node-chunks/chunk-NGFFEW2B.js +972 -0
- package/dist/_node-chunks/chunk-OPG46TLN.js +1119 -0
- package/dist/_node-chunks/chunk-PEL4YXU6.js +19 -0
- package/dist/_node-chunks/chunk-QFXAGOIO.js +115 -0
- package/dist/_node-chunks/chunk-QGC3UWR5.js +110 -0
- package/dist/_node-chunks/chunk-QGVU7IFS.js +414 -0
- package/dist/_node-chunks/chunk-QOFBJXPH.js +1525 -0
- package/dist/_node-chunks/chunk-QVLHVO4X.js +532 -0
- package/dist/_node-chunks/chunk-R2ZCFA7I.js +60 -0
- package/dist/_node-chunks/chunk-RC4HPD5Q.js +26 -0
- package/dist/_node-chunks/chunk-RJXAXHDJ.js +415 -0
- package/dist/_node-chunks/chunk-SGEPJMTU.js +1094 -0
- package/dist/_node-chunks/chunk-SYUOBOB5.js +35 -0
- package/dist/_node-chunks/chunk-T5VZYRL2.js +40 -0
- package/dist/_node-chunks/chunk-T6IU66AM.js +69 -0
- package/dist/_node-chunks/chunk-THDTJJMO.js +611 -0
- package/dist/_node-chunks/chunk-TNFH4Y4G.js +1133 -0
- package/dist/_node-chunks/chunk-TY2ZY7AO.js +155 -0
- package/dist/_node-chunks/chunk-TZIT6SZP.js +49 -0
- package/dist/_node-chunks/chunk-VG2KFIOW.js +45 -0
- package/dist/_node-chunks/chunk-VSHYJR23.js +56 -0
- package/dist/_node-chunks/chunk-VUMGWJ6Y.js +844 -0
- package/dist/_node-chunks/chunk-WVRM6DQU.js +3767 -0
- package/dist/_node-chunks/chunk-YU5TVYPS.js +87 -0
- package/dist/_node-chunks/chunk-ZBWAA2EY.js +2106 -0
- package/dist/_node-chunks/chunk-ZD5TUA6I.js +20 -0
- package/dist/_node-chunks/chunk-ZFLK7MY5.js +144 -0
- package/dist/_node-chunks/dist-7OJKTBKL.js +27 -0
- package/dist/_node-chunks/dist-MWP6WLW4.js +16 -0
- package/dist/_node-chunks/local-runtime-V5YTRN24.js +78 -0
- package/dist/_node-chunks/mdx-plugin-CBOD52VP.js +7813 -0
- package/dist/_node-chunks/monorepo-GF6H53U4.js +121 -0
- package/dist/_node-chunks/monorepo-optimized-tests-relaxed-limits-no-story-deletion-K4TTV2DQ.js +121 -0
- package/dist/_node-chunks/optimized-tests-KOTSVWTN.js +22 -0
- package/dist/_node-chunks/pattern-copy-play-M2QNC4IZ.js +807 -0
- package/dist/_node-chunks/postinstallAddon-WXKJL6DP.js +20 -0
- package/dist/_node-chunks/rehype-external-links-3IDE4CYH.js +121 -0
- package/dist/_node-chunks/rehype-slug-GKB3WS3U.js +52 -0
- package/dist/_node-chunks/relaxed-limits-C6QU365N.js +117 -0
- package/dist/_node-chunks/run-TMVS3KKA.js +4792 -0
- package/dist/_node-chunks/run-XWBUPXLN.js +103 -0
- package/dist/_node-chunks/session-id-VMH57SKN.js +23 -0
- package/dist/_node-chunks/setup-KEEJK4WI.js +278 -0
- package/dist/_node-chunks/vitest.config.4.template-74HEE4WJ.js +54 -0
- package/dist/actions/decorator.d.ts +7 -0
- package/dist/actions/decorator.js +44 -0
- package/dist/actions/index.d.ts +67 -0
- package/dist/actions/index.js +29 -0
- package/dist/addon-a11y/index.d.ts +52 -0
- package/dist/addon-a11y/index.js +17 -0
- package/dist/addon-a11y/manager.js +1432 -0
- package/dist/addon-a11y/preset.js +18 -0
- package/dist/addon-a11y/preview.d.ts +17 -0
- package/dist/addon-a11y/preview.js +16 -0
- package/dist/addon-docs/blocks.d.ts +1080 -0
- package/dist/addon-docs/blocks.js +2537 -0
- package/dist/addon-docs/index.d.ts +236 -0
- package/dist/addon-docs/index.js +16 -0
- package/dist/addon-docs/manager.js +90 -0
- package/dist/addon-docs/mdx-react-shim.d.ts +1 -0
- package/dist/addon-docs/mdx-react-shim.js +2 -0
- package/dist/addon-docs/preset.js +378 -0
- package/dist/addon-docs/preview.d.ts +4 -0
- package/dist/addon-docs/preview.js +7 -0
- package/dist/addon-links/index.d.ts +22 -0
- package/dist/addon-links/index.js +23 -0
- package/dist/addon-links/manager.js +14 -0
- package/dist/addon-links/preview.d.ts +6 -0
- package/dist/addon-links/preview.js +12 -0
- package/dist/addon-links/react/index.d.ts +25 -0
- package/dist/addon-links/react/index.js +55 -0
- package/dist/addon-mcp/preset.js +1353 -0
- package/dist/addon-mcp/preview.js +29 -0
- package/dist/addon-mcp/tools/preview-stories/preview-stories-app-script.js +1129 -0
- package/dist/addon-ondevice-actions/index.d.ts +4 -0
- package/dist/addon-ondevice-actions/index.js +11 -0
- package/dist/addon-ondevice-actions/register.js +11 -0
- package/dist/addon-ondevice-controls/index.d.ts +6 -0
- package/dist/addon-ondevice-controls/index.js +14 -0
- package/dist/addon-ondevice-controls/register.js +10 -0
- package/dist/addon-pseudo-states/index.d.ts +35 -0
- package/dist/addon-pseudo-states/index.js +15 -0
- package/dist/addon-pseudo-states/manager.js +53 -0
- package/dist/addon-pseudo-states/preview.d.ts +9 -0
- package/dist/addon-pseudo-states/preview.js +10 -0
- package/dist/addon-themes/index.d.ts +80 -0
- package/dist/addon-themes/index.js +104 -0
- package/dist/addon-themes/manager.js +97 -0
- package/dist/addon-themes/postinstall.js +33 -0
- package/dist/addon-themes/preview.d.ts +6 -0
- package/dist/addon-themes/preview.js +8 -0
- package/dist/addon-vitest/constants.d.ts +132 -0
- package/dist/addon-vitest/constants.js +66 -0
- package/dist/addon-vitest/index.d.ts +4 -0
- package/dist/addon-vitest/index.js +8 -0
- package/dist/addon-vitest/manager.js +665 -0
- package/dist/addon-vitest/node/coverage-reporter.js +1284 -0
- package/dist/addon-vitest/node/vitest.js +674 -0
- package/dist/addon-vitest/postinstall.js +24 -0
- package/dist/addon-vitest/preset.js +942 -0
- package/dist/addon-vitest/vitest-plugin/global-setup.js +162 -0
- package/dist/addon-vitest/vitest-plugin/index.d.ts +56 -0
- package/dist/addon-vitest/vitest-plugin/index.js +463 -0
- package/dist/addon-vitest/vitest-plugin/setup-file-with-project-annotations.js +9 -0
- package/dist/addon-vitest/vitest-plugin/setup-file.browser.4.js +20 -0
- package/dist/addon-vitest/vitest-plugin/setup-file.js +50 -0
- package/dist/addon-vitest/vitest-plugin/test-utils.js +128 -0
- package/dist/babel/index.d.ts +1550 -0
- package/dist/babel/index.js +55 -0
- package/dist/backgrounds/index.d.ts +6 -0
- package/dist/backgrounds/index.js +15 -0
- package/dist/bin/core.js +1706 -0
- package/dist/bin/dispatcher.js +45 -0
- package/dist/bin/loader.js +116 -0
- package/dist/builder-vite/index.d.ts +50 -0
- package/dist/builder-vite/index.js +245 -0
- package/dist/builder-vite/preset.js +27 -0
- package/dist/channels/index.d.ts +2 -0
- package/dist/channels/index.js +352 -0
- package/dist/chunk-BCoJQE-f.d.ts +602 -0
- package/dist/chunk-BGhyFTJO.d.ts +115 -0
- package/dist/chunk-BGkgZp-H.d.ts +214 -0
- package/dist/chunk-BXLImeLy.d.ts +197 -0
- package/dist/chunk-Bpi2tz-6.d.ts +511 -0
- package/dist/chunk-C6PAgHLT.d.ts +12 -0
- package/dist/chunk-CFk6djyM.d.ts +55 -0
- package/dist/chunk-CNqjcOmK.d.ts +15 -0
- package/dist/chunk-CT2iXaHz.d.ts +179 -0
- package/dist/chunk-CV4-Z2pn.d.ts +30 -0
- package/dist/chunk-CYuvV2sR.d.ts +282 -0
- package/dist/chunk-Ct9xd6IM.d.ts +65 -0
- package/dist/chunk-D0NUmzXp.d.ts +253 -0
- package/dist/chunk-D7DwV41f.d.ts +3622 -0
- package/dist/chunk-DDd8BhTY.d.ts +79 -0
- package/dist/chunk-DROZ9oel.d.ts +669 -0
- package/dist/chunk-DaVb55-_.d.ts +124 -0
- package/dist/chunk-DgRNfmj_.d.ts +40 -0
- package/dist/chunk-DgzPaTw9.d.ts +61 -0
- package/dist/chunk-Dm-iHJ-s.d.ts +59 -0
- package/dist/chunk-DoIGKY33.d.ts +666 -0
- package/dist/chunk-Dr3R0DXk.d.ts +40 -0
- package/dist/chunk-Dw_4ad2Y.d.ts +34 -0
- package/dist/chunk-Fg1Fm__9.d.ts +13091 -0
- package/dist/chunk-FjDVzZTj.d.ts +62 -0
- package/dist/chunk-Susgfkap.d.ts +20 -0
- package/dist/chunk-XP8oHzpE.d.ts +6 -0
- package/dist/chunk-pcFXCimE.d.ts +741 -0
- package/dist/cli/index.d.ts +321 -0
- package/dist/cli/index.js +703 -0
- package/dist/cli/skills/content/index.d.ts +72 -0
- package/dist/cli/skills/content/index.js +335 -0
- package/dist/cli/tools/sdk/child-host.d.ts +61 -0
- package/dist/cli/tools/sdk/child-host.js +131 -0
- package/dist/cli/tools/sdk/index.d.ts +137 -0
- package/dist/cli/tools/sdk/index.js +44 -0
- package/dist/cli-commands/bin/index.js +25 -0
- package/dist/client-logger/index.d.ts +31 -0
- package/dist/client-logger/index.js +65 -0
- package/dist/common/index.d.ts +1091 -0
- package/dist/common/index.js +358 -0
- package/dist/components/index.d.ts +1727 -0
- package/dist/components/index.js +7982 -0
- package/dist/core-events/index.d.ts +156 -0
- package/dist/core-events/index.js +138 -0
- package/dist/core-server/index.d.ts +2200 -0
- package/dist/core-server/index.js +4577 -0
- package/dist/core-server/presets/common-manager.js +3744 -0
- package/dist/core-server/presets/common-override-preset.js +83 -0
- package/dist/core-server/presets/common-preset.js +2194 -0
- package/dist/create/bin/index.js +23 -0
- package/dist/create/index.js +25 -0
- package/dist/csf/csf-utils.d.ts +2 -0
- package/dist/csf/csf-utils.js +19 -0
- package/dist/csf/index.d.ts +7 -0
- package/dist/csf/index.js +2077 -0
- package/dist/csf-tools/index.d.ts +1161 -0
- package/dist/csf-tools/index.js +738 -0
- package/dist/docs-tools/index.d.ts +197 -0
- package/dist/docs-tools/index.js +61 -0
- package/dist/highlight/index.d.ts +10 -0
- package/dist/highlight/index.js +15 -0
- package/dist/instrumenter/index.d.ts +113 -0
- package/dist/instrumenter/index.js +2597 -0
- package/dist/manager/_manager-chunks/globals-runtime-BKQscPdC.js +5661 -0
- package/dist/manager/_manager-chunks/globals-runtime-BY3epqww.js +1807 -0
- package/dist/manager/_manager-chunks/globals-runtime-BdGkqNEt.js +45 -0
- package/dist/manager/_manager-chunks/globals-runtime-Bj5KDUJi.js +8935 -0
- package/dist/manager/_manager-chunks/globals-runtime-Bs75QQ_I.js +9987 -0
- package/dist/manager/_manager-chunks/globals-runtime-BweHuXkK.js +6838 -0
- package/dist/manager/_manager-chunks/globals-runtime-CA8AuIRT.js +7617 -0
- package/dist/manager/_manager-chunks/globals-runtime-CBviMKtt.js +446 -0
- package/dist/manager/_manager-chunks/globals-runtime-CJL1dQtn.js +4674 -0
- package/dist/manager/_manager-chunks/globals-runtime-CfurFwS_.js +121 -0
- package/dist/manager/_manager-chunks/globals-runtime-CvIgTRVu.js +1190 -0
- package/dist/manager/_manager-chunks/globals-runtime-DBba3I9c.js +5307 -0
- package/dist/manager/_manager-chunks/globals-runtime-DvV_TF3-.js +12214 -0
- package/dist/manager/_manager-chunks/globals-runtime-DwFqpqya.js +722 -0
- package/dist/manager/_manager-chunks/globals-runtime-NwJK8t0T.js +9274 -0
- package/dist/manager/_manager-chunks/globals-runtime-WZKaeKm9.js +4091 -0
- package/dist/manager/_manager-chunks/globals-runtime-wjkxyMn0.js +5283 -0
- package/dist/manager/_manager-chunks/runtime-5B2mWjEm.js +294 -0
- package/dist/manager/_manager-chunks/runtime-5o_11Jae.js +78 -0
- package/dist/manager/_manager-chunks/runtime-B_nqedQW.js +197 -0
- package/dist/manager/_manager-chunks/runtime-BdGkqNEt.js +45 -0
- package/dist/manager/_manager-chunks/runtime-Bs3bEhuy.js +1232 -0
- package/dist/manager/_manager-chunks/runtime-CBQsKmch.js +2351 -0
- package/dist/manager/_manager-chunks/runtime-DG61zYUm.js +1158 -0
- package/dist/manager/_manager-chunks/runtime-DtCVCy4G.js +6841 -0
- package/dist/manager/_manager-chunks/runtime-P663lpsR.js +528 -0
- package/dist/manager/_manager-chunks/runtime-eBAgOym6.js +9010 -0
- package/dist/manager/_manager-chunks/runtime-j9yqh0tr.js +1023 -0
- package/dist/manager/_manager-chunks/runtime-jj8qYc2n.js +3488 -0
- package/dist/manager/globals-runtime.js +2 -0
- package/dist/manager/globals.d.ts +23 -0
- package/dist/manager/globals.js +26 -0
- package/dist/manager/manager-stores.d.ts +2 -0
- package/dist/manager/manager-stores.js +19 -0
- package/dist/manager/runtime.js +2 -0
- package/dist/manager-api/index.d.ts +2 -0
- package/dist/manager-api/index.js +3247 -0
- package/dist/manager-errors.d.ts +89 -0
- package/dist/manager-errors.js +20 -0
- package/dist/mcp/index.d.ts +270 -0
- package/dist/mcp/index.js +305 -0
- package/dist/mocking-utils/index.d.ts +689 -0
- package/dist/mocking-utils/index.js +526 -0
- package/dist/mocking-utils/mocker-runtime.js +1254 -0
- package/dist/nextjs-vite/config/preview.js +3 -0
- package/dist/nextjs-vite/export-mocks/cache/index.d.ts +25 -0
- package/dist/nextjs-vite/export-mocks/cache/index.js +29 -0
- package/dist/nextjs-vite/export-mocks/headers/index.d.ts +37 -0
- package/dist/nextjs-vite/export-mocks/headers/index.js +54 -0
- package/dist/nextjs-vite/export-mocks/link/index.d.ts +9 -0
- package/dist/nextjs-vite/export-mocks/link/index.js +59 -0
- package/dist/nextjs-vite/export-mocks/navigation/index.d.ts +28 -0
- package/dist/nextjs-vite/export-mocks/navigation/index.js +58 -0
- package/dist/nextjs-vite/export-mocks/router/index.d.ts +34 -0
- package/dist/nextjs-vite/export-mocks/router/index.js +63 -0
- package/dist/nextjs-vite/index.d.ts +92 -0
- package/dist/nextjs-vite/index.js +59 -0
- package/dist/nextjs-vite/node/index.d.ts +6 -0
- package/dist/nextjs-vite/node/index.js +20 -0
- package/dist/nextjs-vite/node-stand-ins/index.d.ts +68 -0
- package/dist/nextjs-vite/node-stand-ins/index.js +145 -0
- package/dist/nextjs-vite/preset.js +727 -0
- package/dist/nextjs-vite/preview.d.ts +20 -0
- package/dist/nextjs-vite/preview.js +11 -0
- package/dist/nextjs-vite/vite-plugin/index.d.ts +6 -0
- package/dist/nextjs-vite/vite-plugin/index.js +19 -0
- package/dist/nextjs-vite-plugin/index.d.ts +27 -0
- package/dist/nextjs-vite-plugin/index.js +908 -0
- package/dist/nextjs-vite-plugin/mocks/storybook.global.js +29 -0
- package/dist/nextjs-vite-plugin/plugins/next-image/alias/image-context.js +8 -0
- package/dist/nextjs-vite-plugin/plugins/next-image/alias/image-default-loader.js +23 -0
- package/dist/nextjs-vite-plugin/plugins/next-image/alias/next-image.js +28 -0
- package/dist/nextjs-vite-plugin/plugins/next-image/alias/next-legacy-image.js +17 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/cache/index.js +29 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/dynamic/index.js +40 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/headers/index.js +55 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/link/index.js +63 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/navigation/index.js +71 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/router/index.js +74 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/rsc/server-only.js +7 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/safe-stable-stringify/index.js +13 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/compatibility/draft-mode.compat.js +7 -0
- package/dist/node-logger/index.d.ts +488 -0
- package/dist/node-logger/index.js +41 -0
- package/dist/oxc-parser/index.d.ts +99 -0
- package/dist/oxc-parser/index.js +273 -0
- package/dist/oxc-parser/worker.js +37 -0
- package/dist/preview/_chunks/runtime-BJwGQok8.js +3873 -0
- package/dist/preview/_chunks/runtime-BPwAnlRx.js +10411 -0
- package/dist/preview/_chunks/runtime-BUnOhg9h.js +6838 -0
- package/dist/preview/_chunks/runtime-BZ4pNS3g.js +284 -0
- package/dist/preview/_chunks/runtime-Bcv1hJky.js +6305 -0
- package/dist/preview/_chunks/runtime-BdGkqNEt.js +45 -0
- package/dist/preview/_chunks/runtime-BgPhfM5P.js +3681 -0
- package/dist/preview/_chunks/runtime-BhSZ1Mwt.js +5262 -0
- package/dist/preview/_chunks/runtime-BsMjBzuq.js +53 -0
- package/dist/preview/_chunks/runtime-C1jgT6tJ.js +4091 -0
- package/dist/preview/_chunks/runtime-CkOhMcXf.js +387 -0
- package/dist/preview/_chunks/runtime-WapFVPAh.js +8484 -0
- package/dist/preview/globals.d.ts +16 -0
- package/dist/preview/globals.js +20 -0
- package/dist/preview/runtime.js +6 -0
- package/dist/preview-api/index.d.ts +4 -0
- package/dist/preview-api/index.js +149 -0
- package/dist/preview-errors.d.ts +186 -0
- package/dist/preview-errors.js +56 -0
- package/dist/react/docgen/docgen-worker.js +37 -0
- package/dist/react/entry-preview-argtypes.js +9 -0
- package/dist/react/entry-preview-docs.js +12 -0
- package/dist/react/entry-preview-rsc.js +11 -0
- package/dist/react/entry-preview.js +22 -0
- package/dist/react/index.d.ts +119 -0
- package/dist/react/index.js +28 -0
- package/dist/react/preset.js +300 -0
- package/dist/react/preview.d.ts +2 -0
- package/dist/react/preview.js +12 -0
- package/dist/react-native/bin/get-stories.js +34 -0
- package/dist/react-native/index.d.ts +160 -0
- package/dist/react-native/index.js +1362 -0
- package/dist/react-native/metro/node.d.ts +83 -0
- package/dist/react-native/metro/node.js +22 -0
- package/dist/react-native/metro/withForkbook.d.ts +2269 -0
- package/dist/react-native/metro/withForkbook.js +139 -0
- package/dist/react-native/preview.d.ts +6 -0
- package/dist/react-native/preview.js +20 -0
- package/dist/react-native/scripts/generate.d.ts +22 -0
- package/dist/react-native/scripts/generate.js +18 -0
- package/dist/react-native/stub.js +20 -0
- package/dist/react-native-theming/index.d.ts +119 -0
- package/dist/react-native-theming/index.js +316 -0
- package/dist/react-native-ui/index.d.ts +129 -0
- package/dist/react-native-ui/index.js +1448 -0
- package/dist/react-native-ui-common/index.d.ts +229 -0
- package/dist/react-native-ui-common/index.js +514 -0
- package/dist/react-vite/index.d.ts +4 -0
- package/dist/react-vite/index.js +8 -0
- package/dist/react-vite/node/index.d.ts +6 -0
- package/dist/react-vite/node/index.js +20 -0
- package/dist/react-vite/preset.d.ts +6 -0
- package/dist/react-vite/preset.js +21 -0
- package/dist/router/index.d.ts +209 -0
- package/dist/router/index.js +1259 -0
- package/dist/server-errors.d.ts +2 -0
- package/dist/server-errors.js +149 -0
- package/dist/shared/open-service/index.d.ts +3 -0
- package/dist/shared/open-service/index.js +115 -0
- package/dist/shared/open-service/services/docgen/worker/docgen-worker.js +75 -0
- package/dist/shared/open-service/toolsets/docs/public.d.ts +1296 -0
- package/dist/shared/open-service/toolsets/docs/public.js +991 -0
- package/dist/telemetry/index.d.ts +314 -0
- package/dist/telemetry/index.js +101 -0
- package/dist/test/index.d.ts +158 -0
- package/dist/test/index.js +19656 -0
- package/dist/theming/create.d.ts +15 -0
- package/dist/theming/create.js +12 -0
- package/dist/theming/index.d.ts +54 -0
- package/dist/theming/index.js +536 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +48 -0
- package/dist/viewport/index.d.ts +275 -0
- package/dist/viewport/index.js +21 -0
- package/package.json +1030 -4
- package/template/nextjs-vite/cli/.eslintrc.json +6 -0
- package/template/nextjs-vite/cli/js/Button.jsx +42 -0
- package/template/nextjs-vite/cli/js/Button.stories.js +49 -0
- package/template/nextjs-vite/cli/js/Configure.mdx +470 -0
- package/template/nextjs-vite/cli/js/Header.jsx +58 -0
- package/template/nextjs-vite/cli/js/Header.stories.js +30 -0
- package/template/nextjs-vite/cli/js/Page.jsx +68 -0
- package/template/nextjs-vite/cli/js/Page.stories.js +28 -0
- package/template/nextjs-vite/cli/ts/Button.stories.ts +54 -0
- package/template/nextjs-vite/cli/ts/Button.tsx +39 -0
- package/template/nextjs-vite/cli/ts/Configure.mdx +446 -0
- package/template/nextjs-vite/cli/ts/Header.stories.ts +34 -0
- package/template/nextjs-vite/cli/ts/Header.tsx +54 -0
- package/template/nextjs-vite/cli/ts/Page.stories.ts +33 -0
- package/template/nextjs-vite/cli/ts/Page.tsx +73 -0
- package/template/react/cli/.eslintrc.json +5 -0
- package/template/react/cli/js/Button.jsx +39 -0
- package/template/react/cli/js/Button.stories.js +49 -0
- package/template/react/cli/js/Header.jsx +56 -0
- package/template/react/cli/js/Header.stories.js +29 -0
- package/template/react/cli/js/Page.jsx +69 -0
- package/template/react/cli/js/Page.stories.js +28 -0
- package/template/react/cli/ts/Button.stories.ts +54 -0
- package/template/react/cli/ts/Button.tsx +37 -0
- package/template/react/cli/ts/Header.stories.ts +34 -0
- package/template/react/cli/ts/Header.tsx +56 -0
- package/template/react/cli/ts/Page.stories.ts +33 -0
- package/template/react/cli/ts/Page.tsx +73 -0
- package/template/react-vite/cli/.eslintrc.json +5 -0
- package/template/react-vite/cli/js/Button.jsx +39 -0
- package/template/react-vite/cli/js/Button.stories.js +49 -0
- package/template/react-vite/cli/js/Header.jsx +56 -0
- package/template/react-vite/cli/js/Header.stories.js +29 -0
- package/template/react-vite/cli/js/Page.jsx +69 -0
- package/template/react-vite/cli/js/Page.stories.js +28 -0
- package/template/react-vite/cli/ts/Button.stories.ts +54 -0
- package/template/react-vite/cli/ts/Button.tsx +37 -0
- package/template/react-vite/cli/ts/Header.stories.ts +34 -0
- package/template/react-vite/cli/ts/Header.tsx +56 -0
- package/template/react-vite/cli/ts/Page.stories.ts +33 -0
- package/template/react-vite/cli/ts/Page.tsx +73 -0
package/dist/bin/core.js
ADDED
|
@@ -0,0 +1,1706 @@
|
|
|
1
|
+
import CJS_COMPAT_NODE_URL_upaeg5sjpn from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_upaeg5sjpn from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_upaeg5sjpn from "node:module";
|
|
4
|
+
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_upaeg5sjpn.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_upaeg5sjpn.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_upaeg5sjpn.createRequire(import.meta.url);
|
|
8
|
+
|
|
9
|
+
// ------------------------------------------------------------
|
|
10
|
+
// end of CJS compatibility banner, injected by Forkbook's esbuild configuration
|
|
11
|
+
// ------------------------------------------------------------
|
|
12
|
+
import {
|
|
13
|
+
readRegistry,
|
|
14
|
+
selectInstances
|
|
15
|
+
} from "../_node-chunks/chunk-KWNBN3DV.js";
|
|
16
|
+
import {
|
|
17
|
+
resolveStorybookConfigDir
|
|
18
|
+
} from "../_node-chunks/chunk-RC4HPD5Q.js";
|
|
19
|
+
import {
|
|
20
|
+
instructions
|
|
21
|
+
} from "../_node-chunks/chunk-QFXAGOIO.js";
|
|
22
|
+
import {
|
|
23
|
+
isReactProject
|
|
24
|
+
} from "../_node-chunks/chunk-IUPE4SU2.js";
|
|
25
|
+
import "../_node-chunks/chunk-FWAF5NBL.js";
|
|
26
|
+
import "../_node-chunks/chunk-LG3NMXCM.js";
|
|
27
|
+
import "../_node-chunks/chunk-BMJPOQ2S.js";
|
|
28
|
+
import {
|
|
29
|
+
createTools,
|
|
30
|
+
reportToolsCommandEvent,
|
|
31
|
+
sanitizeNamePart,
|
|
32
|
+
toCatalogEntry
|
|
33
|
+
} from "../_node-chunks/chunk-MBPHOLXB.js";
|
|
34
|
+
import {
|
|
35
|
+
formatMultiInstanceNotice
|
|
36
|
+
} from "../_node-chunks/chunk-DR7NW2MI.js";
|
|
37
|
+
import {
|
|
38
|
+
ToolsRuntimeError,
|
|
39
|
+
attachGateReasonFromError,
|
|
40
|
+
isAttachGateError
|
|
41
|
+
} from "../_node-chunks/chunk-BDU3ZUMK.js";
|
|
42
|
+
import {
|
|
43
|
+
detectLanguage,
|
|
44
|
+
getStorybookData
|
|
45
|
+
} from "../_node-chunks/chunk-GGE7TBVX.js";
|
|
46
|
+
import {
|
|
47
|
+
isClaudePreviewLaunch,
|
|
48
|
+
resolveSkillInputs
|
|
49
|
+
} from "../_node-chunks/chunk-IL7YA7QJ.js";
|
|
50
|
+
import "../_node-chunks/chunk-PEL4YXU6.js";
|
|
51
|
+
import {
|
|
52
|
+
frameworkToRendererMap
|
|
53
|
+
} from "../_node-chunks/chunk-CSFNS7HA.js";
|
|
54
|
+
import {
|
|
55
|
+
getMonorepoType
|
|
56
|
+
} from "../_node-chunks/chunk-FAEOR2AW.js";
|
|
57
|
+
import {
|
|
58
|
+
version
|
|
59
|
+
} from "../_node-chunks/chunk-ENBDAHOV.js";
|
|
60
|
+
import {
|
|
61
|
+
detectAgent
|
|
62
|
+
} from "../_node-chunks/chunk-C3PLG47Q.js";
|
|
63
|
+
import "../_node-chunks/chunk-MRCPS4S3.js";
|
|
64
|
+
import "../_node-chunks/chunk-TNFH4Y4G.js";
|
|
65
|
+
import "../_node-chunks/chunk-NGFFEW2B.js";
|
|
66
|
+
import "../_node-chunks/chunk-ACSO4HQP.js";
|
|
67
|
+
import "../_node-chunks/chunk-HCP5DG52.js";
|
|
68
|
+
import {
|
|
69
|
+
globalSettings
|
|
70
|
+
} from "../_node-chunks/chunk-T6IU66AM.js";
|
|
71
|
+
import "../_node-chunks/chunk-ECOW63CV.js";
|
|
72
|
+
import {
|
|
73
|
+
leven
|
|
74
|
+
} from "../_node-chunks/chunk-TZIT6SZP.js";
|
|
75
|
+
import {
|
|
76
|
+
getRegisteredToolsets
|
|
77
|
+
} from "../_node-chunks/chunk-FERXOKZY.js";
|
|
78
|
+
import "../_node-chunks/chunk-GJSYGBI5.js";
|
|
79
|
+
import {
|
|
80
|
+
getToolName,
|
|
81
|
+
parseToolsetMethodId,
|
|
82
|
+
toCliMethodName
|
|
83
|
+
} from "../_node-chunks/chunk-LX2XSPPL.js";
|
|
84
|
+
import {
|
|
85
|
+
escapeRegExp
|
|
86
|
+
} from "../_node-chunks/chunk-ZD5TUA6I.js";
|
|
87
|
+
import {
|
|
88
|
+
getService
|
|
89
|
+
} from "../_node-chunks/chunk-BPL3ERBH.js";
|
|
90
|
+
import "../_node-chunks/chunk-AAL6X7YG.js";
|
|
91
|
+
import "../_node-chunks/chunk-DNV3LPV3.js";
|
|
92
|
+
import "../_node-chunks/chunk-5NRWU7S2.js";
|
|
93
|
+
import "../_node-chunks/chunk-KRWR44KT.js";
|
|
94
|
+
import "../_node-chunks/chunk-7KD5DKGZ.js";
|
|
95
|
+
import "../_node-chunks/chunk-MIWBXEUH.js";
|
|
96
|
+
import "../_node-chunks/chunk-SYUOBOB5.js";
|
|
97
|
+
import "../_node-chunks/chunk-G2ZUFOHU.js";
|
|
98
|
+
import "../_node-chunks/chunk-CKE4R4NL.js";
|
|
99
|
+
import "../_node-chunks/chunk-VUMGWJ6Y.js";
|
|
100
|
+
import "../_node-chunks/chunk-T5VZYRL2.js";
|
|
101
|
+
import "../_node-chunks/chunk-LH5QBX2U.js";
|
|
102
|
+
import {
|
|
103
|
+
require_picocolors
|
|
104
|
+
} from "../_node-chunks/chunk-7O2UIVID.js";
|
|
105
|
+
import "../_node-chunks/chunk-HVOSLI2K.js";
|
|
106
|
+
import "../_node-chunks/chunk-7CV4VEA2.js";
|
|
107
|
+
import "../_node-chunks/chunk-OPG46TLN.js";
|
|
108
|
+
import {
|
|
109
|
+
__toESM
|
|
110
|
+
} from "../_node-chunks/chunk-FQGQ5KHN.js";
|
|
111
|
+
|
|
112
|
+
// src/bin/core.ts
|
|
113
|
+
import {
|
|
114
|
+
HandledError as HandledError2,
|
|
115
|
+
getEnvConfig,
|
|
116
|
+
optionalEnvToBoolean,
|
|
117
|
+
parseList
|
|
118
|
+
} from "@aussieljk/forkbook/internal/common";
|
|
119
|
+
import { logTracker, logger as logger3 } from "@aussieljk/forkbook/internal/node-logger";
|
|
120
|
+
import { addToGlobalContext } from "@aussieljk/forkbook/internal/telemetry";
|
|
121
|
+
import { Option as Option2, program } from "commander";
|
|
122
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
123
|
+
|
|
124
|
+
// src/cli/skills/register.ts
|
|
125
|
+
import {
|
|
126
|
+
experimental_loadStorybook,
|
|
127
|
+
withTelemetry
|
|
128
|
+
} from "@aussieljk/forkbook/internal/core-server";
|
|
129
|
+
import { telemetry as telemetry2 } from "@aussieljk/forkbook/internal/telemetry";
|
|
130
|
+
|
|
131
|
+
// src/cli/skills/content/setup-prompts/index.ts
|
|
132
|
+
import { dedent } from "ts-dedent";
|
|
133
|
+
|
|
134
|
+
// src/cli/skills/content/setup-utils/project-overview.ts
|
|
135
|
+
function getProjectOverview(projectInfo) {
|
|
136
|
+
let rows = [
|
|
137
|
+
["Version", projectInfo.storybookVersion || "unknown"],
|
|
138
|
+
["Renderer", projectInfo.rendererPackage || "unknown"],
|
|
139
|
+
["Framework", projectInfo.framework || "unknown"],
|
|
140
|
+
["Builder", projectInfo.builderPackage || "unknown"],
|
|
141
|
+
["Config Dir", `\`${projectInfo.configDir}\``],
|
|
142
|
+
["Language", projectInfo.language === "ts" ? "TypeScript" : "JavaScript"]
|
|
143
|
+
];
|
|
144
|
+
return projectInfo.packageManager && rows.push(["Package Manager", projectInfo.packageManagerName || "unknown"]), rows.push(["Addons", projectInfo.addons.length > 0 ? projectInfo.addons.join(", ") : "none"]), ["## Project Info", "", "| Property | Value |", "|----------|-------|", rows.map(([key, value]) => `| ${key} | ${value} |`).join(`
|
|
145
|
+
`)].join(
|
|
146
|
+
`
|
|
147
|
+
`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// src/cli/skills/content/setup-prompts/index.ts
|
|
152
|
+
var DEFAULT_PROMPT_NAME = "optimized-tests", CURRENTLY_USED_PROMPT = {
|
|
153
|
+
[DEFAULT_PROMPT_NAME]: instructions
|
|
154
|
+
}, FORMERLY_USED_PROMPTS = {
|
|
155
|
+
monorepo: async () => (await import("../_node-chunks/monorepo-GF6H53U4.js")).instructions,
|
|
156
|
+
"optimized-tests": async () => (await import("../_node-chunks/optimized-tests-KOTSVWTN.js")).instructions,
|
|
157
|
+
"relaxed-limits": async () => (await import("../_node-chunks/relaxed-limits-C6QU365N.js")).instructions,
|
|
158
|
+
setup: async () => (await import("../_node-chunks/setup-KEEJK4WI.js")).instructions,
|
|
159
|
+
"pattern-copy-play": async () => (await import("../_node-chunks/pattern-copy-play-M2QNC4IZ.js")).instructions,
|
|
160
|
+
"monorepo-optimized-tests-relaxed-limits-no-story-deletion": async () => (await import("../_node-chunks/monorepo-optimized-tests-relaxed-limits-no-story-deletion-K4TTV2DQ.js")).instructions
|
|
161
|
+
}, PROMPT_NAMES = [
|
|
162
|
+
...Object.keys(CURRENTLY_USED_PROMPT),
|
|
163
|
+
...Object.keys(FORMERLY_USED_PROMPTS)
|
|
164
|
+
], EVAL_SETUP_PROMPT_ENV = "EVAL_SETUP_PROMPT";
|
|
165
|
+
function resolvePromptName() {
|
|
166
|
+
let requested = process.env[EVAL_SETUP_PROMPT_ENV]?.trim();
|
|
167
|
+
return requested && (Object.hasOwn(CURRENTLY_USED_PROMPT, requested) || Object.hasOwn(FORMERLY_USED_PROMPTS, requested)) ? requested : DEFAULT_PROMPT_NAME;
|
|
168
|
+
}
|
|
169
|
+
async function getSetupPrompt(projectInfo) {
|
|
170
|
+
let requestedName = resolvePromptName(), name = !isReactProject(projectInfo) && ["setup", "pattern-copy-play"].includes(requestedName) ? DEFAULT_PROMPT_NAME : requestedName;
|
|
171
|
+
return { content: (CURRENTLY_USED_PROMPT[name] ?? await FORMERLY_USED_PROMPTS[name]())(projectInfo), name };
|
|
172
|
+
}
|
|
173
|
+
async function getSetupMarkdownOutput(projectInfo) {
|
|
174
|
+
let { content, name } = await getSetupPrompt(projectInfo);
|
|
175
|
+
return {
|
|
176
|
+
markdown: dedent`
|
|
177
|
+
# Forkbook Setup
|
|
178
|
+
|
|
179
|
+
${getProjectOverview(projectInfo)}
|
|
180
|
+
|
|
181
|
+
${content}
|
|
182
|
+
`,
|
|
183
|
+
prompt: name
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/cli/skills/project-info.ts
|
|
188
|
+
import { getPrettyPackageManagerName } from "@aussieljk/forkbook/internal/common";
|
|
189
|
+
import { SupportedLanguage } from "@aussieljk/forkbook/internal/types";
|
|
190
|
+
function parseMajorVersion(version2) {
|
|
191
|
+
let match = version2.match(/^(\d+)/);
|
|
192
|
+
return match ? parseInt(match[1], 10) : void 0;
|
|
193
|
+
}
|
|
194
|
+
async function getProjectInfo(opts) {
|
|
195
|
+
try {
|
|
196
|
+
let data = await getStorybookData({ configDir: opts.configDir });
|
|
197
|
+
if (!data.frameworkPackage || !data.rendererPackage || !data.builderPackage)
|
|
198
|
+
return {
|
|
199
|
+
ok: !1,
|
|
200
|
+
message: "Could not detect framework, renderer, or builder from your Forkbook config. Make sure you are running this command from your project root, or specify --config-dir."
|
|
201
|
+
};
|
|
202
|
+
let majorVersion = data.versionInstalled ? parseMajorVersion(data.versionInstalled) : void 0, language = await detectLanguage(data.packageManager, data.workingDir) === SupportedLanguage.TYPESCRIPT ? "ts" : "js";
|
|
203
|
+
return { ok: !0, projectInfo: {
|
|
204
|
+
storybookVersion: data.versionInstalled,
|
|
205
|
+
majorVersion,
|
|
206
|
+
framework: data.frameworkPackage,
|
|
207
|
+
rendererPackage: data.rendererPackage,
|
|
208
|
+
renderer: data.renderer,
|
|
209
|
+
builderPackage: data.builderPackage,
|
|
210
|
+
addons: data.addons ?? [],
|
|
211
|
+
configDir: data.configDir,
|
|
212
|
+
storiesPaths: data.storiesPaths,
|
|
213
|
+
packageManager: data.packageManager,
|
|
214
|
+
packageManagerName: getPrettyPackageManagerName(data.packageManager.type),
|
|
215
|
+
language,
|
|
216
|
+
hasCsfFactoryPreview: data.hasCsfFactoryPreview,
|
|
217
|
+
monorepoType: getMonorepoType()
|
|
218
|
+
} };
|
|
219
|
+
} catch (err) {
|
|
220
|
+
return {
|
|
221
|
+
ok: !1,
|
|
222
|
+
message: `Failed to read Forkbook configuration: ${err instanceof Error ? err.message : String(err)}
|
|
223
|
+
Make sure you are running this command from your project root, or specify --config-dir.`
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/cli/skills/record-setup-run.ts
|
|
229
|
+
import { resolve } from "node:path";
|
|
230
|
+
import { cache } from "@aussieljk/forkbook/internal/common";
|
|
231
|
+
import { telemetry } from "@aussieljk/forkbook/internal/telemetry";
|
|
232
|
+
async function recordSetupRun({ projectInfo, prompt }) {
|
|
233
|
+
let runId = Math.random().toString(36), configDir = resolve(projectInfo.configDir);
|
|
234
|
+
await cache.set("ai-setup-ran", {
|
|
235
|
+
timestamp: Date.now(),
|
|
236
|
+
runId,
|
|
237
|
+
configDir
|
|
238
|
+
}).catch(() => {
|
|
239
|
+
}), await telemetry(
|
|
240
|
+
"ai-setup",
|
|
241
|
+
{
|
|
242
|
+
cliOptions: {
|
|
243
|
+
packageManager: projectInfo.packageManager.type,
|
|
244
|
+
prompt
|
|
245
|
+
},
|
|
246
|
+
project: {
|
|
247
|
+
framework: projectInfo.framework,
|
|
248
|
+
renderer: projectInfo.rendererPackage,
|
|
249
|
+
builder: projectInfo.builderPackage,
|
|
250
|
+
language: projectInfo.language
|
|
251
|
+
},
|
|
252
|
+
runId
|
|
253
|
+
},
|
|
254
|
+
{ configDir }
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// src/cli/skills/run.ts
|
|
259
|
+
import { relative } from "node:path";
|
|
260
|
+
|
|
261
|
+
// src/cli/tools/help.ts
|
|
262
|
+
import * as v2 from "valibot";
|
|
263
|
+
|
|
264
|
+
// src/cli/tools/schema-lines.ts
|
|
265
|
+
import * as v from "valibot";
|
|
266
|
+
var JsonSchemaNodeSchema = v.lazy(
|
|
267
|
+
() => v.looseObject({
|
|
268
|
+
type: v.optional(v.string()),
|
|
269
|
+
description: v.optional(v.string()),
|
|
270
|
+
properties: v.optional(v.record(v.string(), JsonSchemaNodeSchema)),
|
|
271
|
+
required: v.optional(v.array(v.string())),
|
|
272
|
+
items: v.optional(v.union([JsonSchemaNodeSchema, v.array(JsonSchemaNodeSchema)])),
|
|
273
|
+
anyOf: v.optional(v.array(JsonSchemaNodeSchema)),
|
|
274
|
+
oneOf: v.optional(v.array(JsonSchemaNodeSchema))
|
|
275
|
+
})
|
|
276
|
+
), MAX_SCHEMA_DEPTH = 4;
|
|
277
|
+
function schemaItem(schema) {
|
|
278
|
+
return Array.isArray(schema.items) ? schema.items[0] : schema.items;
|
|
279
|
+
}
|
|
280
|
+
function schemaTypeLabel(schema) {
|
|
281
|
+
if (schema.type === "array") {
|
|
282
|
+
let item = schemaItem(schema);
|
|
283
|
+
return item?.type ? `array of ${item.type}` : "array";
|
|
284
|
+
}
|
|
285
|
+
return schema.anyOf || schema.oneOf ? "one of" : schema.type;
|
|
286
|
+
}
|
|
287
|
+
function schemaChildLines(schema, indent, depth) {
|
|
288
|
+
if (depth <= 0)
|
|
289
|
+
return [];
|
|
290
|
+
let lines = [];
|
|
291
|
+
if (schema.type === "object" && schema.properties) {
|
|
292
|
+
let required = new Set(schema.required ?? []);
|
|
293
|
+
for (let [name, child] of Object.entries(schema.properties))
|
|
294
|
+
lines.push(...schemaLines(`\`${name}\``, child, required.has(name), indent, depth));
|
|
295
|
+
}
|
|
296
|
+
let item = schemaItem(schema);
|
|
297
|
+
item && (item.type === "object" && item.properties || item.anyOf || item.oneOf) && (lines.push(`${indent}each item:`), lines.push(...schemaChildLines(item, `${indent} `, depth - 1)));
|
|
298
|
+
let variants = schema.anyOf ?? schema.oneOf;
|
|
299
|
+
return variants && variants.forEach((variant, index) => {
|
|
300
|
+
let suffix = variant.description ? `: ${variant.description}` : "";
|
|
301
|
+
lines.push(`${indent}option ${index + 1}${suffix}`), lines.push(...schemaChildLines(variant, `${indent} `, depth - 1));
|
|
302
|
+
}), lines;
|
|
303
|
+
}
|
|
304
|
+
function schemaLines(label, schema, isRequired, indent, depth) {
|
|
305
|
+
let meta = [schemaTypeLabel(schema), isRequired ? "required" : void 0].filter(Boolean).join(", "), description = schema.description ? `: ${schema.description}` : "";
|
|
306
|
+
return [`${indent}- ${label}${meta ? ` (${meta})` : ""}${description}`, ...schemaChildLines(schema, `${indent} `, depth - 1)];
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// src/cli/tools/tool-tokens.ts
|
|
310
|
+
function parseToolsTokens(tokens, defaults = {}) {
|
|
311
|
+
let rawInput = defaults.input, help = defaults.help ?? !1, json = defaults.json ?? !1, output = defaults.output, attach = defaults.attach, flagArgs = {}, i = 0;
|
|
312
|
+
for (; i < tokens.length; ) {
|
|
313
|
+
let token = tokens[i];
|
|
314
|
+
if (i += 1, token === "--help" || token === "-h") {
|
|
315
|
+
help = !0;
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
if (token === "--json") {
|
|
319
|
+
json = !0;
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
if (token === "--attach") {
|
|
323
|
+
if (attach === !1)
|
|
324
|
+
return { ok: !1, error: "Cannot combine `--attach` and `--no-attach`." };
|
|
325
|
+
attach = !0;
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
if (token === "--no-attach") {
|
|
329
|
+
if (attach === !0)
|
|
330
|
+
return { ok: !1, error: "Cannot combine `--attach` and `--no-attach`." };
|
|
331
|
+
attach = !1;
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (token === "-o") {
|
|
335
|
+
if (i >= tokens.length || tokens[i].startsWith("-"))
|
|
336
|
+
return { ok: !1, error: "`-o` requires a file path." };
|
|
337
|
+
output = tokens[i], i += 1;
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
if (!token.startsWith("--") || token === "--")
|
|
341
|
+
return {
|
|
342
|
+
ok: !1,
|
|
343
|
+
error: `Unexpected argument \`${token}\`. Tool arguments must be passed as \`--key value\` flags (or via \`--input '<object>'\`).`
|
|
344
|
+
};
|
|
345
|
+
let key = token.slice(2), value, equalsIndex = key.indexOf("=");
|
|
346
|
+
if (equalsIndex !== -1 ? (value = key.slice(equalsIndex + 1), key = key.slice(0, equalsIndex)) : i < tokens.length && !tokens[i].startsWith("--") && (value = tokens[i], i += 1), key === "")
|
|
347
|
+
return { ok: !1, error: `Invalid flag \`${token}\`.` };
|
|
348
|
+
if (key === "help" || key === "json" || key === "attach" || key === "no-attach")
|
|
349
|
+
return { ok: !1, error: `\`--${key}\` does not take a value.` };
|
|
350
|
+
if (key === "output") {
|
|
351
|
+
if (!value)
|
|
352
|
+
return { ok: !1, error: "`--output` requires a file path." };
|
|
353
|
+
output = value;
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
if (key === "input") {
|
|
357
|
+
if (value === void 0)
|
|
358
|
+
return { ok: !1, error: "`--input` requires a value." };
|
|
359
|
+
rawInput = value;
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
flagArgs[key] = value === void 0 ? !0 : coerceValue(value);
|
|
363
|
+
}
|
|
364
|
+
let inputArgs = {};
|
|
365
|
+
if (rawInput !== void 0) {
|
|
366
|
+
let parsed;
|
|
367
|
+
try {
|
|
368
|
+
parsed = JSON.parse(rawInput);
|
|
369
|
+
} catch (error) {
|
|
370
|
+
return {
|
|
371
|
+
ok: !1,
|
|
372
|
+
error: `\`--input\` must be valid JSON: ${error instanceof Error ? error.message : String(error)}`
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
if (typeof parsed != "object" || parsed === null || Array.isArray(parsed))
|
|
376
|
+
return {
|
|
377
|
+
ok: !1,
|
|
378
|
+
error: '`--input` must be a JSON object, e.g. \'{"id": "button-docs"}\'.'
|
|
379
|
+
};
|
|
380
|
+
inputArgs = parsed;
|
|
381
|
+
}
|
|
382
|
+
return { ok: !0, help, json, output, attach, args: { ...inputArgs, ...flagArgs } };
|
|
383
|
+
}
|
|
384
|
+
function isJsonToolsRun(tokens, defaults = {}) {
|
|
385
|
+
let parsed = parseToolsTokens(tokens, defaults);
|
|
386
|
+
return parsed.ok && parsed.json && !parsed.help;
|
|
387
|
+
}
|
|
388
|
+
function coerceValue(raw) {
|
|
389
|
+
try {
|
|
390
|
+
return JSON.parse(raw);
|
|
391
|
+
} catch {
|
|
392
|
+
return raw;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
function parsePort(rawPort) {
|
|
396
|
+
if (rawPort === void 0)
|
|
397
|
+
return { ok: !0, port: void 0 };
|
|
398
|
+
let port = Number(rawPort);
|
|
399
|
+
return !Number.isInteger(port) || port < 1 || port > 65535 ? {
|
|
400
|
+
ok: !1,
|
|
401
|
+
error: `\`--port\` must be a port number (1-65535), got \`${rawPort}\`.`
|
|
402
|
+
} : { ok: !0, port };
|
|
403
|
+
}
|
|
404
|
+
var TOOLS_OPTION_SPECS = [
|
|
405
|
+
{ flags: "--cwd <path>", description: "Project directory of the target Forkbook" },
|
|
406
|
+
{
|
|
407
|
+
flags: "-c, --config-dir <dir-name>",
|
|
408
|
+
description: "Forkbook config directory of the target Forkbook"
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
flags: "-p, --port <number>",
|
|
412
|
+
description: "Port of a running Forkbook; targets that instance directly, no --cwd or --config-dir needed"
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
flags: "--attach",
|
|
416
|
+
description: "Require attaching to a running Forkbook; gate failures are errors instead of a local fallback"
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
flags: "--no-attach",
|
|
420
|
+
description: "Load the project configuration without attaching"
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
flags: "--input <object>",
|
|
424
|
+
description: "Raw JSON object with the tool arguments (escape hatch for complex values)"
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
flags: "--json",
|
|
428
|
+
description: "Print the tool's structured result data as JSON instead of markdown"
|
|
429
|
+
},
|
|
430
|
+
{ flags: "-o, --output <path>", description: "Write the result to a file instead of stdout" },
|
|
431
|
+
{
|
|
432
|
+
flags: "-h, --help",
|
|
433
|
+
description: "List the tools of the target Forkbook, or show one tool with its arguments"
|
|
434
|
+
}
|
|
435
|
+
];
|
|
436
|
+
|
|
437
|
+
// src/cli/tools/help.ts
|
|
438
|
+
var LOCAL_BADGE = "[local]", DEV_SERVER_BADGE = "[requires running Forkbook]";
|
|
439
|
+
function optionLines() {
|
|
440
|
+
let column = Math.max(...TOOLS_OPTION_SPECS.map((spec) => spec.flags.length)) + 2;
|
|
441
|
+
return TOOLS_OPTION_SPECS.map((spec) => ` ${spec.flags.padEnd(column)}${spec.description}`);
|
|
442
|
+
}
|
|
443
|
+
function indented(lines, depth) {
|
|
444
|
+
let pad = " ".repeat(depth);
|
|
445
|
+
return lines.flatMap((line) => line.split(`
|
|
446
|
+
`)).map((line) => line && pad + line);
|
|
447
|
+
}
|
|
448
|
+
function cliPath(method) {
|
|
449
|
+
let { toolsetId, methodName } = parseToolsetMethodId(method.ref);
|
|
450
|
+
return `${toolsetId} ${toCliMethodName(methodName)}`;
|
|
451
|
+
}
|
|
452
|
+
function badge(method) {
|
|
453
|
+
return method.requiresDevServer ? DEV_SERVER_BADGE : LOCAL_BADGE;
|
|
454
|
+
}
|
|
455
|
+
function argumentLines(schema, flagPrefix) {
|
|
456
|
+
if (schema !== void 0)
|
|
457
|
+
return propertyLines(schema, { flagPrefix });
|
|
458
|
+
}
|
|
459
|
+
function methodBodyLines(method) {
|
|
460
|
+
let lines = [method.description.trim()], inputLines = argumentLines(method.input, !0);
|
|
461
|
+
inputLines === void 0 ? lines.push("", "Arguments: (this schema could not be rendered)") : inputLines.length === 0 ? lines.push("", "Arguments: none.") : lines.push("", "Arguments:", ...inputLines);
|
|
462
|
+
let outputLines = argumentLines(method.output, !1);
|
|
463
|
+
return outputLines && outputLines.length > 0 && lines.push("", "Output (`--json`):", ...outputLines), lines;
|
|
464
|
+
}
|
|
465
|
+
function propertyLines(schema, { flagPrefix }) {
|
|
466
|
+
let properties = Object.entries(
|
|
467
|
+
schema.properties ?? {}
|
|
468
|
+
), required = new Set(schema.required ?? []), lines = [];
|
|
469
|
+
for (let [name, propertySchema] of properties) {
|
|
470
|
+
let parsed = v2.safeParse(JsonSchemaNodeSchema, propertySchema), node = parsed.success ? parsed.output : {}, label = flagPrefix ? `\`--${name}\`` : `\`${name}\``;
|
|
471
|
+
lines.push(...schemaLines(label, node, required.has(name), "", MAX_SCHEMA_DEPTH));
|
|
472
|
+
}
|
|
473
|
+
return lines;
|
|
474
|
+
}
|
|
475
|
+
function renderToolsetSection(entry) {
|
|
476
|
+
let sections = [`${entry.id} \u2014 ${entry.description}`];
|
|
477
|
+
for (let method of entry.methods) {
|
|
478
|
+
let heading = ` ${cliPath(method)} ${badge(method)}`;
|
|
479
|
+
sections.push([heading, "", ...indented(methodBodyLines(method), 4)].join(`
|
|
480
|
+
`));
|
|
481
|
+
}
|
|
482
|
+
return sections.join(`
|
|
483
|
+
|
|
484
|
+
`);
|
|
485
|
+
}
|
|
486
|
+
function renderToolsHelpFromCatalog(catalog) {
|
|
487
|
+
let commands = catalog.toolsets.flatMap(
|
|
488
|
+
(toolset) => toolset.methods.map((method) => ({
|
|
489
|
+
path: cliPath(method),
|
|
490
|
+
summary: method.title,
|
|
491
|
+
badge: badge(method)
|
|
492
|
+
}))
|
|
493
|
+
), column = commands.length === 0 ? 0 : Math.max(...commands.map((command2) => command2.path.length)) + 2, commandBlock = commands.length === 0 ? " (none)" : commands.map((command2) => ` ${command2.path.padEnd(column)}${command2.summary} ${command2.badge}`).join(`
|
|
494
|
+
`), header = [
|
|
495
|
+
"Usage: npx forkbook tools [options] [toolset] [tool] [args...]",
|
|
496
|
+
"",
|
|
497
|
+
`Forkbook tools from the Forkbook configuration at ${catalog.configDir}.`,
|
|
498
|
+
"",
|
|
499
|
+
"Options:",
|
|
500
|
+
...optionLines(),
|
|
501
|
+
"",
|
|
502
|
+
"Commands:",
|
|
503
|
+
commandBlock
|
|
504
|
+
].join(`
|
|
505
|
+
`), notes = [
|
|
506
|
+
`${LOCAL_BADGE} tools run without a running Forkbook.`,
|
|
507
|
+
`${DEV_SERVER_BADGE} tools need a running Forkbook dev server; start it first.`,
|
|
508
|
+
"Individual `--key value` flags override entries of `--input`.",
|
|
509
|
+
"Run `npx forkbook tools <toolset> <tool> --help` for the description, arguments and `--json` output of one tool."
|
|
510
|
+
].join(`
|
|
511
|
+
`);
|
|
512
|
+
return [header, notes].join(`
|
|
513
|
+
|
|
514
|
+
`);
|
|
515
|
+
}
|
|
516
|
+
function renderToolsetHelpFromCatalog(entry) {
|
|
517
|
+
return [
|
|
518
|
+
`Usage: npx forkbook tools ${entry.id} <tool> [--key value ...]`,
|
|
519
|
+
"",
|
|
520
|
+
renderToolsetSection(entry)
|
|
521
|
+
].join(`
|
|
522
|
+
`);
|
|
523
|
+
}
|
|
524
|
+
function renderMethodHelpFromCatalog(method) {
|
|
525
|
+
return [
|
|
526
|
+
`Usage: npx forkbook tools ${cliPath(method)} [--key value ...]`,
|
|
527
|
+
"",
|
|
528
|
+
method.requiresDevServer ? "Execution: requires a running Forkbook dev server; start it first." : "Execution: local (no running Forkbook required).",
|
|
529
|
+
"",
|
|
530
|
+
...methodBodyLines(method)
|
|
531
|
+
].join(`
|
|
532
|
+
`);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// src/cli/skills/command-reference.ts
|
|
536
|
+
var toCommand = getToolName({ transport: "cli" });
|
|
537
|
+
function findReferredTools(skillText, toolsets) {
|
|
538
|
+
return toolsets.flatMap(
|
|
539
|
+
(toolset) => toolset.methods.filter(
|
|
540
|
+
(method) => (
|
|
541
|
+
// The lookahead keeps `docs show-story` from counting as a mention of `docs show`.
|
|
542
|
+
new RegExp(`${escapeRegExp(toCommand(method.ref))}(?![\\w-])`).test(skillText)
|
|
543
|
+
)
|
|
544
|
+
)
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
function renderCommandReference(skillText, toolsets) {
|
|
548
|
+
let referred = findReferredTools(skillText, toolsets), namedToolsets = toolsets.filter(
|
|
549
|
+
(toolset) => toolset.methods.some((method) => referred.includes(method))
|
|
550
|
+
);
|
|
551
|
+
for (; ; ) {
|
|
552
|
+
let text = [skillText, ...referred.map(renderMethodHelpFromCatalog)].join(`
|
|
553
|
+
`), found = findReferredTools(text, namedToolsets);
|
|
554
|
+
if (found.length === referred.length)
|
|
555
|
+
break;
|
|
556
|
+
referred = found;
|
|
557
|
+
}
|
|
558
|
+
return referred.length === 0 ? "" : [
|
|
559
|
+
"# Command reference",
|
|
560
|
+
"`--json` only changes the output format; to pass all arguments as one JSON object, use `--input '<json>'`.",
|
|
561
|
+
...referred.map((method) => ["```text", renderMethodHelpFromCatalog(method), "```"].join(`
|
|
562
|
+
`))
|
|
563
|
+
].join(`
|
|
564
|
+
|
|
565
|
+
`);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// src/cli/skills/content/build-stories-skill.ts
|
|
569
|
+
var ref = getToolName({ transport: "cli" });
|
|
570
|
+
function docsSection() {
|
|
571
|
+
return `## Look up components first
|
|
572
|
+
|
|
573
|
+
\`\`\`sh
|
|
574
|
+
${ref("docs.list")} # every component and docs page, with its id
|
|
575
|
+
${ref("docs.show")} --id <id> # props and usage examples of one entry
|
|
576
|
+
${ref("docs.showStory")} --storyId <id> # the code of a story that docs show only lists
|
|
577
|
+
\`\`\`
|
|
578
|
+
|
|
579
|
+
Do this before you edit any file: run \`docs list\` once, then \`docs show\` for every listed component your change uses, even one you only add such as a button, and for each one you are asked about. Reuse what exists instead of building a duplicate. Use only the props that \`docs show\` documents, never one you assume from a name or another library, and answer props, API and usage questions from these commands. Read source files or \`node_modules\` only when the commands return nothing relevant. When \`docs list\` groups its entries under sources (\`id: acme\`), pass the source of the entry to both commands that show it: \`--storybookId acme\`.`;
|
|
580
|
+
}
|
|
581
|
+
function writeSection({
|
|
582
|
+
framework,
|
|
583
|
+
csfFactories,
|
|
584
|
+
previewFile,
|
|
585
|
+
typescript
|
|
586
|
+
}) {
|
|
587
|
+
return `## Write the component and its stories
|
|
588
|
+
|
|
589
|
+
Every component you create or change gets stories: one per distinct state it can reach (variants, loading, empty, error, disabled), with realistic props. Never export a story under the name of a global such as \`Error\`: export \`ErrorState\` and set \`name: 'Error'\`. An interactive component also gets a \`play\` function that drives it and asserts the visible result; for a callback passed as \`fn()\`, assert whether it was called, as that state expects. The rules below are for the stories you write; do not rewrite existing stories only to match them.
|
|
590
|
+
|
|
591
|
+
- ${csfFactories ? `This project writes stories with CSF Factories, because \`${previewFile}\` uses \`definePreview\`: \`import preview from '../.forkbook/preview'\` (the path to that file), then \`const meta = preview.meta({ component: Button })\` and \`export const Primary = meta.story({ args: { ... } })\`. Do not import \`Meta\` or \`StoryObj\`. Import` : typescript ? `Import \`Meta\` and \`StoryObj\` from \`${framework}\`, and` : "Import"} \`fn\`, \`expect\`, \`mocked\` and \`sb\` from \`@aussieljk/forkbook/test\`.
|
|
592
|
+
- \`play: async ({ canvas, userEvent }) => { ... }\`: query \`canvas\` directly, by role or label. Never wrap it in \`within()\`. \`userEvent.click(element)\` takes no options.
|
|
593
|
+
- A story never calls a real service. Mock network requests with MSW, never with a module mock or a replaced \`fetch\`: give the story \`beforeEach({ msw }) { msw.use(http.get('/api/users', () => HttpResponse.json([...]))) }\`, and leave the code that calls \`fetch\` as it is. When the project has no \`msw-storybook-addon\` yet, set it up first: install \`msw\` and \`msw-storybook-addon\` as dev dependencies, run \`npx msw init ./public --save\` (\`../public\` has to be in \`staticDirs\` of the main config), and add ${csfFactories ? "`addons: [addonMsw()]` (`import addonMsw from 'msw-storybook-addon'`, without an `initialize()` call)" : "`loaders: [mswLoader()]` (`import { mswLoader } from 'msw-storybook-addon/csf3'`, without an `initialize()` call)"} to \`${previewFile}\`. Read the addon's version in \`package.json\`: only before version 3 do stories have no \`msw\` in \`beforeEach\` and take \`parameters: { msw: { handlers: [...] } }\` instead. From version 3 on, never write \`parameters.msw\`.
|
|
594
|
+
- Mock a module only for a dependency that is not a network call: register it in \`${previewFile}\` with \`sb.mock(import('../src/api.${typescript ? "ts" : "js"}'), { spy: true })\` (path relative to that file, with its extension), then set the result per story in \`beforeEach\` with \`mocked(getUser).mockResolvedValue(...)\`.`;
|
|
595
|
+
}
|
|
596
|
+
function testSection(a11yEnabled) {
|
|
597
|
+
let a11y = a11yEnabled ? "\n\nThe run lists accessibility violations under `## Accessibility Violations`. Fix semantic ones yourself (roles, labels, alt text, keyboard access). For visual ones such as color contrast, do not change the design: describe the problem, offer two or three options and ask the user." : "";
|
|
598
|
+
return `## Test
|
|
599
|
+
|
|
600
|
+
\`\`\`sh
|
|
601
|
+
${ref("test.run")} --stories '[{"storyId":"<id>"}]' # ids: see "Find the stories"; leave out --stories to run every story
|
|
602
|
+
\`\`\`
|
|
603
|
+
|
|
604
|
+
Run this after every change. It is the only way to run story tests: never a \`package.json\` test script (such as \`npm run test:stories\`) or \`vitest\` directly, also when the user asks you to run the tests. Use focused runs while iterating and one full run before you finish. Fix failures and rerun; never finish with failing tests.${a11y}`;
|
|
605
|
+
}
|
|
606
|
+
function discoverSection(inputs) {
|
|
607
|
+
let commands = [
|
|
608
|
+
inputs.moduleGraphSupported && `${ref("stories.changed")} # stories affected by your uncommitted changes`,
|
|
609
|
+
inputs.moduleGraphSupported && `${ref("stories.findByComponent")} --componentPaths '["/abs/path/Button.tsx"]' # stories that render these files`,
|
|
610
|
+
inputs.docsEnabled && `${ref("docs.list")} --withStoryIds true # every story id`
|
|
611
|
+
].filter(Boolean);
|
|
612
|
+
if (commands.length === 0)
|
|
613
|
+
return `## Find the stories
|
|
614
|
+
|
|
615
|
+
This project has no command that lists story ids. Select a story by its file and export instead: \`--stories '[{"absoluteStoryPath":"/abs/path/Button.stories.tsx","exportName":"Primary"}]'\`.`;
|
|
616
|
+
let several = commands.length > 1, guidance = [
|
|
617
|
+
inputs.moduleGraphSupported && "Run `stories changed` or `find-by-component` before every review, also when you already know the ids of the stories you wrote: they add the stories of other components that your change affects.",
|
|
618
|
+
`Story ids come only from ${several ? "these commands" : "this command"}. Never build one from a file name, a title or memory.`,
|
|
619
|
+
inputs.moduleGraphSupported && "When `stories changed` leaves out a file you touched, pass that file to `find-by-component`; for a shared file (design token, theme, util, hook), which has no stories of its own, pass the components that use it. When `find-by-component` reports stories hidden by `maxDistance`, rerun it with a higher `--maxDistance`.",
|
|
620
|
+
`When ${several ? "none of them finds" : "it does not find"} a story for a component, it has no stories yet: say so, or write them.`
|
|
621
|
+
].filter(Boolean).join(" ");
|
|
622
|
+
return `## Find the stories
|
|
623
|
+
|
|
624
|
+
\`\`\`sh
|
|
625
|
+
${commands.join(`
|
|
626
|
+
`)}
|
|
627
|
+
\`\`\`
|
|
628
|
+
|
|
629
|
+
${guidance}`;
|
|
630
|
+
}
|
|
631
|
+
function reviewSection({ moduleGraphSupported }) {
|
|
632
|
+
let discoverFirst = moduleGraphSupported ? " When you changed files, run `stories changed` or `find-by-component` right before it and take the story ids from there, also when you only wrote stories, not from the output of the tests." : "";
|
|
633
|
+
return `## Finish with a review
|
|
634
|
+
|
|
635
|
+
\`\`\`sh
|
|
636
|
+
${ref("review.create")} --input '{
|
|
637
|
+
"title": "Rounder buttons",
|
|
638
|
+
"description": "The **Button** corner radius goes from 4px to 8px.",
|
|
639
|
+
"collections": [
|
|
640
|
+
{ "title": "Button variants", "rationale": "The component that changed.", "storyIds": ["button--primary", "button--disabled"] },
|
|
641
|
+
{ "title": "Forms that use it", "rationale": "Where the change shows up in context.", "storyIds": ["login-form--default"] }
|
|
642
|
+
],
|
|
643
|
+
"changedFiles": ["src/Button.tsx"]
|
|
644
|
+
}'
|
|
645
|
+
\`\`\`
|
|
646
|
+
|
|
647
|
+
Publish a review after every change the user can see, and again after each later change. It needs a running Forkbook.${discoverFirst} Group the stories into two to five collections, from the changed component up to the pages that show it (one is enough when a single component is affected), and include every story you created. List every file you created or changed in \`changedFiles\`, story files too. When the user only asks to see or browse components or stories and you changed no files, publish the same review with \`"changedFiles": []\`. Skip the review only when nothing visible changed and the user did not ask to see anything, and say that instead.
|
|
648
|
+
|
|
649
|
+
Then do both things the command prints, every time: open the review in the in-app browser with a browser tool (unless you have none), and end your answer with the review section it gives you. Do not list separate story links next to it.`;
|
|
650
|
+
}
|
|
651
|
+
function previewSection() {
|
|
652
|
+
return `## Link to one story
|
|
653
|
+
|
|
654
|
+
\`\`\`sh
|
|
655
|
+
${ref("stories.preview")} --stories '[{"storyId":"<id>"}]' # direct links to stories
|
|
656
|
+
\`\`\`
|
|
657
|
+
|
|
658
|
+
Only for a look at one story while you iterate, or when the user asks for a direct link. It does not replace the review, unless \`review create\` keeps failing after you fixed what it reported: then share these links and say why.`;
|
|
659
|
+
}
|
|
660
|
+
function buildStoriesSkill(inputs) {
|
|
661
|
+
return [
|
|
662
|
+
"# Forkbook workflow\n\nFollow this for every change to how the UI looks (components, stories, styles, themes, tokens) and for requests to show components or stories. Some commands print what to do next; follow that too. Add `--help` to a command only when a call fails.",
|
|
663
|
+
inputs.docsEnabled && docsSection(),
|
|
664
|
+
writeSection(inputs),
|
|
665
|
+
inputs.testSupported && testSection(inputs.a11yEnabled),
|
|
666
|
+
discoverSection(inputs),
|
|
667
|
+
reviewSection(inputs),
|
|
668
|
+
previewSection()
|
|
669
|
+
].filter(Boolean).join(`
|
|
670
|
+
|
|
671
|
+
`);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// src/cli/skills/content/build-server-instructions.ts
|
|
675
|
+
function getFinalLinksGuidance(transport) {
|
|
676
|
+
let ref2 = getToolName({ transport });
|
|
677
|
+
return `In your final user-facing response, show one set of links \u2014 never both. If you published a review with **${ref2("review.create")}**, finish your reply with a dedicated review section as the very last thing in the output: its own top-level heading on a line by itself (for example \`## \u{1F440} Review your changes\`), then a one-line explanation that the review shows the handful of stories most relevant to this change and that, because it is AI-curated, results may be inaccurate or incomplete, then on the next line the review page as a markdown link prefixed with a \u{1F449} so it is easy to spot, using the returned \`reviewUrl\` (for example \`\u{1F449} [Open the Forkbook review page](<reviewUrl>)\`). Nothing should come after this section. Never also list the individual story or preview URLs. Avoid internal jargon like "collection" or "trigger" in anything the user reads \u2014 those are terms from this tooling, not words that mean anything to them; use plain language unless the user used the term first. A visually observable change is not finished until its review is published \u2014 never substitute preview URLs for the review. If **${ref2("review.create")}** keeps failing, end with the **${ref2("stories.preview")}** URLs instead and say the review could not be published. Only when there is no review because the change has no visually observable impact, say so plainly; include preview URLs only if the user asked to see specific stories.`;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// src/cli/skills/content/instructions/a11y-instructions.md
|
|
681
|
+
var a11y_instructions_default = `### Accessibility Violations
|
|
682
|
+
|
|
683
|
+
**Fix automatically** (semantic/structural, no visual change):
|
|
684
|
+
|
|
685
|
+
- ARIA attributes, roles, labels, alt text
|
|
686
|
+
- Heading hierarchy, landmarks, table structure
|
|
687
|
+
- Keyboard access (tabindex, focus, handlers)
|
|
688
|
+
- Document-level: lang attr, frame titles, duplicate IDs
|
|
689
|
+
|
|
690
|
+
**Confirm with user first** (visual/design changes):
|
|
691
|
+
|
|
692
|
+
- Color contrast ratios
|
|
693
|
+
- Font sizes, spacing, layout
|
|
694
|
+
- Focus indicator styling
|
|
695
|
+
|
|
696
|
+
Describe the issue, ask how the user wants to proceed, and provide 2-3 concrete options.
|
|
697
|
+
Do not auto-apply visual changes before user confirmation, and do not claim visual issues are fixed until they approve an option.
|
|
698
|
+
`;
|
|
699
|
+
|
|
700
|
+
// src/cli/skills/content/instructions/story-testing-instructions.md
|
|
701
|
+
var story_testing_instructions_default = `## Story Testing Requirements
|
|
702
|
+
|
|
703
|
+
**Run \`{{RUN_STORY_TESTS_TOOL_NAME}}\` after EVERY component or story change.** This includes creating, modifying, or refactoring components, stories, or their dependencies. It is the only way to run story tests \u2014 never run package.json test scripts (like \`npm run test:stories\`) instead.
|
|
704
|
+
|
|
705
|
+
### Workflow
|
|
706
|
+
|
|
707
|
+
1. Make your change
|
|
708
|
+
2. Run \`{{RUN_STORY_TESTS_TOOL_NAME}}\` with related stories for focused feedback (faster while iterating)
|
|
709
|
+
3. If tests fail: analyze, fix{{A11Y_FIX_SUFFIX}}, re-run
|
|
710
|
+
4. Repeat until all tests pass
|
|
711
|
+
|
|
712
|
+
Do not skip tests, ignore failures, or move on with failing tests. If stuck after multiple attempts, report to user.
|
|
713
|
+
|
|
714
|
+
### Focused vs. full-suite test runs
|
|
715
|
+
|
|
716
|
+
- Prefer focused runs (\`stories\` input) during development to validate the parts you changed quickly.
|
|
717
|
+
- Run all tests (omit \`stories\`) before final handoff, after broad/refactor changes, or when impact is unclear and you need project-wide verification.
|
|
718
|
+
`;
|
|
719
|
+
|
|
720
|
+
// src/cli/skills/content/instructions/storybook-story-instructions.md
|
|
721
|
+
var storybook_story_instructions_default = `# Writing User Interfaces
|
|
722
|
+
|
|
723
|
+
Use the configured framework (\`{{FRAMEWORK}}\`) and renderer (\`{{RENDERER}}\`). Follow the project\u2019s component syntax, story format, imports, and setup conventions. Use examples for this framework when consulting documentation.
|
|
724
|
+
|
|
725
|
+
When writing UI, prefer breaking larger components up into smaller parts.
|
|
726
|
+
|
|
727
|
+
ALWAYS write a Forkbook story for any component written. If editing a component, ensure appropriate changes have been made to stories for that component.
|
|
728
|
+
{{DOCS_WORKFLOW_GUIDANCE}}
|
|
729
|
+
|
|
730
|
+
## How to write good stories
|
|
731
|
+
|
|
732
|
+
Goal: Cover every distinct piece of business logic and state the component can reach (happy paths, error/edge states, loading, permissions/roles, empty states, variations from props/context). Avoid redundant stories that show the same logic.
|
|
733
|
+
|
|
734
|
+
Interactivity: If the component is interactive, add Interaction tests using play functions that drive the UI with @aussieljk/forkbook/test utilities (e.g., fn, userEvent, expect). Simulate key user flows: clicking buttons/links, typing, focus/blur, keyboard nav, form submit, async responses, toggle/selection changes, pagination/filters, etc. When passing \`fn\` functions as \`args\` for callback functions, make sure to add a play function which interacts with the component and assert whether the callback function was actually called.
|
|
735
|
+
|
|
736
|
+
Data/setup: Provide realistic props, state, and mocked data. Include meaningful labels/text to make behaviors observable. Stub network/services with deterministic fixtures; keep stories reliable.
|
|
737
|
+
|
|
738
|
+
Assertions: In play functions, assert the visible outcome of the interaction (text, aria state, enabled/disabled, class/state changes, emitted events). Prefer role/label-based queries.
|
|
739
|
+
|
|
740
|
+
Variants to consider (pick only those that change behavior): default vs. alternate themes; loading vs. loaded vs. empty vs. error; validated vs. invalid input; permissions/roles/capabilities; feature flags; size/density/layout variants that alter logic.
|
|
741
|
+
|
|
742
|
+
Accessibility: Use semantic roles/labels; ensure focusable/keyboard interactions are test-covered where relevant.
|
|
743
|
+
|
|
744
|
+
Naming/structure: Use clear story names that describe the scenario (\u201CError state after failed submit\u201D). Group related variants logically; don\u2019t duplicate.
|
|
745
|
+
|
|
746
|
+
Imports/format: Import Meta/StoryObj from the framework package; import test helpers from @aussieljk/forkbook/test (not @storybook/test). Keep stories minimal\u2014only what's needed to demonstrate behavior.
|
|
747
|
+
|
|
748
|
+
## Forkbook 9 Essential Changes for Story Writing
|
|
749
|
+
|
|
750
|
+
### Package Consolidation
|
|
751
|
+
|
|
752
|
+
#### \`Meta\` and \`StoryObj\` imports
|
|
753
|
+
|
|
754
|
+
Update story imports to use the framework package:
|
|
755
|
+
|
|
756
|
+
\`\`\`diff
|
|
757
|
+
- import { Meta, StoryObj } from '{{RENDERER}}';
|
|
758
|
+
+ import { Meta, StoryObj } from '{{FRAMEWORK}}';
|
|
759
|
+
\`\`\`
|
|
760
|
+
|
|
761
|
+
#### Test utility imports
|
|
762
|
+
|
|
763
|
+
Update test imports to use \`@aussieljk/forkbook/test\` instead of \`@storybook/test\`
|
|
764
|
+
|
|
765
|
+
\`\`\`diff
|
|
766
|
+
- import { fn } from '@storybook/test';
|
|
767
|
+
+ import { fn } from '@aussieljk/forkbook/test';
|
|
768
|
+
\`\`\`
|
|
769
|
+
|
|
770
|
+
### Global State Changes
|
|
771
|
+
|
|
772
|
+
The \`globals\` annotation has be renamed to \`initialGlobals\`:
|
|
773
|
+
|
|
774
|
+
\`\`\`diff
|
|
775
|
+
// .forkbook/preview.js
|
|
776
|
+
export default {
|
|
777
|
+
- globals: { theme: 'light' }
|
|
778
|
+
+ initialGlobals: { theme: 'light' }
|
|
779
|
+
};
|
|
780
|
+
\`\`\`
|
|
781
|
+
|
|
782
|
+
### Autodocs Configuration
|
|
783
|
+
|
|
784
|
+
Instead of \`parameters.docs.autodocs\` in main.js, use tags:
|
|
785
|
+
|
|
786
|
+
\`\`\`js
|
|
787
|
+
// .forkbook/preview.js or in individual stories
|
|
788
|
+
export default {
|
|
789
|
+
tags: ['autodocs'], // generates autodocs for all stories
|
|
790
|
+
};
|
|
791
|
+
\`\`\`
|
|
792
|
+
|
|
793
|
+
### Mocking imports in Forkbook
|
|
794
|
+
|
|
795
|
+
To mock imports in Forkbook, use Forkbook's mocking features. ALWAYS mock external dependencies to ensure stories render consistently.
|
|
796
|
+
|
|
797
|
+
1. **Register in the mock in Forkbook's preview file**:
|
|
798
|
+
To mock dependendencies, you MUST register a module mock in \`.forkbook/preview.ts\` (or equivalent):
|
|
799
|
+
|
|
800
|
+
\`\`\`js
|
|
801
|
+
import { sb } from '@aussieljk/forkbook/test';
|
|
802
|
+
|
|
803
|
+
// Prefer spy mocks (keeps functions, but allows to override them and spy on them)
|
|
804
|
+
sb.mock(import('some-library'), { spy: true });
|
|
805
|
+
\`\`\`
|
|
806
|
+
|
|
807
|
+
**Important: Use file extensions when referring to relative files!**
|
|
808
|
+
|
|
809
|
+
\`\`\`js
|
|
810
|
+
sb.mock(import('./relative/module.ts'), { spy: true });
|
|
811
|
+
\`\`\`
|
|
812
|
+
|
|
813
|
+
2. **Specify mock values in stories**:
|
|
814
|
+
You can override the behaviour of the mocks per-story using \`beforeEach\` and the \`mocked()\` type function:
|
|
815
|
+
|
|
816
|
+
\`\`\`js
|
|
817
|
+
import { expect, mocked, fn } from '@aussieljk/forkbook/test';
|
|
818
|
+
import { library } from 'some-library';
|
|
819
|
+
|
|
820
|
+
const meta = {
|
|
821
|
+
component: AuthButton,
|
|
822
|
+
beforeEach: async () => {
|
|
823
|
+
mocked(library).mockResolvedValue({ user: 'data' });
|
|
824
|
+
},
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
export const LoggedIn: Story = {
|
|
828
|
+
play: async ({ canvas }) => {
|
|
829
|
+
await expect(library).toHaveBeenCalled();
|
|
830
|
+
},
|
|
831
|
+
};
|
|
832
|
+
\`\`\`
|
|
833
|
+
|
|
834
|
+
Before doing this ensure you have mocked the import in the preview file.
|
|
835
|
+
|
|
836
|
+
### Play Function Parameters
|
|
837
|
+
|
|
838
|
+
- The play function has a \`canvas\` parameter that can be used directly with testing-library-like query methods.
|
|
839
|
+
- It also has a \`canvasElement\` which is the actual DOM element.
|
|
840
|
+
- The \`within\`-function imported from \`@aussieljk/forkbook/test\` transforms a DOM element to an object with query methods, similar to \`canvas\`.
|
|
841
|
+
|
|
842
|
+
**DO NOT** use \`within(canvas)\` - it is redundant because \`canvas\` already has the query methods, \`canvas\` is not a DOM element.
|
|
843
|
+
|
|
844
|
+
\`\`\`ts
|
|
845
|
+
// \u2705 Correct: Use canvas directly
|
|
846
|
+
play: async ({ canvas }) => {
|
|
847
|
+
await canvas.getByLabelText('Submit').click();
|
|
848
|
+
};
|
|
849
|
+
|
|
850
|
+
// \u26A0\uFE0F Also acceptable: Use \`canvasElement\` with \`within\`
|
|
851
|
+
import { within } from '@aussieljk/forkbook/test';
|
|
852
|
+
|
|
853
|
+
play: async ({ canvasElement }) => {
|
|
854
|
+
const canvas = within(canvasElement);
|
|
855
|
+
await canvas.getByLabelText('Submit').click();
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
// \u274C Wrong: Do NOT use within(canvas)
|
|
859
|
+
play: async ({ canvas }) => {
|
|
860
|
+
const screen = within(canvas); // Error!
|
|
861
|
+
};
|
|
862
|
+
\`\`\`
|
|
863
|
+
|
|
864
|
+
### Key Requirements
|
|
865
|
+
|
|
866
|
+
- **Node.js 22.12+**
|
|
867
|
+
- For TypeScript projects, use a version supported by the configured Forkbook framework and application framework.
|
|
868
|
+
{{RENDERER_REQUIREMENTS}}
|
|
869
|
+
|
|
870
|
+
## Story Linking Agent Behavior
|
|
871
|
+
|
|
872
|
+
- ALWAYS provide story links after any changes to stories files, including changes to existing stories.
|
|
873
|
+
- {{STORY_LINKING_WORKFLOW}}
|
|
874
|
+
- {{FINAL_LINKS_GUIDANCE}}
|
|
875
|
+
- When you will share preview/story links (i.e. when you are not collapsing everything into a single review section), pass only the most relevant story IDs into **{{PREVIEW_STORIES}}** (generally no more than 5) so the returned URL list stays manageable. Include every URL returned by that call in your final response \u2014 do not drop links there.
|
|
876
|
+
- {{CHANGED_STORY_FALLBACK_LINK_GUIDANCE}}
|
|
877
|
+
- After changing any UI components, ALWAYS search for related stories that might cover the changes you've made. If you find any, provide the story links to the user. THIS IS VERY IMPORTANT, as it allows the user to visually inspect the changes you've made. Even later in a session when changing UI components or stories that have already been linked to previously, YOU MUST PROVIDE THE LINKS AGAIN.
|
|
878
|
+
`;
|
|
879
|
+
|
|
880
|
+
// src/cli/skills/content/build-story-instructions.ts
|
|
881
|
+
function buildStoryInstructions({
|
|
882
|
+
transport,
|
|
883
|
+
framework,
|
|
884
|
+
renderer,
|
|
885
|
+
testSupported,
|
|
886
|
+
a11yEnabled,
|
|
887
|
+
docsEnabled
|
|
888
|
+
}) {
|
|
889
|
+
let ref2 = getToolName({ transport }), resolvedRenderer = renderer ?? frameworkToRendererMap[framework] ?? framework, storyLinkingWorkflow = `After changing any component or story, call \`${ref2("stories.changed")}\` to discover the new, modified, and related stories affected by your change. Story IDs must come from that call (or a fallback discovery tool such as ${ref2("stories.findByComponent")} for shared-infrastructure changes) \u2014 never construct them from file names, export names, or memory. Feed the discovered IDs into **${ref2("review.create")}** when the change is visually observable; use \`${ref2("stories.preview")}\` only while iterating on a specific story.`, changedStoryFallbackLinkGuidance = `When sharing preview/story links (not when ending with a review section): if you did not pass every changed story into \`${ref2("stories.preview")}\`, include this Forkbook fallback link so the user can view the complete changed list: \`/?statuses=affected;modified;new\`.`, docsWorkflowGuidance = `
|
|
890
|
+
|
|
891
|
+
## Using library components
|
|
892
|
+
|
|
893
|
+
This Forkbook exposes component documentation tools. Before creating or changing any UI, call **${ref2("docs.list")}** once to see what the design system already provides \u2014 build on existing components instead of hand-rolling duplicates \u2014 then call **${ref2("docs.show")}** with the \`id\` of each component you build on or get asked about, for its real props and usage examples. When multiple Forkbook sources are configured, pass the \`storybookId\` from **${ref2("docs.list")}** on follow-up calls. Do this instead of reading the library's source or type definitions out of \`node_modules\` \u2014 stories show intended usage, raw types don't \u2014 and answer props/usage questions from these tools too. Never assume or invent props.`, uiInstructions = storybook_story_instructions_default.replaceAll("{{FRAMEWORK}}", framework).replaceAll("{{RENDERER}}", resolvedRenderer).replace(
|
|
894
|
+
"{{RENDERER_REQUIREMENTS}}",
|
|
895
|
+
resolvedRenderer === "@storybook/react-native" ? "- React Native uses `.rnforkbook` directory" : ""
|
|
896
|
+
).replace(`
|
|
897
|
+
{{DOCS_WORKFLOW_GUIDANCE}}`, docsEnabled ? docsWorkflowGuidance : "").replace("{{STORY_LINKING_WORKFLOW}}", storyLinkingWorkflow).replace("{{FINAL_LINKS_GUIDANCE}}", getFinalLinksGuidance(transport)).replace("{{PREVIEW_STORIES}}", ref2("stories.preview")).replace("{{CHANGED_STORY_FALLBACK_LINK_GUIDANCE}}", changedStoryFallbackLinkGuidance);
|
|
898
|
+
if (testSupported) {
|
|
899
|
+
let a11yFixSuffix = a11yEnabled ? " (see a11y guidelines below)" : "", storyTestingInstructions = story_testing_instructions_default.replaceAll("{{RUN_STORY_TESTS_TOOL_NAME}}", ref2("test.run")).replace("{{A11Y_FIX_SUFFIX}}", a11yFixSuffix);
|
|
900
|
+
uiInstructions += `
|
|
901
|
+
|
|
902
|
+
${storyTestingInstructions}`, a11yEnabled && (uiInstructions += `
|
|
903
|
+
${a11y_instructions_default}`);
|
|
904
|
+
}
|
|
905
|
+
return uiInstructions;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
// src/cli/skills/content/skills.ts
|
|
909
|
+
var SKILL_IDS = ["stories", "write-story", "setup"], SKILLS = {
|
|
910
|
+
stories: {
|
|
911
|
+
blurb: "The workflow for UI changes, with every command it needs: look up components, write stories, test, and publish a review."
|
|
912
|
+
},
|
|
913
|
+
"write-story": {
|
|
914
|
+
blurb: "How to write, update, and test Forkbook stories for this project: imports, patterns, and conventions."
|
|
915
|
+
},
|
|
916
|
+
setup: {
|
|
917
|
+
blurb: "Setup instructions to write stories for the real components in this project."
|
|
918
|
+
}
|
|
919
|
+
};
|
|
920
|
+
function isSkillId(value) {
|
|
921
|
+
return SKILL_IDS.includes(value);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// src/cli/skills/setup-support.ts
|
|
925
|
+
var SUPPORTED_SETUP_RENDERERS = ["@aussieljk/forkbook/react"];
|
|
926
|
+
function getSetupSupportError({
|
|
927
|
+
rendererPackage,
|
|
928
|
+
builderPackage
|
|
929
|
+
}) {
|
|
930
|
+
if (!(rendererPackage && SUPPORTED_SETUP_RENDERERS.includes(rendererPackage) && builderPackage === "@aussieljk/forkbook/builder-vite"))
|
|
931
|
+
return `AI-assisted setup is currently only available for React projects using the Vite builder. Detected renderer: ${rendererPackage ?? "unknown"}, builder: ${builderPackage ?? "unknown"}.`;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// src/cli/skills/run.ts
|
|
935
|
+
var SKILLS_OPTION_SPECS = [
|
|
936
|
+
{ flags: "--cwd <path>", description: "Project directory of the target Forkbook" },
|
|
937
|
+
{
|
|
938
|
+
flags: "-c, --config-dir <dir-name>",
|
|
939
|
+
description: "Forkbook config directory of the target Forkbook"
|
|
940
|
+
},
|
|
941
|
+
{ flags: "--all", description: "Print every skill in full" },
|
|
942
|
+
{ flags: "-h, --help", description: "Show this usage and every skill" }
|
|
943
|
+
];
|
|
944
|
+
function resolveSkillsIntent({
|
|
945
|
+
tokens,
|
|
946
|
+
help,
|
|
947
|
+
all
|
|
948
|
+
}) {
|
|
949
|
+
let [id, ...rest] = tokens;
|
|
950
|
+
return help ? { kind: "catalog" } : id === void 0 ? all ? { kind: "all" } : { kind: "catalog" } : isSkillId(id) ? all ? {
|
|
951
|
+
kind: "error",
|
|
952
|
+
message: `\`--all\` prints every skill and takes no skill id; drop "${id}" or \`--all\`.`
|
|
953
|
+
} : rest.length > 0 ? {
|
|
954
|
+
kind: "error",
|
|
955
|
+
message: `Unexpected arguments: ${rest.map((token) => `"${token}"`).join(" ")}. Run \`npx forkbook skills --help\` for usage.`
|
|
956
|
+
} : { kind: "get", id } : {
|
|
957
|
+
kind: "error",
|
|
958
|
+
message: `Unknown skill "${id}". Available skills: ${SKILL_IDS.join(", ")}.`
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
async function runSkillsCommand(input, deps) {
|
|
962
|
+
let intent = resolveSkillsIntent(input);
|
|
963
|
+
if (intent.kind === "catalog")
|
|
964
|
+
return { output: renderCatalogHelp(), exitCode: 0 };
|
|
965
|
+
if (intent.kind === "error")
|
|
966
|
+
return { output: "", errorOutput: intent.message, exitCode: 1 };
|
|
967
|
+
try {
|
|
968
|
+
let ids = intent.kind === "all" ? SKILL_IDS : [intent.id], { docs, setupRun } = await serveSkills(
|
|
969
|
+
ids,
|
|
970
|
+
resolveStorybookConfigDir(input.target),
|
|
971
|
+
deps
|
|
972
|
+
);
|
|
973
|
+
return {
|
|
974
|
+
output: docs.join(`
|
|
975
|
+
|
|
976
|
+
---
|
|
977
|
+
|
|
978
|
+
`),
|
|
979
|
+
exitCode: 0,
|
|
980
|
+
skill: intent.kind === "all" ? "all" : intent.id,
|
|
981
|
+
...intent.kind === "get" && setupRun ? { setupRun } : {}
|
|
982
|
+
};
|
|
983
|
+
} catch (error) {
|
|
984
|
+
if (error instanceof SkillsError)
|
|
985
|
+
return { output: "", errorOutput: error.message, exitCode: 1 };
|
|
986
|
+
throw error;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
var SkillsError = class extends Error {
|
|
990
|
+
};
|
|
991
|
+
async function serveSkills(ids, configDir, deps) {
|
|
992
|
+
let inputs, toolsets, setupRun, docs = [];
|
|
993
|
+
for (let id of ids)
|
|
994
|
+
if (id === "setup") {
|
|
995
|
+
let setup = await serveSetup(configDir, deps);
|
|
996
|
+
docs.push(setup.markdown), setupRun = setup.run;
|
|
997
|
+
} else
|
|
998
|
+
inputs ??= await loadInputs(configDir, deps), toolsets ??= deps.describeToolsets(), docs.push(withCommandReference(id, inputs, toolsets));
|
|
999
|
+
return { docs, setupRun };
|
|
1000
|
+
}
|
|
1001
|
+
async function serveSetup(configDir, deps) {
|
|
1002
|
+
let probed = await deps.getProjectInfo({
|
|
1003
|
+
configDir: relative(process.cwd(), configDir) || "."
|
|
1004
|
+
});
|
|
1005
|
+
if (!probed.ok)
|
|
1006
|
+
throw new SkillsError(probed.message);
|
|
1007
|
+
let supportError = getSetupSupportError(probed.projectInfo);
|
|
1008
|
+
if (supportError)
|
|
1009
|
+
throw new SkillsError(supportError);
|
|
1010
|
+
let { markdown, prompt } = await deps.getSetupMarkdown(probed.projectInfo);
|
|
1011
|
+
return { markdown, run: { projectInfo: probed.projectInfo, prompt } };
|
|
1012
|
+
}
|
|
1013
|
+
async function loadInputs(configDir, deps) {
|
|
1014
|
+
try {
|
|
1015
|
+
return await deps.resolveSkillInputs(await deps.loadStorybook({ configDir }));
|
|
1016
|
+
} catch (error) {
|
|
1017
|
+
throw new SkillsError(
|
|
1018
|
+
`Could not load the Forkbook configuration for this project: ${error instanceof Error ? error.message : String(error)}`
|
|
1019
|
+
);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
function table(rows) {
|
|
1023
|
+
let column = Math.max(...rows.map(([key]) => key.length)) + 2;
|
|
1024
|
+
return rows.map(([key, text]) => ` ${key.padEnd(column)}${text}`);
|
|
1025
|
+
}
|
|
1026
|
+
function renderCatalogHelp() {
|
|
1027
|
+
return [
|
|
1028
|
+
"Usage: npx forkbook skills [options] [id]",
|
|
1029
|
+
"",
|
|
1030
|
+
"Agent skills served by this Forkbook.",
|
|
1031
|
+
"",
|
|
1032
|
+
"Options:",
|
|
1033
|
+
...table(SKILLS_OPTION_SPECS.map((spec) => [spec.flags, spec.description])),
|
|
1034
|
+
"",
|
|
1035
|
+
"Skills:",
|
|
1036
|
+
...table(SKILL_IDS.map((id) => [id, SKILLS[id].blurb])),
|
|
1037
|
+
"",
|
|
1038
|
+
"Print a skill with `npx forkbook skills <id>`, or every skill with `npx forkbook skills --all`."
|
|
1039
|
+
].join(`
|
|
1040
|
+
`);
|
|
1041
|
+
}
|
|
1042
|
+
function withCommandReference(id, inputs, toolsets) {
|
|
1043
|
+
let text = assemble(id, inputs);
|
|
1044
|
+
if (id === "stories")
|
|
1045
|
+
return text;
|
|
1046
|
+
let reference = renderCommandReference(text, toolsets);
|
|
1047
|
+
return reference ? `${text.trimEnd()}
|
|
1048
|
+
|
|
1049
|
+
${reference}` : text;
|
|
1050
|
+
}
|
|
1051
|
+
function assemble(id, inputs) {
|
|
1052
|
+
return id === "stories" ? buildStoriesSkill({
|
|
1053
|
+
framework: inputs.framework,
|
|
1054
|
+
csfFactories: inputs.csfFactories,
|
|
1055
|
+
previewFile: inputs.previewFile,
|
|
1056
|
+
typescript: inputs.typescript,
|
|
1057
|
+
docsEnabled: inputs.docsEnabledForCli,
|
|
1058
|
+
testSupported: inputs.testSupported,
|
|
1059
|
+
a11yEnabled: inputs.a11yEnabled,
|
|
1060
|
+
moduleGraphSupported: inputs.moduleGraphSupported
|
|
1061
|
+
}) : buildStoryInstructions({
|
|
1062
|
+
transport: "cli",
|
|
1063
|
+
framework: inputs.framework,
|
|
1064
|
+
renderer: inputs.renderer,
|
|
1065
|
+
testSupported: inputs.testSupported,
|
|
1066
|
+
a11yEnabled: inputs.a11yEnabled,
|
|
1067
|
+
docsEnabled: inputs.docsEnabledForCli
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
// src/cli/skills/register.ts
|
|
1072
|
+
function registerSkillsCommand(program2, skillsCommand2, handleCommandFailure2) {
|
|
1073
|
+
program2.enablePositionalOptions(), skillsCommand2.helpOption(!1).helpCommand(!1).usage("[options] [id]").argument("[tokens...]", "A skill id from `forkbook skills --help`");
|
|
1074
|
+
for (let { flags, description } of SKILLS_OPTION_SPECS)
|
|
1075
|
+
skillsCommand2.option(flags, description);
|
|
1076
|
+
skillsCommand2.action(async (tokens, options) => {
|
|
1077
|
+
let cliOptions = {
|
|
1078
|
+
disableTelemetry: options.disableTelemetry,
|
|
1079
|
+
logfile: options.logfile,
|
|
1080
|
+
configDir: resolveStorybookConfigDir({ cwd: options.cwd, configDir: options.configDir })
|
|
1081
|
+
}, invocation = {
|
|
1082
|
+
tokens: tokens ?? [],
|
|
1083
|
+
help: options.help,
|
|
1084
|
+
all: options.all,
|
|
1085
|
+
target: { cwd: options.cwd, configDir: options.configDir }
|
|
1086
|
+
}, intent = resolveSkillsIntent(invocation), run = async () => {
|
|
1087
|
+
let result = await runSkillsCommand(invocation, defaultDeps());
|
|
1088
|
+
await printResult(result), result.setupRun && await recordSetupRun(result.setupRun), result.skill && await telemetry2("skills-get", { skill: result.skill }, { configDir: cliOptions.configDir });
|
|
1089
|
+
};
|
|
1090
|
+
intent.kind === "catalog" ? await run() : await withTelemetry("skills-get", { cliOptions, fallbackTelemetryState: !0 }, run).catch(
|
|
1091
|
+
handleCommandFailure2(options.logfile)
|
|
1092
|
+
), process.exit();
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
function defaultDeps() {
|
|
1096
|
+
return {
|
|
1097
|
+
loadStorybook: experimental_loadStorybook,
|
|
1098
|
+
resolveSkillInputs,
|
|
1099
|
+
getProjectInfo,
|
|
1100
|
+
getSetupMarkdown: getSetupMarkdownOutput,
|
|
1101
|
+
describeToolsets: () => getRegisteredToolsets().map(
|
|
1102
|
+
(toolset) => toCatalogEntry(toolset, {
|
|
1103
|
+
transport: "cli",
|
|
1104
|
+
getService: (serviceId, options) => getService(serviceId, options)
|
|
1105
|
+
})
|
|
1106
|
+
)
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
async function printResult(result) {
|
|
1110
|
+
result.errorOutput && await new Promise(
|
|
1111
|
+
(done) => process.stderr.write(`${result.errorOutput}
|
|
1112
|
+
`, () => done())
|
|
1113
|
+
), result.output && await new Promise((done) => process.stdout.write(`${result.output}
|
|
1114
|
+
`, () => done())), result.exitCode !== 0 && (process.exitCode = result.exitCode);
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
// src/cli/tools/register.ts
|
|
1118
|
+
import { writeFile } from "node:fs/promises";
|
|
1119
|
+
import { resolve as resolve3 } from "node:path";
|
|
1120
|
+
import { sendTelemetryError, withTelemetry as withTelemetry2 } from "@aussieljk/forkbook/internal/core-server";
|
|
1121
|
+
import { logger } from "@aussieljk/forkbook/internal/node-logger";
|
|
1122
|
+
import { Option } from "commander";
|
|
1123
|
+
|
|
1124
|
+
// src/cli/tools/run.ts
|
|
1125
|
+
import { versions } from "@aussieljk/forkbook/internal/common";
|
|
1126
|
+
|
|
1127
|
+
// src/cli/tools/discover-instance.ts
|
|
1128
|
+
import { resolve as resolve2 } from "node:path";
|
|
1129
|
+
async function discoverRunningInstance(target, deps = {}) {
|
|
1130
|
+
let cwd = resolve2(target.cwd ?? process.cwd()), configDir = resolveStorybookConfigDir({ cwd, configDir: target.configDir }), records = await readRegistry(deps.registryDir), selection = selectInstances(records, {
|
|
1131
|
+
cwd,
|
|
1132
|
+
configDir,
|
|
1133
|
+
configDirExplicit: target.configDir != null,
|
|
1134
|
+
port: target.port,
|
|
1135
|
+
agent: detectAgent()?.name
|
|
1136
|
+
});
|
|
1137
|
+
return { currentRecord: selection.kind === "match" ? selection.matches[0] : void 0, records };
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// src/cli/tools/run.ts
|
|
1141
|
+
var CLI_CLIENT_INFO = {
|
|
1142
|
+
name: "storybook-cli",
|
|
1143
|
+
version: versions["@aussieljk/forkbook"],
|
|
1144
|
+
kind: "cli"
|
|
1145
|
+
};
|
|
1146
|
+
function toMethodKey(cliName) {
|
|
1147
|
+
return cliName.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
1148
|
+
}
|
|
1149
|
+
function isAgentFacingError(error) {
|
|
1150
|
+
return error instanceof Error && error.agentFacing === !0;
|
|
1151
|
+
}
|
|
1152
|
+
function isInvalidInputError(error) {
|
|
1153
|
+
return error instanceof ToolsRuntimeError && error.data.reason === "invalid-input";
|
|
1154
|
+
}
|
|
1155
|
+
function normalizeHelpFlag(invocation) {
|
|
1156
|
+
return invocation.tool !== "--help" && invocation.tool !== "-h" ? invocation : {
|
|
1157
|
+
...invocation,
|
|
1158
|
+
tool: void 0,
|
|
1159
|
+
flags: { ...invocation.flags, help: !0 }
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
function resolveToolsMode(invocationAttach, parsedAttach) {
|
|
1163
|
+
let flag = parsedAttach ?? invocationAttach;
|
|
1164
|
+
return flag === !0 ? "attached" : flag === !1 ? "local" : "auto";
|
|
1165
|
+
}
|
|
1166
|
+
async function runToolsCommand(invocation, deps = {}) {
|
|
1167
|
+
let normalized = normalizeHelpFlag(invocation), { tokens, flags = {}, attach } = normalized, parsed = parseToolsTokens(tokens, flags), requestedMode = parsed.ok ? resolveToolsMode(attach, parsed.attach) : resolveToolsMode(attach, void 0);
|
|
1168
|
+
if (!parsed.ok)
|
|
1169
|
+
return {
|
|
1170
|
+
exitCode: 1,
|
|
1171
|
+
output: parsed.error,
|
|
1172
|
+
outcome: { kind: "intercept", reason: "invalid-arguments" },
|
|
1173
|
+
outputPath: flags.output,
|
|
1174
|
+
requestedMode,
|
|
1175
|
+
attachMode: requestedMode
|
|
1176
|
+
};
|
|
1177
|
+
let parsedPort = parsePort(normalized.port);
|
|
1178
|
+
if (!parsedPort.ok)
|
|
1179
|
+
return {
|
|
1180
|
+
exitCode: 1,
|
|
1181
|
+
output: parsedPort.error,
|
|
1182
|
+
outcome: { kind: "intercept", reason: "invalid-arguments" },
|
|
1183
|
+
outputPath: parsed.output,
|
|
1184
|
+
requestedMode,
|
|
1185
|
+
attachMode: requestedMode
|
|
1186
|
+
};
|
|
1187
|
+
let target = {
|
|
1188
|
+
...normalized.target,
|
|
1189
|
+
...parsedPort.port !== void 0 ? { port: parsedPort.port } : {}
|
|
1190
|
+
}, result = (partial) => ({
|
|
1191
|
+
...partial,
|
|
1192
|
+
outputPath: parsed.output,
|
|
1193
|
+
requestedMode,
|
|
1194
|
+
attachMode: requestedMode
|
|
1195
|
+
}), tools, create = deps.createTools ?? createTools;
|
|
1196
|
+
try {
|
|
1197
|
+
tools = await create({
|
|
1198
|
+
cwd: target.cwd,
|
|
1199
|
+
configDir: target.configDir,
|
|
1200
|
+
...target.port != null ? { port: target.port } : {},
|
|
1201
|
+
mode: requestedMode,
|
|
1202
|
+
clientInfo: CLI_CLIENT_INFO
|
|
1203
|
+
});
|
|
1204
|
+
} catch (error) {
|
|
1205
|
+
return isAttachGateError(error) ? result({
|
|
1206
|
+
exitCode: 1,
|
|
1207
|
+
output: error instanceof Error ? error.message : String(error),
|
|
1208
|
+
outcome: { kind: "attach-gate", reason: attachGateReasonFromError(error) }
|
|
1209
|
+
}) : result({
|
|
1210
|
+
exitCode: 1,
|
|
1211
|
+
output: error instanceof Error ? error.message : String(error),
|
|
1212
|
+
outcome: { kind: "error", error }
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1215
|
+
try {
|
|
1216
|
+
return {
|
|
1217
|
+
...await dispatchTools(
|
|
1218
|
+
tools,
|
|
1219
|
+
{ ...normalized, target },
|
|
1220
|
+
parsed,
|
|
1221
|
+
deps,
|
|
1222
|
+
requestedMode,
|
|
1223
|
+
result
|
|
1224
|
+
),
|
|
1225
|
+
requestedMode: tools.requestedMode,
|
|
1226
|
+
attachMode: tools.mode,
|
|
1227
|
+
host: tools.host,
|
|
1228
|
+
fallbackNotice: tools.fallbackNotice,
|
|
1229
|
+
fallbackReason: tools.fallbackReason,
|
|
1230
|
+
...tools.storybook.siblings?.length ? { multiInstanceNotice: formatMultiInstanceNotice(tools.storybook), multipleMatches: !0 } : {}
|
|
1231
|
+
};
|
|
1232
|
+
} finally {
|
|
1233
|
+
await tools.close();
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
async function dispatchTools(tools, invocation, parsed, deps, requestedMode, result) {
|
|
1237
|
+
let { toolset: toolsetName, tool: toolName } = invocation, catalog;
|
|
1238
|
+
try {
|
|
1239
|
+
catalog = await tools.describe();
|
|
1240
|
+
} catch (error) {
|
|
1241
|
+
return isAgentFacingError(error) ? result({ exitCode: 1, output: error.message, outcome: { kind: "failure" } }) : result({
|
|
1242
|
+
exitCode: 1,
|
|
1243
|
+
output: error instanceof Error ? error.message : String(error),
|
|
1244
|
+
outcome: { kind: "error", error }
|
|
1245
|
+
});
|
|
1246
|
+
}
|
|
1247
|
+
if (!toolsetName)
|
|
1248
|
+
return result({
|
|
1249
|
+
exitCode: 0,
|
|
1250
|
+
output: renderToolsHelpFromCatalog(catalog),
|
|
1251
|
+
outcome: { kind: "help" }
|
|
1252
|
+
});
|
|
1253
|
+
let entry = catalog.toolsets.find((candidate) => candidate.id === toolsetName);
|
|
1254
|
+
if (!entry)
|
|
1255
|
+
return result({
|
|
1256
|
+
exitCode: 1,
|
|
1257
|
+
output: formatUnknownToolsetFromCatalog(toolsetName, catalog),
|
|
1258
|
+
outcome: { kind: "intercept", reason: "unknown-toolset" }
|
|
1259
|
+
});
|
|
1260
|
+
if (!toolName)
|
|
1261
|
+
return result({
|
|
1262
|
+
exitCode: 0,
|
|
1263
|
+
output: renderToolsetHelpFromCatalog(entry),
|
|
1264
|
+
outcome: { kind: "help" }
|
|
1265
|
+
});
|
|
1266
|
+
let method = entry.methods.find((candidate) => {
|
|
1267
|
+
let { methodName: methodName2 } = parseToolsetMethodId(candidate.ref);
|
|
1268
|
+
return methodName2 === toMethodKey(toolName) || toCliMethodName(methodName2) === toolName;
|
|
1269
|
+
});
|
|
1270
|
+
if (!method)
|
|
1271
|
+
return result({
|
|
1272
|
+
exitCode: 1,
|
|
1273
|
+
output: formatUnknownToolFromCatalog(toolName, entry),
|
|
1274
|
+
outcome: { kind: "intercept", reason: "unknown-tool" }
|
|
1275
|
+
});
|
|
1276
|
+
if (parsed.help)
|
|
1277
|
+
return result({
|
|
1278
|
+
exitCode: 0,
|
|
1279
|
+
output: renderMethodHelpFromCatalog(method),
|
|
1280
|
+
outcome: { kind: "help" }
|
|
1281
|
+
});
|
|
1282
|
+
let { methodName } = parseToolsetMethodId(method.ref), toolPath = `${entry.id} ${toCliMethodName(methodName)}`, commandPath = `npx forkbook tools ${toolPath}`;
|
|
1283
|
+
if (tools.mode === "local" && method.requiresDevServer) {
|
|
1284
|
+
let discovery = await (deps.discoverInstance ?? discoverRunningInstance)(invocation.target);
|
|
1285
|
+
return result({
|
|
1286
|
+
exitCode: 1,
|
|
1287
|
+
output: formatRequiresDevServer(commandPath, discovery, requestedMode),
|
|
1288
|
+
outcome: { kind: "intercept", reason: "requires-dev-server" }
|
|
1289
|
+
});
|
|
1290
|
+
}
|
|
1291
|
+
try {
|
|
1292
|
+
let outcome = await tools.call(method.ref, parsed.args, {
|
|
1293
|
+
...tools.storybook.url ? { origin: tools.storybook.url } : {}
|
|
1294
|
+
}), output = parsed.json ? JSON.stringify(outcome.data, null, 2) : joinMarkdown(outcome.markdown);
|
|
1295
|
+
return result({
|
|
1296
|
+
exitCode: outcome.ok ? 0 : 1,
|
|
1297
|
+
output,
|
|
1298
|
+
outcome: { kind: outcome.ok ? "success" : "failure" },
|
|
1299
|
+
...outcome.telemetry ? { report: outcome.telemetry } : {}
|
|
1300
|
+
});
|
|
1301
|
+
} catch (error) {
|
|
1302
|
+
return isInvalidInputError(error) ? result({
|
|
1303
|
+
exitCode: 1,
|
|
1304
|
+
output: formatValidationIssues(toolPath, error.data.issues ?? [], method.input),
|
|
1305
|
+
outcome: { kind: "intercept", reason: "invalid-arguments" }
|
|
1306
|
+
}) : isAgentFacingError(error) ? result({ exitCode: 1, output: error.message, outcome: { kind: "failure" } }) : result({
|
|
1307
|
+
exitCode: 1,
|
|
1308
|
+
output: error instanceof Error ? error.message : String(error),
|
|
1309
|
+
outcome: { kind: "error", error }
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
function formatUnknownToolsetFromCatalog(toolsetName, catalog) {
|
|
1314
|
+
let available = catalog.toolsets.map((toolset) => `- \`${toolset.id}\``).join(`
|
|
1315
|
+
`);
|
|
1316
|
+
return `Unknown toolset \`${toolsetName}\`. The Forkbook configuration at ${catalog.configDir} provides:
|
|
1317
|
+
|
|
1318
|
+
${available}
|
|
1319
|
+
|
|
1320
|
+
Run \`npx forkbook tools --help\` for every tool.`;
|
|
1321
|
+
}
|
|
1322
|
+
function formatUnknownToolFromCatalog(toolName, entry) {
|
|
1323
|
+
let available = entry.methods.map((method) => `- \`${toCliMethodName(parseToolsetMethodId(method.ref).methodName)}\``).join(`
|
|
1324
|
+
`);
|
|
1325
|
+
return `Unknown tool \`${toolName}\`. The \`${entry.id}\` toolset provides:
|
|
1326
|
+
|
|
1327
|
+
${available}
|
|
1328
|
+
|
|
1329
|
+
Run \`npx forkbook tools ${entry.id}\` for their descriptions.`;
|
|
1330
|
+
}
|
|
1331
|
+
function joinMarkdown(markdown) {
|
|
1332
|
+
return Array.isArray(markdown) ? markdown.join(`
|
|
1333
|
+
|
|
1334
|
+
`) : markdown;
|
|
1335
|
+
}
|
|
1336
|
+
function formatRequiresDevServer(commandPath, discovery, requestedMode) {
|
|
1337
|
+
if (discovery.currentRecord && requestedMode === "local")
|
|
1338
|
+
return `Found your Forkbook running at ${discovery.currentRecord.url}, but \`${commandPath}\` cannot run from a local tools host. Re-run without \`--no-attach\` to attach to that instance.`;
|
|
1339
|
+
if (discovery.currentRecord)
|
|
1340
|
+
return `Found your Forkbook running at ${discovery.currentRecord.url}, but \`${commandPath}\` could not attach to it. Start or restart that Forkbook, then re-run this command.`;
|
|
1341
|
+
let lines = [
|
|
1342
|
+
`\`${commandPath}\` requires a running Forkbook dev server, and none was found for this project. Start it first (for example \`npm run forkbook\`), then re-run this command.`
|
|
1343
|
+
];
|
|
1344
|
+
if (discovery.records.length > 0) {
|
|
1345
|
+
let candidates = discovery.records.map((record2) => `- ${record2.url} (cwd \`${record2.cwd}\`)`).join(`
|
|
1346
|
+
`);
|
|
1347
|
+
lines.push(
|
|
1348
|
+
"",
|
|
1349
|
+
"Running Forkbook instances that did not match this project \u2014 target one with `--cwd` or `--config-dir`:",
|
|
1350
|
+
candidates
|
|
1351
|
+
);
|
|
1352
|
+
}
|
|
1353
|
+
return lines.join(`
|
|
1354
|
+
`);
|
|
1355
|
+
}
|
|
1356
|
+
var TARGET_OPTIONS = ["cwd", "config-dir", "port"];
|
|
1357
|
+
function formatValidationIssues(toolPath, issues, input) {
|
|
1358
|
+
let commandPath = `npx forkbook tools ${toolPath}`, declaredKeys = input?.properties ? Object.keys(input.properties) : void 0, hasUnknownKey = !1, lines = issues.map((issue) => {
|
|
1359
|
+
let segments = issue.path?.map(
|
|
1360
|
+
(segment) => String(typeof segment == "object" && segment !== null ? segment.key : segment)
|
|
1361
|
+
) ?? [], [key] = segments;
|
|
1362
|
+
if (declaredKeys && segments.length === 1 && !declaredKeys.includes(key))
|
|
1363
|
+
return hasUnknownKey = !0, TARGET_OPTIONS.includes(key) ? `- Unknown flag \`--${key}\`. It selects the target Forkbook, so it goes before the toolset name: \`npx forkbook tools --${key} <value> ${toolPath}\`.` : `- Unknown flag \`--${key}\`.`;
|
|
1364
|
+
let path = segments.join(".");
|
|
1365
|
+
return path ? `- \`${path}\`: ${issue.message}` : `- ${issue.message}`;
|
|
1366
|
+
}), validFlags = declaredKeys?.length ? `Valid flags: ${declaredKeys.map((key) => `\`--${key}\``).join(", ")}.` : "This tool takes no arguments.";
|
|
1367
|
+
return `Invalid arguments for \`${commandPath}\`:
|
|
1368
|
+
|
|
1369
|
+
${lines.join(`
|
|
1370
|
+
`)}
|
|
1371
|
+
${hasUnknownKey ? `
|
|
1372
|
+
${validFlags}
|
|
1373
|
+
` : ""}
|
|
1374
|
+
Run \`${commandPath} --help\` for the expected arguments.`;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
// src/cli/tools/register.ts
|
|
1378
|
+
function registerToolsPassthrough(program2, toolsCommand2, handleCommandFailure2) {
|
|
1379
|
+
program2.enablePositionalOptions(), toolsCommand2.helpOption(!1).usage("[options] [toolset] [tool] [args...]").argument("[toolset]", "A toolset provided by the target Forkbook configuration").argument("[tool]", "One of the toolset's tools, e.g. `stories find-by-component`").argument(
|
|
1380
|
+
"[args...]",
|
|
1381
|
+
"Tool arguments as `--key value` flags; values are JSON-parsed when possible"
|
|
1382
|
+
);
|
|
1383
|
+
for (let { flags, description } of TOOLS_OPTION_SPECS) {
|
|
1384
|
+
if (flags === "--no-attach") {
|
|
1385
|
+
let option = new Option(flags, description);
|
|
1386
|
+
option.negate = !1, toolsCommand2.addOption(option);
|
|
1387
|
+
continue;
|
|
1388
|
+
}
|
|
1389
|
+
toolsCommand2.option(flags, description);
|
|
1390
|
+
}
|
|
1391
|
+
toolsCommand2.passThroughOptions().action(
|
|
1392
|
+
async (toolset, tool, tokens, options) => {
|
|
1393
|
+
let cliOptions = pickCliOptions(options), flags = {
|
|
1394
|
+
input: options.input,
|
|
1395
|
+
json: options.json,
|
|
1396
|
+
output: options.output,
|
|
1397
|
+
help: options.help,
|
|
1398
|
+
attach: options.noAttach ? !1 : options.attach
|
|
1399
|
+
}, originalStdoutWrite = process.stdout.write;
|
|
1400
|
+
isJsonToolsRun(tokens, flags) && (process.stdout.write = process.stderr.write.bind(
|
|
1401
|
+
process.stderr
|
|
1402
|
+
));
|
|
1403
|
+
try {
|
|
1404
|
+
await withTelemetry2(
|
|
1405
|
+
"tools-command",
|
|
1406
|
+
{ cliOptions, fallbackTelemetryState: !0 },
|
|
1407
|
+
async () => {
|
|
1408
|
+
let keepAlive = setInterval(() => {
|
|
1409
|
+
}, 6e4), start = Date.now(), result;
|
|
1410
|
+
try {
|
|
1411
|
+
options.attach && options.noAttach ? result = {
|
|
1412
|
+
exitCode: 1,
|
|
1413
|
+
output: "Cannot combine `--attach` and `--no-attach`.",
|
|
1414
|
+
outcome: { kind: "intercept", reason: "invalid-arguments" },
|
|
1415
|
+
requestedMode: "auto",
|
|
1416
|
+
attachMode: "auto"
|
|
1417
|
+
} : result = await runToolsCommand({
|
|
1418
|
+
toolset,
|
|
1419
|
+
tool,
|
|
1420
|
+
tokens,
|
|
1421
|
+
target: { cwd: options.cwd, configDir: options.configDir },
|
|
1422
|
+
port: options.port,
|
|
1423
|
+
attach: options.noAttach ? !1 : options.attach,
|
|
1424
|
+
flags
|
|
1425
|
+
});
|
|
1426
|
+
} finally {
|
|
1427
|
+
clearInterval(keepAlive);
|
|
1428
|
+
}
|
|
1429
|
+
let duration = Date.now() - start;
|
|
1430
|
+
try {
|
|
1431
|
+
await printResult2(result, originalStdoutWrite);
|
|
1432
|
+
} finally {
|
|
1433
|
+
await reportToolsCommandTelemetry({ toolset, tool, result, duration }, cliOptions);
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
).catch(handleCommandFailure2(options.logfile));
|
|
1437
|
+
} finally {
|
|
1438
|
+
process.stdout.write = originalStdoutWrite;
|
|
1439
|
+
}
|
|
1440
|
+
process.exit();
|
|
1441
|
+
}
|
|
1442
|
+
);
|
|
1443
|
+
}
|
|
1444
|
+
function pickCliOptions(options) {
|
|
1445
|
+
let targetCwd = options.cwd ?? process.cwd();
|
|
1446
|
+
return {
|
|
1447
|
+
disableTelemetry: options.disableTelemetry,
|
|
1448
|
+
logfile: options.logfile,
|
|
1449
|
+
configDir: resolveStorybookConfigDir({ cwd: targetCwd, configDir: options.configDir })
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
async function reportToolsCommandTelemetry(run, cliOptions) {
|
|
1453
|
+
let { toolset, tool, result, duration } = run, { outcome } = result;
|
|
1454
|
+
outcome.kind !== "help" && (await reportToolsCommandEvent(
|
|
1455
|
+
{
|
|
1456
|
+
...toolset !== void 0 ? { toolset: sanitizeNamePart(toolset) } : {},
|
|
1457
|
+
...tool !== void 0 ? { tool: sanitizeNamePart(tool) } : {},
|
|
1458
|
+
success: outcome.kind === "success",
|
|
1459
|
+
outcome: outcome.kind,
|
|
1460
|
+
client: "cli",
|
|
1461
|
+
requestedMode: result.requestedMode,
|
|
1462
|
+
attachMode: result.attachMode,
|
|
1463
|
+
...result.host && (result.attachMode === "attached" || result.attachMode === "local") ? { resolvedMode: result.attachMode } : {},
|
|
1464
|
+
...result.host ? { host: result.host } : {},
|
|
1465
|
+
...result.multipleMatches ? { multipleMatches: !0 } : {},
|
|
1466
|
+
...result.fallbackReason ? { attachGate: result.fallbackReason } : {},
|
|
1467
|
+
...outcome.kind === "attach-gate" ? { attachGate: outcome.reason } : {},
|
|
1468
|
+
...outcome.kind === "intercept" ? { interceptReason: outcome.reason } : {},
|
|
1469
|
+
duration
|
|
1470
|
+
},
|
|
1471
|
+
// Metadata must describe the target project, consistent with the opt-out resolution.
|
|
1472
|
+
{ report: result.report, configDir: cliOptions.configDir }
|
|
1473
|
+
), outcome.kind === "error" && await sendTelemetryError(outcome.error, "tools-command", { cliOptions }));
|
|
1474
|
+
}
|
|
1475
|
+
async function printResult2({ output, exitCode, outputPath, fallbackNotice, multiInstanceNotice }, stdoutWrite) {
|
|
1476
|
+
for (let notice of [fallbackNotice, multiInstanceNotice])
|
|
1477
|
+
notice && await new Promise((resolveWrite) => {
|
|
1478
|
+
process.stderr.write(`${notice}
|
|
1479
|
+
`, () => resolveWrite());
|
|
1480
|
+
});
|
|
1481
|
+
if (outputPath) {
|
|
1482
|
+
let resolvedPath = resolve3(outputPath);
|
|
1483
|
+
await writeFile(resolvedPath, `${output}
|
|
1484
|
+
`, "utf-8"), logger.log(`Output written to ${resolvedPath}`);
|
|
1485
|
+
} else
|
|
1486
|
+
await new Promise((resolveWrite) => {
|
|
1487
|
+
stdoutWrite.call(process.stdout, `${output}
|
|
1488
|
+
`, void 0, () => resolveWrite());
|
|
1489
|
+
});
|
|
1490
|
+
exitCode !== 0 && (process.exitCode = exitCode);
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
// src/cli/build.ts
|
|
1494
|
+
import { cache as cache2, defaultConfigDir } from "@aussieljk/forkbook/internal/common";
|
|
1495
|
+
import { buildStaticStandalone, withTelemetry as withTelemetry3 } from "@aussieljk/forkbook/internal/core-server";
|
|
1496
|
+
var build = async (cliOptions) => {
|
|
1497
|
+
let { default: packageJson } = await import("@aussieljk/forkbook/package.json", { with: { type: "json" } }), options = {
|
|
1498
|
+
...cliOptions,
|
|
1499
|
+
configDir: cliOptions.configDir || defaultConfigDir(),
|
|
1500
|
+
outputDir: cliOptions.outputDir || "./forkbook-static",
|
|
1501
|
+
configType: "PRODUCTION",
|
|
1502
|
+
cache: cache2,
|
|
1503
|
+
packageJson
|
|
1504
|
+
};
|
|
1505
|
+
await withTelemetry3(
|
|
1506
|
+
"build",
|
|
1507
|
+
{ cliOptions, presetOptions: options },
|
|
1508
|
+
() => buildStaticStandalone(options)
|
|
1509
|
+
);
|
|
1510
|
+
};
|
|
1511
|
+
|
|
1512
|
+
// src/cli/buildIndex.ts
|
|
1513
|
+
import { Channel } from "@aussieljk/forkbook/internal/channels";
|
|
1514
|
+
import { cache as cache3, defaultConfigDir as defaultConfigDir2 } from "@aussieljk/forkbook/internal/common";
|
|
1515
|
+
import { buildIndexStandalone, withTelemetry as withTelemetry4 } from "@aussieljk/forkbook/internal/core-server";
|
|
1516
|
+
var buildIndex = async (cliOptions) => {
|
|
1517
|
+
let options = {
|
|
1518
|
+
...cliOptions,
|
|
1519
|
+
configDir: cliOptions.configDir || defaultConfigDir2(),
|
|
1520
|
+
outputFile: cliOptions.outputFile || "index.json",
|
|
1521
|
+
configType: "PRODUCTION",
|
|
1522
|
+
cache: cache3,
|
|
1523
|
+
packageJson: cliOptions.packageJson
|
|
1524
|
+
}, presetOptions = {
|
|
1525
|
+
...options,
|
|
1526
|
+
corePresets: [],
|
|
1527
|
+
overridePresets: [],
|
|
1528
|
+
channel: new Channel({})
|
|
1529
|
+
};
|
|
1530
|
+
await withTelemetry4("index", { cliOptions, presetOptions }, () => buildIndexStandalone(options));
|
|
1531
|
+
};
|
|
1532
|
+
|
|
1533
|
+
// src/cli/dev.ts
|
|
1534
|
+
import { cache as cache4, defaultConfigDir as defaultConfigDir3 } from "@aussieljk/forkbook/internal/common";
|
|
1535
|
+
import { buildDevStandalone, withTelemetry as withTelemetry5 } from "@aussieljk/forkbook/internal/core-server";
|
|
1536
|
+
import { logger as logger2 } from "@aussieljk/forkbook/internal/node-logger";
|
|
1537
|
+
import { dedent as dedent2 } from "ts-dedent";
|
|
1538
|
+
function printError(error) {
|
|
1539
|
+
error instanceof Error ? error.error ? logger2.error(error.error) : error.stats && error.stats.compilation.errors ? error.stats.compilation.errors.forEach((e) => logger2.log(e)) : logger2.error(error) : error.compilation?.errors && error.compilation.errors.forEach((e) => logger2.log(e)), logger2.warn(
|
|
1540
|
+
error.close ? dedent2`
|
|
1541
|
+
FATAL broken build!, will close the process,
|
|
1542
|
+
Fix the error below and restart storybook.
|
|
1543
|
+
` : dedent2`
|
|
1544
|
+
Broken build, fix the error above.
|
|
1545
|
+
You may need to refresh the browser.
|
|
1546
|
+
`
|
|
1547
|
+
);
|
|
1548
|
+
}
|
|
1549
|
+
var dev = async (cliOptions) => {
|
|
1550
|
+
let { env } = process;
|
|
1551
|
+
env.NODE_ENV = env.NODE_ENV || "development";
|
|
1552
|
+
let { default: packageJson } = await import("@aussieljk/forkbook/package.json", { with: { type: "json" } }), options = {
|
|
1553
|
+
...cliOptions,
|
|
1554
|
+
configDir: cliOptions.configDir || defaultConfigDir3(),
|
|
1555
|
+
configType: "DEVELOPMENT",
|
|
1556
|
+
cache: cache4,
|
|
1557
|
+
packageJson
|
|
1558
|
+
};
|
|
1559
|
+
await withTelemetry5(
|
|
1560
|
+
"dev",
|
|
1561
|
+
{
|
|
1562
|
+
cliOptions,
|
|
1563
|
+
presetOptions: options,
|
|
1564
|
+
printError
|
|
1565
|
+
},
|
|
1566
|
+
() => buildDevStandalone(options)
|
|
1567
|
+
);
|
|
1568
|
+
};
|
|
1569
|
+
|
|
1570
|
+
// src/bin/dev-options.ts
|
|
1571
|
+
import * as v3 from "valibot";
|
|
1572
|
+
import { HandledError } from "@aussieljk/forkbook/internal/common";
|
|
1573
|
+
var PortSchema = v3.message(
|
|
1574
|
+
v3.pipe(
|
|
1575
|
+
v3.union([v3.pipe(v3.string(), v3.trim(), v3.regex(/^\d+$/), v3.transform(Number)), v3.number()]),
|
|
1576
|
+
v3.minValue(1),
|
|
1577
|
+
v3.integer(),
|
|
1578
|
+
v3.maxValue(65535)
|
|
1579
|
+
),
|
|
1580
|
+
(issue) => `Port must be a valid number from 1 to 65535, received ${issue.received}.`
|
|
1581
|
+
), DevOptionsSchema = v3.looseObject({
|
|
1582
|
+
ci: v3.optional(v3.union([v3.boolean(), v3.string()])),
|
|
1583
|
+
configDir: v3.optional(v3.string()),
|
|
1584
|
+
host: v3.optional(v3.string()),
|
|
1585
|
+
open: v3.optional(v3.boolean()),
|
|
1586
|
+
port: v3.optional(PortSchema),
|
|
1587
|
+
staticDir: v3.optional(v3.string())
|
|
1588
|
+
});
|
|
1589
|
+
function resolveDevCommandOptions(options, { env = process.env } = {}) {
|
|
1590
|
+
let isClaudePreview = isClaudePreviewLaunch(env), PORT = env.PORT ?? void 0, SBCONFIG_PORT = env.SBCONFIG_PORT ?? void 0, result = v3.safeParse(DevOptionsSchema, {
|
|
1591
|
+
...options,
|
|
1592
|
+
host: env.SBCONFIG_HOSTNAME || options.host,
|
|
1593
|
+
staticDir: env.SBCONFIG_STATIC_DIR || options.staticDir,
|
|
1594
|
+
configDir: env.SBCONFIG_CONFIG_DIR || options.configDir,
|
|
1595
|
+
ci: env.CI || options.ci,
|
|
1596
|
+
port: isClaudePreview ? PORT ?? options.port ?? SBCONFIG_PORT : options.port ?? SBCONFIG_PORT ?? PORT,
|
|
1597
|
+
open: options.open ?? !1
|
|
1598
|
+
});
|
|
1599
|
+
if (!result.success)
|
|
1600
|
+
throw new HandledError(v3.summarize(result.issues));
|
|
1601
|
+
return result.output;
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
// src/bin/core.ts
|
|
1605
|
+
addToGlobalContext("cliVersion", version);
|
|
1606
|
+
process.env.STORYBOOK = "true";
|
|
1607
|
+
var handleCommandFailure = async (logFilePath) => {
|
|
1608
|
+
try {
|
|
1609
|
+
let logFile = await logTracker.writeToFile(logFilePath);
|
|
1610
|
+
logger3.log(`Debug logs are written to: ${logFile}`);
|
|
1611
|
+
} catch {
|
|
1612
|
+
}
|
|
1613
|
+
logger3.outro("Forkbook exited with an error"), process.exit(1);
|
|
1614
|
+
}, command = (name) => program.command(name).option(
|
|
1615
|
+
"--disable-telemetry",
|
|
1616
|
+
"Disable sending telemetry data",
|
|
1617
|
+
optionalEnvToBoolean(process.env.FORKBOOK_DISABLE_TELEMETRY)
|
|
1618
|
+
).option("--debug", "Get more logs in debug mode", !1).option("--enable-crash-reports", "Enable sending crash reports to telemetry data").addOption(
|
|
1619
|
+
new Option2("--loglevel <level>", "Define log level").choices(["trace", "debug", "info", "warn", "error", "silent"]).default("info")
|
|
1620
|
+
).option(
|
|
1621
|
+
"--logfile [path]",
|
|
1622
|
+
"Write all debug logs to the specified file at the end of the run. Defaults to debug-storybook.log when [path] is not provided"
|
|
1623
|
+
).hook("preAction", async (self) => {
|
|
1624
|
+
try {
|
|
1625
|
+
let options = self.opts(), loglevel = options.debug ? "debug" : options.loglevel;
|
|
1626
|
+
logger3.setLogLevel(loglevel), options.logfile && logTracker.enableLogWriting(), await globalSettings();
|
|
1627
|
+
} catch (e) {
|
|
1628
|
+
logger3.error(`Error loading global settings:
|
|
1629
|
+
` + String(e));
|
|
1630
|
+
}
|
|
1631
|
+
}).hook("postAction", async (command2) => {
|
|
1632
|
+
if (logTracker.shouldWriteLogsToFile)
|
|
1633
|
+
try {
|
|
1634
|
+
let logFile = await logTracker.writeToFile(command2.getOptionValue("logfile"));
|
|
1635
|
+
logger3.outro(`Debug logs are written to: ${logFile}`);
|
|
1636
|
+
} catch {
|
|
1637
|
+
}
|
|
1638
|
+
command2.name() === "build" && process.exit(0);
|
|
1639
|
+
});
|
|
1640
|
+
command("dev").option("-p, --port <number>", "Port to run Forkbook").option("-h, --host <string>", "Host to run Forkbook").option("-c, --config-dir <dir-name>", "Directory where to load Forkbook configurations from").option(
|
|
1641
|
+
"--https",
|
|
1642
|
+
"Serve Forkbook over HTTPS. Note: You must provide your own certificate information."
|
|
1643
|
+
).option(
|
|
1644
|
+
"--ssl-ca <ca>",
|
|
1645
|
+
"Provide an SSL certificate authority. (Optional with --https, required if using a self-signed certificate)",
|
|
1646
|
+
parseList
|
|
1647
|
+
).option("--ssl-cert <cert>", "Provide an SSL certificate. (Required with --https)").option("--ssl-key <key>", "Provide an SSL key. (Required with --https)").option("--smoke-test", "Exit after successful start").option("--ci", "CI mode (skip interactive prompts, don't open browser)").option("--open", "Open Forkbook automatically in the browser", !1).option("--no-open", "Do not open Forkbook in the browser (the default)").option("--quiet", "Suppress verbose build output").option("--no-version-updates", "Suppress update check", !0).option("--debug-webpack", "Display final webpack configurations for debugging purposes").option("--stats-json [directory]", "Write stats JSON to disk").option("--docs", "Build a documentation-only site using addon-docs").option("--exact-port", "Exit early if the desired port is not available").option(
|
|
1648
|
+
"--initial-path [path]",
|
|
1649
|
+
"URL path to be appended when visiting Forkbook for the first time"
|
|
1650
|
+
).option("--preview-only", "Use the preview without the manager UI").action(async (options) => {
|
|
1651
|
+
let { default: packageJson } = await import("@aussieljk/forkbook/package.json", { with: { type: "json" } });
|
|
1652
|
+
logger3.intro(`${packageJson.name} v${packageJson.version}`);
|
|
1653
|
+
let resolvedOptions;
|
|
1654
|
+
try {
|
|
1655
|
+
resolvedOptions = resolveDevCommandOptions(options);
|
|
1656
|
+
} catch (error) {
|
|
1657
|
+
return logger3.error(error instanceof Error ? error.message : String(error)), handleCommandFailure(options.logfile);
|
|
1658
|
+
}
|
|
1659
|
+
await dev({ ...resolvedOptions, packageJson }).catch(() => {
|
|
1660
|
+
handleCommandFailure(options.logfile);
|
|
1661
|
+
});
|
|
1662
|
+
});
|
|
1663
|
+
command("build").option("-o, --output-dir <dir-name>", "Directory where to store built files").option("-c, --config-dir <dir-name>", "Directory where to load Forkbook configurations from").option("--quiet", "Suppress verbose build output").option("--debug-webpack", "Display final webpack configurations for debugging purposes").option("--stats-json [directory]", "Write stats JSON to disk").option("--docs", "Build a documentation-only site using addon-docs").option("--test", "Build stories optimized for testing purposes.").option("--preview-only", "Use the preview without the manager UI").action(async (options) => {
|
|
1664
|
+
let { env } = process;
|
|
1665
|
+
env.NODE_ENV = env.NODE_ENV || "production";
|
|
1666
|
+
let { default: packageJson } = await import("@aussieljk/forkbook/package.json", { with: { type: "json" } });
|
|
1667
|
+
logger3.intro(`Building ${packageJson.name} v${packageJson.version}`), getEnvConfig(options, {
|
|
1668
|
+
staticDir: "SBCONFIG_STATIC_DIR",
|
|
1669
|
+
outputDir: "SBCONFIG_OUTPUT_DIR",
|
|
1670
|
+
configDir: "SBCONFIG_CONFIG_DIR"
|
|
1671
|
+
}), await build({
|
|
1672
|
+
...options,
|
|
1673
|
+
packageJson,
|
|
1674
|
+
test: !!options.test || optionalEnvToBoolean(process.env.FB_TESTBUILD)
|
|
1675
|
+
}).catch(() => {
|
|
1676
|
+
logger3.outro("Forkbook exited with an error"), process.exit(1);
|
|
1677
|
+
}), logger3.outro("Forkbook build completed successfully");
|
|
1678
|
+
});
|
|
1679
|
+
command("index").option("-o, --output-file <file-name>", "JSON file to output index").option("-c, --config-dir <dir-name>", "Directory where to load Forkbook configurations from").option("--quiet", "Suppress verbose build output").action(async (options) => {
|
|
1680
|
+
let { env } = process;
|
|
1681
|
+
env.NODE_ENV = env.NODE_ENV || "production";
|
|
1682
|
+
let { default: packageJson } = await import("@aussieljk/forkbook/package.json", { with: { type: "json" } });
|
|
1683
|
+
logger3.log(import_picocolors.default.bold(`${packageJson.name} v${packageJson.version}
|
|
1684
|
+
`)), getEnvConfig(options, {
|
|
1685
|
+
configDir: "SBCONFIG_CONFIG_DIR",
|
|
1686
|
+
outputFile: "SBCONFIG_OUTPUT_FILE"
|
|
1687
|
+
}), await buildIndex({
|
|
1688
|
+
...options,
|
|
1689
|
+
packageJson
|
|
1690
|
+
}).catch(() => process.exit(1));
|
|
1691
|
+
});
|
|
1692
|
+
var handleCliCommandFailure = (logFilePath) => async (error) => (error instanceof HandledError2 || logger3.error(String(error)), handleCommandFailure(logFilePath ?? !1)), toolsCommand = command("tools").description(
|
|
1693
|
+
"Run the agent tools provided by the target Forkbook configuration"
|
|
1694
|
+
);
|
|
1695
|
+
registerToolsPassthrough(program, toolsCommand, handleCliCommandFailure);
|
|
1696
|
+
var skillsCommand = command("skills").description(
|
|
1697
|
+
"Agent skills served by the target Forkbook configuration"
|
|
1698
|
+
);
|
|
1699
|
+
registerSkillsCommand(program, skillsCommand, handleCliCommandFailure);
|
|
1700
|
+
program.on("command:*", ([invalidCmd]) => {
|
|
1701
|
+
let errorMessage = ` Invalid command: ${import_picocolors.default.bold(invalidCmd)}.
|
|
1702
|
+
See --help for a list of available commands.`, suggestion = program.commands.map((cmd) => cmd.name()).find((cmd) => leven(cmd, invalidCmd) < 3);
|
|
1703
|
+
suggestion && (errorMessage += `
|
|
1704
|
+
Did you mean ${import_picocolors.default.yellow(suggestion)}?`), logger3.error(errorMessage), process.exit(1);
|
|
1705
|
+
});
|
|
1706
|
+
program.usage("<command> [options]").version(String(version)).parse(process.argv);
|