@remix-run/cli 0.1.0 → 0.3.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 (110) hide show
  1. package/README.md +0 -3
  2. package/dist/lib/bootstrap-project.d.ts.map +1 -1
  3. package/dist/lib/bootstrap-project.js +32 -9
  4. package/dist/lib/cli.d.ts +29 -0
  5. package/dist/lib/cli.d.ts.map +1 -1
  6. package/dist/lib/cli.js +33 -14
  7. package/dist/lib/commands/completion.d.ts.map +1 -1
  8. package/dist/lib/commands/completion.js +5 -1
  9. package/dist/lib/commands/doctor.js +18 -18
  10. package/dist/lib/commands/help.d.ts.map +1 -1
  11. package/dist/lib/commands/help.js +9 -33
  12. package/dist/lib/commands/routes.js +3 -3
  13. package/dist/lib/commands/test.d.ts +1 -1
  14. package/dist/lib/commands/test.d.ts.map +1 -1
  15. package/dist/lib/commands/test.js +8 -4
  16. package/dist/lib/completion.d.ts.map +1 -1
  17. package/dist/lib/completion.js +4 -106
  18. package/dist/lib/controller-files.d.ts +0 -1
  19. package/dist/lib/controller-files.d.ts.map +1 -1
  20. package/dist/lib/controller-files.js +3 -5
  21. package/dist/lib/controller-ownership.d.ts +9 -9
  22. package/dist/lib/controller-ownership.d.ts.map +1 -1
  23. package/dist/lib/controller-ownership.js +56 -91
  24. package/dist/lib/doctor/controller-findings.d.ts +1 -1
  25. package/dist/lib/doctor/controller-findings.d.ts.map +1 -1
  26. package/dist/lib/doctor/controller-findings.js +15 -87
  27. package/dist/lib/doctor/controller-fix-plans.d.ts.map +1 -1
  28. package/dist/lib/doctor/controller-fix-plans.js +13 -24
  29. package/dist/lib/doctor/controller-placeholders.d.ts +2 -3
  30. package/dist/lib/doctor/controller-placeholders.d.ts.map +1 -1
  31. package/dist/lib/doctor/controller-placeholders.js +18 -149
  32. package/dist/lib/doctor/controllers.js +1 -1
  33. package/dist/lib/doctor/project.js +60 -52
  34. package/dist/lib/doctor/types.d.ts +2 -2
  35. package/dist/lib/doctor/types.d.ts.map +1 -1
  36. package/dist/lib/errors.d.ts +0 -6
  37. package/dist/lib/errors.d.ts.map +1 -1
  38. package/dist/lib/errors.js +0 -11
  39. package/dist/lib/load-route-map-worker.js +17 -9
  40. package/dist/lib/route-map.d.ts +1 -1
  41. package/dist/lib/route-map.d.ts.map +1 -1
  42. package/dist/lib/route-map.js +29 -17
  43. package/package.json +4 -5
  44. package/src/lib/bootstrap-project.ts +39 -13
  45. package/src/lib/cli.ts +46 -15
  46. package/src/lib/commands/completion.ts +6 -1
  47. package/src/lib/commands/doctor.ts +18 -21
  48. package/src/lib/commands/help.ts +9 -43
  49. package/src/lib/commands/routes.ts +3 -3
  50. package/src/lib/commands/test.ts +10 -4
  51. package/src/lib/completion.ts +4 -151
  52. package/src/lib/controller-files.ts +4 -8
  53. package/src/lib/controller-ownership.ts +78 -141
  54. package/src/lib/doctor/controller-findings.ts +20 -97
  55. package/src/lib/doctor/controller-fix-plans.ts +13 -29
  56. package/src/lib/doctor/controller-placeholders.ts +17 -189
  57. package/src/lib/doctor/controllers.ts +1 -1
  58. package/src/lib/doctor/project.ts +60 -52
  59. package/src/lib/doctor/types.ts +1 -5
  60. package/src/lib/errors.ts +0 -12
  61. package/src/lib/load-route-map-worker.ts +19 -10
  62. package/src/lib/route-map.ts +61 -16
  63. package/template/.agents/skills/remix/SKILL.md +588 -0
  64. package/template/.agents/skills/remix/references/animate-elements.md +195 -0
  65. package/template/.agents/skills/remix/references/assets-and-browser-modules.md +130 -0
  66. package/template/.agents/skills/remix/references/auth-and-sessions.md +443 -0
  67. package/template/.agents/skills/remix/references/component-model.md +282 -0
  68. package/template/.agents/skills/remix/references/create-mixins.md +158 -0
  69. package/template/.agents/skills/remix/references/data-and-validation.md +379 -0
  70. package/template/.agents/skills/remix/references/hydration-frames-navigation.md +297 -0
  71. package/template/.agents/skills/remix/references/middleware-and-server.md +233 -0
  72. package/template/.agents/skills/remix/references/mixins-styling-events.md +213 -0
  73. package/template/.agents/skills/remix/references/routing-and-controllers.md +391 -0
  74. package/template/.agents/skills/remix/references/testing-patterns.md +172 -0
  75. package/{bootstrap → template}/AGENTS.md +13 -8
  76. package/template/README.md +29 -0
  77. package/template/app/actions/controller.tsx +18 -0
  78. package/template/app/assets/entry.ts +8 -0
  79. package/template/app/assets/prompt-button.tsx +163 -0
  80. package/template/app/assets.ts +20 -0
  81. package/template/app/middleware/render.tsx +43 -0
  82. package/template/app/router.ts +20 -0
  83. package/template/app/routes.ts +6 -0
  84. package/template/app/ui/document.tsx +33 -0
  85. package/template/app/ui/scaffold-home-page.tsx +527 -0
  86. package/template/gitignore +4 -0
  87. package/{bootstrap → template}/package.json +5 -6
  88. package/template/public/favicon.svg +11 -0
  89. package/{bootstrap → template}/server.ts +4 -5
  90. package/{bootstrap → template}/tsconfig.json +3 -3
  91. package/bootstrap/README.md +0 -27
  92. package/bootstrap/app/controllers/auth.tsx +0 -21
  93. package/bootstrap/app/controllers/home.tsx +0 -26
  94. package/bootstrap/app/router.ts +0 -10
  95. package/bootstrap/app/routes.ts +0 -6
  96. package/bootstrap/app/ui/document.tsx +0 -21
  97. package/bootstrap/app/ui/layout.tsx +0 -22
  98. package/bootstrap/app/utils/render.tsx +0 -7
  99. package/dist/lib/commands/skills.d.ts +0 -6
  100. package/dist/lib/commands/skills.d.ts.map +0 -1
  101. package/dist/lib/commands/skills.js +0 -222
  102. package/dist/lib/skills-cache.d.ts +0 -19
  103. package/dist/lib/skills-cache.d.ts.map +0 -1
  104. package/dist/lib/skills-cache.js +0 -89
  105. package/dist/lib/skills.d.ts +0 -30
  106. package/dist/lib/skills.d.ts.map +0 -1
  107. package/dist/lib/skills.js +0 -441
  108. package/src/lib/commands/skills.ts +0 -306
  109. package/src/lib/skills-cache.ts +0 -140
  110. package/src/lib/skills.ts +0 -706
