diff --git a/.changeset/curly-dragons-poke.md b/.changeset/curly-dragons-poke.md new file mode 100644 index 0000000..fa0af07 --- /dev/null +++ b/.changeset/curly-dragons-poke.md @@ -0,0 +1,6 @@ +--- +"stack-effect": minor +--- + +add JSX slot injection system and upgrade client templates to shadcn components. + diff --git a/bun.lock b/bun.lock index 4b5901b..5b469ce 100644 --- a/bun.lock +++ b/bun.lock @@ -19,7 +19,7 @@ }, "apps/cli": { "name": "stack-effect", - "version": "0.3.0", + "version": "0.4.0", "bin": { "stack-effect": "dist/index.js", }, @@ -120,6 +120,8 @@ "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.15", "", { "os": "win32", "cpu": "x64" }, "sha512-zBrGq5mx5wwpnow4+2BxUvleDM+GNd4sLbPaMapsSLQLD0NGRCquqPBTgN+7XkUteHvj7M+BstuI8tmnV7+HgQ=="], + "@blazediff/core": ["@blazediff/core@1.9.1", "", {}, "sha512-ehg3jIkYKulZh+8om/O25vkvSsXXwC+skXmyA87FFx6A/45eqOkZsBltMw/TVteb0mloiGT8oGRTcjRAz66zaA=="], + "@changesets/apply-release-plan": ["@changesets/apply-release-plan@7.1.1", "", { "dependencies": { "@changesets/config": "^3.1.4", "@changesets/get-version-range-type": "^0.4.0", "@changesets/git": "^3.0.4", "@changesets/should-skip-package": "^0.1.2", "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3", "detect-indent": "^6.0.0", "fs-extra": "^7.0.1", "lodash.startcase": "^4.4.0", "outdent": "^0.5.0", "prettier": "^2.7.1", "resolve-from": "^5.0.0", "semver": "^7.5.3" } }, "sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA=="], "@changesets/assemble-release-plan": ["@changesets/assemble-release-plan@6.0.10", "", { "dependencies": { "@changesets/errors": "^0.2.0", "@changesets/get-dependents-graph": "^2.1.4", "@changesets/should-skip-package": "^0.1.2", "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3", "semver": "^7.5.3" } }, "sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A=="], @@ -174,8 +176,18 @@ "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], + "@inquirer/ansi": ["@inquirer/ansi@2.0.5", "", {}, "sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw=="], + + "@inquirer/confirm": ["@inquirer/confirm@6.0.13", "", { "dependencies": { "@inquirer/core": "^11.1.10", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-wkGPC7yJ5WJk1DJ5SX7fzk+gfj4BM8cf5dDDi71B/551xHrdsZVRJOC0WyikXd0pEsb/9cLniuE4atbsMqmFkw=="], + + "@inquirer/core": ["@inquirer/core@11.1.10", "", { "dependencies": { "@inquirer/ansi": "^2.0.5", "@inquirer/figures": "^2.0.5", "@inquirer/type": "^4.0.5", "cli-width": "^4.1.0", "fast-wrap-ansi": "^0.2.0", "mute-stream": "^3.0.0", "signal-exit": "^4.1.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-a4Q5BXHQAHa9eO202sTaFCHFYVB3x5fauDuThEAdZ9gfn76pSxiKU7wWcEH0N1O0XmQvNfQNU6QXpiRxmYQx+A=="], + "@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="], + "@inquirer/figures": ["@inquirer/figures@2.0.5", "", {}, "sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ=="], + + "@inquirer/type": ["@inquirer/type@4.0.5", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q=="], + "@ioredis/commands": ["@ioredis/commands@1.5.1", "", {}, "sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw=="], "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], @@ -196,6 +208,8 @@ "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3", "", { "os": "win32", "cpu": "x64" }, "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ=="], + "@mswjs/interceptors": ["@mswjs/interceptors@0.41.9", "", { "dependencies": { "@open-draft/deferred-promise": "^2.2.0", "@open-draft/logger": "^0.3.0", "@open-draft/until": "^2.0.0", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "strict-event-emitter": "^0.5.1" } }, "sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], @@ -204,8 +218,16 @@ "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + "@open-draft/deferred-promise": ["@open-draft/deferred-promise@3.0.0", "", {}, "sha512-XW375UK8/9SqUVNVa6M0yEy8+iTi4QN5VZ7aZuRFQmy76LRwI9wy5F4YIBU6T+eTe2/DNDo8tqu8RHlwLHM6RA=="], + + "@open-draft/logger": ["@open-draft/logger@0.3.0", "", { "dependencies": { "is-node-process": "^1.2.0", "outvariant": "^1.4.0" } }, "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ=="], + + "@open-draft/until": ["@open-draft/until@2.1.0", "", {}, "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg=="], + "@oxc-project/types": ["@oxc-project/types@0.129.0", "", {}, "sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg=="], + "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], + "@repo/catalog": ["@repo/catalog@workspace:packages/catalog"], "@repo/config-typescript": ["@repo/config-typescript@workspace:packages/config-typescript"], @@ -276,8 +298,16 @@ "@types/node": ["@types/node@25.9.0", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-AOQwYUNolgy3VosiRqXrACUXTN8nJUtPl7FJXMqZVyxiiCLhQuG3jXKvCS1ALr+Y2OmZhzzLVlYPEqJaiqkaJQ=="], + "@types/set-cookie-parser": ["@types/set-cookie-parser@2.4.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw=="], + + "@types/statuses": ["@types/statuses@2.0.6", "", {}, "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA=="], + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], + "@vitest/browser": ["@vitest/browser@4.1.7", "", { "dependencies": { "@blazediff/core": "1.9.1", "@vitest/mocker": "4.1.7", "@vitest/utils": "4.1.7", "magic-string": "^0.30.21", "pngjs": "^7.0.0", "sirv": "^3.0.2", "tinyrainbow": "^3.1.0", "ws": "^8.19.0" }, "peerDependencies": { "vitest": "4.1.7" } }, "sha512-N2JFGfXoEGVAut+kHeru9dD4BUMq/q5xDvBARNl0tUsly3m5KglLOu8VO/6MkDfOlgxXTycojkt6gBKsuyR+IQ=="], + + "@vitest/browser-playwright": ["@vitest/browser-playwright@4.1.7", "", { "dependencies": { "@vitest/browser": "4.1.7", "@vitest/mocker": "4.1.7", "tinyrainbow": "^3.1.0" }, "peerDependencies": { "playwright": "*", "vitest": "4.1.7" } }, "sha512-OlTlJej7YN6VwV7zJJoNeaCsctF+JXpzpZ4oBHUbrQFfIq+0KW2f07rprCLh9N/zRIZ0v4Mchn1QDDmWMUhPKw=="], + "@vitest/expect": ["@vitest/expect@4.1.6", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.6", "@vitest/utils": "4.1.6", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-7EHDquPthALSV0jhhjgEW8FXaviMx7rSqu8W6oqCoAuOhKov814P99QDV1pxMA3QPv21YudvJngIhjrNI4opLg=="], "@vitest/mocker": ["@vitest/mocker@4.1.6", "", { "dependencies": { "@vitest/spy": "4.1.6", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-MCFc63czMjEInOlcY2cpQCvCN+KgbAn+60xu9cMgP4sKaLC5JNAKw7JH8QdAnoAC88hW1IiSNZ+GgVXlN1UcMQ=="], @@ -296,6 +326,8 @@ "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="], @@ -316,12 +348,22 @@ "chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="], + "cli-width": ["cli-width@4.1.0", "", {}, "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ=="], + + "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + "cluster-key-slot": ["cluster-key-slot@1.1.2", "", {}, "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="], "code-block-writer": ["code-block-writer@13.0.3", "", {}, "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg=="], + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "dataloader": ["dataloader@1.4.0", "", {}, "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw=="], @@ -342,10 +384,14 @@ "effect-boxes": ["effect-boxes@0.15.2", "", { "peerDependencies": { "effect": ">=4.0.0-beta.59" } }, "sha512-Ee3yNt1/Qf5h3Uczsbb+assCYlWi84vz/+HlLVrqan62+X6NrbFSo6ppjqPtn7CDKhV2o+HwLxJ1ORVs/TjiDg=="], + "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + "enquirer": ["enquirer@2.4.1", "", { "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" } }, "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ=="], "es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="], + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], @@ -358,6 +404,12 @@ "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + "fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="], + + "fast-string-width": ["fast-string-width@3.0.2", "", { "dependencies": { "fast-string-truncated-width": "^3.0.2" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="], + + "fast-wrap-ansi": ["fast-wrap-ansi@0.2.2", "", { "dependencies": { "fast-string-width": "^3.0.2" } }, "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q=="], + "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], @@ -372,12 +424,18 @@ "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + "graphql": ["graphql@16.14.0", "", {}, "sha512-BBvQ/406p+4CZbTpCbVPSxfzrZrbnuWSP1ELYgyS6B+hNeKzgrdB4JczCa5VZUBQrDa9hUngm0KnexY6pJRN5Q=="], + + "headers-polyfill": ["headers-polyfill@5.0.1", "", { "dependencies": { "@types/set-cookie-parser": "^2.4.10", "set-cookie-parser": "^3.0.1" } }, "sha512-1TJ6Fih/b8h5TIcv+1+Hw0PDQWJTKDKzFZzcKOiW1wJza3XoAQlkCuXLbymPYB8+ZQyw8mHvdw560e8zVFIWyA=="], + "human-id": ["human-id@4.1.3", "", { "bin": { "human-id": "dist/cli.js" } }, "sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q=="], "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], @@ -390,8 +448,12 @@ "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + "is-node-process": ["is-node-process@1.2.0", "", {}, "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw=="], + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], "is-subdir": ["is-subdir@1.2.0", "", { "dependencies": { "better-path-resolve": "1.0.0" } }, "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw=="], @@ -400,6 +462,8 @@ "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + "jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], + "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], "jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], @@ -450,14 +514,20 @@ "mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="], + "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "msgpackr": ["msgpackr@2.0.1", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-9J+tqTEsbHqY8YohazYgty7LgerFIWxvMLpUjqETSmjHojtJm2WnX2kK/2a1fLI7CO7ERP1YSEUXMucz4j+yBA=="], "msgpackr-extract": ["msgpackr-extract@3.0.3", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA=="], + "msw": ["msw@2.14.6", "", { "dependencies": { "@inquirer/confirm": "^6.0.11", "@mswjs/interceptors": "^0.41.3", "@open-draft/deferred-promise": "^3.0.0", "@types/statuses": "^2.0.6", "cookie": "^1.1.1", "graphql": "^16.13.2", "headers-polyfill": "^5.0.1", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", "picocolors": "^1.1.1", "rettime": "^0.11.11", "statuses": "^2.0.2", "strict-event-emitter": "^0.5.1", "tough-cookie": "^6.0.1", "type-fest": "^5.5.0", "until-async": "^3.0.2", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": ">= 4.8.x" }, "optionalPeers": ["typescript"], "bin": { "msw": "cli/index.js" } }, "sha512-ALe+N10S72cyx94cMcy3Zs4HhXCj35sgeAL4c+WTvKi0zWnbd8/h0lcFqv0mb2P+aSgAdD7p9HzvA0DiUPxsyg=="], + "multipasta": ["multipasta@0.2.7", "", {}, "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA=="], + "mute-stream": ["mute-stream@3.0.0", "", {}, "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw=="], + "nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], @@ -468,6 +538,8 @@ "outdent": ["outdent@0.5.0", "", {}, "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q=="], + "outvariant": ["outvariant@1.4.3", "", {}, "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA=="], + "p-filter": ["p-filter@2.1.0", "", { "dependencies": { "p-map": "^2.0.0" } }, "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw=="], "p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], @@ -486,6 +558,8 @@ "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + "path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], + "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], @@ -496,6 +570,12 @@ "pify": ["pify@4.0.1", "", {}, "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="], + "playwright": ["playwright@1.60.0", "", { "dependencies": { "playwright-core": "1.60.0" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA=="], + + "playwright-core": ["playwright-core@1.60.0", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA=="], + + "pngjs": ["pngjs@7.0.0", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="], + "postcss": ["postcss@8.5.14", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg=="], "prettier": ["prettier@2.8.8", "", { "bin": { "prettier": "bin-prettier.js" } }, "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="], @@ -512,8 +592,12 @@ "redis-parser": ["redis-parser@3.0.0", "", { "dependencies": { "redis-errors": "^1.0.0" } }, "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A=="], + "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + "rettime": ["rettime@0.11.11", "", {}, "sha512-ILJRqVWBCTlg9r42fFgwVZx1gnFAcQF8mRoMkbgQfIrjEDf9nbBFDFx00oloOa+Q869FUtaYDXZvEfnecQSCoQ=="], + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], "rolldown": ["rolldown@1.0.0", "", { "dependencies": { "@oxc-project/types": "=0.129.0", "@rolldown/pluginutils": "1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0", "@rolldown/binding-darwin-arm64": "1.0.0", "@rolldown/binding-darwin-x64": "1.0.0", "@rolldown/binding-freebsd-x64": "1.0.0", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0", "@rolldown/binding-linux-arm64-gnu": "1.0.0", "@rolldown/binding-linux-arm64-musl": "1.0.0", "@rolldown/binding-linux-ppc64-gnu": "1.0.0", "@rolldown/binding-linux-s390x-gnu": "1.0.0", "@rolldown/binding-linux-x64-gnu": "1.0.0", "@rolldown/binding-linux-x64-musl": "1.0.0", "@rolldown/binding-openharmony-arm64": "1.0.0", "@rolldown/binding-wasm32-wasi": "1.0.0", "@rolldown/binding-win32-arm64-msvc": "1.0.0", "@rolldown/binding-win32-x64-msvc": "1.0.0" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA=="], @@ -524,6 +608,8 @@ "semver": ["semver@7.8.0", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA=="], + "set-cookie-parser": ["set-cookie-parser@3.1.0", "", {}, "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw=="], + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], @@ -532,6 +618,8 @@ "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + "sirv": ["sirv@3.0.2", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g=="], + "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], @@ -546,12 +634,20 @@ "standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="], + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + "std-env": ["std-env@4.1.0", "", {}, "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ=="], + "strict-event-emitter": ["strict-event-emitter@0.5.1", "", {}, "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ=="], + + "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], + "tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="], + "term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="], "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], @@ -562,10 +658,18 @@ "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], + "tldts": ["tldts@7.0.30", "", { "dependencies": { "tldts-core": "^7.0.30" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw=="], + + "tldts-core": ["tldts-core@7.0.30", "", {}, "sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q=="], + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], "toml": ["toml@4.1.1", "", {}, "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw=="], + "totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="], + + "tough-cookie": ["tough-cookie@6.0.1", "", { "dependencies": { "tldts": "^7.0.5" } }, "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw=="], + "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], "ts-morph": ["ts-morph@28.0.0", "", { "dependencies": { "@ts-morph/common": "~0.29.0", "code-block-writer": "^13.0.3" } }, "sha512-Wp3tnZ2bzwxyTZMtgWVzXDfm7lB1Drz+y9DmmYH/L702PQhPyVrp3pkou3yIz4qjS14GY9kcpmLiOOMvl8oG1g=="], @@ -574,6 +678,8 @@ "turbo": ["turbo@2.9.14", "", { "optionalDependencies": { "@turbo/darwin-64": "2.9.14", "@turbo/darwin-arm64": "2.9.14", "@turbo/linux-64": "2.9.14", "@turbo/linux-arm64": "2.9.14", "@turbo/windows-64": "2.9.14", "@turbo/windows-arm64": "2.9.14" }, "bin": { "turbo": "bin/turbo" } }, "sha512-BQqXRr4UoWI3UPFrtznCLykYHxwxWh53iCB57x092jPMjIlW1wnm3N895g5irpiXmnxUhREBB0n6+y8BHhs4nw=="], + "type-fest": ["type-fest@5.6.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA=="], + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], "undici": ["undici@8.2.0", "", {}, "sha512-Z+4Hx9GE26Lh9Upwfnc8C7SsrpBPGaM/Gm6kMFtiG7c+5IvQKlXi/t+9x9DrrCh29cww5TSP9YdVaBcnLDs5fQ=="], @@ -582,6 +688,8 @@ "universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + "until-async": ["until-async@3.0.2", "", {}, "sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw=="], + "uuid": ["uuid@14.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg=="], "vite": ["vite@8.0.12", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.14", "rolldown": "1.0.0", "tinyglobby": "^0.2.16" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.18", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w2dDofOWv2QB09ZITZBsvKTVAlYvPR4IAmrY/v0ir9KvLs0xybR7i48wxhM1/oyBWO34wPns+bPGw5ZrZqDpZg=="], @@ -596,10 +704,18 @@ "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], + "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + "ws": ["ws@8.20.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w=="], + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], + "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + + "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + "@manypkg/find-root/@types/node": ["@types/node@12.20.55", "", {}, "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="], "@manypkg/find-root/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], @@ -608,16 +724,32 @@ "@manypkg/get-packages/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], + "@mswjs/interceptors/@open-draft/deferred-promise": ["@open-draft/deferred-promise@2.2.0", "", {}, "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA=="], + "@types/ws/@types/node": ["@types/node@25.7.0", "", { "dependencies": { "undici-types": "~7.21.0" } }, "sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg=="], + "@vitest/browser/@vitest/mocker": ["@vitest/mocker@4.1.7", "", { "dependencies": { "@vitest/spy": "4.1.7", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA=="], + + "@vitest/browser/@vitest/utils": ["@vitest/utils@4.1.7", "", { "dependencies": { "@vitest/pretty-format": "4.1.7", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw=="], + + "@vitest/browser-playwright/@vitest/mocker": ["@vitest/mocker@4.1.7", "", { "dependencies": { "@vitest/spy": "4.1.7", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA=="], + "bun-types/@types/node": ["@types/node@25.7.0", "", { "dependencies": { "undici-types": "~7.21.0" } }, "sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg=="], "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + "playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], + "read-yaml-file/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], "@types/ws/@types/node/undici-types": ["undici-types@7.21.0", "", {}, "sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ=="], + "@vitest/browser-playwright/@vitest/mocker/@vitest/spy": ["@vitest/spy@4.1.7", "", {}, "sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q=="], + + "@vitest/browser/@vitest/mocker/@vitest/spy": ["@vitest/spy@4.1.7", "", {}, "sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q=="], + + "@vitest/browser/@vitest/utils/@vitest/pretty-format": ["@vitest/pretty-format@4.1.7", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw=="], + "bun-types/@types/node/undici-types": ["undici-types@7.21.0", "", {}, "sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ=="], "read-yaml-file/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], diff --git a/package.json b/package.json index 7dd82e0..e6ed014 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "format:check": "biome check .", "prepare": "effect-language-service patch", "test": "turbo run test", - "test:e2e": "playwright test", + "test:e2e": "vitest run --config vitest.e2e.config.ts --root apps/cli", "start": "bun apps/cli/src/index.ts", "type-check": "turbo run type-check", "complexity": "bun run scripts/complexity-report.ts" diff --git a/packages/catalog/src/registry/content/client-api.ts b/packages/catalog/src/registry/content/client-api.ts index 1173e40..f9683a7 100644 --- a/packages/catalog/src/registry/content/client-api.ts +++ b/packages/catalog/src/registry/content/client-api.ts @@ -27,42 +27,44 @@ export const helloAtom = runtime.fn(() => export const clientRestCardContents = `import { useAtom } from "@effect/atom-react"; import { AsyncResult } from "effect/unstable/reactivity"; import { helloAtom } from "@/lib/atoms/hello-atom"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; export const RestCard = () => { const [response, getHello] = useAtom(helloAtom); return ( -
-

REST API

- -
- {AsyncResult.builder(response) - .onSuccess((data) => ( -
-              
-                Message: {data.message}{"\\n"}Success: {data.success.toString()}
-              
-            
- )) - .onFailure((error) => ( -
-              Error: {JSON.stringify(error, null, 2)}
-            
- )) - .onInitial(() => ( -

- Click the button above to test the REST API -

- )) - .orNull()} -
-
+ + + REST API + + + +
+ {AsyncResult.builder(response) + .onSuccess((data) => ( +
+                
+                  Message: {data.message}{"\\n"}Success: {data.success.toString()}
+                
+              
+ )) + .onFailure((error) => ( +
+                Error: {JSON.stringify(error, null, 2)}
+              
+ )) + .onInitial(() => ( +

+ Click the button above to test the REST API +

+ )) + .orNull()} +
+
+
); }; `; diff --git a/packages/catalog/src/registry/content/client-chat.ts b/packages/catalog/src/registry/content/client-chat.ts index 8df8166..433650a 100644 --- a/packages/catalog/src/registry/content/client-chat.ts +++ b/packages/catalog/src/registry/content/client-chat.ts @@ -301,6 +301,9 @@ import { AsyncResult } from "effect/unstable/reactivity"; import { useEffect, useMemo, useRef, useState } from "react"; import { chatAtom } from "@/lib/atoms/chat-atom"; import { cn } from "@/lib/utils"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; type Message = { role: "user" | "assistant" | "system"; @@ -437,9 +440,9 @@ export function ChatBox() { }, [scrollTrigger]); return ( -
-
-

Chat (RPC)

+ + + Chat (RPC)
{isStreaming && ( @@ -457,9 +460,10 @@ export function ChatBox() { )}
-
+ -
+ +
{displayHistory.length === 0 && currentSegments.length === 0 && (
@@ -535,16 +539,17 @@ export function ChatBox() { {currentResult.error.message}

{currentResult.error.recoverable && ( - + )}
)} @@ -553,26 +558,24 @@ export function ChatBox() {
- setInput(e.target.value)} onKeyDown={(e) => e.key === "Enter" && handleSend()} disabled={isWaiting || isStreaming} - className="flex-1 rounded-md border border-input bg-background px-3 py-2 text-sm" /> - +
-
+ + ); } diff --git a/packages/catalog/src/registry/content/client-rpc.ts b/packages/catalog/src/registry/content/client-rpc.ts index 24f43bd..eb962dd 100644 --- a/packages/catalog/src/registry/content/client-rpc.ts +++ b/packages/catalog/src/registry/content/client-rpc.ts @@ -92,6 +92,8 @@ export const tickAtom = runtime.fn( export const clientRpcCardContents = `import { useAtom } from "@effect/atom-react"; import { AsyncResult } from "effect/unstable/reactivity"; import { tickAtom } from "@/lib/atoms/tick-atom"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; export const RpcCard = () => { const [result, search] = useAtom(tickAtom); @@ -102,16 +104,16 @@ export const RpcCard = () => { }; return (
-
-

RPC API

- -
+ + + RPC API + + + + +
{event ? ( diff --git a/packages/catalog/src/registry/content/client-websocket.ts b/packages/catalog/src/registry/content/client-websocket.ts index 3b066ae..c494f55 100644 --- a/packages/catalog/src/registry/content/client-websocket.ts +++ b/packages/catalog/src/registry/content/client-websocket.ts @@ -61,6 +61,8 @@ import type { import { AsyncResult } from "effect/unstable/reactivity"; import { useEffect, useMemo } from "react"; import { cn } from "@/lib/utils"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { presenceSubscriptionAtom, WebSocketClient, @@ -157,11 +159,11 @@ export function PresencePanel({ className }: { className?: string }) { const isConnecting = AsyncResult.isInitial(eventsResult); return ( -
-
+ +
-

WebSocket Presence (RPC)

+ WebSocket Presence (RPC)

Realtime status updates over RPC.

-
+ -
+
- - - +
@@ -248,8 +249,8 @@ export function PresencePanel({ className }: { className?: string }) { )}
-
-
+ + ); } `; diff --git a/packages/catalog/src/registry/content/client.ts b/packages/catalog/src/registry/content/client.ts index e1c6977..a077d81 100644 --- a/packages/catalog/src/registry/content/client.ts +++ b/packages/catalog/src/registry/content/client.ts @@ -27,6 +27,7 @@ export const clientPackageJsonContents = `{ "dependencies": { "@base-ui/react": "^1.3.0", "@effect/atom-react": "4.0.0-beta.67", + "@fontsource-variable/jetbrains-mono": "^5.2.5", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "effect": "4.0.0-beta.67", @@ -110,10 +111,21 @@ if (rootElement) { } `; -export const clientAppTsxContents = `function App() { +export const clientAppTsxContents = `import { ThemeToggle } from "./components/theme-toggle"; + +function App() { return ( -
-

{{targetName}}

+
+ + +
+

{{targetName}}

+

A typesafe fullstack monorepo

+
+ +
+ {/* @slot:components */} +
); } @@ -133,6 +145,9 @@ export default defineConfig({ "@": path.resolve(__dirname, "./src"), }, }, + optimizeDeps: { + include: ["@repo/domain"], + }, server: { strictPort: true, host: "127.0.0.1", @@ -169,6 +184,9 @@ export const clientShadcnComponentJson = `{ export const clientIndexCssContents = `@import "tailwindcss"; @import "tw-animate-css"; @import "shadcn/tailwind.css"; +@import "@fontsource-variable/jetbrains-mono"; + +@custom-variant dark (&:is(.dark *)); @theme inline { --radius-sm: calc(var(--radius) - 4px); @@ -193,6 +211,24 @@ export const clientIndexCssContents = `@import "tailwindcss"; --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); + --font-heading: var(--font-mono); + --font-mono: "JetBrains Mono Variable", monospace; + --radius-2xl: calc(var(--radius) * 1.8); + --radius-3xl: calc(var(--radius) * 2.2); + --radius-4xl: calc(var(--radius) * 2.6); } :root { @@ -215,6 +251,19 @@ export const clientIndexCssContents = `@import "tailwindcss"; --border: oklch(0.925 0.005 214.3); --input: oklch(0.925 0.005 214.3); --ring: oklch(0.723 0.014 214.4); + --chart-1: oklch(0.823 0.12 346.018); + --chart-2: oklch(0.656 0.241 354.308); + --chart-3: oklch(0.592 0.249 0.584); + --chart-4: oklch(0.525 0.223 3.958); + --chart-5: oklch(0.459 0.187 3.815); + --sidebar: oklch(0.987 0.002 197.1); + --sidebar-foreground: oklch(0.148 0.004 228.8); + --sidebar-primary: oklch(0.609 0.126 221.723); + --sidebar-primary-foreground: oklch(0.984 0.019 200.873); + --sidebar-accent: oklch(0.963 0.002 197.1); + --sidebar-accent-foreground: oklch(0.218 0.008 223.9); + --sidebar-border: oklch(0.925 0.005 214.3); + --sidebar-ring: oklch(0.723 0.014 214.4); } .dark { @@ -236,6 +285,19 @@ export const clientIndexCssContents = `@import "tailwindcss"; --border: oklch(1 0 0 / 10%); --input: oklch(1 0 0 / 15%); --ring: oklch(0.56 0.021 213.5); + --chart-1: oklch(0.823 0.12 346.018); + --chart-2: oklch(0.656 0.241 354.308); + --chart-3: oklch(0.592 0.249 0.584); + --chart-4: oklch(0.525 0.223 3.958); + --chart-5: oklch(0.459 0.187 3.815); + --sidebar: oklch(0.218 0.008 223.9); + --sidebar-foreground: oklch(0.987 0.002 197.1); + --sidebar-primary: oklch(0.715 0.143 215.221); + --sidebar-primary-foreground: oklch(0.302 0.056 229.695); + --sidebar-accent: oklch(0.275 0.011 216.9); + --sidebar-accent-foreground: oklch(0.987 0.002 197.1); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.56 0.021 213.5); } @layer base { @@ -245,9 +307,62 @@ export const clientIndexCssContents = `@import "tailwindcss"; body { @apply bg-background text-foreground; } + html { + @apply font-mono; + } } `; +export const clientAtomContents = `import { Layer } from "effect"; +import { DevTools } from "effect/unstable/devtools"; +import { Atom } from "effect/unstable/reactivity"; + +const ENABLE_DEVTOOLS = import.meta.env.VITE_ENABLE_DEVTOOLS === "true"; + +export const runtime = Atom.runtime( + ENABLE_DEVTOOLS ? DevTools.layer() : Layer.empty, +); +`; + +export const clientThemeToggleContents = `import { useLayoutEffect, useState } from "react"; +import { Card, CardContent } from "./ui/card"; +import { Switch } from "./ui/switch"; + +export const ThemeToggle = () => { + const [isDark, setIsDark] = useState(false); + + useLayoutEffect(() => { + const storedTheme = localStorage.getItem("theme"); + const prefersDark = window.matchMedia( + "(prefers-color-scheme: dark)", + ).matches; + const shouldUseDark = storedTheme ? storedTheme === "dark" : prefersDark; + + document.documentElement.classList.toggle("dark", shouldUseDark); + setIsDark(shouldUseDark); + }, []); + + const handleThemeToggle = () => { + const nextIsDark = !isDark; + setIsDark(nextIsDark); + document.documentElement.classList.toggle("dark", nextIsDark); + localStorage.setItem("theme", nextIsDark ? "dark" : "light"); + }; + return ( + + + + + + + ); +}; +`; + export const clientUtilsContents = `import { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; diff --git a/packages/catalog/src/registry/modules/client.ts b/packages/catalog/src/registry/modules/client.ts index 1d329cb..6a106f3 100644 --- a/packages/catalog/src/registry/modules/client.ts +++ b/packages/catalog/src/registry/modules/client.ts @@ -66,6 +66,26 @@ export const clientModules: ReadonlyArray = [ name: "@repo/domain", value: "workspace:*", }, + { + _tag: "jsx-slot", + path: "{{targetPath}}/src/app.tsx", + slotId: "components", + content: "", + import: { + moduleSpecifier: "./components/rest-card", + namedImports: ["RestCard"], + }, + }, + ], + scripts: [ + { + label: "Install shadcn button component", + command: "bunx shadcn@latest add button --yes --overwrite", + }, + { + label: "Install shadcn card component", + command: "bunx shadcn@latest add card --yes --overwrite", + }, ], }, { @@ -112,6 +132,26 @@ export const clientModules: ReadonlyArray = [ name: "@repo/domain", value: "workspace:*", }, + { + _tag: "jsx-slot", + path: "{{targetPath}}/src/app.tsx", + slotId: "components", + content: "", + import: { + moduleSpecifier: "./components/rpc-card", + namedImports: ["RpcCard"], + }, + }, + ], + scripts: [ + { + label: "Install shadcn button component", + command: "bunx shadcn@latest add button --yes --overwrite", + }, + { + label: "Install shadcn card component", + command: "bunx shadcn@latest add card --yes --overwrite", + }, ], }, { @@ -158,6 +198,30 @@ export const clientModules: ReadonlyArray = [ name: "@repo/domain", value: "workspace:*", }, + { + _tag: "jsx-slot", + path: "{{targetPath}}/src/app.tsx", + slotId: "components", + content: "", + import: { + moduleSpecifier: "./components/chat-box", + namedImports: ["ChatBox"], + }, + }, + ], + scripts: [ + { + label: "Install shadcn button component", + command: "bunx shadcn@latest add button --yes --overwrite", + }, + { + label: "Install shadcn card component", + command: "bunx shadcn@latest add card --yes --overwrite", + }, + { + label: "Install shadcn input component", + command: "bunx shadcn@latest add input --yes --overwrite", + }, ], }, { @@ -206,6 +270,26 @@ export const clientModules: ReadonlyArray = [ name: "@effect/platform-browser", value: "4.0.0-beta.67", }, + { + _tag: "jsx-slot", + path: "{{targetPath}}/src/app.tsx", + slotId: "components", + content: ``, + import: { + moduleSpecifier: "./components/presence-panel", + namedImports: ["PresencePanel"], + }, + }, + ], + scripts: [ + { + label: "Install shadcn button component", + command: "bunx shadcn@latest add button --yes --overwrite", + }, + { + label: "Install shadcn card component", + command: "bunx shadcn@latest add card --yes --overwrite", + }, ], }, ]; diff --git a/packages/catalog/src/registry/targetRegistry.ts b/packages/catalog/src/registry/targetRegistry.ts index 3f70e0e..5efdb8f 100644 --- a/packages/catalog/src/registry/targetRegistry.ts +++ b/packages/catalog/src/registry/targetRegistry.ts @@ -10,11 +10,13 @@ import { } from "./content/cli"; import { clientAppTsxContents, + clientAtomContents, clientIndexCssContents, clientIndexHtmlContents, clientMainTsxContents, clientPackageJsonContents, clientShadcnComponentJson, + clientThemeToggleContents, clientTsconfigConfigContents, clientTsconfigContents, clientUtilsContents, @@ -127,6 +129,16 @@ export const targetRegistry: ReadonlyArray = [ path: "{{targetPath}}/src/lib/utils.ts", contents: clientUtilsContents, }, + { + _tag: "file", + path: "{{targetPath}}/src/lib/atom.ts", + contents: clientAtomContents, + }, + { + _tag: "file", + path: "{{targetPath}}/src/components/theme-toggle.tsx", + contents: clientThemeToggleContents, + }, { _tag: "file", path: "{{targetPath}}/src/vite-env.d.ts", @@ -183,6 +195,16 @@ export const targetRegistry: ReadonlyArray = [ value: "git clean -xdf .cache .turbo dist node_modules", }, ], + scripts: [ + { + label: "Install shadcn card component", + command: "bunx shadcn@latest add card --yes --overwrite", + }, + { + label: "Install shadcn switch component", + command: "bunx shadcn@latest add switch --yes --overwrite", + }, + ], }, { diff --git a/packages/domain/src/Catalog.ts b/packages/domain/src/Catalog.ts index 4ee0e1c..f50c4dc 100644 --- a/packages/domain/src/Catalog.ts +++ b/packages/domain/src/Catalog.ts @@ -171,6 +171,26 @@ export const Contribution = Schema.TaggedUnion({ defaultImport: Schema.optional(Schema.String), }), }, + + /** + * JSX slot injection - inserts content at a named slot marker in a file. + * + * Template files use `{/* @slot: *​/}` comments as injection points. + * Multiple contributions targeting the same slot are concatenated in order. + * Optionally adds import statements to the top of the file. + */ + "jsx-slot": { + path: Schema.String, + slotId: Schema.String, + content: Schema.String, + import: Schema.optional( + Schema.Struct({ + moduleSpecifier: Schema.String, + namedImports: Schema.optional(Schema.Array(Schema.String)), + defaultImport: Schema.optional(Schema.String), + }), + ), + }, }); /** diff --git a/packages/domain/src/Plan.ts b/packages/domain/src/Plan.ts index 7d093ae..e509cac 100644 --- a/packages/domain/src/Plan.ts +++ b/packages/domain/src/Plan.ts @@ -90,6 +90,12 @@ export const TsAppendCallArgOp = Schema.TaggedStruct("ts-append-call-arg", { argument: Schema.String, }); +export const TsJsxSlotOp = Schema.TaggedStruct("ts-jsx-slot", { + fileType: Schema.tag("typescript"), + slotId: Schema.String, + content: Schema.String, +}); + export const CompositionOperation = Schema.Union([ // JSON operations JsonPkgExportsOp, @@ -99,6 +105,7 @@ export const CompositionOperation = Schema.Union([ TsAddImportOp, TsAddReexportOp, TsAppendCallArgOp, + TsJsxSlotOp, ]).pipe(Schema.toTaggedUnion("fileType")); // ============================================================================= diff --git a/packages/scaffold/src/service/apply/TypeScriptComposer.ts b/packages/scaffold/src/service/apply/TypeScriptComposer.ts index 038cd51..2298f0f 100644 --- a/packages/scaffold/src/service/apply/TypeScriptComposer.ts +++ b/packages/scaffold/src/service/apply/TypeScriptComposer.ts @@ -3,6 +3,7 @@ import type { TsAddImportOp, TsAddReexportOp, TsAppendCallArgOp, + TsJsxSlotOp, } from "@repo/domain/Plan"; import { Array as Arr, @@ -56,6 +57,9 @@ export class TypeScriptComposer extends Context.Service()( Match.tag("ts-append-call-arg", (appendOp) => applyTsAppendCallArg(sourceFile, appendOp), ), + Match.tag("ts-jsx-slot", (slotOp) => + Effect.sync(() => applyTsJsxSlot(sourceFile, slotOp)), + ), Match.exhaustive, ), { discard: true }, @@ -253,3 +257,23 @@ const applyTsAppendCallArg = Effect.fn("applyTsAppendCallArg")(function* ( functionName: op.functionName, }); }); + +// ============================================================================= +// JSX Slot Injection +// ============================================================================= + +const applyTsJsxSlot = ( + sourceFile: SourceFile, + op: typeof TsJsxSlotOp.Type, +): void => { + const text = sourceFile.getFullText(); + const slotMarker = `{/* @slot:${op.slotId} */}`; + const index = text.indexOf(slotMarker); + + if (index === -1) return; + + // Insert content after the slot marker (on the next line) + const insertPos = index + slotMarker.length; + const newText = `${text.slice(0, insertPos)}\n ${op.content}${text.slice(insertPos)}`; + sourceFile.replaceWithText(newText); +}; diff --git a/packages/scaffold/src/service/plan/ContributionResolver.ts b/packages/scaffold/src/service/plan/ContributionResolver.ts index 5335c48..0c31ef9 100644 --- a/packages/scaffold/src/service/plan/ContributionResolver.ts +++ b/packages/scaffold/src/service/plan/ContributionResolver.ts @@ -125,6 +125,13 @@ const resolveContributionTokens = ( argument: c.argument, import: c.import, }), + "jsx-slot": (c): typeof Contribution.Type => + Contribution.cases["jsx-slot"].make({ + path: resolveString(c.path), + slotId: c.slotId, + content: c.content, + import: c.import, + }), }), ); }; diff --git a/packages/scaffold/src/service/plan/PlanAssessor.ts b/packages/scaffold/src/service/plan/PlanAssessor.ts index 8418dee..dbd8e19 100644 --- a/packages/scaffold/src/service/plan/PlanAssessor.ts +++ b/packages/scaffold/src/service/plan/PlanAssessor.ts @@ -38,6 +38,18 @@ export type PlanningIntentComposition = { }; }; +export type PlanningIntentJsxSlot = { + readonly slotId: string; + readonly content: string; + readonly import: + | { + readonly moduleSpecifier: string; + readonly namedImports: ReadonlyArray | undefined; + readonly defaultImport: string | undefined; + } + | undefined; +}; + export type PlanningIntentPath = { readonly path: string; readonly contents: string | undefined; @@ -46,6 +58,7 @@ export type PlanningIntentPath = { readonly scripts: ReadonlyArray<{ name: string; value: string }>; readonly barrelExports: ReadonlyArray<{ exportPath: string }>; readonly compositions: ReadonlyArray; + readonly jsxSlots: ReadonlyArray; readonly tsconfig: | { path: string; @@ -192,6 +205,26 @@ function toCompositionOperations( }); } + // JSX slots -> ts-add-import (optional) + ts-jsx-slot + for (const jsxSlot of planningPath.jsxSlots) { + if (jsxSlot.import) { + operations.push({ + _tag: "ts-add-import", + fileType: "typescript", + moduleSpecifier: jsxSlot.import.moduleSpecifier, + namedImports: jsxSlot.import.namedImports, + defaultImport: jsxSlot.import.defaultImport, + }); + } + + operations.push({ + _tag: "ts-jsx-slot", + fileType: "typescript", + slotId: jsxSlot.slotId, + content: jsxSlot.content, + }); + } + return operations; } diff --git a/packages/scaffold/src/service/plan/PlanRenderer.ts b/packages/scaffold/src/service/plan/PlanRenderer.ts index 6fb07f8..1093743 100644 --- a/packages/scaffold/src/service/plan/PlanRenderer.ts +++ b/packages/scaffold/src/service/plan/PlanRenderer.ts @@ -92,6 +92,9 @@ const renderOperation = ( Match.tag("ts-append-call-arg", (o) => { return `In \`${path}\`, find \`const ${o.targetVariable} = ${o.functionName}(...)\` and append \`${o.argument}\` as an additional argument`; }), + Match.tag("ts-jsx-slot", (o) => { + return `In \`${path}\`, inject content at slot \`@slot:${o.slotId}\``; + }), Match.exhaustive, ); diff --git a/packages/scaffold/src/service/plan/PlanService.ts b/packages/scaffold/src/service/plan/PlanService.ts index 9de02ce..7f655ba 100644 --- a/packages/scaffold/src/service/plan/PlanService.ts +++ b/packages/scaffold/src/service/plan/PlanService.ts @@ -195,6 +195,22 @@ export const PlanningIntentEntry = Schema.TaggedUnion({ defaultImport: Schema.Union([Schema.String, Schema.Undefined]), }), }, + jsxSlot: { + path: Schema.String, + slotId: Schema.String, + content: Schema.String, + import: Schema.Union([ + Schema.Struct({ + moduleSpecifier: Schema.String, + namedImports: Schema.Union([ + Schema.Array(Schema.String), + Schema.Undefined, + ]), + defaultImport: Schema.Union([Schema.String, Schema.Undefined]), + }), + Schema.Undefined, + ]), + }, }); const toPlanningIntentEntries = ( @@ -237,6 +253,20 @@ const toPlanningIntentEntries = ( }, }), ], + "jsx-slot": (c): ReadonlyArray => [ + PlanningIntentEntry.cases.jsxSlot.make({ + path: c.path, + slotId: c.slotId, + content: c.content, + import: c.import + ? { + moduleSpecifier: c.import.moduleSpecifier, + namedImports: c.import.namedImports, + defaultImport: c.import.defaultImport, + } + : undefined, + }), + ], }), ); @@ -261,6 +291,7 @@ const derivePlanningIntentPath = ({ const tsCallArgEntries = entries.filter( PlanningIntentEntry.guards.tsCallArg, ); + const jsxSlotEntries = entries.filter(PlanningIntentEntry.guards.jsxSlot); const resolveContents = () => requireSingleValue({ @@ -338,6 +369,7 @@ const derivePlanningIntentPath = ({ ...emptyPackageJsonFields, barrelExports: [], compositions: [], + jsxSlots: [], tsconfig: isConflictOnModify ? { path, contents } : undefined, } satisfies PlanningIntentPath; }), @@ -350,6 +382,7 @@ const derivePlanningIntentPath = ({ ...(yield* resolvePackageJsonFields()), barrelExports: [], compositions: [], + jsxSlots: [], tsconfig: undefined, } satisfies PlanningIntentPath; }), @@ -368,6 +401,7 @@ const derivePlanningIntentPath = ({ errorMessage: `Conflicting barrel export outcomes for ${path}.`, }), compositions: [], + jsxSlots: [], tsconfig: undefined, } satisfies PlanningIntentPath; }), @@ -385,6 +419,24 @@ const derivePlanningIntentPath = ({ argument: entry.argument, import: entry.import, })), + jsxSlots: [], + tsconfig: undefined, + } satisfies PlanningIntentPath; + }), + ), + Match.when("jsxSlot", () => + Effect.gen(function* () { + return { + path, + contents: undefined, + ...emptyPackageJsonFields, + barrelExports: [], + compositions: [], + jsxSlots: Arr.map(jsxSlotEntries, (entry) => ({ + slotId: entry.slotId, + content: entry.content, + import: entry.import, + })), tsconfig: undefined, } satisfies PlanningIntentPath; }), @@ -397,6 +449,7 @@ const derivePlanningIntentPath = ({ ...(yield* resolvePackageJsonFields()), barrelExports: [], compositions: [], + jsxSlots: [], tsconfig: undefined, } satisfies PlanningIntentPath; }), @@ -414,6 +467,7 @@ const derivePlanningIntentPath = ({ argument: entry.argument, import: entry.import, })), + jsxSlots: [], tsconfig: undefined, } satisfies PlanningIntentPath; }), @@ -432,6 +486,24 @@ const derivePlanningIntentPath = ({ errorMessage: `Conflicting barrel export outcomes for ${path}.`, }), compositions: [], + jsxSlots: [], + tsconfig: undefined, + } satisfies PlanningIntentPath; + }), + ), + Match.when("authoritativeJsxSlot", () => + Effect.gen(function* () { + return { + path, + contents: yield* resolveContents(), + ...emptyPackageJsonFields, + barrelExports: [], + compositions: [], + jsxSlots: Arr.map(jsxSlotEntries, (entry) => ({ + slotId: entry.slotId, + content: entry.content, + import: entry.import, + })), tsconfig: undefined, } satisfies PlanningIntentPath; }), @@ -443,7 +515,8 @@ const derivePlanningIntentPath = ({ type CompositePlanningIntentFamily = | "authoritativePackageJson" | "authoritativeTsCallArg" - | "authoritativeBarrel"; + | "authoritativeBarrel" + | "authoritativeJsxSlot"; const COMPOSITE_FAMILIES: ReadonlyArray<{ pair: [PlanningIntentFamily, PlanningIntentFamily]; @@ -455,6 +528,7 @@ const COMPOSITE_FAMILIES: ReadonlyArray<{ }, { pair: ["authoritative", "tsCallArg"], result: "authoritativeTsCallArg" }, { pair: ["authoritative", "barrel"], result: "authoritativeBarrel" }, + { pair: ["authoritative", "jsxSlot"], result: "authoritativeJsxSlot" }, ]; const derivePlanningIntentFamily = ({ @@ -495,13 +569,15 @@ type PlanningIntentFamily = | "authoritative" | "packageJson" | "barrel" - | "tsCallArg"; + | "tsCallArg" + | "jsxSlot"; const toPlanningIntentFamily = PlanningIntentEntry.match({ authoritative: () => "authoritative" as const, packageJsonEntry: () => "packageJson" as const, barrelExport: () => "barrel" as const, tsCallArg: () => "tsCallArg" as const, + jsxSlot: () => "jsxSlot" as const, }) satisfies (entry: typeof PlanningIntentEntry.Type) => PlanningIntentFamily; const requireSingleValue = ({ diff --git a/stack.effect.json b/stack.effect.json new file mode 100644 index 0000000..7d2e60b --- /dev/null +++ b/stack.effect.json @@ -0,0 +1,9 @@ +{ + "name": "proj_e_stack", + "runtime": { "_tag": "bun" }, + "lint": "biome", + "format": "biome", + "test": "vitest", + "monorepo": "turbo", + "git": false +}