Skip to content

feat: add qlty and ast-grep installation to setup wizard#144

Open
udhaya10 wants to merge 2 commits intoparcadei:mainfrom
udhaya10:feat/wizard-qlty-astgrep
Open

feat: add qlty and ast-grep installation to setup wizard#144
udhaya10 wants to merge 2 commits intoparcadei:mainfrom
udhaya10:feat/wizard-qlty-astgrep

Conversation

@udhaya10
Copy link
Copy Markdown

@udhaya10 udhaya10 commented Feb 15, 2026

Summary

  • Add Step 11/15: qlty CLI — universal code quality (70+ linters, 40+ languages)
  • Add Step 12/15: ast-grep — AST-based structural code search and refactoring
  • Both are free tools, no API keys needed
  • Follows existing TLDR install pattern (explain → confirm → install → verify)
  • Updates all step numbers from /13 to /15
  • Updates README wizard steps table

Why

The wizard already installs TLDR (Step 10) and Loogle (Step 14) using the same pattern, but skips these two free tools that unlock 5+ skills:

Tool Skills Unlocked
qlty qlty-check, qlty-during-development, fix (deps scope)
ast-grep ast-grep-find, search-router, search-tools

Without them, these skills silently fail or degrade with no user feedback.

Changes

  • opc/scripts/setup/wizard.py — 2 new install steps + step number updates
  • README.md — Updated wizard steps table (12 → 15 steps)

Test plan

  • Run wizard — verify qlty step appears after TLDR
  • Skip qlty — verify "Install later" message shown
  • Accept qlty — verify curl -fsSL https://qlty.sh | sh runs
  • Run wizard — verify ast-grep step appears after qlty
  • Skip ast-grep — verify "Install later" message shown
  • Accept ast-grep — verify brew/cargo install attempted
  • Verify step numbering is consistent (0/15 through 14/15)

Closes #140

Summary by CodeRabbit

  • New Features

    • Setup wizard now includes optional Code Quality CLI (qlty) and AST-based code search (ast-grep) tools with interactive installation support.
    • Wizard expanded from 12 to 15 total setup steps with improved tool organization.
  • Documentation

    • Updated Quick Start guide to reflect new setup wizard steps and optional tools.

- Add Step 11/15: qlty CLI installation (code quality, 70+ linters)
- Add Step 12/15: ast-grep installation (AST-based code search)
- Both follow existing TLDR install pattern (explain → confirm → install → verify)
- Check if already installed before offering
- Try brew first, then cargo for ast-grep
- Update all step numbers from /13 to /15
- Update README wizard steps table

Closes parcadei#140
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Feb 15, 2026

PR author is not in the allowed authors list.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 15, 2026

📝 Walkthrough

Walkthrough

The changes expand the setup wizard to include two additional optional CLI tools (qlty and ast-grep) with interactive installation flows, documentation updates, and renumbered wizard steps. The wizard now totals 15 steps instead of 12.

Changes

Cohort / File(s) Summary
Documentation
README.md
Updated Quick Start section to reflect expanded setup wizard from 12 to 15 steps. Replaces combined "Diagnostics tools + Loogle (optional)" entry with two separate steps for qlty and ast-grep.
Wizard Implementation
opc/scripts/setup/wizard.py
Added interactive installation flows for qlty (code quality CLI) and ast-grep (AST-based code search). Includes subprocess-based curl and brew/cargo installers with timeout handling, fallback messaging, error handling, and interactive user prompts. All wizard step headers and numbering updated to reflect 15-step workflow.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding qlty and ast-grep installation steps to the setup wizard, matching the primary focus of the changeset.
Linked Issues check ✅ Passed The pull request implements all coding requirements from issue #140: adds qlty installation via curl with init verification, adds ast-grep installation via brew/cargo with fallback, updates step numbering from 13 to 15, and updates README documentation.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #140: wizard.py modifications add the two required tools and step renumbering, and README.md updates reflect these changes only.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Comment on lines +1099 to +1104
result = subprocess.run(
["sh", "-c", "curl -fsSL https://qlty.sh | sh"],
capture_output=True,
text=True,
timeout=120,
)