@@ -0,0 +1,195 @@
1
+ # Animating Elements
2
+
3
+ ## What This Covers
4
+
5
+ How to animate insertion, removal, and layout changes of elements. Read this when the task
6
+ involves:
7
+
8
+ - Adding entrance, exit, or shared-layout transitions to UI
9
+ - Choosing between spring physics (`spring(...)`) and time-based easing (`tween`)
10
+ - Coordinating CSS transitions with the same easing as JS animations
11
+ - Imperative animation loops via `requestAnimationFrame`
12
+
13
+ Import animation APIs from `remix/ui/animation`. For the smaller set of animation helpers that
14
+ show up alongside other mixins, see `mixins-styling-events.md`.
15
+
16
+ ## Animation Mixins
17
+
18
+ ### `animateEntrance(config)`
19
+
20
+ Animates an element when inserted. Config specifies the **starting** style the element animates
21
+ **from**:
22
+
23
+ ```tsx
24
+ <div
25
+ mix={animateEntrance({
26
+ opacity: 0,
27
+ transform: 'translateY(8px)',
28
+ ...spring('smooth'),
29
+ })}
30
+ />
31
+ ```
32
+
33
+ ### `animateExit(config)`
34
+
35
+ Animates an element when removed. Config specifies the **ending** style the element animates
36
+ **to**. The element stays in the DOM until the animation completes:
37
+
38
+ ```tsx
39
+ {
40
+ isVisible && (
41
+ <div
42
+ key="panel"
43
+ mix={[
44
+ animateEntrance({ opacity: 0, transform: 'scale(0.98)', ...spring('smooth') }),
45
+ animateExit({ opacity: 0, duration: 120, easing: 'ease-in' }),
46
+ ]}
47
+ />
48
+ )
49
+ }
50
+ ```
51
+
52
+ ### `animateLayout(config?)`
53
+
54
+ Animates layout changes (position/size) using FLIP-style transforms:
55
+
56
+ ```tsx
57
+ {
58
+ items.map((item) => (
59
+ <li key={item.id} mix={animateLayout({ ...spring({ duration: 500, bounce: 0.2 }) })} />
60
+ ))
61
+ }
62
+ ```
63
+
64
+ Options: `duration` (default 200ms), `easing` (default spring snappy), `size` (default true —
65
+ include scale projection for size changes).
66
+
67
+ ### Combining mixins
68
+
69
+ ```tsx
70
+ <div
71
+ key="card"
72
+ mix={[
73
+ animateEntrance({ opacity: 0, transform: 'scale(0.95)', ...spring('snappy') }),
74
+ animateExit({ opacity: 0, transform: 'scale(0.98)', duration: 120, easing: 'ease-in' }),
75
+ animateLayout({ duration: 220, easing: 'ease-out' }),
76
+ ]}
77
+ />
78
+ ```
79
+
80
+ ### Shared-layout swap
81
+
82
+ ```tsx
83
+ <div mix={css({ display: 'grid', '& > *': { gridArea: '1 / 1' } })}>
84
+ {stateA ? (
85
+ <div key="a" mix={[animateEntrance({ opacity: 0 }), animateExit({ opacity: 0 })]} />
86
+ ) : (
87
+ <div key="b" mix={[animateEntrance({ opacity: 0 }), animateExit({ opacity: 0 })]} />
88
+ )}
89
+ </div>
90
+ ```
91
+
92
+ ## Spring API
93
+
94
+ Physics-based spring animation. Returns a `SpringIterator` with `duration`, `easing`, and
95
+ `toString()` for CSS.
96
+
97
+ ### Presets
98
+
99
+ | Preset | Bounce | Duration | Character |
100
+ | -------- | ------ | -------- | --------------------------- |
101
+ | `smooth` | -0.3 | 400ms | Overdamped, no overshoot |
102
+ | `snappy` | 0 | 200ms | Critically damped, quick |
103
+ | `bouncy` | 0.3 | 400ms | Underdamped, visible bounce |
104
+
105
+ ```tsx
106
+ spring('bouncy')
107
+ spring('snappy')
108
+ spring('smooth')
109
+ spring('bouncy', { duration: 300 }) // override duration
110
+ ```
111
+
112
+ ### Custom spring
113
+
114
+ ```tsx
115
+ spring({ duration: 500, bounce: 0.3 })
116
+ spring({ duration: 500, bounce: 0.3, velocity: 2 }) // continue momentum from gesture
117
+ ```
118
+
119
+ ### Spread into animation mixins
120
+
121
+ Spreading a spring gives both `duration` and `easing`:
122
+
123
+ ```tsx
124
+ animateEntrance({ opacity: 0, ...spring('bouncy') })
125
+ ```
126
+
127
+ ### CSS transitions
128
+
129
+ The iterator stringifies to `"550ms linear(...)"`:
130
+
131
+ ```tsx
132
+ css({ transition: `width ${spring('bouncy')}` })
133
+ ```
134
+
135
+ Or use the `spring.transition()` helper for multiple properties:
136
+
137
+ ```tsx
138
+ css({ transition: spring.transition('width', 'bouncy') })
139
+ css({ transition: spring.transition(['left', 'top'], 'snappy') })
140
+ ```
141
+
142
+ ### Web Animations API
143
+
144
+ ```tsx
145
+ element.animate(keyframes, { ...spring('bouncy') })
146
+ ```
147
+
148
+ ### JS iteration
149
+
150
+ The iterator yields position values from 0 to 1, one per frame:
151
+
152
+ ```tsx
153
+ for (let t of spring('bouncy')) {
154
+ let x = from + (to - from) * t
155
+ updateSomething(x)
156
+ await nextFrame()
157
+ }
158
+ ```
159
+
160
+ ## Tween API
161
+
162
+ Generator-based tween for animating values over time with cubic bezier easing. Prefer animation
163
+ mixins or CSS transitions with `spring` for most UI work. Use `tween` for imperative
164
+ `requestAnimationFrame` loops, canvas/WebGL, or non-CSS properties.
165
+
166
+ ```tsx
167
+ import { tween, easings } from 'remix/ui/animation'
168
+
169
+ let animation = tween({
170
+ from: 0,
171
+ to: 100,
172
+ duration: 300,
173
+ curve: easings.easeOut,
174
+ })
175
+
176
+ animation.next() // initialize
177
+ function tick(timestamp: number) {
178
+ if (handle.signal.aborted) return
179
+ let { value, done } = animation.next(timestamp)
180
+ element.style.transform = `translateX(${value}px)`
181
+ if (!done) requestAnimationFrame(tick)
182
+ }
183
+ requestAnimationFrame(tick)
184
+ ```
185
+
186
+ Built-in easings: `easings.linear`, `easings.ease`, `easings.easeIn`, `easings.easeOut`,
187
+ `easings.easeInOut`.
188
+
189
+ ## Practical Guidance
190
+
191
+ - Always key conditional or switching elements you expect to animate.
192
+ - Use `animateLayout` only on the element whose position or size changes.
193
+ - Prefer one clear transition intent per mixin: entrance starts from a style, exit ends at a style.
194
+ - Default to `...spring()` for duration and easing in most cases.
195
+ - Keep DOM work in `handle.queueTask(...)` or `ref(...)`, not in render.
@@ -0,0 +1,130 @@
1
+ # Assets and Browser Modules
2
+
3
+ ## What This Covers
4
+
5
+ How to serve browser scripts and styles from source. Read this when the task involves:
6
+
7
+ - Configuring `createAssetServer` (`basePath`, `fileMap`, `allow`, `deny`, fingerprinting,
8
+ compiler options)
9
+ - Choosing between `staticFiles()` for already-built files and `createAssetServer()` for source
10
+ assets that need import rewriting, preloads, or fingerprinted URLs
11
+ - Generating script URLs or `<link rel="modulepreload">` tags for a client entry
12
+ - Keeping server-only files out of the browser via `deny` rules
13
+
14
+ For routing the URL namespace itself, see `routing-and-controllers.md`. For client entry
15
+ hydration, see `hydration-frames-navigation.md`.
16
+
17
+ ## When To Reach For It
18
+
19
+ Use `remix/assets` when the app serves browser JavaScript, TypeScript, or CSS from source files.
20
+ This is the right tool for client entrypoints, browser-only helpers, styles under `app/assets/`,
21
+ and monorepo code that should be compiled and served under a public URL namespace.
22
+
23
+ Use `staticFiles()` for files that already exist on disk exactly as they should be served. Use
24
+ `createAssetServer()` for source scripts or styles that need rewriting, dependency scanning,
25
+ preloads, sourcemaps, or fingerprinted URLs.
26
+
27
+ ## Default Pattern
28
+
29
+ ```typescript
30
+ import { createAssetServer } from 'remix/assets'
31
+ import { createController } from 'remix/router'
32
+ import { get, route } from 'remix/routes'
33
+
34
+ export const routes = route({
35
+ assets: get('/assets/*path'),
36
+ })
37
+
38
+ let assetServer = createAssetServer({
39
+ basePath: '/assets',
40
+ rootDir: process.cwd(),
41
+ fileMap: {
42
+ 'app/*path': 'app/*path',
43
+ 'node_modules/*path': 'node_modules/*path',
44
+ },
45
+ allow: ['app/assets/**', 'node_modules/**'],
46
+ deny: ['app/**/*.server.*'],
47
+ target: { es: '2020', chrome: '109', safari: '16.4' },
48
+ sourceMaps: process.env.NODE_ENV === 'development' ? 'external' : undefined,
49
+ minify: process.env.NODE_ENV === 'production',
50
+ scripts: {
51
+ define: {
52
+ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV ?? 'development'),
53
+ },
54
+ },
55
+ })
56
+
57
+ export default createController(routes, {
58
+ actions: {
59
+ async assets({ request }) {
60
+ return (await assetServer.fetch(request)) ?? new Response('Not Found', { status: 404 })
61
+ },
62
+ },
63
+ })
64
+ ```
65
+
66
+ ## Rules
67
+
68
+ - Treat `allow` and `deny` as the security boundary for browser-reachable source files.
69
+ - Add a `deny` list for server-only modules such as `*.server.*`, private config, or other files
70
+ that should never be exposed.
71
+ - Set `rootDir` explicitly in monorepos so relative paths resolve from the intended project root.
72
+ - `basePath` is the public URL namespace handled by the asset server.
73
+ - `fileMap` keys are URL patterns relative to `basePath`, and values are root-relative file path
74
+ patterns. They use `route-pattern` syntax on both sides.
75
+ - Keep the same wildcard params on both sides of a `fileMap` entry so import rewriting can map
76
+ source files back to public URLs.
77
+ - CSS files are compiled and served alongside scripts. Local CSS `@import` rules are rewritten and
78
+ fingerprinted with the same asset server routing rules.
79
+
80
+ ## Rendering HTML
81
+
82
+ Use `getHref()` when you need the public URL for one module, and `getPreloads()` when you want
83
+ `<link rel="modulepreload">` tags or `Link` headers for one or more entrypoints and their
84
+ dependencies.
85
+
86
+ ```typescript
87
+ let entryHref = await assetServer.getHref('app/assets/entry.ts')
88
+ let preloads = await assetServer.getPreloads(['app/assets/entry.ts'])
89
+ ```
90
+
91
+ Use this when rendering documents or layouts that boot browser behavior with a known client entry.
92
+
93
+ When resolving hydrated client entries during server rendering, pass the source entry ID from
94
+ `clientEntry(import.meta.url, ...)` to `getHref()` inside `resolveClientEntry`. Keep export-name
95
+ resolution in that render helper, and avoid hard-coding public asset URLs in source-owned component
96
+ modules.
97
+
98
+ ## Development vs Deployment
99
+
100
+ In development:
101
+
102
+ - Keep `watch` enabled so source changes are picked up without restarting the server
103
+ - Prefer stable URLs with normal revalidation
104
+ - Enable source maps when debugging browser code
105
+
106
+ In deployment:
107
+
108
+ - Set `watch: false`
109
+ - Use `fingerprint: { buildId }` for long-lived immutable caching
110
+ - Make sure `buildId` changes for each deploy
111
+
112
+ Fingerprinting assumes files on disk are stable and requires `watch: false`.
113
+
114
+ ## Useful Compiler Options
115
+
116
+ - `minify` for production minification of scripts and styles
117
+ - `sourceMaps` for `'external'` or `'inline'` source maps for scripts and styles
118
+ - `sourceMapSourcePaths` for `'url'` or `'absolute'` source map paths
119
+ - `target` as an object for shared browser targets and script-only ECMAScript output, such as
120
+ `{ es: '2020', chrome: '109', safari: '16.4' }`
121
+ - `scripts.define` to replace globals such as `process.env.NODE_ENV`
122
+ - `scripts.external` to leave specific script imports untouched
123
+
124
+ Do not nest shared compiler options under `scripts`. Use top-level `minify`, `sourceMaps`,
125
+ `sourceMapSourcePaths`, and `target` so they apply to styles as well as scripts.
126
+
127
+ ## Lifecycle
128
+
129
+ If the asset server is long-lived and watching the file system, call `await assetServer.close()`
130
+ when shutting down dev servers or disposing tests.