Skip to content

Conversation

@AmanVarshney01
Copy link
Owner

@AmanVarshney01 AmanVarshney01 commented Sep 11, 2025

Summary by CodeRabbit

  • Bug Fixes

    • CLI formatter is more resilient: avoids crashes when formatting tool isn’t available and skips additional file types (lockfiles, .d.ts).
    • Project creation now blocks paths outside the current directory and falls back to an interactive prompt with a clear error message.
  • Refactor

    • Widespread removal of explicit return-type annotations across CLI and web utilities; no behavioral changes.
  • Documentation

    • Contributor guidelines updated.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 11, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Caution

Review failed

The pull request is closed.

Walkthrough

This PR removes explicit return type annotations across many TypeScript files (CLI and web), adds a repo guideline banning explicit return types, and makes a few focused behavioral tweaks: Biome formatter now returns null instead of throwing on errors, Docker uses a static execa import, and project-name gains a cwd containment validation with an error log.

Changes

Cohort / File(s) Summary
Repo rules
\.cursor/rules/better-t-stack-repo.mdc
Added guideline: "Do not use explicit return types."
Core CLI & exports
apps/cli/src/index.ts, apps/cli/src/constants.ts, apps/cli/src/helpers/core/*
Removed explicit return types from exported/internal functions; dropped some type imports; one local var explicitly typed; exported APIs unchanged (types now inferred).
Prompts
apps/cli/src/prompts/*
Removed explicit Promise return types across prompt modules (addons, api, database, examples, frontend, orm, package-manager, runtime, server-deploy, web-deploy). backend.ts only formatting. project-name.ts adds basename validation and cwd containment check with an error log; defaultName typed.
Database providers
apps/cli/src/helpers/database-providers/*
Removed explicit return types; turso-setup.ts also removes TursoGroup type alias and relies on inferred returns.
Biome formatter
apps/cli/src/utils/biome-formatter.ts
Removed explicit return types; initializeBiome now returns null on failure (no throw); formatFileWithBiome returns null on errors; expanded skip patterns; quieter error handling.
Docker utils
apps/cli/src/utils/docker-utils.ts
Replaced dynamic execa import with top-level import { $ } from "execa" and use $ template for docker checks; removed explicit return types from some helpers.
Utilities & validation
apps/cli/src/utils/*, apps/cli/src/validation.ts, apps/cli/src/validation.ts
Many exported helpers had their explicit return types removed (addon-compatibility, bts-config, compatibility-rules, config-processing, config-validation, errors, generate-reproducible-command, package-runner, project-directory, project-name-validation, sponsors, telemetry, ts-morph, validation). Behavior unchanged; types now inferred.
Web stack utils
apps/web/src/lib/stack-utils.ts
Removed explicit return types from exported functions; logic unchanged.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Caller
  participant Formatter as formatFileWithBiome
  participant Biome as initializeBiome
  participant FS as Biome.format

  Caller->>Formatter: formatFileWithBiome(filePath, content)
  Formatter->>Formatter: shouldSkipFile?/isSupportedFile?
  alt Skip/Unsupported
    Formatter-->>Caller: null
  else Proceed
    Formatter->>Biome: initializeBiome()
    alt Init fails (returns null)
      Biome-->>Formatter: null
      Formatter-->>Caller: null
    else Init OK
      Biome-->>Formatter: { biome, projectKey }
      Formatter->>FS: biome.format(content)
      alt Diagnostics OK
        FS-->>Formatter: formatted
        Formatter-->>Caller: formatted
      else Diagnostics warn/error
        FS-->>Formatter: original/partial
        Formatter-->>Caller: null
      end
    end
  end
Loading
sequenceDiagram
  autonumber
  actor User
  participant Prompt as getProjectName
  participant Path as path validation
  participant Log as consola

  User->>Prompt: call with initialName?
  alt initialName missing or "."
    Prompt->>User: interactive prompt → chosen name
  else provided
    Prompt->>Path: validate basename
    alt invalid basename
      Prompt->>User: interactive prompt → chosen name
    else valid basename
      Path->>Path: is within cwd?
      alt outside cwd
        Log-->>User: "Project path must be within current directory"
        Prompt->>User: interactive prompt → chosen name
      else inside cwd
        Prompt-->>User: basename returned
      end
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I nibbled types till edges blurred,
Returns inferred, the linter purred.
Biome now whispers, returns a null,
Docker hums steady, imports grown dull.
Hop, hop — validated paths ahead,
Carrots, commits, and cozy bed. 🥕


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 384a0d5 and e556c82.

📒 Files selected for processing (1)
  • apps/cli/src/helpers/database-providers/turso-setup.ts (2 hunks)
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch no-return-types

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR removes explicit return types from functions across the CLI codebase to align with the project's coding standards. The changes span multiple files including utilities, prompts, validation, and configuration handling modules.

  • Remove explicit return types from all function declarations
  • Maintain functional programming patterns while simplifying type annotations
  • Update project coding rules to enforce this convention going forward

Reviewed Changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
apps/web/src/lib/stack-utils.ts Remove return types from stack utility functions
apps/cli/src/validation.ts Remove return types from validation and processing functions
apps/cli/src/utils/ Remove return types from utility functions across multiple modules
apps/cli/src/prompts/ Remove return types from prompt handling functions
apps/cli/src/helpers/ Remove return types from helper functions and handlers
apps/cli/src/constants.ts Remove return types from configuration functions
.cursor/rules/better-t-stack-repo.mdc Add rule to enforce no explicit return types
Comments suppressed due to low confidence (1)

apps/cli/src/helpers/database-providers/turso-setup.ts:1

  • The TursoGroup type definition is removed but the getTursoGroups function still references it in its logic. The type should be kept or the function should be updated to work without explicit typing.
import os from "node:os";

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

flags.api,
results.frontend,
results.backend,
) as Promise<API>,
Copy link

Copilot AI Sep 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type assertion 'as Promise' is unnecessary since getApiChoice already returns Promise. The type assertion should be removed for cleaner code.

Suggested change
) as Promise<API>,
),

Copilot uses AI. Check for mistakes.
results.backend,
results.api,
),
) as Promise<Examples[]>,
Copy link

Copilot AI Sep 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type assertion 'as Promise<Examples[]>' is unnecessary since getExamplesChoice already returns Promise<Examples[]>. The type assertion should be removed for cleaner code.

Suggested change
) as Promise<Examples[]>,
),

Copilot uses AI. Check for mistakes.
@AmanVarshney01 AmanVarshney01 merged commit 0bfb3cf into main Sep 11, 2025
@AmanVarshney01 AmanVarshney01 deleted the no-return-types branch September 11, 2025 04:31
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 (9)
apps/cli/src/helpers/deployment/alchemy/alchemy-svelte-setup.ts (1)

16-18: Remove dotenv from devDependencies; Bun auto-loads .env per repo rules.

The repo guideline forbids dotenv; avoid adding it.

Apply this diff:

-    devDependencies: ["alchemy", "@sveltejs/adapter-cloudflare", "dotenv"],
+    devDependencies: ["alchemy", "@sveltejs/adapter-cloudflare"],
apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts (1)

4-4: Replace execa with Bun.$ per project guidelines.

The repo guidelines prefer Bun.$ for shelling out. This also removes an external dependency.

-import { execa } from "execa";
+import { $ } from "bun";
@@
-    await execa("atlas", ["deployments", "setup"], {
-      cwd: serverDir,
-      stdio: "inherit",
-    });
+    await $({ cwd: serverDir })`atlas deployments setup`;

Also applies to: 50-53

apps/cli/src/helpers/core/post-installation.ts (2)

431-438: Fix double "run" in Wrangler deploy commands.

${runCmd} already contains "<pm> run". Appending run produces npm run run deploy.

Apply:

-      `${pc.bold("Deploy web to Cloudflare Workers:")}\n${pc.cyan("•")} Deploy: ${`cd apps/web && ${runCmd} run deploy`}`,
+      `${pc.bold("Deploy web to Cloudflare Workers:")}\n${pc.cyan("•")} Deploy: ${`cd apps/web && ${runCmd} deploy`}`,
-      `${pc.bold("Deploy server to Cloudflare Workers:")}\n${pc.cyan("•")} Deploy: ${`cd apps/server && ${runCmd} run deploy`}`,
+      `${pc.bold("Deploy server to Cloudflare Workers:")}\n${pc.cyan("•")} Deploy: ${`cd apps/server && ${runCmd} deploy`}`,

262-263: Derive the package manager correctly from runCmd.

Current logic yields "pnpm run" or "bun run" instead of "pnpm"/"bun", producing invalid commands.

Apply:

-    const packageManager = runCmd === "npm run" ? "npm" : runCmd || "npm";
+    const packageManager = runCmd?.split(" ")[0] ?? "npm";
apps/cli/src/helpers/core/auth-setup.ts (1)

118-127: Use a cryptographically secure RNG for auth secrets.

Math.random() is not suitable for secrets.

Apply:

-export function generateAuthSecret(length = 32) {
-  const characters =
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
-  let result = "";
-  const charactersLength = characters.length;
-  for (let i = 0; i < length; i++) {
-    result += characters.charAt(Math.floor(Math.random() * charactersLength));
-  }
-  return result;
-}
+export function generateAuthSecret(length = 32) {
+  const alphabet =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+  const bytes = new Uint8Array(length);
+  crypto.getRandomValues(bytes);
+  let out = "";
+  for (let i = 0; i < length; i++) {
+    out += alphabet[bytes[i] % alphabet.length];
+  }
+  return out;
+}
apps/cli/src/helpers/database-providers/turso-setup.ts (3)

151-158: Don’t treat missing connection details as success. Throw to let caller retry.

On failure this returns undefined, and the caller proceeds.

Apply:

   try {
     const { stdout: dbUrl } = await $`turso db show ${dbName} --url`;
     const { stdout: authToken } = await $`turso db tokens create ${dbName}`;
     s.stop("Database connection details retrieved");
-    return {
+    return {
       dbUrl: dbUrl.trim(),
       authToken: authToken.trim(),
     };
   } catch (_error) {
     s.stop(pc.red("Failed to retrieve database connection details"));
+    throw new Error("FAILED_TO_RETRIEVE_DB_CREDENTIALS");
   }

267-283: Only mark success when credentials exist; handle retries cleanly.

Prevents silent success with empty .env.

Apply:

-      try {
-        const config = await createTursoDatabase(dbName, selectedGroup);
-        await writeEnvFile(projectDir, config);
-        success = true;
+      try {
+        const config = await createTursoDatabase(dbName, selectedGroup);
+        if (!config?.dbUrl || !config?.authToken) {
+          log.error(pc.red("Missing database credentials. Please try again."));
+          continue;
+        }
+        await writeEnvFile(projectDir, config);
+        success = true;
       } catch (error) {
         if (error instanceof Error && error.message === "DATABASE_EXISTS") {
           log.warn(pc.yellow(`Database "${pc.red(dbName)}" already exists`));
           suggestedName = `${dbName}-${Math.floor(Math.random() * 1000)}`;
         } else {
           throw error;
         }
       }

5-5: Replace execa import with Bun.$ in this file.

Apply:

-import { $ } from "execa";
+const $ = Bun.$;

Also: execa is still a dependency and used across the repo (apps/cli/package.json; apps/cli/test/cli.smoke.test.ts; apps/cli/src/helpers/** — e.g. core/install-dependencies.ts, core/git.ts, addons/, database-providers/). Migrate other usages or keep execa where necessary and update package.json accordingly.

apps/cli/src/prompts/project-name.ts (1)

47-53: Avoid possible crash when a file exists at the candidate path

If a file named like defaultName exists, readdir throws. Guard by checking directory-ness first.

-while (
-  (await fs.pathExists(path.resolve(process.cwd(), defaultName))) &&
-  (await fs.readdir(path.resolve(process.cwd(), defaultName))).length > 0
-) {
+while (true) {
+  const candidate = path.resolve(process.cwd(), defaultName);
+  const exists = await fs.pathExists(candidate);
+  if (!exists) break;
+  const stat = await fs.stat(candidate).catch(() => null);
+  const isDir = !!stat && stat.isDirectory();
+  const notEmpty = isDir ? (await fs.readdir(candidate)).length > 0 : false;
+  if (!(isDir && notEmpty)) break;
   defaultName = `${DEFAULT_CONFIG.projectName}-${counter}`;
   counter++;
 }
♻️ Duplicate comments (3)
apps/cli/src/helpers/database-providers/turso-setup.ts (1)

115-116: No return needed before exitCancelled.

exitCancelled() is typed never; control flow does not continue.

apps/cli/src/prompts/config-prompts.ts (2)

78-83: Remove unnecessary cast to Promise

The call already returns Promise<API>. Drop the assertion.

-				getApiChoice(
-					flags.api,
-					results.frontend,
-					results.backend,
-				) as Promise<API>,
+				getApiChoice(
+					flags.api,
+					results.frontend,
+					results.backend,
+				),

92-99: Remove unnecessary cast to Promise<Examples[]>

getExamplesChoice infers Promise<Examples[]>; the cast is superfluous.

-				getExamplesChoice(
-					flags.examples,
-					results.database,
-					results.frontend,
-					results.backend,
-					results.api,
-				) as Promise<Examples[]>,
+				getExamplesChoice(
+					flags.examples,
+					results.database,
+					results.frontend,
+					results.backend,
+					results.api,
+				),
🧹 Nitpick comments (25)
apps/cli/src/prompts/package-manager.ts (2)

29-31: Don’t return the exit helper; call it to stabilize inference.

Calling (not returning) the exit function avoids union-widening even if its type isn’t never.

- if (isCancel(response)) return exitCancelled("Operation cancelled");
+ if (isCancel(response)) {
+   exitCancelled("Operation cancelled");
+ }

11-27: Lock option values to the PackageManager union.

Use as const + satisfies so option values can’t drift from PackageManager.

   const response = await select<PackageManager>({
     message: "Choose package manager",
-    options: [
+    options: [
       { value: "npm", label: "npm", hint: "Node Package Manager" },
       {
         value: "pnpm",
         label: "pnpm",
         hint: "Fast, disk space efficient package manager",
       },
       {
         value: "bun",
         label: "bun",
         hint: "All-in-one JavaScript runtime & toolkit",
       },
-    ],
+    ] as const satisfies ReadonlyArray<{ value: PackageManager; label: string; hint: string }>,
     initialValue: detectedPackageManager,
   });
.cursor/rules/better-t-stack-repo.mdc (1)

10-10: Clarify narrowly-scoped exceptions to the no-return-types rule.

To prevent accidental public API drift and preserve intent in edge cases, consider documenting minimal exceptions.

Apply this diff:

-- Do not use explicit return types
+- Avoid explicit return types
+  (exceptions: exported/public APIs, recursive functions where inference degrades,
+  and cases where Promise<void> vs Promise<unknown> ambiguity matters).
apps/cli/src/helpers/deployment/alchemy/alchemy-svelte-setup.ts (1)

79-83: Narrow param type to ObjectLiteralExpression; drop redundant runtime check.

Improves type-safety and simplifies control flow without reintroducing explicit return types.

Apply this diff:

-import { IndentationText, Node, Project, QuoteKind } from "ts-morph";
+import { IndentationText, Node, Project, QuoteKind, ObjectLiteralExpression } from "ts-morph";
@@
-function updateAdapterInConfig(configObject: Node) {
-	if (!Node.isObjectLiteralExpression(configObject)) return;
+function updateAdapterInConfig(configObject: ObjectLiteralExpression) {
apps/cli/src/helpers/database-providers/supabase-setup.ts (2)

40-47: Make DB URL extraction more robust (case-insensitive, postgres|postgresql, non-space terminator).

Prevents breakage if CLI output format varies slightly.

Apply this diff:

-function extractDbUrl(output: string) {
-	const dbUrlMatch = output.match(/DB URL:\s*(postgresql:\/\/[^\s]+)/);
+function extractDbUrl(output: string) {
+	const dbUrlMatch = output.match(/DB\s*URL:\s*(postgres(?:ql)?:\/\/\S+)/i);
 	const url = dbUrlMatch?.[1];
 	if (url) {
 		return url;
 	}
 	return null;
 }

4-4: Align with repo rule to prefer Bun.$ over execa (follow-up OK).

Current code shells out via execa; repo guidance prefers Bun.$. Given the PR scope, consider a follow-up to migrate initializeSupabase/startSupabase to Bun.$ (mind tokenization vs single-string commands from getPackageExecutionCommand).

Would you like a separate PR plan for safely swapping execa to Bun.$ here (including capturing stdout incrementally)?

Also applies to: 95-118

apps/cli/src/prompts/runtime.ts (1)

6-15: Preserve literal inference with as const on direct returns.

Without explicit return types, make sure "none"/"node" stay within Runtime’s literal union.

Apply this diff:

 export async function getRuntimeChoice(runtime?: Runtime, backend?: Backend) {
 	if (backend === "convex" || backend === "none") {
-		return "none";
+		return "none" as const;
 	}
@@
 	if (backend === "next") {
-		return "node";
+		return "node" as const;
 	}
apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts (1)

34-34: Return type inference is fine; keep call-site typed for clarity.

To preserve the MongoDBConfig | null contract at the usage site without reintroducing an explicit return type, annotate the local variable where it’s consumed.

-    const config = await initMongoDBAtlas(serverDir);
+    const config: MongoDBConfig | null = await initMongoDBAtlas(serverDir);
apps/cli/src/constants.ts (2)

28-37: Constrain inferred return with satisfies to keep strong typing.

Removing the explicit return type widens frontend/addons/examples to string[] at inference time. Use satisfies ProjectConfig and explicit generic arrays to retain precise types without annotating the return type.

+import type { Addons, Examples, Frontend, ProjectConfig } from "./types";
@@
-export function getDefaultConfig() {
-  return {
+export function getDefaultConfig() {
+  const config = {
     ...DEFAULT_CONFIG_BASE,
     projectDir: path.resolve(process.cwd(), DEFAULT_CONFIG_BASE.projectName),
     packageManager: getUserPkgManager(),
-    frontend: [...DEFAULT_CONFIG_BASE.frontend],
-    addons: [...DEFAULT_CONFIG_BASE.addons],
-    examples: [...DEFAULT_CONFIG_BASE.examples],
+    frontend: [...DEFAULT_CONFIG_BASE.frontend] as Array<Frontend>,
+    addons: [...DEFAULT_CONFIG_BASE.addons] as Array<Addons>,
+    examples: [...DEFAULT_CONFIG_BASE.examples] as Array<Examples>,
-  };
+  } satisfies ProjectConfig;
+  return config;
}

162-175: Keep ADDON_COMPATIBILITY key coverage checked at compile-time.

Switching from Record<Addons, readonly Frontend[]> to a plain const may drop “exhaustiveness” checking if Addons evolves. Use satisfies with the const to ensure keys stay in sync.

-export const ADDON_COMPATIBILITY = {
+export const ADDON_COMPATIBILITY = {
   pwa: ["tanstack-router", "react-router", "solid", "next"],
   tauri: ["tanstack-router", "react-router", "nuxt", "svelte", "solid", "next"],
   biome: [],
   husky: [],
   turborepo: [],
   starlight: [],
   ultracite: [],
   ruler: [],
   oxlint: [],
   fumadocs: [],
   none: [],
-} as const;
+} as const satisfies Record<import("./types").Addons, readonly import("./types").Frontend[]>;
apps/cli/src/prompts/frontend.ts (1)

7-11: Inference OK; ensure initialValue remains typed as Frontend.

Because getDefaultConfig() now infers, DEFAULT_CONFIG.frontend[0] can widen to string. The suggested satisfies fix in constants.ts keeps this as Frontend without reintroducing return types.

apps/cli/src/helpers/core/create-readme.ts (1)

20-24: Prefer Bun.write over fs-extra for writes.

Small cleanup aligned with repo guidance to prefer Bun APIs where possible.

-import fs from "fs-extra";
+// import fs from "fs-extra"; // no longer needed
@@
-    await fs.writeFile(readmePath, content);
+    await Bun.write(readmePath, content);
apps/cli/src/utils/addon-compatibility.ts (1)

29-33: LGTM on inferred return; keep type-safety with constants object.

Function inference yields Addons[] from the filtered input. Ensure ADDON_COMPATIBILITY uses satisfies (see constants.ts suggestion) so indexing by Addons remains safe long-term.

apps/cli/src/helpers/core/post-installation.ts (1)

229-233: Make runCmd required (or provide an internal default) to avoid "undefined dev".

These helpers are always passed a value today, but the optional param risks emitting undefined in strings if reused.

Apply (one example shown; repeat for others):

-function getLintingInstructions(runCmd?: string) {
+function getLintingInstructions(runCmd: string) {

Alternatively, default: function getLintingInstructions(runCmd = "pnpm run") { ... }.

Also applies to: 387-395, 403-409, 423-443, 448-470

apps/cli/src/helpers/database-providers/turso-setup.ts (2)

50-54: Avoid inlining installer script into bash -c. Use a pipeline.

Safer and simpler; avoids quoting pitfalls.

Apply:

-      const { stdout: installScript } =
-        await $`curl -sSfL https://get.tur.so/install.sh`;
-      await $`bash -c '${installScript}'`;
+      await $`curl -fsSL https://get.tur.so/install.sh`.pipe($`bash -s --`);

58-63: Detect user-cancel via exit code instead of string matching.

Message text is brittle; Bun.$ exposes exitCode.

Apply:

-    if (error instanceof Error && error.message.includes("User force closed")) {
+    // Bun.$ throws a SubprocessError with exitCode when interrupted (e.g., SIGINT -> 130)
+    // @ts-expect-error Bun SubprocessError has exitCode
+    if (typeof (error as any)?.exitCode === "number" && (error as any).exitCode !== 0) {
apps/cli/src/helpers/addons/addons-setup.ts (1)

98-109: Remove redundant conditional in getWebAppDir

Both branches return the same path. Simplify to a single return.

-function getWebAppDir(projectDir: string, frontends: Frontend[]) {
-	if (
-		frontends.some((f) =>
-			["react-router", "tanstack-router", "nuxt", "svelte", "solid"].includes(
-				f,
-			),
-		)
-	) {
-		return path.join(projectDir, "apps/web");
-	}
-	return path.join(projectDir, "apps/web");
-}
+function getWebAppDir(projectDir: string, frontends: Frontend[]) {
+	return path.join(projectDir, "apps/web");
+}
apps/cli/src/helpers/core/command-handlers.ts (1)

59-61: Drop redundant local type annotation.

Rely on inference to stay consistent with the PR’s goal.

-    let defaultName: string = defaultConfig.relativePath;
+    let defaultName = defaultConfig.relativePath;
apps/cli/src/utils/config-processing.ts (1)

17-21: Constrain T to string to avoid the cast and simplify includes check.

This tightens types and removes the need for "as T | 'none'".

-export function processArrayOption<T>(options: (T | "none")[] | undefined) {
+export function processArrayOption<T extends string>(options: (T | "none")[] | undefined) {
   if (!options || options.length === 0) return [];
-  if (options.includes("none" as T | "none")) return [];
+  if (options.includes("none")) return [];
   return options.filter((item): item is T => item !== "none");
 }
apps/cli/src/prompts/project-name.ts (2)

10-14: Harden cwd containment against symlink escapes

Resolve both cwd and target with realpath to prevent bypass via symlinks.

-function isPathWithinCwd(targetPath: string) {
-  const resolved = path.resolve(targetPath);
-  const rel = path.relative(process.cwd(), resolved);
+function isPathWithinCwd(targetPath: string) {
+  const resolved = fs.realpathSync(path.resolve(targetPath));
+  const cwdReal = fs.realpathSync(process.cwd());
+  const rel = path.relative(cwdReal, resolved);
   return !rel.startsWith("..") && !path.isAbsolute(rel);
 }

26-40: Early-path UX improvement (non-blocking)

When initialName is inside cwd, consider normalizing before returning so consumers get a consistent path (e.g., collapse foo/../bar). Safe to do with path.normalize.

-        if (isPathWithinCwd(projectDir)) {
-          return initialName;
-        }
+        if (isPathWithinCwd(projectDir)) {
+          return path.normalize(initialName);
+        }
apps/cli/src/utils/project-directory.ts (1)

72-76: Drop redundant await on returned promise

return await handleDirectoryConflict(newPathInput) adds no value here.

-        return await handleDirectoryConflict(newPathInput);
+        return handleDirectoryConflict(newPathInput);
apps/cli/src/utils/package-runner.ts (1)

11-15: Minor: handle Yarn explicitly or fix docs

Docstring mentions Yarn but switch doesn’t. Either add Yarn handling or adjust docs.

 export function getPackageExecutionCommand(
   packageManager: PackageManager | null | undefined,
   commandWithArgs: string,
 ) {
   switch (packageManager) {
+    case "yarn":
+      // Yarn Berry (v2+) supports `yarn dlx`; v1 falls back to `npx`
+      return `yarn dlx ${commandWithArgs}`;
     case "pnpm":
       return `pnpm dlx ${commandWithArgs}`;
     case "bun":
       return `bunx ${commandWithArgs}`;
     default:
       return `npx ${commandWithArgs}`;
   }
 }
apps/cli/src/utils/project-name-validation.ts (1)

16-21: Throwing validator: OK

Inferred void; error message is clear. Consider adding the fallback like the non-throwing variant for consistency, optional.

apps/cli/src/utils/docker-utils.ts (1)

53-78: Return-type removal: docker status

Inferred object shape remains explicit in usage; fine. Consider .quiet() if output is noisy (optional).

-  const running = await isDockerRunning();
+  const running = await isDockerRunning();
   if (!running) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b97093 and 384a0d5.

📒 Files selected for processing (45)
  • .cursor/rules/better-t-stack-repo.mdc (1 hunks)
  • apps/cli/src/constants.ts (2 hunks)
  • apps/cli/src/helpers/addons/addons-setup.ts (1 hunks)
  • apps/cli/src/helpers/core/auth-setup.ts (1 hunks)
  • apps/cli/src/helpers/core/command-handlers.ts (3 hunks)
  • apps/cli/src/helpers/core/create-readme.ts (8 hunks)
  • apps/cli/src/helpers/core/detect-project-config.ts (1 hunks)
  • apps/cli/src/helpers/core/post-installation.ts (7 hunks)
  • apps/cli/src/helpers/database-providers/docker-compose-setup.ts (1 hunks)
  • apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts (1 hunks)
  • apps/cli/src/helpers/database-providers/supabase-setup.ts (1 hunks)
  • apps/cli/src/helpers/database-providers/turso-setup.ts (3 hunks)
  • apps/cli/src/helpers/deployment/alchemy/alchemy-svelte-setup.ts (1 hunks)
  • apps/cli/src/index.ts (1 hunks)
  • apps/cli/src/prompts/addons.ts (2 hunks)
  • apps/cli/src/prompts/api.ts (1 hunks)
  • apps/cli/src/prompts/backend.ts (1 hunks)
  • apps/cli/src/prompts/config-prompts.ts (3 hunks)
  • apps/cli/src/prompts/database-setup.ts (1 hunks)
  • apps/cli/src/prompts/database.ts (1 hunks)
  • apps/cli/src/prompts/examples.ts (1 hunks)
  • apps/cli/src/prompts/frontend.ts (1 hunks)
  • apps/cli/src/prompts/orm.ts (1 hunks)
  • apps/cli/src/prompts/package-manager.ts (1 hunks)
  • apps/cli/src/prompts/project-name.ts (3 hunks)
  • apps/cli/src/prompts/runtime.ts (1 hunks)
  • apps/cli/src/prompts/server-deploy.ts (2 hunks)
  • apps/cli/src/prompts/web-deploy.ts (3 hunks)
  • apps/cli/src/utils/addon-compatibility.ts (1 hunks)
  • apps/cli/src/utils/biome-formatter.ts (4 hunks)
  • apps/cli/src/utils/bts-config.ts (1 hunks)
  • apps/cli/src/utils/compatibility-rules.ts (2 hunks)
  • apps/cli/src/utils/config-processing.ts (5 hunks)
  • apps/cli/src/utils/config-validation.ts (9 hunks)
  • apps/cli/src/utils/docker-utils.ts (3 hunks)
  • apps/cli/src/utils/errors.ts (1 hunks)
  • apps/cli/src/utils/generate-reproducible-command.ts (1 hunks)
  • apps/cli/src/utils/package-runner.ts (1 hunks)
  • apps/cli/src/utils/project-directory.ts (2 hunks)
  • apps/cli/src/utils/project-name-validation.ts (3 hunks)
  • apps/cli/src/utils/sponsors.ts (1 hunks)
  • apps/cli/src/utils/telemetry.ts (1 hunks)
  • apps/cli/src/utils/ts-morph.ts (1 hunks)
  • apps/cli/src/validation.ts (2 hunks)
  • apps/web/src/lib/stack-utils.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

**/*.{ts,tsx}: Use Id from './_generated/dataModel' to type document ids (e.g., Id<'users'>)
Ensure Record key/value types align with validators (e.g., v.record(v.id('users'), v.string()) => Record<Id<'users'>, string>)
Be strict with types for document ids; prefer Id<'table'> over string
Use 'as const' for string literals in discriminated unions
When using Array and Record types, declare with explicit generic types (e.g., const arr: Array = ...)

