Skip to content

Feature/easy setup#464

Merged
liangshuo-1 merged 1 commit intomainfrom
feature/easy-setup
Apr 15, 2026
Merged

Feature/easy setup#464
liangshuo-1 merged 1 commit intomainfrom
feature/easy-setup

Conversation

@mazhe-nerd
Copy link
Copy Markdown
Collaborator

@mazhe-nerd mazhe-nerd commented Apr 14, 2026

Summary

新增 npx @larksuite/cli install 一键安装命令,引导用户完成全局安装 CLI、安装 AI
Skills、应用配置和用户授权。

Changes

  • 新增 scripts/install-wizard.js:4 步交互式引导流程(全局安装 → Skills → config init → auth
    login),零外部依赖
  • 修改 scripts/run.js:拦截 install 子命令走引导流程;二进制缺失时自动下载,通过 LARK_CLI_RUN
    环境变量绕过 npx 检测
  • 修改 scripts/install.js:检测 npx 环境(npm_command === "exec")时跳过 postinstall 二进制下载,避免 npx
    因下载失败而中止
  • 修改 package.json:files 数组新增 install-wizard.js

Test Plan

  • npx -y @larksuite/cli install 在干净环境下完成全部安装流程
  • 已全局安装 CLI 时自动跳过
  • 已安装 Skills 时自动跳过
  • 已有应用配置时提示是否复用
  • npm install -g @larksuite/cli 的 postinstall 仍正常下载二进制
  • npx @larksuite/cli <其他命令> 自动下载二进制并正常执行
  • auth login 步骤可通过 n 跳过

Related Issues

  • None

Summary by CodeRabbit

  • New Features

    • Interactive 4-step setup wizard for initial CLI installation, configuration, and optional authorization.
    • CLI now auto-triggers the setup wizard for install commands and can attempt automatic installation when the native CLI is missing.
  • Chores

    • Package version bumped to 1.0.11 and the installer included in published artifacts.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new interactive installation wizard (scripts/install-wizard.js), publishes it via package.json (version bumped to 1.0.11 and files whitelist updated), and updates scripts/install.js and scripts/run.js to route install to the wizard and provide an auto-install fallback when the native binary is missing.

Changes

Cohort / File(s) Summary
Package Configuration
package.json
Bumped @larksuite/cli 1.0.101.0.11; added scripts/install-wizard.js to the npm files whitelist.
Installation Wizard (new)
scripts/install-wizard.js
New executable CLI script implementing a 4-step interactive setup: detect/install global lark-cli, check/install lark-* skills, init or reuse config, and optional auth login; includes prompting, spinners, command helpers, and error guidance.
Installer & Entrypoint Flow
scripts/install.js, scripts/run.js
scripts/install.js: strip prerelease suffix from VERSION and early-exit for npm exec when LARK_CLI_RUN unset. scripts/run.js: special-case "install" to load the wizard; otherwise attempt auto-install via scripts/install.js (with LARK_CLI_RUN) when native bin/lark-cli is missing before executing the native binary.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as run.js
    participant Wizard as install-wizard.js
    participant NPM as npm/npx
    participant Binary as lark-cli
    participant Skills as Skills System
    participant Config as Config System
    participant Auth as Auth System

    User->>CLI: run `lark-cli install` (or other cmd)
    CLI->>CLI: parse args
    alt args == "install"
        CLI->>Wizard: load & execute install-wizard.js
        Wizard->>NPM: check for global `lark-cli` (which / --version)
        alt not found
            Wizard->>NPM: `npm install -g `@larksuite/cli``
            NPM-->>Wizard: install result
        else found
            NPM-->>Wizard: version info
        end

        Wizard->>NPM: `npx skills ls -g --json`
        alt no lark-* skills
            Wizard->>NPM: `npx skills add https://github.com/larksuite/cli -y -g`
            NPM-->>Wizard: install result
        else skills present
            NPM-->>Wizard: skills list
        end

        Wizard->>Binary: `lark-cli config show`
        alt appId exists
            Binary-->>Wizard: appId
            Wizard->>User: prompt reuse or reinit
        else no config
            Wizard->>Binary: `lark-cli config init --new`
            Binary-->>Wizard: init result
        end

        Wizard->>User: prompt for auth
        alt consent
            Wizard->>Binary: `lark-cli auth login`
            Binary->>Auth: auth flow
            Auth-->>Binary: result
            Binary-->>Wizard: result
        else decline
            Wizard-->>User: skip auth
        end

        Wizard->>User: completion guidance
    else
        CLI->>CLI: detect native binary
        alt binary missing
            CLI->>NPM: exec scripts/install.js with LARK_CLI_RUN to auto-install
            NPM-->>CLI: install result
            CLI->>Binary: execFileSync(bin, args)
        else binary present
            CLI->>Binary: execFileSync(bin, args)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

