-
-
Notifications
You must be signed in to change notification settings - Fork 50
feat: implemet Automatic Documentation Generator #644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: implemet Automatic Documentation Generator #644
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughAdds a new DocsGenerator feature (cortex/docs_generator.py) with CLI integration ( Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant CLI
participant DocsGenerator
participant InstallationHistory
participant ConfigManager
participant FileSystem
participant Templates
User->>CLI: cortex docs generate nginx
CLI->>DocsGenerator: generate_software_docs("nginx")
DocsGenerator->>InstallationHistory: get_installation_data("nginx")
InstallationHistory-->>DocsGenerator: install_history
DocsGenerator->>ConfigManager: get_package_info("nginx")
ConfigManager-->>DocsGenerator: package_details
DocsGenerator->>FileSystem: scan /etc, ~/.config, home
FileSystem-->>DocsGenerator: config_file_paths
DocsGenerator->>Templates: load templates (software/default)
Templates-->>DocsGenerator: templates
DocsGenerator->>DocsGenerator: render guides (installation, config, quick-start, troubleshooting)
DocsGenerator->>FileSystem: write guide files (~/.cortex/docs/nginx/)
DocsGenerator-->>CLI: generated_file_paths
CLI-->>User: ✓ Documentation generated
sequenceDiagram
actor User
participant CLI
participant DocsGenerator
participant FileSystem
participant Renderer as MarkdownHTMLPDF
participant Console
User->>CLI: cortex docs export nginx --format pdf
CLI->>DocsGenerator: export_docs("nginx","pdf")
DocsGenerator->>FileSystem: check ~/.cortex/docs/nginx/
alt docs exist
FileSystem-->>DocsGenerator: doc_files
else docs missing
DocsGenerator->>DocsGenerator: generate_software_docs("nginx")
end
DocsGenerator->>FileSystem: read and merge .md files
DocsGenerator->>Renderer: convert merged markdown to pdf/html
alt pdfkit available
Renderer-->>DocsGenerator: nginx_docs.pdf
else fallback to HTML
Renderer-->>DocsGenerator: nginx_docs.html
end
DocsGenerator->>FileSystem: write exported file
DocsGenerator-->>CLI: export_file_path
CLI-->>User: ✓ Exported to nginx_docs.pdf
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
CLA Verification PassedAll contributors have signed the CLA.
|
Summary of ChangesHello @pratyush07-hub, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request integrates an automatic documentation generator into Cortex Linux, significantly improving the accessibility and currency of system and software documentation. By automating the creation and updating of guides, it aims to provide users with up-to-date information on installations, configurations, and usage, directly enhancing the overall user experience and system maintainability. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces an automatic documentation generator, a significant new feature for Cortex. The implementation is comprehensive, covering document generation, viewing, and exporting. However, the current implementation has critical security vulnerabilities related to path traversal that must be addressed. Additionally, there are opportunities to improve error handling, dependency management, and code structure for better maintainability and robustness. While the test coverage for the new feature is good, it lacks tests for the identified security vulnerabilities.
|
|
||
| return sorted(set(found)) | ||
|
|
||
| def generate_software_docs(self, software_name: str) -> dict[str, str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The software_name parameter, which can be controlled by the user, is used to construct file paths throughout this class without proper sanitization. This introduces a critical path traversal vulnerability.
For example, in this method, software_dir = self.docs_dir / software_name at line 125 could allow an attacker to write files outside the intended ~/.cortex/docs directory by providing a malicious name like ../../my_target_dir.
This vulnerability exists in multiple places:
_find_config_files(line 97)generate_software_docs(line 125)_get_template(line 136)view_guide(line 228)export_docs(lines 242, 246)
Recommendation:
Sanitize the software_name at the beginning of each public method (generate_software_docs, view_guide, export_docs) to prevent directory traversal. A simple check can prevent this:
if '..' in software_name or '/' in software_name or '\\' in software_name:
raise ValueError(f"Invalid characters in software name: {software_name}")There was a problem hiding this 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
🤖 Fix all issues with AI agents
In `@cortex/cli.py`:
- Around line 4022-4043: The current check uses substring heuristics ("failed"
in path.lower()) in the docs export branch; update export logic so export_docs
returns a structured result (e.g., tuple (success, path) or dict {'success':
bool, 'path': str} ) or raises an exception on error, and then change the CLI
branch (the args.docs_action == "export" block that calls docs_gen.export_docs)
to rely on that boolean/exception instead of substring matching; specifically
modify DocsGenerator.export_docs and the caller in cortex/cli.py to use the new
return shape (check success explicitly or catch the exception) and display the
appropriate success or warning message.
In `@cortex/docs_generator.py`:
- Around line 125-129: The code uses user-provided software_name, format, and
filenames directly to build filesystem paths and resolve templates (see
variables/software_name, format, docs_dir and the file-writing loop in
docs_generator.py), which allows path traversal; fix by validating and
normalizing these inputs: reject or sanitize any value containing path
separators, "..", or null bytes; restrict format to an allowlist of known safe
formats; construct paths using pathlib and call resolve() then assert the
resolved path is a child of docs_dir to prevent escapes; also sanitize filenames
produced in docs (and any template lookup keys) to a safe subset of characters
or map them to generated safe names before opening/writing files. Ensure the
same checks are applied at the other occurrences you noted (around the other
blocks at lines 134-139, 228-229, 242-247).
- Around line 23-30: Add explicit return type annotations and a docstring:
annotate the constructor def __init__(self) as -> None and add a one-line
docstring describing initialization (e.g., "Initialize docs generator, configure
paths and helpers."), and annotate the public method def view_guide(self, ...)
as -> None (keep its existing docstring unchanged). Update the function
signatures in the Cortex DocsGenerator class (look for __init__ and view_guide)
to include the -> None return type to satisfy the typing guideline.
In `@cortex/installation_history.py`:
- Around line 366-378: The current docs auto-generation block (guarded by
InstallationStatus.SUCCESS and invoking
cortex.docs_generator.DocsGenerator.generate_software_docs on packages) must be
further gated by the installation's operation_type so it only runs for INSTALL,
UPGRADE, and CONFIG (not for REMOVE/PURGE/ROLLBACK or dry-run). Update the block
to query the installation record (using the installation identifier available in
this context) to fetch operation_type from the DB, check that operation_type is
one of "INSTALL", "UPGRADE", or "CONFIG" before instantiating DocsGenerator and
calling generate_software_docs for each package, and skip generation otherwise;
keep the existing ImportError and generic Exception handling around
DocsGenerator as-is.
🧹 Nitpick comments (1)
docs/modules/README_DOCS_GENERATOR.md (1)
21-23: Minor wording nit: “CLI Interface” is redundant.Consider shortening to “CLI” for clarity.
✏️ Wording tweak
-- **CLI Interface (`cortex/cli.py`)**: The `cortex docs` command group. +- **CLI (`cortex/cli.py`)**: The `cortex docs` command group.
| def __init__(self): | ||
| self.config_manager = ConfigManager() | ||
| self.history = InstallationHistory() | ||
| self.console = Console() | ||
| self.docs_dir = Path.home() / ".cortex" / "docs" | ||
| self.docs_dir.mkdir(parents=True, exist_ok=True) | ||
| self.template_base_dir = Path(__file__).parent / "templates" / "docs" | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Find and examine the file
find . -name "docs_generator.py" -path "*/cortex/*"Repository: cortexlinux/cortex
Length of output: 88
🏁 Script executed:
# Read the file with line numbers to verify the content at the specified lines
wc -l cortex/docs_generator.pyRepository: cortexlinux/cortex
Length of output: 90
🏁 Script executed:
# Get a larger context around lines 23-30 and line 214
cat -n cortex/docs_generator.py | sed -n '1,50p'Repository: cortexlinux/cortex
Length of output: 2168
🏁 Script executed:
# Check around line 214
cat -n cortex/docs_generator.py | sed -n '200,220p'Repository: cortexlinux/cortex
Length of output: 1119
Add return type annotations to public methods.
__init__ (line 23) is missing both return type annotation (-> None) and a docstring. view_guide (line 214) is missing a return type annotation (-> None), though it already has a docstring. Per coding guidelines, type hints are required for Python code.
Suggested update
- def __init__(self):
+ def __init__(self) -> None:
+ """Initialize the documentation generator and its dependencies."""
self.config_manager = ConfigManager()
self.history = InstallationHistory()
self.console = Console()
self.docs_dir = Path.home() / ".cortex" / "docs"
self.docs_dir.mkdir(parents=True, exist_ok=True)
self.template_base_dir = Path(__file__).parent / "templates" / "docs"- def view_guide(self, software_name: str, guide_type: str):
+ def view_guide(self, software_name: str, guide_type: str) -> None:
"""View a documentation guide in the terminal."""🤖 Prompt for AI Agents
In `@cortex/docs_generator.py` around lines 23 - 30, Add explicit return type
annotations and a docstring: annotate the constructor def __init__(self) as ->
None and add a one-line docstring describing initialization (e.g., "Initialize
docs generator, configure paths and helpers."), and annotate the public method
def view_guide(self, ...) as -> None (keep its existing docstring unchanged).
Update the function signatures in the Cortex DocsGenerator class (look for
__init__ and view_guide) to include the -> None return type to satisfy the
typing guideline.
| software_dir = self.docs_dir / software_name | ||
| software_dir.mkdir(parents=True, exist_ok=True) | ||
|
|
||
| for filename, content in docs.items(): | ||
| with open(software_dir / filename, "w") as f: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sanitize software_name/format to prevent path traversal and unsafe file access.
User-provided software_name and format are used in filesystem paths and template resolution without validation, enabling path traversal or arbitrary reads/writes.
🔒 Suggested hardening
+import re
@@
class DocsGenerator:
@@
+ def _sanitize_name(self, software_name: str) -> str:
+ safe = re.sub(r"[^A-Za-z0-9._+-]", "_", software_name).strip("._")
+ if not safe:
+ raise ValueError("Invalid software name")
+ return safe
@@
def _get_template(self, software_name: str, guide_name: str) -> Template:
"""Load a template for a specific software or the default."""
- software_template = self.template_base_dir / software_name / f"{guide_name}.md"
+ safe_name = self._sanitize_name(software_name)
+ software_template = self.template_base_dir / safe_name / f"{guide_name}.md"
@@
- software_dir = self.docs_dir / software_name
+ safe_name = self._sanitize_name(software_name)
+ software_dir = (self.docs_dir / safe_name).resolve()
+ if self.docs_dir not in software_dir.parents:
+ raise ValueError("Invalid software name")
@@
- filepath = self.docs_dir / software_name / filename
+ safe_name = self._sanitize_name(software_name)
+ filepath = self.docs_dir / safe_name / filename
@@
- software_dir = self.docs_dir / software_name
+ safe_name = self._sanitize_name(software_name)
+ software_dir = self.docs_dir / safe_name
@@
- export_path = Path.cwd() / f"{software_name}_docs.{format}"
+ format = format.lower()
+ if format not in {"md", "html", "pdf"}:
+ raise ValueError(f"Unsupported export format: {format}")
+ export_path = Path.cwd() / f"{safe_name}_docs.{format}"Also applies to: 134-139, 228-229, 242-247
🤖 Prompt for AI Agents
In `@cortex/docs_generator.py` around lines 125 - 129, The code uses user-provided
software_name, format, and filenames directly to build filesystem paths and
resolve templates (see variables/software_name, format, docs_dir and the
file-writing loop in docs_generator.py), which allows path traversal; fix by
validating and normalizing these inputs: reject or sanitize any value containing
path separators, "..", or null bytes; restrict format to an allowlist of known
safe formats; construct paths using pathlib and call resolve() then assert the
resolved path is a child of docs_dir to prevent escapes; also sanitize filenames
produced in docs (and any template lookup keys) to a safe subset of characters
or map them to generated safe names before opening/writing files. Ensure the
same checks are applied at the other occurrences you noted (around the other
blocks at lines 134-139, 228-229, 242-247).
|
|
||
| # Trigger documentation update for successful installations | ||
| if status == InstallationStatus.SUCCESS: | ||
| try: | ||
| from cortex.docs_generator import DocsGenerator | ||
|
|
||
| docs_gen = DocsGenerator() | ||
| for pkg in packages: | ||
| docs_gen.generate_software_docs(pkg) | ||
| except ImportError: | ||
| pass # Might happen during testing or if docs_generator is not yet available | ||
| except Exception as e: | ||
| logger.warning(f"Failed to auto-update docs for {packages}: {e}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, find the file and understand its structure
find . -name "installation_history.py" -type fRepository: cortexlinux/cortex
Length of output: 94
🏁 Script executed:
# Get the full context around the flagged lines
if [ -f "cortex/installation_history.py" ]; then
wc -l cortex/installation_history.py
fiRepository: cortexlinux/cortex
Length of output: 96
🏁 Script executed:
# Read the update_installation function and surrounding context
sed -n '340,400p' cortex/installation_history.pyRepository: cortexlinux/cortex
Length of output: 2215
🏁 Script executed:
# Search for InstallationType enum definition
rg "class InstallationType|enum InstallationType" -A 10Repository: cortexlinux/cortex
Length of output: 614
🏁 Script executed:
# Search for operation_type usage in the file
rg "operation_type" cortex/installation_history.py -B 2 -A 2Repository: cortexlinux/cortex
Length of output: 2224
🏁 Script executed:
# Check the database schema for installations table
rg "CREATE TABLE.*installations" -A 15Repository: cortexlinux/cortex
Length of output: 3230
🏁 Script executed:
# Search for REMOVE, PURGE, ROLLBACK operations
rg "REMOVE|PURGE|ROLLBACK" cortex/installation_history.py -B 2 -A 2Repository: cortexlinux/cortex
Length of output: 378
🏁 Script executed:
# Check dry-run handling in the file
rg "dry.run|dry_run" cortex/installation_history.py -B 3 -A 3Repository: cortexlinux/cortex
Length of output: 1343
🏁 Script executed:
# Find all calls to update_installation
rg "update_installation\(" cortex/installation_history.py -B 5 -A 5Repository: cortexlinux/cortex
Length of output: 1342
🏁 Script executed:
# Search for calls in other files
rg "update_installation\(" --type py -B 3 -A 3Repository: cortexlinux/cortex
Length of output: 15538
🏁 Script executed:
# Check the full update_installation method signature and beginning
sed -n '280,370p' cortex/installation_history.pyRepository: cortexlinux/cortex
Length of output: 3230
🏁 Script executed:
# Search for where dry_run affects the status parameter passed to update_installation
rg "InstallationStatus" cortex/installation_history.py | head -30Repository: cortexlinux/cortex
Length of output: 905
🏁 Script executed:
# Look at the install/upgrade/remove operations to see how they handle dry_run
rg "def install|def upgrade|def remove|def purge" cortex/ -A 30 | head -100Repository: cortexlinux/cortex
Length of output: 5603
🏁 Script executed:
# Check the exact query and see if operation_type is retrievable
sed -n '320,350p' cortex/installation_history.pyRepository: cortexlinux/cortex
Length of output: 1208
🏁 Script executed:
# Look for where operation_type is stored vs retrieved
rg "operation_type" cortex/installation_history.py | grep -E "(SELECT|INSERT|UPDATE)"Repository: cortexlinux/cortex
Length of output: 44
🏁 Script executed:
# Find all SELECT statements in the file
rg "SELECT" cortex/installation_history.py -A 3Repository: cortexlinux/cortex
Length of output: 686
🏁 Script executed:
# Check the full update_installation method one more time to be absolutely sure
sed -n '315,395p' cortex/installation_history.pyRepository: cortexlinux/cortex
Length of output: 3005
🏁 Script executed:
# Let me check the exact context in cli.py where dry_run calls update_installation
rg "dry_run" cortex/cli.py -B 5 -A 5 | head -80Repository: cortexlinux/cortex
Length of output: 2905
🏁 Script executed:
# Find the exact section where dry_run affects update_installation call in install method
sed -n '1,100p' cortex/cli.py | grep -n "def install" -A 200 | head -150Repository: cortexlinux/cortex
Length of output: 44
🏁 Script executed:
# Get the full install method with dry_run logic
rg "def install\(" cortex/cli.py -A 150 | head -200Repository: cortexlinux/cortex
Length of output: 6166
Gate auto-doc generation to install/upgrade/config operations only.
Documentation generation currently triggers on all SUCCESS operations, including REMOVE/PURGE/ROLLBACK and dry-run installations. This creates unnecessary I/O and produces incorrect docs (e.g., documenting packages as "installed" when they've been removed). Fetch operation_type from the database and gate generation to INSTALL, UPGRADE, and CONFIG operations.
🔧 Suggested guard
- cursor.execute(
- "SELECT packages, timestamp FROM installations WHERE id = ?", (install_id,)
- )
+ cursor.execute(
+ "SELECT packages, timestamp, operation_type FROM installations WHERE id = ?",
+ (install_id,),
+ )
result = cursor.fetchone()
@@
- packages = json.loads(result[0])
+ packages = json.loads(result[0])
+ op_type = InstallationType(result[2])
@@
- if status == InstallationStatus.SUCCESS:
+ if status == InstallationStatus.SUCCESS and op_type in {
+ InstallationType.INSTALL,
+ InstallationType.UPGRADE,
+ InstallationType.CONFIG,
+ }:🤖 Prompt for AI Agents
In `@cortex/installation_history.py` around lines 366 - 378, The current docs
auto-generation block (guarded by InstallationStatus.SUCCESS and invoking
cortex.docs_generator.DocsGenerator.generate_software_docs on packages) must be
further gated by the installation's operation_type so it only runs for INSTALL,
UPGRADE, and CONFIG (not for REMOVE/PURGE/ROLLBACK or dry-run). Update the block
to query the installation record (using the installation identifier available in
this context) to fetch operation_type from the DB, check that operation_type is
one of "INSTALL", "UPGRADE", or "CONFIG" before instantiating DocsGenerator and
calling generate_software_docs for each package, and skip generation otherwise;
keep the existing ImportError and generic Exception handling around
DocsGenerator as-is.
There was a problem hiding this 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
🤖 Fix all issues with AI agents
In `@cortex/cli.py`:
- Around line 4056-4077: The docs command block lacks exception handling around
DocsGenerator operations (DocsGenerator, generate_software_docs, export_docs,
view_guide), so wrap each docs_action branch (generate, export, view) in a
try/except that catches Exception, logs a user-friendly error via cx_print
(matching other CLI handlers), and returns a non-zero exit code on failure;
ensure you still return the normal success codes when no exception occurs and
include the exception message in the cx_print to aid the user.
♻️ Duplicate comments (1)
cortex/cli.py (1)
4056-4077: Avoid substring heuristics for export failures.
"failed" in path.lower()will misclassify software names likefailed-service. Prefer a stricter prefix or a structured return fromexport_docs.
🧹 Nitpick comments (1)
cortex/cli.py (1)
4075-4077: Handle missingdocs_actiongracefully.When the user runs
cortex docswithout a subcommand,args.docs_actionwill beNone, which falls through to theelsebranch and prints help. This works, but consider adding an explicit check for better clarity, similar to hownotify(line 223) handles missing subcommands.♻️ Optional improvement
elif args.command == "docs": + if not args.docs_action: + docs_parser.print_help() + return 0 docs_gen = DocsGenerator() if args.docs_action == "generate":
|
Anshgrover23
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pratyush07-hub Kindly address all coderabbitai comments and then ping me again.
Also, follow contributing.md guidelines ( i.e. add a demonstration video in PR description, write AI Usage etc.)



Related Issue
Closes #58
Summary
Implemented the Automatic Documentation Generator for Cortex Linux.
This PR adds functionality to:
Demonstration
Screencast.from.2026-01-18.15-40-22.webm
AI Disclosure
Claude Opus 4.5 (Antigravity Coding Assistant) was used to help frame and improve test cases and documentation structuring.
Checklist
type(scope): descriptionor[scope] descriptionpytest tests/)Summary by CodeRabbit
New Features
cortex docswith generate, export (MD/HTML/PDF), and view subcommands.Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.