Skip to content

Init script agent mode and react option#897

Merged
BilalG1 merged 9 commits intodevfrom
non-interactive-init-script
Sep 16, 2025
Merged

Init script agent mode and react option#897
BilalG1 merged 9 commits intodevfrom
non-interactive-init-script

Conversation

@BilalG1
Copy link
Collaborator

@BilalG1 BilalG1 commented Sep 15, 2025

High-level PR Summary

This PR adds support for non-interactive initialization in the Stack Auth initialization script. It introduces a STACK_DISABLE_INTERACTIVE environment variable flag and makes appropriate changes throughout the codebase to handle non-interactive flows. The changes include improving type definitions, adding automatic determination of project type (JS vs Next.js) and configuration (client vs server) when running in non-interactive mode, and better error handling for cases where required information is missing. These changes enable CI/CD scenarios and automation for Stack Auth integration.

⏱️ Estimated Review Time: 0h 20m

💡 Review Order Suggestion
Order File Path
1 packages/init-stack/src/index.ts

Review by RecurseML

🔍 Review performed on bba4db2..974e4fd

✨ No bugs found, your code is sparkling clean

✅ Files analyzed, no issues (1)

packages/init-stack/src/index.ts

Need help? Join our Discord


Important

Adds non-interactive and React project initialization options to Stack Auth setup script, updates tests and documentation.

  • Behavior:
    • Adds --agent-mode option in index.ts for non-interactive CLI runs.
    • Adds --react option in index.ts for React project initialization.
    • Updates writeReactClientFile() in index.ts to handle React-specific setup.
  • Scripts:
    • Updates package.json to include test-run-react and test-run-react:manual scripts.
    • Modifies existing test scripts in package.json to use --agent-mode.
  • Documentation:
    • Updates setup.mdx to include React setup instructions and wizard/manual tabs.
  • Misc:
    • Removes STACK_DISABLE_INTERACTIVE checks in index.ts.
    • Updates error handling and logging in index.ts.

This description was created by Ellipsis for f63a2a5. You can customize this summary. It will automatically update as commits are pushed.


Summary by CodeRabbit

  • New Features

    • First-class React project initialization (--react) with automatic React client scaffolding.
    • Added --agent-mode for fully non-interactive CLI runs and consistent --no-browser behavior.
    • Public env var for local React package override (STACK_REACT_INSTALL_PACKAGE_NAME_OVERRIDE).
  • Chores

    • Standardized non-interactive flows across scripts (removed legacy interactive gating).
  • Tests

    • Updated test scaffolding and run commands to use agent-mode and browser-free execution.
  • Documentation

    • Converted setup docs to a wizard-style experience with consolidated wizard/manual tabs.

@vercel
Copy link

vercel bot commented Sep 15, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
stack-backend Ready Ready Preview Comment Sep 16, 2025 0:36am
stack-dashboard Ready Ready Preview Comment Sep 16, 2025 0:36am
stack-demo Ready Ready Preview Comment Sep 16, 2025 0:36am
stack-docs Ready Ready Preview Comment Sep 16, 2025 0:36am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 15, 2025

Walkthrough

Adds React as a first-class init target and a non-interactive --agent-mode. Expands CLI flags, strong-typed project types, and scaffolding (including Steps.writeReactClientFile). Test-run scripts replace STACK_DISABLE_INTERACTIVE with --agent-mode/--no-browser and add a local React package override. Docs move to a wizard/manual Tabs layout.

Changes