size/L

Suggested reviewers

  • liangshuo-1
  • JackZhao10086

Poem

🐰 I hopped through code to guide your first command,
With prompts and spinners I lend a gentle hand.
Skills, config, and auth — one trail to begin,
Follow my pawprints, and your CLI will win. 🥕✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Feature/easy setup' is vague and generic, using non-descriptive terms that don't convey what the feature actually does or what the main change is. Use a more specific title that describes the feature, such as 'Add one-step install wizard for easy CLI setup' or 'Introduce interactive setup flow via npx @larksuite/cli install'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description covers all required sections (Summary, Changes, Test Plan, Related Issues) with substantive details, though written in Chinese rather than English.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/easy-setup

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.

@github-actions github-actions bot added the size/L Large or sensitive change across domains or core paths label Apr 14, 2026
Comment thread scripts/install-wizard.js Fixed
Comment thread scripts/install-wizard.js Fixed
Comment thread scripts/install-wizard.js Fixed
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 14, 2026

Greptile Summary

This PR adds an interactive 4-step setup wizard (install-wizard.js) invoked via npx @larksuite/cli install, guiding users through global CLI installation, AI Skills setup, app configuration, and optional auth login. It also fixes a long-standing pain point where npx would skip the postinstall binary download, causing confusing errors for non-install commands.

Confidence Score: 4/5

  • Mostly safe to merge; a previously flagged Windows ENOENT issue for bare npm/npx via execFileSync remains unresolved in the wizard.
  • The core logic for skipping postinstall under npx and auto-downloading the binary is sound. The only new finding is the non-functional spinner (P2). However, the prior Windows execFileSync("npm"/"npx") P1 from previous review threads is still present in the codebase, keeping the score at 4.
  • scripts/install-wizard.js — Windows npm/npx executable resolution and spinner animation.

Important Files Changed

Filename Overview
scripts/install-wizard.js New 4-step interactive setup wizard; spinner in stepInstallSkills will not animate because execFileSync blocks the event loop; Windows npm/npx ENOENT issue flagged in prior threads remains unresolved.
scripts/run.js Cleanly intercepts "install" subcommand to launch the wizard and adds auto-download of the binary for other commands when postinstall was skipped under npx.
scripts/install.js Guards binary download from running during npx postinstall via npm_command/LARK_CLI_RUN; version pre-release stripping is deliberate.
package.json Version bump to 1.0.11 and install-wizard.js added to published files array — correct.

Sequence Diagram

sequenceDiagram
    participant User
    participant npx
    participant run.js
    participant install-wizard.js
    participant npm
    participant lark-cli

    User->>npx: "npx @larksuite/cli install"
    npx->>run.js: "spawn (postinstall skipped via npm_command=exec)"
    run.js->>run.js: "args[0] === "install""
    run.js->>install-wizard.js: require()

    install-wizard.js->>install-wizard.js: [1/4] whichLarkCli()
    alt not installed
        install-wizard.js->>npm: "npm install -g @larksuite/cli"
        npm-->>install-wizard.js: postinstall → binary downloaded
    end

    install-wizard.js->>install-wizard.js: [2/4] skillsAlreadyInstalled()
    alt skills missing
        install-wizard.js->>npx: npx skills add SKILLS_REPO -y -g
        npx-->>install-wizard.js: skills installed
    end

    install-wizard.js->>lark-cli: [3/4] config show (check existing app)
    alt no existing config
        install-wizard.js->>lark-cli: lark-cli config init --new
    end

    install-wizard.js->>User: [4/4] Prompt: allow AI data access?
    alt User says Y
        install-wizard.js->>lark-cli: lark-cli auth login
    end

    install-wizard.js-->>User: ✅ You're all set!