Use TypeScript type aliases instead of interface declarations.

Files:

  • apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts
  • apps/cli/src/utils/telemetry.ts
  • apps/cli/src/utils/bts-config.ts
  • apps/cli/src/prompts/package-manager.ts
  • apps/cli/src/prompts/api.ts
  • apps/cli/src/utils/sponsors.ts
  • apps/cli/src/utils/errors.ts
  • apps/cli/src/helpers/database-providers/docker-compose-setup.ts
  • apps/cli/src/helpers/deployment/alchemy/alchemy-svelte-setup.ts
  • apps/cli/src/utils/ts-morph.ts
  • apps/cli/src/helpers/core/auth-setup.ts
  • apps/cli/src/index.ts
  • apps/cli/src/utils/generate-reproducible-command.ts
  • apps/cli/src/prompts/config-prompts.ts
  • apps/cli/src/prompts/frontend.ts
  • apps/cli/src/prompts/runtime.ts
  • apps/cli/src/utils/config-processing.ts
  • apps/cli/src/utils/compatibility-rules.ts
  • apps/web/src/lib/stack-utils.ts
  • apps/cli/src/utils/addon-compatibility.ts
  • apps/cli/src/helpers/core/post-installation.ts
  • apps/cli/src/validation.ts
  • apps/cli/src/helpers/core/command-handlers.ts
  • apps/cli/src/constants.ts
  • apps/cli/src/helpers/addons/addons-setup.ts
  • apps/cli/src/prompts/orm.ts
  • apps/cli/src/helpers/database-providers/supabase-setup.ts
  • apps/cli/src/utils/package-runner.ts
  • apps/cli/src/helpers/core/create-readme.ts
  • apps/cli/src/utils/project-directory.ts
  • apps/cli/src/prompts/examples.ts
  • apps/cli/src/utils/config-validation.ts
  • apps/cli/src/prompts/backend.ts
  • apps/cli/src/prompts/database-setup.ts
  • apps/cli/src/prompts/addons.ts
  • apps/cli/src/utils/project-name-validation.ts
  • apps/cli/src/helpers/database-providers/turso-setup.ts
  • apps/cli/src/helpers/core/detect-project-config.ts
  • apps/cli/src/prompts/web-deploy.ts
  • apps/cli/src/prompts/server-deploy.ts
  • apps/cli/src/utils/docker-utils.ts
  • apps/cli/src/prompts/project-name.ts
  • apps/cli/src/utils/biome-formatter.ts
  • apps/cli/src/prompts/database.ts