Cohort / File(s) Summary
Test run scripts & package override
packages/init-stack/package.json
Adds STACK_REACT_INSTALL_PACKAGE_NAME_OVERRIDE=../../react. Replaces STACK_DISABLE_INTERACTIVE usages with --agent-mode and --no-browser across test-run scripts; updates scaffolding flags for non-interactive automated runs.
Init CLI core and steps
packages/init-stack/src/index.ts
Adds --react and --agent-mode flags; expands project type union to `"js"
Docs: getting-started wizard
docs/templates/getting-started/setup.mdx
Replaces linear per-framework steps with a Tabs-style wizard + manual tab; consolidates install/update/wrap steps and provides unified examples for React/JS/Next flows.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User / CI
  participant CLI as init-stack CLI
  participant Steps as Steps core
  participant PM as Package Manager
  participant FS as Filesystem
  participant Browser as Browser

  U->>CLI: run init-stack [--js | --next | --react] [--agent-mode] [--no-browser]
  CLI->>Steps: parse flags, read package.json
  Steps->>Steps: detect project type ("js"/"next"/"react")
  alt agent-mode and missing interactive input
    Steps-->>CLI: throw UserError
    CLI-->>U: exit with error
  else proceed
    Steps->>PM: resolve package manager (non-interactive if agent-mode)
    Steps->>PM: add stack package (type-specific mapping, react override supported)
    Steps->>FS: write env vars / app files
    alt type == react
      Steps->>FS: write React client file (router-aware)
    else
      Steps->>FS: write Next/JS Stack app files
    end
    alt no-browser is false
      CLI->>Browser: open URL
    else
      CLI-->>U: print next steps
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I nibble keys and spin a tiny plot,
React hops in — a new friend on the lot.
Agent-mode hums, no prompts to delay,
Tests run headless, brisk as a day.
Burrow polished, docs in wizard sway 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description contains detailed summaries and the repository template comment, but it includes a factual inconsistency: it claims a STACK_DISABLE_INTERACTIVE environment flag was introduced while the file summaries and PR objectives indicate STACK_DISABLE_INTERACTIVE was removed and replaced by a new --agent-mode CLI option, which makes the description inaccurate. Please update the PR description to accurately reflect the code changes: state that --agent-mode was added and STACK_DISABLE_INTERACTIVE was removed, document the new --react option and the added writeReactClientFile behavior, and align the autogenerated RECURSEML/ellipsis summary with the actual diffs and updated package.json scripts; include brief usage or CI testing notes for the non-interactive flow if available.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title "Init script agent mode and react option" succinctly and accurately summarizes the main changes—adding a non-interactive agent-mode to the init script and introducing a React initialization option—making it clear, specific, and relevant for team history scanning.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch non-interactive-init-script

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.

@BilalG1 BilalG1 marked this pull request as ready for review September 15, 2025 19:21
@claude
Copy link
Contributor

claude bot commented Sep 15, 2025

Claude finished @BilalG1's task —— View job


I'll analyze this and get back to you.

@BilalG1 BilalG1 changed the title Non interactive init script Init script agent mode and react option Sep 15, 2025
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Summary

This PR adds comprehensive non-interactive support to the Stack Auth initialization script, enabling automated CI/CD workflows and expanding framework support. The main changes include:

New Command-Line Interface: Replaces the STACK_DISABLE_INTERACTIVE environment variable with a cleaner --agent-mode flag that disables interactive prompts. This provides a more discoverable and explicit way to run automated setups.

React Framework Support: Introduces a new --react flag and associated project type handling for React applications. The script can now detect React projects by checking for react and react-dom dependencies and includes specific setup logic for React Router DOM integration.

Improved Type Safety: Replaces loose string types with strict union types ('js' | 'next' | 'react') for project types, reducing the risk of runtime errors and improving code maintainability.

Automatic Project Detection: When running in agent mode, the script now automatically determines the project type by analyzing dependencies - Next.js projects are detected via Next.js dependencies, React projects via React dependencies, with vanilla JavaScript as the fallback.

Enhanced Error Handling: Adds proper validation to ensure required arguments are provided when running in non-interactive mode, preventing silent failures in automated environments.

These changes integrate with the existing codebase by extending the Steps object with new methods like writeReactClientFile() and enhancing existing functions to handle the new project types. The implementation maintains full backward compatibility while enabling Stack Auth to work seamlessly in automated deployment pipelines.

Confidence score: 4/5

  • This PR is safe to merge with minimal risk as it adds new functionality without breaking existing behavior
  • Score reflects well-structured code changes with proper type safety improvements and comprehensive project type handling
  • Pay close attention to the automatic project type detection logic in agent mode to ensure it correctly identifies different project types

2 files reviewed, no comments

Edit Code Review Bot Settings | Greptile

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: 0

🧹 Nitpick comments (4)
packages/init-stack/src/index.ts (4)

61-61: Consider using a Map for type resolution.

While the current implementation works, using an ES6 Map would be more maintainable and follow the coding guidelines.

Consider refactoring to use a Map:

-const typeFromArgs: "js" | "next" | "react" | undefined = options.js ? "js" : options.next ? "next" : options.react ? "react" : undefined;
+const typeOptionsMap = new Map([
+  ["js", options.js],
+  ["next", options.next],
+  ["react", options.react]
+]);
+const typeFromArgs = Array.from(typeOptionsMap.entries()).find(([_, enabled]) => enabled)?.[0] as "js" | "next" | "react" | undefined;

606-606: Unnecessary type assertion can be removed.

The type of clientOrServer is already constrained to "server" | "client", so the type assertion is redundant.

-    }[clientOrServer as "client" | "server"];
+    }[clientOrServer];

638-638: Complex template literal could be simplified.

The inline conditional logic makes this template string hard to read and maintain. Consider extracting the configuration object construction.

Consider extracting the configuration logic:

+const getTokenStoreConfig = (type: "js" | "next" | "react", clientOrServer: "client" | "server") => {
+  if (type === "next") return '"nextjs-cookie"';
+  return clientOrServer === "client" ? '"cookie"' : '"memory"';
+};
+
+const buildConfigProperties = (type: "js" | "next" | "react", clientOrServer: "client" | "server", indentation: string) => {
+  const props = [`${indentation}tokenStore: ${getTokenStoreConfig(type, clientOrServer)}`];
+  
+  if (type === "js") {
+    props.push(`\n${indentation}// get your Stack Auth API keys from https://app.stack-auth.com${clientOrServer === "client" ? ` and store them in a safe place (eg. environment variables)` : ""}`);
+    if (projectIdFromArgs) props.push(`\n${indentation}projectId: '${projectIdFromArgs}'`);
+    props.push(`\n${indentation}publishableClientKey: ${publishableClientKeyWrite}`);
+    if (clientOrServer === "server") props.push(`\n${indentation}secretServerKey: process.env.STACK_SECRET_SERVER_KEY`);
+  }
+  
+  return props.join(',');
+};

 export const stack${clientOrServerCap}App = new Stack${clientOrServerCap}App({
-${indentation}tokenStore: ${type === "next" ? '"nextjs-cookie"' : (clientOrServer === "client" ? '"cookie"' : '"memory"')},${type === "js" ? `\n\n${indentation}// get your Stack Auth API keys from https://app.stack-auth.com${clientOrServer === "client" ? ` and store them in a safe place (eg. environment variables)` : ""}` : ""}${type === "js" && projectIdFromArgs ? `\n${indentation}projectId: '${projectIdFromArgs}',` : ""}${type === "js" ? `\n${indentation}publishableClientKey: ${publishableClientKeyWrite},` : ""}${type === "js" && clientOrServer === "server" ? `\n${indentation}secretServerKey: process.env.STACK_SECRET_SERVER_KEY,` : ""}
+${buildConfigProperties(type, clientOrServer, indentation)}
 });

729-734: Consider using Map for type string mapping.

Following the coding guidelines preference for ES6 Map over Record/object literals.

-    const typeStringMap = {
-      js: "JavaScript",
-      next: "Next.js",
-      react: "React",
-    } as const;
-    const typeString = typeStringMap[type];
+    const typeStringMap = new Map([
+      ["js", "JavaScript"],
+      ["next", "Next.js"],
+      ["react", "React"]
+    ] as const);
+    const typeString = typeStringMap.get(type);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bba4db2 and bf0d1dd.

📒 Files selected for processing (2)
  • packages/init-stack/package.json (1 hunks)
  • packages/init-stack/src/index.ts (20 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer ES6 Map over Record when representing key–value collections

Files:

  • packages/init-stack/src/index.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: build (22.x)
  • GitHub Check: all-good
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: build (22.x)
  • GitHub Check: restart-dev-and-test
  • GitHub Check: setup-tests
  • GitHub Check: docker
  • GitHub Check: docker
  • GitHub Check: Security Check
🔇 Additional comments (19)
packages/init-stack/package.json (2)

15-15: LGTM! React package override added correctly.

The addition of STACK_REACT_INSTALL_PACKAGE_NAME_OVERRIDE=../../react is consistent with the existing pattern for Next.js and JS overrides.


21-31: Consistent migration to agent-mode across test scripts.

The test scripts have been uniformly updated to use --agent-mode and --no-browser flags, replacing the environment variable approach. This provides better CLI ergonomics and explicit control flow.

packages/init-stack/src/index.ts (17)

39-39: React option added to CLI.

The addition of --react option follows the existing pattern for framework selection.


49-49: Agent mode flag added for CI/CD workflows.

The --agent-mode option properly enables non-interactive execution for automation scenarios.


67-67: LGTM! Agent mode flag captured correctly.

The agentMode variable is properly initialized from the CLI options.


210-223: React project initialization implemented correctly.

The React-specific initialization properly:

  1. Detects react-router-dom dependency
  2. Writes a client file with appropriate configuration
  3. Provides clear next steps for environment variable setup

256-256: Consider using Map for install commands.

Good use of Map here for package manager commands, aligning with ES6 best practices.


380-380: Type union properly updated for ProjectInfo.

The type field correctly includes "react" in the union type.


394-394: Type union properly updated for StackAppFileOptions.

The type field correctly includes "react" in the union type.


429-441: Project type detection logic handles React correctly.

The function properly:

  1. Returns CLI-specified type if provided
  2. Detects Next.js projects
  3. Falls back to React if react/react-dom dependencies exist
  4. Defaults to "js" in agent mode
  5. Prompts user in interactive mode

459-466: Stack package name resolution updated for React.

The function correctly maps project types to their respective package names with proper override support.


540-551: Environment variable templates properly handle agent mode.

The conditional logic correctly provides different guidance based on whether browser will open.


645-675: React client file generation implemented correctly.

The function properly:

  1. Checks for existing files to avoid overwrites
  2. Conditionally imports and configures react-router-dom
  3. Generates appropriate client configuration

693-693: TypeScript type annotation handled correctly.

The conditional TypeScript type annotation for the handler props is appropriate.


735-735: Agent mode check properly prevents interactive prompt.

The conditional logic correctly skips the confirmation prompt in agent mode.


753-755: Proper error handling in agent mode for missing arguments.

The function correctly throws a descriptive error when required information is missing in non-interactive mode.


893-895: Agent mode properly handles missing package.json.

The error message provides clear guidance on how to resolve the issue.


938-940: Agent mode properly handles ambiguous package manager detection.

The error message clearly explains which arguments to use.


1086-1101: Input clearing properly handles TTY mode.

The function correctly checks for TTY mode before attempting to set raw mode, preventing errors in non-interactive environments.

@BilalG1 BilalG1 assigned N2D4 and unassigned BilalG1 Sep 15, 2025
@BilalG1 BilalG1 requested a review from N2D4 September 15, 2025 19:54
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: 0

♻️ Duplicate comments (1)
docs/templates/getting-started/setup.mdx (1)

300-331: Duplicate of the Router sample: ensure consistency once redirectMethod is resolved.

Once the redirectMethod API is verified, please mirror the same corrected pattern in both wizard and manual examples to avoid diverging guidance.

🧹 Nitpick comments (5)
docs/templates/getting-started/setup.mdx (5)

167-167: Fix broken/mismatched sign-up URL in Next.js section.

Anchor text and href differ: "signup" vs "sign-up". Use the hyphenated route consistently.

-That's it! Stack is now configured in your Next.js project. If you start your Next.js app with `npm run dev` and navigate to [http://localhost:3000/handler/signup](http://localhost:3000/handler/sign-up), you will see the sign-up page.
+That's it! Stack is now configured in your Next.js project. If you start your Next.js app with `npm run dev` and navigate to [http://localhost:3000/handler/sign-up](http://localhost:3000/handler/sign-up), you will see the sign-up page.

188-191: Minor copy tweak: “set up” (verb) and clarity on the example.

-Before getting started, make sure you have a [React project](https://react.dev/learn/creating-a-react-app) setup. We show an example here of a Vite React project.
-We recommend using our **setup wizard** for a seamless installation experience. The wizard automatically detects your project structure and walks you through the setup process. If you encounter any issues with the wizard, you can follow our manual installation steps instead.
+Before getting started, make sure you have a [React project](https://react.dev/learn/creating-a-react-app) set up. The examples below use a Vite React project.
+We recommend using our **setup wizard** for a seamless installation. It automatically detects your project structure and walks you through the steps. If you encounter issues, use the manual installation instead.

205-207: Consider adding a short CI note for the new non-interactive flag.

A tiny callout helps users running this in CI discover the new --agent-mode (and --no-browser) without hunting CLI docs.

 npx @stackframe/init-stack@latest
+
+> Note: Running in CI or non-interactively? Use:
+> `npx @stackframe/init-stack@latest --agent-mode --no-browser`

212-213: Clarify where to store keys for Vite and avoid accidental client/secret confusion.

  • Suggest showing Vite env variable names so users don’t hardcode values.
  • Explicitly remind that the secret server key must never be added to client bundles (not shown here, but worth a one-liner).
-Then, create an account on [the Stack Auth dashboard](https://app.stack-auth.com/projects), create a new project with an API key, and copy its values into the `stack/client.ts` file created by the wizard.
+Then, create an account on [the Stack Auth dashboard](https://app.stack-auth.com/projects), create a new project with an API key, and provide the Project ID and Publishable Client Key to the wizard output.
+
+For Vite projects, prefer environment variables:
+
+```sh title=".env"
+VITE_STACK_PROJECT_ID=<your-project-id>
+VITE_STACK_PUBLISHABLE_CLIENT_KEY=<your-publishable-client-key>
+```
+
+Never include your secret server key in client-side code.

283-295: Clarify redirectMethod usage: document hook vs function and show both examples

Verified: redirectMethod accepts either an object with useNavigate (hook form) or a navigate function; the template currently shows { useNavigate }. Update docs/templates/getting-started/setup.mdx (lines 283–295) and packages/init-stack/src/index.ts (≈662–668) to state: use { useNavigate } when calling app.useNavigate() from React components (hook rules apply), or pass a captured navigate function (e.g., via useNavigate() + useMemo) as { navigate } for redirects outside components. Reference implementation/types: packages/template/src/lib/stack-app/common.ts and packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf0d1dd and fc37c11.

📒 Files selected for processing (1)
  • docs/templates/getting-started/setup.mdx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: setup-tests
  • GitHub Check: restart-dev-and-test
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: build (22.x)
  • GitHub Check: build (22.x)
  • GitHub Check: docker
  • GitHub Check: docker
  • GitHub Check: all-good
  • GitHub Check: Security Check
🔇 Additional comments (4)
docs/templates/getting-started/setup.mdx (4)

253-261: Nice: clear “Done” path and routes.

The dev server port and routes look correct for Vite. The image block and follow-up links are consistent.


269-272: Install command LGTM.

Package name matches the new React package entry; no peer deps implied here. Good.


333-344: Manual React flow reads well.

The steps are coherent and align with the wizard path. Once the redirectMethod detail is finalized, this section will be solid.


219-247: Verify StackHandler props for React: confirm location is a pathname string and fullPage flag

Docs/examples pass location={location.pathname} while server-side code uses routeProps={props}; I could not find the StackHandler prop/type definition in the repo to confirm the expected shape. Confirm that @stackframe/react's StackHandler expects location: string (not a Location object) and that fullPage is still the correct prop; update docs/examples if the API differs.

Locations: docs/templates/getting-started/setup.mdx (client example ~lines 219–247), examples/react-example/src/App.tsx.

@github-actions github-actions bot assigned BilalG1 and unassigned N2D4 Sep 15, 2025
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: 0

🧹 Nitpick comments (11)
packages/init-stack/src/index.ts (11)

39-39: Enforce mutual exclusivity for --js/--next/--react; fail fast when multiple are provided.

Right now precedence is implicit (js > next > react). Add a guard to avoid accidental misselection, especially in CI.

 import { Command } from "commander";
+import { Option } from "commander";
@@
 program
   .name(packageJson.name)
@@
-  .option("--react", "Initialize for React project")
+  .addOption(new Option("--react", "Initialize for React project").conflicts(["js", "next"]))
   .option("--npm", "Use npm as package manager")
@@
-  .option("--agent-mode", "Run without prompting for any input")
+  .option("--agent-mode", "Run without prompting for any input")
@@
-const typeFromArgs: "js" | "next" | "react" | undefined = options.js ? "js" : options.next ? "next" : options.react ? "react" : undefined;
+const typeFromArgs: "js" | "next" | "react" | undefined =
+  options.js ? "js" : options.next ? "next" : options.react ? "react" : undefined;
+const selectedTypes = [options.js, options.next, options.react].filter(Boolean).length;
+if (selectedTypes > 1) {
+  throw new UserError("Please specify exactly one of --js, --next, or --react.");
+}

Also applies to: 49-49, 61-61, 67-67


210-223: React path wiring: good flow; minor: consider consistent indentation detection.

Hardcoding indentation to two spaces works, but you could reuse guessIndentation from an existing file (if any) for consistency.


429-441: React detection should also consider devDependencies.

Some templates pin react in devDependencies. Expand the check to avoid false negatives.

-    if (packageJson.dependencies?.["react"] || packageJson.dependencies?.["react-dom"]) {
+    if (
+      packageJson.dependencies?.react ||
+      packageJson.devDependencies?.react ||
+      packageJson.dependencies?.["react-dom"] ||
+      packageJson.devDependencies?.["react-dom"]
+    ) {
       return "react";
     }

459-466: Prefer ES6 Map over object literal for package mapping (per repo guidelines).

Functional behavior is fine; Map better signals key–value intent and avoids accidental key widening.

-  async getStackPackageName(type: "js" | "next" | "react", install = false): Promise<string> {
-    const mapping = {
-      js: (install && process.env.STACK_JS_INSTALL_PACKAGE_NAME_OVERRIDE) || "@stackframe/js",
-      next: (install && process.env.STACK_NEXT_INSTALL_PACKAGE_NAME_OVERRIDE) || "@stackframe/stack",
-      react: (install && process.env.STACK_REACT_INSTALL_PACKAGE_NAME_OVERRIDE) || "@stackframe/react",
-    } as const;
-    return mapping[type];
-  },
+  async getStackPackageName(type: "js" | "next" | "react", install = false): Promise<string> {
+    const mapping = new Map<"js" | "next" | "react", string>([
+      ["js",   (install && process.env.STACK_JS_INSTALL_PACKAGE_NAME_OVERRIDE)   || "@stackframe/js"],
+      ["next", (install && process.env.STACK_NEXT_INSTALL_PACKAGE_NAME_OVERRIDE) || "@stackframe/stack"],
+      ["react",(install && process.env.STACK_REACT_INSTALL_PACKAGE_NAME_OVERRIDE)|| "@stackframe/react"],
+    ]);
+    return mapping.get(type)!;
+  },

Also applies to: 468-468


626-636: Harden string injection for keys; prefer nullish coalescing for env fallback.

Avoid breaking literals if keys contain quotes and don’t treat empty string as “unset”.

-    const publishableClientKeyWrite = clientOrServer === "server"
-      ? `process.env.STACK_PUBLISHABLE_CLIENT_KEY ${publishableClientKeyFromArgs ? `|| '${publishableClientKeyFromArgs}'` : ""}`
-      : `'${publishableClientKeyFromArgs ?? 'INSERT_YOUR_PUBLISHABLE_CLIENT_KEY_HERE'}'`;
+    const publishableClientKeyWrite = clientOrServer === "server"
+      ? `process.env.STACK_PUBLISHABLE_CLIENT_KEY${publishableClientKeyFromArgs ? ` ?? ${JSON.stringify(publishableClientKeyFromArgs)}` : ""}`
+      : JSON.stringify(publishableClientKeyFromArgs ?? "INSERT_YOUR_PUBLISHABLE_CLIENT_KEY_HERE");
@@
-    const jsOptions = type === "js" ? [
+    const jsOptions = type === "js" ? [
       `\n\n${indentation}// get your Stack Auth API keys from https://app.stack-auth.com${clientOrServer === "client" ? ` and store them in a safe place (eg. environment variables)` : ""}`,
-      `${projectIdFromArgs ? `${indentation}projectId: '${projectIdFromArgs}',` : ""}`,
+      `${projectIdFromArgs ? `${indentation}projectId: ${JSON.stringify(projectIdFromArgs)},` : ""}`,
       `${indentation}publishableClientKey: ${publishableClientKeyWrite},`,
       `${clientOrServer === "server" ? `${indentation}secretServerKey: process.env.STACK_SECRET_SERVER_KEY,` : ""}`,
     ].filter(Boolean).join("\n") : "";

Also applies to: 646-647


653-684: writeReactClientFile: quote safely, polish placeholders, normalize formatting.

Use JSON.stringify for literals; align placeholder text; trim output for consistency.

-    const publishableClientKeyWrite = `'${publishableClientKeyFromArgs ?? 'INSERT_YOUR_PUBLISHABLE_CLIENT_KEY_HERE'}'`;
-    const projectIdWrite = `'${projectIdFromArgs ?? 'INSERT_PROJECT_ID'}'`;
+    const publishableClientKeyWrite = ${JSON.stringify(publishableClientKeyFromArgs ?? "INSERT_YOUR_PUBLISHABLE_CLIENT_KEY_HERE")};
+    const projectIdWrite = ${JSON.stringify(projectIdFromArgs ?? "INSERT_YOUR_PROJECT_ID")};
@@
-    laterWriteFileIfNotExists(
-      stackAppPath,
-      `${imports}export const stackClientApp = new StackClientApp({ \n${indentation}tokenStore: "cookie", \n${indentation}projectId: ${projectIdWrite}, \n${indentation}publishableClientKey: ${publishableClientKeyWrite}${redirectMethod}, \n}); \n`
-    );
+    laterWriteFileIfNotExists(
+      stackAppPath,
+      (
+`${imports}export const stackClientApp = new StackClientApp({
+${indentation}tokenStore: "cookie",
+${indentation}projectId: ${projectIdWrite},
+${indentation}publishableClientKey: ${publishableClientKeyWrite}${redirectMethod},
+});
+`).trim() + "\n"
+    );

696-703: Fix spacing/grammar in error and tidy the generated handler formatting.

Minor UX nit + cleaner JSX spacing.

-        `A file at the path ${handlerPath} already exists.Stack uses the / handler path to handle incoming requests.Please remove the existing file and try again.`
+        `A file at the path ${handlerPath} already exists. Stack uses the /handler/[...stack]/page route to handle incoming requests. Please remove the existing file and try again.`
@@
-      `import { StackHandler } from "@stackframe/stack"; \nimport { stackServerApp } from "../../../stack/server"; \n\nexport default function Handler(props${handlerFileExtension.includes("ts") ? ": unknown" : ""
-      }) { \n${projectInfo.indentation} return <StackHandler fullPage app = { stackServerApp } routeProps = { props } />; \n } \n`
+      `import { StackHandler } from "@stackframe/stack";
+import { stackServerApp } from "../../../stack/server";
+
+export default function Handler(props${handlerFileExtension.includes("ts") ? ": unknown" : ""}) {
+${projectInfo.indentation}return <StackHandler fullPage app={stackServerApp} routeProps={props} />;
+}
+`

739-744: Nit: prefer Map for typeStringMap (style guideline).

Semantically a map; tiny refactor keeps style consistent with installCommandMap.

-    const typeStringMap = {
-      js: "JavaScript",
-      next: "Next.js",
-      react: "React",
-    } as const;
-    const typeString = typeStringMap[type];
+    const typeString = new Map([
+      ["js", "JavaScript"],
+      ["next", "Next.js"],
+      ["react", "React"],
+    ]).get(type)!;

762-764: Improve agent-mode error message to mention “both” option.

Clarify how to request both sides non-interactively.

-      throw new UserError("Please specify the installation type using the --server or --client argument.");
+      throw new UserError("Please specify the installation type using --server or --client (or pass both flags for both).");

902-904: Fix misleading flag name in error message.

There is no --project-path option; it’s a positional argument.

-        throw new UserError(`No package.json file found in the project directory ${savedProjectPath}. Please specify the correct project path using the --project-path argument, or create a new project before running the wizard.`);
+        throw new UserError(`No package.json file found in the project directory ${savedProjectPath}. Please pass the correct [project-path] positional argument, or create a new project before running the wizard.`);

1095-1110: Guard setRawMode availability and always restore TTY mode.

Avoid crashes on non-TTY streams and ensure restoration even if flush is called early.

-    if (process.stdin.isTTY) {
-      process.stdin.setRawMode(true);
-    }
+    const canSetRaw = process.stdin.isTTY && typeof (process.stdin as any).setRawMode === "function";
+    if (canSetRaw) (process.stdin as any).setRawMode(true);
@@
-    const flush = () => {
+    const flush = () => {
       while (process.stdin.read() !== null) { }
-      if (process.stdin.isTTY) {
-        process.stdin.setRawMode(false);
-      }
+      if (canSetRaw) (process.stdin as any).setRawMode(false);
       resolve();
     };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc37c11 and f63a2a5.

📒 Files selected for processing (2)
  • packages/init-stack/package.json (1 hunks)
  • packages/init-stack/src/index.ts (22 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/init-stack/package.json
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer ES6 Map over Record when representing key–value collections

Files:

  • packages/init-stack/src/index.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: build (22.x)
  • GitHub Check: all-good
  • GitHub Check: restart-dev-and-test
  • GitHub Check: docker
  • GitHub Check: build (22.x)
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: docker
  • GitHub Check: Security Check
🔇 Additional comments (5)
packages/init-stack/src/index.ts (5)

331-333: Browser open gating LGTM.

Switching to solely --no-browser is clear and predictable.


380-386: Type surface updated to include "react" — looks consistent.

No issues spotted; downstream uses appear aligned.

Also applies to: 394-399


521-552: Next env file writer: LGTM.

Creates .env.local only when none is present and pre-fills values when provided.


713-715: Next loading file scaffold: LGTM.

Clear comment; no behavior risks.


947-949: Package manager agent-mode guard: LGTM.

Clear guidance and fail-fast behavior.

@BilalG1 BilalG1 merged commit 23b9eb8 into dev Sep 16, 2025
19 of 21 checks passed
@BilalG1 BilalG1 deleted the non-interactive-init-script branch September 16, 2025 01:47
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