Skip to content

Conversation

@lu11y0
Copy link
Contributor

@lu11y0 lu11y0 commented Dec 24, 2025

Related Issue

Closes #140

Summary

Generates standalone .sh bash scripts AND Ansible .yml playbooks for docker/python/nodejs/ollama stacks. Idempotent (command_exists), colorful logging, error traps. cortex script test validates syntax, cortex script history tracks all.

Commands Usage

cortex script generate <filename> --stack <stack-name>

Generates a standalone installation script for the specified stack.

  • Supported stacks: docker, python, nodejs, ollama
  • Default format: bash
  • Output file is created under ~/cortex/install-scripts/ unless an absolute path is provided

Examples:

cortex script generate docker.sh --stack docker
cortex script generate python.sh --stack python
cortex script generate node.sh --stack nodejs
cortex script generate ollama.sh --stack ollama

cortex script generate docker.yml --stack docker --format ansible (generates ansible format)
cortex script generate docker.sh --stack docker --dry-run 

cortex script test <filename>

Validates the syntax of a generated bash script using a sandboxed bash -n check.

Example:

cortex script test docker.sh

cortex script history

Displays the history of generated scripts

cortex script history
cortex script history --limit 5

check-list

  • Bash script generation (cortex script generate docker.sh)
  • 4 stacks: docker, python, nodejs, ollama
  • Idempotent: command_exists docker
  • Error handling: set -euo pipefail + trap
  • Storage: ~/cortex/install-scripts/ (creates new folder for installation script)
  • Test: cortex script test
  • History: cortex script history
  • All tests passed

Video walk-around

Screen.Recording.2025-12-24.225216.1.1.mp4

Installing using script-file (docker already installed but it works!)

Screen.Recording.2025-12-24.225907.mp4

Checklist

  • Tests pass (pytest tests/test_script_gen.py)
  • PR title format: [#XX] Description
  • MVP label added if closing MVP issue

Summary by CodeRabbit

  • New Features

    • Added a top-level "doctor" check and a new "script" command with subcommands to generate, test, and view history of install scripts. Supports multiple stacks and output formats (Bash/Ansible), filename and flags for stack/format/dry-run/sandbox/limit. Generated scripts are saved executable and recorded to a generation history (gracefully degrades if history storage is unavailable).
  • Tests

    • Added comprehensive tests covering generation, formats, stacks, dry-run, syntax checks, verification steps, idempotency, and history handling.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 24, 2025

📝 Walkthrough

Walkthrough

Adds a new ScriptGenerator module for producing installation scripts (Bash/Ansible) with generate/test/history actions, integrates new cortex script subcommands and a doctor CLI entry, and adds tests for generation, syntax checking, history, and CLI wiring.

Changes

Cohort / File(s) Summary
CLI integration
cortex/cli.py
Adds CortexCLI.doctor() and CortexCLI.script(args); wires script subcommands (generate, test, history) and flags (filename, stack, format, dry-run, sandbox, limit); updates main() routing and help output.
Script generation module
cortex/script_gen.py
New ScriptGenerator class with generate(), test(), show_history(), and _save_to_history(); defines per-stack dependencies & verification, Bash/Ansible templates, dry-run support, file write + exec perms, sandboxed syntax checks, and YAML-based history persistence with graceful fallback.
Tests
tests/test_script_gen.py
New parameterized tests covering multiple stacks (docker, python, nodejs, ollama) and formats (bash, ansible), dry-run behavior, executable bit, syntax checks, verification commands, Ansible structure, error cases, idempotency, and history handling.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CLI
    participant ScriptGen as ScriptGenerator
    participant FS as FileSystem
    participant Hist as HistoryFile

    rect rgb(247,250,255)
    Note over User,Hist: Generate Script Flow
    User->>CLI: script generate <file> --stack <stack> --format <fmt> [--dry-run]
    CLI->>ScriptGen: generate(filename, stack, format, dry_run)
    ScriptGen->>ScriptGen: validate stack & format, assemble content
    alt dry-run
        ScriptGen->>User: print generated content and intended path
    else write
        ScriptGen->>FS: write file content
        ScriptGen->>FS: set executable permissions
        ScriptGen->>Hist: _save_to_history(stack, format, filename)
        Hist->>FS: append YAML entry (if yaml available)
    end
    ScriptGen->>CLI: return exit code
    CLI->>User: display success or error
    end
Loading
sequenceDiagram
    actor User
    participant CLI
    participant ScriptGen as ScriptGenerator
    participant FS as FileSystem

    rect rgb(245,255,245)
    Note over User,FS: Test Script Flow (syntax/sandbox)
    User->>CLI: script test <file> [--sandbox]
    CLI->>ScriptGen: test(filename, sandbox)
    ScriptGen->>FS: read script file
    ScriptGen->>ScriptGen: run syntax check (bash -n) / sandboxed validation
    alt syntax OK
        ScriptGen->>CLI: return success
        CLI->>User: report success
    else failure
        ScriptGen->>CLI: return error + diagnostics
        CLI->>User: report failure
    end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • mikejmorgan-ai
  • Sahilbhatane

Poem

🐇
I nibble keys and craft a script at dawn,
Docker, Python, Node — each dependency drawn,
Bash or Ansible, tidy lines I sow,
I log the trail so installs smoothly go,
Hop on — the burrow's ready to run!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.91% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Cortex Installation Script Generator' clearly and directly describes the main feature being added—a new installation script generator with support for multiple stacks.
Description check ✅ Passed The PR description covers most required sections: Related Issue (#140), detailed Summary with command examples, implementation checklist, and tests. However, the template asks for an MVP label field which is not addressed.
Linked Issues check ✅ Passed The PR successfully implements most core requirements from issue #140: bash script generation [#140], multi-stack support [#140], idempotent operations [#140], error handling [#140], testing mode [#140], and history tracking [#140]. However, PowerShell output and customizable templates are not implemented.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #140 requirements: CLI commands (doctor/script), ScriptGenerator class, test suite, and related integrations are in scope for the installation script generator feature.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc8eda2 and 0e81396.

📒 Files selected for processing (1)
  • cortex/cli.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • cortex/cli.py
⏰ 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). (4)
  • GitHub Check: Build Package
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.10)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
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: 2