Loading

Reviews (5): Last reviewed commit: "feat: 一键安装并配置" | Re-trigger Greptile

Comment thread scripts/install-wizard.js Outdated
Comment thread scripts/install.js
@github-actions github-actions bot added size/M Single-domain feat or fix with limited business impact and removed size/L Large or sensitive change across domains or core paths labels Apr 14, 2026
Copy link
Copy Markdown

@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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/install-wizard.js`:
- Around line 32-35: The confirm() function currently treats every input except
exact "n" as consent; update it so empty answer returns true (default yes), but
otherwise normalize the response (trim + toLowerCase) and only return true for
accepted affirmative tokens like "y" or "yes", and return false for "n" or "no"
(and any other non-affirmative). Modify the async function confirm(question)
that calls ask(...) to perform this normalization and explicit checks rather
than the current answer === "" || answer.toLowerCase() !== "n" expression.
- Around line 87-99: The global installer in stepInstallGlobally currently runs
run("npm", ["install", "-g", PKG]) which allows npm to pick the latest dist-tag;
change it to install the exact version by using the PKG@VERSION token (use
`${PKG}@${VERSION}`) so the global install matches the wizard's VERSION, and
before early-return after whichLarkCli()/getLarkCliVersion() compare the found
ver to VERSION and only skip installation if they match (otherwise proceed to
reinstall/update).
- Around line 37-45: The run/runSilent helpers currently call execFileSync(cmd,
...) directly which fails on Windows when cmd points to a .cmd shim; update run
and runSilent to detect Windows (process.platform === "win32") and when the
command path ends with ".cmd" or ".bat" wrap the call through cmd.exe by
invoking execFileSync("cmd.exe", ["/c", cmd, ...args], ...) so .cmd shims
execute correctly; keep existing stdio behavior and preserve opts; ensure both
run and runSilent use the same wrapper so calls originating from whichLarkCli()
(the resolved lark-cli path) work on Windows.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b19c0f46-0948-438d-9f0d-7719cea1f4ad

📥 Commits

Reviewing files that changed from the base of the PR and between 2a30124 and 7078825.

📒 Files selected for processing (5)
  • cmd/auth/login_interactive.go
  • package.json
  • scripts/install-wizard.js
  • scripts/install.js
  • scripts/run.js
💤 Files with no reviewable changes (1)
  • cmd/auth/login_interactive.go

Comment thread scripts/install-wizard.js Outdated
Comment thread scripts/install-wizard.js
Comment thread scripts/install-wizard.js Outdated
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 14, 2026

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@823df70fa6a8a0a6e1a0e16dcfd17e3a8e758899

🧩 Skill update

npx skills add larksuite/cli#feature/easy-setup -y -g

Copy link
Copy Markdown

@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.

♻️ Duplicate comments (3)
scripts/install-wizard.js (3)

32-35: ⚠️ Potential issue | 🟠 Major

Fix confirm() so non-affirmative input is not treated as consent.

At Line 34, anything except exact "n" becomes true, so "no" and typos are accepted as yes.

Proposed fix
 async function confirm(question) {
-  const answer = await ask(`${question} (Y/n) `);
-  return answer === "" || answer.toLowerCase() !== "n";
+  const answer = (await ask(`${question} (Y/n) `)).trim().toLowerCase();
+  if (answer === "" || answer === "y" || answer === "yes") return true;
+  if (answer === "n" || answer === "no") return false;
+  console.log("      Please answer y/yes or n/no.");
+  return confirm(question);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install-wizard.js` around lines 32 - 35, The confirm() helper
currently treats any input other than exact "n" as consent; update it so consent
is returned only for explicit affirmative responses: capture the answer from
ask(), normalize it (trim and toLowerCase()), and return true only if the answer
is empty or matches an affirmative token such as "y" or "yes" (and false
otherwise); modify the confirm function's condition to use the normalized answer
and check for these affirmative values (reference function name: confirm and the
ask call).