This comment was marked as 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.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@opc/scripts/setup/wizard.py`:
- Line 631: The print call uses an unnecessary f-string and likely meant to
include the runtime variable; update the call to include runtime (e.g.,
interpolate runtime into the message) or remove the leading f to make it a
normal string. Locate the console.print invocation in wizard.py (the call to
console.print(... "Step 6/15: Container Stack (Sandbox Infrastructure)")) and
either add {runtime} in the formatted string where appropriate or change the
string to a plain literal to eliminate the unused f-string.
- Around line 1133-1164: The ast-grep install block (in wizard.py around the
ast-grep install logic) must verify the installation and avoid misleading
fallback text: after a successful subprocess.run that returns 0, run a
verification check (e.g., subprocess.run(["sg","--version"],
capture_output=True, text=True) or check shutil.which("sg")) and only print
"[green]OK[/green] ast-grep installed" if the verification succeeds; if
verification fails, treat it as an installation failure and print the
appropriate failure message. Also replace hardcoded "Install manually: brew
install ast-grep" in the failure and timeout branches with a generic instruction
or a context-aware suggestion (if shutil.which("brew") is truthy suggest brew,
elif shutil.which("cargo") suggest cargo, else print the upstream install URL
https://github.com/ast-grep/ast-grep#installation) so users without brew aren't
directed to use it.
- Around line 1098-1117: After a successful curl install (the branch where
subprocess.run returns 0), invoke the qlty initialization and a verification
command: call "qlty init" (run via subprocess.run similar to the existing call)
and then run a verification command such as "qlty --version" or another
appropriate qlty health/status check; handle non-zero return codes and
exceptions for both calls and log results via console.print (reuse the same
timeout/ capture_output/text pattern), printing an OK on success or WARN/ERROR
with actionable manual instructions on failure. Ensure you update the success
branch that currently prints "OK qlty installed" to perform these two
subprocess.run calls (referencing subprocess.run and result.returncode) and to
surface errors/exceptions just like the existing install block.
🧹 Nitpick comments (2)
opc/scripts/setup/wizard.py (2)

1084-1084: Internal comments use stale sub-step numbering (10b/10c/10d) that doesn't match displayed step headers (11/12/13).

These inline comments appear to be leftover from an earlier numbering scheme and will cause confusion during future maintenance.

Proposed fix
-    # Step 10b: Code Quality CLI - qlty (Optional)
+    # Step 11: Code Quality CLI - qlty (Optional)
-    # Step 10c: AST-Grep (Optional)
+    # Step 12: AST-Grep (Optional)
-    # Step 10d: Diagnostics Tools (Shift-Left Feedback)
+    # Step 13: Diagnostics Tools (Shift-Left Feedback)

Also applies to: 1119-1119, 1169-1169


1099-1104: Piping curl to sh — consider adding --proto =https for defense-in-depth.

While curl | sh matches the official qlty install instructions, adding --proto =https --tlsv1.2 hardens against protocol downgrade. This is a common hardening pattern used by rustup, Homebrew, etc.

Proposed fix
-                ["sh", "-c", "curl -fsSL https://qlty.sh | sh"],
+                ["sh", "-c", "curl --proto =https --tlsv1.2 -fsSL https://qlty.sh | sh"],

# Step 5: Container stack (Sandbox Infrastructure)
runtime = prereqs.get("container_runtime", "docker")
console.print(f"\n[bold]Step 6/13: Container Stack (Sandbox Infrastructure)[/bold]")
console.print(f"\n[bold]Step 6/15: Container Stack (Sandbox Infrastructure)[/bold]")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

f-string without placeholders (static analysis).

Line 631 uses an f-string but contains no interpolated variables. The runtime variable on line 630 is likely intended to be used here.

Proposed fix
-        console.print(f"\n[bold]Step 6/15: Container Stack (Sandbox Infrastructure)[/bold]")
+        console.print("\n[bold]Step 6/15: Container Stack (Sandbox Infrastructure)[/bold]")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.print(f"\n[bold]Step 6/15: Container Stack (Sandbox Infrastructure)[/bold]")
console.print("\n[bold]Step 6/15: Container Stack (Sandbox Infrastructure)[/bold]")
🧰 Tools
🪛 Ruff (0.15.0)

[error] 631-631: f-string without any placeholders

Remove extraneous f prefix

(F541)

🤖 Prompt for AI Agents
In `@opc/scripts/setup/wizard.py` at line 631, The print call uses an unnecessary
f-string and likely meant to include the runtime variable; update the call to
include runtime (e.g., interpolate runtime into the message) or remove the
leading f to make it a normal string. Locate the console.print invocation in
wizard.py (the call to console.print(... "Step 6/15: Container Stack (Sandbox
Infrastructure)")) and either add {runtime} in the formatted string where
appropriate or change the string to a plain literal to eliminate the unused
f-string.

Comment on lines +1098 to +1117
try:
result = subprocess.run(
["sh", "-c", "curl -fsSL https://qlty.sh | sh"],
capture_output=True,
text=True,
timeout=120,
)
if result.returncode == 0:
console.print(" [green]OK[/green] qlty installed")
else:
console.print(" [yellow]WARN[/yellow] Installation failed")
console.print(" Install manually: curl -fsSL https://qlty.sh | sh")
except subprocess.TimeoutExpired:
console.print(" [yellow]WARN[/yellow] Installation timed out")
console.print(" Install manually: curl -fsSL https://qlty.sh | sh")
except Exception as e:
console.print(f" [red]ERROR[/red] {e}")
else:
console.print(" Skipped qlty installation")
console.print(" [dim]Install later: curl -fsSL https://qlty.sh | sh[/dim]")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing qlty init and post-install verification per PR objectives.

The PR description states that qlty init should be called on successful install, and the issue requires following the "explain → confirm → install → verify" pattern. Currently, neither happens after qlty installation succeeds.

Proposed fix
             if result.returncode == 0:
                 console.print("  [green]OK[/green] qlty installed")
+
+                # Verify installation
+                verify = subprocess.run(
+                    ["qlty", "--version"],
+                    capture_output=True,
+                    text=True,
+                    timeout=10,
+                )
+                if verify.returncode == 0:
+                    console.print(f"  [green]OK[/green] Verified: {verify.stdout.strip()}")
+                else:
+                    console.print("  [yellow]WARN[/yellow] qlty installed but not on PATH")
+
+                # Initialize qlty in the project
+                console.print("  Running qlty init...")
+                init_result = subprocess.run(
+                    ["qlty", "init"],
+                    capture_output=True,
+                    text=True,
+                    timeout=60,
+                )
+                if init_result.returncode == 0:
+                    console.print("  [green]OK[/green] qlty initialized")
+                else:
+                    console.print("  [yellow]WARN[/yellow] qlty init failed (run manually: qlty init)")
             else:
🤖 Prompt for AI Agents
In `@opc/scripts/setup/wizard.py` around lines 1098 - 1117, After a successful
curl install (the branch where subprocess.run returns 0), invoke the qlty
initialization and a verification command: call "qlty init" (run via
subprocess.run similar to the existing call) and then run a verification command
such as "qlty --version" or another appropriate qlty health/status check; handle
non-zero return codes and exceptions for both calls and log results via
console.print (reuse the same timeout/ capture_output/text pattern), printing an
OK on success or WARN/ERROR with actionable manual instructions on failure.
Ensure you update the success branch that currently prints "OK qlty installed"
to perform these two subprocess.run calls (referencing subprocess.run and
result.returncode) and to surface errors/exceptions just like the existing
install block.

Comment on lines +1133 to +1164
try:
# Try brew first (macOS), then cargo
if shutil.which("brew"):
result = subprocess.run(
["brew", "install", "ast-grep"],
capture_output=True,
text=True,
timeout=120,
)
elif shutil.which("cargo"):
console.print(" [dim]Using cargo (may take a few minutes)...[/dim]")
result = subprocess.run(
["cargo", "install", "ast-grep", "--locked"],
capture_output=True,
text=True,
timeout=300,
)
else:
console.print(" [yellow]WARN[/yellow] Neither brew nor cargo found")
console.print(" Install manually: https://github.com/ast-grep/ast-grep#installation")
result = None

if result and result.returncode == 0:
console.print(" [green]OK[/green] ast-grep installed")
elif result:
console.print(" [yellow]WARN[/yellow] Installation failed")
console.print(" Install manually: brew install ast-grep")
except subprocess.TimeoutExpired:
console.print(" [yellow]WARN[/yellow] Installation timed out")
console.print(" Install manually: brew install ast-grep")
except Exception as e:
console.print(f" [red]ERROR[/red] {e}")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing post-install verification for ast-grep, and misleading fallback message.

Two issues:

  1. Like qlty, ast-grep doesn't verify the install succeeded (e.g., sg --version), deviating from the "explain → confirm → install → verify" pattern required by issue #140.

  2. Lines 1158-1159 and 1161-1162: when cargo install fails or times out, the fallback message suggests brew install ast-grep, which is confusing if the user doesn't have brew. Consider a more generic message.

Proposed fix
             if result and result.returncode == 0:
                 console.print("  [green]OK[/green] ast-grep installed")
+
+                # Verify installation
+                sg_cmd = "sg" if shutil.which("sg") else "ast-grep"
+                verify = subprocess.run(
+                    [sg_cmd, "--version"],
+                    capture_output=True,
+                    text=True,
+                    timeout=10,
+                )
+                if verify.returncode == 0:
+                    console.print(f"  [green]OK[/green] Verified: {verify.stdout.strip()}")
+                else:
+                    console.print("  [yellow]WARN[/yellow] ast-grep installed but not on PATH")
             elif result:
                 console.print("  [yellow]WARN[/yellow] Installation failed")
-                console.print("  Install manually: brew install ast-grep")
+                console.print("  Install manually: https://github.com/ast-grep/ast-grep#installation")
         except subprocess.TimeoutExpired:
             console.print("  [yellow]WARN[/yellow] Installation timed out")
-            console.print("  Install manually: brew install ast-grep")
+            console.print("  Install manually: https://github.com/ast-grep/ast-grep#installation")
🤖 Prompt for AI Agents
In `@opc/scripts/setup/wizard.py` around lines 1133 - 1164, The ast-grep install
block (in wizard.py around the ast-grep install logic) must verify the
installation and avoid misleading fallback text: after a successful
subprocess.run that returns 0, run a verification check (e.g.,
subprocess.run(["sg","--version"], capture_output=True, text=True) or check
shutil.which("sg")) and only print "[green]OK[/green] ast-grep installed" if the
verification succeeds; if verification fails, treat it as an installation
failure and print the appropriate failure message. Also replace hardcoded
"Install manually: brew install ast-grep" in the failure and timeout branches
with a generic instruction or a context-aware suggestion (if
shutil.which("brew") is truthy suggest brew, elif shutil.which("cargo") suggest
cargo, else print the upstream install URL
https://github.com/ast-grep/ast-grep#installation) so users without brew aren't
directed to use it.

- Remove spurious f-string prefix on line 631 (no placeholders)
- Add qlty --version verification after successful install
- Add sg --version verification after successful ast-grep install
- Replace hardcoded "brew install ast-grep" fallback with generic
  GitHub install URL (works for cargo/npm/brew users alike)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
if result and result.returncode == 0:
console.print(" [green]OK[/green] ast-grep installed")
# Verify installation
sg_cmd = "sg" if shutil.which("sg") else "ast-grep"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The verification check for newly installed tools like ast-grep or qlty fails because the PATH environment variable is not updated within the running script.
Severity: MEDIUM

Suggested Fix

Instead of relying on the process's PATH variable, determine the absolute path to the newly installed binary. For cargo, this is typically ~/.cargo/bin/. Use this absolute path directly when calling subprocess.run() for verification, bypassing the need for shutil.which() or a PATH search.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: opc/scripts/setup/wizard.py#L1169

Potential issue: After installing a tool like `ast-grep` or `qlty` via `cargo` or
`brew`, the verification step fails. This occurs because the installation updates the
shell's `PATH` configuration but not the `PATH` of the currently running Python wizard
process. The script uses `shutil.which()` to find the executable, which searches the
outdated `PATH` and fails. Consequently, the script incorrectly reports that the tool is
"installed but not on PATH", even though the installation was successful and the tool
will be available in new shell sessions.

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.

Enhancement: Add qlty and ast-grep installation to setup wizard

1 participant