🧹 Nitpick comments (5)
cortex/script_gen.py (4)

14-35: Add type hints to STACK_DEPS constant.

As per coding guidelines, type hints are required. The STACK_DEPS dictionary should include type annotations.

🔎 Suggested type hint
+from typing import TypedDict
+
+class StackConfig(TypedDict):
+    packages: list[str]
+    check_command: str
+    verification: str
+
-STACK_DEPS = {
+STACK_DEPS: dict[str, StackConfig] = {

74-77: Add type hints to init method.

The __init__ method lacks type hints. Per coding guidelines, type hints are required for Python code.

-    def __init__(self):
+    def __init__(self) -> None:

165-199: Add type hints to test method.

The method signature lacks type hints for parameters and return value. Per coding guidelines, type hints are required.

-    def test(self, filename: str, sandbox: bool = True):
+    def test(self, filename: str, sandbox: bool = True) -> None:

201-256: Add type hints to history methods.

Both _save_to_history and show_history are missing complete type hints for their parameters.

-    def show_history(self, limit: int = 10) -> None:
+    def show_history(self, limit: int = 10) -> None:  # ✓ Already has return type

The _save_to_history already has -> None, and show_history already has return type annotations, so this is good. However, ensure all parameters have type hints throughout the class.

cortex/cli.py (1)

297-327: Remove unnecessary hasattr check for limit.

Line 318 uses hasattr(args, "limit") to check for the limit attribute, but limit is always defined in the history_parser with a default value of 10 (line 907). The hasattr check is unnecessary.

-                limit = args.limit if hasattr(args, "limit") else 10
+                limit = args.limit
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e80134d and 9e2397d.

📒 Files selected for processing (3)
  • cortex/cli.py
  • cortex/script_gen.py
  • tests/test_script_gen.py
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Follow PEP 8 style guide
Type hints required in Python code
Docstrings required for all public APIs

Files:

  • cortex/cli.py
  • cortex/script_gen.py
  • tests/test_script_gen.py
tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Maintain >80% test coverage for pull requests

Files:

  • tests/test_script_gen.py
🧬 Code graph analysis (2)
cortex/cli.py (1)
cortex/script_gen.py (4)
  • ScriptGenerator (73-257)
  • generate (79-163)
  • test (165-199)
  • show_history (226-257)
tests/test_script_gen.py (1)
cortex/script_gen.py (3)
  • ScriptGenerator (73-257)
  • generate (79-163)
  • test (165-199)
⏰ 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). (4)
  • GitHub Check: Build Package
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.10)
🔇 Additional comments (5)
tests/test_script_gen.py (2)