87-99: ⚠️ Potential issue | 🟠 Major

Install the same package version as the running wizard and only skip on version match.

At Line 98, unpinned npm install -g @larksuite/cli`` can install a different dist-tag version than the currently executed wizard.

Proposed fix
 async function stepInstallGlobally() {
   console.log("\n[1/4] Installing %s globally...", PKG);

   const existing = whichLarkCli();
   if (existing) {
     const ver = getLarkCliVersion(existing);
-    console.log("      Already installed (v%s). Skipped.", ver || "unknown");
-    return;
+    if (ver === VERSION) {
+      console.log("      Already installed (v%s). Skipped.", ver || "unknown");
+      return;
+    }
+    console.log("      Found v%s; reinstalling v%s...", ver || "unknown", VERSION);
   }

   try {
-    run("npm", ["install", "-g", PKG]);
+    run("npm", ["install", "-g", `${PKG}@${VERSION}`]);
     console.log("      Done.");
When running `npm install -g `@larksuite/cli`` without a version, does npm resolve the current dist-tag (e.g., latest) rather than the version used by `npx `@larksuite/cli`@<version>`?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install-wizard.js` around lines 87 - 99, The global installer
currently runs an unpinned npm install which may install a different dist-tag
than the version of the running wizard; in stepInstallGlobally(), fetch the
running wizard's exact package version (e.g., from package.json or
process.env.npm_package_version) and use it to pin the global install (install
PKG@<version> instead of PKG), and change the skip logic that uses
whichLarkCli()/getLarkCliVersion() so it only returns early when the installed
ver strictly equals the running wizard version; update the call to run("npm",
["install", "-g", ...]) to include PKG + "@" + currentVersion and keep using
whichLarkCli, getLarkCliVersion, and run to locate and install.

37-45: ⚠️ Potential issue | 🔴 Critical

Handle Windows .cmd/.bat execution in run() and runSilent().

whichLarkCli() can resolve to a .cmd shim on Windows, and direct execFileSync(cmd, ...) can fail for those commands.

Proposed fix
 function run(cmd, args, opts = {}) {
+  if (isWindows && /\.(cmd|bat)$/i.test(cmd)) {
+    execFileSync("cmd.exe", ["/d", "/s", "/c", cmd, ...args], {
+      stdio: "inherit",
+      ...opts,
+    });
+    return;
+  }
   execFileSync(cmd, args, { stdio: "inherit", ...opts });
 }
 
 function runSilent(cmd, args, opts = {}) {
+  if (isWindows && /\.(cmd|bat)$/i.test(cmd)) {
+    return execFileSync("cmd.exe", ["/d", "/s", "/c", cmd, ...args], {
+      stdio: ["ignore", "pipe", "pipe"],
+      ...opts,
+    });
+  }
   return execFileSync(cmd, args, {
     stdio: ["ignore", "pipe", "pipe"],
     ...opts,
   });
 }
#!/bin/bash
# Verify current implementation and impacted call chain.
cat -n scripts/install-wizard.js | sed -n '37,55p;48,70p;168,206p'

# Verify Node docs mention execFile + .cmd/.bat behavior on Windows.
curl -s https://nodejs.org/api/child_process.html | rg -n "execFile|\\.bat|\\.cmd|Windows"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install-wizard.js` around lines 37 - 45, The run() and runSilent()
helpers must handle Windows .cmd/.bat shims; detect if process.platform ===
"win32" and the resolved command (from whichLarkCli() callers) endsWith ".cmd"
or ".bat", and in that case invoke execFileSync against the Windows shell
(cmd.exe) with arguments ['/c', cmd, ...args] rather than execFileSync(cmd,
...), preserving the same stdio options used by run and runSilent (inherit vs
["ignore","pipe","pipe"]) and forwarding opts; update both run and runSilent to
perform this platform-specific branch so .cmd/.bat shims execute correctly on
Windows.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@scripts/install-wizard.js`:
- Around line 32-35: The confirm() helper currently treats any input other than
exact "n" as consent; update it so consent is returned only for explicit
affirmative responses: capture the answer from ask(), normalize it (trim and
toLowerCase()), and return true only if the answer is empty or matches an
affirmative token such as "y" or "yes" (and false otherwise); modify the confirm
function's condition to use the normalized answer and check for these
affirmative values (reference function name: confirm and the ask call).
- Around line 87-99: The global installer currently runs an unpinned npm install
which may install a different dist-tag than the version of the running wizard;
in stepInstallGlobally(), fetch the running wizard's exact package version
(e.g., from package.json or process.env.npm_package_version) and use it to pin
the global install (install PKG@<version> instead of PKG), and change the skip
logic that uses whichLarkCli()/getLarkCliVersion() so it only returns early when
the installed ver strictly equals the running wizard version; update the call to
run("npm", ["install", "-g", ...]) to include PKG + "@" + currentVersion and
keep using whichLarkCli, getLarkCliVersion, and run to locate and install.
- Around line 37-45: The run() and runSilent() helpers must handle Windows
.cmd/.bat shims; detect if process.platform === "win32" and the resolved command
(from whichLarkCli() callers) endsWith ".cmd" or ".bat", and in that case invoke
execFileSync against the Windows shell (cmd.exe) with arguments ['/c', cmd,
...args] rather than execFileSync(cmd, ...), preserving the same stdio options
used by run and runSilent (inherit vs ["ignore","pipe","pipe"]) and forwarding
opts; update both run and runSilent to perform this platform-specific branch so
.cmd/.bat shims execute correctly on Windows.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: af133049-85aa-4ccc-8c89-567cde21d636

📥 Commits

Reviewing files that changed from the base of the PR and between 7078825 and f05de96.

📒 Files selected for processing (4)
  • package.json
  • scripts/install-wizard.js
  • scripts/install.js
  • scripts/run.js
✅ Files skipped from review due to trivial changes (1)
  • package.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/install.js
  • scripts/run.js

Copy link
Copy Markdown

@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.

♻️ Duplicate comments (3)
scripts/install-wizard.js (3)

90-99: ⚠️ Potential issue | 🟠 Major

Pin global install version and only skip when versions match.

Line 93-Line 94 skips on any existing binary, and Line 98 installs unpinned @larksuite/cli, which can drift from the wizard’s VERSION.

Proposed fix
   const existing = whichLarkCli();
   if (existing) {
     const ver = getLarkCliVersion(existing);
-    console.log("      Already installed (v%s). Skipped.", ver || "unknown");
-    return;
+    if (ver === VERSION) {
+      console.log("      Already installed (v%s). Skipped.", ver);
+      return;
+    }
+    console.log(
+      "      Found version %s, upgrading to v%s...",
+      ver || "unknown",
+      VERSION
+    );
   }
 
   try {
-    run("npm", ["install", "-g", PKG]);
+    run("npm", ["install", "-g", `${PKG}@${VERSION}`]);
     console.log("      Done.");
   } catch (_) {
     console.error(
       "\n      Failed to install globally.\n" +
-      "      Try running manually: npm install -g " + PKG + "\n"
+      "      Try running manually: npm install -g " + `${PKG}@${VERSION}` + "\n"
     );
     process.exit(1);
   }
When running npm install -g `@scope/pkg` from code launched by npx `@scope/pkg`@<version>, does npm install that same version automatically, or resolve latest unless @<version> is specified?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install-wizard.js` around lines 90 - 99, The script currently skips
install if any existing binary is found and installs an unpinned PKG; change it
to only skip when the detected version from getLarkCliVersion(existing) strictly
equals the desired VERSION (do not skip if ver is falsy/unknown), and pin the
global install by invoking run("npm", ["install", "-g", `${PKG}@${VERSION}`])
(or build a PKG_VERSION variable) instead of installing unpinned PKG; update
references in whichLarkCli(), getLarkCliVersion(), and the run(...) call
accordingly so the wizard only skips when versions match and always installs the
explicit VERSION otherwise.

37-45: ⚠️ Potential issue | 🔴 Critical

Use cmd.exe /c for .cmd/.bat execution on Windows.

Line 38 and Line 42 call execFileSync directly; when whichLarkCli() returns a .cmd shim, these calls fail on Windows. This is the root cause for downstream failures in version/config/auth steps.

Proposed fix
 function run(cmd, args, opts = {}) {
+  if (isWindows && /\.(cmd|bat)$/i.test(cmd)) {
+    execFileSync("cmd.exe", ["/d", "/s", "/c", cmd, ...args], {
+      stdio: "inherit",
+      ...opts,
+    });
+    return;
+  }
   execFileSync(cmd, args, { stdio: "inherit", ...opts });
 }
 
 function runSilent(cmd, args, opts = {}) {
+  if (isWindows && /\.(cmd|bat)$/i.test(cmd)) {
+    return execFileSync("cmd.exe", ["/d", "/s", "/c", cmd, ...args], {
+      stdio: ["ignore", "pipe", "pipe"],
+      ...opts,
+    });
+  }
   return execFileSync(cmd, args, {
     stdio: ["ignore", "pipe", "pipe"],
     ...opts,
   });
 }
Does Node.js child_process.execFileSync support executing .cmd/.bat files directly on Windows without shell:true or cmd.exe /c?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install-wizard.js` around lines 37 - 45, The run and runSilent
helpers call execFileSync directly which fails when whichLarkCli() returns a
.cmd/.bat shim on Windows; update both functions to detect Windows
(process.platform === 'win32') and, when running a .cmd or .bat (or always on
Windows), invoke the command via cmd.exe /c by passing 'cmd.exe' as the
executable and ['/c', cmd, ...args] as the args (preserving the existing opts
and stdio settings) so .cmd/.bat shims execute correctly on Windows.

32-35: ⚠️ Potential issue | 🟠 Major

Fix confirmation parsing: no currently evaluates to consent.

On Line 34, any value except exact "n" returns true, so "no" and typos become opt-in.

Proposed fix
 async function confirm(question) {
-  const answer = await ask(`${question} (Y/n) `);
-  return answer === "" || answer.toLowerCase() !== "n";
+  const answer = (await ask(`${question} (Y/n) `)).trim().toLowerCase();
+  if (answer === "" || answer === "y" || answer === "yes") return true;
+  if (answer === "n" || answer === "no") return false;
+  return false;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install-wizard.js` around lines 32 - 35, The confirm() function
incorrectly treats any response except exact "n" as consent (so "no" becomes
yes); update confirm to normalize the answer (trim and toLowerCase()) and return
true only for explicit affirmative responses (e.g., empty string for default
yes, "y", or "yes") rather than negating only "n". Locate the async function
confirm and the ask() call and replace the current boolean expression with a
check that accepts only the intended affirmative values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@scripts/install-wizard.js`:
- Around line 90-99: The script currently skips install if any existing binary
is found and installs an unpinned PKG; change it to only skip when the detected
version from getLarkCliVersion(existing) strictly equals the desired VERSION (do
not skip if ver is falsy/unknown), and pin the global install by invoking
run("npm", ["install", "-g", `${PKG}@${VERSION}`]) (or build a PKG_VERSION
variable) instead of installing unpinned PKG; update references in
whichLarkCli(), getLarkCliVersion(), and the run(...) call accordingly so the
wizard only skips when versions match and always installs the explicit VERSION
otherwise.
- Around line 37-45: The run and runSilent helpers call execFileSync directly
which fails when whichLarkCli() returns a .cmd/.bat shim on Windows; update both
functions to detect Windows (process.platform === 'win32') and, when running a
.cmd or .bat (or always on Windows), invoke the command via cmd.exe /c by
passing 'cmd.exe' as the executable and ['/c', cmd, ...args] as the args
(preserving the existing opts and stdio settings) so .cmd/.bat shims execute
correctly on Windows.
- Around line 32-35: The confirm() function incorrectly treats any response
except exact "n" as consent (so "no" becomes yes); update confirm to normalize
the answer (trim and toLowerCase()) and return true only for explicit
affirmative responses (e.g., empty string for default yes, "y", or "yes") rather
than negating only "n". Locate the async function confirm and the ask() call and
replace the current boolean expression with a check that accepts only the
intended affirmative values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 64541bda-f772-4623-a226-dd4dffe6a90a

📥 Commits

Reviewing files that changed from the base of the PR and between f05de96 and be8af5c.

📒 Files selected for processing (4)
  • package.json
  • scripts/install-wizard.js
  • scripts/install.js
  • scripts/run.js
✅ Files skipped from review due to trivial changes (1)
  • package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/run.js

Comment thread scripts/install-wizard.js Outdated
Copy link
Copy Markdown

@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.

♻️ Duplicate comments (2)
scripts/install-wizard.js (2)

29-32: ⚠️ Potential issue | 🟠 Major

confirm() currently treats no (and most typos) as “yes”.

On Line 31, only exact "n" is false; "no" incorrectly becomes true. This impacts consent flow in both app reuse and auth prompts.

Proposed fix
 async function confirm(question) {
-  const answer = await ask(`${question} (Y/n) `);
-  return answer === "" || answer.toLowerCase() !== "n";
+  const answer = (await ask(`${question} (Y/n) `)).trim().toLowerCase();
+  if (answer === "" || answer === "y" || answer === "yes") return true;
+  if (answer === "n" || answer === "no") return false;
+  return false;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install-wizard.js` around lines 29 - 32, The confirm() helper
currently treats "no" and typos starting with "n" as yes because it only checks
for exact "n"; update confirm(question) to trim and lowercase the answer from
ask(), treat an empty string as true (default yes), and return false for any
answer that starts with "n" (e.g., "n", "no", "nah") — i.e., compute const a =
answer.trim().toLowerCase(); if (a === "") return true; return
!a.startsWith("n"); make this change in the confirm function that calls ask().

34-43: ⚠️ Potential issue | 🔴 Critical

Windows .cmd/.bat execution is not safely handled in run helpers.

Lines 35 and 39 call execFileSync directly. When cmd is a Windows shim (e.g., lark-cli.cmd, npm.cmd, npx.cmd), these calls can fail without cmd.exe /c.

Proposed fix
 function run(cmd, args, opts = {}) {
-  execFileSync(cmd, args, { stdio: "inherit", ...opts });
+  if (isWindows && /\.(cmd|bat)$/i.test(cmd)) {
+    execFileSync("cmd.exe", ["/d", "/s", "/c", cmd, ...args], {
+      stdio: "inherit",
+      ...opts,
+    });
+    return;
+  }
+  execFileSync(cmd, args, { stdio: "inherit", ...opts });
 }
 
 function runSilent(cmd, args, opts = {}) {
+  if (isWindows && /\.(cmd|bat)$/i.test(cmd)) {
+    return execFileSync("cmd.exe", ["/d", "/s", "/c", cmd, ...args], {
+      stdio: ["ignore", "pipe", "pipe"],
+      ...opts,
+    });
+  }
   return execFileSync(cmd, args, {
     stdio: ["ignore", "pipe", "pipe"],
     ...opts,
   });
 }
#!/bin/bash
set -euo pipefail

echo "Inspect current command execution helpers:"
rg -n -C2 'function run\(|function runSilent\(|execFileSync\(|cmd\.exe|\.cmd|\.bat' scripts/install-wizard.js

echo
echo "Check Node docs references for .bat/.cmd + execFile behavior:"
curl -fsSL https://nodejs.org/api/child_process.html | rg -n -i 'bat|cmd|execFile'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install-wizard.js` around lines 34 - 43, The run and runSilent
helpers call execFileSync directly and fail for Windows shims (e.g.,
lark-cli.cmd, npm.cmd); update both run and runSilent to detect Windows
(process.platform === "win32") and when cmd ends with ".cmd" or ".bat" invoke
cmd.exe /c by replacing cmd with "cmd.exe" and prefixing args with "/c" and the
original cmd, or set windowsVerbatimArguments accordingly, then call
execFileSync with the transformed cmd/args and original opts; reference the
functions run, runSilent and the use of execFileSync so the fix is applied in
both helpers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@scripts/install-wizard.js`:
- Around line 29-32: The confirm() helper currently treats "no" and typos
starting with "n" as yes because it only checks for exact "n"; update
confirm(question) to trim and lowercase the answer from ask(), treat an empty
string as true (default yes), and return false for any answer that starts with
"n" (e.g., "n", "no", "nah") — i.e., compute const a =
answer.trim().toLowerCase(); if (a === "") return true; return
!a.startsWith("n"); make this change in the confirm function that calls ask().
- Around line 34-43: The run and runSilent helpers call execFileSync directly
and fail for Windows shims (e.g., lark-cli.cmd, npm.cmd); update both run and
runSilent to detect Windows (process.platform === "win32") and when cmd ends
with ".cmd" or ".bat" invoke cmd.exe /c by replacing cmd with "cmd.exe" and
prefixing args with "/c" and the original cmd, or set windowsVerbatimArguments
accordingly, then call execFileSync with the transformed cmd/args and original
opts; reference the functions run, runSilent and the use of execFileSync so the
fix is applied in both helpers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 592d3a03-26c8-4ac2-9935-459aff0d7d18

📥 Commits

Reviewing files that changed from the base of the PR and between be8af5c and 5f3fa3d.

📒 Files selected for processing (4)
  • package.json
  • scripts/install-wizard.js
  • scripts/install.js
  • scripts/run.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • scripts/run.js

Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/install-wizard.js`:
- Around line 35-39: The execCmd function currently only wraps commands that
already end with .cmd/.bat; on Windows you must also treat bare "npm" and "npx"
as cmd shims and run them via cmd.exe. Update execCmd so that when isWindows is
true and the provided cmd either matches /\.cmd|\.bat$/i OR is a bare "npm" or
"npx" (case-insensitive) or otherwise has no file extension, you call
execFileSync("cmd.exe", ["/c", cmd, ...args], opts) instead of executing cmd
directly; leave direct execFileSync for non-Windows or when the command already
has an executable extension. Ensure you check the cmd string (the parameter to
execCmd) and use its basename/Lowercased value to detect "npm"/"npx".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4eb02b54-06ee-42d1-8513-6621dcd052f1

📥 Commits

Reviewing files that changed from the base of the PR and between 5f3fa3d and 9b916af.

📒 Files selected for processing (4)
  • package.json
  • scripts/install-wizard.js
  • scripts/install.js
  • scripts/run.js
✅ Files skipped from review due to trivial changes (2)
  • package.json
  • scripts/run.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/install.js

Comment thread scripts/install-wizard.js
Copy link
Copy Markdown

@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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@github-actions github-actions bot added size/L Large or sensitive change across domains or core paths and removed size/M Single-domain feat or fix with limited business impact labels Apr 14, 2026
Copy link
Copy Markdown

@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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Copy link
Copy Markdown

@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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Comment thread scripts/install-wizard.js Fixed
@mazhe-nerd mazhe-nerd force-pushed the feature/easy-setup branch 3 times, most recently from 13a4859 to 9bfe696 Compare April 14, 2026 13:56
@mazhe-nerd mazhe-nerd force-pushed the feature/easy-setup branch 4 times, most recently from da0db98 to a997d3a Compare April 15, 2026 08:06
@liangshuo-1 liangshuo-1 merged commit 1583af7 into main Apr 15, 2026
14 of 15 checks passed
@liangshuo-1 liangshuo-1 deleted the feature/easy-setup branch April 15, 2026 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants