Conversation
📝 WalkthroughWalkthroughThis PR adds CSRF protection middleware to TanStack Start server functions (Sec-Fetch-Site → Origin → Referer validation), wires automatic injection and dev warning controls, re-exports middleware APIs, adds tests and docs, introduces AsyncLocalStorage plugin context for the start compiler, and implements a runtime callable fallback for isomorphic functions. ChangesCSRF Middleware Protection
Start Compiler Plugin Context
Isomorphic Function Runtime Fallback
Sequence Diagram(s)sequenceDiagram
participant Browser
participant StartHandler
participant RequestMiddleware
participant ServerFunction
Browser->>StartHandler: HTTP request (includes headers)
StartHandler->>RequestMiddleware: Execute middleware (handlerType added)
RequestMiddleware->>StartHandler: allow or reject
alt allowed
StartHandler->>ServerFunction: invoke serverFn handler
else rejected
RequestMiddleware-->>Browser: 403 Forbidden
end
Estimated code review effort: Possibly related PRs:
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Comment |
|
View your CI Pipeline Execution ↗ for commit 85d7a96
☁️ Nx Cloud last updated this comment at |
🚀 Changeset Version Preview4 package(s) bumped directly, 11 bumped as dependents. 🟨 Minor bumps
🟩 Patch bumps
|
Bundle Size Benchmarks
Current gzip tracks all emitted client JS chunks. Initial gzip tracks only the entry/import graph. Trend sparkline is historical current gzip ending with this PR measurement; lower is better. |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (4)
packages/start-fn-stubs/tests/createIsomorphicFn.test.ts (1)
4-24: ⚡ Quick winAdd argument-forwarding and reverse-chain coverage.
These tests validate core behavior, but adding argument passthrough and
client().server()order coverage will better protect the new runtime fallback path.✅ Suggested test additions
describe('createIsomorphicFn runtime fallback', () => { @@ it('returns a callable client-only implementation', () => { const fn = createIsomorphicFn().client(() => 'client') expect(fn()).toBe('client') }) + + it('forwards call arguments to the active implementation', () => { + const fn = createIsomorphicFn().server((a: number, b: number) => a + b) + + expect(fn(2, 3)).toBe(5) + }) + + it('uses server implementation when client is registered first', () => { + const fn = createIsomorphicFn() + .client(() => 'client') + .server(() => 'server') + + expect(fn()).toBe('server') + }) })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/start-fn-stubs/tests/createIsomorphicFn.test.ts` around lines 4 - 24, Add tests to cover argument forwarding and the reverse registration order: extend the existing createIsomorphicFn tests to assert that both server and client implementations receive and return arguments correctly (e.g., call fn(1, 'a') and expect the registered implementation to receive those args and return based on them), and add a test where .client(...) is chained before .server(...) to ensure .server still wins at runtime; update tests around createIsomorphicFn, .server, and .client to include these cases.packages/start-client-core/src/createCsrfMiddleware.ts (1)
80-83: ⚡ Quick winRemove
anycast from CSRF middleware context typing.Line 82 currently drops type safety with
RequestServerOptions<any, any>. Since the function is typed asCreateCsrfMiddleware(a generic type) but the implementation doesn't declare explicit type parameters,TRegisterandTMiddlewaresaren't in scope—forcing the unsafe cast. Add explicit generics to the implementation to match the type signature and eliminate this.♻️ Proposed type-safe refactor
-const innerCreateCsrfMiddleware: CreateCsrfMiddleware = (opts = {}) => { +const innerCreateCsrfMiddleware: CreateCsrfMiddleware = < + TRegister, + TMiddlewares, +>( + opts: CsrfMiddlewareOptions<TRegister, TMiddlewares> = {}, +) => { const middleware = createMiddleware().server(async (ctx) => { - const csrfCtx = ctx as RequestServerOptions<any, any> & typeof ctx + const csrfCtx = ctx as RequestServerOptions<TRegister, TMiddlewares> & + typeof ctxAs per coding guidelines,
**/*.{ts,tsx}: Use TypeScript strict mode with extensive type safety. This middleware is security-sensitive and should not useanytypes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/start-client-core/src/createCsrfMiddleware.ts` around lines 80 - 83, The implementation of innerCreateCsrfMiddleware drops type safety by casting ctx to RequestServerOptions<any, any>; instead add explicit generic parameters to innerCreateCsrfMiddleware so TRegister and TMiddlewares are in scope and use RequestServerOptions<TRegister, TMiddlewares> (or the correct generic aliases) for the csrfCtx typing; update the function signature for innerCreateCsrfMiddleware to declare the same generics as CreateCsrfMiddleware and remove the `any` cast where createMiddleware().server(async (ctx) => { const csrfCtx = ... }) is typed, ensuring the middleware uses the proper generic types throughout.docs/start/framework/react/guide/middleware.md (2)
462-462: ⚡ Quick winClarify what "different public origin" means.
The phrase "different public origin" is ambiguous. Consider clarifying that this is for cases where your application's public-facing URL differs from the server's internal origin (e.g., when behind a reverse proxy, CDN, or load balancer).
Suggested clarification
-By default, `Origin` and `Referer` checks compare against the incoming request URL origin. If your deployment needs to allow a different public origin, configure it on the CSRF middleware with `createCsrfMiddleware({ origin: 'https://app.example.com' })`. +By default, `Origin` and `Referer` checks compare against the incoming request URL origin. If your application's public-facing origin differs from the server origin (e.g., when behind a reverse proxy or CDN), configure the expected public origin with `createCsrfMiddleware({ origin: 'https://app.example.com' })`.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/start/framework/react/guide/middleware.md` at line 462, Update the sentence explaining "different public origin" to explicitly state it refers to situations where the public-facing URL differs from the server's internal origin (for example when behind a reverse proxy, CDN, or load balancer) and show how to set that with createCsrfMiddleware({ origin: 'https://app.example.com' }); also mention that Origin and Referer checks compare against the configured origin instead of the incoming request URL when this option is provided.
477-486: 💤 Low valueConsider strengthening the security message.
The current text explains how to disable the warning but could more explicitly emphasize that disabling the warning does not provide CSRF protection. Consider adding a note that users must still implement CSRF protection through another mechanism.
Optional enhancement
If you define `src/start.ts` without the CSRF middleware, Start shows a development warning for server function requests. If you intentionally handle CSRF another way, disable the warning: + +> [!WARNING] +> Disabling this warning does not provide CSRF protection. You must implement CSRF protection through the middleware shown above or an alternative mechanism. ```tsx // vite.config.ts or rsbuild.config.ts🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/start/framework/react/guide/middleware.md` around lines 477 - 486, Update the docs text around the CSRF middleware warning to explicitly state that setting serverFns.disableCsrfMiddlewareWarning (used in tanstackStart when you omit src/start.ts) only suppresses the development warning and does not provide CSRF protection; add a clear note that you must implement an alternative CSRF mitigation (e.g., same-site cookies, custom CSRF tokens, or other server-side checks) if you disable the warning and reference the disableCsrfMiddlewareWarning option so readers can locate the exact configuration.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/start/framework/react/guide/middleware.md`:
- Around line 466-475: The wording "use the same middleware" is inconsistent
with the example which calls createCsrfMiddleware() anew; either change the
sentence to "You can also use CSRF middleware to protect any other route" or
update the example to reuse the earlier csrfMiddleware variable (e.g. replace
createCsrfMiddleware() with csrfMiddleware in the createFileRoute call). Ensure
references to createCsrfMiddleware, csrfMiddleware and the Route/createFileRoute
example are updated so text and code match.
In `@packages/start-client-core/src/tests/createCsrfMiddleware.test.ts`:
- Around line 124-128: The test incorrectly treats `${requestOrigin}:443/path`
as cross-origin; update the it.each cases in createCsrfMiddleware.test.ts so
`${requestOrigin}:443/path` is moved from the rejection list into the allowed
Referer cases (same-origin) and replace the rejected port case with a
non-default port (e.g. `${requestOrigin}:444/path`) to assert true cross-origin
rejection; adjust the corresponding test descriptions (e.g., 'rejects
cross-origin Referer fallback') if needed so the examples and expectations
match.
In `@packages/start-fn-stubs/src/createIsomorphicFn.ts`:
- Around line 47-66: The current createRuntimeFn and RuntimeFallbackFn use loose
any types, an as any cast and mutate the input function via Object.assign;
change RuntimeFallbackFn to be generic (e.g., RuntimeFallbackFn<T extends
(...args:any[])=>any>) so the base function and server/client implementations
keep proper parameter/return types, update createRuntimeFn signature to
createRuntimeFn<T>(fn: T, serverImpl?: T): RuntimeFallbackFn<T>, and implement
it by returning a new wrapper object/function (not mutating the passed fn) that
forwards to fn and exposes server and client methods which return new typed
wrapper instances; ensure server and client accept implementations of type T and
remove the as any cast.
---
Nitpick comments:
In `@docs/start/framework/react/guide/middleware.md`:
- Line 462: Update the sentence explaining "different public origin" to
explicitly state it refers to situations where the public-facing URL differs
from the server's internal origin (for example when behind a reverse proxy, CDN,
or load balancer) and show how to set that with createCsrfMiddleware({ origin:
'https://app.example.com' }); also mention that Origin and Referer checks
compare against the configured origin instead of the incoming request URL when
this option is provided.
- Around line 477-486: Update the docs text around the CSRF middleware warning
to explicitly state that setting serverFns.disableCsrfMiddlewareWarning (used in
tanstackStart when you omit src/start.ts) only suppresses the development
warning and does not provide CSRF protection; add a clear note that you must
implement an alternative CSRF mitigation (e.g., same-site cookies, custom CSRF
tokens, or other server-side checks) if you disable the warning and reference
the disableCsrfMiddlewareWarning option so readers can locate the exact
configuration.
In `@packages/start-client-core/src/createCsrfMiddleware.ts`:
- Around line 80-83: The implementation of innerCreateCsrfMiddleware drops type
safety by casting ctx to RequestServerOptions<any, any>; instead add explicit
generic parameters to innerCreateCsrfMiddleware so TRegister and TMiddlewares
are in scope and use RequestServerOptions<TRegister, TMiddlewares> (or the
correct generic aliases) for the csrfCtx typing; update the function signature
for innerCreateCsrfMiddleware to declare the same generics as
CreateCsrfMiddleware and remove the `any` cast where
createMiddleware().server(async (ctx) => { const csrfCtx = ... }) is typed,
ensuring the middleware uses the proper generic types throughout.
In `@packages/start-fn-stubs/tests/createIsomorphicFn.test.ts`:
- Around line 4-24: Add tests to cover argument forwarding and the reverse
registration order: extend the existing createIsomorphicFn tests to assert that
both server and client implementations receive and return arguments correctly
(e.g., call fn(1, 'a') and expect the registered implementation to receive those
args and return based on them), and add a test where .client(...) is chained
before .server(...) to ensure .server still wins at runtime; update tests around
createIsomorphicFn, .server, and .client to include these cases.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f73d3d49-153d-4b5f-a94a-4547aae1e707
📒 Files selected for processing (19)
.changeset/strong-trains-act.mddocs/start/framework/react/guide/middleware.mddocs/start/framework/react/guide/server-functions.mde2e/react-start/server-functions/src/start.tse2e/react-start/server-functions/tests/server-functions.spec.tspackages/start-client-core/src/createCsrfMiddleware.tspackages/start-client-core/src/createMiddleware.tspackages/start-client-core/src/index.tsxpackages/start-client-core/src/tests/createCsrfMiddleware.test.tspackages/start-client-core/src/tests/createServerMiddleware.test-d.tspackages/start-fn-stubs/src/createIsomorphicFn.tspackages/start-fn-stubs/tests/createIsomorphicFn.test.tspackages/start-plugin-core/src/rsbuild/plugin.tspackages/start-plugin-core/src/schema.tspackages/start-plugin-core/src/vite/planning.tspackages/start-plugin-core/src/vite/plugin.tspackages/start-plugin-core/tests/csrf-warning-config.test.tspackages/start-server-core/src/createStartHandler.tspackages/start-server-core/src/global.d.ts
| You can also use the same middleware to protect any other route. | ||
|
|
||
| ```tsx | ||
| export const Route = createFileRoute('/api/foo')({ | ||
| server: { | ||
| middleware: [createCsrfMiddleware()], | ||
| handlers: { GET: () => {...} } | ||
| } | ||
| }) | ||
| ``` |
There was a problem hiding this comment.
Clarify whether to reuse or create a new middleware instance.
Line 466 says "use the same middleware" but the code example creates a new instance with createCsrfMiddleware(). Either update the text to say "You can also use CSRF middleware to protect any other route" or update the code to reuse the csrfMiddleware variable from the earlier example.
Option 1: Update text to match code (creates new instance)
-You can also use the same middleware to protect any other route.
+You can also use CSRF middleware to protect any other route.Option 2: Update code to reuse existing instance
export const Route = createFileRoute('/api/foo')({
server: {
- middleware: [createCsrfMiddleware()],
+ middleware: [csrfMiddleware],
handlers: { GET: () => {...} }
}
})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| You can also use the same middleware to protect any other route. | |
| ```tsx | |
| export const Route = createFileRoute('/api/foo')({ | |
| server: { | |
| middleware: [createCsrfMiddleware()], | |
| handlers: { GET: () => {...} } | |
| } | |
| }) | |
| ``` | |
| You can also use CSRF middleware to protect any other route. | |
| You can also use the same middleware to protect any other route. | |
| ```tsx | |
| export const Route = createFileRoute('/api/foo')({ | |
| server: { | |
| middleware: [createCsrfMiddleware()], | |
| handlers: { GET: () => {...} } | |
| } | |
| }) | |
| ``` | |
| You can also use the same middleware to protect any other route. | |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/start/framework/react/guide/middleware.md` around lines 466 - 475, The
wording "use the same middleware" is inconsistent with the example which calls
createCsrfMiddleware() anew; either change the sentence to "You can also use
CSRF middleware to protect any other route" or update the example to reuse the
earlier csrfMiddleware variable (e.g. replace createCsrfMiddleware() with
csrfMiddleware in the createFileRoute call). Ensure references to
createCsrfMiddleware, csrfMiddleware and the Route/createFileRoute example are
updated so text and code match.
| it.each([ | ||
| 'https://evil.example.com/path', | ||
| `${requestOrigin}.evil/path`, | ||
| `${requestOrigin}:443/path`, | ||
| ])('rejects cross-origin Referer fallback: %s', async (referer) => { |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Under the browser same-origin policy, are https://app.example.com` and https://app.example.com:443 considered the same origin?`
💡 Result:
Yes. Under the browser same-origin policy, https://app.example.com and https://app.example.com:443 are considered the same origin. Reason: the origin is defined by the scheme, hostname, and port tuple, and the port is only included in the origin if it is not the default for the scheme; for HTTPS the default port is 443, so omitting:443 is equivalent to explicitly specifying it. Therefore both URLs have the same scheme (https), same host (app.example.com), and effectively the same port (443). [1][2][3]
Citations:
- 1: https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Same-origin_policy
- 2: https://developer.mozilla.org/en-US/docs/Web/API/URL/origin
- 3: http://developer.mozilla.org/en-US/docs/Glossary/Origin
Default HTTPS port is same-origin; move this case to the allowed list.
Line 127 treats ${requestOrigin}:443/path as cross-origin, but https://app.example.com and https://app.example.com:443 are same-origin equivalents per the browser same-origin policy—the default port 443 for HTTPS is implicit when omitted. This test expectation can push the implementation toward false CSRF denials for valid same-origin requests.
Move ${requestOrigin}:443/path from the rejection list to the allowed list and replace it with a non-default port like 444 in the rejection cases.
Suggested test adjustment
it.each([
requestOrigin,
`${requestOrigin}/path`,
`${requestOrigin}?query=1`,
`${requestOrigin}#hash`,
+ `${requestOrigin}:443/path`,
])('allows same-origin Referer fallback: %s', async (referer) => {
const ctx = createContext({ headers: { Referer: referer } })
await expect(getCsrfRequestValidationResult({}, ctx)).resolves.toBe(true)
})
it.each([
'https://evil.example.com/path',
`${requestOrigin}.evil/path`,
- `${requestOrigin}:443/path`,
+ 'https://app.example.com:444/path',
])('rejects cross-origin Referer fallback: %s', async (referer) => {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/start-client-core/src/tests/createCsrfMiddleware.test.ts` around
lines 124 - 128, The test incorrectly treats `${requestOrigin}:443/path` as
cross-origin; update the it.each cases in createCsrfMiddleware.test.ts so
`${requestOrigin}:443/path` is moved from the rejection list into the allowed
Referer cases (same-origin) and replace the rejected port case with a
non-default port (e.g. `${requestOrigin}:444/path`) to assert true cross-origin
rejection; adjust the corresponding test descriptions (e.g., 'rejects
cross-origin Referer fallback') if needed so the examples and expectations
match.
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts (1)
334-336: 💤 Low valueConsider adding a brief inline comment explaining the cast.
The
as unknown as StartCompilerPluginContextcast bypasses TypeScript's type checking, which is a pragmatic approach for plugin contexts. However, a brief comment would clarify why this is safe and what subset of Vite's context is being captured.📝 Suggested comment
const result = await compilerContextStorage.run( + // Cast to our context subset - Vite's transform handler provides these methods this as unknown as StartCompilerPluginContext, () =>As per coding guidelines: "Use TypeScript strict mode with extensive type safety" - while this cast is necessary, documenting it improves maintainability.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts` around lines 334 - 336, Add a short inline comment above the cast in the compilerContextStorage.run call explaining why the `as unknown as StartCompilerPluginContext` cast is used and what subset of Vite's context is being captured; mention that the cast is intentional to adapt Vite's broader context to the plugin's narrower StartCompilerPluginContext and note any invariants or assumptions that make this conversion safe (reference: compilerContextStorage.run and StartCompilerPluginContext).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts`:
- Around line 334-336: Add a short inline comment above the cast in the
compilerContextStorage.run call explaining why the `as unknown as
StartCompilerPluginContext` cast is used and what subset of Vite's context is
being captured; mention that the cast is intentional to adapt Vite's broader
context to the plugin's narrower StartCompilerPluginContext and note any
invariants or assumptions that make this conversion safe (reference:
compilerContextStorage.run and StartCompilerPluginContext).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d69083d0-3052-4c33-ad54-a251d1231e5c
📒 Files selected for processing (2)
packages/react-start-client/src/tests/createServerFn.test-d.tsxpackages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts
There was a problem hiding this comment.
Nx Cloud is proposing a fix for your failed CI:
We fix the Start compiler Vite context is unavailable error by wrapping the hotUpdate handler's finishHotUpdate() call with compilerContextStorage.run(), mirroring the same pattern already used in transform.handler. Without this, the AsyncLocalStorage store was empty during HMR, causing getCompilerContext() to throw when compiler.getTransitiveImporters() internally called the resolveId callback.
Tip
✅ We verified this fix by re-running tanstack-react-start-e2e-hmr:test:e2e--vite-ssr.
Suggested Fix changes
diff --git a/packages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts b/packages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts
index d4237985..dcc26ad6 100644
--- a/packages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts
+++ b/packages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts
@@ -198,6 +198,14 @@ export function startCompilerPlugin(
const compilers = new Map<string, ReturnType<typeof createStartCompiler>>()
const compilerContextStorage =
new AsyncLocalStorage<StartCompilerPluginContext>()
+ // Stores the most recent full PluginContext from transform.handler per
+ // environment. hotUpdate runs with MinimalPluginContext (no resolve/load),
+ // so we fall back to this when setting up the AsyncLocalStorage context for
+ // getTransitiveImporters calls during HMR.
+ const lastTransformContextByEnv = new Map<
+ string,
+ StartCompilerPluginContext
+ >()
const getCompilerContext = () => {
const context = compilerContextStorage.getStore()
@@ -331,14 +339,15 @@ export function startCompilerPlugin(
compilerTransforms,
})
- const result = await compilerContextStorage.run(
- this as unknown as StartCompilerPluginContext,
- () =>
- compiler.compile({
- id,
- code,
- detectedKinds,
- }),
+ const pluginContext = this as unknown as StartCompilerPluginContext
+ lastTransformContextByEnv.set(this.environment.name, pluginContext)
+
+ const result = await compilerContextStorage.run(pluginContext, () =>
+ compiler.compile({
+ id,
+ code,
+ detectedKinds,
+ }),
)
return result
},
@@ -424,6 +433,13 @@ export function startCompilerPlugin(
return mergeHotUpdateModules(ctx.modules, providerModules)
}
+ const storedContext = lastTransformContextByEnv.get(
+ this.environment.name,
+ )
+ if (storedContext) {
+ return compilerContextStorage.run(storedContext, finishHotUpdate)
+ }
+
return finishHotUpdate()
},
}
Or Apply changes locally with:
npx nx-cloud apply-locally NHaT-0fiz
Apply fix locally with your editor ↗ View interactive diff ↗
🎓 Learn more about Self-Healing CI on nx.dev
createCsrfMiddleware()to protect TanStack Start server functions from cross-site requests usingSec-Fetch-Site,Origin, andRefererchecks.startInstanceis defined, and add a dev warning when a customstartInstanceomits CSRF middleware.serverFns.disableCsrfMiddlewareWarning, wired through Vite and Rsbuild.createCsrfMiddleware()should be fully removed at build time for the client, including the arguments passed to itSummary by CodeRabbit
New Features
Documentation
Bug Fixes
Tests