chore: trigger CodeRabbit review - config files & Dockerfiles (7/7)#10
chore: trigger CodeRabbit review - config files & Dockerfiles (7/7)#10Helal-maker wants to merge 1 commit intomainfrom
Conversation
|
Warning Ignoring CodeRabbit configuration file changes. For security, only the configuration from the base branch is applied for open source repositories. WalkthroughThis pull request replaces blank lines with space-only lines or adds trailing whitespace across 15 configuration, build, and source files. No functional code changes, logic modifications, or API alterations are present. Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~1 minute 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@CodeRabbit review , hi I wanna you to review this PR and when finshed output the full agent ai prompt , I mean the agent prompt for my agents like after finding the bugs and errors produce an agent promot for these bugs so my agent can solve them |
🧩 Analysis chain
🏁 Script executed: Length of output: 7093 The diff is pure whitespace — need to read the actual file content to find real issues. 🏁 Script executed: Length of output: 74631
Issues Found🔴 Critical
Commander.js passes positional arguments before the options object. The current handler: .action(async (options: { iac?: boolean }, projectName?: string) => {
await runInitCommand({ projectName, ...options });
})…receives Fix: .action(async (projectName: string | undefined, options: { iac?: boolean }) => {
await runInitCommand({ projectName, ...options });
})🟠 Major1.
Fix: const PUBLIC_COMMANDS = ["login", "logout", "version", "help", "init", "--version", "-v", "--help", "-h", "-V"];2. The Additionally, the cleanup function Fix: useEffect(() => {
let timeoutId: ReturnType<typeof setTimeout> | null = null;
let isCleaned = false;
function connect() {
if (isCleaned) return;
const wsUrl = `${config.url.replace(/^http/, "ws")}/betterbase/ws?project=${config.projectSlug ?? "default"}`;
const ws = new WebSocket(wsUrl);
wsRef.current = ws;
ws.onopen = () => { if (!isCleaned) setWsReady(true); };
ws.onclose = () => {
if (isCleaned) return;
setWsReady(false);
timeoutId = setTimeout(connect, 3_000);
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "ping") ws.send(JSON.stringify({ type: "pong" }));
};
}
connect();
return () => {
isCleaned = true;
if (timeoutId !== null) clearTimeout(timeoutId);
wsRef.current?.close();
};
}, [config.url, config.projectSlug]);3. branch
.argument("[project-root]", "project root directory", process.cwd())
.option("-p, --project-root <path>", ...)
.action(async (options) => { // ← "options" is actually the arg string
const projectRoot = options.projectRoot || process.cwd(); // always cwd()
});Commander passes .action(async (projectRootArg: string, options: { projectRoot?: string }) => {
const projectRoot = projectRootArg || options.projectRoot || process.cwd();
await runBranchCommand([], projectRoot);
})4. fn.command("deploy")
.argument("<name>", "function name")
.option("--sync-env", ...)
.argument("[project-root]", ...)
.action(async (name: string, options: { syncEnv?: boolean; projectRoot?: string }) => {
const projectRoot = options.projectRoot ?? process.cwd(); // always cwd()
});Commander passes .action(async (name: string, projectRootArg: string, options: { syncEnv?: boolean }) => {
const projectRoot = projectRootArg ?? process.cwd();
await runFunctionCommand(["deploy", name, options.syncEnv ? "--sync-env" : ""], projectRoot);
})5. The Fix — builder should use deps: FROM deps AS builder
WORKDIR /app
# deps already installed, just copy source
COPY . .
RUN bun run build6. healthcheck:
test: ["CMD", "nginx", "-t"] # tests config syntax, not live HTTP
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 37. Production and self-hosted compose files pin MinIO to 🔵 Minor8. Per 9. All three jobs use 10.
🤖 Agent Prompt (paste this to Kilo Code)[M-3] packages/cli/src/index.ts — branch default action reads wrong parameterCommander passes (argValue, optionsObject, command). [M-4] packages/cli/src/index.ts — fn deploy action reads wrong parameterSame class of bug. fn deploy has arguments (name, projectRoot) + options. [M-5] Dockerfile.project — deps stage is unused dead codeThe builder stage starts FROM base and re-runs bun install independently. [M-6] docker-compose.self-hosted.yml — nginx healthcheck wrongCurrent: test: ["CMD", "nginx", "-t"] [M-7] docker-compose.yml — unpinned minio:latest and mc:latestminio and minio-init use :latest. All other compose files pin to MINOR — Fix in Same Pass[m-1] apps/dashboard/src/vite-env.d.ts — VITE_API_URL typed as optionalVITE_API_URL is the only env var and is required at runtime. Change: [m-2] .github/workflows/ci.yml — bun-version: latest not reproducibleAll 3 jobs use bun-version: latest. Pin to 1.3.9 (matches all Dockerfiles).
After checkout, before install:
[m-3] docker-compose.dev.yml — deprecated version fieldRemove the Verification Steps (run after all fixes)
Fix Summary FormatAfter completing all fixes, output: |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (8)
packages/cli/src/index.ts (4)
118-125:⚠️ Potential issue | 🔴 CriticalCommander parameter order reversed –
bb init my-appwill fail.Commander passes positional arguments first, then the options object. Line 123 has
(options: { iac?: boolean }, projectName?: string)which is backward. When a user runsbb init my-app,projectNamereceives the options object andoptionsreceives the string, causingprojectNameto be undefined inside the handler.Proposed fix
program .command("init") .description("Initialize a BetterBase project with BetterBase template (betterbase/ functions)") .option("--no-iac", "Use interactive mode instead of BetterBase template (for legacy projects)") .argument("[project-name]", "project name") - .action(async (options: { iac?: boolean }, projectName?: string) => { + .action(async (projectName: string | undefined, options: { iac?: boolean }) => { await runInitCommand({ projectName, ...options }); });As per coding guidelines: "init MUST be in PUBLIC_COMMANDS. If it's removed or missing, bb init breaks for new users who aren't logged in. This is a documented critical bug pattern."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/cli/src/index.ts` around lines 118 - 125, The command handler signature for program.command("init") is reversed: the action currently declares (options: { iac?: boolean }, projectName?: string) so positional projectName becomes the options object; update the action parameters to (projectName?: string, options: { iac?: boolean }) and pass them into runInitCommand as runInitCommand({ projectName, ...options }) so program.command("init") and runInitCommand receive the correct values.
32-32:⚠️ Potential issue | 🟠 MajorPUBLIC_COMMANDS missing flag strings – unauthenticated flags treated as protected.
Line 32 defines
PUBLIC_COMMANDS = ["login", "logout", "version", "help", "init"]butcheckAuthHook(line 38) readsprocess.argv[2]which will be"--version"or"-v"when the user runsbb --version. Since those strings are not in the array, the auth check runs and blocks unauthenticated users from seeing version/help output via flags.Proposed fix
-const PUBLIC_COMMANDS = ["login", "logout", "version", "help", "init"]; +const PUBLIC_COMMANDS = ["login", "logout", "version", "help", "init", "--version", "-v", "--help", "-h"];As per coding guidelines: "PUBLIC_COMMANDS must contain at minimum: ['login', 'init', '--version', '--help', '-V', '-h']. Flag any PR that removes from this list without explicit justification."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/cli/src/index.ts` at line 32, PUBLIC_COMMANDS currently lists only literal command names so checkAuthHook (which inspects process.argv[2]) treats flag invocations like "--version" or "-v" as protected; update the PUBLIC_COMMANDS constant to include the flag forms so flag-based calls bypass auth (add at minimum "--version", "--help", "-V", "-h" and consider including "-v" and "-help" variants per CLI conventions) so checkAuthHook recognizes them as public.
543-549:⚠️ Potential issue | 🟠 MajorBranch command parameter handling incorrect.
Line 544 declares
argument("[project-root]", ...)and line 545 declaresoption("-p, --project-root <path>", ...), but line 546's action handler isasync (options)which expects the positional argument to be inoptions.projectRoot. Commander passes the positional argument as the first parameter, not inside the options object.Proposed fix
branch .argument("[project-root]", "project root directory", process.cwd()) .option("-p, --project-root <path>", "project root directory", process.cwd()) - .action(async (options) => { - const projectRoot = options.projectRoot || process.cwd(); + .action(async (projectRootArg: string, options: { projectRoot?: string }) => { + const projectRoot = options.projectRoot || projectRootArg; await runBranchCommand([], projectRoot); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/cli/src/index.ts` around lines 543 - 549, The branch CLI handler is using async (options) but Commander passes the positional argument separately; update the .action callback signature to accept the positional project-root first and options second (e.g., async (projectRootArg, options) => { ... }) and compute projectRoot as options.projectRoot || projectRootArg || process.cwd() before calling runBranchCommand([], projectRoot); reference the branch command builder, .argument, .option, .action and runBranchCommand to locate the change.
474-482:⚠️ Potential issue | 🟠 MajorFunction deploy command parameter order incorrect.
Lines 476, 478 declare two positional arguments (
<name>and[project-root]), but line 479's action handler isasync (name: string, options: { syncEnv?: boolean; projectRoot?: string })which expectsprojectRootin the options object. Commander passes positional arguments in order (name, thenprojectRoot), then the options object.Proposed fix
fn.command("deploy") .description("Deploy function to cloud") .argument("<name>", "function name") .option("--sync-env", "Sync environment variables from .env") .argument("[project-root]", "project root directory", process.cwd()) - .action(async (name: string, options: { syncEnv?: boolean; projectRoot?: string }) => { - const projectRoot = options.projectRoot ?? process.cwd(); + .action(async (name: string, projectRootArg: string, options: { syncEnv?: boolean }) => { + const projectRoot = projectRootArg; await runFunctionCommand(["deploy", name, options.syncEnv ? "--sync-env" : ""], projectRoot); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/cli/src/index.ts` around lines 474 - 482, The action handler for the fn.command("deploy") command has the wrong parameter order: commander will call action(name, projectRoot, options), but the code defines async (name, options) and reads projectRoot from options; update the action signature to async (name: string, projectRoot?: string, options?: { syncEnv?: boolean; projectRoot?: string }) (or equivalent positional parameter names) and then compute const projectRootResolved = projectRoot ?? process.cwd(); finally call runFunctionCommand(["deploy", name, options?.syncEnv ? "--sync-env" : ""], projectRootResolved) so runFunctionCommand and the positional arguments (.argument("<name>", ...) and .argument("[project-root]", ...)) are used correctly..github/workflows/ci.yml (1)
18-18:⚠️ Potential issue | 🟡 MinorPin
bun-versionfor reproducible CI.Using
latestcreates non-reproducible builds. Pin to a specific version (e.g.,1.3.9).Proposed fix
- name: Setup Bun uses: oven-sh/setup-bun@v2 with: - bun-version: latest + bun-version: 1.3.9Apply the same change to lines 39 and 57.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/ci.yml at line 18, Replace the non-reproducible "bun-version: latest" entries in the CI workflow by pinning to a specific stable bun release (for example "bun-version: 1.3.9"); locate every occurrence of the bun-version key (there are three occurrences) and update them consistently so all CI jobs use the same pinned version.apps/dashboard/src/vite-env.d.ts (1)
4-4:⚠️ Potential issue | 🟡 Minor
VITE_API_URLshould be required.Line 4 types
VITE_API_URLas optional (?: string), but the coding guidelines state "VITE_API_URL is the only env var" and the dashboard'sapi.tsdepends on it. Mark it as required.Proposed fix
interface ImportMetaEnv { - readonly VITE_API_URL?: string; + readonly VITE_API_URL: string; }As per coding guidelines: "VITE_API_URL is the only env var. Never hardcode localhost:3001 in component code."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/dashboard/src/vite-env.d.ts` at line 4, Change the VITE_API_URL ambient type from optional to required so the dashboard code can't compile without it: update the readonly VITE_API_URL?: string declaration in vite-env.d.ts to a required property (remove the ?), ensuring callers like the api.ts module that rely on VITE_API_URL get a guaranteed string type at compile time.docker-compose.dev.yml (1)
1-1:⚠️ Potential issue | 🟡 MinorRemove deprecated
versionfield.The top-level
version: "3.9"field is deprecated in Docker Compose v2 and ignored. Remove it.Proposed fix
-version: "3.9" - # Local development: runs Inngest dev server only.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docker-compose.dev.yml` at line 1, Remove the deprecated top-level version field from docker-compose.dev.yml: delete the line containing version: "3.9" and ensure the remaining compose file starts with the top-level keys (e.g., services, networks, volumes) so the file is valid for Docker Compose v2; verify the file still parses and docker-compose up works after removal.packages/client/src/iac/provider.tsx (1)
34-40:⚠️ Potential issue | 🟠 MajorWebSocket reconnect creates orphaned connection.
The
onclosehandler (line 34) creates a new WebSocket at line 38 but does not reattachonopen,onmessage, oronclosehandlers. The new socket is non-functional. Additionally, thesetTimeoutis not tracked—if the component unmounts during the 3-second delay, the timer fires anyway and creates a leaked connection.Proposed fix
useEffect(() => { const wsUrl = `${config.url.replace(/^http/, "ws")}/betterbase/ws?project=${config.projectSlug ?? "default"}`; - const ws = new WebSocket(wsUrl); + let reconnectTimer: ReturnType<typeof setTimeout> | null = null; + + const connect = () => { + const ws = new WebSocket(wsUrl); ws.onopen = () => { setWsReady(true); }; ws.onclose = () => { setWsReady(false); - // Reconnect after 3 seconds - setTimeout(() => { - wsRef.current = new WebSocket(wsUrl); + reconnectTimer = setTimeout(() => { + connect(); }, 3_000); }; - wsRef.current = ws; - - // Handle pings ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "ping") ws.send(JSON.stringify({ type: "pong" })); }; + + wsRef.current = ws; + }; + + connect(); return () => { - ws.close(); + if (reconnectTimer) clearTimeout(reconnectTimer); + wsRef.current?.close(); }; }, [config.url, config.projectSlug]);As per coding guidelines: "RealtimeClient uses WebSocket with exponential backoff reconnection. unsubscribe() must clean up the WS connection if it's the last subscriber."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/client/src/iac/provider.tsx` around lines 34 - 40, The onclose handler currently creates a new WebSocket via wsRef.current = new WebSocket(wsUrl) without reattaching handlers and without tracking the timeout, causing orphaned, non-functional sockets and leaks; change the reconnection logic to use a reconnection helper that (1) sets up a new WebSocket with the same onopen/onmessage/onclose handlers (reuse the existing handler functions or a setupWebSocket(ws) function) and (2) implements exponential backoff for retries while storing the timeout ID in a ref so it can be cleared on unmount/unsubscribe; also ensure unsubscribe() (or the RealtimeClient cleanup path) closes the active wsRef.current and clears any pending reconnect timeout so no stray connections are created when the last subscriber unsubscribes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In @.github/workflows/ci.yml:
- Line 18: Replace the non-reproducible "bun-version: latest" entries in the CI
workflow by pinning to a specific stable bun release (for example "bun-version:
1.3.9"); locate every occurrence of the bun-version key (there are three
occurrences) and update them consistently so all CI jobs use the same pinned
version.
In `@apps/dashboard/src/vite-env.d.ts`:
- Line 4: Change the VITE_API_URL ambient type from optional to required so the
dashboard code can't compile without it: update the readonly VITE_API_URL?:
string declaration in vite-env.d.ts to a required property (remove the ?),
ensuring callers like the api.ts module that rely on VITE_API_URL get a
guaranteed string type at compile time.
In `@docker-compose.dev.yml`:
- Line 1: Remove the deprecated top-level version field from
docker-compose.dev.yml: delete the line containing version: "3.9" and ensure the
remaining compose file starts with the top-level keys (e.g., services, networks,
volumes) so the file is valid for Docker Compose v2; verify the file still
parses and docker-compose up works after removal.
In `@packages/cli/src/index.ts`:
- Around line 118-125: The command handler signature for program.command("init")
is reversed: the action currently declares (options: { iac?: boolean },
projectName?: string) so positional projectName becomes the options object;
update the action parameters to (projectName?: string, options: { iac?: boolean
}) and pass them into runInitCommand as runInitCommand({ projectName, ...options
}) so program.command("init") and runInitCommand receive the correct values.
- Line 32: PUBLIC_COMMANDS currently lists only literal command names so
checkAuthHook (which inspects process.argv[2]) treats flag invocations like
"--version" or "-v" as protected; update the PUBLIC_COMMANDS constant to include
the flag forms so flag-based calls bypass auth (add at minimum "--version",
"--help", "-V", "-h" and consider including "-v" and "-help" variants per CLI
conventions) so checkAuthHook recognizes them as public.
- Around line 543-549: The branch CLI handler is using async (options) but
Commander passes the positional argument separately; update the .action callback
signature to accept the positional project-root first and options second (e.g.,
async (projectRootArg, options) => { ... }) and compute projectRoot as
options.projectRoot || projectRootArg || process.cwd() before calling
runBranchCommand([], projectRoot); reference the branch command builder,
.argument, .option, .action and runBranchCommand to locate the change.
- Around line 474-482: The action handler for the fn.command("deploy") command
has the wrong parameter order: commander will call action(name, projectRoot,
options), but the code defines async (name, options) and reads projectRoot from
options; update the action signature to async (name: string, projectRoot?:
string, options?: { syncEnv?: boolean; projectRoot?: string }) (or equivalent
positional parameter names) and then compute const projectRootResolved =
projectRoot ?? process.cwd(); finally call runFunctionCommand(["deploy", name,
options?.syncEnv ? "--sync-env" : ""], projectRootResolved) so
runFunctionCommand and the positional arguments (.argument("<name>", ...) and
.argument("[project-root]", ...)) are used correctly.
In `@packages/client/src/iac/provider.tsx`:
- Around line 34-40: The onclose handler currently creates a new WebSocket via
wsRef.current = new WebSocket(wsUrl) without reattaching handlers and without
tracking the timeout, causing orphaned, non-functional sockets and leaks; change
the reconnection logic to use a reconnection helper that (1) sets up a new
WebSocket with the same onopen/onmessage/onclose handlers (reuse the existing
handler functions or a setupWebSocket(ws) function) and (2) implements
exponential backoff for retries while storing the timeout ID in a ref so it can
be cleared on unmount/unsubscribe; also ensure unsubscribe() (or the
RealtimeClient cleanup path) closes the active wsRef.current and clears any
pending reconnect timeout so no stray connections are created when the last
subscriber unsubscribes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: f4577f0f-6492-47d4-8b2d-6d6be16ef327
📒 Files selected for processing (15)
.coderabbit.yaml.github/workflows/ci.ymlDockerfileDockerfile.projectapps/dashboard/Dockerfileapps/dashboard/src/vite-env.d.tsdocker-compose.dev.ymldocker-compose.production.ymldocker-compose.self-hosted.ymldocker-compose.ymlpackages/cli/src/build.tspackages/cli/src/constants.tspackages/cli/src/index.tspackages/client/src/iac/provider.tsxpackages/server/Dockerfile
This PR adds a trailing space to config files, Dockerfiles and remaining files to trigger CodeRabbit review. Part 7 of 7.
Summary by CodeRabbit