1-257: Excellent test coverage!

The test suite is comprehensive and well-structured, covering:

  • All supported stacks (docker, python, nodejs, ollama)
  • Both output formats (bash, ansible)
  • File operations (permissions, timestamps, dry-run)
  • Error handling (invalid inputs)
  • Bash best practices (strict mode, traps, logging, colors)
  • Syntax validation
  • Parameterized tests for multi-stack coverage

This meets the >80% coverage requirement from the acceptance criteria in issue #140.


100-135: Update idempotency tests after fixing the implementation bug.

These tests currently validate the broken idempotency behavior in cortex/script_gen.py. The implementation uses a single check_command per stack for all packages, causing multi-package stacks to fail true idempotency. For example, the docker stack uses command_exists docker for both docker.io and docker-compose, so if docker is installed but docker-compose is missing, docker-compose will never be installed.

After implementing the fix to use per-package checks, these tests need to be updated to verify:

  • Docker test: command_exists docker-compose appears for the docker-compose package check (not just command_exists docker)
  • Nodejs test: command_exists npm appears for the npm package check (not just command_exists node)
cortex/cli.py (3)

297-327: Clean CLI integration for script commands.

The script() method follows the established CLI patterns and properly delegates to the ScriptGenerator. Error handling covers the expected failure modes (file not found, generic exceptions), and the local import of ScriptGenerator avoids potential circular dependency issues.


870-908: Well-structured argument parsing for script commands.

The argument parser configuration is comprehensive and follows best practices:

  • Clear help text for each subcommand and argument
  • Appropriate use of choices to constrain inputs (stacks, formats)
  • Sensible defaults (stack="docker", format="bash", limit=10)
  • The alias "scripts" provides user convenience

809-813: Proper integration into CLI help and routing.

The script commands are properly integrated into the help output and command routing, making them discoverable and accessible to users.

Also applies to: 1014-1015

@lu11y0 lu11y0 changed the title cortex Installation Script Generator Cortex Installation Script Generator Dec 24, 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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cortex/cli.py (1)

1-1: Critical: Black formatting check failed.

The CI pipeline reports that this file needs Black formatting. Run black cortex/cli.py to fix the formatting issues before merging.

#!/bin/bash
# Format the file with Black
black cortex/cli.py
🧹 Nitpick comments (1)
cortex/cli.py (1)

319-319: Optional: hasattr check is unnecessary.

The --limit argument is defined with default=10 in the parser (line 939), so args.limit will always exist. The hasattr check is defensive but redundant.

🔎 Simplification
-                limit = args.limit if hasattr(args, "limit") else 10
+                limit = args.limit
                 generator.show_history(limit=limit)
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e2397d and edf3445.

📒 Files selected for processing (1)
  • cortex/cli.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Follow PEP 8 style guide
Type hints required in Python code
Docstrings required for all public APIs

Files:

  • cortex/cli.py
🪛 GitHub Actions: CI
cortex/cli.py

[error] 1-1: Black formatting check failed. 1 file would be reformatted. Run 'black' to format the code.

⏰ 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). (3)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.10)
  • GitHub Check: test (3.11)
🔇 Additional comments (3)
cortex/cli.py (3)

841-845: LGTM! Clear help text for script commands.

The help text additions are well-structured and consistent with the existing command documentation.


902-940: LGTM! Well-structured argument parser definitions.

The script subcommand parser is properly configured with:

  • Appropriate default values
  • Constrained choices for stack and format options
  • Required subcommands via required=True
  • Alias support for "scripts"

The implementation follows the existing patterns in the file and matches the requirements from issue #140.


1051-1052: LGTM! Proper command routing.

The script command is correctly routed to cli.script(args), following the established pattern for other commands. The alias "scripts" will be handled automatically by argparse.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cortex/cli.py (1)

1-1: Critical: Black formatting check failed.

The CI pipeline reports that this file would be reformatted by Black. Run black . to format the code before merging.

#!/bin/bash
# Run Black formatter to fix the formatting issues
black cortex/cli.py
♻️ Duplicate comments (3)
cortex/cli.py (2)

298-328: Critical: Missing return statement causes implicit None return.

The function declares -> int but the exception handler at line 326-327 doesn't return a value, and there's no return statement after the try/except block. This causes the function to return None in error cases, violating the type contract.

🔎 Proposed fix
         except FileNotFoundError:
             console.print(f"[red]✗ Script file not found: {args.filename}[/red]")
             return 1
         except Exception as e:
             console.print(f"[red]✗ Script command failed: {str(e)}[/red]")
+            return 1
+
     def ask(self, question: str) -> int:

323-325: Critical: AttributeError when FileNotFoundError occurs during history command.

The FileNotFoundError handler references args.filename, but the history subcommand doesn't have a filename argument. This will raise an AttributeError if a file-not-found error occurs during history operations.

🔎 Proposed fix
         except FileNotFoundError:
-            console.print(f"[red]✗ Script file not found: {args.filename}[/red]")
+            filename = getattr(args, "filename", "unknown")
+            console.print(f"[red]✗ Script file not found: {filename}[/red]")
             return 1
cortex/script_gen.py (1)

131-155: Critical: Ansible format breaks with dict-structured packages.

Line 132 assumes packages are strings, but STACK_DEPS now uses dicts with name and check_command fields. This will generate invalid Ansible YAML like - {'name': 'docker.io', 'check_command': 'docker'} instead of - docker.io.

🔎 Proposed fix
         elif format == "ansible":
-            pkg_list = "\n".join([f"    - {pkg}" for pkg in deps.get("packages", [])])
+            packages = deps.get("packages", [])
+            pkg_names = [
+                pkg["name"] if isinstance(pkg, dict) else pkg for pkg in packages
+            ]
+            pkg_list = "\n".join([f"    - {pkg_name}" for pkg_name in pkg_names])
             content = f"""---
🧹 Nitpick comments (2)
cortex/script_gen.py (2)

1-3: Consider expanding the module docstring.

The current module docstring is minimal. Consider adding more details such as supported formats, stacks, and usage examples.

🔎 Suggested enhancement
 """
