feat(workflow): add versioned stream event schema system#41
feat(workflow): add versioned stream event schema system#41BjornMelin wants to merge 5 commits intomainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughThis PR centralizes workflow stream event schemas into a new shared module, replacing removed per-file schemas, and updates producers/consumers to use domain + version-enveloped events (schemaVersion: 2). It adds a server-only workflow runtime re-export module and updates many imports to that path. Network policy constants and shapes were changed, and build/CI was extended with a Bun strict build path and documentation for Bun-first builds. Multiple package versions and package.json scripts/overrides were updated. Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 6 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (6 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
Review Summary by QodoStandardize workflow stream events with versioning and implement Bun-first build strategy
WalkthroughsDescription• Centralize workflow runtime imports and standardize stream event schemas with versioning • Add Bun-first build strategy with deterministic Node fallback for transient failures • Update approval and chat hooks to include schemaVersion field for compatibility • Migrate stream event definitions to unified workflow-stream-events module • Refactor sandbox network policy to use new Vercel SDK API (string literals and allow field) Diagramflowchart LR
A["Build Scripts"] -->|"auto/bun/node modes"| B["build-next.sh"]
B -->|"Bun primary"| C["Next.js Build"]
B -->|"Known transient failure"| D["Bun Retry"]
D -->|"Still fails"| E["Node Fallback"]
F["Stream Events"] -->|"Unified schema v2"| G["workflow-stream-events"]
G -->|"domain + version"| H["Run/Chat/CodeMode Events"]
I["Workflow Runtime"] -->|"Centralized imports"| J["workflow-runtime.server"]
J -->|"Used by"| K["Route Handlers & Helpers"]
File Changes1. scripts/build-next.sh
|
There was a problem hiding this comment.
Pull request overview
This PR introduces a robust, documented Bun-first build strategy with fallback mechanisms, upgrades dependencies, and implements schema versioning (v2) across workflow stream events. The changes focus on improving build reliability, maintainability, and establishing clear API versioning.
Changes:
- Implemented Bun-first build policy with deterministic Node fallback for known transient failures
- Added schema version 2 with
domainandversionfields to all workflow stream events - Upgraded 40+ dependencies and added package overrides for version consistency
- Centralized workflow runtime imports and updated network policy API usage
Reviewed changes
Copilot reviewed 48 out of 49 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/build-next.sh | New build orchestration script with transient error detection and runtime fallback logic |
| package.json | Updated build scripts, dependency upgrades, added overrides section |
| docs/ops/build-runtime.md | Comprehensive build policy documentation |
| .github/workflows/ci.yml | Added non-blocking strict-Bun canary build job |
| vercel.json | Added frozen lockfile install command |
| next.config.ts | Disabled Turbopack filesystem cache pending benchmarking |
| src/workflows/_shared/workflow-stream-events.ts | New centralized stream event schemas with v2 versioning |
| src/workflows/*/writer.step.ts | Updated to use centralized event creators with envelope fields |
| src/lib/sandbox/network-policy.server.ts | Updated to new Vercel Sandbox network policy API |
| src/workflows/_shared/workflow-runtime.server.ts | New centralized workflow runtime imports |
| eslint.config.js | Removed unused TypeScript ESLint plugin import |
| Multiple test files | Updated assertions for v2 schema with domain/version fields |
| Multiple client files | Updated storage keys and schema validation for v2 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Code Review by Qodo
✅ 1.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 76963b80e6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
src/lib/sandbox/network-policy.server.ts (1)
5-31:⚠️ Potential issue | 🟠 MajorAdd required TSDoc blocks for exported network policy constants.
These exported constants are in a TS source file and must have immediately preceding TSDoc; otherwise lint/typecheck will fail.
✍️ Proposed fix
+/** Defines the deny-all network policy used when outbound traffic is blocked. */ export const SANDBOX_NETWORK_POLICY_NONE: NetworkPolicy = "deny-all"; +/** Defines the default restricted allowlist for Node-based sandboxes. */ export const SANDBOX_NETWORK_POLICY_RESTRICTED_DEFAULT: NetworkPolicy = { allow: [ "*.github.com", "*.githubusercontent.com", "*.npmjs.org", "api.github.com", "codeload.github.com", "github.com", "raw.githubusercontent.com", "registry.npmjs.org", ], }; +/** Defines the default restricted allowlist for Python sandboxes. */ export const SANDBOX_NETWORK_POLICY_RESTRICTED_PYTHON_DEFAULT: NetworkPolicy = { allow: [ "*.github.com", "*.githubusercontent.com", "api.github.com", "codeload.github.com", "files.pythonhosted.org", "github.com", "pypi.org", "raw.githubusercontent.com", ], };As per coding guidelines, "Every changed or added exported declaration (export function, export async function, export const, export class, export interface, export type, export enum, Next.js route handlers, re-exports) MUST have an immediately preceding doc comment
/** ... */with no blank line separating it."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/sandbox/network-policy.server.ts` around lines 5 - 31, Add immediately preceding TSDoc comments for each exported constant (SANDBOX_NETWORK_POLICY_NONE, SANDBOX_NETWORK_POLICY_RESTRICTED_DEFAULT, SANDBOX_NETWORK_POLICY_RESTRICTED_PYTHON_DEFAULT) with no blank line between comment and export; the TSDoc should briefly describe the purpose of the constant (e.g., deny-all default policy, restricted npm/JS policy, restricted Python/pip policy) and any noteworthy details (allowed hosts). Ensure each exported declaration has its own /** ... */ block directly above it to satisfy the lint/typecheck rule.src/workflows/approvals/hooks/approval.ts (1)
15-15:⚠️ Potential issue | 🟡 MinorMissing TSDoc for exported type
ApprovalResumePayload.Per coding guidelines, every exported declaration must have an immediately preceding doc comment. The
ApprovalResumePayloadtype is exported but lacks documentation.📝 Proposed fix
+/** Payload structure for resuming an approval gate with versioned schema. */ export type ApprovalResumePayload = z.infer<typeof approvalResumeSchema>;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/workflows/approvals/hooks/approval.ts` at line 15, Add a TSDoc comment immediately above the exported type ApprovalResumePayload describing what the payload represents and its relation to approvalResumeSchema (e.g., "Payload for resuming an approval flow, inferred from approvalResumeSchema"). Ensure the comment is a proper /** ... */ block placed directly before the line exporting ApprovalResumePayload so it satisfies the exported-declaration documentation rule and references approvalResumeSchema for context.src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx (1)
200-206: 🧹 Nitpick | 🔵 TrivialConsider migrating or clearing stale v1 storage keys.
The storage key was updated from v1 to v2 (
workflow:code-mode:v2:...). Per coding guidelines, storage versioning should include migrations. If users have existing v1 keys in sessionStorage, they will remain as stale data. Since this is sessionStorage (not localStorage), the impact is limited to the current browser session, but a one-time cleanup could prevent confusion during debugging.🧹 Optional cleanup for v1 keys
// Optional: Clear stale v1 keys on component mount useEffect(() => { try { const keysToRemove: string[] = []; for (let i = 0; i < window.sessionStorage.length; i++) { const key = window.sessionStorage.key(i); if (key?.startsWith("workflow:code-mode:v1:")) { keysToRemove.push(key); } } keysToRemove.forEach((k) => window.sessionStorage.removeItem(k)); } catch { // Ignore storage access errors } }, []);Also applies to: 217-217
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`(app)/projects/[projectId]/code-mode/code-mode-client.tsx around lines 200 - 206, The current cleanup only removes the v2 key (`workflow:code-mode:v2:${parsedRunId}:startIndex`) but doesn't clear stale v1 keys; update the component (e.g., in the same mount logic or useEffect around where window.sessionStorage.removeItem is called in code-mode-client.tsx) to also enumerate sessionStorage keys inside a try/catch and remove any key that startsWith "workflow:code-mode:v1:" (collect keys first then remove to avoid iteration issues); apply the same migration/cleanup logic where the other v2 removal occurs (the other occurrence around line 217) so v1 keys are cleared consistently.src/app/api/skills/registry/install/route.ts (1)
71-71: 🧹 Nitpick | 🔵 TrivialConsider logging the suppressed cancelRun error for observability.
The
.catch(() => undefined)silently swallows any cancellation failure. While this is acceptable for best-effort cleanup, logging the error would help diagnose issues with orphaned workflow runs.🔧 Proposed improvement
- await cancelRun(world, run.runId).catch(() => undefined); + await cancelRun(world, run.runId).catch((cancelErr) => { + log.warn("project_skill_registry_install_cancel_failed", { + cancelErr, + runId: run.runId, + }); + });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/api/skills/registry/install/route.ts` at line 71, The current best-effort cleanup call await cancelRun(world, run.runId).catch(() => undefined) swallows errors silently; change the catch to log the error (e.g., .catch(err => { /* use existing logger or console.error */ logger?.error ? logger.error({ err, world, runId: run.runId }, "cancelRun failed") : console.error("cancelRun failed", { err, world, runId: run.runId }); })) so the error is recorded for observability while still suppressing it from bubbling; reference cancelRun(world, run.runId), world and run.runId when adding the log message.src/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsx (1)
99-116:⚠️ Potential issue | 🟡 MinorAdd a migration for the v1 startIndex storage key.
Bumping to v2 drops any existing resume position and leaves the legacy key behind; migrate or clear it on first read.🔁 Suggested migration for legacy startIndex
- let startIndex = readStartIndex(storageKey); + const legacyStorageKey = `workflow:runs:v1:${props.runId}:startIndex`; + let startIndex = readStartIndex(storageKey); + if (startIndex === 0) { + const legacyStartIndex = readStartIndex(legacyStorageKey); + if (legacyStartIndex > 0) { + startIndex = legacyStartIndex; + persistStartIndex(storageKey, legacyStartIndex); + try { + window.sessionStorage.removeItem(legacyStorageKey); + } catch { + // Ignore. + } + } + }As per coding guidelines: For localStorage/sessionStorage: version keys, store minimal data, wrap get/set in try/catch, and implement migrations.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsx around lines 99 - 116, The v2 storageKey (`workflow:runs:v2:${props.runId}:startIndex`) ignores any legacy v1 key and drops resume position; update the startup logic around readStartIndex/storageKey to detect the legacy key (e.g., `workflow:runs:${props.runId}:startIndex`), wrap storage reads/writes in try/catch, migrate the legacy value into the v2 key (or clear it) on first read, and then proceed using readStartIndex; modify or add a small migration helper called from the effect (referencing storageKey and readStartIndex) to perform the copy+delete (or clear) and ensure only minimal/versioned data is stored.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (48)
.github/actions/ci-setup/action.yml.github/workflows/ci.ymlAGENTS.mddocs/ops/build-runtime.mdeslint.config.jsnext.config.tspackage.jsonscripts/build-next.shsrc/app/(app)/projects/[projectId]/chat/chat-client.tsxsrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/app/api/approvals/__tests__/route.test.tssrc/app/api/approvals/route.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/app/api/chat/[runId]/cancel/route.tssrc/app/api/chat/[runId]/route.tssrc/app/api/chat/[runId]/stream/route.tssrc/app/api/chat/route.tssrc/app/api/code-mode/[runId]/stream/route.tssrc/app/api/runs/[runId]/stream/route.tssrc/app/api/skills/registry/install/route.tssrc/app/api/skills/registry/status/route.tssrc/lib/runs/code-mode-stream.test.tssrc/lib/runs/code-mode-stream.tssrc/lib/runs/code-mode.server.tssrc/lib/runs/project-run.server.tssrc/lib/runs/run-stream.tssrc/lib/sandbox/network-policy.server.test.tssrc/lib/sandbox/network-policy.server.tssrc/lib/sandbox/sandbox-runner.server.test.tssrc/workflows/_shared/workflow-runtime.server.tssrc/workflows/_shared/workflow-stream-events.tssrc/workflows/approvals/hooks/approval.tssrc/workflows/chat/hooks/chat-message.test.tssrc/workflows/chat/hooks/chat-message.tssrc/workflows/chat/steps/writer.step.test.tssrc/workflows/chat/steps/writer.step.tssrc/workflows/code-mode/steps/code-mode.step.test.tssrc/workflows/code-mode/steps/code-mode.step.tssrc/workflows/code-mode/steps/writer.step.test.tssrc/workflows/code-mode/steps/writer.step.tssrc/workflows/runs/project-run.workflow.tssrc/workflows/runs/steps/writer.step.test.tssrc/workflows/runs/steps/writer.step.tssrc/workflows/runs/workflow-errors.test.tssrc/workflows/runs/workflow-errors.tsvercel.json
💤 Files with no reviewable changes (3)
- src/lib/runs/run-stream.ts
- src/lib/runs/code-mode-stream.ts
- eslint.config.js
🧰 Additional context used
📓 Path-based instructions (15)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{js,jsx,ts,tsx}: No promise-valued statement may be left unhandled. A Promise is handled ONLY if it isawaited,returned, terminated with.catch(...), terminated with.then(onFulfilled, onRejected)(rejection handler required), or explicitly ignored withvoidAND meets additional requirements.
For files importing or referencing AI SDK / Vercel AI modules (ai,@ai-sdk/*,@vercel/ai,openai,@openai/*), fire-and-forget is forbidden by default. If usingvoid someAsyncCall(...), it MUST include an inline comment explaining why detaching is safe AND errors must be surfaced via.catch(...)or a dedicated error sink (logging/telemetry).
Files:
src/app/api/chat/[runId]/route.tssrc/app/api/approvals/route.tssrc/workflows/chat/hooks/chat-message.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/workflows/_shared/workflow-runtime.server.tssrc/app/api/chat/[runId]/stream/route.tssrc/workflows/runs/project-run.workflow.tssrc/app/api/chat/route.tssrc/lib/sandbox/sandbox-runner.server.test.tssrc/app/api/code-mode/[runId]/stream/route.tssrc/app/api/runs/[runId]/stream/route.tssrc/workflows/code-mode/steps/writer.step.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/workflows/runs/workflow-errors.test.tssrc/lib/runs/code-mode.server.tssrc/workflows/code-mode/steps/writer.step.test.tssrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/workflows/_shared/workflow-stream-events.tssrc/workflows/code-mode/steps/code-mode.step.test.tssrc/workflows/code-mode/steps/code-mode.step.tssrc/lib/runs/project-run.server.tssrc/workflows/chat/hooks/chat-message.test.tssrc/app/api/skills/registry/status/route.tssrc/app/api/chat/[runId]/cancel/route.tssrc/workflows/runs/steps/writer.step.test.tssrc/workflows/runs/steps/writer.step.tssrc/lib/sandbox/network-policy.server.test.tsnext.config.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/workflows/runs/workflow-errors.tssrc/app/api/skills/registry/install/route.tssrc/workflows/chat/steps/writer.step.tssrc/app/api/approvals/__tests__/route.test.tssrc/workflows/chat/steps/writer.step.test.tssrc/workflows/approvals/hooks/approval.tssrc/lib/sandbox/network-policy.server.tssrc/lib/runs/code-mode-stream.test.tssrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{ts,tsx,js,jsx}: Hard FAIL if the PR introduces any test-only helpers, shims, mocks, or conditional branches intended only for tests in production source files. All test scaffolding must live in test suites and test configuration (Vitest and/or Playwright).
Doc comment formatting must satisfy Biome, including violations ofuseSingleJsDocAsterisk. Hard FAIL if Biome reports any issue with JSDoc/TSDoc formatting.
The first non-empty line inside a doc comment MUST be a single-sentence summary ending with a period.. The summary must describe behavior and intent, not just the symbol name. Hard FAIL if any condition is violated.
Only these tags are allowed in doc comments:@remarks,@param,@typeParam,@returns,@throws,@example,@see,@deprecated. Hard FAIL if any other@tagappears.
Doc comment tags must appear in this strict order (skip unused):@remarks, all@typeParam, all@param,@returns, all@throws, all@example, all@see,@deprecated. Hard FAIL if tags are out of order.
@remarksmust be separated from the summary by a blank line and must have non-empty content. Hard FAIL if present but empty or not separated by a blank line.
For every exported function (including route handlers), document EVERY parameter with@param. Each@paramline MUST match the exact pattern:@param <name> - <description>where<name>matches an actual parameter name, the literal separator-is present, and<description>is non-empty and explains semantics and constraints. JSDoc type braces are forbidden in TS/TSX. Hard FAIL if violations exist.
@returnsis required for every exported function whose return type is notvoidand notPromise<void>, and for all Next.js route handlers. It must have non-empty semantic description. JSDoc type braces are forbidden in TS/TSX. Hard FAIL if required but missing, empty, or typed via braces.
If an exported function body contains the tokenthrowin newly added or modified lines, at lea...
Files:
src/app/api/chat/[runId]/route.tssrc/app/api/approvals/route.tssrc/workflows/chat/hooks/chat-message.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/workflows/_shared/workflow-runtime.server.tssrc/app/api/chat/[runId]/stream/route.tssrc/workflows/runs/project-run.workflow.tssrc/app/api/chat/route.tssrc/lib/sandbox/sandbox-runner.server.test.tssrc/app/api/code-mode/[runId]/stream/route.tssrc/app/api/runs/[runId]/stream/route.tssrc/workflows/code-mode/steps/writer.step.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/workflows/runs/workflow-errors.test.tssrc/lib/runs/code-mode.server.tssrc/workflows/code-mode/steps/writer.step.test.tssrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/workflows/_shared/workflow-stream-events.tssrc/workflows/code-mode/steps/code-mode.step.test.tssrc/workflows/code-mode/steps/code-mode.step.tssrc/lib/runs/project-run.server.tssrc/workflows/chat/hooks/chat-message.test.tssrc/app/api/skills/registry/status/route.tssrc/app/api/chat/[runId]/cancel/route.tssrc/workflows/runs/steps/writer.step.test.tssrc/workflows/runs/steps/writer.step.tssrc/lib/sandbox/network-policy.server.test.tsnext.config.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/workflows/runs/workflow-errors.tssrc/app/api/skills/registry/install/route.tssrc/workflows/chat/steps/writer.step.tssrc/app/api/approvals/__tests__/route.test.tssrc/workflows/chat/steps/writer.step.test.tssrc/workflows/approvals/hooks/approval.tssrc/lib/sandbox/network-policy.server.tssrc/lib/runs/code-mode-stream.test.tssrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{ts,tsx}: Every changed or added exported declaration (export function, export async function, export const, export class, export interface, export type, export enum, Next.js route handlers, re-exports) MUST have an immediately preceding doc comment/** ... */with no blank line separating it. Hard FAIL if any required export lacks a doc comment.
If an exported function/type/class introduces generic type parameters AND they are not self-explanatory, require@typeParamper generic parameter following the pattern:@typeParam <name> - <description>. Hard FAIL if required generics are undocumented, or if@typeParamdoes not follow the hyphen pattern, or is empty.
In TS/TSX doc comments, these tags are forbidden:@type,@typedef,@property,@template,@enum,@memberof. Hard FAIL if any appear.
Server Actions are public endpoints. Inside every Server Action: validate input, authenticate, authorize. Never rely only on middleware/layout guards.
Minimize RSC→client serialization: pass only fields the client uses. Avoid sending multiple derived copies of large primitive arrays; derive in client unless the server compute is expensive or the client must not see the raw data.
Avoid duplicate serialization by reference: transformations liketoSorted(),filter(),map(), spreads create new references. Prefer passing one reference across the RSC/client boundary.
Usereactcache()for per-request deduplication of DB/auth/heavy compute within a single request. Avoid inline object args (cache hits require stable identity). Note: Next.jsfetchis already memoized per request.
Use Next.jsafter()for non-blocking work (logging, analytics, notifications, cleanup). Do not block responses on side effects.
**/*.{ts,tsx}: Enforce strict TypeScript with no use of 'any' type
Code must pass bun run typecheck clean (TypeScript compiler)
Files:
src/app/api/chat/[runId]/route.tssrc/app/api/approvals/route.tssrc/workflows/chat/hooks/chat-message.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/workflows/_shared/workflow-runtime.server.tssrc/app/api/chat/[runId]/stream/route.tssrc/workflows/runs/project-run.workflow.tssrc/app/api/chat/route.tssrc/lib/sandbox/sandbox-runner.server.test.tssrc/app/api/code-mode/[runId]/stream/route.tssrc/app/api/runs/[runId]/stream/route.tssrc/workflows/code-mode/steps/writer.step.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/workflows/runs/workflow-errors.test.tssrc/lib/runs/code-mode.server.tssrc/workflows/code-mode/steps/writer.step.test.tssrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/workflows/_shared/workflow-stream-events.tssrc/workflows/code-mode/steps/code-mode.step.test.tssrc/workflows/code-mode/steps/code-mode.step.tssrc/lib/runs/project-run.server.tssrc/workflows/chat/hooks/chat-message.test.tssrc/app/api/skills/registry/status/route.tssrc/app/api/chat/[runId]/cancel/route.tssrc/workflows/runs/steps/writer.step.test.tssrc/workflows/runs/steps/writer.step.tssrc/lib/sandbox/network-policy.server.test.tsnext.config.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/workflows/runs/workflow-errors.tssrc/app/api/skills/registry/install/route.tssrc/workflows/chat/steps/writer.step.tssrc/app/api/approvals/__tests__/route.test.tssrc/workflows/chat/steps/writer.step.test.tssrc/workflows/approvals/hooks/approval.tssrc/lib/sandbox/network-policy.server.tssrc/lib/runs/code-mode-stream.test.tssrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
src/app/**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use Next.js App Router patterns only (no Pages Router)
Files:
src/app/api/chat/[runId]/route.tssrc/app/api/approvals/route.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/app/api/chat/[runId]/stream/route.tssrc/app/api/chat/route.tssrc/app/api/code-mode/[runId]/stream/route.tssrc/app/api/runs/[runId]/stream/route.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/api/skills/registry/status/route.tssrc/app/api/chat/[runId]/cancel/route.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/app/api/skills/registry/install/route.tssrc/app/api/approvals/__tests__/route.test.tssrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
src/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Enable Cache Components with 'use cache' directive and use cacheTag/revalidateTag for stable server reads
Files:
src/app/api/chat/[runId]/route.tssrc/app/api/approvals/route.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/app/api/chat/[runId]/stream/route.tssrc/app/api/chat/route.tssrc/app/api/code-mode/[runId]/stream/route.tssrc/app/api/runs/[runId]/stream/route.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/api/skills/registry/status/route.tssrc/app/api/chat/[runId]/cancel/route.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/app/api/skills/registry/install/route.tssrc/app/api/approvals/__tests__/route.test.tssrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use memoization (useMemo, useCallback, React.memo) only for expensive computations or to prevent costly re-renders; avoid memo for simple primitives/cheap work; hoist stable non-primitive defaults
Provide TSDoc documentation for all exported APIs
Use Neon Auth only (@neondatabase/auth) for authentication
Prefer AI SDK's gateway(...) / createGateway(...) provider for model routing
Use AI SDK Gateway provider base URL https://ai-gateway.vercel.sh/v3/ai (default; configurable via AI_GATEWAY_BASE_URL)
Use OpenAI-compatible base URL https://ai-gateway.vercel.sh/v1 for OpenAI SDK compatibility and GET /models
Public/exported APIs must have valid TSDoc documentation
Files:
src/app/api/chat/[runId]/route.tssrc/app/api/approvals/route.tssrc/workflows/chat/hooks/chat-message.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/workflows/_shared/workflow-runtime.server.tssrc/app/api/chat/[runId]/stream/route.tssrc/workflows/runs/project-run.workflow.tssrc/app/api/chat/route.tssrc/lib/sandbox/sandbox-runner.server.test.tssrc/app/api/code-mode/[runId]/stream/route.tssrc/app/api/runs/[runId]/stream/route.tssrc/workflows/code-mode/steps/writer.step.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/workflows/runs/workflow-errors.test.tssrc/lib/runs/code-mode.server.tssrc/workflows/code-mode/steps/writer.step.test.tssrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/workflows/_shared/workflow-stream-events.tssrc/workflows/code-mode/steps/code-mode.step.test.tssrc/workflows/code-mode/steps/code-mode.step.tssrc/lib/runs/project-run.server.tssrc/workflows/chat/hooks/chat-message.test.tssrc/app/api/skills/registry/status/route.tssrc/app/api/chat/[runId]/cancel/route.tssrc/workflows/runs/steps/writer.step.test.tssrc/workflows/runs/steps/writer.step.tssrc/lib/sandbox/network-policy.server.test.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/workflows/runs/workflow-errors.tssrc/app/api/skills/registry/install/route.tssrc/workflows/chat/steps/writer.step.tssrc/app/api/approvals/__tests__/route.test.tssrc/workflows/chat/steps/writer.step.test.tssrc/workflows/approvals/hooks/approval.tssrc/lib/sandbox/network-policy.server.tssrc/lib/runs/code-mode-stream.test.tssrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx,js,jsx}: Do not use package barrel imports by default; use explicit imports
Use barrel imports only for packages listed in next.config.ts experimental.optimizePackageImports (currently radix-ui and lucide-react)
Code must pass bun run format with no changes
Code must pass bun run lint clean (Biome + ESLint for TSDoc syntax and JSDoc on exported APIs)
No console spam in production paths
Files:
src/app/api/chat/[runId]/route.tssrc/app/api/approvals/route.tssrc/workflows/chat/hooks/chat-message.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/workflows/_shared/workflow-runtime.server.tssrc/app/api/chat/[runId]/stream/route.tssrc/workflows/runs/project-run.workflow.tssrc/app/api/chat/route.tssrc/lib/sandbox/sandbox-runner.server.test.tssrc/app/api/code-mode/[runId]/stream/route.tssrc/app/api/runs/[runId]/stream/route.tssrc/workflows/code-mode/steps/writer.step.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/workflows/runs/workflow-errors.test.tssrc/lib/runs/code-mode.server.tssrc/workflows/code-mode/steps/writer.step.test.tssrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/workflows/_shared/workflow-stream-events.tssrc/workflows/code-mode/steps/code-mode.step.test.tssrc/workflows/code-mode/steps/code-mode.step.tssrc/lib/runs/project-run.server.tssrc/workflows/chat/hooks/chat-message.test.tssrc/app/api/skills/registry/status/route.tssrc/app/api/chat/[runId]/cancel/route.tssrc/workflows/runs/steps/writer.step.test.tssrc/workflows/runs/steps/writer.step.tssrc/lib/sandbox/network-policy.server.test.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/workflows/runs/workflow-errors.tssrc/app/api/skills/registry/install/route.tssrc/workflows/chat/steps/writer.step.tssrc/app/api/approvals/__tests__/route.test.tssrc/workflows/chat/steps/writer.step.test.tssrc/workflows/approvals/hooks/approval.tssrc/lib/sandbox/network-policy.server.tssrc/lib/runs/code-mode-stream.test.tssrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
src/app/api/chat/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Follow-ups during active durable chat sessions must use POST /api/chat/:runId accepting optional files alongside message (messageId required)
Files:
src/app/api/chat/[runId]/route.tssrc/app/api/chat/[runId]/stream/route.tssrc/app/api/chat/route.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/app/api/chat/[runId]/cancel/route.ts
src/workflows/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Place workflow-only shared helpers in src/workflows/_shared/ instead of src/lib/; avoid index.ts re-export facades and import concrete modules directly
Files:
src/workflows/chat/hooks/chat-message.tssrc/workflows/_shared/workflow-runtime.server.tssrc/workflows/runs/project-run.workflow.tssrc/workflows/code-mode/steps/writer.step.tssrc/workflows/runs/workflow-errors.test.tssrc/workflows/code-mode/steps/writer.step.test.tssrc/workflows/_shared/workflow-stream-events.tssrc/workflows/code-mode/steps/code-mode.step.test.tssrc/workflows/code-mode/steps/code-mode.step.tssrc/workflows/chat/hooks/chat-message.test.tssrc/workflows/runs/steps/writer.step.test.tssrc/workflows/runs/steps/writer.step.tssrc/workflows/runs/workflow-errors.tssrc/workflows/chat/steps/writer.step.tssrc/workflows/chat/steps/writer.step.test.tssrc/workflows/approvals/hooks/approval.ts
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{tsx,jsx}: Pure presentational React components exported only for JSX composition may omit doc comments ONLY if they have no non-obvious behavior (no IO, no side effects, no caching semantics, no security checks, no data fetching, no tool calls). If in doubt, require doc comment.
Defer non-critical third-party code (analytics, error tracking) until after hydration:next/dynamic(..., { ssr:false })or client-only boundary.
Dynamically import heavy components not needed for initial paint (editors, charts, maps). Usessr:falsewhen they require the DOM.
Preload based on user intent (hover/focus) or feature flags to reduce perceived latency. Preload should be optional and non-blocking.
Prefer SWR (or an equivalent) for client fetching to get caching, deduplication, revalidation, and mutation helpers.
Deduplicate global event listeners. Avoid "N components = N listeners" patterns; centralize subscriptions and fan out callbacks.
Do not subscribe to reactive sources you only need in callbacks (e.g., search params). Read at the point of use when possible.
Put early returns before expensive computations. If needed, extract expensive work into memoized components so "loading" paths skip the work.
Narrow effect dependencies: depend on primitives and derived booleans, not entire objects.
Subscribe to derived state rather than continuous signals (use media queries instead of window width pixels when only a breakpoint matters).
Use functional state updates when new state depends on previous state (setX(curr => ...)). This prevents stale closures and stabilizes callbacks.
Use lazy state initialization for expensive initial values (useState(() => expensive())), especially storage parsing or index building.
Use transitions for frequent non-urgent updates (startTransition) to preserve responsiveness (scroll tracking, large filtering).
Forms: keep inputs hydration-safe (no lost focus/value). Never block paste in<input>/<textarea>. Loading buttons show spinner and...
Files:
src/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
**/*.tsx
📄 CodeRabbit inference engine (Custom checks)
Parallelize server data fetches with component composition: split independent async server components so they can run concurrently. Avoid "parent awaits, child awaits" chains.
Files:
src/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
**/*.{css,tsx,jsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{css,tsx,jsx}: Honorprefers-reduced-motionin animations (provide reduced variant or disable).
Prefer CSS > Web Animations API > JS libraries for animations.
Animate only compositor-friendly props (transform,opacity). Never animate layout props (top,left,width,height).
Animate only to clarify cause/effect or add deliberate delight. Animations must be interruptible and input-driven (no autoplay).
Use optical alignment; adjust ±1px when perception beats geometry.
Ensure deliberate alignment to grid/baseline/edges – no accidental placement. Verify mobile, laptop, ultra-wide (simulate ultra-wide at 50% zoom).
Balance icon/text lockups (weight/size/spacing/color). Respect safe areas (env(safe-area-inset-*)). Avoid unwanted scrollbars; fix overflows.
Prefer Flex/Grid over JS measurement for layout.
Full keyboard support per WAI-ARIA APG. Must have visible focus rings (:focus-visible; group with:focus-within). Manage focus (trap, move, return) per APG patterns. Never useoutline: nonewithout visible focus replacement.
Hit target ≥24px (mobile ≥44px); if visual <24px, expand hit area. Mobile<input>font-size ≥16px to prevent iOS zoom. Never disable browser zoom. Usetouch-action: manipulationto prevent double-tap zoom. Set-webkit-tap-highlight-colorto match design.
Touch & Drag: generous targets, clear affordances; avoid finicky interactions. Delay first tooltip; subsequent peers instant. Useoverscroll-behavior: containin modals/drawers. During drag, disable text selection and setinerton dragged elements. If it looks clickable, it must be clickable.
Use curly quotes (" "); avoid widows/orphans (text-wrap: balance). Usefont-variant-numeric: tabular-numsfor number comparisons. Redundant status cues (not color-only); icons have text labels.
Text containers handle long content (truncate,line-clamp-*,break-words). Flex children needmin-w-0to allow truncation. Handle empty states – no broken UI for empty stri...
Files:
src/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
**/*.{css,tsx,jsx,svg}
📄 CodeRabbit inference engine (Custom checks)
Set correct
transform-originfor animations (motion starts where it "physically" should). For SVG transforms, use<g>wrapper withtransform-box: fill-box.
Files:
src/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
**/*.{tsx,jsx,css}
📄 CodeRabbit inference engine (Custom checks)
**/*.{tsx,jsx,css}: Forms: accept free text, validate after – don't block typing. Allow incomplete form submission to surface validation. Errors inline next to fields; on submit, focus first error. Useautocomplete+ meaningfulname; correcttypeandinputmode.
Inline help first; tooltips last resort. Skeletons mirror final content to avoid layout shift.<title>matches current context. No dead ends; always offer next step/recovery. Design empty/sparse/dense/error states.
For dark themes, usecolor-scheme: darkon<html>. Set<meta name="theme-color">to match page background. For native<select>: explicitbackground-colorandcolor(Windows fix).
Files:
src/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Code must pass bun run test clean (Vitest)
Files:
src/lib/sandbox/sandbox-runner.server.test.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/workflows/runs/workflow-errors.test.tssrc/workflows/code-mode/steps/writer.step.test.tssrc/workflows/code-mode/steps/code-mode.step.test.tssrc/workflows/chat/hooks/chat-message.test.tssrc/workflows/runs/steps/writer.step.test.tssrc/lib/sandbox/network-policy.server.test.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/app/api/approvals/__tests__/route.test.tssrc/workflows/chat/steps/writer.step.test.tssrc/lib/runs/code-mode-stream.test.ts
🧠 Learnings (2)
📚 Learning: 2026-02-04T07:05:13.147Z
Learnt from: BjornMelin
Repo: BjornMelin/ai-agent-builder PR: 13
File: next.config.ts:5-21
Timestamp: 2026-02-04T07:05:13.147Z
Learning: This repository now uses the unified radix-ui package. Ensure that all new and existing components import from 'radix-ui' directly and do not use any 'radix-ui/react-*' import paths. Configure optimizePackageImports to include only 'radix-ui' to limit bundle size and ensure correct subpackage resolution. Apply this guideline across all TypeScript files in the project.
Applied to files:
src/app/api/chat/[runId]/route.tssrc/app/api/approvals/route.tssrc/workflows/chat/hooks/chat-message.tssrc/workflows/_shared/workflow-runtime.server.tssrc/app/api/chat/[runId]/stream/route.tssrc/workflows/runs/project-run.workflow.tssrc/app/api/chat/route.tssrc/lib/sandbox/sandbox-runner.server.test.tssrc/app/api/code-mode/[runId]/stream/route.tssrc/app/api/runs/[runId]/stream/route.tssrc/workflows/code-mode/steps/writer.step.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/workflows/runs/workflow-errors.test.tssrc/lib/runs/code-mode.server.tssrc/workflows/code-mode/steps/writer.step.test.tssrc/workflows/_shared/workflow-stream-events.tssrc/workflows/code-mode/steps/code-mode.step.test.tssrc/workflows/code-mode/steps/code-mode.step.tssrc/lib/runs/project-run.server.tssrc/workflows/chat/hooks/chat-message.test.tssrc/app/api/skills/registry/status/route.tssrc/app/api/chat/[runId]/cancel/route.tssrc/workflows/runs/steps/writer.step.test.tssrc/workflows/runs/steps/writer.step.tssrc/lib/sandbox/network-policy.server.test.tsnext.config.tssrc/workflows/runs/workflow-errors.tssrc/app/api/skills/registry/install/route.tssrc/workflows/chat/steps/writer.step.tssrc/app/api/approvals/__tests__/route.test.tssrc/workflows/chat/steps/writer.step.test.tssrc/workflows/approvals/hooks/approval.tssrc/lib/sandbox/network-policy.server.tssrc/lib/runs/code-mode-stream.test.ts
📚 Learning: 2026-02-04T07:05:13.147Z
Learnt from: BjornMelin
Repo: BjornMelin/ai-agent-builder PR: 13
File: next.config.ts:5-21
Timestamp: 2026-02-04T07:05:13.147Z
Learning: Standardize Radix UI imports by using the top-level 'radix-ui' package instead of scoped imports like 'radix-ui/react-use-controllable-state'. In reviews, flag and update any files that import from 'radix-ui/*' and replace with the corresponding import from 'radix-ui'. This improves consistency and reduces potential version drift.
Applied to files:
src/app/api/chat/[runId]/route.tssrc/app/api/approvals/route.tssrc/workflows/chat/hooks/chat-message.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxsrc/workflows/_shared/workflow-runtime.server.tssrc/app/api/chat/[runId]/stream/route.tssrc/workflows/runs/project-run.workflow.tssrc/app/api/chat/route.tssrc/lib/sandbox/sandbox-runner.server.test.tssrc/app/api/code-mode/[runId]/stream/route.tssrc/app/api/runs/[runId]/stream/route.tssrc/workflows/code-mode/steps/writer.step.tssrc/app/api/chat/[runId]/__tests__/route.test.tssrc/workflows/runs/workflow-errors.test.tssrc/lib/runs/code-mode.server.tssrc/workflows/code-mode/steps/writer.step.test.tssrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/workflows/_shared/workflow-stream-events.tssrc/workflows/code-mode/steps/code-mode.step.test.tssrc/workflows/code-mode/steps/code-mode.step.tssrc/lib/runs/project-run.server.tssrc/workflows/chat/hooks/chat-message.test.tssrc/app/api/skills/registry/status/route.tssrc/app/api/chat/[runId]/cancel/route.tssrc/workflows/runs/steps/writer.step.test.tssrc/workflows/runs/steps/writer.step.tssrc/lib/sandbox/network-policy.server.test.tsnext.config.tssrc/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxsrc/workflows/runs/workflow-errors.tssrc/app/api/skills/registry/install/route.tssrc/workflows/chat/steps/writer.step.tssrc/app/api/approvals/__tests__/route.test.tssrc/workflows/chat/steps/writer.step.test.tssrc/workflows/approvals/hooks/approval.tssrc/lib/sandbox/network-policy.server.tssrc/lib/runs/code-mode-stream.test.tssrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
🧬 Code graph analysis (7)
src/workflows/runs/project-run.workflow.ts (1)
src/workflows/_shared/workflow-stream-events.ts (1)
RunStreamEventInput(165-165)
src/workflows/code-mode/steps/writer.step.ts (1)
src/workflows/_shared/workflow-stream-events.ts (2)
CodeModeStreamEventInput(169-169)createCodeModeStreamEvent(209-217)
src/workflows/code-mode/steps/code-mode.step.test.ts (1)
src/workflows/_shared/workflow-stream-events.ts (1)
CodeModeStreamEvent(156-156)
src/workflows/code-mode/steps/code-mode.step.ts (1)
src/workflows/_shared/workflow-stream-events.ts (2)
CodeModeStreamEventInput(169-169)createCodeModeStreamEvent(209-217)
src/workflows/runs/steps/writer.step.ts (1)
src/workflows/_shared/workflow-stream-events.ts (2)
RunStreamEventInput(165-165)createRunStreamEvent(177-185)
src/lib/sandbox/network-policy.server.test.ts (1)
src/lib/sandbox/network-policy.server.ts (3)
SANDBOX_NETWORK_POLICY_NONE(5-5)SANDBOX_NETWORK_POLICY_RESTRICTED_DEFAULT(7-18)SANDBOX_NETWORK_POLICY_RESTRICTED_PYTHON_DEFAULT(20-31)
src/workflows/chat/steps/writer.step.ts (1)
src/workflows/_shared/workflow-stream-events.ts (1)
createChatUserMessageMarker(193-201)
🔍 Remote MCP Firecrawl
Based on the information gathered from my tool searches, I can now provide a comprehensive review context:
Gathered Context Summary
1. Turbopack FileSystem Cache Configuration(#)
The turbopackFileSystemCacheForBuild flag is currently experimental for production builds, though it is enabled by default for development in Next.js 16.1.0. The PR sets this to false, which is actually the default value in Next.js. This is a deliberate choice that contradicts the example documentation, suggesting this PR either:
- Disables the experimental feature intentionally for stability reasons
- Or documents that it should remain off during builds
This warrants clarification in comments about the rationale for disabling it explicitly when it's already the default.
2. Bun Build Reliability and Transient Failures ::Firecrawl_firecrawl_search::
The search results confirm that Bun build failures with Next.js projects are documented issues, validating the PR's approach of implementing a fallback mechanism. The scripts/build-next.sh script with its "transient failure detection → retry → Node fallback" pattern aligns with industry best practices for handling build tool instability.
3. Event Schema Versioning Pattern ::Firecrawl_firecrawl_scrape::
Adding version metadata to events and domain identifiers is a recognized pattern in event-driven architecture for managing schema evolution without breaking changes. The PR's addition of domain and version fields to workflow stream events follows standard practices. However, the pattern typically requires:
- Consumer code to gracefully handle both versioned and unversioned events during transition
- Documentation of the migration path for old event consumers
4. Dependency Upgrade Status ::gh_grep_searchGitHub::
The PR upgrades @ai-sdk/react from ^3.0.79 to ^3.0.88, which aligns with real-world usage patterns in the Vercel AI ecosystem (examples show versions 3.0.81-3.0.84 in production).
Key Findings for Code Review
-
Build Strategy: The Bun-first fallback approach with transient error detection is technically sound and addresses known Bun/Turbopack instability.
-
Event Schema Migration: The addition of
domainandversionfields follows established event versioning patterns, but consumers must be verified to handle the envelope fields correctly. -
Configuration Change: The explicit
turbopackFileSystemCacheForBuild: falseshould be documented with the reason (e.g., "disabled to avoid build cache corruption with Bun"). -
Sandbox Policy Changes: The refactoring of
SANDBOX_NETWORK_POLICY_NONEfrom{ type: "no-access" }to"deny-all"is a breaking change that requires verification that all consumers (tests, integrations) handle the string type correctly. -
Import Consolidation: The new
src/workflows/_shared/workflow-runtime.server.tsprovides a clean canonical import boundary for server-only workflow functions, improving maintainability.
⏰ Context from checks skipped due to timeout of 30000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Agent
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/`(app)/projects/[projectId]/chat/chat-client.tsx:
- Around line 95-103: The UserMessageMarker type and its runtime checks
currently require domain==="chat" and version===2, which drops legacy markers;
relax the validation to accept markers that lack domain/version during migration
by: update the runtime guard(s) that consume UserMessageMarker to treat objects
with the expected shape (id, content, type==="user-message", timestamp, optional
files) as valid even if domain or version is missing, while still
preferring/handling version===2 when present; apply the same relaxed-check
change to the other marker/type validation near the second marker definition so
older threads resume correctly; keep strict checks when you detect a persisted
schema version indicating only v2 markers should be allowed.
---
Outside diff comments:
In `@src/app/`(app)/projects/[projectId]/code-mode/code-mode-client.tsx:
- Around line 200-206: The current cleanup only removes the v2 key
(`workflow:code-mode:v2:${parsedRunId}:startIndex`) but doesn't clear stale v1
keys; update the component (e.g., in the same mount logic or useEffect around
where window.sessionStorage.removeItem is called in code-mode-client.tsx) to
also enumerate sessionStorage keys inside a try/catch and remove any key that
startsWith "workflow:code-mode:v1:" (collect keys first then remove to avoid
iteration issues); apply the same migration/cleanup logic where the other v2
removal occurs (the other occurrence around line 217) so v1 keys are cleared
consistently.
In `@src/app/`(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsx:
- Around line 99-116: The v2 storageKey
(`workflow:runs:v2:${props.runId}:startIndex`) ignores any legacy v1 key and
drops resume position; update the startup logic around readStartIndex/storageKey
to detect the legacy key (e.g., `workflow:runs:${props.runId}:startIndex`), wrap
storage reads/writes in try/catch, migrate the legacy value into the v2 key (or
clear it) on first read, and then proceed using readStartIndex; modify or add a
small migration helper called from the effect (referencing storageKey and
readStartIndex) to perform the copy+delete (or clear) and ensure only
minimal/versioned data is stored.
In `@src/app/api/skills/registry/install/route.ts`:
- Line 71: The current best-effort cleanup call await cancelRun(world,
run.runId).catch(() => undefined) swallows errors silently; change the catch to
log the error (e.g., .catch(err => { /* use existing logger or console.error */
logger?.error ? logger.error({ err, world, runId: run.runId }, "cancelRun
failed") : console.error("cancelRun failed", { err, world, runId: run.runId });
})) so the error is recorded for observability while still suppressing it from
bubbling; reference cancelRun(world, run.runId), world and run.runId when adding
the log message.
In `@src/lib/sandbox/network-policy.server.ts`:
- Around line 5-31: Add immediately preceding TSDoc comments for each exported
constant (SANDBOX_NETWORK_POLICY_NONE,
SANDBOX_NETWORK_POLICY_RESTRICTED_DEFAULT,
SANDBOX_NETWORK_POLICY_RESTRICTED_PYTHON_DEFAULT) with no blank line between
comment and export; the TSDoc should briefly describe the purpose of the
constant (e.g., deny-all default policy, restricted npm/JS policy, restricted
Python/pip policy) and any noteworthy details (allowed hosts). Ensure each
exported declaration has its own /** ... */ block directly above it to satisfy
the lint/typecheck rule.
In `@src/workflows/approvals/hooks/approval.ts`:
- Line 15: Add a TSDoc comment immediately above the exported type
ApprovalResumePayload describing what the payload represents and its relation to
approvalResumeSchema (e.g., "Payload for resuming an approval flow, inferred
from approvalResumeSchema"). Ensure the comment is a proper /** ... */ block
placed directly before the line exporting ApprovalResumePayload so it satisfies
the exported-declaration documentation rule and references approvalResumeSchema
for context.
|
Resolved threads: 5 | Files: .github/workflows/ci.yml, package.json, docs/ops/build-runtime.md, next.config.ts, src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx, src/app/(app)/projects/[projectId]/chat/chat-client.tsx | Tests: bun run format, bun run lint, bun run typecheck, bun run test, bun run build | Notes: CI action pins fixed; strict-Bun logs now upload with always(); legacy stream/marker compatibility restored; Bun-only script path maintained with stable webpack build mode. |
There was a problem hiding this comment.
Actionable comments posted: 5
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (6)
.github/workflows/ci.ymldocs/ops/build-runtime.mdnext.config.tspackage.jsonsrc/app/(app)/projects/[projectId]/chat/chat-client.tsxsrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{js,jsx,ts,tsx}: No promise-valued statement may be left unhandled. A Promise is handled ONLY if it isawaited,returned, terminated with.catch(...), terminated with.then(onFulfilled, onRejected)(rejection handler required), or explicitly ignored withvoidAND meets additional requirements.
For files importing or referencing AI SDK / Vercel AI modules (ai,@ai-sdk/*,@vercel/ai,openai,@openai/*), fire-and-forget is forbidden by default. If usingvoid someAsyncCall(...), it MUST include an inline comment explaining why detaching is safe AND errors must be surfaced via.catch(...)or a dedicated error sink (logging/telemetry).
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsxnext.config.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{ts,tsx,js,jsx}: Hard FAIL if the PR introduces any test-only helpers, shims, mocks, or conditional branches intended only for tests in production source files. All test scaffolding must live in test suites and test configuration (Vitest and/or Playwright).
Doc comment formatting must satisfy Biome, including violations ofuseSingleJsDocAsterisk. Hard FAIL if Biome reports any issue with JSDoc/TSDoc formatting.
The first non-empty line inside a doc comment MUST be a single-sentence summary ending with a period.. The summary must describe behavior and intent, not just the symbol name. Hard FAIL if any condition is violated.
Only these tags are allowed in doc comments:@remarks,@param,@typeParam,@returns,@throws,@example,@see,@deprecated. Hard FAIL if any other@tagappears.
Doc comment tags must appear in this strict order (skip unused):@remarks, all@typeParam, all@param,@returns, all@throws, all@example, all@see,@deprecated. Hard FAIL if tags are out of order.
@remarksmust be separated from the summary by a blank line and must have non-empty content. Hard FAIL if present but empty or not separated by a blank line.
For every exported function (including route handlers), document EVERY parameter with@param. Each@paramline MUST match the exact pattern:@param <name> - <description>where<name>matches an actual parameter name, the literal separator-is present, and<description>is non-empty and explains semantics and constraints. JSDoc type braces are forbidden in TS/TSX. Hard FAIL if violations exist.
@returnsis required for every exported function whose return type is notvoidand notPromise<void>, and for all Next.js route handlers. It must have non-empty semantic description. JSDoc type braces are forbidden in TS/TSX. Hard FAIL if required but missing, empty, or typed via braces.
If an exported function body contains the tokenthrowin newly added or modified lines, at lea...
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsxnext.config.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{ts,tsx}: Every changed or added exported declaration (export function, export async function, export const, export class, export interface, export type, export enum, Next.js route handlers, re-exports) MUST have an immediately preceding doc comment/** ... */with no blank line separating it. Hard FAIL if any required export lacks a doc comment.
If an exported function/type/class introduces generic type parameters AND they are not self-explanatory, require@typeParamper generic parameter following the pattern:@typeParam <name> - <description>. Hard FAIL if required generics are undocumented, or if@typeParamdoes not follow the hyphen pattern, or is empty.
In TS/TSX doc comments, these tags are forbidden:@type,@typedef,@property,@template,@enum,@memberof. Hard FAIL if any appear.
Server Actions are public endpoints. Inside every Server Action: validate input, authenticate, authorize. Never rely only on middleware/layout guards.
Minimize RSC→client serialization: pass only fields the client uses. Avoid sending multiple derived copies of large primitive arrays; derive in client unless the server compute is expensive or the client must not see the raw data.
Avoid duplicate serialization by reference: transformations liketoSorted(),filter(),map(), spreads create new references. Prefer passing one reference across the RSC/client boundary.
Usereactcache()for per-request deduplication of DB/auth/heavy compute within a single request. Avoid inline object args (cache hits require stable identity). Note: Next.jsfetchis already memoized per request.
Use Next.jsafter()for non-blocking work (logging, analytics, notifications, cleanup). Do not block responses on side effects.
**/*.{ts,tsx}: Enforce strict TypeScript with no use of 'any' type
Code must pass bun run typecheck clean (TypeScript compiler)
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsxnext.config.ts
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{tsx,jsx}: Pure presentational React components exported only for JSX composition may omit doc comments ONLY if they have no non-obvious behavior (no IO, no side effects, no caching semantics, no security checks, no data fetching, no tool calls). If in doubt, require doc comment.
Defer non-critical third-party code (analytics, error tracking) until after hydration:next/dynamic(..., { ssr:false })or client-only boundary.
Dynamically import heavy components not needed for initial paint (editors, charts, maps). Usessr:falsewhen they require the DOM.
Preload based on user intent (hover/focus) or feature flags to reduce perceived latency. Preload should be optional and non-blocking.
Prefer SWR (or an equivalent) for client fetching to get caching, deduplication, revalidation, and mutation helpers.
Deduplicate global event listeners. Avoid "N components = N listeners" patterns; centralize subscriptions and fan out callbacks.
Do not subscribe to reactive sources you only need in callbacks (e.g., search params). Read at the point of use when possible.
Put early returns before expensive computations. If needed, extract expensive work into memoized components so "loading" paths skip the work.
Narrow effect dependencies: depend on primitives and derived booleans, not entire objects.
Subscribe to derived state rather than continuous signals (use media queries instead of window width pixels when only a breakpoint matters).
Use functional state updates when new state depends on previous state (setX(curr => ...)). This prevents stale closures and stabilizes callbacks.
Use lazy state initialization for expensive initial values (useState(() => expensive())), especially storage parsing or index building.
Use transitions for frequent non-urgent updates (startTransition) to preserve responsiveness (scroll tracking, large filtering).
Forms: keep inputs hydration-safe (no lost focus/value). Never block paste in<input>/<textarea>. Loading buttons show spinner and...
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
**/*.tsx
📄 CodeRabbit inference engine (Custom checks)
Parallelize server data fetches with component composition: split independent async server components so they can run concurrently. Avoid "parent awaits, child awaits" chains.
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
**/*.{css,tsx,jsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{css,tsx,jsx}: Honorprefers-reduced-motionin animations (provide reduced variant or disable).
Prefer CSS > Web Animations API > JS libraries for animations.
Animate only compositor-friendly props (transform,opacity). Never animate layout props (top,left,width,height).
Animate only to clarify cause/effect or add deliberate delight. Animations must be interruptible and input-driven (no autoplay).
Use optical alignment; adjust ±1px when perception beats geometry.
Ensure deliberate alignment to grid/baseline/edges – no accidental placement. Verify mobile, laptop, ultra-wide (simulate ultra-wide at 50% zoom).
Balance icon/text lockups (weight/size/spacing/color). Respect safe areas (env(safe-area-inset-*)). Avoid unwanted scrollbars; fix overflows.
Prefer Flex/Grid over JS measurement for layout.
Full keyboard support per WAI-ARIA APG. Must have visible focus rings (:focus-visible; group with:focus-within). Manage focus (trap, move, return) per APG patterns. Never useoutline: nonewithout visible focus replacement.
Hit target ≥24px (mobile ≥44px); if visual <24px, expand hit area. Mobile<input>font-size ≥16px to prevent iOS zoom. Never disable browser zoom. Usetouch-action: manipulationto prevent double-tap zoom. Set-webkit-tap-highlight-colorto match design.
Touch & Drag: generous targets, clear affordances; avoid finicky interactions. Delay first tooltip; subsequent peers instant. Useoverscroll-behavior: containin modals/drawers. During drag, disable text selection and setinerton dragged elements. If it looks clickable, it must be clickable.
Use curly quotes (" "); avoid widows/orphans (text-wrap: balance). Usefont-variant-numeric: tabular-numsfor number comparisons. Redundant status cues (not color-only); icons have text labels.
Text containers handle long content (truncate,line-clamp-*,break-words). Flex children needmin-w-0to allow truncation. Handle empty states – no broken UI for empty stri...
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
**/*.{css,tsx,jsx,svg}
📄 CodeRabbit inference engine (Custom checks)
Set correct
transform-originfor animations (motion starts where it "physically" should). For SVG transforms, use<g>wrapper withtransform-box: fill-box.
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
**/*.{tsx,jsx,css}
📄 CodeRabbit inference engine (Custom checks)
**/*.{tsx,jsx,css}: Forms: accept free text, validate after – don't block typing. Allow incomplete form submission to surface validation. Errors inline next to fields; on submit, focus first error. Useautocomplete+ meaningfulname; correcttypeandinputmode.
Inline help first; tooltips last resort. Skeletons mirror final content to avoid layout shift.<title>matches current context. No dead ends; always offer next step/recovery. Design empty/sparse/dense/error states.
For dark themes, usecolor-scheme: darkon<html>. Set<meta name="theme-color">to match page background. For native<select>: explicitbackground-colorandcolor(Windows fix).
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
src/app/**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use Next.js App Router patterns only (no Pages Router)
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
src/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Enable Cache Components with 'use cache' directive and use cacheTag/revalidateTag for stable server reads
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use memoization (useMemo, useCallback, React.memo) only for expensive computations or to prevent costly re-renders; avoid memo for simple primitives/cheap work; hoist stable non-primitive defaults
Provide TSDoc documentation for all exported APIs
Use Neon Auth only (@neondatabase/auth) for authentication
Prefer AI SDK's gateway(...) / createGateway(...) provider for model routing
Use AI SDK Gateway provider base URL https://ai-gateway.vercel.sh/v3/ai (default; configurable via AI_GATEWAY_BASE_URL)
Use OpenAI-compatible base URL https://ai-gateway.vercel.sh/v1 for OpenAI SDK compatibility and GET /models
Public/exported APIs must have valid TSDoc documentation
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx,js,jsx}: Do not use package barrel imports by default; use explicit imports
Use barrel imports only for packages listed in next.config.ts experimental.optimizePackageImports (currently radix-ui and lucide-react)
Code must pass bun run format with no changes
Code must pass bun run lint clean (Biome + ESLint for TSDoc syntax and JSDoc on exported APIs)
No console spam in production paths
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsx
🧠 Learnings (26)
📓 Common learnings
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Use Bun toolchain for installs, scripts, and CI; run Vercel Functions on Bun runtime where supported (IR-010).
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Enforce CI quality gates with Bun-only commands for format, lint, typecheck, test, and build (NFR-010).
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Applies to src/workflows/**/*.{ts,tsx} : Place workflow-only shared helpers in src/workflows/_shared/ instead of src/lib/; avoid index.ts re-export facades and import concrete modules directly
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Applies to src/workflows/**/*.{ts,tsx} : Place workflow-only shared helpers in src/workflows/_shared/ instead of src/lib/; avoid index.ts re-export facades and import concrete modules directly
Applied to files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxpackage.jsonnext.config.ts
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Ensure runs and interactive chat streams resume after client disconnects/timeouts and continue to completion (PR-004).
Applied to files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
📚 Learning: 2026-02-04T07:05:13.147Z
Learnt from: BjornMelin
Repo: BjornMelin/ai-agent-builder PR: 13
File: next.config.ts:5-21
Timestamp: 2026-02-04T07:05:13.147Z
Learning: Standardize Radix UI imports by using the top-level 'radix-ui' package instead of scoped imports like 'radix-ui/react-use-controllable-state'. In reviews, flag and update any files that import from 'radix-ui/*' and replace with the corresponding import from 'radix-ui'. This improves consistency and reduces potential version drift.
Applied to files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxsrc/app/(app)/projects/[projectId]/chat/chat-client.tsxnext.config.ts
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Use Bun toolchain for installs, scripts, and CI; run Vercel Functions on Bun runtime where supported (IR-010).
Applied to files:
docs/ops/build-runtime.md.github/workflows/ci.ymlpackage.json
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Use Bun only for installs and scripts (not npm/yarn/pnpm)
Applied to files:
docs/ops/build-runtime.mdpackage.json
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Enforce CI quality gates with Bun-only commands for format, lint, typecheck, test, and build (NFR-010).
Applied to files:
docs/ops/build-runtime.md.github/workflows/ci.ymlpackage.json
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Code must pass bun run build clean
Applied to files:
docs/ops/build-runtime.md.github/workflows/ci.ymlpackage.json
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Run all command execution touching untrusted inputs or code in Vercel Sandbox; keep app runtime minimal (NFR-014).
Applied to files:
docs/ops/build-runtime.md
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Implement durable Implementation Run workflow for structured plan → code → verify → deploy execution using Vercel Workflow DevKit (FR-023).
Applied to files:
docs/ops/build-runtime.md
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Enforce default-deny command allowlists in sandbox execution, confine workspace path to `/vercel/sandbox`, and restrict package-exec tools (npx, bunx) to explicit allowlist (NFR-016).
Applied to files:
docs/ops/build-runtime.md
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Applies to src/app/api/chat/**/*.{ts,tsx} : Follow-ups during active durable chat sessions must use POST /api/chat/:runId accepting optional files alongside message (messageId required)
Applied to files:
src/app/(app)/projects/[projectId]/chat/chat-client.tsx
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Applies to src/app/api/upload/**/*.{ts,tsx} : Project chat attachments must support document uploads (PDF/DOCX/PPTX/XLSX/TXT/MD) via POST /api/upload with maxFileSize = budgets.maxUploadBytes (default 25 MB) and maxFiles = 5 per message
Applied to files:
src/app/(app)/projects/[projectId]/chat/chat-client.tsx
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx} : Code must pass bun run format with no changes
Applied to files:
.github/workflows/ci.ymlpackage.json
📚 Learning: 2026-01-30T23:33:55.730Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-01-30T23:33:55.730Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Hard FAIL if the PR introduces any test-only helpers, shims, mocks, or conditional branches intended only for tests in production source files. All test scaffolding must live in test suites and test configuration (Vitest and/or Playwright).
Applied to files:
package.json
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Optimize repository conventions for AI coding agents: include AGENTS.md documentation, maintain strict doc requirements, and use deterministic scripts (NFR-011).
Applied to files:
package.json
📚 Learning: 2026-01-30T23:33:55.730Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-01-30T23:33:55.730Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : For files importing or referencing AI SDK / Vercel AI modules (`ai`, `ai-sdk/*`, `vercel/ai`, `openai`, `openai/*`), fire-and-forget is forbidden by default. If using `void someAsyncCall(...)`, it MUST include an inline comment explaining why detaching is safe AND errors must be surfaced via `.catch(...)` or a dedicated error sink (logging/telemetry).
Applied to files:
package.json
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx} : Use barrel imports only for packages listed in next.config.ts experimental.optimizePackageImports (currently radix-ui and lucide-react)
Applied to files:
next.config.ts
📚 Learning: 2026-01-30T23:33:55.731Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-01-30T23:33:55.731Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Avoid barrel imports from large libs (icons, UI kits, utilities) in React/Next.js. Prefer direct subpath imports or configure `experimental.optimizePackageImports` when supported.
Applied to files:
next.config.ts
📚 Learning: 2026-01-30T23:33:55.730Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-01-30T23:33:55.730Z
Learning: Applies to **/*.{ts,tsx} : Every changed or added exported declaration (export function, export async function, export const, export class, export interface, export type, export enum, Next.js route handlers, re-exports) MUST have an immediately preceding doc comment `/** ... */` with no blank line separating it. Hard FAIL if any required export lacks a doc comment.
Applied to files:
next.config.ts
📚 Learning: 2026-01-30T23:33:55.731Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-01-30T23:33:55.731Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Eliminate waterfalls in React/Next.js: defer `await` until the branch that truly needs it; use early returns to skip expensive work. Start independent async work immediately, then await later. Use `Promise.all()` for independent operations. Maximize overlap for dependency graphs.
Applied to files:
next.config.ts
📚 Learning: 2026-01-30T23:33:55.731Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-01-30T23:33:55.731Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use conditional module loading: only `import()` big modules or data when a feature is enabled. Guard browser-only loads (`typeof window !== 'undefined'`) to avoid server bundle bloat in Next.js.
Applied to files:
next.config.ts
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Applies to src/app/**/* : Use Next.js App Router patterns only (no Pages Router)
Applied to files:
next.config.ts
📚 Learning: 2026-01-30T23:33:55.731Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-01-30T23:33:55.731Z
Learning: Applies to **/*.{ts,tsx} : Use Next.js `after()` for non-blocking work (logging, analytics, notifications, cleanup). Do not block responses on side effects.
Applied to files:
next.config.ts
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx} : No console spam in production paths
Applied to files:
next.config.ts
📚 Learning: 2026-02-04T07:05:13.147Z
Learnt from: BjornMelin
Repo: BjornMelin/ai-agent-builder PR: 13
File: next.config.ts:5-21
Timestamp: 2026-02-04T07:05:13.147Z
Learning: This repository now uses the unified radix-ui package. Ensure that all new and existing components import from 'radix-ui' directly and do not use any 'radix-ui/react-*' import paths. Configure optimizePackageImports to include only 'radix-ui' to limit bundle size and ensure correct subpackage resolution. Apply this guideline across all TypeScript files in the project.
Applied to files:
next.config.ts
🔍 Remote MCP Firecrawl
Additional review context (concise)
-
Next.js Turbopack filesystem cache behavior
- Turbopack filesystem caching is enabled by default for dev but is opt-in/experimental for production builds; the config keys are experimental.turbopackFileSystemCacheForDev and experimental.turbopackFileSystemCacheForBuild (the latter must be enabled explicitly). Source: Next.js docs (Turbopack / turbopackFileSystemCache).
-
Using Webpack vs Turbopack for production builds
- Next.js documents that you can opt out of Turbopack and use Webpack for builds by passing the --webpack flag (e.g., next build --webpack). This validates the PR's approach of offering a --webpack fallback in build scripts. Source: Next.js Turbopack docs (usage / --webpack).
-
Bun + Next.js / Turbopack build instability is a known practical issue
- Community issues and discussions indicate Bun can trigger intermittent build failures with Next.js/Turbopack (examples: GitHub issues and Vercel community threads). This supports the PR’s retry + Node fallback strategy and the non-blocking Bun-only CI canary. Sources: GitHub and Vercel community threads (example issues/discussions) found via Firecrawl search,,.
Citations:
- Next.js Turbopack docs / turbopackFileSystemCache (experimental flag details) — Firecrawl_firecrawl_search: https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopackFileSystemCache
- Next.js Turbopack overview / --webpack note — Firecrawl_firecrawl_search: https://nextjs.org/docs/app/api-reference/turbopack
- Community reports of Bun + Next.js/Turbopack build problems — Firecrawl_firecrawl_search results (GitHub issues / Vercel community),,.
⏰ Context from checks skipped due to timeout of 30000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build (Next.js, Bun Strict Canary)
- GitHub Check: Build (Next.js)
🔇 Additional comments (10)
src/app/(app)/projects/[projectId]/chat/chat-client.tsx (1)
95-103: LGTM! Backward compatibility for pre-v2 markers is correctly implemented.The
UserMessageMarkertype now makesdomainandversionoptional, and theisUserMessageMarkertype guard accepts markers where these fields are either their expected values orundefined. This correctly preserves compatibility with older thread markers when resuming sessions, addressing the backward compatibility concern from the previous review.Also applies to: 146-161
.github/workflows/ci.yml (1)
139-161: LGTM!The non-blocking canary job is well-structured:
continue-on-error: trueensures CI doesn't fail on Bun-specific issues,pipefailcatches pipeline failures, and logs are captured for analysis. This aligns with the Bun-first strategy while maintaining CI reliability. Based on learnings, this satisfies NFR-010 (Bun-only commands for CI gates).docs/ops/build-runtime.md (1)
1-32: LGTM!The documentation clearly establishes the Bun-only build policy with well-organized sections covering goals, entrypoints, CI, and Vercel deployment. This aligns with the project's IR-010 and NFR-010 requirements for Bun toolchain usage. Based on learnings, this supports the Bun-first strategy mandated by project specifications.
next.config.ts (3)
15-17: LGTM!Disabling
turbopackFileSystemCacheForBuildis appropriate given the documented instability of Turbopack filesystem caching for production builds. The inline comment provides clear rationale for revisiting this decision once benchmark data is collected.
45-55: LGTM!The turbopack rules consistently apply the node_modules exclusion across all relevant file extensions. This ensures workflow-related processing is limited to project source files.
56-72: LGTM!The webpack configuration defensively filters out the workflow loader with proper type guards. The nullable chaining (
config.module?.rules) and runtime type checks ensure robustness against varying webpack configurations.package.json (2)
38-94: LGTM!The dependency updates are routine patch/minor version bumps. The use of beta versions for
workflowaligns with the project's adoption of the workflow SDK. Based on learnings, the project uses Bun toolchain which these dependencies support.
126-136: Remove incorrect lodash-es version claim.The lodash-es version
^4.17.23does exist in npm registry (it's the latest stable version). No actionable issues remain with the overrides block as presented — the versions are all valid and the override paths follow standard npm syntax for nested dependency pinning.Likely an incorrect or invalid review comment.
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx (2)
32-52: Schema version/domain alignment looks good.The stricter schema makes event validation explicit and matches the shared stream event versioning.
317-322: Expanded chunk-type acceptance is correct.Accepting both
data-workflowanddata-code-modekeeps compatibility with the shared stream envelope while still validating the inner payload.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/ci.yml:
- Around line 162-168: The artifact upload step named "Upload strict Bun build
logs" is using actions/upload-artifact@v4 while other jobs use
actions/upload-artifact@v6.0.0; update the step that currently references
actions/upload-artifact@v4 to actions/upload-artifact@v6.0.0 (the same version
used in the `test` and `test-merge` jobs) to ensure consistent artifact behavior
across workflows.
- Around line 24-25: The lint job's Checkout step is using actions/checkout@v4
while other jobs use actions/checkout@v6.0.2; update the Checkout step in the
lint job (the step with name "Checkout" and uses "actions/checkout@v4") to use
actions/checkout@v6.0.2 so all jobs use the same checkout action version.
In `@docs/ops/build-runtime.md`:
- Around line 13-16: The two scripts `bun run build` and `bun run
build:strict-bun` both show the same command; update the docs to clarify why
both exist and when to use each by adding a short note after the command list
explaining the intent: indicate that `bun run build` is the general/local build
entry, `bun run build:strict-bun` is the CI/strict-environment (or future
stricter behavior) alias for reproducible builds, and mention any semantic
differences or planned divergence (e.g., stricter flags or environment
enforcement) so readers understand why both scripts are provided.
In `@package.json`:
- Around line 14-15: The package.json defines two scripts, "build" and
"build:strict-bun", that currently run the identical command (`bun --bun next
build --webpack`); either make their intent explicit or differentiate them:
update the "build:strict-bun" or "build" script to the intended different
command (e.g., add stricter flags or CI-specific env vars) or add a clarifying
comment in docs/README describing why both exist and are identical for now;
reference the "build" and "build:strict-bun" script names when making the change
so future maintainers understand the semantic distinction.
In `@src/app/`(app)/projects/[projectId]/code-mode/code-mode-client.tsx:
- Around line 200-203: The code removes the v2 key
`workflow:code-mode:v2:${parsedRunId}:startIndex` without migrating the legacy
key, so resume state is lost; update the logic around parsedRunId/startIndex to
first try reading the v2 sessionStorage key inside a try/catch, if absent
fallback to the legacy key `workflow:code-mode:${parsedRunId}:startIndex`, copy
that value into the v2 key (set it) and then remove the legacy key, and ensure
all sessionStorage get/set/remove uses are wrapped in try/catch; apply the same
migration/fallback for the other occurrence referenced (around lines 217-219)
and use consistent key names so reconnects preserve startIndex.
| "build": "bun --bun next build --webpack", | ||
| "build:strict-bun": "bun --bun next build --webpack", |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Scripts build and build:strict-bun are identical.
Both scripts run the exact same command: bun --bun next build --webpack. If they're intended to serve different purposes (e.g., CI canary vs. standard build), consider differentiating them or adding a comment in the documentation explaining the semantic distinction. If they're intentionally identical for now, this is acceptable but worth noting for future maintainers.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@package.json` around lines 14 - 15, The package.json defines two scripts,
"build" and "build:strict-bun", that currently run the identical command (`bun
--bun next build --webpack`); either make their intent explicit or differentiate
them: update the "build:strict-bun" or "build" script to the intended different
command (e.g., add stricter flags or CI-specific env vars) or add a clarifying
comment in docs/README describing why both exist and are identical for now;
reference the "build" and "build:strict-bun" script names when making the change
so future maintainers understand the semantic distinction.
…test versions; enhance documentation on build commands and add storage migration functions in code-mode-client
There was a problem hiding this comment.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
.github/workflows/ci.ymldocs/ops/build-runtime.mdsrc/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{js,jsx,ts,tsx}: No promise-valued statement may be left unhandled. A Promise is handled ONLY if it isawaited,returned, terminated with.catch(...), terminated with.then(onFulfilled, onRejected)(rejection handler required), or explicitly ignored withvoidAND meets additional requirements.
For files importing or referencing AI SDK / Vercel AI modules (ai,@ai-sdk/*,@vercel/ai,openai,@openai/*), fire-and-forget is forbidden by default. If usingvoid someAsyncCall(...), it MUST include an inline comment explaining why detaching is safe AND errors must be surfaced via.catch(...)or a dedicated error sink (logging/telemetry).
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{ts,tsx,js,jsx}: Hard FAIL if the PR introduces any test-only helpers, shims, mocks, or conditional branches intended only for tests in production source files. All test scaffolding must live in test suites and test configuration (Vitest and/or Playwright).
Doc comment formatting must satisfy Biome, including violations ofuseSingleJsDocAsterisk. Hard FAIL if Biome reports any issue with JSDoc/TSDoc formatting.
The first non-empty line inside a doc comment MUST be a single-sentence summary ending with a period.. The summary must describe behavior and intent, not just the symbol name. Hard FAIL if any condition is violated.
Only these tags are allowed in doc comments:@remarks,@param,@typeParam,@returns,@throws,@example,@see,@deprecated. Hard FAIL if any other@tagappears.
Doc comment tags must appear in this strict order (skip unused):@remarks, all@typeParam, all@param,@returns, all@throws, all@example, all@see,@deprecated. Hard FAIL if tags are out of order.
@remarksmust be separated from the summary by a blank line and must have non-empty content. Hard FAIL if present but empty or not separated by a blank line.
For every exported function (including route handlers), document EVERY parameter with@param. Each@paramline MUST match the exact pattern:@param <name> - <description>where<name>matches an actual parameter name, the literal separator-is present, and<description>is non-empty and explains semantics and constraints. JSDoc type braces are forbidden in TS/TSX. Hard FAIL if violations exist.
@returnsis required for every exported function whose return type is notvoidand notPromise<void>, and for all Next.js route handlers. It must have non-empty semantic description. JSDoc type braces are forbidden in TS/TSX. Hard FAIL if required but missing, empty, or typed via braces.
If an exported function body contains the tokenthrowin newly added or modified lines, at lea...
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{ts,tsx}: Every changed or added exported declaration (export function, export async function, export const, export class, export interface, export type, export enum, Next.js route handlers, re-exports) MUST have an immediately preceding doc comment/** ... */with no blank line separating it. Hard FAIL if any required export lacks a doc comment.
If an exported function/type/class introduces generic type parameters AND they are not self-explanatory, require@typeParamper generic parameter following the pattern:@typeParam <name> - <description>. Hard FAIL if required generics are undocumented, or if@typeParamdoes not follow the hyphen pattern, or is empty.
In TS/TSX doc comments, these tags are forbidden:@type,@typedef,@property,@template,@enum,@memberof. Hard FAIL if any appear.
Server Actions are public endpoints. Inside every Server Action: validate input, authenticate, authorize. Never rely only on middleware/layout guards.
Minimize RSC→client serialization: pass only fields the client uses. Avoid sending multiple derived copies of large primitive arrays; derive in client unless the server compute is expensive or the client must not see the raw data.
Avoid duplicate serialization by reference: transformations liketoSorted(),filter(),map(), spreads create new references. Prefer passing one reference across the RSC/client boundary.
Usereactcache()for per-request deduplication of DB/auth/heavy compute within a single request. Avoid inline object args (cache hits require stable identity). Note: Next.jsfetchis already memoized per request.
Use Next.jsafter()for non-blocking work (logging, analytics, notifications, cleanup). Do not block responses on side effects.
**/*.{ts,tsx}: Enforce strict TypeScript with no use of 'any' type
Code must pass bun run typecheck clean (TypeScript compiler)
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{tsx,jsx}: Pure presentational React components exported only for JSX composition may omit doc comments ONLY if they have no non-obvious behavior (no IO, no side effects, no caching semantics, no security checks, no data fetching, no tool calls). If in doubt, require doc comment.
Defer non-critical third-party code (analytics, error tracking) until after hydration:next/dynamic(..., { ssr:false })or client-only boundary.
Dynamically import heavy components not needed for initial paint (editors, charts, maps). Usessr:falsewhen they require the DOM.
Preload based on user intent (hover/focus) or feature flags to reduce perceived latency. Preload should be optional and non-blocking.
Prefer SWR (or an equivalent) for client fetching to get caching, deduplication, revalidation, and mutation helpers.
Deduplicate global event listeners. Avoid "N components = N listeners" patterns; centralize subscriptions and fan out callbacks.
Do not subscribe to reactive sources you only need in callbacks (e.g., search params). Read at the point of use when possible.
Put early returns before expensive computations. If needed, extract expensive work into memoized components so "loading" paths skip the work.
Narrow effect dependencies: depend on primitives and derived booleans, not entire objects.
Subscribe to derived state rather than continuous signals (use media queries instead of window width pixels when only a breakpoint matters).
Use functional state updates when new state depends on previous state (setX(curr => ...)). This prevents stale closures and stabilizes callbacks.
Use lazy state initialization for expensive initial values (useState(() => expensive())), especially storage parsing or index building.
Use transitions for frequent non-urgent updates (startTransition) to preserve responsiveness (scroll tracking, large filtering).
Forms: keep inputs hydration-safe (no lost focus/value). Never block paste in<input>/<textarea>. Loading buttons show spinner and...
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
**/*.tsx
📄 CodeRabbit inference engine (Custom checks)
Parallelize server data fetches with component composition: split independent async server components so they can run concurrently. Avoid "parent awaits, child awaits" chains.
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
**/*.{css,tsx,jsx}
📄 CodeRabbit inference engine (Custom checks)
**/*.{css,tsx,jsx}: Honorprefers-reduced-motionin animations (provide reduced variant or disable).
Prefer CSS > Web Animations API > JS libraries for animations.
Animate only compositor-friendly props (transform,opacity). Never animate layout props (top,left,width,height).
Animate only to clarify cause/effect or add deliberate delight. Animations must be interruptible and input-driven (no autoplay).
Use optical alignment; adjust ±1px when perception beats geometry.
Ensure deliberate alignment to grid/baseline/edges – no accidental placement. Verify mobile, laptop, ultra-wide (simulate ultra-wide at 50% zoom).
Balance icon/text lockups (weight/size/spacing/color). Respect safe areas (env(safe-area-inset-*)). Avoid unwanted scrollbars; fix overflows.
Prefer Flex/Grid over JS measurement for layout.
Full keyboard support per WAI-ARIA APG. Must have visible focus rings (:focus-visible; group with:focus-within). Manage focus (trap, move, return) per APG patterns. Never useoutline: nonewithout visible focus replacement.
Hit target ≥24px (mobile ≥44px); if visual <24px, expand hit area. Mobile<input>font-size ≥16px to prevent iOS zoom. Never disable browser zoom. Usetouch-action: manipulationto prevent double-tap zoom. Set-webkit-tap-highlight-colorto match design.
Touch & Drag: generous targets, clear affordances; avoid finicky interactions. Delay first tooltip; subsequent peers instant. Useoverscroll-behavior: containin modals/drawers. During drag, disable text selection and setinerton dragged elements. If it looks clickable, it must be clickable.
Use curly quotes (" "); avoid widows/orphans (text-wrap: balance). Usefont-variant-numeric: tabular-numsfor number comparisons. Redundant status cues (not color-only); icons have text labels.
Text containers handle long content (truncate,line-clamp-*,break-words). Flex children needmin-w-0to allow truncation. Handle empty states – no broken UI for empty stri...
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
**/*.{css,tsx,jsx,svg}
📄 CodeRabbit inference engine (Custom checks)
Set correct
transform-originfor animations (motion starts where it "physically" should). For SVG transforms, use<g>wrapper withtransform-box: fill-box.
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
**/*.{tsx,jsx,css}
📄 CodeRabbit inference engine (Custom checks)
**/*.{tsx,jsx,css}: Forms: accept free text, validate after – don't block typing. Allow incomplete form submission to surface validation. Errors inline next to fields; on submit, focus first error. Useautocomplete+ meaningfulname; correcttypeandinputmode.
Inline help first; tooltips last resort. Skeletons mirror final content to avoid layout shift.<title>matches current context. No dead ends; always offer next step/recovery. Design empty/sparse/dense/error states.
For dark themes, usecolor-scheme: darkon<html>. Set<meta name="theme-color">to match page background. For native<select>: explicitbackground-colorandcolor(Windows fix).
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
src/app/**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use Next.js App Router patterns only (no Pages Router)
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
src/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Enable Cache Components with 'use cache' directive and use cacheTag/revalidateTag for stable server reads
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use memoization (useMemo, useCallback, React.memo) only for expensive computations or to prevent costly re-renders; avoid memo for simple primitives/cheap work; hoist stable non-primitive defaults
Provide TSDoc documentation for all exported APIs
Use Neon Auth only (@neondatabase/auth) for authentication
Prefer AI SDK's gateway(...) / createGateway(...) provider for model routing
Use AI SDK Gateway provider base URL https://ai-gateway.vercel.sh/v3/ai (default; configurable via AI_GATEWAY_BASE_URL)
Use OpenAI-compatible base URL https://ai-gateway.vercel.sh/v1 for OpenAI SDK compatibility and GET /models
Public/exported APIs must have valid TSDoc documentation
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx,js,jsx}: Do not use package barrel imports by default; use explicit imports
Use barrel imports only for packages listed in next.config.ts experimental.optimizePackageImports (currently radix-ui and lucide-react)
Code must pass bun run format with no changes
Code must pass bun run lint clean (Biome + ESLint for TSDoc syntax and JSDoc on exported APIs)
No console spam in production paths
Files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Applies to src/workflows/**/*.{ts,tsx} : Place workflow-only shared helpers in src/workflows/_shared/ instead of src/lib/; avoid index.ts re-export facades and import concrete modules directly
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Implement durable, multi-step 'Run' workflows using Vercel Workflow DevKit for interactive runs and Upstash QStash for background jobs, serving as the base pattern for all workflow execution (FR-010, IR-004).
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Use Bun toolchain for installs, scripts, and CI; run Vercel Functions on Bun runtime where supported (IR-010).
Applied to files:
docs/ops/build-runtime.md.github/workflows/ci.yml
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Use Bun only for installs and scripts (not npm/yarn/pnpm)
Applied to files:
docs/ops/build-runtime.md
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Enforce CI quality gates with Bun-only commands for format, lint, typecheck, test, and build (NFR-010).
Applied to files:
docs/ops/build-runtime.md.github/workflows/ci.yml
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Optimize repository conventions for AI coding agents: include AGENTS.md documentation, maintain strict doc requirements, and use deterministic scripts (NFR-011).
Applied to files:
docs/ops/build-runtime.md
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Code must pass bun run build clean
Applied to files:
docs/ops/build-runtime.md.github/workflows/ci.yml
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Run all command execution touching untrusted inputs or code in Vercel Sandbox; keep app runtime minimal (NFR-014).
Applied to files:
docs/ops/build-runtime.md
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Implement durable Implementation Run workflow for structured plan → code → verify → deploy execution using Vercel Workflow DevKit (FR-023).
Applied to files:
docs/ops/build-runtime.md.github/workflows/ci.yml
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Enforce default-deny command allowlists in sandbox execution, confine workspace path to `/vercel/sandbox`, and restrict package-exec tools (npx, bunx) to explicit allowlist (NFR-016).
Applied to files:
docs/ops/build-runtime.md
📚 Learning: 2026-01-30T23:33:55.731Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-01-30T23:33:55.731Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : For localStorage/sessionStorage: version keys, store minimal data, wrap get/set in try/catch, and implement migrations. Never store secrets, tokens, or PII unless explicitly required.
Applied to files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
📚 Learning: 2026-02-11T08:17:14.613Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: docs/specs/requirements.md:0-0
Timestamp: 2026-02-11T08:17:14.613Z
Learning: Ensure runs and interactive chat streams resume after client disconnects/timeouts and continue to completion (PR-004).
Applied to files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
📚 Learning: 2026-02-04T07:05:13.147Z
Learnt from: BjornMelin
Repo: BjornMelin/ai-agent-builder PR: 13
File: next.config.ts:5-21
Timestamp: 2026-02-04T07:05:13.147Z
Learning: Standardize Radix UI imports by using the top-level 'radix-ui' package instead of scoped imports like 'radix-ui/react-use-controllable-state'. In reviews, flag and update any files that import from 'radix-ui/*' and replace with the corresponding import from 'radix-ui'. This improves consistency and reduces potential version drift.
Applied to files:
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx
📚 Learning: 2026-02-11T08:17:44.398Z
Learnt from: CR
Repo: BjornMelin/ai-agent-builder PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-11T08:17:44.398Z
Learning: Applies to src/**/*.{ts,tsx,js,jsx} : Code must pass bun run format with no changes
Applied to files:
.github/workflows/ci.yml
🔍 Remote MCP Firecrawl
Summary of web-sourced facts relevant to this PR (from Next.js docs via Firecrawl):
-
Next.js supports opting out of Turbopack and using Webpack by passing the --webpack flag to next build/dev (docs show examples using next build --webpack).
-
Turbopack’s filesystem cache for production builds is opt-in: experimental.turbopackFileSystemCacheForBuild must be enabled to persist filesystem caching across next build; turbopackFileSystemCacheForDev is enabled by default for dev. (Docs explicitly describe turbopackFileSystemCacheForBuild as opt-in/experimental.)
-
Turbopack configuration exposes a turbopack.rules option (mapping globs like '*.svg' to loaders) and other turbopack options in next.config.js/ts; the PR’s addition of turbopack.rules and disabling turbopackFileSystemCacheForBuild aligns with documented config fields.
Additional note for reviewers: these docs support the PR’s approach to (a) adding --webpack fallbacks in build scripts, (b) adding explicit turbopack.rules entries, and (c) disabling the experimental filesystem cache for builds to avoid cache-related nondeterminism during CI.
⏰ Context from checks skipped due to timeout of 30000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build (Next.js)
- GitHub Check: Build (Next.js, Bun Strict Canary)
🔇 Additional comments (5)
.github/workflows/ci.yml (1)
139-168: Bun strict canary job looks solid.Non-blocking canary build with log capture and artifact upload is well-structured.
docs/ops/build-runtime.md (1)
1-37: Clear and consistent Bun-first policy doc.The build entrypoints and CI/Vercel policy are explained cleanly.
src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsx (3)
32-52: Schema versioning changes look correct.The addition of
domain: z.literal("code-mode")andversion: z.literal(2)aligns with the PR's introduction of domain-based envelopes and schema versioning across workflow stream events. The Zod 4 syntax withz.looseObjectandz.literalis used correctly.
357-362: Backward-compatible chunk type handling.Accepting both
data-workflowanddata-code-modechunk types ensures compatibility during the transition to the new domain-based envelope system while maintaining support for existing event formats.
246-247: Migration and cleanup integration is correct.
- Line 246:
void migrateStartIndexStorage(parsedRunId)performs migration as a side-effect on start, discarding the return value since the actual index is read later.- Lines 257-259: Properly uses v2 storage key and calls migration when connecting to the stream.
- Line 455:
clearStartIndexStorage(currentRunId)cleans up both legacy and v2 keys on completion.The flow ensures migration happens before reading and cleanup happens on successful completion.
Also applies to: 257-259, 455-456
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/app/`(app)/projects/[projectId]/code-mode/code-mode-client.tsx:
- Around line 91-135: There is a duplicate review comment/marker present
([duplicate_comment]) for the storage migration utilities; remove the duplicate
approval marker or consolidate the redundant review comment so only one
approval/comment remains for the changes around getStartIndexStorageKeys,
migrateStartIndexStorage, and clearStartIndexStorage to avoid repeated reviewer
noise.
This pull request introduces a robust and documented Bun-first build policy, refactors build scripts for reliability, upgrades dependencies, and updates several workflow and code conventions to improve maintainability and error handling. The most significant changes focus on the build process, schema versioning, and dependency management.
Build Process Modernization and Policy
docs/ops/build-runtime.md) outlining a Bun-first, deterministic fallback strategy, including details on transient failure handling and CI/Vercel policies.scripts/build-next.shto encapsulate the new build logic: attempts Bun build, retries on known transient errors, and falls back to Node only for specific failure signatures.package.jsonscripts to use the new build entrypoints and fallback logic, includingbuild:next:auto,build:next:bun,build:next:node, andbuild:strict-bun.build-bun-strict) to run strict Bun-only builds and upload logs for canary signal.Dependency and Package Management
overridesinpackage.jsonto ensure consistent versions for critical packages. [1] [2] [3]next.config.tsto improve build reliability pending further benchmarking.Schema and Versioning Updates
domainandversion: 2fields, and updated storage key versioning for session data. (src/app/(app)/projects/[projectId]/chat/chat-client.tsxL96-R102, src/app/(app)/projects/[projectId]/chat/chat-client.tsxR151-R153, src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxR34, src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxR51, src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxL200-R202, src/app/(app)/projects/[projectId]/code-mode/code-mode-client.tsxL215-R217, src/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.tsxL99-R99, src/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxR51-R56, src/app/(app)/projects/[projectId]/runs/[runId]/run-stream-client.test.tsxR97-R102, [1] [2]Codebase and Linting Cleanup
eslint.config.jsfor cleanup. [1] [2]Documentation and Developer Experience
These changes collectively improve build reliability, observability, and developer clarity, while modernizing dependencies and enforcing clearer schema versioning throughout the codebase.