**/*.{js,jsx,ts,tsx,mjs,cjs}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{js,jsx,ts,tsx,mjs,cjs}: Do not use dotenv; Bun auto-loads .env
Use Bun.serve() for HTTP/WebSockets; do not use express
Use bun:sqlite for SQLite; do not use better-sqlite3
Use Bun.redis for Redis; do not use ioredis
Use Bun.sql for Postgres; do not use pg or postgres.js
Use built-in WebSocket; do not use ws
Prefer Bun.file over node:fs readFile/writeFile
Use Bun.$ instead of execa for shelling out

Define functions using the standard function declaration syntax, not arrow functions.

Files:

  • apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts
  • apps/cli/src/utils/telemetry.ts
  • apps/cli/src/utils/bts-config.ts
  • apps/cli/src/prompts/package-manager.ts
  • apps/cli/src/prompts/api.ts
  • apps/cli/src/utils/sponsors.ts
  • apps/cli/src/utils/errors.ts
  • apps/cli/src/helpers/database-providers/docker-compose-setup.ts
  • apps/cli/src/helpers/deployment/alchemy/alchemy-svelte-setup.ts
  • apps/cli/src/utils/ts-morph.ts
  • apps/cli/src/helpers/core/auth-setup.ts
  • apps/cli/src/index.ts
  • apps/cli/src/utils/generate-reproducible-command.ts
  • apps/cli/src/prompts/config-prompts.ts
  • apps/cli/src/prompts/frontend.ts
  • apps/cli/src/prompts/runtime.ts
  • apps/cli/src/utils/config-processing.ts
  • apps/cli/src/utils/compatibility-rules.ts
  • apps/web/src/lib/stack-utils.ts
  • apps/cli/src/utils/addon-compatibility.ts
  • apps/cli/src/helpers/core/post-installation.ts
  • apps/cli/src/validation.ts
  • apps/cli/src/helpers/core/command-handlers.ts
  • apps/cli/src/constants.ts
  • apps/cli/src/helpers/addons/addons-setup.ts
  • apps/cli/src/prompts/orm.ts
  • apps/cli/src/helpers/database-providers/supabase-setup.ts
  • apps/cli/src/utils/package-runner.ts
  • apps/cli/src/helpers/core/create-readme.ts
  • apps/cli/src/utils/project-directory.ts
  • apps/cli/src/prompts/examples.ts
  • apps/cli/src/utils/config-validation.ts
  • apps/cli/src/prompts/backend.ts
  • apps/cli/src/prompts/database-setup.ts
  • apps/cli/src/prompts/addons.ts
  • apps/cli/src/utils/project-name-validation.ts
  • apps/cli/src/helpers/database-providers/turso-setup.ts
  • apps/cli/src/helpers/core/detect-project-config.ts
  • apps/cli/src/prompts/web-deploy.ts
  • apps/cli/src/prompts/server-deploy.ts
  • apps/cli/src/utils/docker-utils.ts
  • apps/cli/src/prompts/project-name.ts
  • apps/cli/src/utils/biome-formatter.ts
  • apps/cli/src/prompts/database.ts
🧠 Learnings (5)
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
PR: AmanVarshney01/create-better-t-stack#0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/*.ts : Respect file-based routing: api.<path>.<name> for public and internal.<path>.<name> for private functions based on file location/name

Applied to files:

  • apps/cli/src/helpers/core/create-readme.ts
📚 Learning: 2025-09-09T08:52:54.105Z
Learnt from: CR
PR: AmanVarshney01/create-better-t-stack#0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-09T08:52:54.105Z
Learning: Applies to **/*.{hbs,handlebars} : In Handlebars templates, avoid generic if/else blocks; use explicit conditions (e.g., if (eq orm "prisma"), else if (eq orm "drizzle")).