-Generates standalone installation scripts for offline or automated deployments.
+Script Generator Module
+
+Generates standalone installation scripts (Bash and Ansible) for offline or automated deployments.
+
+Supported stacks: docker, python, nodejs, ollama
+Supported formats: bash, ansible
+
+Example:
+    generator = ScriptGenerator()
+    generator.generate("install.sh", stack="docker", format="bash")
 """

238-244: Avoid bare except clauses.

The bare except clause on line 243 catches all exceptions including KeyboardInterrupt and SystemExit. Use except Exception: to catch only standard exceptions while allowing system exits and interrupts to propagate.

🔎 Proposed fix
         if self.history_file.exists():
             try:
                 content = self.history_file.read_text()
                 if content.strip():
                     history = yaml.safe_load(content) or []
-            except Exception:
+            except Exception:
                 history = []

Note: This is actually already using except Exception: in the implementation, so this comment may not apply. Let me verify...

Actually looking again, line 243 just says except Exception: which is correct. But line 262 also has a bare except. Let me check that one.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between edf3445 and e38b665.

📒 Files selected for processing (3)
  • cortex/cli.py
  • cortex/script_gen.py
  • tests/test_script_gen.py
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Follow PEP 8 style guide
Type hints required in Python code
Docstrings required for all public APIs

Files:

  • tests/test_script_gen.py
  • cortex/cli.py
  • cortex/script_gen.py
tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Maintain >80% test coverage for pull requests

Files:

  • tests/test_script_gen.py
🧠 Learnings (1)
📚 Learning: 2025-12-11T12:03:24.071Z
Learnt from: CR
Repo: cortexlinux/cortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-11T12:03:24.071Z
Learning: Applies to {setup.py,setup.cfg,pyproject.toml,**/__init__.py} : Use Python 3.10 or higher as the minimum supported version

Applied to files:

  • cortex/script_gen.py
🧬 Code graph analysis (3)
tests/test_script_gen.py (1)
cortex/script_gen.py (3)
  • ScriptGenerator (87-280)
  • generate (96-186)
  • test (188-222)
cortex/cli.py (2)
cortex/script_gen.py (4)
  • ScriptGenerator (87-280)
  • generate (96-186)
  • test (188-222)
  • show_history (249-280)
tests/test_script_gen.py (1)
  • generator (16-18)
cortex/script_gen.py (1)
cortex/cli.py (2)
  • stack (184-212)
  • history (608-669)
🪛 GitHub Actions: CI
cortex/cli.py

[error] 1-1: black --check . reported that 1 file would be reformatted. Run 'black' to format the code.

⏰ 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). (3)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.10)
🔇 Additional comments (7)
cortex/script_gen.py (2)

21-49: Excellent fix for idempotency and Python version concerns!

The package structure now correctly uses per-package check commands (e.g., docker for docker.io, docker-compose for docker-compose), which addresses the critical idempotency bug flagged in previous reviews. Additionally, changing from python3.11 to python3 makes the configuration more portable.


260-264: Good exception handling.

The error handling correctly uses except Exception: rather than a bare except:, which properly allows system exits and keyboard interrupts to propagate.

cortex/cli.py (2)

841-845: Help documentation is clear and consistent.

The help table entries for the script commands are well-documented and follow the existing format conventions.


902-940: Parser configuration is well-structured.

The argparse setup is comprehensive with appropriate choices, defaults, and help text. The required=True for script_action ensures users must specify a subcommand.

tests/test_script_gen.py (3)

1-25: Well-structured test fixtures.

The test suite uses pytest fixtures appropriately, with clean separation between the generator instance and temporary file paths.


73-223: Comprehensive test coverage meeting requirements.

The test suite thoroughly covers:

  • All four stacks (docker, python, nodejs, ollama)
  • Both output formats (bash, ansible)
  • Idempotency checks
  • Error handling
  • Bash best practices (strict mode, traps, logging)
  • File operations and permissions

This aligns well with the >80% coverage target from the coding guidelines and issue #140 requirements.


210-222: Excellent use of parameterized tests.

The parameterized tests efficiently validate all stacks in both formats, reducing code duplication while maintaining comprehensive coverage.

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

🧹 Nitpick comments (2)
cortex/script_gen.py (2)

16-19: Consider tightening the verification type.

The verification field is typed as str | None, but all stack definitions in STACK_DEPS provide non-null verification commands. Consider changing the type to just str for consistency, or keep the optional type if you plan to support stacks without verification in the future.

🔎 Proposed type refinement
 class StackConfig(TypedDict):
     packages: list[dict | str]
-    verification: str | None
+    verification: str

281-282: Enhance docstring to document the limit parameter.

While a docstring is now present (addressing the previous comment), it doesn't document the limit parameter. Per best practices, all parameters should be documented in public API docstrings.

🔎 Enhanced docstring
     def show_history(self, limit: int = 10) -> None:
-        """Print recent script generation history."""
+        """
+        Display recent script generation history.
+
+        Args:
+            limit: Maximum number of history entries to show (default: 10)
+        """
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 09a353d and ea9f3c5.

📒 Files selected for processing (2)
  • cortex/cli.py
  • cortex/script_gen.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • cortex/cli.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Follow PEP 8 style guide
Type hints required in Python code
Docstrings required for all public APIs

Files:

  • cortex/script_gen.py
🧠 Learnings (2)
📚 Learning: 2025-12-11T12:03:24.071Z
Learnt from: CR
Repo: cortexlinux/cortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-11T12:03:24.071Z
Learning: Applies to {setup.py,setup.cfg,pyproject.toml,**/__init__.py} : Use Python 3.10 or higher as the minimum supported version

Applied to files:

  • cortex/script_gen.py
📚 Learning: 2025-12-11T12:03:24.071Z
Learnt from: CR
Repo: cortexlinux/cortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-11T12:03:24.071Z
Learning: Applies to **/*.py : Docstrings required for all public APIs

Applied to files:

  • cortex/script_gen.py
🧬 Code graph analysis (1)
cortex/script_gen.py (1)
cortex/cli.py (2)
  • stack (184-212)
  • history (611-672)
⏰ 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). (3)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.10)
  • GitHub Check: test (3.11)
🔇 Additional comments (3)
cortex/script_gen.py (3)

99-210: Well-structured script generation implementation.

The generate method properly addresses previous review concerns:

  • Complete docstring with parameter documentation ✓
  • Per-package idempotency checks to avoid the multi-package installation bug ✓
  • Supports both dict and string package formats (lines 122-127)
  • Proper error handling with informative messages
  • Correct file permissions (0o755 for executable scripts)
  • History tracking integration

The implementation is thorough and follows best practices.


211-254: Solid test implementation with good safety measures.

The test method includes:

  • Complete docstring ✓
  • Proper script validation using bash -n for syntax checking
  • Timeout protection (10 seconds) to prevent hanging on problematic scripts
  • Clear error messages and user feedback
  • Option to skip validation with sandbox=False parameter

283-313: Clean history display with proper error handling.

The implementation demonstrates good practices:

  • Graceful degradation when PyYAML is unavailable (lines 283-287)
  • Robust error handling for missing or corrupted history files (lines 289-297)
  • Clear user feedback for all scenarios (empty history, errors, etc.)
  • Correct ordering with reversed(data[-limit:]) to show latest entries first (line 306)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
cortex/cli.py (3)

284-289: Add type hint and docstring for public API.

Per coding guidelines, public methods require type hints and docstrings. The doctor() method should declare its return type and document its purpose.

🔎 Proposed fix
     # Run system health checks
-    def doctor(self):
+    def doctor(self) -> int:
+        """Run comprehensive system health checks and diagnostics."""
         from cortex.doctor import SystemDoctor

         doctor = SystemDoctor()
         return doctor.run_checks()

291-322: Add fallback return for unhandled script actions.

If args.script_action doesn't match any of the expected values ("generate", "test", "history"), the function exits the try block without returning, resulting in an implicit None return which violates the -> int type hint. While argparse should prevent this via required=True, a defensive fallback is recommended.

🔎 Proposed fix
         elif args.script_action == "history":
             limit = args.limit
             generator.show_history(limit=limit)
             return 0

+        else:
+            console.print(f"[red]✗ Unknown script action: {args.script_action}[/red]")
+            return 1
+
     except FileNotFoundError:
         filename = getattr(args, "filename", "unknown")
         console.print(f"[red]✗ Script file not found: {filename}[/red]")
         return 1
     except Exception as e:
         console.print(f"[red]✗ Script command failed: {str(e)}[/red]")
         return 1

1251-1255: Variable history_parser shadows the main history command parser.

The variable history_parser defined here on line 1252 shadows the identically named variable defined later on line 1272 for the main cortex history command. While Python allows this, it can cause confusion during maintenance.

🔎 Proposed fix
     # cortex script history
-    history_parser = script_subs.add_parser("history", help="Show script generation history")
-    history_parser.add_argument(
+    script_history_parser = script_subs.add_parser("history", help="Show script generation history")
+    script_history_parser.add_argument(
         "--limit", "-l", type=int, default=10, help="Number of entries to show (default: 10)"
     )
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f49671c and 5c7f5f5.

📒 Files selected for processing (1)
  • cortex/cli.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Follow PEP 8 style guide
Type hints required in Python code
Docstrings required for all public APIs

Files:

  • cortex/cli.py
🧬 Code graph analysis (1)
cortex/cli.py (3)
cortex/doctor.py (2)
  • SystemDoctor (21-478)
  • run_checks (48-103)
cortex/script_gen.py (4)
  • ScriptGenerator (91-324)
  • generate (105-215)
  • test (217-259)
  • show_history (287-324)
tests/test_script_gen.py (1)
  • generator (16-18)
⏰ 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). (3)
  • GitHub Check: test (3.10)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)
🔇 Additional comments (2)
cortex/cli.py (2)

1136-1140: LGTM!

The help table entries accurately describe the new script subcommands and are consistent with the existing help format.


1443-1446: LGTM!

The dispatch logic for doctor and script commands follows the established pattern and integrates correctly with the existing command handling structure.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c7f5f5 and bc8eda2.

📒 Files selected for processing (1)
  • cortex/cli.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Follow PEP 8 style guide
Type hints required in Python code
Docstrings required for all public APIs

Files:

  • cortex/cli.py
🧠 Learnings (1)
📚 Learning: 2025-12-11T12:03:24.071Z
Learnt from: CR
Repo: cortexlinux/cortex PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-11T12:03:24.071Z
Learning: Applies to **/*sandbox*.py : Implement Firejail sandboxing for package operations

Applied to files:

  • cortex/cli.py
🧬 Code graph analysis (1)
cortex/cli.py (2)
cortex/doctor.py (2)
  • SystemDoctor (21-478)
  • run_checks (48-103)
cortex/script_gen.py (4)
  • ScriptGenerator (91-324)
  • generate (105-215)
  • test (217-259)
  • show_history (287-324)
⏰ 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). (4)
  • GitHub Check: Build Package
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.10)
  • GitHub Check: test (3.12)
🔇 Additional comments (1)
cortex/cli.py (1)

291-322: LGTM! Past review issues addressed.

The implementation correctly handles all script subcommands with proper error handling. All previously flagged issues have been resolved:

  • Exception handlers now return explicit integer values
  • FileNotFoundError uses safe attribute access with getattr
  • All code paths return the declared int type

@sonarqubecloud
Copy link

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.

Installation Script Generator

1 participant