feat(tools): add architecture violation scanner with CLI/REPL GitHub issue workflow (#3235)#3625
feat(tools): add architecture violation scanner with CLI/REPL GitHub issue workflow (#3235)#3625Devesh36 wants to merge 25 commits into
Conversation
Greptile code reviewThis repo uses Greptile for automated review. Before merge, aim for Confidence Score: 5/5 with zero unresolved review threads — see CONTRIBUTING.md. Run a review — add a PR comment with: Give it ~5-10 minutes (sometimes longer) for results, then fix feedback and re-trigger until you reach Confidence Score: 5/5. Optional: automate with the greploop skill. |
Greptile SummaryThis PR introduces the
Confidence Score: 4/5Safe to merge with minor follow-up — the scan and CLI paths are well-tested; the main remaining nits are a stale hint string and an unguarded OS-level read error. The PR addresses most of the pre-review feedback (lazy CI bridge, UnicodeDecodeError guard, SyntaxError guard, BaseTool base-class detection, clean-repo propose exit, group-flag propagation, explicit GITHUB_REPO forwarding). The outstanding items are:
Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant User
participant REPL as REPL / CLI
participant ScanOrch as scan.py orchestration
participant Scanners as scanners.py
participant GHClient as integrations/github/client.py
User->>REPL: /architecture-scan (or opensre architecture-scan)
REPL->>REPL: turn_needs_exclusive_stdin grants exclusive stdin
REPL->>REPL: _architecture_scan_initial_choice() menu
User->>REPL: selects propose or file-issues
REPL->>ScanOrch: run_architecture_scan(repo_root, max_file_lines, include_baselines)
ScanOrch->>Scanners: scan_dependency_violations()
ScanOrch->>Scanners: scan_oversized_files()
ScanOrch->>Scanners: scan_compatibility_shims()
ScanOrch->>Scanners: scan_misplaced_modules()
Scanners-->>ScanOrch: list[ArchitectureViolation]
ScanOrch->>ScanOrch: build_refactor_tasks(violations)
ScanOrch-->>REPL: scan result dict
alt propose
REPL->>ScanOrch: run_architecture_scan_and_propose_github_issues()
ScanOrch-->>REPL: proposals (read-only)
REPL->>User: display proposals
else file-issues
REPL->>GHClient: resolve_github_token() store then env vars
REPL->>ScanOrch: run_architecture_scan_and_file_github_issues()
ScanOrch->>GHClient: execute_github_issue_mutation per proposal
GHClient-->>ScanOrch: issue results
ScanOrch-->>REPL: issue results
REPL->>User: display created issues
end
REPL->>User: offer --issue-numbers follow-up menu
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant User
participant REPL as REPL / CLI
participant ScanOrch as scan.py orchestration
participant Scanners as scanners.py
participant GHClient as integrations/github/client.py
User->>REPL: /architecture-scan (or opensre architecture-scan)
REPL->>REPL: turn_needs_exclusive_stdin grants exclusive stdin
REPL->>REPL: _architecture_scan_initial_choice() menu
User->>REPL: selects propose or file-issues
REPL->>ScanOrch: run_architecture_scan(repo_root, max_file_lines, include_baselines)
ScanOrch->>Scanners: scan_dependency_violations()
ScanOrch->>Scanners: scan_oversized_files()
ScanOrch->>Scanners: scan_compatibility_shims()
ScanOrch->>Scanners: scan_misplaced_modules()
Scanners-->>ScanOrch: list[ArchitectureViolation]
ScanOrch->>ScanOrch: build_refactor_tasks(violations)
ScanOrch-->>REPL: scan result dict
alt propose
REPL->>ScanOrch: run_architecture_scan_and_propose_github_issues()
ScanOrch-->>REPL: proposals (read-only)
REPL->>User: display proposals
else file-issues
REPL->>GHClient: resolve_github_token() store then env vars
REPL->>ScanOrch: run_architecture_scan_and_file_github_issues()
ScanOrch->>GHClient: execute_github_issue_mutation per proposal
GHClient-->>ScanOrch: issue results
ScanOrch-->>REPL: issue results
REPL->>User: display created issues
end
REPL->>User: offer --issue-numbers follow-up menu
Reviews (20): Last reviewed commit: "style: fix ruff format in architecture-s..." | Re-trigger Greptile |
…ibility shim detection and misplaced module handling
|
@greptile review |
| violations: list[ArchitectureViolation] = [] | ||
| for py_file in iter_python_files(repo_root, roots): | ||
| rel_path = str(py_file.relative_to(repo_root)) | ||
| source = py_file.read_text(encoding="utf-8") |
There was a problem hiding this comment.
UnicodeDecodeError can crash the entire scan
py_file.read_text(encoding="utf-8") raises UnicodeDecodeError for any Python file that contains non-UTF-8 bytes — common in legacy source files with Latin-1–encoded comments or string literals. When that happens the exception propagates all the way out of run_architecture_scan, returning nothing to the caller instead of a partial result. The same unguarded pattern exists in _scan_core_prefix_violations (dependencies.py line 125), scan_misplaced_modules (misplaced.py line 62), and scan_compatibility_shims (shims.py line 72). parse_module in ast_utils.py already handles the analogous SyntaxError case — a matching read_source_safe helper there that catches UnicodeDecodeError and returns None, with callers skipping None results, would close this gap consistently across all four scanners.
…chitecture violation reporting Added a new command `opensre architecture-scan` for CLI and `/architecture-scan` for interactive shell, enabling users to scan for architecture violations with a deterministic report. The report includes detailed summaries of violation types and integrates with the existing architecture issue tool, enhancing usability and consistency across interfaces. Updated documentation to reflect these changes and ensure clarity on usage.
|
@greptile review |
…ture issue tool Updated variable names for clarity and introduced a new Protocol for type hinting in the scanners module. This enhances code readability and maintainability, ensuring better alignment with type expectations in the architecture issue tool.
|
@greptile review |
…issue tool Introduced the `propose_github_issues_from_architecture_tasks` function to build read-only GitHub issue proposals from architecture scan tasks. Updated documentation to clarify the process of filing issues and modified existing code to integrate this new functionality. Enhanced tests to ensure proper behavior of the new proposal generation feature.
|
@greptile review |
… capabilities Expanded the architecture issue tool to support filing GitHub issues directly from scan results. Introduced new commands for proposing and creating issues via the CLI and interactive shell. Updated documentation to clarify usage and added guidance for GitHub issue creation. Enhanced tests to validate the new functionality and ensure proper integration with existing features.
|
@greptile-apps review again |
Added logging to the GitHub token resolution process to capture warnings for invalid credentials and environment configurations. Introduced a new helper function to parse task indices, improving error handling for invalid inputs. Updated CLI commands to utilize the new parsing function and added tests to ensure proper behavior for invalid task indices.
|
@greptile review |
…ands with flags Merge group-level architecture-scan options into subcommand context instead of overwriting defaults, and parse propose/file-issues even when scan flags precede the subcommand in CLI and REPL wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@greptile review |
Short-circuit the integrated CLI workflow when a scan finds no refactor tasks instead of surfacing the LLM-tool empty-input error as a fatal exit. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@greptile review |
Defer importing .github/ci modules until dependency scanning runs so the tool package loads in pip-installed deployments while still using CI graph checks from a source checkout. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@greptile review |
| global _CI_BRIDGE, _CI_BRIDGE_LOAD_ATTEMPTED | ||
| if _CI_BRIDGE_LOAD_ATTEMPTED: | ||
| return _CI_BRIDGE | ||
| _CI_BRIDGE_LOAD_ATTEMPTED = True |
Broaden the lazy CI bridge loader to treat renamed or incomplete CI scripts like an unavailable bridge instead of crashing architecture scans. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@greptile review |
…st imports Resolve leftover post-merge lint failures from the upstream ReplSession->Session rename in cli_parity.py and test_commands.py, and fix import ordering in the gateway agent lifecycle test. Co-authored-by: Cursor <cursoragent@cursor.com>
|
looks good to me, it needs more review from the team |
instead of and other features like file-issues etc should be sub commands and not in the same line |
okay working on it |
- Refactor architecture-scan commands to accept GitHub repository URLs in the format `https://github.com/OWNER/REPO` or `OWNER/REPO`. - Update documentation and examples to reflect the new argument format. - Enhance error handling for invalid GitHub repository inputs. - Modify tests to ensure compatibility with the new URL format. This change improves usability by allowing users to specify repositories more flexibly and clearly.
|
@greptile-apps review again |
Merge upstream/main so CI picks up the github_mcp -> integrations.github.mcp move, update token-resolution imports and tests, preserve scan flags in REPL follow-up subcommands, and reformat architecture-scan CLI tests. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@greptile-apps review again |
Merge group-level --repo-root, --max-file-lines, and --include-baselines into propose/file-issues when set before the subcommand, with subcommand flags taking precedence when explicitly provided. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@greptile-apps review again |
|
@Devesh36 should be subcommands no? |
Default GitHub repo to Tracer-Cloud/opensre, show propose/file-issues menu up front, offer --issue-numbers follow-up after filing, and rename the task-indices flag across CLI, REPL, docs, and tests. Co-authored-by: Cursor <cursoragent@cursor.com>
| def architecture_scan_github_subcommand(args: list[str]) -> str | None: | ||
| """Return ``propose``/``file-issues`` when present, skipping scan-only flags.""" | ||
| i = 0 | ||
| while i < len(args): | ||
| token = args[i] | ||
| if token in _SCAN_OPTION_FLAGS: | ||
| i += 2 | ||
| continue | ||
| if token in _SCAN_FLAG_ONLY: | ||
| i += 1 | ||
| continue | ||
| if any(token.startswith(f"{flag}=") for flag in _SCAN_OPTION_FLAGS): | ||
| i += 1 | ||
| continue | ||
| if token.startswith("-"): | ||
| i += 1 | ||
| continue | ||
| lowered = token.lower() | ||
| if lowered in ARCHITECTURE_SCAN_GITHUB_SUBCOMMANDS: | ||
| return lowered | ||
| return None | ||
| return None | ||
|
|
There was a problem hiding this comment.
move this and the other parsing logic to a parsing util.
|
kindly fix the merge conflict @Devesh36 |
Resolve the .importlinter.strict conflict, extract architecture-scan argument parsing into a shared util per review feedback, trim duplicated CLI decorators, and add parsing/failure regression tests for the GitHub issue workflow. Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve .importlinter.strict by adopting the renamed azure_openai path and dropping stale config.gateway_output_sink ignores after the sink moved to gateway/. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@greptile review |
Parse the positional GITHUB_REPO from scan args when resolving repo scope and building follow-up CLI commands so --issue-numbers reruns target the user's repo instead of the git-inferred default. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@greptile review |
Co-authored-by: Cursor <cursoragent@cursor.com>
|
@greptile review |
|
tagging @w3joe |


This pull request introduces the new Architecture Issue Tool, which enables maintainers to scan the repository for architectural violations, generate refactor task proposals, and optionally file GitHub issues directly from the CLI or REPL. The implementation includes a new CLI command, comprehensive documentation, and enhancements to GitHub integration token resolution. The changes also update import boundaries and improve integration with the interactive shell.
Major features and improvements:
1. Architecture Issue Tool introduction and CLI integration
architecture-issue-tooldocumentation page describing the tool's purpose, usage, checks performed, parameters, and API examples (docs/architecture-issue-tool.mdx).opensre architecture-scanCLI command group with subcommands for scanning, proposing, and filing GitHub issues, including options for repo root, file size limits, and baseline inclusion (surfaces/cli/commands/architecture_scan.py,surfaces/cli/commands/__init__.py) [1] [2] [3].docs/docs.json).2. GitHub integration enhancements
integrations/github/client.py) [1] [2] [3] [4] [5].integrations/github/client.py) [1] [2].3. Import boundary and dependency updates
.importlinter.strictto allow necessary imports for the architecture issue tool and new integrations, including GitHub client and Slack delivery (.importlinter.strict) [1] [2] [3].4. Interactive shell enhancements
surfaces/interactive_shell/command_registry/cli_parity.py).References:
/fix #3235
demo shots