Applied to files:

  • .cursor/rules/better-t-stack-repo.mdc
📚 Learning: 2025-09-09T08:52:54.105Z
Learnt from: CR
PR: AmanVarshney01/create-better-t-stack#0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-09T08:52:54.105Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript type aliases instead of interface declarations.

Applied to files:

  • .cursor/rules/better-t-stack-repo.mdc
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
PR: AmanVarshney01/create-better-t-stack#0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/*.ts : Always include argument and return validators for all Convex functions (public and internal)

Applied to files:

  • apps/cli/src/utils/config-validation.ts
📚 Learning: 2025-08-24T18:01:11.544Z
Learnt from: CR
PR: AmanVarshney01/create-better-t-stack#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-08-24T18:01:11.544Z
Learning: Applies to **/*.{js,jsx,ts,tsx,mjs,cjs} : Use `Bun.$` instead of `execa` for shelling out

Applied to files:

  • apps/cli/src/utils/docker-utils.ts
🧬 Code graph analysis (15)
apps/cli/src/prompts/package-manager.ts (1)
apps/cli/src/types.ts (1)
  • PackageManager (64-64)
apps/cli/src/helpers/database-providers/docker-compose-setup.ts (1)
apps/cli/src/types.ts (1)
  • Database (6-6)
apps/cli/src/index.ts (1)
apps/cli/src/types.ts (1)
  • CreateInput (127-150)
apps/cli/src/utils/generate-reproducible-command.ts (1)
apps/cli/src/types.ts (1)
  • ProjectConfig (165-184)
apps/cli/src/prompts/config-prompts.ts (3)
apps/cli/src/prompts/api.ts (1)
  • getApiChoice (6-49)
apps/cli/src/types.ts (2)
  • API (82-82)
  • Examples (59-59)
apps/cli/src/prompts/auth.ts (1)
  • getAuthChoice (6-56)
apps/cli/src/prompts/runtime.ts (1)
apps/cli/src/types.ts (2)
  • Runtime (21-21)
  • Backend (16-16)
apps/cli/src/utils/config-processing.ts (2)
apps/cli/src/types.ts (1)
  • CLIInput (161-163)
apps/cli/src/validation.ts (1)
  • getProvidedFlags (125-125)
apps/cli/src/utils/compatibility-rules.ts (1)
apps/cli/src/types.ts (1)
  • Frontend (37-37)
apps/web/src/lib/stack-utils.ts (1)
apps/web/src/lib/constant.ts (1)
  • StackState (720-739)
apps/cli/src/helpers/addons/addons-setup.ts (1)
apps/cli/src/index.ts (1)
  • Frontend (249-249)
apps/cli/src/helpers/core/create-readme.ts (1)
apps/cli/src/types.ts (1)
  • ProjectConfig (165-184)
apps/cli/src/helpers/database-providers/turso-setup.ts (1)
apps/cli/src/utils/errors.ts (1)
  • exitCancelled (17-23)
apps/cli/src/prompts/web-deploy.ts (1)
apps/cli/src/types.ts (1)
  • Frontend (37-37)
apps/cli/src/utils/docker-utils.ts (1)
apps/cli/src/types.ts (1)
  • Database (6-6)
apps/cli/src/prompts/project-name.ts (1)
apps/cli/src/constants.ts (1)
  • DEFAULT_CONFIG (39-39)
🔇 Additional comments (59)
apps/cli/src/prompts/package-manager.ts (1)

6-6: Keep inferred return strictly as Promise (exitCancelled is typed never). exitCancelled is declared export function exitCancelled(...): never, so the async function's inferred return remains Promise; no action required.

apps/cli/src/utils/errors.ts (1)

5-7: LGTM on return type inference.

Behavior unchanged; call sites using never-typed exits remain correct.

apps/cli/src/prompts/backend.ts (1)

9-9: LGTM — formatting-only change.

No functional or type-safety impact.

apps/cli/src/utils/telemetry.ts (1)

7-19: LGTM on inferred boolean return type.

Semantics preserved; defaults and env overrides unchanged.

apps/cli/src/helpers/database-providers/docker-compose-setup.ts (1)

37-48: LGTM on return type inference.

Function remains internal; string return is unambiguous.

apps/cli/src/utils/sponsors.ts (1)

44-57: LGTM on removing the explicit return type.

Inferred Promise is preserved via the cast on response.json().

apps/cli/src/prompts/orm.ts (1)

24-30: LGTM on inference; minor note on union coverage.

Return paths still resolve to ORM (including "none" for convex). No action needed.

apps/cli/src/utils/generate-reproducible-command.ts (1)

3-3: LGTM.

Return type inference to string is obvious from the final template literal.

apps/cli/src/helpers/core/create-readme.ts (1)

27-27: LGTM on removing explicit string return types across helpers.

All functions still clearly return strings; inference is unambiguous.

Also applies to: 166-166, 213-213, 268-268, 352-352, 496-496, 594-594, 660-660

apps/cli/src/utils/bts-config.ts (1)

65-90: LGTM on inferred return type.

Inference still yields BetterTStackConfig | null; control flow unchanged.

apps/cli/src/helpers/database-providers/turso-setup.ts (1)

67-91: LGTM on groups fetch and parsing.

Behavior is sound; spinner usage and fallback to empty list are fine.

apps/cli/src/utils/ts-morph.ts (1)

19-31: LGTM on inferred return type; cast preserves API.

Implementation remains clear and correct.

apps/cli/src/prompts/web-deploy.ts (1)

7-9: LGTM on removing explicit return types.

Control flow and discriminated values remain intact; select<WebDeploy> keeps strong typing.

Also applies to: 39-70, 72-125

apps/cli/src/utils/compatibility-rules.ts (1)

15-17: LGTM on inferred returns.

isWebFrontend and allowedApisForFrontends read well; union narrowing is preserved.

Also applies to: 141-150

apps/cli/src/helpers/core/detect-project-config.ts (1)

5-32: LGTM on inferred return type.

Return shape matches prior behavior; nullability preserved.

apps/cli/src/prompts/server-deploy.ts (2)

34-39: LGTM! Clean removal of return type annotation.

The function's return type is correctly inferred as Promise<ServerDeploy> from the return statements.


81-85: LGTM! Clean removal of return type annotation.

The function's return type is correctly inferred as Promise<ServerDeploy> from the return statements.

apps/web/src/lib/stack-utils.ts (4)

28-28: LGTM! Clean removal of return type annotation.

The function's return type is correctly inferred as string from the ternary operator return statement.


54-54: LGTM! Clean removal of return type annotation.

The function's return type is correctly inferred as string from the return statement.


129-129: LGTM! Clean removal of return type annotation.

The function's return type is correctly inferred as string from the return statement.


147-147: LGTM! Clean removal of return type annotation.

The function's return type is correctly inferred as string from the return statement.

apps/cli/src/utils/biome-formatter.ts (4)

8-42: LGTM! Improved error handling with softer approach.

The changes improve error handling by returning null instead of logging and throwing on initialization errors. The removal of the explicit return type is clean, with the function type correctly inferred as Promise<{ biome: Biome; projectKey: number } | null>.


44-48: LGTM! Clean removal of return type annotation.

The function's return type is correctly inferred as boolean from the return statement.


50-62: LGTM! Enhanced skip patterns with clean type inference.

The expanded skip patterns include additional file types that should be excluded from formatting. The function's return type is correctly inferred as boolean.


64-90: LGTM! Improved error handling and clean type inference.

The changes implement softer error handling by returning null on failures and properly handle the nullable return from initializeBiome(). The function's return type is correctly inferred as Promise<string | null>.

apps/cli/src/index.ts (1)

221-230: LGTM: inferred return type for init

Return type inference remains stable due to the as InitResult cast on the returned value.

apps/cli/src/prompts/database.ts (1)

6-11: LGTM: remove explicit return type

Type inference is clear; function still resolves to Promise<Database>.

apps/cli/src/prompts/examples.ts (1)

10-16: LGTM: inferred return type

No behavior change; inference yields Promise<Examples[]>.

apps/cli/src/prompts/database-setup.ts (1)

5-11: LGTM: inferred return type

The control flow still results in Promise<DatabaseSetup>.

apps/cli/src/prompts/api.ts (1)

6-10: LGTM: inferred return type

Inferred as Promise<API>; early returns and select<API> keep types tight.

apps/cli/src/prompts/addons.ts (2)

75-79: LGTM: inferred return type for getAddonsChoice

Signatures rely on inference; generics on groupMultiselect<Addons> keep types precise.


131-134: LGTM: inferred return type for getAddonsToAdd

Type inference is adequate; no runtime changes.

apps/cli/src/prompts/config-prompts.ts (1)

53-58: LGTM: inferred return type for gatherConfig

Return object shape is explicit; inference is fine.

apps/cli/src/helpers/core/command-handlers.ts (3)

209-213: LGTM on inferred return type; return shape is consistent across branches.


40-43: LGTM — confirm/remove remaining InitResult references

Inferred return type is fine. rg shows InitResult still referenced; confirm these are intentional or update/remove them to match the new return shape:

  • apps/cli/src/index.ts: lines 30, 229, 262
  • apps/cli/src/types.ts: line 204 (InitResult interface)
  • apps/web/content/docs/cli/programmatic-api.mdx: lines 93, 156, 161

If stale, replace/remove uses (e.g., return result as InitResult) to avoid a mismatched public type.


128-131: Use resolved directory path (finalResolvedPath) for projectDirectory

projectDirectory must be the resolved filesystem path — passing input.projectName provides a name, not a path, and can break downstream validators.

File: apps/cli/src/helpers/core/command-handlers.ts (lines 128–131)

-  const cliInput = {
-    ...input,
-    projectDirectory: input.projectName,
-  };
+  const cliInput = {
+    ...input,
+    projectDirectory: finalResolvedPath,
+  };

Verify usages (run locally if file not found):
rg -n --hidden --files -g 'apps/cli/**' 'command-handlers.ts' || true
rg -n -C3 '\bprojectDirectory\b' apps/cli || true
rg -n -C3 '\bprojectName\b' apps/cli || true
rg -n -C3 '\bfinalResolvedPath\b' apps/cli || true
rg -n -C3 -e 'extractAndValidateProjectName(' -e 'deriveProjectName(' apps/cli || true

apps/cli/src/validation.ts (2)

47-52: LGTM on removing explicit return type.

Inference yields Partial; behavior unchanged.


89-93: LGTM on removing explicit return type.

Matches the pattern used in processAndValidateFlags.

apps/cli/src/utils/config-processing.ts (5)

23-27: LGTM on inferred return type for deriveProjectName.


36-38: LGTM on inferred return type for processFlags; explicit Partial on the local keeps the return typed.


107-113: LGTM on inferred return type for getProvidedFlags (Set inferred).


115-119: LGTM on inferred void for validateNoneExclusivity.


126-130: LGTM on inferred void for validateArrayOptions.

apps/cli/src/utils/config-validation.ts (9)

20-24: LGTM on removing explicit void.


91-97: LGTM on removing explicit void.


188-193: LGTM on removing explicit void.


243-247: LGTM on removing explicit void.


298-304: LGTM on removing explicit void.


353-359: LGTM on removing explicit void.


375-381: LGTM on removing explicit void.


392-398: LGTM on removing explicit void.


431-435: LGTM on removing explicit void.

apps/cli/src/prompts/project-name.ts (2)

16-24: Return-type inference here is fine

The inferred string | undefined works with downstream checks; no action needed.


44-44: Explicit local type is fine

Keeping defaultName: string is consistent with the PR scope (removing return types only). No change.

apps/cli/src/utils/project-directory.ts (2)

8-12: Signature return-type removal aligns with PR goals

Type inference remains precise for the returned object and early-exit paths. LGTM.


83-87: Signature return-type removal aligns with PR goals

Inferred { finalResolvedPath: string; finalBaseName: string } is clear. LGTM.

apps/cli/src/utils/project-name-validation.ts (2)

5-14: Return-type removal is safe

Function performs side effects only; inferred void is appropriate.


23-47: Extractor validator: OK

Inferred string return is preserved; flow remains unchanged. LGTM.

apps/cli/src/utils/docker-utils.ts (1)

20-51: Return-type removal: install instructions

Inferred string return is clear; content unchanged. LGTM.

@@ -1,4 +1,5 @@
import os from "node:os";
import { $ } from "execa";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Replace execa with Bun.$ per repo guidelines

This project standardizes on Bun for shelling out. Switch to Bun.$ (or import { $ } from "bun").

-import { $ } from "execa";
+import { $ } from "bun";

No other changes needed since the template-literal API is compatible:

export async function isDockerRunning() {
  try {
    await $`docker info`;
    return true;
  } catch {
    return false;
  }
}
🤖 Prompt for AI Agents
In apps/cli/src/utils/docker-utils.ts around line 2, the file imports $ from
"execa" but the repo standard requires using Bun's shell helper; replace the
execa import with Bun's ($ from "bun") or reference Bun.$ directly. Update the
import statement to pull $ from "bun" (or remove the import and use Bun.$) and
leave the rest of the code unchanged since the template-literal API is
compatible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants