create-raredays-app 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/README.md +89 -0
  2. package/bin/index.js +1024 -0
  3. package/package.json +43 -0
  4. package/scaffold-fragments/billing/files/app/api/billing/webhook/route.ts +5 -0
  5. package/scaffold-fragments/billing/module.json +31 -0
  6. package/scaffold-fragments/billing/runtime/config.ts +8 -0
  7. package/scaffold-fragments/billing/runtime/exports.ts +6 -0
  8. package/scaffold-fragments/billing/runtime/imports.ts +6 -0
  9. package/scaffold-fragments/billing/runtime/ports.ts +3 -0
  10. package/scaffold-fragments/cms/module.json +29 -0
  11. package/scaffold-fragments/cms/runtime/config.ts +4 -0
  12. package/scaffold-fragments/cms/runtime/exports.ts +1 -0
  13. package/scaffold-fragments/cms/runtime/imports.ts +1 -0
  14. package/scaffold-fragments/email/module.json +30 -0
  15. package/scaffold-fragments/email/runtime/config.ts +1 -0
  16. package/scaffold-fragments/email/runtime/imports.ts +1 -0
  17. package/scaffold-fragments/email/runtime/ports.ts +1 -0
  18. package/scaffold-fragments/feature-flags/files/app/lib/flags.ts +48 -0
  19. package/scaffold-fragments/feature-flags/module.json +66 -0
  20. package/scaffold-fragments/i18n/files/messages/en-US.json +15 -0
  21. package/scaffold-fragments/i18n/module.json +9 -0
  22. package/scaffold-fragments/i18n/runtime/config.ts +7 -0
  23. package/scaffold-fragments/i18n/runtime/exports.ts +1 -0
  24. package/scaffold-fragments/i18n/runtime/imports.ts +2 -0
  25. package/scaffold-fragments/i18n/runtime/ports.ts +1 -0
  26. package/scaffold-fragments/identity/module.json +30 -0
  27. package/scaffold-fragments/identity/vendors/better-auth/files/app/api/auth/[...all]/route.ts +15 -0
  28. package/scaffold-fragments/identity/vendors/better-auth/files/app/lib/auth.ts +20 -0
  29. package/scaffold-fragments/jobs/module.json +12 -0
  30. package/scaffold-fragments/jobs/runtime/config.ts +4 -0
  31. package/scaffold-fragments/jobs/runtime/imports.ts +1 -0
  32. package/scaffold-fragments/jobs/runtime/ports.ts +1 -0
  33. package/scaffold-fragments/notifications/module.json +12 -0
  34. package/scaffold-fragments/notifications/runtime/config.ts +8 -0
  35. package/scaffold-fragments/notifications/runtime/imports.ts +5 -0
  36. package/scaffold-fragments/notifications/runtime/ports.ts +1 -0
  37. package/scaffold-fragments/organizations/module.json +12 -0
  38. package/scaffold-fragments/telemetry/module.json +43 -0
  39. package/scaffold-fragments/telemetry/runtime/config.ts +7 -0
  40. package/scaffold-fragments/telemetry/runtime/imports.ts +7 -0
  41. package/scaffold-fragments/telemetry/runtime/ports.ts +1 -0
  42. package/skillex/private/contribute.md +193 -0
  43. package/skillex/public/consumer.md +157 -0
  44. package/templates/client/.storybook/main.ts +77 -0
  45. package/templates/client/.storybook/preview.ts +12 -0
  46. package/templates/client/CLAUDE.md +50 -0
  47. package/templates/client/_claude/settings.json +107 -0
  48. package/templates/client/_github/PULL_REQUEST_TEMPLATE.md +19 -0
  49. package/templates/client/_github/dependabot.yml +48 -0
  50. package/templates/client/_github/workflows/ci.yml +104 -0
  51. package/templates/client/_gitignore +15 -0
  52. package/templates/client/_npmrc +1 -0
  53. package/templates/client/app/(app)/layout.tsx +49 -0
  54. package/templates/client/app/(marketing)/layout.tsx +21 -0
  55. package/templates/client/app/(marketing)/page.tsx +34 -0
  56. package/templates/client/app/api/backend/[...path]/route.ts +37 -0
  57. package/templates/client/app/api/dev/login/route.ts +14 -0
  58. package/templates/client/app/api/dev/logout/route.ts +18 -0
  59. package/templates/client/app/globals.css +22 -0
  60. package/templates/client/app/home-auth-controls.tsx +28 -0
  61. package/templates/client/app/layout.tsx +38 -0
  62. package/templates/client/app/lib/backend-client.ts +55 -0
  63. package/templates/client/app/lib/runtime.test.ts +38 -0
  64. package/templates/client/app/lib/runtime.ts +54 -0
  65. package/templates/client/app/protected/page.tsx +31 -0
  66. package/templates/client/app/theme.override.css +9 -0
  67. package/templates/client/instrumentation.ts +10 -0
  68. package/templates/client/mocks/browser.tsx +28 -0
  69. package/templates/client/mocks/handlers.ts +20 -0
  70. package/templates/client/mocks/node.ts +7 -0
  71. package/templates/client/next.config.ts +8 -0
  72. package/templates/client/oxfmt.config.ts +8 -0
  73. package/templates/client/oxlint.config.ts +8 -0
  74. package/templates/client/package.json +61 -0
  75. package/templates/client/postcss.config.mjs +1 -0
  76. package/templates/client/public/mockServiceWorker.js +349 -0
  77. package/templates/client/scripts/build-theme.mjs +18 -0
  78. package/templates/client/site.spec.ts +58 -0
  79. package/templates/client/skillex.json +12 -0
  80. package/templates/client/skills/repo.md +56 -0
  81. package/templates/client/stylelint.config.mjs +4 -0
  82. package/templates/client/tsconfig.json +11 -0
  83. package/templates/client/vitest.config.ts +27 -0
  84. package/templates/client/vitest.setup.ts +18 -0
  85. package/templates/full-stack/.storybook/main.ts +77 -0
  86. package/templates/full-stack/.storybook/preview.ts +12 -0
  87. package/templates/full-stack/CLAUDE.md +50 -0
  88. package/templates/full-stack/_claude/settings.json +107 -0
  89. package/templates/full-stack/_github/PULL_REQUEST_TEMPLATE.md +19 -0
  90. package/templates/full-stack/_github/dependabot.yml +57 -0
  91. package/templates/full-stack/_github/workflows/ci.yml +109 -0
  92. package/templates/full-stack/_github/workflows/db-check.yml +36 -0
  93. package/templates/full-stack/_github/workflows/db-migrate.yml +39 -0
  94. package/templates/full-stack/_gitignore +15 -0
  95. package/templates/full-stack/_npmrc +1 -0
  96. package/templates/full-stack/app/(app)/layout.tsx +53 -0
  97. package/templates/full-stack/app/(marketing)/layout.tsx +21 -0
  98. package/templates/full-stack/app/(marketing)/page.tsx +38 -0
  99. package/templates/full-stack/app/api/dev/login/route.ts +14 -0
  100. package/templates/full-stack/app/api/dev/logout/route.ts +18 -0
  101. package/templates/full-stack/app/api/widgets/route.ts +10 -0
  102. package/templates/full-stack/app/demo/widgets/page.tsx +86 -0
  103. package/templates/full-stack/app/globals.css +22 -0
  104. package/templates/full-stack/app/home-auth-controls.tsx +28 -0
  105. package/templates/full-stack/app/layout.tsx +38 -0
  106. package/templates/full-stack/app/lib/runtime.test.ts +38 -0
  107. package/templates/full-stack/app/lib/runtime.ts +54 -0
  108. package/templates/full-stack/app/protected/page.tsx +31 -0
  109. package/templates/full-stack/app/theme.override.css +9 -0
  110. package/templates/full-stack/db/check.ts +46 -0
  111. package/templates/full-stack/db/index.ts +109 -0
  112. package/templates/full-stack/db/migrate.ts +66 -0
  113. package/templates/full-stack/db/migrations/.gitkeep +0 -0
  114. package/templates/full-stack/db/schema.ts +20 -0
  115. package/templates/full-stack/drizzle.config.ts +16 -0
  116. package/templates/full-stack/instrumentation.ts +10 -0
  117. package/templates/full-stack/mocks/browser.tsx +28 -0
  118. package/templates/full-stack/mocks/handlers.ts +34 -0
  119. package/templates/full-stack/mocks/node.ts +7 -0
  120. package/templates/full-stack/next.config.ts +8 -0
  121. package/templates/full-stack/oxfmt.config.ts +8 -0
  122. package/templates/full-stack/oxlint.config.ts +8 -0
  123. package/templates/full-stack/package.json +72 -0
  124. package/templates/full-stack/postcss.config.mjs +1 -0
  125. package/templates/full-stack/public/mockServiceWorker.js +349 -0
  126. package/templates/full-stack/scripts/build-theme.mjs +18 -0
  127. package/templates/full-stack/site.spec.ts +58 -0
  128. package/templates/full-stack/skillex.json +12 -0
  129. package/templates/full-stack/skills/repo.md +56 -0
  130. package/templates/full-stack/stylelint.config.mjs +4 -0
  131. package/templates/full-stack/tsconfig.json +11 -0
  132. package/templates/full-stack/vitest.config.ts +42 -0
  133. package/templates/full-stack/vitest.setup.ts +18 -0
  134. package/templates/static/.storybook/main.ts +77 -0
  135. package/templates/static/.storybook/preview.ts +12 -0
  136. package/templates/static/CLAUDE.md +50 -0
  137. package/templates/static/_claude/settings.json +107 -0
  138. package/templates/static/_github/PULL_REQUEST_TEMPLATE.md +18 -0
  139. package/templates/static/_github/dependabot.yml +43 -0
  140. package/templates/static/_github/workflows/ci.yml +91 -0
  141. package/templates/static/_gitignore +15 -0
  142. package/templates/static/_npmrc +1 -0
  143. package/templates/static/app/(marketing)/layout.tsx +21 -0
  144. package/templates/static/app/(marketing)/page.tsx +17 -0
  145. package/templates/static/app/globals.css +22 -0
  146. package/templates/static/app/layout.tsx +24 -0
  147. package/templates/static/app/theme.override.css +9 -0
  148. package/templates/static/next.config.ts +19 -0
  149. package/templates/static/oxfmt.config.ts +8 -0
  150. package/templates/static/oxlint.config.ts +8 -0
  151. package/templates/static/package.json +53 -0
  152. package/templates/static/postcss.config.mjs +1 -0
  153. package/templates/static/scripts/build-theme.mjs +18 -0
  154. package/templates/static/site.spec.ts +58 -0
  155. package/templates/static/skillex.json +12 -0
  156. package/templates/static/skills/repo.md +56 -0
  157. package/templates/static/stylelint.config.mjs +4 -0
  158. package/templates/static/tsconfig.json +11 -0
@@ -0,0 +1,77 @@
1
+ import { dirname, resolve } from "node:path";
2
+ import { createRequire } from "node:module";
3
+ import type { StorybookConfig } from "@storybook/react-vite";
4
+ import react from "@vitejs/plugin-react";
5
+ import tailwindcss from "@tailwindcss/vite";
6
+
7
+ // Storybook config for the scaffolded app.
8
+ //
9
+ // Loads stories from two sources, namespaced separately:
10
+ //
11
+ // App/<...> → ../app/**/*.stories.@(ts|tsx)
12
+ // ../src/**/*.stories.@(ts|tsx)
13
+ //
14
+ // @raredays/components/<...> → resolved-package-root/dist/**/*.stories.js
15
+ //
16
+ // Framework stories are pre-compiled by the framework's build (vite
17
+ // `preserveModules: true`) — `@/` aliases are already resolved, so
18
+ // the consumer's Vite doesn't need any path-alias config to load
19
+ // them. To add more framework packages with stories, add a matching
20
+ // stories[] entry pointing at their dist/.
21
+ //
22
+ // We resolve `@raredays/components` via Node's module resolver rather
23
+ // than a literal `../node_modules/...` path because pnpm hoists
24
+ // workspace dependencies to the workspace root — under a workspace
25
+ // install the package may not exist in the app's own node_modules at
26
+ // all, and the literal path silently matches zero stories.
27
+ //
28
+ // `require.resolve("@raredays/components")` returns the package's
29
+ // main entry (`dist/index.js`); we walk up to the package root so the
30
+ // glob can target `dist/**/*.stories.js`. We avoid resolving
31
+ // `@raredays/components/package.json` directly because the package's
32
+ // `exports` map does not expose `./package.json`.
33
+ //
34
+ // Stories render in THIS Storybook's iframe — they inherit the
35
+ // consumer's theme.override.css, RaredaysProvider, fonts, and any
36
+ // other context loaded in .storybook/preview.ts. That's the whole
37
+ // point: see how framework components look with YOUR theme applied,
38
+ // not a generic one.
39
+ const require = createRequire(import.meta.url);
40
+ const componentsRoot = dirname(dirname(require.resolve("@raredays/components")));
41
+
42
+ const config: StorybookConfig = {
43
+ framework: "@storybook/react-vite",
44
+ stories: [
45
+ {
46
+ directory: "../app",
47
+ files: "**/*.stories.@(ts|tsx)",
48
+ titlePrefix: "App",
49
+ },
50
+ {
51
+ directory: "../src",
52
+ files: "**/*.stories.@(ts|tsx)",
53
+ titlePrefix: "App",
54
+ },
55
+ {
56
+ directory: `${componentsRoot}/dist`,
57
+ files: "**/*.stories.js",
58
+ titlePrefix: "@raredays/components",
59
+ },
60
+ ],
61
+ addons: [],
62
+ typescript: {
63
+ check: false,
64
+ reactDocgen: "react-docgen-typescript",
65
+ },
66
+ viteFinal: async (viteConfig) => {
67
+ viteConfig.plugins = [...(viteConfig.plugins ?? []), react(), tailwindcss()];
68
+ viteConfig.resolve ??= {};
69
+ viteConfig.resolve.alias = {
70
+ ...(viteConfig.resolve.alias as Record<string, string>),
71
+ "@": resolve(import.meta.dirname, "../app"),
72
+ };
73
+ return viteConfig;
74
+ },
75
+ };
76
+
77
+ export default config;
@@ -0,0 +1,12 @@
1
+ import type { Preview } from "@storybook/react-vite";
2
+ import "../app/globals.css";
3
+
4
+ const preview: Preview = {
5
+ parameters: {
6
+ controls: {
7
+ matchers: { color: /(background|color)$/i, date: /Date$/i },
8
+ },
9
+ },
10
+ };
11
+
12
+ export default preview;
@@ -0,0 +1,50 @@
1
+ # Project conventions
2
+
3
+ Always read `AGENTS.md` first — it lists every skill available via `@raredays/*`
4
+ packages. Use them before authoring components, modules, or providers from
5
+ scratch.
6
+
7
+ ## Quick orientation
8
+
9
+ This app was scaffolded with `create-raredays-app` and consumes the RareDays
10
+ framework via `@raredays/*` workspace deps. Conventions:
11
+
12
+ - **Components**: prefer composing from `@raredays/components` (shadcn-flavored,
13
+ Tailwind v4, browser-tested with vitest+playwright). When you do author new
14
+ components, follow the patterns documented in
15
+ `pnpm exec skillex query --package @raredays/components`.
16
+ - **Server logic**: use `@raredays/core`'s provider/port pattern. Identity,
17
+ billing, notifications, CMS, etc. are wired in `app/lib/runtime.ts` —
18
+ edit there to swap providers, don't sprinkle SDK calls through the codebase.
19
+ - **Tests**: vitest. Browser-mode tests use the `.browser.test.tsx` suffix and
20
+ run separately from node-mode tests. Conformance harnesses live in each
21
+ module's `src/testing/` directory and exercise every provider against the
22
+ same invariants.
23
+ - **Lint/format**: `pnpm check` runs lint + format-check + style + typecheck.
24
+ Pre-commit hook (if you add one) should call this.
25
+
26
+ ## Don't
27
+
28
+ - Re-implement primitives that already exist in `@raredays/*`. Always query
29
+ skillex first.
30
+ - Edit code in `node_modules/@raredays/*` directly. If a provider needs
31
+ changing, file a framework issue or PR upstream.
32
+ - Commit code with failing lint/format/style/test. `pnpm check` should be
33
+ green before every commit.
34
+
35
+ ## Skillex
36
+
37
+ Skills from installed `@raredays/*` packages are auto-discovered. To refresh
38
+ the index after adding a new dependency:
39
+
40
+ ```sh
41
+ pnpm exec skillex refresh
42
+ ```
43
+
44
+ Query patterns:
45
+
46
+ ```sh
47
+ pnpm exec skillex query --search "<concepts>"
48
+ pnpm exec skillex query --package "@raredays/components"
49
+ pnpm exec skillex query --topic identity
50
+ ```
@@ -0,0 +1,107 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/claude-code-settings.json",
3
+ "_comment": "Permissive defaults — agents can iterate without prompting on routine dev actions. Anything that mutates shared/remote state still requires explicit approval.",
4
+ "permissions": {
5
+ "allow": [
6
+ "Bash(pnpm install*)",
7
+ "Bash(pnpm run *)",
8
+ "Bash(pnpm exec *)",
9
+ "Bash(pnpm dev*)",
10
+ "Bash(pnpm build*)",
11
+ "Bash(pnpm test*)",
12
+ "Bash(pnpm lint*)",
13
+ "Bash(pnpm format*)",
14
+ "Bash(pnpm style*)",
15
+ "Bash(pnpm check*)",
16
+ "Bash(pnpm typecheck*)",
17
+ "Bash(pnpm db:*)",
18
+ "Bash(pnpm theme:build*)",
19
+ "Bash(pnpm dlx *)",
20
+ "Bash(pnpm --filter *)",
21
+ "Bash(pnpm -w *)",
22
+ "Bash(node *)",
23
+ "Bash(npx *)",
24
+ "Bash(git status*)",
25
+ "Bash(git diff*)",
26
+ "Bash(git log*)",
27
+ "Bash(git show*)",
28
+ "Bash(git branch*)",
29
+ "Bash(git ls-files*)",
30
+ "Bash(git ls-tree*)",
31
+ "Bash(git stash*)",
32
+ "Bash(git add*)",
33
+ "Bash(git checkout *)",
34
+ "Bash(git switch *)",
35
+ "Bash(git restore *)",
36
+ "Bash(git rev-parse*)",
37
+ "Bash(git remote -v)",
38
+ "Bash(git fetch*)",
39
+ "Bash(git pull --ff-only*)",
40
+ "Bash(mkdir *)",
41
+ "Bash(touch *)",
42
+ "Bash(ls *)",
43
+ "Bash(find *)",
44
+ "Bash(grep *)",
45
+ "Bash(rg *)",
46
+ "Bash(cat *)",
47
+ "Bash(head *)",
48
+ "Bash(tail *)",
49
+ "Bash(wc *)",
50
+ "Bash(sort *)",
51
+ "Bash(uniq *)",
52
+ "Bash(jq *)",
53
+ "Bash(curl http://localhost*)",
54
+ "Bash(curl http://127.0.0.1*)",
55
+ "Bash(pnpm exec skillex*)",
56
+ "Bash(pnpm exec playwright *)",
57
+ "Bash(pnpm exec vitest*)",
58
+ "Bash(pnpm exec drizzle-kit*)",
59
+ "Bash(pnpm exec next *)",
60
+ "Bash(pnpm exec tsc*)",
61
+ "Bash(pnpm exec oxlint*)",
62
+ "Bash(pnpm exec oxfmt*)",
63
+ "Bash(pnpm exec stylelint*)",
64
+ "Read",
65
+ "Edit",
66
+ "Write",
67
+ "Glob",
68
+ "Grep",
69
+ "WebFetch"
70
+ ],
71
+ "ask": [
72
+ "Bash(git commit*)",
73
+ "Bash(git push*)",
74
+ "Bash(git merge*)",
75
+ "Bash(git rebase*)",
76
+ "Bash(git reset*)",
77
+ "Bash(gh issue*)",
78
+ "Bash(gh pr*)",
79
+ "Bash(gh release*)",
80
+ "Bash(gh workflow*)",
81
+ "Bash(pnpm publish*)",
82
+ "Bash(pnpm nx release*)",
83
+ "Bash(npm publish*)"
84
+ ],
85
+ "deny": [
86
+ "Bash(git push --force*)",
87
+ "Bash(git push -f *)",
88
+ "Bash(git push * --force*)",
89
+ "Bash(rm -rf /*)",
90
+ "Bash(rm -rf ~)",
91
+ "Bash(rm -rf $HOME*)",
92
+ "Bash(cat .env*)",
93
+ "Bash(cat *.env)",
94
+ "Bash(cat *.env.local)",
95
+ "Bash(cat *.env.production)",
96
+ "Bash(printenv)",
97
+ "Bash(env)",
98
+ "Read(./.env)",
99
+ "Read(./.env.local)",
100
+ "Read(./.env.production)",
101
+ "Read(./.env.*)",
102
+ "Read(./**/.env)",
103
+ "Read(./**/.env.local)",
104
+ "Read(./**/.env.production)"
105
+ ]
106
+ }
107
+ }
@@ -0,0 +1,18 @@
1
+ <!-- Brief description of what this PR does and why. -->
2
+
3
+ ## Summary
4
+
5
+ -
6
+ -
7
+
8
+ ## Verification
9
+
10
+ - [ ] `pnpm lint` passes
11
+ - [ ] `pnpm format:check` passes
12
+ - [ ] `pnpm style` passes
13
+ - [ ] `pnpm typecheck` passes
14
+ - [ ] `pnpm build` succeeds
15
+
16
+ ## Notes
17
+
18
+ <!-- Anything reviewers should know. -->
@@ -0,0 +1,43 @@
1
+ version: 2
2
+
3
+ updates:
4
+ - package-ecosystem: npm
5
+ directory: /
6
+ schedule:
7
+ interval: weekly
8
+ open-pull-requests-limit: 5
9
+ groups:
10
+ raredays:
11
+ patterns:
12
+ - "@raredays/*"
13
+ react:
14
+ patterns:
15
+ - react
16
+ - react-dom
17
+ - "@types/react"
18
+ - "@types/react-dom"
19
+ next:
20
+ patterns:
21
+ - next
22
+ tailwind:
23
+ patterns:
24
+ - tailwindcss
25
+ - "@tailwindcss/*"
26
+ storybook:
27
+ patterns:
28
+ - storybook
29
+ - "@storybook/*"
30
+ dev-tooling:
31
+ dependency-type: development
32
+ patterns:
33
+ - "*"
34
+
35
+ - package-ecosystem: github-actions
36
+ directory: /
37
+ schedule:
38
+ interval: weekly
39
+ open-pull-requests-limit: 3
40
+ groups:
41
+ gha:
42
+ patterns:
43
+ - "*"
@@ -0,0 +1,91 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ concurrency:
10
+ group: ci-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ # Mirrors the RareDays framework's CI discipline for consumer apps.
14
+ # Static template has no vitest test target — verification chain is
15
+ # lint / format / style / typecheck / build / storybook only.
16
+
17
+ jobs:
18
+ lint:
19
+ name: Lint
20
+ runs-on: ubuntu-latest
21
+ timeout-minutes: 10
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: pnpm/action-setup@v4
25
+ - uses: actions/setup-node@v4
26
+ with: { node-version: 24, cache: pnpm }
27
+ - run: pnpm install --frozen-lockfile
28
+ - run: pnpm lint
29
+
30
+ format-check:
31
+ name: Format check
32
+ runs-on: ubuntu-latest
33
+ timeout-minutes: 10
34
+ steps:
35
+ - uses: actions/checkout@v4
36
+ - uses: pnpm/action-setup@v4
37
+ - uses: actions/setup-node@v4
38
+ with: { node-version: 24, cache: pnpm }
39
+ - run: pnpm install --frozen-lockfile
40
+ - run: pnpm format:check
41
+
42
+ style:
43
+ name: Style
44
+ runs-on: ubuntu-latest
45
+ timeout-minutes: 10
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+ - uses: pnpm/action-setup@v4
49
+ - uses: actions/setup-node@v4
50
+ with: { node-version: 24, cache: pnpm }
51
+ - run: pnpm install --frozen-lockfile
52
+ - run: pnpm style
53
+
54
+ typecheck:
55
+ name: Typecheck
56
+ runs-on: ubuntu-latest
57
+ timeout-minutes: 10
58
+ steps:
59
+ - uses: actions/checkout@v4
60
+ - uses: pnpm/action-setup@v4
61
+ - uses: actions/setup-node@v4
62
+ with: { node-version: 24, cache: pnpm }
63
+ - run: pnpm install --frozen-lockfile
64
+ - run: pnpm theme:build
65
+ - run: pnpm typecheck
66
+
67
+ build:
68
+ name: Build
69
+ runs-on: ubuntu-latest
70
+ timeout-minutes: 15
71
+ steps:
72
+ - uses: actions/checkout@v4
73
+ - uses: pnpm/action-setup@v4
74
+ - uses: actions/setup-node@v4
75
+ with: { node-version: 24, cache: pnpm }
76
+ - run: pnpm install --frozen-lockfile
77
+ - run: pnpm build
78
+
79
+ storybook:
80
+ name: Storybook build
81
+ runs-on: ubuntu-latest
82
+ timeout-minutes: 15
83
+ if: hashFiles('.storybook/main.ts', '.storybook/main.js') != ''
84
+ steps:
85
+ - uses: actions/checkout@v4
86
+ - uses: pnpm/action-setup@v4
87
+ - uses: actions/setup-node@v4
88
+ with: { node-version: 24, cache: pnpm }
89
+ - run: pnpm install --frozen-lockfile
90
+ - run: pnpm theme:build
91
+ - run: pnpm storybook:build
@@ -0,0 +1,15 @@
1
+ node_modules/
2
+ .next/
3
+ out/
4
+ dist/
5
+ *.tsbuildinfo
6
+ next-env.d.ts
7
+
8
+ .env
9
+ .env.local
10
+ .env.*.local
11
+
12
+ .skillex/
13
+
14
+ .DS_Store
15
+ *.log
@@ -0,0 +1 @@
1
+ @raredays:registry=http://localhost:4873
@@ -0,0 +1,21 @@
1
+ import { MarketingLayout, MarketingHeader, MarketingFooter } from "@raredays/components";
2
+ import type { ReactNode } from "react";
3
+
4
+ export default function MarketingGroupLayout({ children }: { children: ReactNode }) {
5
+ return (
6
+ <MarketingLayout
7
+ header={
8
+ <MarketingHeader
9
+ logo={<span className="text-lg font-bold">RareDays</span>}
10
+ navigation={[
11
+ { label: "Features", href: "/#features" },
12
+ { label: "Pricing", href: "/#pricing" },
13
+ ]}
14
+ />
15
+ }
16
+ footer={<MarketingFooter copyright={`© ${new Date().getFullYear()} RareDays`} />}
17
+ >
18
+ {children}
19
+ </MarketingLayout>
20
+ );
21
+ }
@@ -0,0 +1,17 @@
1
+ export default function HomePage() {
2
+ return (
3
+ <main className="p-8 font-sans">
4
+ <h1 className="text-3xl font-bold">RareDays</h1>
5
+ <p className="mt-4 text-neutral-600">
6
+ Edit <code>app/page.tsx</code> to get started. Tailwind utilities are backed by tokens from{" "}
7
+ <code>@raredays/tokens</code>.
8
+ </p>
9
+ <button
10
+ type="button"
11
+ className="mt-6 rounded-md bg-brand-primary px-4 py-2 text-white hover:bg-brand-secondary"
12
+ >
13
+ Hello
14
+ </button>
15
+ </main>
16
+ );
17
+ }
@@ -0,0 +1,22 @@
1
+ /* CSS @import lines must precede all other rules. If you add a remote-font
2
+ * import (e.g. @import url("https://rsms.me/inter/inter.css")), it MUST go
3
+ * BEFORE the lines below — @raredays/style inlines ~6800 lines of CSS,
4
+ * after which any further @import is mid-document and rejected by Lightning
5
+ * CSS / PostCSS / browsers per the CSS spec. */
6
+ @import "@raredays/style";
7
+ @import "./theme.override.css";
8
+
9
+ /* Scan compiled output from @raredays/* packages so Tailwind emits
10
+ * the arbitrary utilities used inside their components (e.g. underline
11
+ * positions, data-attribute variants). The relative `@source` paths in
12
+ * @raredays/style/index.css don't resolve under pnpm's strict
13
+ * node_modules layout — each @raredays/* package gets its own
14
+ * .pnpm/<pkg>/node_modules/<pkg>/ directory, so style's
15
+ * `../components/dist` points nowhere. These directives are relative
16
+ * to THIS file (`app/globals.css`), which is the consumer's cwd —
17
+ * resolves correctly.
18
+ *
19
+ * Add `@source "../node_modules/@raredays/<pkg>/dist"` for any
20
+ * additional @raredays/* package whose component utilities you use. */
21
+ @source "../node_modules/@raredays/components/dist";
22
+ @source "../node_modules/@raredays/core/dist";
@@ -0,0 +1,24 @@
1
+ import { RaredaysProvider } from "@raredays/core";
2
+ import type { Metadata, Viewport } from "next";
3
+ import type { ReactNode } from "react";
4
+ import "./globals.css";
5
+
6
+ export const metadata: Metadata = {
7
+ title: "RareDays App",
8
+ description: "A RareDays Next.js application.",
9
+ };
10
+
11
+ export const viewport: Viewport = {
12
+ width: "device-width",
13
+ initialScale: 1,
14
+ };
15
+
16
+ export default function RootLayout({ children }: { children: ReactNode }) {
17
+ return (
18
+ <html lang="en">
19
+ <body>
20
+ <RaredaysProvider>{children}</RaredaysProvider>
21
+ </body>
22
+ </html>
23
+ );
24
+ }
@@ -0,0 +1,9 @@
1
+ /*
2
+ * Auto-generated by @raredays/theme-build. Do not edit by hand.
3
+ * Source: site.spec.ts
4
+ * To regenerate: pnpm theme:build
5
+ */
6
+
7
+ @theme {
8
+ /* No spec overrides — defaults from @raredays/tokens apply. */
9
+ }
@@ -0,0 +1,19 @@
1
+ import { withRaredays } from "@raredays/core";
2
+ import type { NextConfig } from "next";
3
+
4
+ // `output: "export"` produces a truly static build — plain HTML/CSS/JS in
5
+ // `out/`, deployable to any CDN (Cloudflare Pages, R2, S3+CloudFront,
6
+ // GitHub Pages, edge workers). No Node runtime, no `next start`.
7
+ //
8
+ // Trade-offs that come with this:
9
+ // - no SSR, no `cookies()`/`headers()`, no `revalidatePath`/`revalidateTag`
10
+ // - no `app/api/` route handlers
11
+ // - dynamic routes need `generateStaticParams`
12
+ //
13
+ // If you need any of the above, scaffold with `--template client` (BFF + SPA)
14
+ // or `--template full-stack` (Next.js + framework modules).
15
+ const config: NextConfig = withRaredays({
16
+ output: "export",
17
+ });
18
+
19
+ export default config;
@@ -0,0 +1,8 @@
1
+ import { defineConfig, mergeConfig, base } from "@raredays/lint/oxfmt";
2
+
3
+ // Explicit return-type annotation avoids TS2742 ("inferred type cannot be
4
+ // named without a reference to ..."). `defineConfig` is re-exported from the
5
+ // upstream `oxfmt` package, so the inferred default-export type would
6
+ // otherwise reference a non-portable path.
7
+ const config: ReturnType<typeof defineConfig> = defineConfig(mergeConfig(base));
8
+ export default config;
@@ -0,0 +1,8 @@
1
+ import { defineConfig, mergeConfig, base } from "@raredays/lint/oxlint";
2
+
3
+ // Explicit return-type annotation avoids TS2742 ("inferred type cannot be
4
+ // named without a reference to ..."). `defineConfig` is re-exported from the
5
+ // upstream `oxlint` package, so the inferred default-export type would
6
+ // otherwise reference a non-portable path.
7
+ const config: ReturnType<typeof defineConfig> = defineConfig(mergeConfig(base));
8
+ export default config;
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "raredays-app",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "postinstall": "skillex refresh -q || true",
8
+ "dev": "pnpm theme:build && next dev -p ${PORT:-3000}",
9
+ "build": "pnpm theme:build && next build",
10
+ "start": "serve out -l ${PORT:-3000}",
11
+ "theme:build": "node ./scripts/build-theme.mjs",
12
+ "storybook": "storybook dev -p 6006",
13
+ "storybook:build": "storybook build -o storybook-static",
14
+ "lint": "raredays lint",
15
+ "lint:fix": "raredays lint:fix",
16
+ "format": "raredays format",
17
+ "format:check": "raredays format:check",
18
+ "style": "raredays style",
19
+ "style:fix": "raredays style:fix",
20
+ "fix": "raredays fix",
21
+ "typecheck": "tsc --noEmit",
22
+ "check": "raredays check && tsc --noEmit"
23
+ },
24
+ "dependencies": {
25
+ "@raredays/components": "0.0.1",
26
+ "@raredays/core": "0.0.1",
27
+ "@raredays/style": "0.0.1",
28
+ "next": "16.2.4",
29
+ "react": "19.2.5",
30
+ "react-dom": "19.2.5"
31
+ },
32
+ "devDependencies": {
33
+ "@raredays/lint": "0.0.1",
34
+ "@raredays/site-config": "0.0.1",
35
+ "@raredays/theme-build": "0.0.1",
36
+ "@raredays/typescript": "0.0.1",
37
+ "@storybook/react-vite": "10.3.6",
38
+ "@tailwindcss/postcss": "4.2.4",
39
+ "@tailwindcss/vite": "4.2.4",
40
+ "@types/node": "22.19.17",
41
+ "@types/react": "19.2.14",
42
+ "@types/react-dom": "19.2.3",
43
+ "@vitejs/plugin-react": "6.0.1",
44
+ "serve": "14.2.5",
45
+ "storybook": "10.3.6",
46
+ "tailwindcss": "4.2.4",
47
+ "typescript": "5.9.3",
48
+ "vite": "8.0.10"
49
+ },
50
+ "engines": {
51
+ "node": ">=24"
52
+ }
53
+ }
@@ -0,0 +1 @@
1
+ export { default } from "@raredays/style/postcss";
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { dirname, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { loadSiteSpec } from "@raredays/site-config";
5
+ import { writeThemeOverride } from "@raredays/theme-build";
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const projectRoot = resolve(__dirname, "..");
9
+
10
+ const spec = await loadSiteSpec(resolve(projectRoot, "site.spec.ts"));
11
+ const outPath = resolve(projectRoot, "app/theme.override.css");
12
+
13
+ await writeThemeOverride(spec, outPath, {
14
+ regenCommand: "pnpm theme:build",
15
+ source: "site.spec.ts",
16
+ });
17
+
18
+ console.log(`✓ wrote ${outPath}`);