Feat/Auto Fix Github issues and do extensive AI PR reviews#250
Feat/Auto Fix Github issues and do extensive AI PR reviews#250AlexMadera merged 5 commits intodevelopfrom
Conversation
Implements comprehensive GitHub automation with three major components: 1. Issue Auto-Fix: Automatically creates specs from labeled issues - AutoFixButton component with progress tracking - useAutoFix hook for config and queue management - Backend handlers for spec creation from issues 2. GitHub PRs Tool: AI-powered PR review sidebar - New sidebar tab (Cmd+Shift+P) alongside GitHub Issues - PRList/PRDetail components for viewing PRs - Review system with findings by severity - Post review comments to GitHub 3. Issue Triage: Duplicate/spam/feature-creep detection - Triage handlers with label application - Configurable detection thresholds Also adds: - Debug logging (DEBUG=true) for all GitHub handlers - Backend runners/github module with orchestrator - AI prompts for PR review, triage, duplicate/spam detection - dev:debug npm script for development with logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes runner.py and orchestrator.py to handle both: - Package import: `from runners.github import ...` - Direct script: `python runners/github/runner.py` Uses try/except pattern for relative vs direct imports. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move --project global argument before subcommand so argparse can correctly parse it. Fixes "unrecognized arguments: --project" error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe PR introduces a comprehensive GitHub automation framework comprising prompt-based analysis, multi-pass PR reviews, issue triage and batching, auto-fix workflow orchestration, and data persistence. It implements audit logging, permission checking, rate limiting, bot detection, and multi-repo support with specialized services coordinated through a central orchestrator. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Orchestrator
participant ContextGatherer
participant PRReviewEngine
participant Services
participant AuditLogger
User->>Orchestrator: review_pr(pr_number)
Orchestrator->>AuditLogger: start_operation(PR_REVIEW_STARTED)
Orchestrator->>ContextGatherer: gather()
ContextGatherer->>ContextGatherer: fetch PR metadata, files, commits, AI bot comments
ContextGatherer-->>Orchestrator: PRContext
Orchestrator->>PRReviewEngine: run_multi_pass_review(context)
PRReviewEngine->>Services: run_review_pass(QUICK_SCAN)
Services->>Services: prompt + AI client → findings
PRReviewEngine->>Services: run_review_pass(SECURITY)
Services-->>PRReviewEngine: findings[]
PRReviewEngine->>PRReviewEngine: deduplicate_findings()
PRReviewEngine-->>Orchestrator: findings, structural_issues, ai_triages, quick_scan
Orchestrator->>Orchestrator: generate verdict, risk assessment, summary
Orchestrator->>Orchestrator: post review + ai_triage replies
Orchestrator->>AuditLogger: log(PR_REVIEW_COMPLETED, result)
Orchestrator-->>User: PRReviewResult
sequenceDiagram
participant BatchService
participant IssueBatcher
participant DuplicateDetector
participant BatchValidator
participant Storage
BatchService->>IssueBatcher: create_batches(issues)
IssueBatcher->>DuplicateDetector: _build_similarity_matrix()
DuplicateDetector->>DuplicateDetector: get embeddings (cache + compute)
DuplicateDetector->>DuplicateDetector: cosine_similarity scores
DuplicateDetector-->>IssueBatcher: similarity_matrix
IssueBatcher->>IssueBatcher: _cluster_issues (agglomerative)
IssueBatcher->>IssueBatcher: _create_batch_from_issues (primary + items)
IssueBatcher->>BatchValidator: validate_batch()
BatchValidator->>BatchValidator: format issues + call Claude
BatchValidator-->>IssueBatcher: BatchValidationResult
IssueBatcher->>IssueBatcher: _validate_and_split_batches (handle invalid)
IssueBatcher->>Storage: save(IssueBatch) + update index
IssueBatcher-->>BatchService: IssueBatch[]
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
| with open(batch_file, "w") as f: | ||
| json.dump(self.to_dict(), f, indent=2) | ||
|
|
||
| self.updated_at = datetime.now(timezone.utc).isoformat() |
There was a problem hiding this comment.
Stale timestamp saved to file due to ordering error
The save method updates updated_at on line 149 AFTER writing the file on line 147. Since to_dict() includes updated_at in its serialization (line 113), the saved file contains the OLD timestamp, not the new one. When the batch is loaded from disk later, it will have a stale updated_at value. The timestamp assignment needs to happen before json.dump is called.
| "avg_confidence": 0.0, | ||
| "by_level": {}, | ||
| "by_risk": {}, | ||
| } |
There was a problem hiding this comment.
Inconsistent dict keys returned for empty findings list
The get_summary method returns inconsistent dictionary keys depending on whether scored_findings is empty. The empty case (lines 527-533) returns only total, avg_confidence, by_level, and by_risk. The non-empty case (lines 548-556) also includes high_confidence_count and low_risk_count. Callers accessing these missing keys on an empty summary will get a KeyError.
Additional Locations (1)
There was a problem hiding this comment.
Actionable comments posted: 135
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (116)
README.mdapps/backend/prompts/github/duplicate_detector.mdapps/backend/prompts/github/issue_analyzer.mdapps/backend/prompts/github/issue_triager.mdapps/backend/prompts/github/pr_ai_triage.mdapps/backend/prompts/github/pr_fixer.mdapps/backend/prompts/github/pr_reviewer.mdapps/backend/prompts/github/pr_structural.mdapps/backend/prompts/github/spam_detector.mdapps/backend/runners/github/__init__.pyapps/backend/runners/github/audit.pyapps/backend/runners/github/batch_issues.pyapps/backend/runners/github/batch_validator.pyapps/backend/runners/github/bot_detection.pyapps/backend/runners/github/bot_detection_example.pyapps/backend/runners/github/cleanup.pyapps/backend/runners/github/confidence.pyapps/backend/runners/github/context_gatherer.pyapps/backend/runners/github/duplicates.pyapps/backend/runners/github/errors.pyapps/backend/runners/github/example_usage.pyapps/backend/runners/github/file_lock.pyapps/backend/runners/github/gh_client.pyapps/backend/runners/github/learning.pyapps/backend/runners/github/lifecycle.pyapps/backend/runners/github/memory_integration.pyapps/backend/runners/github/models.pyapps/backend/runners/github/multi_repo.pyapps/backend/runners/github/onboarding.pyapps/backend/runners/github/orchestrator.pyapps/backend/runners/github/output_validator.pyapps/backend/runners/github/override.pyapps/backend/runners/github/permissions.pyapps/backend/runners/github/providers/__init__.pyapps/backend/runners/github/providers/factory.pyapps/backend/runners/github/providers/github_provider.pyapps/backend/runners/github/providers/protocol.pyapps/backend/runners/github/purge_strategy.pyapps/backend/runners/github/rate_limiter.pyapps/backend/runners/github/runner.pyapps/backend/runners/github/sanitize.pyapps/backend/runners/github/services/__init__.pyapps/backend/runners/github/services/autofix_processor.pyapps/backend/runners/github/services/batch_processor.pyapps/backend/runners/github/services/pr_review_engine.pyapps/backend/runners/github/services/prompt_manager.pyapps/backend/runners/github/services/response_parsers.pyapps/backend/runners/github/services/triage_engine.pyapps/backend/runners/github/storage_metrics.pyapps/backend/runners/github/test_bot_detection.pyapps/backend/runners/github/test_context_gatherer.pyapps/backend/runners/github/test_enhanced_pr_review.pyapps/backend/runners/github/test_file_lock.pyapps/backend/runners/github/test_gh_client.pyapps/backend/runners/github/test_permissions.pyapps/backend/runners/github/test_rate_limiter.pyapps/backend/runners/github/testing.pyapps/backend/runners/github/trust.pyapps/backend/runners/github/validator_example.pyapps/frontend/package.jsonapps/frontend/src/main/ipc-handlers/github/autofix-handlers.tsapps/frontend/src/main/ipc-handlers/github/index.tsapps/frontend/src/main/ipc-handlers/github/pr-handlers.tsapps/frontend/src/main/ipc-handlers/github/triage-handlers.tsapps/frontend/src/main/ipc-handlers/github/utils/index.tsapps/frontend/src/main/ipc-handlers/github/utils/ipc-communicator.tsapps/frontend/src/main/ipc-handlers/github/utils/logger.tsapps/frontend/src/main/ipc-handlers/github/utils/project-middleware.tsapps/frontend/src/main/ipc-handlers/github/utils/subprocess-runner.tsapps/frontend/src/main/ipc-handlers/task/crud-handlers.tsapps/frontend/src/preload/api/index.tsapps/frontend/src/preload/api/modules/github-api.tsapps/frontend/src/renderer/App.tsxapps/frontend/src/renderer/components/GitHubIssues.tsxapps/frontend/src/renderer/components/Sidebar.tsxapps/frontend/src/renderer/components/github-issues/components/AutoFixButton.tsxapps/frontend/src/renderer/components/github-issues/components/BatchReviewWizard.tsxapps/frontend/src/renderer/components/github-issues/components/IssueDetail.tsxapps/frontend/src/renderer/components/github-issues/components/IssueListHeader.tsxapps/frontend/src/renderer/components/github-issues/components/index.tsapps/frontend/src/renderer/components/github-issues/hooks/index.tsapps/frontend/src/renderer/components/github-issues/hooks/useAnalyzePreview.tsapps/frontend/src/renderer/components/github-issues/hooks/useAutoFix.tsapps/frontend/src/renderer/components/github-issues/hooks/useGitHubInvestigation.tsapps/frontend/src/renderer/components/github-issues/hooks/useGitHubIssues.tsapps/frontend/src/renderer/components/github-issues/types/index.tsapps/frontend/src/renderer/components/github-prs/GitHubPRs.tsxapps/frontend/src/renderer/components/github-prs/components/FindingItem.tsxapps/frontend/src/renderer/components/github-prs/components/FindingsSummary.tsxapps/frontend/src/renderer/components/github-prs/components/PRDetail.tsxapps/frontend/src/renderer/components/github-prs/components/PRList.tsxapps/frontend/src/renderer/components/github-prs/components/ReviewFindings.tsxapps/frontend/src/renderer/components/github-prs/components/SeverityGroupHeader.tsxapps/frontend/src/renderer/components/github-prs/components/index.tsapps/frontend/src/renderer/components/github-prs/constants/severity-config.tsapps/frontend/src/renderer/components/github-prs/hooks/index.tsapps/frontend/src/renderer/components/github-prs/hooks/useFindingSelection.tsapps/frontend/src/renderer/components/github-prs/hooks/useGitHubPRs.tsapps/frontend/src/renderer/components/github-prs/index.tsapps/frontend/src/renderer/components/project-settings/hooks/useProjectSettings.tsapps/frontend/src/renderer/components/settings/GeneralSettings.tsxapps/frontend/src/renderer/lib/browser-mock.tsapps/frontend/src/renderer/stores/github/index.tsapps/frontend/src/renderer/stores/github/investigation-store.tsapps/frontend/src/renderer/stores/github/issues-store.tsapps/frontend/src/renderer/stores/github/pr-review-store.tsapps/frontend/src/renderer/stores/github/sync-status-store.tsapps/frontend/src/shared/constants/ipc.tsapps/frontend/src/shared/constants/models.tsapps/frontend/src/shared/types/ipc.tsapps/frontend/src/shared/types/settings.tspackage.jsontests/QA_REPORT_TEST_REFACTORING.mdtests/REFACTORING_SUMMARY.mdtests/REVIEW_TESTS_REFACTORING.mdtests/test_output_validator.py
🧰 Additional context used
📓 Path-based instructions (2)
apps/backend/prompts/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Agent prompts must be stored in
apps/backend/prompts/directory with descriptive filenames matching their purpose (e.g.,planner.md,coder.md,qa_reviewer.md)
Files:
apps/backend/prompts/github/duplicate_detector.mdapps/backend/prompts/github/spam_detector.mdapps/backend/prompts/github/issue_triager.mdapps/backend/prompts/github/pr_reviewer.mdapps/backend/prompts/github/pr_fixer.mdapps/backend/prompts/github/pr_structural.mdapps/backend/prompts/github/issue_analyzer.mdapps/backend/prompts/github/pr_ai_triage.md
apps/backend/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
apps/backend/**/*.py: Install test dependencies before running tests:cd apps/backend && uv pip install -r ../../tests/requirements-test.txt
Python 3.12+ is required for the backend
Files:
apps/backend/runners/github/providers/__init__.pyapps/backend/runners/github/services/batch_processor.pyapps/backend/runners/github/rate_limiter.pyapps/backend/runners/github/services/autofix_processor.pyapps/backend/runners/github/sanitize.pyapps/backend/runners/github/permissions.pyapps/backend/runners/github/providers/protocol.pyapps/backend/runners/github/services/pr_review_engine.pyapps/backend/runners/github/purge_strategy.pyapps/backend/runners/github/services/__init__.pyapps/backend/runners/github/confidence.pyapps/backend/runners/github/learning.pyapps/backend/runners/github/override.pyapps/backend/runners/github/runner.pyapps/backend/runners/github/batch_validator.pyapps/backend/runners/github/output_validator.pyapps/backend/runners/github/bot_detection.pyapps/backend/runners/github/gh_client.pyapps/backend/runners/github/file_lock.pyapps/backend/runners/github/cleanup.pyapps/backend/runners/github/orchestrator.pyapps/backend/runners/github/batch_issues.pyapps/backend/runners/github/example_usage.pyapps/backend/runners/github/onboarding.pyapps/backend/runners/github/models.pyapps/backend/runners/github/providers/factory.pyapps/backend/runners/github/__init__.pyapps/backend/runners/github/multi_repo.pyapps/backend/runners/github/context_gatherer.pyapps/backend/runners/github/audit.pyapps/backend/runners/github/bot_detection_example.pyapps/backend/runners/github/services/response_parsers.pyapps/backend/runners/github/memory_integration.pyapps/backend/runners/github/providers/github_provider.pyapps/backend/runners/github/storage_metrics.pyapps/backend/runners/github/services/triage_engine.pyapps/backend/runners/github/duplicates.pyapps/backend/runners/github/errors.pyapps/backend/runners/github/services/prompt_manager.pyapps/backend/runners/github/lifecycle.py
⚙️ CodeRabbit configuration file
apps/backend/**/*.py: Focus on Python best practices, type hints, and async patterns.
Check for proper error handling and security considerations.
Verify compatibility with Python 3.12+.
Files:
apps/backend/runners/github/providers/__init__.pyapps/backend/runners/github/services/batch_processor.pyapps/backend/runners/github/rate_limiter.pyapps/backend/runners/github/services/autofix_processor.pyapps/backend/runners/github/sanitize.pyapps/backend/runners/github/permissions.pyapps/backend/runners/github/providers/protocol.pyapps/backend/runners/github/services/pr_review_engine.pyapps/backend/runners/github/purge_strategy.pyapps/backend/runners/github/services/__init__.pyapps/backend/runners/github/confidence.pyapps/backend/runners/github/learning.pyapps/backend/runners/github/override.pyapps/backend/runners/github/runner.pyapps/backend/runners/github/batch_validator.pyapps/backend/runners/github/output_validator.pyapps/backend/runners/github/bot_detection.pyapps/backend/runners/github/gh_client.pyapps/backend/runners/github/file_lock.pyapps/backend/runners/github/cleanup.pyapps/backend/runners/github/orchestrator.pyapps/backend/runners/github/batch_issues.pyapps/backend/runners/github/example_usage.pyapps/backend/runners/github/onboarding.pyapps/backend/runners/github/models.pyapps/backend/runners/github/providers/factory.pyapps/backend/runners/github/__init__.pyapps/backend/runners/github/multi_repo.pyapps/backend/runners/github/context_gatherer.pyapps/backend/runners/github/audit.pyapps/backend/runners/github/bot_detection_example.pyapps/backend/runners/github/services/response_parsers.pyapps/backend/runners/github/memory_integration.pyapps/backend/runners/github/providers/github_provider.pyapps/backend/runners/github/storage_metrics.pyapps/backend/runners/github/services/triage_engine.pyapps/backend/runners/github/duplicates.pyapps/backend/runners/github/errors.pyapps/backend/runners/github/services/prompt_manager.pyapps/backend/runners/github/lifecycle.py
🧠 Learnings (2)
📚 Learning: 2025-12-23T13:28:36.005Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-23T13:28:36.005Z
Learning: Applies to apps/backend/prompts/**/*.md : Agent prompts must be stored in `apps/backend/prompts/` directory with descriptive filenames matching their purpose (e.g., `planner.md`, `coder.md`, `qa_reviewer.md`)
Applied to files:
apps/backend/prompts/github/spam_detector.mdapps/backend/prompts/github/issue_triager.mdapps/backend/prompts/github/pr_reviewer.mdapps/backend/prompts/github/pr_structural.mdapps/backend/runners/github/services/prompt_manager.py
📚 Learning: 2025-12-23T13:28:36.005Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-23T13:28:36.005Z
Learning: Spec directories must contain: `spec.md`, `requirements.json`, `context.json`, `implementation_plan.json`, `qa_report.md`, and optional `QA_FIX_REQUEST.md`
Applied to files:
apps/backend/prompts/github/issue_analyzer.md
🧬 Code graph analysis (16)
apps/backend/runners/github/providers/__init__.py (2)
apps/backend/runners/github/providers/factory.py (2)
get_provider(41-107)register_provider(21-38)apps/backend/runners/github/providers/github_provider.py (1)
GitHubProvider(34-531)
apps/backend/runners/github/permissions.py (6)
apps/backend/runners/github/providers/github_provider.py (3)
gh_client(70-72)repo(66-67)api_get(406-412)apps/backend/runners/github/providers/protocol.py (2)
repo(186-188)api_get(459-474)apps/backend/runners/github/multi_repo.py (1)
owner(84-86)apps/backend/runners/github/gh_client.py (1)
api_get(512-530)apps/backend/runners/github/testing.py (2)
api_get(73-77)api_get(293-304)apps/backend/runners/github/lifecycle.py (1)
get(406-414)
apps/backend/runners/github/providers/protocol.py (2)
apps/backend/runners/github/onboarding.py (1)
LabelData(48-51)apps/backend/runners/github/providers/github_provider.py (22)
provider_type(62-63)repo(66-67)fetch_pr(78-104)fetch_prs(106-153)fetch_pr_diff(155-157)post_review(159-165)merge_pr(167-192)close_pr(194-206)fetch_issue(212-229)fetch_issues(231-276)create_issue(278-303)close_issue(305-317)add_comment(319-327)apply_labels(333-339)remove_labels(341-347)create_label(349-356)list_labels(358-377)get_repository_info(383-385)get_default_branch(387-390)check_permissions(392-400)api_get(406-412)api_post(414-420)
apps/backend/runners/github/services/pr_review_engine.py (4)
apps/backend/runners/github/context_gatherer.py (2)
PRContext(83-101)gather(116-172)apps/backend/runners/github/models.py (4)
AICommentTriage(248-277)PRReviewFinding(203-244)ReviewPass(47-55)StructuralIssue(281-313)apps/backend/runners/github/services/prompt_manager.py (2)
PromptManager(18-268)get_review_pass_prompt(32-189)apps/backend/runners/github/services/response_parsers.py (5)
ResponseParser(40-214)parse_scan_result(44-64)parse_review_findings(67-113)parse_structural_issues(116-143)parse_ai_comment_triages(146-176)
apps/backend/runners/github/purge_strategy.py (3)
apps/backend/runners/github/providers/github_provider.py (1)
repo(66-67)apps/backend/runners/github/providers/protocol.py (1)
repo(186-188)apps/backend/runners/github/storage_metrics.py (1)
_calculate_directory_size(124-146)
apps/backend/runners/github/services/__init__.py (3)
apps/backend/runners/github/services/prompt_manager.py (1)
PromptManager(18-268)apps/backend/runners/github/services/response_parsers.py (1)
ResponseParser(40-214)apps/backend/runners/github/services/triage_engine.py (1)
TriageEngine(22-128)
apps/backend/runners/github/confidence.py (1)
apps/backend/runners/github/learning.py (7)
LearningPattern(229-255)LearningTracker(258-642)to_dict(128-150)to_dict(213-225)to_dict(245-255)get_accuracy(415-475)accuracy(199-204)
apps/backend/runners/github/batch_validator.py (1)
apps/backend/runners/github/batch_issues.py (2)
to_dict(56-63)to_dict(101-118)
apps/backend/runners/github/output_validator.py (1)
apps/backend/runners/github/models.py (2)
PRReviewFinding(203-244)ReviewSeverity(26-32)
apps/backend/runners/github/onboarding.py (2)
apps/backend/runners/github/providers/protocol.py (4)
LabelData(156-163)repo(186-188)get_repository_info(425-432)create_label(400-410)apps/backend/runners/github/providers/github_provider.py (3)
repo(66-67)get_repository_info(383-385)create_label(349-356)
apps/backend/runners/github/models.py (2)
apps/frontend/src/main/ipc-handlers/github/pr-handlers.ts (2)
PRReviewFinding(37-48)PRReviewResult(53-63)apps/frontend/src/preload/api/modules/github-api.ts (2)
PRReviewFinding(276-287)PRReviewResult(292-302)
apps/backend/runners/github/context_gatherer.py (2)
apps/backend/runners/github/gh_client.py (2)
run(100-249)pr_diff(335-347)apps/backend/runners/github/orchestrator.py (1)
_fetch_pr_diff(209-211)
apps/backend/runners/github/bot_detection_example.py (2)
apps/backend/runners/github/models.py (1)
GitHubRunnerConfig(668-777)apps/backend/runners/github/bot_detection.py (4)
get_stats(379-397)should_skip_pr_review(280-328)mark_reviewed(330-358)clear_pr_state(360-377)
apps/backend/runners/github/services/response_parsers.py (2)
apps/backend/runners/github/models.py (8)
AICommentTriage(248-277)AICommentVerdict(67-74)PRReviewFinding(203-244)ReviewCategory(35-44)ReviewSeverity(26-32)StructuralIssue(281-313)TriageCategory(77-86)TriageResult(468-541)apps/backend/runners/github/trust.py (1)
description(47-55)
apps/backend/runners/github/providers/github_provider.py (1)
apps/backend/runners/github/providers/protocol.py (6)
IssueFilters(126-137)LabelData(156-163)PRData(33-62)PRFilters(141-152)ProviderType(17-24)ReviewData(111-122)
apps/backend/runners/github/storage_metrics.py (1)
apps/backend/runners/github/purge_strategy.py (1)
_calculate_directory_size(271-288)
🪛 LanguageTool
apps/backend/prompts/github/issue_triager.md
[uncategorized] ~60-~60: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...own` label ## Priority Assessment ### High Priority - Security vulnerabilities - Data loss ...
(EN_COMPOUND_ADJECTIVE_INTERNAL)
[uncategorized] ~67-~67: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...- Regression from previous version ### Medium Priority - Feature requests with clear use case ...
(EN_COMPOUND_ADJECTIVE_INTERNAL)
[uncategorized] ~73-~73: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...rformance issues - UX improvements ### Low Priority - Minor enhancements - Edge cases - Cos...
(EN_COMPOUND_ADJECTIVE_INTERNAL)
apps/backend/prompts/github/pr_reviewer.md
[style] ~162-~162: To elevate your writing, try using a synonym here.
Context: ...xity**: Functions with >10 branches are hard to test - Code duplication: Same lo...
(HARD_TO)
apps/backend/prompts/github/pr_ai_triage.md
[style] ~174-~174: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...lly null? Is there validation upstream? Is this in a try/catch? TypeScript non-nul...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.18.1)
README.md
7-7: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
21-21: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
apps/backend/prompts/github/spam_detector.md
7-7: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
14-14: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
21-21: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
28-28: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
36-36: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
43-43: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
49-49: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
apps/backend/prompts/github/issue_triager.md
7-7: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
18-18: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
31-31: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
45-45: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
60-60: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
67-67: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
73-73: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
81-81: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
87-87: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
92-92: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
98-98: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
104-104: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
129-129: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
130-130: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
146-146: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
147-147: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
167-167: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
168-168: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
apps/backend/prompts/github/pr_reviewer.md
19-19: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
40-40: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
49-49: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
57-57: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
72-72: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
80-80: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
89-89: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
96-96: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
105-105: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
114-114: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
122-122: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
133-133: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
146-146: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
apps/backend/prompts/github/pr_fixer.md
24-24: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
31-31: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
38-38: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
91-91: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
98-98: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
apps/backend/prompts/github/pr_structural.md
85-85: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
90-90: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
95-95: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
100-100: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
apps/backend/prompts/github/issue_analyzer.md
15-15: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
24-24: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
33-33: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
95-95: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
apps/backend/prompts/github/pr_ai_triage.md
22-22: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
31-31: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
40-40: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
49-49: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
58-58: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
72-72: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
77-77: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
82-82: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
87-87: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
169-169: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
173-173: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
177-177: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
181-181: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
⏰ 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). (1)
- GitHub Check: Cursor Bugbot
🔇 Additional comments (57)
README.md (1)
7-7: Version bump applied consistently across documentation.The update from 2.7.2 is correctly reflected in both the version badge (Line 7) and all five download links (Lines 20–24), with proper filename conventions maintained for each platform.
Also applies to: 20-24
apps/backend/runners/github/lifecycle.py (5)
1-22: LGTM!Clean module docstring and imports. Using standard library only is appropriate for this foundational module.
24-72: LGTM!Well-structured enum with clear state groupings and useful class methods for state classification. The
str, Enuminheritance ensures JSON-serializable values.
74-151: LGTM!Comprehensive state transition mapping. Good that terminal states explicitly define empty transition sets, and retry/override paths are documented with comments.
154-184: LGTM!Clean conflict type enumeration and result dataclass with proper serialization.
187-217: LGTM!Clean transition record dataclass with proper serialization support.
apps/backend/runners/github/multi_repo.py (2)
1-32: LGTM!Clear module documentation with usage examples and appropriate imports for the functionality.
35-41: LGTM!The
(str, Enum)inheritance pattern enables clean JSON serialization.apps/backend/prompts/github/spam_detector.md (1)
94-102: LGTM! Well-designed safety guidelines.The guidelines appropriately prioritize human review ("Never auto-close"), consider edge cases (new users, language barriers), and emphasize that false positives are worse than missed spam. This is a responsible approach for automated moderation. The prompt location and naming follow the coding guidelines for agent prompts.
apps/backend/runners/github/rate_limiter.py (2)
68-98: LGTM! Correct token bucket implementation for async usage.The token bucket algorithm is correctly implemented using
time.monotonic()for elapsed time tracking. The refill logic and token acquisition are sound for single-threaded async contexts.
161-172: Verify AI model pricing is current.The AI_PRICING dictionary contains hardcoded model costs. These prices can change frequently, and the comment "as of 2025" suggests they may need periodic updates.
Consider loading pricing from a configuration file or environment variable for easier updates, or add a TODO to review periodically.
apps/backend/runners/github/confidence.py (3)
31-36: LGTM! Graceful handling of optional dependency.The try/except pattern for importing
LearningTrackerallows the module to function without the learning subsystem while enabling enhanced features when available.
319-348: LGTM! Defensive pattern access with fallback.The
_score_patternsmethod handles both object attributes and dictionary access usinggetattrwith dictgetfallback. This makes the code resilient to different pattern data structures.
360-373: The code is correct.AccuracyStatshas anaccuracyproperty that is properly implemented as a@propertydecorator, which computescorrect_predictions / (correct_predictions + incorrect_predictions)with zero-division handling. The access tostats.accuracyat lines 366-367 is valid and requires no changes. The suggested fix is unnecessary.Likely an incorrect or invalid review comment.
apps/backend/runners/github/duplicates.py (1)
166-201: LGTM! Reasonable entity extraction with sensible limits.The extraction patterns cover common technical content (error codes, file paths, function names, URLs, versions, stack traces) with appropriate limits to prevent excessive data. The limits (20 functions, 10 URLs, etc.) are sensible for similarity comparison.
apps/backend/runners/github/memory_integration.py (1)
201-213: LGTM! Sensible local storage with size limits.The local insights storage limits to the last 1000 entries and sanitizes the repo name for the filename. This prevents unbounded growth while maintaining useful history.
apps/backend/runners/github/errors.py (2)
68-148: LGTM! Well-designed structured error model.The
StructuredErrordataclass provides comprehensive error information including categorization, retry hints, correlation IDs, and serialization. The design supports both IPC and UI display needs effectively.
463-499: LGTM! Clean Result type for operation outcomes.The
Resultdataclass withsuccess()andfailure()factory methods provides a clean pattern for handling operations that may fail, similar to Rust's Result type.apps/backend/prompts/github/duplicate_detector.md (1)
1-90: LGTM! Comprehensive duplicate detection prompt.The prompt is well-structured with clear detection strategies, weighted indicators, comparison process, and confidence thresholds. The guidelines and edge cases sections help prevent false positives. The file is correctly located in
apps/backend/prompts/github/per coding guidelines.apps/backend/runners/github/providers/__init__.py (1)
1-48: LGTM! Clean package interface with proper exports.The
__init__.pyprovides a well-organized public API with:
- Protocol types (
GitProvider, data classes)- Concrete implementation (
GitHubProvider)- Factory functions (
get_provider,register_provider)The
__all__list correctly documents the public interface, and the docstring provides clear usage examples.apps/backend/prompts/github/issue_analyzer.md (1)
1-112: LGTM: Well-structured issue analysis prompt.The prompt provides a clear workflow for transforming GitHub issues into structured specs, with well-defined JSON output format, complexity levels, and readiness criteria. The separation of issue types (Bug Report, Feature Request, Documentation) with specific extraction guidelines is particularly helpful.
Optional: Fix heading spacing for consistency
Static analysis flagged missing blank lines around some headings (MD022). While not critical, adding blank lines improves readability:
- Line 15: Add blank line before "### Bug Report Analysis"
- Line 24: Add blank line before "### Feature Request Analysis"
- Line 33: Add blank line before "### Documentation Issue Analysis"
- Line 95: Add blank line before "```json"
Based on learnings, this file correctly follows the convention of storing agent prompts in
apps/backend/prompts/with descriptive filenames.apps/backend/runners/github/services/__init__.py (1)
1-22: LGTM: Clean service layer API surface.The module provides a well-organized public API for GitHub automation services. The
__all__export list is complete and consistent with the imports, enabling clean external usage patterns likefrom apps.backend.runners.github.services import PromptManager.apps/backend/prompts/github/pr_structural.md (1)
1-171: LGTM: Comprehensive structural review guide.This prompt provides excellent guidance for identifying feature creep, scope issues, architecture violations, and PR structure problems. The severity guidelines (lines 83-103), concrete examples (lines 109-139), and constructive approach are particularly well-designed.
Optional: Fix heading spacing for consistency
Static analysis flagged missing blank lines around severity level headings (MD022):
- Line 85: Add blank line before "### Critical"
- Line 90: Add blank line before "### High"
- Line 95: Add blank line before "### Medium"
- Line 100: Add blank line before "### Low"
Based on learnings, this file correctly follows the convention of storing agent prompts in
apps/backend/prompts/with descriptive filenames.apps/backend/prompts/github/pr_fixer.md (1)
1-120: LGTM: Well-designed fix generation prompt.The prompt provides clear guidance for generating precise code fixes, with comprehensive JSON output format including line-level changes, explanations, and test requirements. The Do/Don't guidelines (lines 89-103) effectively prevent over-fixing and scope creep.
Optional: Fix heading spacing for consistency
Static analysis flagged missing blank lines around category headings (MD022):
- Line 24: Add blank line before "### Security Fixes"
- Line 31: Add blank line before "### Quality Fixes"
- Line 38: Add blank line before "### Logic Fixes"
- Line 91: Add blank line before "### Do"
- Line 98: Add blank line before "### Don't"
Based on learnings, this file correctly follows the convention of storing agent prompts in
apps/backend/prompts/with descriptive filenames.apps/backend/prompts/github/pr_ai_triage.md (1)
1-183: LGTM: Excellent meta-review prompt for AI comment triage.This prompt addresses a real problem (AI false positives) with a well-structured verdict taxonomy and evaluation framework. The inclusion of response templates (lines 142-150) and practical examples (lines 167-183) makes this immediately actionable.
Optional improvements
1. Minor style improvement at line 174:
LanguageTool flagged three successive sentences starting with "Is". Consider rephrasing for variety:
-**Your analysis**: Is this actually user input or internal data? Is there sanitization elsewhere (middleware, framework)? What's the actual attack vector? +**Your analysis**: Is this actually user input or internal data? Check for sanitization elsewhere (middleware, framework). What's the actual attack vector?2. Fix heading spacing for consistency:
Multiple MD022 warnings for missing blank lines around headings (lines 22, 31, 40, 49, 58, 72, 77, 82, 87, 169, 173, 177, 181).
Based on learnings, this file correctly follows the convention of storing agent prompts in
apps/backend/prompts/with descriptive filenames.apps/backend/runners/github/providers/factory.py (2)
1-152: Well-designed extensible provider factory.The factory pattern with dynamic registration is clean and extensible. Type hints are comprehensive, error handling is clear, and the API supports both built-in providers (GitHub) and future extensions (registry-based).
Key strengths:
- Clean separation between registry and built-in providers
- Proper enum normalization from strings (lines 65-72)
- Helpful error messages for unimplemented providers
- Python 3.12+ compatible with modern type hints
80-80: The parameter name_repois correct and matches theGitHubProviderdataclass definition.The
GitHubProviderclass uses@dataclasswith_repo: stras a field (line 46), which automatically generates an__init__method that accepts_repoas a parameter. Line 80's usage of_repo=repois correct.The underscore prefix is intentional—it follows Python convention for internal/private attributes and is used consistently throughout the class. No change needed.
apps/backend/runners/github/__init__.py (1)
1-41: LGTM: Clean public API for GitHub automation runners.The module provides a well-organized public API with clear separation between orchestrator, models, and enums. The docstring (lines 1-12) helpfully clarifies that this is separate from the main task execution pipeline, which prevents confusion about the architecture.
apps/backend/prompts/github/issue_triager.md (1)
1-199: LGTM: Comprehensive issue triage prompt with clear criteria.This prompt provides excellent guidance for issue classification with well-defined categories, appropriate confidence thresholds for different detection types (duplicate 80%+, spam 75%+, feature creep 70%+), and a comprehensive label taxonomy. The emphasis on conservative flagging and human-in-the-loop review (lines 184-191) is particularly important.
Key strengths:
- Clear detection criteria with specific confidence thresholds
- Multiple concrete examples showing different scenarios
- Complete JSON schema with all necessary fields
- Conservative approach prevents over-automation
Optional: Fix heading spacing for consistency
Static analysis flagged missing blank lines around numerous headings (MD022). While not critical, adding blank lines improves readability. Main occurrences at lines 7, 18, 31, 45, 60, 67, 73, 81, 87, 92, 98, 104, 129-130, 146-147, 167-168.
Based on learnings, this file correctly follows the convention of storing agent prompts in
apps/backend/prompts/with descriptive filenames.apps/backend/prompts/github/pr_reviewer.md (1)
1-335: LGTM! Well-structured PR review prompt.The prompt follows the coding guidelines by being stored in
apps/backend/prompts/github/with a descriptive filename matching its purpose. The multi-phase methodology (OWASP Top 10, language-specific checks, quality, logic, tests, patterns, documentation) is comprehensive, and the JSON output contract is clearly defined with good examples.The markdownlint warnings about missing blank lines around headings (lines 40, 49, 57, etc.) are minor formatting issues that don't affect functionality.
apps/backend/runners/github/bot_detection_example.py (1)
14-65: LGTM - Clear demonstration of bot detection integration.The example effectively illustrates the three key scenarios (human PR, cooling-off period, bot-authored PR) and shows how to access statistics. The placeholder tokens and paths are appropriate for example code.
apps/backend/runners/github/services/prompt_manager.py (1)
191-267: LGTM - Good prompt loading pattern with fallbacks.The file-based prompt loading with embedded fallbacks provides flexibility for customization while ensuring the system works out-of-the-box. The prompt content aligns with the coding guidelines requiring prompts in
apps/backend/prompts/.apps/backend/runners/github/storage_metrics.py (1)
26-62: LGTM - Clean dataclass design.The
StorageMetricsdataclass is well-structured with sensible defaults, a convenienttotal_mbproperty, and ato_dictmethod for serialization. The breakdown structure into_dictprovides good organization for API responses.apps/backend/runners/github/services/batch_processor.py (1)
118-119: Division by zero risk whenbatchesis empty.If
batchesis an empty list, this loop body will never execute, but the progress calculation40 * (i / len(batches))would cause aZeroDivisionErrorif the loop did run with an empty list. While the currentforloop naturally handles this, consider adding an explicit guard for clarity and future-proofing.The current code is safe because the loop won't execute if
batchesis empty, but verify this assumption holds if the code is refactored.apps/backend/runners/github/output_validator.py (1)
70-89: LGTM on the validation pipeline structure.The
validate_findingsmethod has a clean design: filter invalid findings and enhance valid ones. The separation of concerns between_is_validand_enhanceis appropriate.apps/backend/runners/github/runner.py (2)
68-76: Well-structured progress callback with context.The
print_progressfunction cleanly formats progress with optional PR/issue context prefixes. Good UX for CLI output.
326-331: The review comment is incorrect. TheIssueBatchclass inapps/backend/runners/github/batch_issues.py(line 83) is defined with anissuesattribute (issues: list[IssueBatchItem]), notitems. The code correctly accessesbatch.issuesat lines 327 and 464 inrunner.py, and noAttributeErrorwould be raised.Likely an incorrect or invalid review comment.
apps/backend/runners/github/purge_strategy.py (1)
32-58: Clean dataclass design for PurgeResult.The
PurgeResultdataclass with computedfreed_mbproperty andto_dict()serialization is well-designed for tracking purge operations.apps/backend/runners/github/sanitize.py (2)
75-96: Excellent prompt injection detection patterns.The
INJECTION_PATTERNSlist covers key attack vectors including instruction override attempts, system prompt injections, and role manipulation. The detection-only approach (warn, don't remove) is appropriate for logging suspicious content while avoiding false positive content modification.
201-207: Good defense against delimiter injection.Escaping the
<user_content>delimiters when they appear in user input prevents attackers from prematurely closing the content wrapper and injecting instructions.apps/backend/runners/github/providers/protocol.py (1)
170-178: Well-designed provider protocol with comprehensive coverage.The
GitProviderprotocol provides a clean abstraction with:
- PR operations (fetch, review, merge, close)
- Issue operations (fetch, create, close, comment)
- Label operations (apply, remove, create, list)
- Repository operations (info, permissions)
- Low-level API access
This enables clean multi-provider support.
apps/backend/runners/github/gh_client.py (2)
100-231: Robust retry and timeout handling.The
runmethod has well-implemented:
- Per-attempt timeouts with proper process cleanup on timeout
- Exponential backoff (1s, 2s, 4s)
- Rate limit detection from stderr patterns
- Structured logging throughout
- Proper exception hierarchy (GHTimeoutError, GHCommandError, RateLimitExceeded)
157-162: Process cleanup logs warning but doesn't re-raise on kill failure.If
proc.kill()fails (line 159), the warning is logged but the code continues to the retry logic. This is acceptable, but consider that a zombie process might accumulate resources.Verify that repeated kill failures don't lead to resource exhaustion in long-running automation scenarios.
apps/backend/runners/github/models.py (1)
202-229: Transformation layer already exists between backend and frontend.The backend correctly returns
suggested_fixin snake_case fromto_dict(), and the frontend IPC handler (apps/frontend/src/main/ipc-handlers/github/pr-handlers.ts, lines 127-130) explicitly converts it to camelCasesuggestedFixwhen building the response. Each layer appropriately uses its own naming convention.Likely an incorrect or invalid review comment.
apps/backend/runners/github/cleanup.py (1)
368-372: Dead code in _prune_indexes: the method targets a non-existent data structure.The
_prune_indexesmethod expects index files with an"items"key containing entries with"file_path"or"path"fields. However, the actual index structures created byPRReviewResult._update_index()andAutoFixState._update_index()use different keys:
- PR index:
{"reviews": [...]}- Issues index:
{"triaged": [], "auto_fix_queue": [...]}Neither contains an
"items"key or entries with file path fields. Theitems = index_data.get("items", {})call will always return an empty dictionary, making the pruning loop never execute.Likely an incorrect or invalid review comment.
apps/backend/runners/github/providers/github_provider.py (2)
69-72: Property may returnNonedespite return type annotation.The
gh_clientproperty is typed to returnGHClient, but_gh_clientcan beNoneif__post_init__logic fails. While__post_init__initializes it whenNone, if an exception occurs duringGHClientconstruction, subsequent access would fail.Consider adding a runtime check:
🔎 Proposed fix
@property def gh_client(self) -> GHClient: """Get the underlying GHClient.""" + if self._gh_client is None: + raise RuntimeError("GHClient not initialized") return self._gh_client
426-467: LGTM!The
_parse_pr_datahelper handles various edge cases well - checking for dict vs string author, iterating labels safely, handling None files, and providing sensible defaults.apps/backend/runners/github/batch_issues.py (2)
721-735:remove_batchdoesn't handle concurrent access.If another process is reading/writing the batch file simultaneously, this could lead to race conditions or partial reads.
For a single-user CLI tool this may be acceptable, but verify if this will be used in a multi-process environment.
559-564: This concern is incorrect. The initialization ofself.validatorat line 225 does not have exception handling that could silently fail, andBatchValidator.__init__does not raise exceptions—it only logs warnings if the Claude SDK is unavailable. The defensive check at line 496 (if self.validate_batches_enabled and self.validator:) correctly ensures that_validate_and_split_batches()is only called whenself.validatoris not None, making the code at line 559 safe. There is no scenario where a silent initialization failure could occur and then line 559 would be reached.apps/backend/runners/github/onboarding.py (1)
256-271: LGTM!The progressive enablement thresholds and minimum action requirements are well-documented and reasonable for a graduated rollout approach.
apps/backend/runners/github/learning.py (2)
624-642:check_pr_statusis a stub that returns 0.This method is documented as checking pending outcomes but does nothing. If callers rely on it, they'll get incorrect behavior.
Either implement the method or mark it clearly as not implemented:
def check_pr_status( self, repo: str, gh_provider, ) -> int: - # This would be called periodically to update pending outcomes - # Implementation depends on gh_provider being async - # Leaving as stub for now - return 0 + raise NotImplementedError( + "check_pr_status requires async implementation - use check_pr_status_async instead" + )
491-599: LGTM!The
detect_patternsmethod is well-structured with clear pattern detection logic for file types, categories, and change sizes. The confidence calculation based on sample size is a reasonable heuristic.apps/backend/runners/github/audit.py (1)
377-439: LGTM!The
operationcontext manager is well-designed - it properly logs start/completion/failure with timing, and usestime.monotonic()for accurate duration measurement regardless of system clock changes.apps/backend/runners/github/context_gatherer.py (4)
590-636:_resolve_import_pathresolves against filesystem but checks existence usingproject_dir.The resolution uses
(base_dir / import_path).resolve()which gives an absolute path, but then checksresolved.exists(). Ifbase_dirdoesn't containproject_diras a prefix (e.g., symlinks), the relative_to call will raise ValueError.The code handles ValueError but the logic flow is complex. Verify this works correctly with symlinked directories.
57-79: LGTM!The
AI_BOT_PATTERNSdictionary provides good coverage of known AI code review tools with consistent naming. This is a reasonable approach for bot detection.
424-503: LGTM!The
_detect_repo_structuremethod thoroughly checks for common monorepo patterns, workspaces, and framework indicators. The markdown formatting will produce clear context for AI consumption.
386-403: The endpoint syntax is correct — no changes needed.The
gh apicommand correctly uses{owner}and{repo}placeholders. These are auto-expanded by gh CLI from the repository context. The f-string with escaped braces ({{owner}}→{owner}) produces the correct endpoint format thatgh apiexpects. The suggested:owner/:reposyntax is not valid for gh api.
| ### Promotional Spam | ||
| - Product advertisements | ||
| - Service promotions | ||
| - Affiliate links | ||
| - SEO manipulation attempts | ||
| - Cryptocurrency/NFT promotions | ||
|
|
||
| ### Abuse & Trolling | ||
| - Offensive language or slurs | ||
| - Personal attacks | ||
| - Harassment content | ||
| - Intentionally disruptive content | ||
| - Repeated off-topic submissions | ||
|
|
||
| ### Low-Quality Content | ||
| - Random characters or gibberish | ||
| - Test submissions ("test", "asdf") | ||
| - Empty or near-empty issues | ||
| - Completely unrelated content | ||
| - Auto-generated nonsense | ||
|
|
||
| ### Bot/Mass Submissions | ||
| - Template-based mass submissions | ||
| - Automated security scanner output (without context) | ||
| - Generic "found a bug" without details | ||
| - Suspiciously similar to other recent issues | ||
|
|
||
| ## Detection Signals | ||
|
|
||
| ### High-Confidence Spam Indicators | ||
| - External promotional links | ||
| - No relation to project | ||
| - Offensive content | ||
| - Gibberish text | ||
| - Known spam patterns | ||
|
|
||
| ### Medium-Confidence Indicators | ||
| - Very short, vague content | ||
| - No technical details | ||
| - Generic language (could be new user) | ||
| - Suspicious links | ||
|
|
||
| ### Low-Confidence Indicators | ||
| - Unusual formatting | ||
| - Non-English content (could be legitimate) | ||
| - First-time contributor (not spam indicator alone) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Minor Markdown formatting: add blank lines around headings.
The static analysis tool flagged missing blank lines below headings at lines 7, 14, 21, 28, 36, 43, and 49. While this doesn't affect functionality, adding blank lines improves readability and adheres to Markdown best practices.
🔎 Example fix for one section
### Promotional Spam
+
- Product advertisements
- Service promotionsApply similar changes to the other flagged headings.
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
7-7: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
14-14: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
21-21: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
28-28: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
36-36: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
43-43: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
49-49: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🤖 Prompt for AI Agents
In apps/backend/prompts/github/spam_detector.md around lines 7 to 52, several
Markdown headings (lines 7, 14, 21, 28, 36, 43, 49) lack blank lines before
and/or after them; add a single blank line above and below each of these heading
lines so each heading is separated from surrounding content (improves
readability and satisfies the linter), and verify the rest of the file follows
the same spacing convention.
| if __name__ == "__main__": | ||
| print("Bot Detection Integration Examples\n") | ||
|
|
||
| print("\n1. Configuration Options") | ||
| print("=" * 50) | ||
| example_configuration_options() | ||
|
|
||
| print("\n2. With Bot Detection (requires GitHub setup)") | ||
| print("=" * 50) | ||
| print("Run: asyncio.run(example_with_bot_detection())") | ||
|
|
||
| print("\n3. Manual State Management") | ||
| print("=" * 50) | ||
| print("Run: asyncio.run(example_manual_state_management())") |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Main block doesn't execute async examples.
The __main__ block only runs the synchronous example_configuration_options() and prints instructions to manually run the async examples. Consider using asyncio.run() for a complete demo:
🔎 Proposed fix
if __name__ == "__main__":
+ import asyncio
+
print("Bot Detection Integration Examples\n")
print("\n1. Configuration Options")
print("=" * 50)
example_configuration_options()
print("\n2. With Bot Detection (requires GitHub setup)")
print("=" * 50)
- print("Run: asyncio.run(example_with_bot_detection())")
+ # Uncomment to run with valid GitHub credentials:
+ # asyncio.run(example_with_bot_detection())
+ print("Skipped: requires valid GitHub setup")
print("\n3. Manual State Management")
print("=" * 50)
- print("Run: asyncio.run(example_manual_state_management())")
+ # Uncomment to run with valid GitHub credentials:
+ # asyncio.run(example_manual_state_management())
+ print("Skipped: requires valid GitHub setup")📝 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.
| if __name__ == "__main__": | |
| print("Bot Detection Integration Examples\n") | |
| print("\n1. Configuration Options") | |
| print("=" * 50) | |
| example_configuration_options() | |
| print("\n2. With Bot Detection (requires GitHub setup)") | |
| print("=" * 50) | |
| print("Run: asyncio.run(example_with_bot_detection())") | |
| print("\n3. Manual State Management") | |
| print("=" * 50) | |
| print("Run: asyncio.run(example_manual_state_management())") | |
| if __name__ == "__main__": | |
| import asyncio | |
| print("Bot Detection Integration Examples\n") | |
| print("\n1. Configuration Options") | |
| print("=" * 50) | |
| example_configuration_options() | |
| print("\n2. With Bot Detection (requires GitHub setup)") | |
| print("=" * 50) | |
| # Uncomment to run with valid GitHub credentials: | |
| # asyncio.run(example_with_bot_detection()) | |
| print("Skipped: requires valid GitHub setup") | |
| print("\n3. Manual State Management") | |
| print("=" * 50) | |
| # Uncomment to run with valid GitHub credentials: | |
| # asyncio.run(example_manual_state_management()) | |
| print("Skipped: requires valid GitHub setup") |
🤖 Prompt for AI Agents
In apps/backend/runners/github/bot_detection_example.py around lines 141 to 154,
the __main__ block only calls the synchronous example_configuration_options()
and prints instructions for async examples; change it to actually execute the
async demos by calling asyncio.run(example_with_bot_detection()) and
asyncio.run(example_manual_state_management()) (add an import asyncio at the top
if not present) so the script runs the full demonstration automatically when
executed; keep the printed headers but replace the plain run instructions with
real asyncio.run calls and handle/propagate any exceptions as currently done by
the module.
| async def _openai_embedding(self, text: str) -> list[float]: | ||
| """Get embedding from OpenAI.""" | ||
| try: | ||
| import openai | ||
|
|
||
| client = openai.AsyncOpenAI(api_key=self.api_key) | ||
| response = await client.embeddings.create( | ||
| model=self.model, | ||
| input=text[:8000], # Limit input | ||
| ) | ||
| return response.data[0].embedding | ||
| except Exception as e: | ||
| logger.error(f"OpenAI embedding error: {e}") | ||
| return self._fallback_embedding(text) | ||
|
|
||
| async def _voyage_embedding(self, text: str) -> list[float]: | ||
| """Get embedding from Voyage AI.""" | ||
| try: | ||
| import httpx | ||
|
|
||
| async with httpx.AsyncClient() as client: | ||
| response = await client.post( | ||
| "https://api.voyageai.com/v1/embeddings", | ||
| headers={"Authorization": f"Bearer {self.api_key}"}, | ||
| json={ | ||
| "model": self.model, | ||
| "input": text[:8000], | ||
| }, | ||
| ) | ||
| data = response.json() | ||
| return data["data"][0]["embedding"] | ||
| except Exception as e: | ||
| logger.error(f"Voyage embedding error: {e}") | ||
| return self._fallback_embedding(text) | ||
|
|
||
| async def _local_embedding(self, text: str) -> list[float]: | ||
| """Get embedding from local model.""" | ||
| try: | ||
| from sentence_transformers import SentenceTransformer | ||
|
|
||
| model = SentenceTransformer(self.model) | ||
| embedding = model.encode(text[:8000]) | ||
| return embedding.tolist() | ||
| except Exception as e: | ||
| logger.error(f"Local embedding error: {e}") | ||
| return self._fallback_embedding(text) |
There was a problem hiding this comment.
Performance issue: embedding clients and models are created on every call.
Each embedding request creates a new client (OpenAI, httpx) or loads a new model (SentenceTransformer). This is inefficient and slow, especially for _local_embedding which loads a model from disk/downloads it each time.
🔎 Recommended fix: cache clients/models
class EmbeddingProvider:
def __init__(
self,
provider: str = "openai",
api_key: str | None = None,
model: str | None = None,
):
self.provider = provider
self.api_key = api_key
self.model = model or self._default_model()
+ self._openai_client: Any = None
+ self._local_model: Any = None
async def _openai_embedding(self, text: str) -> list[float]:
try:
import openai
- client = openai.AsyncOpenAI(api_key=self.api_key)
+ if self._openai_client is None:
+ self._openai_client = openai.AsyncOpenAI(api_key=self.api_key)
+ client = self._openai_client
# ...
async def _local_embedding(self, text: str) -> list[float]:
try:
from sentence_transformers import SentenceTransformer
- model = SentenceTransformer(self.model)
+ if self._local_model is None:
+ self._local_model = SentenceTransformer(self.model)
+ model = self._local_model
# ...Committable suggestion skipped: line range outside the PR's diff.
| async def _voyage_embedding(self, text: str) -> list[float]: | ||
| """Get embedding from Voyage AI.""" | ||
| try: | ||
| import httpx | ||
|
|
||
| async with httpx.AsyncClient() as client: | ||
| response = await client.post( | ||
| "https://api.voyageai.com/v1/embeddings", | ||
| headers={"Authorization": f"Bearer {self.api_key}"}, | ||
| json={ | ||
| "model": self.model, | ||
| "input": text[:8000], | ||
| }, | ||
| ) | ||
| data = response.json() | ||
| return data["data"][0]["embedding"] | ||
| except Exception as e: | ||
| logger.error(f"Voyage embedding error: {e}") | ||
| return self._fallback_embedding(text) |
There was a problem hiding this comment.
Missing response status validation for Voyage API call.
The response status code is not checked before parsing JSON. If the API returns an error (4xx/5xx), response.json() may fail or return an error structure, and accessing data["data"][0]["embedding"] will raise a KeyError.
🔎 Recommended fix
async with httpx.AsyncClient() as client:
response = await client.post(
"https://api.voyageai.com/v1/embeddings",
headers={"Authorization": f"Bearer {self.api_key}"},
json={
"model": self.model,
"input": text[:8000],
},
+ timeout=30.0,
)
+ response.raise_for_status()
data = response.json()
return data["data"][0]["embedding"]🤖 Prompt for AI Agents
In apps/backend/runners/github/duplicates.py around lines 256 to 274, the Voyage
API response is used without validating the HTTP status or JSON structure;
update the code to check response.status_code (or response.is_success) and if
it's not a 2xx, log the status code and response.text/body and return
self._fallback_embedding(text); if it is successful, parse the JSON safely
(catch JSON decode errors), validate that "data" and the first element and
"embedding" exist (or use dict.get checks) before returning the embedding, and
on any parsing/key error fall back to logging the detailed error and returning
self._fallback_embedding(text).
| def _load_cache(self, repo: str) -> dict[int, CachedEmbedding]: | ||
| """Load embedding cache for a repo.""" | ||
| cache_file = self._get_cache_file(repo) | ||
| if not cache_file.exists(): | ||
| return {} | ||
|
|
||
| with open(cache_file) as f: | ||
| data = json.load(f) | ||
|
|
||
| cache = {} | ||
| for item in data.get("embeddings", []): | ||
| embedding = CachedEmbedding.from_dict(item) | ||
| if not embedding.is_expired(): | ||
| cache[embedding.issue_number] = embedding | ||
|
|
||
| return cache | ||
|
|
||
| def _save_cache(self, repo: str, cache: dict[int, CachedEmbedding]) -> None: | ||
| """Save embedding cache for a repo.""" | ||
| cache_file = self._get_cache_file(repo) | ||
| data = { | ||
| "embeddings": [e.to_dict() for e in cache.values()], | ||
| "last_updated": datetime.now(timezone.utc).isoformat(), | ||
| } | ||
| with open(cache_file, "w") as f: | ||
| json.dump(data, f) | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider async file I/O for cache operations.
The cache loading and saving use synchronous file operations (open(), json.load(), json.dump()), which block the event loop. For large caches or slow storage, this could impact performance.
For high-throughput scenarios, consider using aiofiles for async file operations or running file I/O in an executor.
🤖 Prompt for AI Agents
In apps/backend/runners/github/duplicates.py around lines 357 to 383, the cache
load/save use blocking open()/json.load()/json.dump() which can block the event
loop; make these non-blocking by converting the methods to async and using async
file I/O or executors. Change _load_cache/_save_cache to async, use
aiofiles.open to read/write the file (await f.read()/f.write()) and
parse/serialize JSON with json.loads/json.dumps inside asyncio.to_thread if
parsing large data, or call json.loads/dumps on the small string directly;
ensure all callers await the new async methods and add error handling for
I/O/JSON errors.
| results = await asyncio.gather(*parallel_tasks, return_exceptions=True) | ||
|
|
||
| # Collect results from all parallel passes | ||
| for i, result in enumerate(results): | ||
| if isinstance(result, Exception): | ||
| print(f"[AI] Pass '{task_names[i]}' failed: {result}", flush=True) | ||
| elif isinstance(result, tuple): | ||
| pass_type, data = result | ||
| if pass_type in ("security", "quality", "deep"): | ||
| all_findings.extend(data) | ||
| elif pass_type == "structural": | ||
| structural_issues.extend(data) | ||
| elif pass_type == "ai_triage": | ||
| ai_triages.extend(data) | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
LGTM - good use of asyncio.gather with fault tolerance.
The use of return_exceptions=True and individual result checking provides graceful degradation when passes fail. Consider adding traceback logging for easier debugging of failures:
if isinstance(result, Exception):
import traceback
print(f"[AI] Pass '{task_names[i]}' failed: {result}\n{traceback.format_exception(type(result), result, result.__traceback__)}", flush=True)🤖 Prompt for AI Agents
In apps/backend/runners/github/services/pr_review_engine.py around lines 312 to
326, the exception branch only prints the exception message which loses the
stack trace; capture and include the full traceback for easier debugging by
importing the traceback module (either at top or locally) and replacing the
current print with one that appends traceback.format_exception(type(result),
result, result.__traceback__) (joined or formatted) so the log shows the
exception message plus the full stack trace and flushes output.
| except Exception as e: | ||
| print(f"Triage error for #{issue['number']}: {e}") | ||
| return TriageResult( | ||
| issue_number=issue["number"], | ||
| repo=self.config.repo, | ||
| category=TriageCategory.FEATURE, | ||
| confidence=0.0, | ||
| ) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Default triage result on error may mask real issues.
When an error occurs, the method returns a TriageResult with category=TriageCategory.FEATURE and confidence=0.0. This silent fallback could cause issues to be incorrectly categorized. Consider re-raising or returning a distinct error state.
🔎 Proposed fix: Add error indicator
except Exception as e:
- print(f"Triage error for #{issue['number']}: {e}")
+ print(f"Triage error for #{issue['number']}: {e}", flush=True)
return TriageResult(
issue_number=issue["number"],
repo=self.config.repo,
- category=TriageCategory.FEATURE,
+ category=TriageCategory.UNKNOWN, # Add UNKNOWN to TriageCategory enum
confidence=0.0,
+ error=str(e), # If TriageResult supports an error field
)Alternatively, consider re-raising the exception to let callers handle it:
except Exception as e:
print(f"Triage error for #{issue['number']}: {e}", flush=True)
raise # Let caller decide how to handleCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/backend/runners/github/services/triage_engine.py around lines 87 to 94,
the except block currently swallows exceptions and returns a default
TriageResult (FEATURE, confidence=0.0), which can mask real errors; change the
handler to either re-raise the caught exception after logging (e.g., print(...,
flush=True); raise) so callers can handle failures, or return an explicit
error-state TriageResult (use a distinct category such as TriageCategory.UNKNOWN
or add an error flag/message on the result) so consumers can detect and treat
triage failures differently.
| lines = [ | ||
| f"## Issue #{issue['number']}", | ||
| f"**Title:** {issue['title']}", | ||
| f"**Author:** {issue['author']['login']}", | ||
| f"**Created:** {issue['createdAt']}", | ||
| f"**Labels:** {', '.join(label['name'] for label in issue.get('labels', []))}", | ||
| "", | ||
| "### Body", | ||
| issue.get("body", "No description"), | ||
| "", | ||
| ] |
There was a problem hiding this comment.
Potential KeyError or TypeError on author access.
Line 113 accesses issue['author']['login'] directly. GitHub can return null for the author field (e.g., for deleted users), which would cause a TypeError.
🔎 Proposed fix: Safe access
lines = [
f"## Issue #{issue['number']}",
f"**Title:** {issue['title']}",
- f"**Author:** {issue['author']['login']}",
+ f"**Author:** {issue.get('author', {}).get('login', 'unknown')}",
f"**Created:** {issue['createdAt']}",
f"**Labels:** {', '.join(label['name'] for label in issue.get('labels', []))}",📝 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.
| lines = [ | |
| f"## Issue #{issue['number']}", | |
| f"**Title:** {issue['title']}", | |
| f"**Author:** {issue['author']['login']}", | |
| f"**Created:** {issue['createdAt']}", | |
| f"**Labels:** {', '.join(label['name'] for label in issue.get('labels', []))}", | |
| "", | |
| "### Body", | |
| issue.get("body", "No description"), | |
| "", | |
| ] | |
| lines = [ | |
| f"## Issue #{issue['number']}", | |
| f"**Title:** {issue['title']}", | |
| f"**Author:** {issue.get('author', {}).get('login', 'unknown')}", | |
| f"**Created:** {issue['createdAt']}", | |
| f"**Labels:** {', '.join(label['name'] for label in issue.get('labels', []))}", | |
| "", | |
| "### Body", | |
| issue.get("body", "No description"), | |
| "", | |
| ] |
🤖 Prompt for AI Agents
In apps/backend/runners/github/services/triage_engine.py around lines 110 to
120, the code directly indexes issue['author']['login'] which can raise a
TypeError/KeyError when author is None or missing; change to safely retrieve the
login (e.g., author = issue.get('author') and login = (author.get('login') if
author else "unknown" or "deleted user")) and use that fallback string in the
formatted lines so missing or null authors do not crash the formatter.
| def _calculate_directory_size(self, path: Path) -> int: | ||
| """ | ||
| Calculate total size of all files in a directory recursively. | ||
|
|
||
| Args: | ||
| path: Directory path to measure | ||
|
|
||
| Returns: | ||
| Total size in bytes | ||
| """ | ||
| if not path.exists(): | ||
| return 0 | ||
|
|
||
| total = 0 | ||
| for file_path in path.rglob("*"): | ||
| if file_path.is_file(): | ||
| try: | ||
| total += file_path.stat().st_size | ||
| except OSError: | ||
| # Skip files that can't be accessed | ||
| continue | ||
|
|
||
| return total |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Code duplication with purge_strategy.py.
The _calculate_directory_size method is nearly identical to the one in apps/backend/runners/github/purge_strategy.py (lines 270-287 per relevant code snippets). Consider extracting to a shared utility module.
🔎 Proposed fix: Extract to shared utility
Create a shared utility (e.g., apps/backend/runners/github/utils/filesystem.py):
from pathlib import Path
def calculate_directory_size(path: Path) -> int:
"""Calculate total size of all files in a directory recursively."""
if not path.exists():
return 0
total = 0
for file_path in path.rglob("*"):
if file_path.is_file():
try:
total += file_path.stat().st_size
except OSError:
continue
return totalThen import and use in both storage_metrics.py and purge_strategy.py.
🤖 Prompt for AI Agents
In apps/backend/runners/github/storage_metrics.py around lines 124-146 there is
a _calculate_directory_size implementation duplicated in
apps/backend/runners/github/purge_strategy.py (around lines 270-287); extract
this logic into a shared utility function (e.g.,
apps/backend/runners/github/utils/filesystem.py) named
calculate_directory_size(path: Path) that implements the same behavior (return 0
if not exists, iterate rglob, sum st_size, skip OSError), replace the local
methods in both storage_metrics.py and purge_strategy.py with imports from the
new utility, update references to call calculate_directory_size, and run
tests/linters to ensure imports and paths are correct.
| def _count_records(self, path: Path) -> int: | ||
| """ | ||
| Count JSON record files in a directory. | ||
|
|
||
| Args: | ||
| path: Directory path to count | ||
|
|
||
| Returns: | ||
| Number of .json files | ||
| """ | ||
| if not path.exists(): | ||
| return 0 | ||
|
|
||
| count = 0 | ||
| for file_path in path.rglob("*.json"): | ||
| count += 1 | ||
|
|
||
| return count |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Minor: Consider using sum() for counting.
The loop-based counting works correctly. A slightly more Pythonic alternative:
return sum(1 for _ in path.rglob("*.json"))This is a minor style preference and the current implementation is perfectly fine.
🤖 Prompt for AI Agents
In apps/backend/runners/github/storage_metrics.py around lines 148 to 165, the
current loop-based JSON file counter can be simplified: replace the manual loop
that increments `count` over `path.rglob("*.json")` with a single expression
that returns `sum(1 for _ in path.rglob("*.json"))`, preserving the existing `if
not path.exists(): return 0` guard.
| self.state.reviewed_commits[pr_key].append(commit_sha) | ||
|
|
||
| # Update last review time | ||
| self.state.last_review_times[pr_key] = datetime.now().isoformat() |
There was a problem hiding this comment.
Inconsistent datetime format - should use timezone-aware timestamp.
datetime.now().isoformat() produces a naive datetime string. For consistency and to avoid the comparison issues mentioned above, use datetime.now(timezone.utc).isoformat().
🤖 Prompt for AI Agents
In apps/backend/runners/github/bot_detection.py around line 350, the code sets a
naive timestamp with datetime.now().isoformat(); replace this with a
timezone-aware timestamp by calling datetime.now(timezone.utc).isoformat() and
ensure timezone is imported from datetime (add "from datetime import timezone"
or update existing import). This will produce a UTC-aware ISO timestamp for
consistent comparisons.
| class FileLockError(Exception): | ||
| """Raised when file locking operations fail.""" | ||
|
|
||
| pass |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Remove unnecessary pass statements after docstrings.
The pass statements are redundant when the exception class body only contains a docstring.
🔎 Proposed fix
class FileLockError(Exception):
"""Raised when file locking operations fail."""
-
- pass
class FileLockTimeout(FileLockError):
"""Raised when lock acquisition times out."""
-
- passAlso applies to: 41-41
🤖 Prompt for AI Agents
In apps/backend/runners/github/file_lock.py around lines 35 and 41, the
exception class bodies contain only a docstring followed by a redundant pass;
remove the unnecessary pass statements so the classes consist solely of their
docstrings (keep the docstrings intact and ensure proper indentation).
| """ | ||
| timeout = timeout or self.default_timeout | ||
| cmd = ["gh"] + args | ||
| start_time = asyncio.get_event_loop().time() |
There was a problem hiding this comment.
asyncio.get_event_loop() is deprecated in Python 3.12+.
Per coding guidelines, Python 3.12+ is required. Using asyncio.get_event_loop().time() is deprecated and may raise DeprecationWarning. Use asyncio.get_running_loop() instead.
🔎 Proposed fix
- start_time = asyncio.get_event_loop().time()
+ start_time = asyncio.get_running_loop().time()Apply to lines 123, 179, and 190. Alternatively, use time.monotonic() which doesn't require an event loop:
import time
start_time = time.monotonic()Also applies to: 179-179, 190-190
🤖 Prompt for AI Agents
In apps/backend/runners/github/gh_client.py around lines 123, 179 and 190,
replace uses of asyncio.get_event_loop().time() (deprecated in Python 3.12+)
with a non-deprecated alternative: either call asyncio.get_running_loop().time()
when running inside an active event loop, or switch to time.monotonic() by
importing time at the top of the module; update the three sites accordingly to
avoid DeprecationWarning and ensure consistent timing behavior.
| # Pre-flight rate limit check | ||
| if self.enable_rate_limiting: | ||
| available, msg = self._rate_limiter.check_github_available() | ||
| if not available: | ||
| # Try to acquire (will wait if needed) | ||
| logger.info(f"Rate limited, waiting for token: {msg}") | ||
| if not await self._rate_limiter.acquire_github(timeout=30.0): | ||
| raise RateLimitExceeded(f"GitHub API rate limit exceeded: {msg}") | ||
| else: | ||
| # Consume a token for this request | ||
| await self._rate_limiter.acquire_github(timeout=1.0) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Rate limit pre-check acquires token even when available.
When available is True (line 127), the code still calls acquire_github (line 135). This is correct for consuming a token, but the 1.0 second timeout is inconsistent with the 30.0 second wait when rate-limited.
Consider using a non-blocking acquire when tokens are known to be available:
else:
# Consume a token for this request
- await self._rate_limiter.acquire_github(timeout=1.0)
+ await self._rate_limiter.acquire_github(timeout=0.1) # Should be instant📝 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.
| # Pre-flight rate limit check | |
| if self.enable_rate_limiting: | |
| available, msg = self._rate_limiter.check_github_available() | |
| if not available: | |
| # Try to acquire (will wait if needed) | |
| logger.info(f"Rate limited, waiting for token: {msg}") | |
| if not await self._rate_limiter.acquire_github(timeout=30.0): | |
| raise RateLimitExceeded(f"GitHub API rate limit exceeded: {msg}") | |
| else: | |
| # Consume a token for this request | |
| await self._rate_limiter.acquire_github(timeout=1.0) | |
| # Pre-flight rate limit check | |
| if self.enable_rate_limiting: | |
| available, msg = self._rate_limiter.check_github_available() | |
| if not available: | |
| # Try to acquire (will wait if needed) | |
| logger.info(f"Rate limited, waiting for token: {msg}") | |
| if not await self._rate_limiter.acquire_github(timeout=30.0): | |
| raise RateLimitExceeded(f"GitHub API rate limit exceeded: {msg}") | |
| else: | |
| # Consume a token for this request | |
| await self._rate_limiter.acquire_github(timeout=0.1) # Should be instant |
| async def api_get(self, endpoint: str, params: dict[str, str] | None = None) -> Any: | ||
| """ | ||
| Make a GET request to GitHub API. | ||
|
|
||
| Args: | ||
| endpoint: API endpoint (e.g., "/repos/owner/repo/contents/path") | ||
| params: Query parameters | ||
|
|
||
| Returns: | ||
| JSON response | ||
| """ | ||
| args = ["api", endpoint] | ||
|
|
||
| if params: | ||
| for key, value in params.items(): | ||
| args.extend(["-f", f"{key}={value}"]) | ||
|
|
||
| result = await self.run(args) |
There was a problem hiding this comment.
Missing api_post method required by GitProvider protocol.
The GitProvider protocol (protocol.py lines 476-491) requires an api_post method, but GHClient only implements api_get. The GitHub provider (github_provider.py lines 413-419) delegates to this method.
🔎 Suggested implementation
async def api_post(
self, endpoint: str, data: dict[str, Any] | None = None
) -> Any:
"""
Make a POST request to GitHub API.
Args:
endpoint: API endpoint
data: JSON body data
Returns:
JSON response
"""
args = ["api", endpoint, "--method", "POST"]
if data:
import json as json_module
args.extend(["--input", "-"])
# Note: gh api accepts JSON via stdin with --input -
# This requires a different approach using stdin
result = await self.run(args)
return json.loads(result.stdout) if result.stdout else {}Note: Implementing POST with body via gh api requires passing JSON via stdin, which needs additional subprocess handling.
🤖 Prompt for AI Agents
In apps/backend/runners/github/gh_client.py around lines 512 to 529, GHClient is
missing the api_post method required by the GitProvider protocol; implement an
async api_post(self, endpoint: str, data: dict[str, Any] | None = None) -> Any
that builds args = ["api", endpoint, "--method", "POST"], and when data is
provided serialize it to JSON and pass it to the gh subprocess via stdin (use
--input -), call await self.run with the prepared args and input bytes, parse
result.stdout with json.loads if present, return an empty dict when no stdout,
and raise or propagate errors consistently with api_get behavior; ensure the
signature and return type match the protocol and import json as needed.
| class ResponseParser: | ||
| """Parses AI responses into structured data.""" |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider adding module-level logger.
The module uses bare print() statements but other files in this PR use logging. Adding a logger would enable consistent log management.
import logging
logger = logging.getLogger(__name__)🤖 Prompt for AI Agents
In apps/backend/runners/github/services/response_parsers.py around lines 40 to
41, the module uses bare print() calls instead of a module-level logger; add a
logger at module scope (import logging and create logger =
logging.getLogger(__name__)) and replace print() usages with logger methods
(e.g., logger.debug/info/warning/error as appropriate) so the module aligns with
the project's logging practice and consistent log handling.
| json_match = re.search( | ||
| r"```json\s*(\{.*?\})\s*```", response_text, re.DOTALL | ||
| ) |
There was a problem hiding this comment.
Non-greedy regex may fail on nested JSON structures.
The pattern r"```json\s*(\{.*?\})\s*```" with re.DOTALL uses a non-greedy match (.*?) which will stop at the first closing brace }. For nested JSON objects, this will truncate the content. Consider using a more robust JSON extraction approach.
🔎 Suggested fix using balanced matching or alternative approach
@staticmethod
def _extract_json_block(response_text: str, expect_array: bool = False) -> str | None:
"""Extract JSON from code block, handling nested structures."""
pattern = r"```json\s*([\s\S]*?)\s*```"
match = re.search(pattern, response_text)
if match:
content = match.group(1).strip()
# Validate it's parseable before returning
try:
json.loads(content)
return content
except json.JSONDecodeError:
pass
return NoneThe key issue is \{.*?\} should be [\s\S]*? to capture the full block content between the fences, then validate with json.loads.
Also applies to: 74-76, 121-123, 151-153, 190-192
🤖 Prompt for AI Agents
In apps/backend/runners/github/services/response_parsers.py around lines 54-56
(and similarly at 74-76, 121-123, 151-153, 190-192), the regex
r"```json\s*(\{.*?\})\s*```" uses a non-greedy brace-limited capture which will
truncate nested JSON; replace these matches with a robust extractor that
captures the full fenced block (e.g. use pattern "```json\s*([\s\S]*?)\s*```")
and then validate/parse the captured content with json.loads (and handle
expect_array by validating against list if needed) so only valid JSON is
returned and nested structures are preserved.
| findings.append( | ||
| PRReviewFinding( | ||
| id=f.get("id", f"finding-{i + 1}"), | ||
| severity=ReviewSeverity( | ||
| f.get("severity", "medium").lower() | ||
| ), | ||
| category=ReviewCategory( | ||
| f.get("category", "quality").lower() | ||
| ), | ||
| title=f.get("title", "Finding"), | ||
| description=f.get("description", ""), | ||
| file=f.get("file", "unknown"), | ||
| line=f.get("line", 1), | ||
| end_line=f.get("end_line"), | ||
| suggested_fix=f.get("suggested_fix"), | ||
| fixable=f.get("fixable", False), | ||
| ) | ||
| ) |
There was a problem hiding this comment.
PRReviewFinding construction may raise ValueError on invalid enum values.
If the AI returns an unexpected severity or category value (e.g., "info" or "other"), ReviewSeverity(...) or ReviewCategory(...) will raise ValueError, which is caught by the outer exception handler but results in losing all subsequent findings.
🔎 Suggested defensive handling
try:
+ severity = ReviewSeverity(f.get("severity", "medium").lower())
+ except ValueError:
+ severity = ReviewSeverity.MEDIUM
+ try:
+ category = ReviewCategory(f.get("category", "quality").lower())
+ except ValueError:
+ category = ReviewCategory.QUALITY
+
findings.append(
PRReviewFinding(
id=f.get("id", f"finding-{i + 1}"),
- severity=ReviewSeverity(
- f.get("severity", "medium").lower()
- ),
- category=ReviewCategory(
- f.get("category", "quality").lower()
- ),
+ severity=severity,
+ category=category,🤖 Prompt for AI Agents
In apps/backend/runners/github/services/response_parsers.py around lines 92 to
109, constructing ReviewSeverity(...) and ReviewCategory(...) from untrusted AI
strings can raise ValueError and abort processing of the entire list; instead,
defensively map or validate those fields per-finding and fall back to safe
defaults (e.g., medium/quality) on invalid values: use a small helper or mapping
to convert the incoming string to the enum with a try/except or lookup.get(...,
DEFAULT) for severity and category, wrap the PRReviewFinding creation for each
finding in its own try/except to log the bad value and continue, and ensure
invalid/missing fields are replaced with the chosen defaults so one malformed
finding doesn’t stop all subsequent findings.
| except (json.JSONDecodeError, KeyError, ValueError) as e: | ||
| print(f"Failed to parse findings: {e}") |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Use logging instead of bare print statements for consistency.
Error messages use print() without flush=True (inconsistent with other files) and without log levels. Consider using logging.warning() or logging.error() for proper observability.
As per coding guidelines, focus on Python best practices for error handling.
Also applies to: 140-141, 173-174, 211-212
🤖 Prompt for AI Agents
In apps/backend/runners/github/services/response_parsers.py around lines
110-111, 140-141, 173-174, and 211-212, replace bare print() error messages with
the logging module at an appropriate level (e.g., logging.warning or
logging.error). Import logging at the top if not present, and change each
print(f"Failed to parse findings: {e}") (and similar prints) to
logging.error(...) or logging.warning(...) including the exception message and
any contextual info; avoid flush=True and ensure messages are clear and
consistent with existing logger usage in the project.
| triages.append( | ||
| AICommentTriage( | ||
| comment_id=triage.get("comment_id", 0), | ||
| tool_name=triage.get("tool_name", "Unknown"), | ||
| original_comment=triage.get("original_summary", ""), | ||
| verdict=verdict, | ||
| reasoning=triage.get("reasoning", ""), | ||
| response_comment=triage.get("response_comment"), | ||
| ) |
There was a problem hiding this comment.
Field name mismatch: original_summary vs original_comment.
Line 167 reads triage.get("original_summary", "") but the AICommentTriage dataclass (per the relevant snippet at models.py lines 247-276) expects original_comment. This will silently result in empty strings for that field.
🔎 Proposed fix
triages.append(
AICommentTriage(
comment_id=triage.get("comment_id", 0),
tool_name=triage.get("tool_name", "Unknown"),
- original_comment=triage.get("original_summary", ""),
+ original_comment=triage.get("original_comment", triage.get("original_summary", "")),
verdict=verdict,
reasoning=triage.get("reasoning", ""),
response_comment=triage.get("response_comment"),
)
)🤖 Prompt for AI Agents
In apps/backend/runners/github/services/response_parsers.py around lines 163 to
171, the code uses triage.get("original_summary", "") to populate
AICommentTriage.original_comment, causing the field to be empty; change the key
to triage.get("original_comment", "") so the dataclass receives the correct
value (keep the same default ""), and run tests to ensure no other places rely
on "original_summary".
| if log_file.exists(): | ||
| size_mb = log_file.stat().st_size / (1024 * 1024) | ||
| if size_mb >= self.max_file_size_mb: | ||
| # Rotate: add timestamp suffix | ||
| timestamp = datetime.now(timezone.utc).strftime("%H%M%S") | ||
| rotated = log_file.with_suffix(f".{timestamp}.jsonl") | ||
| log_file.rename(rotated) | ||
| logger.info(f"Rotated audit log to {rotated}") | ||
|
|
||
| self._current_log_file = log_file |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Log rotation renames file without locking.
If multiple processes are writing to the same log file, the rename operation could interfere with concurrent writes.
Consider using a file lock during rotation or atomic file operations. For a single-process tool this may be acceptable.
🤖 Prompt for AI Agents
In apps/backend/runners/github/audit.py around lines 250 to 259, the log
rotation renames the file without any inter-process locking which can clash with
concurrent writers; acquire an exclusive file lock on the log file (e.g. via
fcntl.lockf on Unix or a cross-platform locker like portalocker) before checking
size and performing the rename, perform the size-check and rename while holding
the lock, reopen or recreate the target log file after the atomic rename and
update self._current_log_file, and handle lock acquisition failures with a short
retry/backoff and a safe fallback to skip rotation if lock cannot be obtained.
| import asyncio | ||
|
|
||
| if asyncio.iscoroutinefunction(func): | ||
| return async_wrapper | ||
| return sync_wrapper |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
asyncio import inside function body.
Moving the import to the top of the file would be cleaner and avoid repeated import overhead if the decorator is applied multiple times.
🤖 Prompt for AI Agents
In apps/backend/runners/github/audit.py around lines 732 to 736, the asyncio
import is performed inside the function body; move "import asyncio" to the
top-level imports of the file, remove the in-function import, and update any
references to asyncio accordingly so the decorator uses the module imported once
(ensure no naming conflicts with existing imports).
| for batch_file in batches_dir.glob("batch_*.json"): | ||
| try: | ||
| with open(batch_file) as f: | ||
| data = json.load(f) | ||
| batches.append(IssueBatch.from_dict(data)) | ||
| except Exception as e: | ||
| logger.error(f"Error loading batch {batch_file}: {e}") | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Broad exception handler logs but continues, potentially returning partial/corrupt data.
If a batch file is malformed, it's skipped with a log message, but callers have no indication that the result is incomplete.
Consider returning a tuple (batches, errors) or raising after logging to make partial failures visible.
🤖 Prompt for AI Agents
In apps/backend/runners/github/batch_issues.py around lines 686 to 693, the
current loop swallows all exceptions when loading batch files and simply logs
them, which can produce silently incomplete results; change the implementation
to either (A) collect load errors and return them with the batches as a tuple
(batches, errors) by adding an errors list, appending error info (file path and
exception) on failure, and updating the function signature and all callers to
handle the tuple, or (B) re-raise after logging by storing a flag or the first
exception during iteration and, after the loop, raise a new exception (or the
stored one) to make partial failures visible; ensure the chosen approach is
applied consistently and update the docs/tests/call sites accordingly.
| settings_file = self.project_dir / ".batch_validator_settings.json" | ||
| with open(settings_file, "w") as f: | ||
| json.dump(settings, f) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Settings file write is not atomic and lacks error handling.
Writing the settings file uses synchronous I/O without atomicity guarantees or proper error handling. If the write fails partially, it could leave a corrupted file.
🔎 Proposed fix
- settings_file = self.project_dir / ".batch_validator_settings.json"
- with open(settings_file, "w") as f:
- json.dump(settings, f)
+ settings_file = self.project_dir / ".batch_validator_settings.json"
+ # Write atomically using temp file
+ import tempfile
+ fd, tmp_path = tempfile.mkstemp(
+ dir=self.project_dir, prefix=".batch_validator_settings.", suffix=".tmp"
+ )
+ try:
+ with os.fdopen(fd, "w") as f:
+ json.dump(settings, f)
+ os.replace(tmp_path, settings_file)
+ except Exception:
+ try:
+ os.unlink(tmp_path)
+ except OSError:
+ pass
+ raise📝 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.
| settings_file = self.project_dir / ".batch_validator_settings.json" | |
| with open(settings_file, "w") as f: | |
| json.dump(settings, f) | |
| settings_file = self.project_dir / ".batch_validator_settings.json" | |
| # Write atomically using temp file | |
| import tempfile | |
| fd, tmp_path = tempfile.mkstemp( | |
| dir=self.project_dir, prefix=".batch_validator_settings.", suffix=".tmp" | |
| ) | |
| try: | |
| with os.fdopen(fd, "w") as f: | |
| json.dump(settings, f) | |
| os.replace(tmp_path, settings_file) | |
| except Exception: | |
| try: | |
| os.unlink(tmp_path) | |
| except OSError: | |
| pass | |
| raise |
🤖 Prompt for AI Agents
In apps/backend/runners/github/batch_validator.py around lines 204 to 206 the
settings file is written directly which is not atomic and has no error handling;
instead, write to a temporary file in the same directory (e.g.
settings_file.with_suffix(".tmp")), use json.dump to the temp file, flush and
os.fsync the file descriptor to ensure data hits disk, close it, then atomically
replace the target file using os.replace; wrap the sequence in try/except to
catch and log or re-raise I/O errors (and ensure the directory exists and
temporary file is cleaned up on failure) so partial writes and silent failures
are avoided.
| try: | ||
| return json.loads(text) | ||
| except json.JSONDecodeError: | ||
| # Try to find JSON object in text | ||
| start = text.find("{") | ||
| end = text.rfind("}") + 1 | ||
| if start >= 0 and end > start: | ||
| return json.loads(text[start:end]) | ||
| raise |
There was a problem hiding this comment.
JSON parsing fallback may extract invalid JSON from surrounding text.
The fallback logic using find("{") and rfind("}") can match mismatched braces if the response contains multiple JSON-like structures or nested objects within text. Consider using a more robust JSON extraction approach.
🔎 Proposed fix
try:
return json.loads(text)
except json.JSONDecodeError:
# Try to find JSON object in text
start = text.find("{")
end = text.rfind("}") + 1
- if start >= 0 and end > start:
- return json.loads(text[start:end])
- raise
+ if start >= 0 and end > start:
+ try:
+ return json.loads(text[start:end])
+ except json.JSONDecodeError:
+ pass
+ # Return safe defaults if parsing fails completely
+ logger.warning("Failed to parse JSON response, using defaults")
+ return {
+ "is_valid": True,
+ "confidence": 0.5,
+ "reasoning": "Failed to parse AI response",
+ "suggested_splits": None,
+ "common_theme": "",
+ }Committable suggestion skipped: line range outside the PR's diff.
| # Cache for user roles (avoid repeated API calls) | ||
| self._role_cache: dict[str, GitHubRole] = {} |
There was a problem hiding this comment.
Role cache has no expiration - stale permissions possible.
The _role_cache dictionary caches user roles indefinitely. If a user's role changes (e.g., promoted to collaborator), the cache will serve stale data until the process restarts.
🔎 Proposed fix - add TTL-based cache
+from datetime import datetime, timedelta
+
+@dataclass
+class CachedRole:
+ role: GitHubRole
+ cached_at: datetime
+
class GitHubPermissionChecker:
...
+ CACHE_TTL_SECONDS = 300 # 5 minutes
+
def __init__(self, ...):
...
- self._role_cache: dict[str, GitHubRole] = {}
+ self._role_cache: dict[str, CachedRole] = {}
async def get_user_role(self, username: str) -> GitHubRole:
# Check cache first
if username in self._role_cache:
- return self._role_cache[username]
+ cached = self._role_cache[username]
+ if (datetime.now() - cached.cached_at).total_seconds() < self.CACHE_TTL_SECONDS:
+ return cached.role
+ del self._role_cache[username]Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/backend/runners/github/permissions.py around lines 96-97, the
_role_cache currently stores GitHubRole entries indefinitely which can return
stale permissions; change it to a TTL-based cache by storing per-key metadata
(role and insertion timestamp) or replacing the dict with a TTL cache (e.g.,
cachetools.TTLCache) and set a reasonable expiration (e.g., few minutes); update
all read/write logic to check timestamps or rely on TTLCache eviction so entries
older than the TTL are refreshed from the API, and ensure thread-safety if
accessed concurrently.
| except Exception: | ||
| logger.debug(f"User {username} is not a collaborator") |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Broad exception handling masks specific errors.
Using bare except Exception catches all errors including unexpected ones. Consider catching specific exceptions (e.g., API errors, network errors) to provide better error messages and avoid masking bugs.
Also applies to: 266-267, 269-270, 282-283
🤖 Prompt for AI Agents
In apps/backend/runners/github/permissions.py around lines 250-251 (and
similarly at 266-267, 269-270, 282-283), the code uses broad `except Exception`
handlers which mask specific API/network errors; replace these with targeted
exception handling by catching the specific exceptions raised by the GitHub
client and network layer (e.g., HTTPError/requests.exceptions.RequestException
or the library's ApiError/BadCredentialsError/NotFound exceptions), log the
exception type and message for diagnostics, and only fall back to the “not a
collaborator” behavior on the expected 404/permission-related error; for other
exceptions re-raise or handle them appropriately (with retries or clearer error
logs) so unexpected errors are not silently swallowed.
| try: | ||
| # This is a heuristic - check if user appears in contributors | ||
| contributors = await self.gh_client.api_get( | ||
| f"/repos/{self.repo}/contributors" | ||
| ) | ||
| if any(c.get("login") == username for c in contributors): | ||
| role = "CONTRIBUTOR" | ||
| self._role_cache[username] = role | ||
| return role |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
GitHub REST API /repos/{repo}/contributors endpoint pagination
💡 Result:
Short summary:
- Endpoint: GET /repos/{owner}/{repo}/contributors. It supports pagination via the query parameters per_page (max 100, default 30) and page. [1]
- Use the response Link header to traverse pages (contains rel="next", "prev", "first", "last"). If Link is absent, all results fit on one page. [2]
- Notes: results are cached and sorted by commit count; only the first 500 author emails are linked to GitHub users (others appear anonymous); you can include anonymous contributors with anon=1/true. [1]
Sources: [1] GitHub REST API — List repository contributors. [2] Using pagination in the REST API.
The /repos/{repo}/contributors endpoint uses pagination with a default limit of 30 results per page. For repositories with many contributors, the current implementation will only check the first page, potentially missing users who appear beyond that. Consider using the per_page parameter (max 100) or handling the pagination via the response Link header to increase coverage.
Additionally, note that only the first 500 author emails are linked to GitHub users; beyond that, contributors appear as anonymous accounts.
🤖 Prompt for AI Agents
In apps/backend/runners/github/permissions.py around lines 273 to 281, the call
to /repos/{repo}/contributors only fetches the default first page (30) so users
beyond that page can be missed; update the logic to handle pagination by either
adding per_page=100 and iterating subsequent pages or by following the response
Link header until no next page, checking each page for the username and
short-circuiting when found, then set self._role_cache[username] and return;
also handle anonymous/unnamed contributors (skip None/log) and ensure errors
from paging are handled gracefully.
| try: | ||
| if comment: | ||
| await self.add_comment(pr_number, comment) | ||
| await self._gh_client._run_gh_command(["pr", "close", str(pr_number)]) | ||
| return True | ||
| except Exception: | ||
| return False |
There was a problem hiding this comment.
Same silent exception handling issue in close_pr.
Apply consistent logging for debugging visibility.
🤖 Prompt for AI Agents
In apps/backend/runners/github/providers/github_provider.py around lines 200 to
206, the except block in close_pr silently swallows exceptions; update it to
catch the exception as a variable (e.g. "except Exception as e") and log the
error with the module/class logger (use self._logger.exception(...) or
logging.getLogger(__name__).exception(...)) including context like pr_number and
comment, then return False; this retains the False return while providing
consistent, detailed logging for debugging.
| try: | ||
| if comment: | ||
| await self.add_comment(number, comment) | ||
| await self._gh_client._run_gh_command(["issue", "close", str(number)]) | ||
| return True | ||
| except Exception: | ||
| return False |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Inconsistent error handling: close_issue swallows exceptions but create_issue propagates them.
This inconsistency makes error handling unpredictable for callers.
Consider adopting a consistent strategy: either all operations return success/failure booleans with logging, or all propagate exceptions with meaningful error types.
🤖 Prompt for AI Agents
In apps/backend/runners/github/providers/github_provider.py around lines 311 to
317, close_issue currently swallows all exceptions and returns False, which is
inconsistent with create_issue that lets exceptions propagate; remove the broad
try/except so errors bubble up like create_issue (or alternatively replace it
with targeted exception handling that re-raises after logging), ensure any
awaited calls remain awaited, and update any callers/tests if needed to expect
exceptions instead of boolean failure.
| @classmethod | ||
| def get_instance( | ||
| cls, | ||
| log_dir: Path | None = None, | ||
| **kwargs, | ||
| ) -> AuditLogger: | ||
| """Get or create singleton instance.""" | ||
| if cls._instance is None: | ||
| cls._instance = cls(log_dir=log_dir, **kwargs) | ||
| return cls._instance |
There was a problem hiding this comment.
Singleton pattern with class variable has thread-safety issues.
get_instance checks and sets _instance without locking, which could cause race conditions in multi-threaded environments where multiple instances get created.
🔎 Proposed fix
+import threading
+
class AuditLogger:
+ _lock = threading.Lock()
_instance: AuditLogger | None = None
@classmethod
def get_instance(
cls,
log_dir: Path | None = None,
**kwargs,
) -> AuditLogger:
"""Get or create singleton instance."""
- if cls._instance is None:
- cls._instance = cls(log_dir=log_dir, **kwargs)
+ if cls._instance is None:
+ with cls._lock:
+ # Double-check locking
+ if cls._instance is None:
+ cls._instance = cls(log_dir=log_dir, **kwargs)
return cls._instanceCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/backend/runners/github/audit.py around lines 222 to 231, the singleton
get_instance method accesses and assigns the class variable _instance without
synchronization, which can produce race conditions in multi-threaded contexts;
add a class-level threading.Lock (e.g., _lock = threading.Lock()) and wrap the
instance-creation section with that lock (use a with cls._lock: block and
perform a second check of cls._instance inside it to avoid duplicate creation),
and ensure threading is imported and the lock is used whenever _instance is set.
| try: | ||
| log_file = self._get_log_file_path() | ||
| with open(log_file, "a") as f: | ||
| f.write(entry.to_json() + "\n") | ||
| except Exception as e: | ||
| logger.error(f"Failed to write audit log: {e}") |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Audit log writes don't flush or sync.
Critical audit entries could be lost if the process crashes before the OS flushes buffers to disk.
🔎 Proposed fix for critical audit entries
def _write_entry(self, entry: AuditEntry) -> None:
"""Write an entry to the log file."""
if not self.enabled:
return
self._rotate_if_needed()
try:
log_file = self._get_log_file_path()
with open(log_file, "a") as f:
f.write(entry.to_json() + "\n")
+ f.flush()
+ # For critical entries, could add: os.fsync(f.fileno())
except Exception as e:
logger.error(f"Failed to write audit log: {e}")🤖 Prompt for AI Agents
In apps/backend/runners/github/audit.py around lines 370 to 375, the audit log
write currently just writes to the file and relies on OS buffering which can
lose critical entries on a crash; after calling f.write(entry.to_json() + "\n")
call f.flush() and then os.fsync(f.fileno()) to force the data to disk, and
ensure os is imported at the top of the file; keep the existing try/except but
perform the flush/fsync inside the try so failures are logged by the existing
logger.error.
| for log_file in sorted(self.log_dir.glob("audit_*.jsonl"), reverse=True): | ||
| try: | ||
| with open(log_file) as f: | ||
| for line in f: | ||
| if not line.strip(): | ||
| continue | ||
|
|
||
| try: | ||
| data = json.loads(line) | ||
| except json.JSONDecodeError: | ||
| continue | ||
|
|
||
| # Apply filters | ||
| if ( | ||
| correlation_id | ||
| and data.get("correlation_id") != correlation_id | ||
| ): | ||
| continue | ||
| if action and data.get("action") != action.value: | ||
| continue | ||
| if repo and data.get("repo") != repo: | ||
| continue | ||
| if pr_number and data.get("pr_number") != pr_number: | ||
| continue | ||
| if issue_number and data.get("issue_number") != issue_number: | ||
| continue | ||
| if since: | ||
| entry_time = datetime.fromisoformat(data["timestamp"]) | ||
| if entry_time < since: | ||
| continue | ||
|
|
||
| # Reconstruct entry | ||
| entry = AuditEntry( | ||
| timestamp=datetime.fromisoformat(data["timestamp"]), | ||
| correlation_id=data["correlation_id"], | ||
| action=AuditAction(data["action"]), | ||
| actor_type=ActorType(data["actor_type"]), | ||
| actor_id=data.get("actor_id"), | ||
| repo=data.get("repo"), | ||
| pr_number=data.get("pr_number"), | ||
| issue_number=data.get("issue_number"), | ||
| result=data["result"], | ||
| duration_ms=data.get("duration_ms"), | ||
| error=data.get("error"), | ||
| details=data.get("details", {}), | ||
| token_usage=data.get("token_usage"), | ||
| ) | ||
| results.append(entry) | ||
|
|
||
| if len(results) >= limit: | ||
| return results | ||
|
|
||
| except Exception as e: | ||
| logger.error(f"Error reading audit log {log_file}: {e}") | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
query_logs reads all files on every query.
For large log directories with many files, this could be slow. Consider adding date-based filtering at the file level before opening.
for log_file in sorted(self.log_dir.glob("audit_*.jsonl"), reverse=True):
+ # Extract date from filename and skip files outside date range
+ if since:
+ file_date_str = log_file.stem.split("_")[1] # audit_YYYY-MM-DD
+ try:
+ file_date = datetime.strptime(file_date_str, "%Y-%m-%d").replace(tzinfo=timezone.utc)
+ if file_date < since.replace(hour=0, minute=0, second=0, microsecond=0):
+ continue
+ except ValueError:
+ pass # Fall through to read file🤖 Prompt for AI Agents
In apps/backend/runners/github/audit.py around lines 586 to 640, query_logs
currently opens every audit_*.jsonl file which is inefficient for large log
dirs; update the loop to skip files that cannot contain entries after the
optional since cutoff by checking file-level date information before opening
(e.g., parse a date from the filename if present or use file.stat().st_mtime /
os.path.getmtime), compare that to the since datetime (convert mtime to datetime
with timezone awareness), and only open files whose modification time or parsed
filename date is >= since; keep the existing in-file filtering, preserve sort
order and limit behavior, and ensure you handle cases where since is None by
falling back to processing all files and still catch and log exceptions as
before.
| def decorator(func): | ||
| async def async_wrapper(*args, **func_kwargs): | ||
| audit = get_audit_logger() | ||
| with audit.operation( | ||
| action_start=action_start, | ||
| action_complete=action_complete, | ||
| action_failed=action_failed, | ||
| **kwargs, | ||
| ) as ctx: | ||
| return await func(*args, audit_context=ctx, **func_kwargs) | ||
|
|
||
| def sync_wrapper(*args, **func_kwargs): | ||
| audit = get_audit_logger() | ||
| with audit.operation( | ||
| action_start=action_start, | ||
| action_complete=action_complete, | ||
| action_failed=action_failed, | ||
| **kwargs, | ||
| ) as ctx: | ||
| return func(*args, audit_context=ctx, **func_kwargs) | ||
|
|
||
| import asyncio | ||
|
|
||
| if asyncio.iscoroutinefunction(func): | ||
| return async_wrapper | ||
| return sync_wrapper |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Decorator doesn't preserve function signature or docstring.
The audit_operation decorator replaces the original function without @functools.wraps, losing metadata.
🔎 Proposed fix
+import functools
+
def audit_operation(
action_start: AuditAction,
action_complete: AuditAction,
action_failed: AuditAction,
**kwargs,
):
"""Decorator for auditing function calls."""
def decorator(func):
+ @functools.wraps(func)
async def async_wrapper(*args, **func_kwargs):
audit = get_audit_logger()
with audit.operation(
action_start=action_start,
action_complete=action_complete,
action_failed=action_failed,
**kwargs,
) as ctx:
return await func(*args, audit_context=ctx, **func_kwargs)
+ @functools.wraps(func)
def sync_wrapper(*args, **func_kwargs):📝 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.
| def decorator(func): | |
| async def async_wrapper(*args, **func_kwargs): | |
| audit = get_audit_logger() | |
| with audit.operation( | |
| action_start=action_start, | |
| action_complete=action_complete, | |
| action_failed=action_failed, | |
| **kwargs, | |
| ) as ctx: | |
| return await func(*args, audit_context=ctx, **func_kwargs) | |
| def sync_wrapper(*args, **func_kwargs): | |
| audit = get_audit_logger() | |
| with audit.operation( | |
| action_start=action_start, | |
| action_complete=action_complete, | |
| action_failed=action_failed, | |
| **kwargs, | |
| ) as ctx: | |
| return func(*args, audit_context=ctx, **func_kwargs) | |
| import asyncio | |
| if asyncio.iscoroutinefunction(func): | |
| return async_wrapper | |
| return sync_wrapper | |
| def decorator(func): | |
| @functools.wraps(func) | |
| async def async_wrapper(*args, **func_kwargs): | |
| audit = get_audit_logger() | |
| with audit.operation( | |
| action_start=action_start, | |
| action_complete=action_complete, | |
| action_failed=action_failed, | |
| **kwargs, | |
| ) as ctx: | |
| return await func(*args, audit_context=ctx, **func_kwargs) | |
| @functools.wraps(func) | |
| def sync_wrapper(*args, **func_kwargs): | |
| audit = get_audit_logger() | |
| with audit.operation( | |
| action_start=action_start, | |
| action_complete=action_complete, | |
| action_failed=action_failed, | |
| **kwargs, | |
| ) as ctx: | |
| return func(*args, audit_context=ctx, **func_kwargs) | |
| import asyncio | |
| if asyncio.iscoroutinefunction(func): | |
| return async_wrapper | |
| return sync_wrapper |
🤖 Prompt for AI Agents
In apps/backend/runners/github/audit.py around lines 711 to 736, the
audit_operation decorator defines async_wrapper and sync_wrapper but does not
preserve the original function's name, docstring, or metadata; wrap both
wrappers with functools.wraps(func) (and import functools if not already
imported) so the decorator preserves the original function signature/metadata,
i.e. apply @functools.wraps(func) above async_wrapper and sync_wrapper (or call
functools.wraps(func)(wrapper) when returning) and ensure the functools import
is present.
| def save(self, github_dir: Path) -> None: | ||
| """Save batch to disk.""" | ||
| batches_dir = github_dir / "batches" | ||
| batches_dir.mkdir(parents=True, exist_ok=True) | ||
|
|
||
| batch_file = batches_dir / f"batch_{self.batch_id}.json" | ||
| with open(batch_file, "w") as f: | ||
| json.dump(self.to_dict(), f, indent=2) | ||
|
|
||
| self.updated_at = datetime.now(timezone.utc).isoformat() |
There was a problem hiding this comment.
updated_at is set after writing to disk, not before.
The file is written with the old updated_at timestamp, then the field is updated. This means the persisted data doesn't reflect the actual save time.
🔎 Proposed fix
def save(self, github_dir: Path) -> None:
"""Save batch to disk."""
+ self.updated_at = datetime.now(timezone.utc).isoformat()
+
batches_dir = github_dir / "batches"
batches_dir.mkdir(parents=True, exist_ok=True)
batch_file = batches_dir / f"batch_{self.batch_id}.json"
with open(batch_file, "w") as f:
json.dump(self.to_dict(), f, indent=2)
-
- self.updated_at = datetime.now(timezone.utc).isoformat()🤖 Prompt for AI Agents
In apps/backend/runners/github/batch_issues.py around lines 140 to 149, the code
updates self.updated_at only after writing the batch JSON to disk so the
persisted file contains the old timestamp; move the line that sets
self.updated_at = datetime.now(timezone.utc).isoformat() to immediately before
serializing/writing the file so the updated_at field is set to the current UTC
time before calling json.dump, ensuring the file reflects the real save time.
| if review_id not in self._outcomes: | ||
| return None | ||
|
|
||
| review_outcome = self._outcomes[review_id] | ||
| review_outcome.actual_outcome = outcome | ||
| review_outcome.time_to_outcome = time_to_outcome | ||
| review_outcome.author_response = author_response | ||
| review_outcome.outcome_recorded_at = datetime.now(timezone.utc) | ||
|
|
||
| self._save_outcomes(repo) | ||
|
|
||
| return review_outcome |
There was a problem hiding this comment.
record_outcome uses repo parameter but doesn't validate it matches the stored outcome.
The repo parameter is used for saving, but the method doesn't verify that it matches review_outcome.repo. This could cause data to be saved to the wrong file.
🔎 Proposed fix
def record_outcome(
self,
repo: str,
review_id: str,
outcome: OutcomeType,
time_to_outcome: timedelta | None = None,
author_response: AuthorResponse = AuthorResponse.UNKNOWN,
) -> ReviewOutcome | None:
if review_id not in self._outcomes:
return None
review_outcome = self._outcomes[review_id]
+ if review_outcome.repo != repo:
+ logger.warning(f"Repo mismatch: expected {review_outcome.repo}, got {repo}")
+ return None
+
review_outcome.actual_outcome = outcome📝 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.
| if review_id not in self._outcomes: | |
| return None | |
| review_outcome = self._outcomes[review_id] | |
| review_outcome.actual_outcome = outcome | |
| review_outcome.time_to_outcome = time_to_outcome | |
| review_outcome.author_response = author_response | |
| review_outcome.outcome_recorded_at = datetime.now(timezone.utc) | |
| self._save_outcomes(repo) | |
| return review_outcome | |
| if review_id not in self._outcomes: | |
| return None | |
| review_outcome = self._outcomes[review_id] | |
| if review_outcome.repo != repo: | |
| logger.warning(f"Repo mismatch: expected {review_outcome.repo}, got {repo}") | |
| return None | |
| review_outcome.actual_outcome = outcome | |
| review_outcome.time_to_outcome = time_to_outcome | |
| review_outcome.author_response = author_response | |
| review_outcome.outcome_recorded_at = datetime.now(timezone.utc) | |
| self._save_outcomes(repo) | |
| return review_outcome |
🤖 Prompt for AI Agents
In apps/backend/runners/github/learning.py around lines 393 to 404, the method
updates a stored review outcome but uses the incoming repo parameter for
persisting without verifying it matches review_outcome.repo; add a validation
step that compares repo to review_outcome.repo and if they differ raise an
exception (e.g., ValueError) or log and return None, otherwise proceed to call
self._save_outcomes with the correct repo (preferably use review_outcome.repo
for saving to avoid accidental writes to the wrong file).
| try: | ||
| with open(self.state_file) as f: | ||
| data = json.load(f) | ||
| self._state = OnboardingState.from_dict(data) | ||
| except (json.JSONDecodeError, KeyError): | ||
| self._state = OnboardingState(repo=self.repo) | ||
| else: | ||
| self._state = OnboardingState(repo=self.repo) | ||
|
|
||
| return self._state |
There was a problem hiding this comment.
Exception handling for JSON decode is incomplete.
The get_state method catches json.JSONDecodeError and KeyError, but OnboardingState.from_dict could raise ValueError (from enum conversion) or TypeError (from datetime parsing).
🔎 Proposed fix
if self.state_file.exists():
try:
with open(self.state_file) as f:
data = json.load(f)
self._state = OnboardingState.from_dict(data)
- except (json.JSONDecodeError, KeyError):
+ except (json.JSONDecodeError, KeyError, ValueError, TypeError) as e:
+ logger.warning(f"Failed to load onboarding state, starting fresh: {e}")
self._state = OnboardingState(repo=self.repo)Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/backend/runners/github/onboarding.py around lines 303 to 312, the
get_state exception handling only catches json.JSONDecodeError and KeyError but
OnboardingState.from_dict can also raise ValueError (e.g., enum conversion) or
TypeError (e.g., datetime parsing); update the except clause to also catch
ValueError and TypeError and handle them the same way (reset self._state =
OnboardingState(repo=self.repo)), optionally logging the original exception for
diagnostics before resetting.
| try: | ||
| await self._gh_client._run_gh_command(cmd) | ||
| return True | ||
| except Exception: | ||
| return False |
There was a problem hiding this comment.
Swallowing exceptions silently loses debugging context.
The merge_pr method catches all exceptions and returns False, making it impossible to distinguish between different failure modes (permission denied, merge conflicts, network errors, etc.).
🔎 Proposed fix
+import logging
+
+logger = logging.getLogger(__name__)
+
async def merge_pr(
self,
pr_number: int,
merge_method: str = "merge",
commit_title: str | None = None,
) -> bool:
"""Merge a pull request."""
cmd = ["pr", "merge", str(pr_number)]
if merge_method == "squash":
cmd.append("--squash")
elif merge_method == "rebase":
cmd.append("--rebase")
else:
cmd.append("--merge")
if commit_title:
cmd.extend(["--subject", commit_title])
cmd.append("--yes")
try:
await self._gh_client._run_gh_command(cmd)
return True
- except Exception:
+ except Exception as e:
+ logger.warning(f"Failed to merge PR #{pr_number}: {e}")
return False🤖 Prompt for AI Agents
In apps/backend/runners/github/providers/github_provider.py around lines 188 to
192, the merge_pr method currently swallows all exceptions and returns False,
losing debugging context; change the except to capture the exception (except
Exception as e), log the full error and stack trace via the class logger or
process logger (including context like PR id and command), and then return False
(or re-raise only for fatal/unexpected cases) so failures are observable and
actionable; ensure the logger call includes the exception object/traceback
rather than just a string.
| result = await self._gh_client._run_gh_command(cmd) | ||
|
|
||
| # Parse the issue URL to get the number | ||
| # gh issue create outputs the URL | ||
| url = result.strip() | ||
| number = int(url.split("/")[-1]) | ||
|
|
||
| return await self.fetch_issue(number) |
There was a problem hiding this comment.
Parsing issue URL to extract number is fragile.
If gh issue create output format changes or returns unexpected output (error message, empty string), the URL parsing will fail with an unclear exception.
🔎 Proposed fix
result = await self._gh_client._run_gh_command(cmd)
# Parse the issue URL to get the number
# gh issue create outputs the URL
url = result.strip()
- number = int(url.split("/")[-1])
+ try:
+ number = int(url.split("/")[-1])
+ except (ValueError, IndexError) as e:
+ raise ValueError(f"Failed to parse issue number from output: {url!r}") from e
return await self.fetch_issue(number)🤖 Prompt for AI Agents
In apps/backend/runners/github/providers/github_provider.py around lines 296 to
303, the code naively splits the raw output of `gh issue create` to extract the
issue number which is fragile and will break on empty/unexpected output; update
the implementation to either (preferred) change the gh command to request
structured output (e.g. use `--json number` or `--json url,number`) and parse
JSON to obtain the number reliably, or (if keeping string output) validate that
`result` is non-empty, trim it, run a robust regex (e.g. match a trailing
`/\d+`), convert to int inside a try/except, and on failure log the full
`result` and raise a clear, descriptive exception so callers get actionable info
instead of an unclear traceback.
| def _parse_datetime(self, dt_str: str | None) -> datetime: | ||
| """Parse ISO datetime string.""" | ||
| if not dt_str: | ||
| return datetime.now(timezone.utc) | ||
| try: | ||
| return datetime.fromisoformat(dt_str.replace("Z", "+00:00")) | ||
| except (ValueError, AttributeError): | ||
| return datetime.now(timezone.utc) |
There was a problem hiding this comment.
Returning current time as fallback for invalid datetime is misleading.
When parsing fails, returning datetime.now(timezone.utc) makes it appear the entity was just created/updated, which could lead to incorrect time-based filtering or sorting.
🔎 Proposed fix
def _parse_datetime(self, dt_str: str | None) -> datetime:
"""Parse ISO datetime string."""
if not dt_str:
- return datetime.now(timezone.utc)
+ # Return epoch as a sentinel for "unknown" rather than misleading "now"
+ return datetime(1970, 1, 1, tzinfo=timezone.utc)
try:
return datetime.fromisoformat(dt_str.replace("Z", "+00:00"))
except (ValueError, AttributeError):
- return datetime.now(timezone.utc)
+ return datetime(1970, 1, 1, tzinfo=timezone.utc)Alternatively, consider making the return type datetime | None and handling missing timestamps explicitly upstream.
📝 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.
| def _parse_datetime(self, dt_str: str | None) -> datetime: | |
| """Parse ISO datetime string.""" | |
| if not dt_str: | |
| return datetime.now(timezone.utc) | |
| try: | |
| return datetime.fromisoformat(dt_str.replace("Z", "+00:00")) | |
| except (ValueError, AttributeError): | |
| return datetime.now(timezone.utc) | |
| def _parse_datetime(self, dt_str: str | None) -> datetime: | |
| """Parse ISO datetime string.""" | |
| if not dt_str: | |
| # Return epoch as a sentinel for "unknown" rather than misleading "now" | |
| return datetime(1970, 1, 1, tzinfo=timezone.utc) | |
| try: | |
| return datetime.fromisoformat(dt_str.replace("Z", "+00:00")) | |
| except (ValueError, AttributeError): | |
| return datetime(1970, 1, 1, tzinfo=timezone.utc) |
🤖 Prompt for AI Agents
In apps/backend/runners/github/providers/github_provider.py around lines 511 to
518 the function currently returns datetime.now(timezone.utc) on missing/invalid
input which falsely indicates a recent timestamp; change the signature to return
datetime | None, return None when dt_str is falsy or parsing fails (do not
swallow errors into "now"), and update all call sites to handle None explicitly
(e.g., skip/ignore, use a fallback only where semantically correct, or log the
missing timestamp) so time-based filtering/sorting remains accurate.
)" This reverts commit 348de6d.
…#250) * feat(github): add GitHub automation system for issues and PRs Implements comprehensive GitHub automation with three major components: 1. Issue Auto-Fix: Automatically creates specs from labeled issues - AutoFixButton component with progress tracking - useAutoFix hook for config and queue management - Backend handlers for spec creation from issues 2. GitHub PRs Tool: AI-powered PR review sidebar - New sidebar tab (Cmd+Shift+P) alongside GitHub Issues - PRList/PRDetail components for viewing PRs - Review system with findings by severity - Post review comments to GitHub 3. Issue Triage: Duplicate/spam/feature-creep detection - Triage handlers with label application - Configurable detection thresholds Also adds: - Debug logging (DEBUG=true) for all GitHub handlers - Backend runners/github module with orchestrator - AI prompts for PR review, triage, duplicate/spam detection - dev:debug npm script for development with logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github-runner): resolve import errors for direct script execution Changes runner.py and orchestrator.py to handle both: - Package import: `from runners.github import ...` - Direct script: `python runners/github/runner.py` Uses try/except pattern for relative vs direct imports. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): correct argparse argument order for runner.py Move --project global argument before subcommand so argparse can correctly parse it. Fixes "unrecognized arguments: --project" error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * logs when debug mode is on * refactor(github): extract service layer and fix linting errors Major refactoring to improve maintainability and code quality: Backend (Python): - Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules: - prompt_manager.py: Prompt template management - response_parsers.py: AI response parsing - pr_review_engine.py: PR review orchestration - triage_engine.py: Issue triage logic - autofix_processor.py: Auto-fix workflow - batch_processor.py: Batch issue handling - Fixed 18 ruff linting errors (F401, C405, C414, E741): - Removed unused imports (BatchValidationResult, AuditAction, locked_json_write) - Optimized collection literals (set([n]) → {n}) - Removed unnecessary list() calls - Renamed ambiguous variable 'l' to 'label' throughout Frontend (TypeScript): - Refactored IPC handlers (19% overall reduction) with shared utilities: - autofix-handlers.ts: 1,042 → 818 lines - pr-handlers.ts: 648 → 543 lines - triage-handlers.ts: 437 lines (no duplication) - Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner - Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status - Split ReviewFindings.tsx into focused components All imports verified, type checks passing, linting clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
…ndyMik90#250)" (AndyMik90#251) This reverts commit d3f6d10.
…#250) * feat(github): add GitHub automation system for issues and PRs Implements comprehensive GitHub automation with three major components: 1. Issue Auto-Fix: Automatically creates specs from labeled issues - AutoFixButton component with progress tracking - useAutoFix hook for config and queue management - Backend handlers for spec creation from issues 2. GitHub PRs Tool: AI-powered PR review sidebar - New sidebar tab (Cmd+Shift+P) alongside GitHub Issues - PRList/PRDetail components for viewing PRs - Review system with findings by severity - Post review comments to GitHub 3. Issue Triage: Duplicate/spam/feature-creep detection - Triage handlers with label application - Configurable detection thresholds Also adds: - Debug logging (DEBUG=true) for all GitHub handlers - Backend runners/github module with orchestrator - AI prompts for PR review, triage, duplicate/spam detection - dev:debug npm script for development with logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github-runner): resolve import errors for direct script execution Changes runner.py and orchestrator.py to handle both: - Package import: `from runners.github import ...` - Direct script: `python runners/github/runner.py` Uses try/except pattern for relative vs direct imports. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): correct argparse argument order for runner.py Move --project global argument before subcommand so argparse can correctly parse it. Fixes "unrecognized arguments: --project" error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * logs when debug mode is on * refactor(github): extract service layer and fix linting errors Major refactoring to improve maintainability and code quality: Backend (Python): - Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules: - prompt_manager.py: Prompt template management - response_parsers.py: AI response parsing - pr_review_engine.py: PR review orchestration - triage_engine.py: Issue triage logic - autofix_processor.py: Auto-fix workflow - batch_processor.py: Batch issue handling - Fixed 18 ruff linting errors (F401, C405, C414, E741): - Removed unused imports (BatchValidationResult, AuditAction, locked_json_write) - Optimized collection literals (set([n]) → {n}) - Removed unnecessary list() calls - Renamed ambiguous variable 'l' to 'label' throughout Frontend (TypeScript): - Refactored IPC handlers (19% overall reduction) with shared utilities: - autofix-handlers.ts: 1,042 → 818 lines - pr-handlers.ts: 648 → 543 lines - triage-handlers.ts: 437 lines (no duplication) - Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner - Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status - Split ReviewFindings.tsx into focused components All imports verified, type checks passing, linting clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
…ndyMik90#250)" (AndyMik90#251) This reverts commit 348de6d.
* docs: Add Git Flow branching strategy to CONTRIBUTING.md
- Add comprehensive branching strategy documentation
- Explain main, develop, feature, fix, release, and hotfix branches
- Clarify that all PRs should target develop (not main)
- Add release process documentation for maintainers
- Update PR process to branch from develop
- Expand table of contents with new sections
* Feature/apps restructure v2.7.2 (#138)
* refactor: restructure project to Apps/frontend and Apps/backend
- Move auto-claude-ui to Apps/frontend with feature-based architecture
- Move auto-claude to Apps/backend
- Switch from pnpm to npm for frontend
- Update Node.js requirement to v24.12.0 LTS
- Add pre-commit hooks for lint, typecheck, and security audit
- Add commit-msg hook for conventional commits
- Fix CommonJS compatibility issues (postcss.config, postinstall scripts)
- Update README with comprehensive setup and contribution guidelines
- Configure ESLint to ignore .cjs files
- 0 npm vulnerabilities
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(refactor): clean code and move to npm
* feat(refactor): clean code and move to npm
* chore: update to v2.7.0, remove Docker deps (LadybugDB is embedded)
* feat: v2.8.0 - update workflows and configs for Apps/ structure, npm
* fix: resolve Python lint errors (F401, I001)
* fix: update test paths for Apps/backend structure
* fix: add missing facade files and update paths for Apps/backend structure
- Fix ruff lint error I001 in auto_claude_tools.py
- Create missing facade files to match upstream (agent, ci_discovery, critique, etc.)
- Update test paths from auto-claude/ to Apps/backend/
- Update .pre-commit-config.yaml paths for Apps/ structure
- Add pytest to pre-commit hooks (skip slow/integration/Windows-incompatible tests)
- Fix Unicode encoding in test_agent_architecture.py for Windows
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat: improve readme
* fix: new path
* fix: correct release workflow and docs for Apps/ restructure
- Fix ARM64 macOS build: pnpm → npm, auto-claude-ui → Apps/frontend
- Fix artifact upload paths in release.yml
- Update Node.js version to 24 for consistency
- Update CLI-USAGE.md with Apps/backend paths
- Update RELEASE.md with Apps/frontend/package.json paths
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: rename Apps/ to apps/ and fix backend path resolution
- Rename Apps/ folder to apps/ for consistency with JS/Node conventions
- Update all path references across CI/CD workflows, docs, and config files
- Fix frontend Python path resolver to look for 'backend' instead of 'auto-claude'
- Update path-resolver.ts to correctly find apps/backend in development mode
This completes the Apps restructure from PR #122 and prepares for v2.8.0 release.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(electron): correct preload script path from .js to .mjs
electron-vite builds the preload script as ESM (index.mjs) but the main
process was looking for CommonJS (index.js). This caused the preload to
fail silently, making the app fall back to browser mock mode with fake
data and non-functional IPC handlers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* - Introduced `dev:debug` script to enable debugging during development.
- Added `dev:mcp` script for running the frontend in MCP mode.
These enhancements streamline the development process for frontend developers.
* refactor(memory): make Graphiti memory mandatory and remove Docker dependency
Memory is now a core component of Auto Claude rather than optional:
- Python 3.12+ is required for the backend (not just memory layer)
- Graphiti is enabled by default in .env.example
- Removed all FalkorDB/Docker references (migrated to embedded LadybugDB)
- Deleted guides/DOCKER-SETUP.md and docker-handlers.ts
- Updated onboarding UI to remove "optional" language
- Updated all documentation to reflect LadybugDB architecture
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add cross-platform Windows support for npm scripts
- Add scripts/install-backend.js for cross-platform Python venv setup
- Auto-detects Python 3.12 (py -3.12 on Windows, python3.12 on Unix)
- Handles platform-specific venv paths
- Add scripts/test-backend.js for cross-platform pytest execution
- Update package.json to use Node.js scripts instead of shell commands
- Update CONTRIBUTING.md with correct paths and instructions:
- apps/backend/ and apps/frontend/ paths
- Python 3.12 requirement (memory system now required)
- Platform-specific install commands (winget, brew, apt)
- npm instead of pnpm
- Quick Start section with npm run install:all
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* remove doc
* fix(frontend): correct Ollama detector script path after apps restructure
The Ollama status check was failing because memory-handlers.ts
was looking for ollama_model_detector.py at auto-claude/ but the
script is now at apps/backend/ after the directory restructure.
This caused "Ollama not running" to display even when Ollama was
actually running and accessible.
* chore: bump version to 2.7.2
Downgrade version from 2.8.0 to 2.7.2 as the Apps/ restructure
is better suited as a patch release rather than a minor release.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: update package-lock.json for Windows compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs(contributing): add hotfix workflow and update paths for apps/ structure
Add Git Flow hotfix workflow documentation with step-by-step guide
and ASCII diagram showing the branching strategy.
Update all paths from auto-claude/auto-claude-ui to apps/backend/apps/frontend
and migrate package manager references from pnpm to npm to match the
new project structure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): remove duplicate ARM64 build from Intel runner
The Intel runner was building both x64 and arm64 architectures,
while a separate ARM64 runner also builds arm64 natively. This
caused duplicate ARM64 builds, wasting CI resources.
Now each runner builds only its native architecture:
- Intel runner: x64 only
- ARM64 runner: arm64 only
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Alex Madera <e.a_madera@hotmail.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Feat: Ollama download progress tracking with new apps structure (#141)
* feat(ollama): add real-time download progress tracking for model downloads
Implement comprehensive download progress tracking with:
- NDJSON parsing for streaming progress data from Ollama API
- Real-time speed calculation (MB/s, KB/s, B/s) with useRef for delta tracking
- Time remaining estimation based on download speed
- Animated progress bars in OllamaModelSelector component
- IPC event streaming from main process to renderer
- Proper listener management with cleanup functions
Changes:
- memory-handlers.ts: Parse NDJSON from Ollama stderr, emit progress events
- OllamaModelSelector.tsx: Display progress bars with speed and time remaining
- project-api.ts: Implement onDownloadProgress listener with cleanup
- ipc.ts types: Define onDownloadProgress listener interface
- infrastructure-mock.ts: Add mock implementation for browser testing
This allows users to see real-time feedback when downloading Ollama models,
including percentage complete, current download speed, and estimated time remaining.
* test: add focused test coverage for Ollama download progress feature
Add unit tests for the critical paths of the real-time download progress tracking:
- Progress calculation tests (52 tests): Speed/time/percentage calculations with comprehensive edge case coverage (zero speeds, NaN, Infinity, large numbers)
- NDJSON parser tests (33 tests): Streaming JSON parsing from Ollama, buffer management for incomplete lines, error handling
All 562 unit tests passing with clean dependencies. Tests focus on critical mathematical logic and data processing - the most important paths that need verification.
Test coverage:
✅ Speed calculation and formatting (B/s, KB/s, MB/s)
✅ Time remaining calculations (seconds, minutes, hours)
✅ Percentage clamping (0-100%)
✅ NDJSON streaming with partial line buffering
✅ Invalid JSON handling
✅ Real Ollama API responses
✅ Multi-chunk streaming scenarios
* docs: add comprehensive JSDoc docstrings for Ollama download progress feature
- Enhanced OllamaModelSelector component with detailed JSDoc
* Documented component props, behavior, and usage examples
* Added docstrings to internal functions (checkInstalledModels, handleDownload, handleSelect)
* Explained progress tracking algorithm and useRef usage
- Improved memory-handlers.ts documentation
* Added docstring to main registerMemoryHandlers function
* Documented all Ollama-related IPC handlers (check-status, list-embedding-models, pull-model)
* Added JSDoc to executeOllamaDetector helper function
* Documented interface types (OllamaStatus, OllamaModel, OllamaEmbeddingModel, OllamaPullResult)
* Explained NDJSON parsing and progress event structure
- Enhanced test file documentation
* Added docstrings to NDJSON parser test utilities with algorithm explanation
* Documented all calculation functions (speed, time, percentage)
* Added detailed comments on formatting and bounds-checking logic
- Improved overall code maintainability
* Docstring coverage now meets 80%+ threshold for code review
* Clear explanation of progress tracking implementation details
* Better context for future maintainers working with download streaming
* feat: add batch task creation and management CLI commands
- Handle batch task creation from JSON files
- Show status of all specs in project
- Cleanup tool for completed specs
- Full integration with new apps/backend structure
- Compatible with implementation_plan.json workflow
* test: add batch task test file and testing checklist
- batch_test.json: Sample tasks for testing batch creation
- TESTING_CHECKLIST.md: Comprehensive testing guide for Ollama and batch tasks
- Includes UI testing steps, CLI testing steps, and edge cases
- Ready for manual and automated testing
* chore: update package-lock.json to match v2.7.2
* test: update checklist with verification results and architecture validation
* docs: add comprehensive implementation summary for Ollama + Batch features
* docs: add comprehensive Phase 2 testing guide with checklists and procedures
* docs: add NEXT_STEPS guide for Phase 2 testing
* fix: resolve merge conflict in project-api.ts from Ollama feature cherry-pick
* fix: remove duplicate Ollama check status handler registration
* test: update checklist with Phase 2 bug findings and fixes
---------
Co-authored-by: ray <ray@rays-MacBook-Pro.local>
* fix: resolve Python environment race condition (#142)
Implemented promise queue pattern in PythonEnvManager to handle
concurrent initialization requests. Previously, multiple simultaneous
requests (e.g., startup + merge) would fail with "Already
initializing" error.
Also fixed parsePythonCommand() to handle file paths with spaces by
checking file existence before splitting on whitespace.
Changes:
- Added initializationPromise field to queue concurrent requests
- Split initialize() into public and private _doInitialize()
- Enhanced parsePythonCommand() with existsSync() check
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* fix: remove legacy path from auto-claude source detection (#148)
Removes the legacy 'auto-claude' path from the possiblePaths array
in agent-process.ts. This path was from before the monorepo
restructure (v2.7.2) and is no longer needed.
The legacy path was causing spec_runner.py to be looked up at the
wrong location:
- OLD (wrong): /path/to/auto-claude/auto-claude/runners/spec_runner.py
- NEW (correct): /path/to/apps/backend/runners/spec_runner.py
This aligns with the new monorepo structure where all backend code
lives in apps/backend/.
Fixes #147
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* Fix/linear 400 error
* fix: Linear API authentication and GraphQL types
- Remove Bearer prefix from Authorization header (Linear API keys are sent directly)
- Change GraphQL variable types from String! to ID! for teamId and issue IDs
- Improve error handling to show detailed Linear API error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: Radix Select empty value error in Linear import modal
Use '__all__' sentinel value instead of empty string for "All projects"
option, as Radix Select does not allow empty string values.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add CodeRabbit configuration file
Introduce a new .coderabbit.yaml file to configure CodeRabbit settings, including review profiles, automatic review options, path filters, and specific instructions for different file types. This enhances the code review process by providing tailored guidelines for Python, TypeScript, and test files.
* fix: correct GraphQL types for Linear team queries
Linear API uses different types for different queries:
- team(id:) expects String!
- issues(filter: { team: { id: { eq: } } }) expects ID!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: refresh task list after Linear import
Call loadTasks() after successful Linear import to update the kanban
board without requiring a page reload.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* cleanup
* cleanup
* fix: address CodeRabbit review comments for Linear integration
- Fix unsafe JSON parsing: check response.ok before parsing JSON to handle
non-JSON error responses (e.g., 503 from proxy) gracefully
- Use ID! type instead of String! for teamId in LINEAR_GET_PROJECTS query
for GraphQL type consistency
- Remove debug console.log (ESLint config only allows warn/error)
- Refresh task list on partial import success (imported > 0) instead of
requiring full success
- Fix pre-existing TypeScript and lint issues blocking commit
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* version sync logic
* lints for develop branch
* chore: update CI workflow to include develop branch
- Modified the CI configuration to trigger on pushes and pull requests to both main and develop branches, enhancing the workflow for development and integration processes.
* fix: update project directory auto-detection for apps/backend structure
The project directory auto-detection was checking for the old `auto-claude/`
directory name but needed to check for `apps/backend/`. When running from
`apps/backend/`, the directory name is `backend` not `auto-claude`, so the
check would fail and `project_dir` would incorrectly remain as `apps/backend/`
instead of resolving to the project root (2 levels up).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use GraphQL variables instead of string interpolation in LINEAR_GET_ISSUES
Replace direct string interpolation of teamId and linearProjectId with
proper GraphQL variables. This prevents potential query syntax errors if
IDs contain special characters like double quotes, and aligns with the
variable-based approach used elsewhere in the file.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ui): correct logging level and await loadTasks on import complete
- Change console.warn to console.log for import success messages
(warn is incorrect severity for normal completion)
- Make onImportComplete callback async and await loadTasks()
to prevent potential unhandled promise rejections
Applies CodeRabbit review feedback across 3 LinearTaskImportModal usages.
* fix(hooks): use POSIX-compliant find instead of bash glob
The pre-commit hook uses #!/bin/sh but had bash-specific ** glob
pattern for staging ruff-formatted files. The ** pattern only works
in bash with globstar enabled - in POSIX sh it expands literally
and won't match subdirectories, causing formatted files in nested
directories to not be staged.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(task): stop running process when task status changes away from in_progress
When a user drags a running task back to Planning (or any other column),
the process was not being stopped, leaving a "ghost" process that
prevented deletion with "Cannot delete a running task" error.
Now the task process is automatically killed when status changes away
from in_progress, ensuring the process state stays in sync with the UI.
* feat: Add UI scale feature with 75-200% range (#125)
* feat: add UI scale feature
* refactor: extract UI scale bounds to shared constants
* fix: duplicated import
* fix: hide status badge when execution phase badge is showing (#154)
* fix: analyzer Python compatibility and settings integration
Fixes project index analyzer failing with TypeError on Python type hints.
Changes:
- Added 'from __future__ import annotations' to all analysis modules
- Fixed project discovery to support new analyzer JSON format
- Read Python path directly from settings.json instead of pythonEnvManager
- Added stderr/stdout logging for analyzer debugging
Resolves 'Discovered 0 files' and 'TypeError: unsupported operand type' issues.
* auto-claude: subtask-1-1 - Hide status badge when execution phase badge is showing
When a task has an active execution (planning, coding, etc.), the
execution phase badge already displays the correct state with a spinner.
The status badge was also rendering, causing duplicate/confusing badges
(e.g., both "Planning" and "Pending" showing at the same time).
This fix wraps the status badge in a conditional that only renders when
there's no active execution, eliminating the redundant badge display.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ipc): remove unused pythonEnvManager parameter and fix ES6 import
Address CodeRabbit review feedback:
- Remove unused pythonEnvManager parameter from registerProjectContextHandlers
and registerContextHandlers (the code reads Python path directly from
settings.json instead)
- Replace require('electron').app with proper ES6 import for consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(lint): fix import sorting in analysis module
Run ruff --fix to resolve I001 lint errors after merging develop.
All 23 files in apps/backend/analysis/ now have properly sorted imports.
---------
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix/PRs from old main setup to apps structure (#185)
* fix(core): add task persistence, terminal handling, and HTTP 300 fixes
Consolidated bug fixes from PRs #168, #170, #171:
- Task persistence (#168): Scan worktrees for tasks on app restart
to prevent loss of in-progress work and wasted API credits. Tasks
in .worktrees/*/specs are now loaded and deduplicated with main.
- Terminal buttons (#170): Fix "Open Terminal" buttons silently
failing on macOS by properly awaiting createTerminal() Promise.
Added useTerminalHandler hook with loading states and error display.
- HTTP 300 errors (#171): Handle branch/tag name collisions that
cause update failures. Added validation script to prevent conflicts
before releases and user-friendly error messages with manual
download links.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(platform): add path resolution, spaces handling, and XDG support
This commit consolidates multiple bug fixes from community PRs:
- PR #187: Path resolution fix - Update path detection to find apps/backend
instead of legacy auto-claude directory after v2.7.2 restructure
- PR #182/#155: Python path spaces fix - Improve parsePythonCommand() to
handle quoted paths and paths containing spaces without splitting
- PR #161: Ollama detection fix - Add new apps structure paths for
ollama_model_detector.py script discovery
- PR #160: AppImage support - Add XDG Base Directory compliant paths for
Linux sandboxed environments (AppImage, Flatpak, Snap). New files:
- config-paths.ts: XDG path utilities
- fs-utils.ts: Filesystem utilities with fallback support
- PR #159: gh CLI PATH fix - Add getAugmentedEnv() utility to include
common binary locations (Homebrew, snap, local) in PATH for child
processes. Fixes gh CLI not found when app launched from Finder/Dock.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit/Cursor review comments on PR #185
Fixes from code review:
- http-client.ts: Use GITHUB_CONFIG instead of hardcoded owner in HTTP 300 error message
- validate-release.js: Fix substring matching bug in branch detection that could cause false positives (e.g., v2.7 matching v2.7.2)
- bump-version.js: Remove unnecessary try-catch wrapper (exec() already exits on failure)
- execution-handlers.ts: Capture original subtask status before mutation for accurate logging
- fs-utils.ts: Add error handling to safeWriteFile with proper logging
Dismissed as trivial/not applicable:
- config-paths.ts: Exhaustive switch check (over-engineering)
- env-utils.ts: PATH priority documentation (existing comments sufficient)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address additional CodeRabbit review comments (round 2)
Fixes from second round of code review:
- fs-utils.ts: Wrap test file cleanup in try-catch for Windows file locking
- fs-utils.ts: Add error handling to safeReadFile for consistency with safeWriteFile
- http-client.ts: Use GITHUB_CONFIG in fetchJson (missed in first round)
- validate-release.js: Exclude symbolic refs (origin/HEAD -> origin/main) from branch check
- python-detector.ts: Return cleanPath instead of pythonPath for empty input edge case
Dismissed as trivial/not applicable:
- execution-handlers.ts: Redundant checkSubtasksCompletion call (micro-optimization)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat/beta-release (#190)
* chore: update README version to 2.7.1
Updated the version badge and download links in the README to reflect the new release version 2.7.1, ensuring users have the correct information for downloading the latest builds.
* feat(releases): add beta release system with user opt-in
Implements a complete beta release workflow that allows users to opt-in
to receiving pre-release versions. This enables testing new features
before they're included in stable releases.
Changes:
- Add beta-release.yml workflow for creating beta releases from develop
- Add betaUpdates setting with UI toggle in Settings > Updates
- Add update channel support to electron-updater (beta vs latest)
- Extract shared settings-utils.ts to reduce code duplication
- Add prepare-release.yml workflow for automated release preparation
- Document beta release process in CONTRIBUTING.md and RELEASE.md
Users can enable beta updates in Settings > Updates, and maintainers
can trigger beta releases via the GitHub Actions workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* workflow update
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Feat/beta release (#193)
* chore: update README version to 2.7.1
Updated the version badge and download links in the README to reflect the new release version 2.7.1, ensuring users have the correct information for downloading the latest builds.
* feat(releases): add beta release system with user opt-in
Implements a complete beta release workflow that allows users to opt-in
to receiving pre-release versions. This enables testing new features
before they're included in stable releases.
Changes:
- Add beta-release.yml workflow for creating beta releases from develop
- Add betaUpdates setting with UI toggle in Settings > Updates
- Add update channel support to electron-updater (beta vs latest)
- Extract shared settings-utils.ts to reduce code duplication
- Add prepare-release.yml workflow for automated release preparation
- Document beta release process in CONTRIBUTING.md and RELEASE.md
Users can enable beta updates in Settings > Updates, and maintainers
can trigger beta releases via the GitHub Actions workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* workflow update
* ci(github): update Discord link and redirect feature requests to discussions
Update Discord invite link to correct URL (QhRnz9m5HE) across all GitHub
templates and workflows. Redirect feature requests from issue template
to GitHub Discussions for better community engagement.
Changes:
- config.yml: Add feature request link to Discussions, fix Discord URL
- question.yml: Update Discord link in pre-question guidance
- welcome.yml: Update Discord link in first-time contributor message
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): correct welcome workflow PR message (#206)
- Change branch reference from main to develop
- Fix contribution guide link to use full URL
- Remove hyphen from "Auto Claude" in welcome message
* fix: Add Python 3.10+ version validation and GitHub Actions Python setup (#180 #167) (#208)
This fixes critical bug where macOS users with default Python 3.9.6 couldn't use Auto-Claude because claude-agent-sdk requires Python 3.10+.
Root Cause:
- Auto-Claude doesn't bundle Python, relies on system Python
- python-detector.ts accepted any Python 3.x without checking minimum version
- macOS ships with Python 3.9.6 by default (incompatible)
- GitHub Actions runners didn't explicitly set Python version
Changes:
1. python-detector.ts:
- Added getPythonVersion() to extract version from command
- Added validatePythonVersion() to check if >= 3.10.0
- Updated findPythonCommand() to skip Python < 3.10 with clear error messages
2. python-env-manager.ts:
- Import and use findPythonCommand() (already has version validation)
- Simplified findSystemPython() to use shared validation logic
- Updated error message from "Python 3.9+" to "Python 3.10+" with download link
3. .github/workflows/release.yml:
- Added Python 3.11 setup to all 4 build jobs (macOS Intel, macOS ARM64, Windows, Linux)
- Ensures consistent Python version across all platforms during build
Impact:
- macOS users with Python 3.9 now see clear error with download link
- macOS users with Python 3.10+ work normally
- CI/CD builds use consistent Python 3.11
- Prevents "ModuleNotFoundError: dotenv" and dependency install failures
Fixes #180, #167
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* feat: Add OpenRouter as LLM/embedding provider (#162)
* feat: Add OpenRouter as LLM/embedding provider
Add OpenRouter provider support for Graphiti memory integration,
enabling access to multiple LLM providers through a single API.
Changes:
Backend:
- Created openrouter_llm.py: OpenRouter LLM provider using OpenAI-compatible API
- Created openrouter_embedder.py: OpenRouter embedder provider
- Updated config.py: Added OpenRouter to provider enums and configuration
- New fields: openrouter_api_key, openrouter_base_url, openrouter_llm_model, openrouter_embedding_model
- Validation methods updated for OpenRouter
- Updated factory.py: Added OpenRouter to LLM and embedder factories
- Updated provider __init__.py files: Exported new OpenRouter functions
Frontend:
- Updated project.ts types: Added 'openrouter' to provider type unions
- GraphitiProviderConfig extended with OpenRouter fields
- Updated GraphitiStep.tsx: Added OpenRouter to provider arrays
- LLM_PROVIDERS: 'Multi-provider aggregator'
- EMBEDDING_PROVIDERS: 'OpenAI-compatible embeddings'
- Added OpenRouter API key input field with show/hide toggle
- Link to https://openrouter.ai/keys
- Updated env-handlers.ts: OpenRouter .env generation and parsing
- Template generation for OPENROUTER_* variables
- Parsing from .env files with proper type casting
Documentation:
- Updated .env.example with OpenRouter section
- Configuration examples
- Popular model recommendations
- Example configuration (#6)
Fixes #92
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* refactor: address CodeRabbit review comments for OpenRouter
- Add globalOpenRouterApiKey to settings types and store updates
- Initialize openrouterApiKey from global settings
- Update documentation to include OpenRouter in provider lists
- Add OpenRouter handling to get_embedding_dimension() method
- Add openrouter to provider cleanup list
- Add OpenRouter to get_available_providers() function
- Clarify Legacy comment for openrouterLlmModel
These changes complete the OpenRouter integration by ensuring proper
settings persistence and provider detection across the application.
* fix: apply ruff formatting to OpenRouter code
- Break long error message across multiple lines
- Format provider list with one item per line
- Fixes lint CI failure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix(core): add global spec numbering lock to prevent collisions (#209)
Implements distributed file-based locking for spec number coordination
across main project and all worktrees. Previously, parallel spec creation
could assign the same number to different specs (e.g., 042-bmad-task and
042-gitlab-integration both using number 042).
The fix adds SpecNumberLock class that:
- Acquires exclusive lock before calculating spec numbers
- Scans ALL locations (main project + worktrees) for global maximum
- Creates spec directories atomically within the lock
- Handles stale locks via PID-based detection with 30s timeout
Applied to both Python backend (spec_runner.py flow) and TypeScript
frontend (ideation conversion, GitHub/GitLab issue import).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Fix/ideation status sync (#212)
* fix(ideation): add missing event forwarders for status sync
- Add event forwarders in ideation-handlers.ts for progress, log,
type-complete, type-failed, complete, error, and stopped events
- Fix ideation-type-complete to load actual ideas array from JSON files
instead of emitting only the count
Resolves UI getting stuck at 0/3 complete during ideation generation.
* fix(ideation): fix UI not updating after actions
- Fix getIdeationSummary to count only active ideas (exclude dismissed/archived)
This ensures header stats match the visible ideas count
- Add transformSessionFromSnakeCase to properly transform session data
from backend snake_case to frontend camelCase on ideation-complete event
- Transform raw session before emitting ideation-complete event
Resolves header showing stale counts after dismissing/deleting ideas.
* fix(ideation): improve type safety and async handling in ideation type completion
- Replace synchronous readFileSync with async fsPromises.readFile in ideation-type-complete handler
- Wrap async file read in IIFE with proper error handling to prevent unhandled promise rejections
- Add type validation for IdeationType with VALID_IDEATION_TYPES set and isValidIdeationType guard
- Add validateEnabledTypes function to filter out invalid type values and log dropped entries
- Handle ENOENT separately
* fix(ideation): improve generation state management and error handling
- Add explicit isGenerating flag to prevent race conditions during async operations
- Implement 5-minute timeout for generation with automatic cleanup and error state
- Add ideation-stopped event emission when process is intentionally killed
- Replace console.warn/error with proper ideation-error events in agent-queue
- Add resetGeneratingTypes helper to transition all generating types to a target state
- Filter out dismissed/
* refactor(ideation): improve event listener cleanup and timeout management
- Extract event handler functions in ideation-handlers.ts to enable proper cleanup
- Return cleanup function from registerIdeationHandlers to remove all listeners
- Replace single generationTimeoutId with Map to support multiple concurrent projects
- Add clearGenerationTimeout helper to centralize timeout cleanup logic
- Extract loadIdeationType IIFE to named function for better error context
- Enhance error logging with projectId,
* refactor: use async file read for ideation and roadmap session loading
- Replace synchronous readFileSync with async fsPromises.readFile
- Prevents blocking the event loop during file operations
- Consistent with async pattern used elsewhere in the codebase
- Improved error handling with proper event emission
* fix(agent-queue): improve roadmap completion handling and error reporting
- Add transformRoadmapFromSnakeCase to convert backend snake_case to frontend camelCase
- Transform raw roadmap data before emitting roadmap-complete event
- Add roadmap-error emission for unexpected errors during completion
- Add roadmap-error emission when project path is unavailable
- Remove duplicate ideation-type-complete emission from error handler (event already emitted in loadIdeationType)
- Update error log message
* fix: add future annotations import to discovery.py (#229)
Adds 'from __future__ import annotations' to spec/discovery.py for
Python 3.9+ compatibility with type hints.
This completes the Python compatibility fixes that were partially
applied in previous commits. All 26 analysis and spec Python files
now have the future annotations import.
Related: #128
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* fix: resolve Python detection and backend packaging issues (#241)
* fix: resolve Python detection and backend packaging issues
- Fix backend packaging path (auto-claude -> backend) to match path-resolver.ts expectations
- Add future annotations import to config_parser.py for Python 3.9+ compatibility
- Use findPythonCommand() in project-context-handlers to prioritize Homebrew Python
- Improve Python detection to prefer Homebrew paths over system Python on macOS
This resolves the following issues:
- 'analyzer.py not found' error due to incorrect packaging destination
- TypeError with 'dict | None' syntax on Python < 3.10
- Wrong Python interpreter being used (system Python instead of Homebrew Python 3.10+)
Tested on macOS with packaged app - project index now loads successfully.
* refactor: address PR review feedback
- Extract findHomebrewPython() helper to eliminate code duplication between
findPythonCommand() and getDefaultPythonCommand()
- Remove hardcoded version-specific paths (python3.12) and rely only on
generic Homebrew symlinks for better maintainability
- Remove unnecessary 'from __future__ import annotations' from config_parser.py
since backend requires Python 3.12+ where union types are native
These changes make the code more maintainable, less fragile to Python version
changes, and properly reflect the project's Python 3.12+ requirement.
* Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Revert "Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)" (#251)
This reverts commit 348de6dfe793ab111043677c61b8452bc5ecb2cc.
* feat: add i18n internationalization system (#248)
* Add multilingual support and i18n integration
- Implemented i18n framework using `react-i18next` for translation management.
- Added support for English and French languages with translation files.
- Integrated language selector into settings.
- Updated all text strings in UI components to use translation keys.
- Ensured smooth language switching with live updates.
* Migrate remaining hard-coded strings to i18n system
- TaskCard: status labels, review reasons, badges, action buttons
- PhaseProgressIndicator: execution phases, progress labels
- KanbanBoard: drop zone, show archived, tooltips
- CustomModelModal: dialog title, description, labels
- ProactiveSwapListener: account switch notifications
- AgentProfileSelector: phase labels, custom configuration
- GeneralSettings: agent framework option
Added translation keys for en/fr locales in tasks.json, common.json,
and settings.json for complete i18n coverage.
* Add i18n support to dialogs and settings components
- AddFeatureDialog: form labels, validation messages, buttons
- AddProjectModal: dialog steps, form fields, actions
- RateLimitIndicator: rate limit notifications
- RateLimitModal: account switching, upgrade prompts
- AdvancedSettings: updates and notifications sections
- ThemeSettings: theme selection labels
- Updated dialogs.json locales (en/fr)
* Fix truncated 'ready' message in dialogs locales
* Fix backlog terminology in i18n locales
Change "Planning"/"Planification" to standard PM term "Backlog"
* Migrate settings navigation and integration labels to i18n
- AppSettings: nav items, section titles, buttons
- IntegrationSettings: Claude accounts, auto-switch, API keys labels
- Added settings nav/projectSections/integrations translation keys
- Added buttons.saving to common translations
* Migrate AgentProfileSettings and Sidebar init dialog to i18n
- AgentProfileSettings: migrate phase config labels, section title,
description, and all hardcoded strings to settings namespace
- Sidebar: migrate init dialog strings to dialogs namespace with
common buttons from common namespace
- Add new translation keys for agent profile settings and update dialog
* Migrate AppSettings navigation labels to i18n
- Add useTranslation hook to AppSettings.tsx
- Replace hardcoded section labels with dynamic translations
- Add projectSections translations for project settings nav
- Add rerunWizardDescription translation key
* Add explicit typing to notificationItems array
Import NotificationSettings type and use keyof to properly type
the notification item keys, removing manual type assertion.
* fix: update path resolution for ollama_model_detector.py in memory handlers (#263)
* ci: implement enterprise-grade PR quality gates and security scanning (#266)
* ci: implement enterprise-grade PR quality gates and security scanning
* ci: implement enterprise-grade PR quality gates and security scanning
* fix:pr comments and improve code
* fix: improve commit linting and code quality
* Removed the dependency-review job (i added it)
* fix: address CodeRabbit review comments
- Expand scope pattern to allow uppercase, underscores, slashes, dots
- Add concurrency control to cancel duplicate security scan runs
- Add explanatory comment for Bandit CLI flags
- Remove dependency-review job (requires repo settings)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: update commit lint examples with expanded scope patterns
Show slashes and dots in scope examples to demonstrate
the newly allowed characters (api/users, package.json)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove feature request issue template
Feature requests are directed to GitHub Discussions
via the issue template config.yml
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address security vulnerabilities in service orchestrator
- Fix port parsing crash on malformed docker-compose entries
- Fix shell injection risk by using shlex.split() with shell=False
Prevents crashes when docker-compose.yml contains environment
variables in port mappings (e.g., '${PORT}:8080') and eliminates
shell injection vulnerabilities in subprocess execution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat(github): add automated PR review with follow-up support (#252)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fixes during testing of PR
* feat(github): implement PR merge, assign, and comment features
- Add auto-assignment when clicking "Run AI Review"
- Implement PR merge functionality with squash method
- Add ability to post comments on PRs
- Display assignees in PR UI
- Add Approve and Merge buttons when review passes
- Update backend gh_client with pr_merge, pr_comment, pr_assign methods
- Create IPC handlers for new PR operations
- Update TypeScript interfaces and browser mocks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Improve PR review AI
* fix(github): use temp files for PR review posting to avoid shell escaping issues
When posting PR reviews with findings containing special characters (backticks,
parentheses, quotes), the shell command was interpreting them as commands instead
of literal text, causing syntax errors.
Changed both postPRReview and postPRComment handlers to write the body content
to temporary files and use gh CLI's --body-file flag instead of --body with
inline content. This safely handles ALL special characters without escaping issues.
Fixes shell errors when posting reviews with suggested fixes containing code snippets.
* fix(i18n): add missing GitHub PRs translation and document i18n requirements
Fixed missing translation key for GitHub PRs feature that was causing
"items.githubPRs" to display instead of the proper translated text.
Added comprehensive i18n guidelines to CLAUDE.md to ensure all future
frontend development follows the translation key pattern instead of
using hardcoded strings.
Also fixed missing deletePRReview mock function in browser-mock.ts
to resolve TypeScript compilation errors.
Changes:
- Added githubPRs translation to en/navigation.json
- Added githubPRs translation to fr/navigation.json
- Added Development Guidelines section to CLAUDE.md with i18n requirements
- Documented translation file locations and namespace usage patterns
- Added deletePRReview mock function to browser-mock.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix ui loading
* Github PR fixes
* improve claude.md
* lints/tests
* fix(github): handle PRs exceeding GitHub's 20K line diff limit
- Add PRTooLargeError exception for large PR detection
- Update pr_diff() to catch and raise PRTooLargeError for HTTP 406 errors
- Gracefully handle large PRs by skipping full diff and using individual file patches
- Add diff_truncated flag to PRContext to track when diff was skipped
- Large PRs will now review successfully using per-file diffs instead of failing
Fixes issue with PR #252 which has 100+ files exceeding the 20,000 line limit.
* fix: implement individual file patch fetching for large PRs
The PR review was getting stuck for large PRs (>20K lines) because when we
skipped the full diff due to GitHub API limits, we had no code to analyze.
The individual file patches were also empty, leaving the AI with just
file names and metadata.
Changes:
- Implemented _get_file_patch() to fetch individual patches via git diff
- Updated PR review engine to build composite diff from file patches when
diff_truncated is True
- Added missing 'state' field to PRContext dataclass
- Limits composite diff to first 50 files for very large PRs
- Shows appropriate warnings when using reconstructed diffs
This allows AI review to proceed with actual code analysis even when the
full PR diff exceeds GitHub's limits.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* 1min reduction
* docs: add GitHub Sponsors funding configuration
Enable the Sponsor button on the repository by adding FUNDING.yml
with the AndyMik90 GitHub Sponsors profile.
* feat(github-pr): add orchestrating agent for thorough PR reviews
Implement a new Opus 4.5 orchestrating agent that performs comprehensive
PR reviews regardless of size. Key changes:
- Add orchestrator_reviewer.py with strategic review workflow
- Add review_tools.py with subagent spawning capabilities
- Add pr_orchestrator.md prompt emphasizing thorough analysis
- Add pr_security_agent.md and pr_quality_agent.md subagent prompts
- Integrate orchestrator into pr_review_engine.py with config flag
- Fix critical bug where findings were extracted but not processed
(indentation issue in _parse_orchestrator_output)
The orchestrator now correctly identifies issues in PRs that were
previously approved as "trivial". Testing showed 7 findings detected
vs 0 before the fix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* i18n
* fix(github-pr): restrict pr_reviewer to read-only permissions
The PR review agent was using qa_reviewer agent type which has Bash
access, allowing it to checkout branches and make changes during
review. Created new pr_reviewer agent type with BASE_READ_TOOLS only
(no Bash, no writes, no auto-claude tools).
This prevents the PR review from accidentally modifying code or
switching branches during analysis.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-pr): robust category mapping and JSON parsing for PR review
The orchestrator PR review was failing to extract findings because:
1. AI generates category names like 'correctness', 'consistency', 'testing'
that aren't in our ReviewCategory enum - added flexible mapping
2. JSON sometimes embedded in markdown code blocks (```json) which broke
parsing - added code block extraction as first parsing attempt
Changes:
- Add _CATEGORY_MAPPING dict to map AI categories to valid enum values
- Add _map_category() helper function with fallback to QUALITY
- Add severity parsing with fallback to MEDIUM
- Add markdown code block detection (```json) before raw JSON parsing
- Add _extract_findings_from_data() helper to reduce code duplication
- Apply same fixes to review_tools.py for subagent parsing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(pr-review): improve post findings UX with batch support and feedback
- Fix post findings failing on own PRs by falling back from REQUEST_CHANGES
to COMMENT when GitHub returns 422 error
- Change status badge to show "Reviewed" instead of "Commented" until
findings are actually posted to GitHub
- Add success notification when findings are posted (auto-dismisses after 3s)
- Add batch posting support: track posted findings, show "Posted" badge,
allow posting remaining findings in additional batches
- Show loading state on button while posting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): resolve stale timestamp and null author bugs
- Fix stale timestamp in batch_issues.py: Move updated_at assignment
BEFORE to_dict() serialization so the saved JSON contains the correct
timestamp instead of the old value
- Fix AttributeError in context_gatherer.py: Handle null author/user
fields when GitHub API returns null for deleted/suspended users
instead of an empty object
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high and medium severity PR review findings
HIGH severity fixes:
- Command Injection in autofix-handlers.ts: Use execFileSync with args array
- Command Injection in pr-handlers.ts (3 locations): Use execFileSync + validation
- Command Injection in triage-handlers.ts: Use execFileSync + label validation
- Token Exposure in bot_detection.py: Pass token via GH_TOKEN env var
MEDIUM severity fixes:
- Environment variable leakage in subprocess-runner.ts: Filter to safe vars only
- Debug logging in subprocess-runner.ts: Only log in development mode
- Delimiter escape bypass in sanitize.py: Use regex pattern for variations
- Insecure file permissions in trust.py: Use os.open with 0o600 mode
- No file locking in learning.py: Use FileLock + atomic_write utilities
- Bare except in confidence.py: Log error with specific exception info
- Fragile module import in pr_review_engine.py: Import at module level
- State transition validation in models.py: Enforce can_transition_to()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR followup
* fix(security): add usedforsecurity=False to MD5 hash calls
MD5 is used for generating unique IDs/cache keys, not for security purposes.
Adding usedforsecurity=False resolves Bandit B324 warnings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(ui): add PR status labels to list view
Add secondary status badges to the PR list showing review state at a glance:
- "Changes Requested" (warning) - PRs with blocking issues (critical/high)
- "Ready to Merge" (green) - PRs with only non-blocking suggestions
- "Ready for Follow-up" (blue) - PRs with new commits since last review
The "Ready for Follow-up" badge uses a cached new commits check from the
store, only shown after the detail view confirms new commits via SHA
comparison. This prevents false positives from PR updatedAt timestamp
changes (which can happen from comments, labels, etc).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR labels
* auto-claude: Initialize subtask-based implementation plan
- Workflow type: feature
- Phases: 3
- Subtasks: 6
- Ready for autonomous implementation
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* chore(deps): bump vitest from 4.0.15 to 4.0.16 in /apps/frontend (#272)
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.0.15 to 4.0.16.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/vitest)
---
updated-dependencies:
- dependency-name: vitest
dependency-version: 4.0.16
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps): bump @electron/rebuild in /apps/frontend (#271)
Bumps [@electron/rebuild](https://github.com/electron/rebuild) from 3.7.2 to 4.0.2.
- [Release notes](https://github.com/electron/rebuild/releases)
- [Commits](https://github.com/electron/rebuild/compare/v3.7.2...v4.0.2)
---
updated-dependencies:
- dependency-name: "@electron/rebuild"
dependency-version: 4.0.2
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(paths): normalize relative paths to posix (#239)
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix: accept bug_fix workflow_type alias during planning (#240)
* fix(planning): accept bug_fix workflow_type alias
* style(planning): ruff format
* fix: refatored common logic
* fix: remove ruff errors
* fix: remove duplicate _normalize_workflow_type method
Remove the incorrectly placed duplicate method inside ContextLoader class.
The module-level function is the correct implementation being used.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): use develop branch for dry-run builds in beta-release workflow (#276)
When dry_run=true, the workflow skipped creating the version tag but
build jobs still tried to checkout that non-existent tag, causing all
4 platform builds to fail with "git failed with exit code 1".
Now build jobs checkout develop branch for dry runs while still using
the version tag for real releases.
Closes: GitHub Actions run #20464082726
* chore(deps): bump typescript-eslint in /apps/frontend (#269)
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.49.0 to 8.50.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.50.1/packages/typescript-eslint)
---
updated-dependencies:
- dependency-name: typescript-eslint
dependency-version: 8.50.1
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* chore(deps): bump jsdom from 26.1.0 to 27.3.0 in /apps/frontend (#268)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 26.1.0 to 27.3.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/26.1.0...27.3.0)
---
updated-dependencies:
- dependency-name: jsdom
dependency-version: 27.3.0
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(ci): use correct electron-builder arch flags (#278)
The project switched from pnpm to npm, which handles script argument
passing differently. pnpm adds a -- separator that caused electron-builder
to ignore the --arch argument, but npm passes it directly.
Since --arch is a deprecated electron-builder argument, use the
recommended flags instead:
- --arch=x64 → --x64
- --arch=arm64 → --arm64
This fixes Mac Intel and ARM64 builds failing with "Unknown argument: arch"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): resolve CodeQL file system race conditions and unused variables (#277)
* fix(security): resolve CodeQL file system race conditions and unused variables
Fix high severity CodeQL alerts:
- Remove TOCTOU (time-of-check-time-of-use) race conditions by eliminating
existsSync checks followed by file operations. Use try-catch instead.
- Files affected: pr-handlers.ts, spec-utils.ts
Fix unused variable warnings:
- Remove unused imports (FeatureModelCon…
* docs: Add Git Flow branching strategy to CONTRIBUTING.md
- Add comprehensive branching strategy documentation
- Explain main, develop, feature, fix, release, and hotfix branches
- Clarify that all PRs should target develop (not main)
- Add release process documentation for maintainers
- Update PR process to branch from develop
- Expand table of contents with new sections
* Feature/apps restructure v2.7.2 (#138)
* refactor: restructure project to Apps/frontend and Apps/backend
- Move auto-claude-ui to Apps/frontend with feature-based architecture
- Move auto-claude to Apps/backend
- Switch from pnpm to npm for frontend
- Update Node.js requirement to v24.12.0 LTS
- Add pre-commit hooks for lint, typecheck, and security audit
- Add commit-msg hook for conventional commits
- Fix CommonJS compatibility issues (postcss.config, postinstall scripts)
- Update README with comprehensive setup and contribution guidelines
- Configure ESLint to ignore .cjs files
- 0 npm vulnerabilities
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(refactor): clean code and move to npm
* feat(refactor): clean code and move to npm
* chore: update to v2.7.0, remove Docker deps (LadybugDB is embedded)
* feat: v2.8.0 - update workflows and configs for Apps/ structure, npm
* fix: resolve Python lint errors (F401, I001)
* fix: update test paths for Apps/backend structure
* fix: add missing facade files and update paths for Apps/backend structure
- Fix ruff lint error I001 in auto_claude_tools.py
- Create missing facade files to match upstream (agent, ci_discovery, critique, etc.)
- Update test paths from auto-claude/ to Apps/backend/
- Update .pre-commit-config.yaml paths for Apps/ structure
- Add pytest to pre-commit hooks (skip slow/integration/Windows-incompatible tests)
- Fix Unicode encoding in test_agent_architecture.py for Windows
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat: improve readme
* fix: new path
* fix: correct release workflow and docs for Apps/ restructure
- Fix ARM64 macOS build: pnpm → npm, auto-claude-ui → Apps/frontend
- Fix artifact upload paths in release.yml
- Update Node.js version to 24 for consistency
- Update CLI-USAGE.md with Apps/backend paths
- Update RELEASE.md with Apps/frontend/package.json paths
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: rename Apps/ to apps/ and fix backend path resolution
- Rename Apps/ folder to apps/ for consistency with JS/Node conventions
- Update all path references across CI/CD workflows, docs, and config files
- Fix frontend Python path resolver to look for 'backend' instead of 'auto-claude'
- Update path-resolver.ts to correctly find apps/backend in development mode
This completes the Apps restructure from PR #122 and prepares for v2.8.0 release.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(electron): correct preload script path from .js to .mjs
electron-vite builds the preload script as ESM (index.mjs) but the main
process was looking for CommonJS (index.js). This caused the preload to
fail silently, making the app fall back to browser mock mode with fake
data and non-functional IPC handlers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* - Introduced `dev:debug` script to enable debugging during development.
- Added `dev:mcp` script for running the frontend in MCP mode.
These enhancements streamline the development process for frontend developers.
* refactor(memory): make Graphiti memory mandatory and remove Docker dependency
Memory is now a core component of Auto Claude rather than optional:
- Python 3.12+ is required for the backend (not just memory layer)
- Graphiti is enabled by default in .env.example
- Removed all FalkorDB/Docker references (migrated to embedded LadybugDB)
- Deleted guides/DOCKER-SETUP.md and docker-handlers.ts
- Updated onboarding UI to remove "optional" language
- Updated all documentation to reflect LadybugDB architecture
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add cross-platform Windows support for npm scripts
- Add scripts/install-backend.js for cross-platform Python venv setup
- Auto-detects Python 3.12 (py -3.12 on Windows, python3.12 on Unix)
- Handles platform-specific venv paths
- Add scripts/test-backend.js for cross-platform pytest execution
- Update package.json to use Node.js scripts instead of shell commands
- Update CONTRIBUTING.md with correct paths and instructions:
- apps/backend/ and apps/frontend/ paths
- Python 3.12 requirement (memory system now required)
- Platform-specific install commands (winget, brew, apt)
- npm instead of pnpm
- Quick Start section with npm run install:all
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* remove doc
* fix(frontend): correct Ollama detector script path after apps restructure
The Ollama status check was failing because memory-handlers.ts
was looking for ollama_model_detector.py at auto-claude/ but the
script is now at apps/backend/ after the directory restructure.
This caused "Ollama not running" to display even when Ollama was
actually running and accessible.
* chore: bump version to 2.7.2
Downgrade version from 2.8.0 to 2.7.2 as the Apps/ restructure
is better suited as a patch release rather than a minor release.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: update package-lock.json for Windows compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs(contributing): add hotfix workflow and update paths for apps/ structure
Add Git Flow hotfix workflow documentation with step-by-step guide
and ASCII diagram showing the branching strategy.
Update all paths from auto-claude/auto-claude-ui to apps/backend/apps/frontend
and migrate package manager references from pnpm to npm to match the
new project structure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): remove duplicate ARM64 build from Intel runner
The Intel runner was building both x64 and arm64 architectures,
while a separate ARM64 runner also builds arm64 natively. This
caused duplicate ARM64 builds, wasting CI resources.
Now each runner builds only its native architecture:
- Intel runner: x64 only
- ARM64 runner: arm64 only
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Alex Madera <e.a_madera@hotmail.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Feat: Ollama download progress tracking with new apps structure (#141)
* feat(ollama): add real-time download progress tracking for model downloads
Implement comprehensive download progress tracking with:
- NDJSON parsing for streaming progress data from Ollama API
- Real-time speed calculation (MB/s, KB/s, B/s) with useRef for delta tracking
- Time remaining estimation based on download speed
- Animated progress bars in OllamaModelSelector component
- IPC event streaming from main process to renderer
- Proper listener management with cleanup functions
Changes:
- memory-handlers.ts: Parse NDJSON from Ollama stderr, emit progress events
- OllamaModelSelector.tsx: Display progress bars with speed and time remaining
- project-api.ts: Implement onDownloadProgress listener with cleanup
- ipc.ts types: Define onDownloadProgress listener interface
- infrastructure-mock.ts: Add mock implementation for browser testing
This allows users to see real-time feedback when downloading Ollama models,
including percentage complete, current download speed, and estimated time remaining.
* test: add focused test coverage for Ollama download progress feature
Add unit tests for the critical paths of the real-time download progress tracking:
- Progress calculation tests (52 tests): Speed/time/percentage calculations with comprehensive edge case coverage (zero speeds, NaN, Infinity, large numbers)
- NDJSON parser tests (33 tests): Streaming JSON parsing from Ollama, buffer management for incomplete lines, error handling
All 562 unit tests passing with clean dependencies. Tests focus on critical mathematical logic and data processing - the most important paths that need verification.
Test coverage:
✅ Speed calculation and formatting (B/s, KB/s, MB/s)
✅ Time remaining calculations (seconds, minutes, hours)
✅ Percentage clamping (0-100%)
✅ NDJSON streaming with partial line buffering
✅ Invalid JSON handling
✅ Real Ollama API responses
✅ Multi-chunk streaming scenarios
* docs: add comprehensive JSDoc docstrings for Ollama download progress feature
- Enhanced OllamaModelSelector component with detailed JSDoc
* Documented component props, behavior, and usage examples
* Added docstrings to internal functions (checkInstalledModels, handleDownload, handleSelect)
* Explained progress tracking algorithm and useRef usage
- Improved memory-handlers.ts documentation
* Added docstring to main registerMemoryHandlers function
* Documented all Ollama-related IPC handlers (check-status, list-embedding-models, pull-model)
* Added JSDoc to executeOllamaDetector helper function
* Documented interface types (OllamaStatus, OllamaModel, OllamaEmbeddingModel, OllamaPullResult)
* Explained NDJSON parsing and progress event structure
- Enhanced test file documentation
* Added docstrings to NDJSON parser test utilities with algorithm explanation
* Documented all calculation functions (speed, time, percentage)
* Added detailed comments on formatting and bounds-checking logic
- Improved overall code maintainability
* Docstring coverage now meets 80%+ threshold for code review
* Clear explanation of progress tracking implementation details
* Better context for future maintainers working with download streaming
* feat: add batch task creation and management CLI commands
- Handle batch task creation from JSON files
- Show status of all specs in project
- Cleanup tool for completed specs
- Full integration with new apps/backend structure
- Compatible with implementation_plan.json workflow
* test: add batch task test file and testing checklist
- batch_test.json: Sample tasks for testing batch creation
- TESTING_CHECKLIST.md: Comprehensive testing guide for Ollama and batch tasks
- Includes UI testing steps, CLI testing steps, and edge cases
- Ready for manual and automated testing
* chore: update package-lock.json to match v2.7.2
* test: update checklist with verification results and architecture validation
* docs: add comprehensive implementation summary for Ollama + Batch features
* docs: add comprehensive Phase 2 testing guide with checklists and procedures
* docs: add NEXT_STEPS guide for Phase 2 testing
* fix: resolve merge conflict in project-api.ts from Ollama feature cherry-pick
* fix: remove duplicate Ollama check status handler registration
* test: update checklist with Phase 2 bug findings and fixes
---------
Co-authored-by: ray <ray@rays-MacBook-Pro.local>
* fix: resolve Python environment race condition (#142)
Implemented promise queue pattern in PythonEnvManager to handle
concurrent initialization requests. Previously, multiple simultaneous
requests (e.g., startup + merge) would fail with "Already
initializing" error.
Also fixed parsePythonCommand() to handle file paths with spaces by
checking file existence before splitting on whitespace.
Changes:
- Added initializationPromise field to queue concurrent requests
- Split initialize() into public and private _doInitialize()
- Enhanced parsePythonCommand() with existsSync() check
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* fix: remove legacy path from auto-claude source detection (#148)
Removes the legacy 'auto-claude' path from the possiblePaths array
in agent-process.ts. This path was from before the monorepo
restructure (v2.7.2) and is no longer needed.
The legacy path was causing spec_runner.py to be looked up at the
wrong location:
- OLD (wrong): /path/to/auto-claude/auto-claude/runners/spec_runner.py
- NEW (correct): /path/to/apps/backend/runners/spec_runner.py
This aligns with the new monorepo structure where all backend code
lives in apps/backend/.
Fixes #147
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* Fix/linear 400 error
* fix: Linear API authentication and GraphQL types
- Remove Bearer prefix from Authorization header (Linear API keys are sent directly)
- Change GraphQL variable types from String! to ID! for teamId and issue IDs
- Improve error handling to show detailed Linear API error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: Radix Select empty value error in Linear import modal
Use '__all__' sentinel value instead of empty string for "All projects"
option, as Radix Select does not allow empty string values.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add CodeRabbit configuration file
Introduce a new .coderabbit.yaml file to configure CodeRabbit settings, including review profiles, automatic review options, path filters, and specific instructions for different file types. This enhances the code review process by providing tailored guidelines for Python, TypeScript, and test files.
* fix: correct GraphQL types for Linear team queries
Linear API uses different types for different queries:
- team(id:) expects String!
- issues(filter: { team: { id: { eq: } } }) expects ID!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: refresh task list after Linear import
Call loadTasks() after successful Linear import to update the kanban
board without requiring a page reload.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* cleanup
* cleanup
* fix: address CodeRabbit review comments for Linear integration
- Fix unsafe JSON parsing: check response.ok before parsing JSON to handle
non-JSON error responses (e.g., 503 from proxy) gracefully
- Use ID! type instead of String! for teamId in LINEAR_GET_PROJECTS query
for GraphQL type consistency
- Remove debug console.log (ESLint config only allows warn/error)
- Refresh task list on partial import success (imported > 0) instead of
requiring full success
- Fix pre-existing TypeScript and lint issues blocking commit
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* version sync logic
* lints for develop branch
* chore: update CI workflow to include develop branch
- Modified the CI configuration to trigger on pushes and pull requests to both main and develop branches, enhancing the workflow for development and integration processes.
* fix: update project directory auto-detection for apps/backend structure
The project directory auto-detection was checking for the old `auto-claude/`
directory name but needed to check for `apps/backend/`. When running from
`apps/backend/`, the directory name is `backend` not `auto-claude`, so the
check would fail and `project_dir` would incorrectly remain as `apps/backend/`
instead of resolving to the project root (2 levels up).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use GraphQL variables instead of string interpolation in LINEAR_GET_ISSUES
Replace direct string interpolation of teamId and linearProjectId with
proper GraphQL variables. This prevents potential query syntax errors if
IDs contain special characters like double quotes, and aligns with the
variable-based approach used elsewhere in the file.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ui): correct logging level and await loadTasks on import complete
- Change console.warn to console.log for import success messages
(warn is incorrect severity for normal completion)
- Make onImportComplete callback async and await loadTasks()
to prevent potential unhandled promise rejections
Applies CodeRabbit review feedback across 3 LinearTaskImportModal usages.
* fix(hooks): use POSIX-compliant find instead of bash glob
The pre-commit hook uses #!/bin/sh but had bash-specific ** glob
pattern for staging ruff-formatted files. The ** pattern only works
in bash with globstar enabled - in POSIX sh it expands literally
and won't match subdirectories, causing formatted files in nested
directories to not be staged.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(task): stop running process when task status changes away from in_progress
When a user drags a running task back to Planning (or any other column),
the process was not being stopped, leaving a "ghost" process that
prevented deletion with "Cannot delete a running task" error.
Now the task process is automatically killed when status changes away
from in_progress, ensuring the process state stays in sync with the UI.
* feat: Add UI scale feature with 75-200% range (#125)
* feat: add UI scale feature
* refactor: extract UI scale bounds to shared constants
* fix: duplicated import
* fix: hide status badge when execution phase badge is showing (#154)
* fix: analyzer Python compatibility and settings integration
Fixes project index analyzer failing with TypeError on Python type hints.
Changes:
- Added 'from __future__ import annotations' to all analysis modules
- Fixed project discovery to support new analyzer JSON format
- Read Python path directly from settings.json instead of pythonEnvManager
- Added stderr/stdout logging for analyzer debugging
Resolves 'Discovered 0 files' and 'TypeError: unsupported operand type' issues.
* auto-claude: subtask-1-1 - Hide status badge when execution phase badge is showing
When a task has an active execution (planning, coding, etc.), the
execution phase badge already displays the correct state with a spinner.
The status badge was also rendering, causing duplicate/confusing badges
(e.g., both "Planning" and "Pending" showing at the same time).
This fix wraps the status badge in a conditional that only renders when
there's no active execution, eliminating the redundant badge display.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ipc): remove unused pythonEnvManager parameter and fix ES6 import
Address CodeRabbit review feedback:
- Remove unused pythonEnvManager parameter from registerProjectContextHandlers
and registerContextHandlers (the code reads Python path directly from
settings.json instead)
- Replace require('electron').app with proper ES6 import for consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(lint): fix import sorting in analysis module
Run ruff --fix to resolve I001 lint errors after merging develop.
All 23 files in apps/backend/analysis/ now have properly sorted imports.
---------
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix/PRs from old main setup to apps structure (#185)
* fix(core): add task persistence, terminal handling, and HTTP 300 fixes
Consolidated bug fixes from PRs #168, #170, #171:
- Task persistence (#168): Scan worktrees for tasks on app restart
to prevent loss of in-progress work and wasted API credits. Tasks
in .worktrees/*/specs are now loaded and deduplicated with main.
- Terminal buttons (#170): Fix "Open Terminal" buttons silently
failing on macOS by properly awaiting createTerminal() Promise.
Added useTerminalHandler hook with loading states and error display.
- HTTP 300 errors (#171): Handle branch/tag name collisions that
cause update failures. Added validation script to prevent conflicts
before releases and user-friendly error messages with manual
download links.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(platform): add path resolution, spaces handling, and XDG support
This commit consolidates multiple bug fixes from community PRs:
- PR #187: Path resolution fix - Update path detection to find apps/backend
instead of legacy auto-claude directory after v2.7.2 restructure
- PR #182/#155: Python path spaces fix - Improve parsePythonCommand() to
handle quoted paths and paths containing spaces without splitting
- PR #161: Ollama detection fix - Add new apps structure paths for
ollama_model_detector.py script discovery
- PR #160: AppImage support - Add XDG Base Directory compliant paths for
Linux sandboxed environments (AppImage, Flatpak, Snap). New files:
- config-paths.ts: XDG path utilities
- fs-utils.ts: Filesystem utilities with fallback support
- PR #159: gh CLI PATH fix - Add getAugmentedEnv() utility to include
common binary locations (Homebrew, snap, local) in PATH for child
processes. Fixes gh CLI not found when app launched from Finder/Dock.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit/Cursor review comments on PR #185
Fixes from code review:
- http-client.ts: Use GITHUB_CONFIG instead of hardcoded owner in HTTP 300 error message
- validate-release.js: Fix substring matching bug in branch detection that could cause false positives (e.g., v2.7 matching v2.7.2)
- bump-version.js: Remove unnecessary try-catch wrapper (exec() already exits on failure)
- execution-handlers.ts: Capture original subtask status before mutation for accurate logging
- fs-utils.ts: Add error handling to safeWriteFile with proper logging
Dismissed as trivial/not applicable:
- config-paths.ts: Exhaustive switch check (over-engineering)
- env-utils.ts: PATH priority documentation (existing comments sufficient)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address additional CodeRabbit review comments (round 2)
Fixes from second round of code review:
- fs-utils.ts: Wrap test file cleanup in try-catch for Windows file locking
- fs-utils.ts: Add error handling to safeReadFile for consistency with safeWriteFile
- http-client.ts: Use GITHUB_CONFIG in fetchJson (missed in first round)
- validate-release.js: Exclude symbolic refs (origin/HEAD -> origin/main) from branch check
- python-detector.ts: Return cleanPath instead of pythonPath for empty input edge case
Dismissed as trivial/not applicable:
- execution-handlers.ts: Redundant checkSubtasksCompletion call (micro-optimization)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat/beta-release (#190)
* chore: update README version to 2.7.1
Updated the version badge and download links in the README to reflect the new release version 2.7.1, ensuring users have the correct information for downloading the latest builds.
* feat(releases): add beta release system with user opt-in
Implements a complete beta release workflow that allows users to opt-in
to receiving pre-release versions. This enables testing new features
before they're included in stable releases.
Changes:
- Add beta-release.yml workflow for creating beta releases from develop
- Add betaUpdates setting with UI toggle in Settings > Updates
- Add update channel support to electron-updater (beta vs latest)
- Extract shared settings-utils.ts to reduce code duplication
- Add prepare-release.yml workflow for automated release preparation
- Document beta release process in CONTRIBUTING.md and RELEASE.md
Users can enable beta updates in Settings > Updates, and maintainers
can trigger beta releases via the GitHub Actions workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* workflow update
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Feat/beta release (#193)
* chore: update README version to 2.7.1
Updated the version badge and download links in the README to reflect the new release version 2.7.1, ensuring users have the correct information for downloading the latest builds.
* feat(releases): add beta release system with user opt-in
Implements a complete beta release workflow that allows users to opt-in
to receiving pre-release versions. This enables testing new features
before they're included in stable releases.
Changes:
- Add beta-release.yml workflow for creating beta releases from develop
- Add betaUpdates setting with UI toggle in Settings > Updates
- Add update channel support to electron-updater (beta vs latest)
- Extract shared settings-utils.ts to reduce code duplication
- Add prepare-release.yml workflow for automated release preparation
- Document beta release process in CONTRIBUTING.md and RELEASE.md
Users can enable beta updates in Settings > Updates, and maintainers
can trigger beta releases via the GitHub Actions workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* workflow update
* ci(github): update Discord link and redirect feature requests to discussions
Update Discord invite link to correct URL (QhRnz9m5HE) across all GitHub
templates and workflows. Redirect feature requests from issue template
to GitHub Discussions for better community engagement.
Changes:
- config.yml: Add feature request link to Discussions, fix Discord URL
- question.yml: Update Discord link in pre-question guidance
- welcome.yml: Update Discord link in first-time contributor message
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): correct welcome workflow PR message (#206)
- Change branch reference from main to develop
- Fix contribution guide link to use full URL
- Remove hyphen from "Auto Claude" in welcome message
* fix: Add Python 3.10+ version validation and GitHub Actions Python setup (#180 #167) (#208)
This fixes critical bug where macOS users with default Python 3.9.6 couldn't use Auto-Claude because claude-agent-sdk requires Python 3.10+.
Root Cause:
- Auto-Claude doesn't bundle Python, relies on system Python
- python-detector.ts accepted any Python 3.x without checking minimum version
- macOS ships with Python 3.9.6 by default (incompatible)
- GitHub Actions runners didn't explicitly set Python version
Changes:
1. python-detector.ts:
- Added getPythonVersion() to extract version from command
- Added validatePythonVersion() to check if >= 3.10.0
- Updated findPythonCommand() to skip Python < 3.10 with clear error messages
2. python-env-manager.ts:
- Import and use findPythonCommand() (already has version validation)
- Simplified findSystemPython() to use shared validation logic
- Updated error message from "Python 3.9+" to "Python 3.10+" with download link
3. .github/workflows/release.yml:
- Added Python 3.11 setup to all 4 build jobs (macOS Intel, macOS ARM64, Windows, Linux)
- Ensures consistent Python version across all platforms during build
Impact:
- macOS users with Python 3.9 now see clear error with download link
- macOS users with Python 3.10+ work normally
- CI/CD builds use consistent Python 3.11
- Prevents "ModuleNotFoundError: dotenv" and dependency install failures
Fixes #180, #167
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* feat: Add OpenRouter as LLM/embedding provider (#162)
* feat: Add OpenRouter as LLM/embedding provider
Add OpenRouter provider support for Graphiti memory integration,
enabling access to multiple LLM providers through a single API.
Changes:
Backend:
- Created openrouter_llm.py: OpenRouter LLM provider using OpenAI-compatible API
- Created openrouter_embedder.py: OpenRouter embedder provider
- Updated config.py: Added OpenRouter to provider enums and configuration
- New fields: openrouter_api_key, openrouter_base_url, openrouter_llm_model, openrouter_embedding_model
- Validation methods updated for OpenRouter
- Updated factory.py: Added OpenRouter to LLM and embedder factories
- Updated provider __init__.py files: Exported new OpenRouter functions
Frontend:
- Updated project.ts types: Added 'openrouter' to provider type unions
- GraphitiProviderConfig extended with OpenRouter fields
- Updated GraphitiStep.tsx: Added OpenRouter to provider arrays
- LLM_PROVIDERS: 'Multi-provider aggregator'
- EMBEDDING_PROVIDERS: 'OpenAI-compatible embeddings'
- Added OpenRouter API key input field with show/hide toggle
- Link to https://openrouter.ai/keys
- Updated env-handlers.ts: OpenRouter .env generation and parsing
- Template generation for OPENROUTER_* variables
- Parsing from .env files with proper type casting
Documentation:
- Updated .env.example with OpenRouter section
- Configuration examples
- Popular model recommendations
- Example configuration (#6)
Fixes #92
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* refactor: address CodeRabbit review comments for OpenRouter
- Add globalOpenRouterApiKey to settings types and store updates
- Initialize openrouterApiKey from global settings
- Update documentation to include OpenRouter in provider lists
- Add OpenRouter handling to get_embedding_dimension() method
- Add openrouter to provider cleanup list
- Add OpenRouter to get_available_providers() function
- Clarify Legacy comment for openrouterLlmModel
These changes complete the OpenRouter integration by ensuring proper
settings persistence and provider detection across the application.
* fix: apply ruff formatting to OpenRouter code
- Break long error message across multiple lines
- Format provider list with one item per line
- Fixes lint CI failure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix(core): add global spec numbering lock to prevent collisions (#209)
Implements distributed file-based locking for spec number coordination
across main project and all worktrees. Previously, parallel spec creation
could assign the same number to different specs (e.g., 042-bmad-task and
042-gitlab-integration both using number 042).
The fix adds SpecNumberLock class that:
- Acquires exclusive lock before calculating spec numbers
- Scans ALL locations (main project + worktrees) for global maximum
- Creates spec directories atomically within the lock
- Handles stale locks via PID-based detection with 30s timeout
Applied to both Python backend (spec_runner.py flow) and TypeScript
frontend (ideation conversion, GitHub/GitLab issue import).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Fix/ideation status sync (#212)
* fix(ideation): add missing event forwarders for status sync
- Add event forwarders in ideation-handlers.ts for progress, log,
type-complete, type-failed, complete, error, and stopped events
- Fix ideation-type-complete to load actual ideas array from JSON files
instead of emitting only the count
Resolves UI getting stuck at 0/3 complete during ideation generation.
* fix(ideation): fix UI not updating after actions
- Fix getIdeationSummary to count only active ideas (exclude dismissed/archived)
This ensures header stats match the visible ideas count
- Add transformSessionFromSnakeCase to properly transform session data
from backend snake_case to frontend camelCase on ideation-complete event
- Transform raw session before emitting ideation-complete event
Resolves header showing stale counts after dismissing/deleting ideas.
* fix(ideation): improve type safety and async handling in ideation type completion
- Replace synchronous readFileSync with async fsPromises.readFile in ideation-type-complete handler
- Wrap async file read in IIFE with proper error handling to prevent unhandled promise rejections
- Add type validation for IdeationType with VALID_IDEATION_TYPES set and isValidIdeationType guard
- Add validateEnabledTypes function to filter out invalid type values and log dropped entries
- Handle ENOENT separately
* fix(ideation): improve generation state management and error handling
- Add explicit isGenerating flag to prevent race conditions during async operations
- Implement 5-minute timeout for generation with automatic cleanup and error state
- Add ideation-stopped event emission when process is intentionally killed
- Replace console.warn/error with proper ideation-error events in agent-queue
- Add resetGeneratingTypes helper to transition all generating types to a target state
- Filter out dismissed/
* refactor(ideation): improve event listener cleanup and timeout management
- Extract event handler functions in ideation-handlers.ts to enable proper cleanup
- Return cleanup function from registerIdeationHandlers to remove all listeners
- Replace single generationTimeoutId with Map to support multiple concurrent projects
- Add clearGenerationTimeout helper to centralize timeout cleanup logic
- Extract loadIdeationType IIFE to named function for better error context
- Enhance error logging with projectId,
* refactor: use async file read for ideation and roadmap session loading
- Replace synchronous readFileSync with async fsPromises.readFile
- Prevents blocking the event loop during file operations
- Consistent with async pattern used elsewhere in the codebase
- Improved error handling with proper event emission
* fix(agent-queue): improve roadmap completion handling and error reporting
- Add transformRoadmapFromSnakeCase to convert backend snake_case to frontend camelCase
- Transform raw roadmap data before emitting roadmap-complete event
- Add roadmap-error emission for unexpected errors during completion
- Add roadmap-error emission when project path is unavailable
- Remove duplicate ideation-type-complete emission from error handler (event already emitted in loadIdeationType)
- Update error log message
* fix: add future annotations import to discovery.py (#229)
Adds 'from __future__ import annotations' to spec/discovery.py for
Python 3.9+ compatibility with type hints.
This completes the Python compatibility fixes that were partially
applied in previous commits. All 26 analysis and spec Python files
now have the future annotations import.
Related: #128
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* fix: resolve Python detection and backend packaging issues (#241)
* fix: resolve Python detection and backend packaging issues
- Fix backend packaging path (auto-claude -> backend) to match path-resolver.ts expectations
- Add future annotations import to config_parser.py for Python 3.9+ compatibility
- Use findPythonCommand() in project-context-handlers to prioritize Homebrew Python
- Improve Python detection to prefer Homebrew paths over system Python on macOS
This resolves the following issues:
- 'analyzer.py not found' error due to incorrect packaging destination
- TypeError with 'dict | None' syntax on Python < 3.10
- Wrong Python interpreter being used (system Python instead of Homebrew Python 3.10+)
Tested on macOS with packaged app - project index now loads successfully.
* refactor: address PR review feedback
- Extract findHomebrewPython() helper to eliminate code duplication between
findPythonCommand() and getDefaultPythonCommand()
- Remove hardcoded version-specific paths (python3.12) and rely only on
generic Homebrew symlinks for better maintainability
- Remove unnecessary 'from __future__ import annotations' from config_parser.py
since backend requires Python 3.12+ where union types are native
These changes make the code more maintainable, less fragile to Python version
changes, and properly reflect the project's Python 3.12+ requirement.
* Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Revert "Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)" (#251)
This reverts commit 348de6dfe793ab111043677c61b8452bc5ecb2cc.
* feat: add i18n internationalization system (#248)
* Add multilingual support and i18n integration
- Implemented i18n framework using `react-i18next` for translation management.
- Added support for English and French languages with translation files.
- Integrated language selector into settings.
- Updated all text strings in UI components to use translation keys.
- Ensured smooth language switching with live updates.
* Migrate remaining hard-coded strings to i18n system
- TaskCard: status labels, review reasons, badges, action buttons
- PhaseProgressIndicator: execution phases, progress labels
- KanbanBoard: drop zone, show archived, tooltips
- CustomModelModal: dialog title, description, labels
- ProactiveSwapListener: account switch notifications
- AgentProfileSelector: phase labels, custom configuration
- GeneralSettings: agent framework option
Added translation keys for en/fr locales in tasks.json, common.json,
and settings.json for complete i18n coverage.
* Add i18n support to dialogs and settings components
- AddFeatureDialog: form labels, validation messages, buttons
- AddProjectModal: dialog steps, form fields, actions
- RateLimitIndicator: rate limit notifications
- RateLimitModal: account switching, upgrade prompts
- AdvancedSettings: updates and notifications sections
- ThemeSettings: theme selection labels
- Updated dialogs.json locales (en/fr)
* Fix truncated 'ready' message in dialogs locales
* Fix backlog terminology in i18n locales
Change "Planning"/"Planification" to standard PM term "Backlog"
* Migrate settings navigation and integration labels to i18n
- AppSettings: nav items, section titles, buttons
- IntegrationSettings: Claude accounts, auto-switch, API keys labels
- Added settings nav/projectSections/integrations translation keys
- Added buttons.saving to common translations
* Migrate AgentProfileSettings and Sidebar init dialog to i18n
- AgentProfileSettings: migrate phase config labels, section title,
description, and all hardcoded strings to settings namespace
- Sidebar: migrate init dialog strings to dialogs namespace with
common buttons from common namespace
- Add new translation keys for agent profile settings and update dialog
* Migrate AppSettings navigation labels to i18n
- Add useTranslation hook to AppSettings.tsx
- Replace hardcoded section labels with dynamic translations
- Add projectSections translations for project settings nav
- Add rerunWizardDescription translation key
* Add explicit typing to notificationItems array
Import NotificationSettings type and use keyof to properly type
the notification item keys, removing manual type assertion.
* fix: update path resolution for ollama_model_detector.py in memory handlers (#263)
* ci: implement enterprise-grade PR quality gates and security scanning (#266)
* ci: implement enterprise-grade PR quality gates and security scanning
* ci: implement enterprise-grade PR quality gates and security scanning
* fix:pr comments and improve code
* fix: improve commit linting and code quality
* Removed the dependency-review job (i added it)
* fix: address CodeRabbit review comments
- Expand scope pattern to allow uppercase, underscores, slashes, dots
- Add concurrency control to cancel duplicate security scan runs
- Add explanatory comment for Bandit CLI flags
- Remove dependency-review job (requires repo settings)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: update commit lint examples with expanded scope patterns
Show slashes and dots in scope examples to demonstrate
the newly allowed characters (api/users, package.json)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove feature request issue template
Feature requests are directed to GitHub Discussions
via the issue template config.yml
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address security vulnerabilities in service orchestrator
- Fix port parsing crash on malformed docker-compose entries
- Fix shell injection risk by using shlex.split() with shell=False
Prevents crashes when docker-compose.yml contains environment
variables in port mappings (e.g., '${PORT}:8080') and eliminates
shell injection vulnerabilities in subprocess execution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat(github): add automated PR review with follow-up support (#252)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fixes during testing of PR
* feat(github): implement PR merge, assign, and comment features
- Add auto-assignment when clicking "Run AI Review"
- Implement PR merge functionality with squash method
- Add ability to post comments on PRs
- Display assignees in PR UI
- Add Approve and Merge buttons when review passes
- Update backend gh_client with pr_merge, pr_comment, pr_assign methods
- Create IPC handlers for new PR operations
- Update TypeScript interfaces and browser mocks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Improve PR review AI
* fix(github): use temp files for PR review posting to avoid shell escaping issues
When posting PR reviews with findings containing special characters (backticks,
parentheses, quotes), the shell command was interpreting them as commands instead
of literal text, causing syntax errors.
Changed both postPRReview and postPRComment handlers to write the body content
to temporary files and use gh CLI's --body-file flag instead of --body with
inline content. This safely handles ALL special characters without escaping issues.
Fixes shell errors when posting reviews with suggested fixes containing code snippets.
* fix(i18n): add missing GitHub PRs translation and document i18n requirements
Fixed missing translation key for GitHub PRs feature that was causing
"items.githubPRs" to display instead of the proper translated text.
Added comprehensive i18n guidelines to CLAUDE.md to ensure all future
frontend development follows the translation key pattern instead of
using hardcoded strings.
Also fixed missing deletePRReview mock function in browser-mock.ts
to resolve TypeScript compilation errors.
Changes:
- Added githubPRs translation to en/navigation.json
- Added githubPRs translation to fr/navigation.json
- Added Development Guidelines section to CLAUDE.md with i18n requirements
- Documented translation file locations and namespace usage patterns
- Added deletePRReview mock function to browser-mock.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix ui loading
* Github PR fixes
* improve claude.md
* lints/tests
* fix(github): handle PRs exceeding GitHub's 20K line diff limit
- Add PRTooLargeError exception for large PR detection
- Update pr_diff() to catch and raise PRTooLargeError for HTTP 406 errors
- Gracefully handle large PRs by skipping full diff and using individual file patches
- Add diff_truncated flag to PRContext to track when diff was skipped
- Large PRs will now review successfully using per-file diffs instead of failing
Fixes issue with PR #252 which has 100+ files exceeding the 20,000 line limit.
* fix: implement individual file patch fetching for large PRs
The PR review was getting stuck for large PRs (>20K lines) because when we
skipped the full diff due to GitHub API limits, we had no code to analyze.
The individual file patches were also empty, leaving the AI with just
file names and metadata.
Changes:
- Implemented _get_file_patch() to fetch individual patches via git diff
- Updated PR review engine to build composite diff from file patches when
diff_truncated is True
- Added missing 'state' field to PRContext dataclass
- Limits composite diff to first 50 files for very large PRs
- Shows appropriate warnings when using reconstructed diffs
This allows AI review to proceed with actual code analysis even when the
full PR diff exceeds GitHub's limits.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* 1min reduction
* docs: add GitHub Sponsors funding configuration
Enable the Sponsor button on the repository by adding FUNDING.yml
with the AndyMik90 GitHub Sponsors profile.
* feat(github-pr): add orchestrating agent for thorough PR reviews
Implement a new Opus 4.5 orchestrating agent that performs comprehensive
PR reviews regardless of size. Key changes:
- Add orchestrator_reviewer.py with strategic review workflow
- Add review_tools.py with subagent spawning capabilities
- Add pr_orchestrator.md prompt emphasizing thorough analysis
- Add pr_security_agent.md and pr_quality_agent.md subagent prompts
- Integrate orchestrator into pr_review_engine.py with config flag
- Fix critical bug where findings were extracted but not processed
(indentation issue in _parse_orchestrator_output)
The orchestrator now correctly identifies issues in PRs that were
previously approved as "trivial". Testing showed 7 findings detected
vs 0 before the fix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* i18n
* fix(github-pr): restrict pr_reviewer to read-only permissions
The PR review agent was using qa_reviewer agent type which has Bash
access, allowing it to checkout branches and make changes during
review. Created new pr_reviewer agent type with BASE_READ_TOOLS only
(no Bash, no writes, no auto-claude tools).
This prevents the PR review from accidentally modifying code or
switching branches during analysis.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-pr): robust category mapping and JSON parsing for PR review
The orchestrator PR review was failing to extract findings because:
1. AI generates category names like 'correctness', 'consistency', 'testing'
that aren't in our ReviewCategory enum - added flexible mapping
2. JSON sometimes embedded in markdown code blocks (```json) which broke
parsing - added code block extraction as first parsing attempt
Changes:
- Add _CATEGORY_MAPPING dict to map AI categories to valid enum values
- Add _map_category() helper function with fallback to QUALITY
- Add severity parsing with fallback to MEDIUM
- Add markdown code block detection (```json) before raw JSON parsing
- Add _extract_findings_from_data() helper to reduce code duplication
- Apply same fixes to review_tools.py for subagent parsing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(pr-review): improve post findings UX with batch support and feedback
- Fix post findings failing on own PRs by falling back from REQUEST_CHANGES
to COMMENT when GitHub returns 422 error
- Change status badge to show "Reviewed" instead of "Commented" until
findings are actually posted to GitHub
- Add success notification when findings are posted (auto-dismisses after 3s)
- Add batch posting support: track posted findings, show "Posted" badge,
allow posting remaining findings in additional batches
- Show loading state on button while posting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): resolve stale timestamp and null author bugs
- Fix stale timestamp in batch_issues.py: Move updated_at assignment
BEFORE to_dict() serialization so the saved JSON contains the correct
timestamp instead of the old value
- Fix AttributeError in context_gatherer.py: Handle null author/user
fields when GitHub API returns null for deleted/suspended users
instead of an empty object
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high and medium severity PR review findings
HIGH severity fixes:
- Command Injection in autofix-handlers.ts: Use execFileSync with args array
- Command Injection in pr-handlers.ts (3 locations): Use execFileSync + validation
- Command Injection in triage-handlers.ts: Use execFileSync + label validation
- Token Exposure in bot_detection.py: Pass token via GH_TOKEN env var
MEDIUM severity fixes:
- Environment variable leakage in subprocess-runner.ts: Filter to safe vars only
- Debug logging in subprocess-runner.ts: Only log in development mode
- Delimiter escape bypass in sanitize.py: Use regex pattern for variations
- Insecure file permissions in trust.py: Use os.open with 0o600 mode
- No file locking in learning.py: Use FileLock + atomic_write utilities
- Bare except in confidence.py: Log error with specific exception info
- Fragile module import in pr_review_engine.py: Import at module level
- State transition validation in models.py: Enforce can_transition_to()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR followup
* fix(security): add usedforsecurity=False to MD5 hash calls
MD5 is used for generating unique IDs/cache keys, not for security purposes.
Adding usedforsecurity=False resolves Bandit B324 warnings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(ui): add PR status labels to list view
Add secondary status badges to the PR list showing review state at a glance:
- "Changes Requested" (warning) - PRs with blocking issues (critical/high)
- "Ready to Merge" (green) - PRs with only non-blocking suggestions
- "Ready for Follow-up" (blue) - PRs with new commits since last review
The "Ready for Follow-up" badge uses a cached new commits check from the
store, only shown after the detail view confirms new commits via SHA
comparison. This prevents false positives from PR updatedAt timestamp
changes (which can happen from comments, labels, etc).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR labels
* auto-claude: Initialize subtask-based implementation plan
- Workflow type: feature
- Phases: 3
- Subtasks: 6
- Ready for autonomous implementation
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* chore(deps): bump vitest from 4.0.15 to 4.0.16 in /apps/frontend (#272)
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.0.15 to 4.0.16.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/vitest)
---
updated-dependencies:
- dependency-name: vitest
dependency-version: 4.0.16
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps): bump @electron/rebuild in /apps/frontend (#271)
Bumps [@electron/rebuild](https://github.com/electron/rebuild) from 3.7.2 to 4.0.2.
- [Release notes](https://github.com/electron/rebuild/releases)
- [Commits](https://github.com/electron/rebuild/compare/v3.7.2...v4.0.2)
---
updated-dependencies:
- dependency-name: "@electron/rebuild"
dependency-version: 4.0.2
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(paths): normalize relative paths to posix (#239)
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix: accept bug_fix workflow_type alias during planning (#240)
* fix(planning): accept bug_fix workflow_type alias
* style(planning): ruff format
* fix: refatored common logic
* fix: remove ruff errors
* fix: remove duplicate _normalize_workflow_type method
Remove the incorrectly placed duplicate method inside ContextLoader class.
The module-level function is the correct implementation being used.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): use develop branch for dry-run builds in beta-release workflow (#276)
When dry_run=true, the workflow skipped creating the version tag but
build jobs still tried to checkout that non-existent tag, causing all
4 platform builds to fail with "git failed with exit code 1".
Now build jobs checkout develop branch for dry runs while still using
the version tag for real releases.
Closes: GitHub Actions run #20464082726
* chore(deps): bump typescript-eslint in /apps/frontend (#269)
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.49.0 to 8.50.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.50.1/packages/typescript-eslint)
---
updated-dependencies:
- dependency-name: typescript-eslint
dependency-version: 8.50.1
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* chore(deps): bump jsdom from 26.1.0 to 27.3.0 in /apps/frontend (#268)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 26.1.0 to 27.3.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/26.1.0...27.3.0)
---
updated-dependencies:
- dependency-name: jsdom
dependency-version: 27.3.0
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(ci): use correct electron-builder arch flags (#278)
The project switched from pnpm to npm, which handles script argument
passing differently. pnpm adds a -- separator that caused electron-builder
to ignore the --arch argument, but npm passes it directly.
Since --arch is a deprecated electron-builder argument, use the
recommended flags instead:
- --arch=x64 → --x64
- --arch=arm64 → --arm64
This fixes Mac Intel and ARM64 builds failing with "Unknown argument: arch"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): resolve CodeQL file system race conditions and unused variables (#277)
* fix(security): resolve CodeQL file system race conditions and unused variables
Fix high severity CodeQL alerts:
- Remove TOCTOU (time-of-check-time-of-use) race conditions by eliminating
existsSync checks followed by file operations. Use try-catch instead.
- Files affected: pr-handlers.ts, spec-utils.ts
Fix unused variable warnings:
- Remove unused imports (FeatureModelCo…
* feat: Add OpenRouter as LLM/embedding provider (#162)
* feat: Add OpenRouter as LLM/embedding provider
Add OpenRouter provider support for Graphiti memory integration,
enabling access to multiple LLM providers through a single API.
Changes:
Backend:
- Created openrouter_llm.py: OpenRouter LLM provider using OpenAI-compatible API
- Created openrouter_embedder.py: OpenRouter embedder provider
- Updated config.py: Added OpenRouter to provider enums and configuration
- New fields: openrouter_api_key, openrouter_base_url, openrouter_llm_model, openrouter_embedding_model
- Validation methods updated for OpenRouter
- Updated factory.py: Added OpenRouter to LLM and embedder factories
- Updated provider __init__.py files: Exported new OpenRouter functions
Frontend:
- Updated project.ts types: Added 'openrouter' to provider type unions
- GraphitiProviderConfig extended with OpenRouter fields
- Updated GraphitiStep.tsx: Added OpenRouter to provider arrays
- LLM_PROVIDERS: 'Multi-provider aggregator'
- EMBEDDING_PROVIDERS: 'OpenAI-compatible embeddings'
- Added OpenRouter API key input field with show/hide toggle
- Link to https://openrouter.ai/keys
- Updated env-handlers.ts: OpenRouter .env generation and parsing
- Template generation for OPENROUTER_* variables
- Parsing from .env files with proper type casting
Documentation:
- Updated .env.example with OpenRouter section
- Configuration examples
- Popular model recommendations
- Example configuration (#6)
Fixes #92
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* refactor: address CodeRabbit review comments for OpenRouter
- Add globalOpenRouterApiKey to settings types and store updates
- Initialize openrouterApiKey from global settings
- Update documentation to include OpenRouter in provider lists
- Add OpenRouter handling to get_embedding_dimension() method
- Add openrouter to provider cleanup list
- Add OpenRouter to get_available_providers() function
- Clarify Legacy comment for openrouterLlmModel
These changes complete the OpenRouter integration by ensuring proper
settings persistence and provider detection across the application.
* fix: apply ruff formatting to OpenRouter code
- Break long error message across multiple lines
- Format provider list with one item per line
- Fixes lint CI failure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix(core): add global spec numbering lock to prevent collisions (#209)
Implements distributed file-based locking for spec number coordination
across main project and all worktrees. Previously, parallel spec creation
could assign the same number to different specs (e.g., 042-bmad-task and
042-gitlab-integration both using number 042).
The fix adds SpecNumberLock class that:
- Acquires exclusive lock before calculating spec numbers
- Scans ALL locations (main project + worktrees) for global maximum
- Creates spec directories atomically within the lock
- Handles stale locks via PID-based detection with 30s timeout
Applied to both Python backend (spec_runner.py flow) and TypeScript
frontend (ideation conversion, GitHub/GitLab issue import).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Fix/ideation status sync (#212)
* fix(ideation): add missing event forwarders for status sync
- Add event forwarders in ideation-handlers.ts for progress, log,
type-complete, type-failed, complete, error, and stopped events
- Fix ideation-type-complete to load actual ideas array from JSON files
instead of emitting only the count
Resolves UI getting stuck at 0/3 complete during ideation generation.
* fix(ideation): fix UI not updating after actions
- Fix getIdeationSummary to count only active ideas (exclude dismissed/archived)
This ensures header stats match the visible ideas count
- Add transformSessionFromSnakeCase to properly transform session data
from backend snake_case to frontend camelCase on ideation-complete event
- Transform raw session before emitting ideation-complete event
Resolves header showing stale counts after dismissing/deleting ideas.
* fix(ideation): improve type safety and async handling in ideation type completion
- Replace synchronous readFileSync with async fsPromises.readFile in ideation-type-complete handler
- Wrap async file read in IIFE with proper error handling to prevent unhandled promise rejections
- Add type validation for IdeationType with VALID_IDEATION_TYPES set and isValidIdeationType guard
- Add validateEnabledTypes function to filter out invalid type values and log dropped entries
- Handle ENOENT separately
* fix(ideation): improve generation state management and error handling
- Add explicit isGenerating flag to prevent race conditions during async operations
- Implement 5-minute timeout for generation with automatic cleanup and error state
- Add ideation-stopped event emission when process is intentionally killed
- Replace console.warn/error with proper ideation-error events in agent-queue
- Add resetGeneratingTypes helper to transition all generating types to a target state
- Filter out dismissed/
* refactor(ideation): improve event listener cleanup and timeout management
- Extract event handler functions in ideation-handlers.ts to enable proper cleanup
- Return cleanup function from registerIdeationHandlers to remove all listeners
- Replace single generationTimeoutId with Map to support multiple concurrent projects
- Add clearGenerationTimeout helper to centralize timeout cleanup logic
- Extract loadIdeationType IIFE to named function for better error context
- Enhance error logging with projectId,
* refactor: use async file read for ideation and roadmap session loading
- Replace synchronous readFileSync with async fsPromises.readFile
- Prevents blocking the event loop during file operations
- Consistent with async pattern used elsewhere in the codebase
- Improved error handling with proper event emission
* fix(agent-queue): improve roadmap completion handling and error reporting
- Add transformRoadmapFromSnakeCase to convert backend snake_case to frontend camelCase
- Transform raw roadmap data before emitting roadmap-complete event
- Add roadmap-error emission for unexpected errors during completion
- Add roadmap-error emission when project path is unavailable
- Remove duplicate ideation-type-complete emission from error handler (event already emitted in loadIdeationType)
- Update error log message
* fix: add future annotations import to discovery.py (#229)
Adds 'from __future__ import annotations' to spec/discovery.py for
Python 3.9+ compatibility with type hints.
This completes the Python compatibility fixes that were partially
applied in previous commits. All 26 analysis and spec Python files
now have the future annotations import.
Related: #128
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* fix: resolve Python detection and backend packaging issues (#241)
* fix: resolve Python detection and backend packaging issues
- Fix backend packaging path (auto-claude -> backend) to match path-resolver.ts expectations
- Add future annotations import to config_parser.py for Python 3.9+ compatibility
- Use findPythonCommand() in project-context-handlers to prioritize Homebrew Python
- Improve Python detection to prefer Homebrew paths over system Python on macOS
This resolves the following issues:
- 'analyzer.py not found' error due to incorrect packaging destination
- TypeError with 'dict | None' syntax on Python < 3.10
- Wrong Python interpreter being used (system Python instead of Homebrew Python 3.10+)
Tested on macOS with packaged app - project index now loads successfully.
* refactor: address PR review feedback
- Extract findHomebrewPython() helper to eliminate code duplication between
findPythonCommand() and getDefaultPythonCommand()
- Remove hardcoded version-specific paths (python3.12) and rely only on
generic Homebrew symlinks for better maintainability
- Remove unnecessary 'from __future__ import annotations' from config_parser.py
since backend requires Python 3.12+ where union types are native
These changes make the code more maintainable, less fragile to Python version
changes, and properly reflect the project's Python 3.12+ requirement.
* Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Revert "Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)" (#251)
This reverts commit 348de6dfe793ab111043677c61b8452bc5ecb2cc.
* feat: add i18n internationalization system (#248)
* Add multilingual support and i18n integration
- Implemented i18n framework using `react-i18next` for translation management.
- Added support for English and French languages with translation files.
- Integrated language selector into settings.
- Updated all text strings in UI components to use translation keys.
- Ensured smooth language switching with live updates.
* Migrate remaining hard-coded strings to i18n system
- TaskCard: status labels, review reasons, badges, action buttons
- PhaseProgressIndicator: execution phases, progress labels
- KanbanBoard: drop zone, show archived, tooltips
- CustomModelModal: dialog title, description, labels
- ProactiveSwapListener: account switch notifications
- AgentProfileSelector: phase labels, custom configuration
- GeneralSettings: agent framework option
Added translation keys for en/fr locales in tasks.json, common.json,
and settings.json for complete i18n coverage.
* Add i18n support to dialogs and settings components
- AddFeatureDialog: form labels, validation messages, buttons
- AddProjectModal: dialog steps, form fields, actions
- RateLimitIndicator: rate limit notifications
- RateLimitModal: account switching, upgrade prompts
- AdvancedSettings: updates and notifications sections
- ThemeSettings: theme selection labels
- Updated dialogs.json locales (en/fr)
* Fix truncated 'ready' message in dialogs locales
* Fix backlog terminology in i18n locales
Change "Planning"/"Planification" to standard PM term "Backlog"
* Migrate settings navigation and integration labels to i18n
- AppSettings: nav items, section titles, buttons
- IntegrationSettings: Claude accounts, auto-switch, API keys labels
- Added settings nav/projectSections/integrations translation keys
- Added buttons.saving to common translations
* Migrate AgentProfileSettings and Sidebar init dialog to i18n
- AgentProfileSettings: migrate phase config labels, section title,
description, and all hardcoded strings to settings namespace
- Sidebar: migrate init dialog strings to dialogs namespace with
common buttons from common namespace
- Add new translation keys for agent profile settings and update dialog
* Migrate AppSettings navigation labels to i18n
- Add useTranslation hook to AppSettings.tsx
- Replace hardcoded section labels with dynamic translations
- Add projectSections translations for project settings nav
- Add rerunWizardDescription translation key
* Add explicit typing to notificationItems array
Import NotificationSettings type and use keyof to properly type
the notification item keys, removing manual type assertion.
* fix: update path resolution for ollama_model_detector.py in memory handlers (#263)
* ci: implement enterprise-grade PR quality gates and security scanning (#266)
* ci: implement enterprise-grade PR quality gates and security scanning
* ci: implement enterprise-grade PR quality gates and security scanning
* fix:pr comments and improve code
* fix: improve commit linting and code quality
* Removed the dependency-review job (i added it)
* fix: address CodeRabbit review comments
- Expand scope pattern to allow uppercase, underscores, slashes, dots
- Add concurrency control to cancel duplicate security scan runs
- Add explanatory comment for Bandit CLI flags
- Remove dependency-review job (requires repo settings)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: update commit lint examples with expanded scope patterns
Show slashes and dots in scope examples to demonstrate
the newly allowed characters (api/users, package.json)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove feature request issue template
Feature requests are directed to GitHub Discussions
via the issue template config.yml
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address security vulnerabilities in service orchestrator
- Fix port parsing crash on malformed docker-compose entries
- Fix shell injection risk by using shlex.split() with shell=False
Prevents crashes when docker-compose.yml contains environment
variables in port mappings (e.g., '${PORT}:8080') and eliminates
shell injection vulnerabilities in subprocess execution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat(github): add automated PR review with follow-up support (#252)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fixes during testing of PR
* feat(github): implement PR merge, assign, and comment features
- Add auto-assignment when clicking "Run AI Review"
- Implement PR merge functionality with squash method
- Add ability to post comments on PRs
- Display assignees in PR UI
- Add Approve and Merge buttons when review passes
- Update backend gh_client with pr_merge, pr_comment, pr_assign methods
- Create IPC handlers for new PR operations
- Update TypeScript interfaces and browser mocks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Improve PR review AI
* fix(github): use temp files for PR review posting to avoid shell escaping issues
When posting PR reviews with findings containing special characters (backticks,
parentheses, quotes), the shell command was interpreting them as commands instead
of literal text, causing syntax errors.
Changed both postPRReview and postPRComment handlers to write the body content
to temporary files and use gh CLI's --body-file flag instead of --body with
inline content. This safely handles ALL special characters without escaping issues.
Fixes shell errors when posting reviews with suggested fixes containing code snippets.
* fix(i18n): add missing GitHub PRs translation and document i18n requirements
Fixed missing translation key for GitHub PRs feature that was causing
"items.githubPRs" to display instead of the proper translated text.
Added comprehensive i18n guidelines to CLAUDE.md to ensure all future
frontend development follows the translation key pattern instead of
using hardcoded strings.
Also fixed missing deletePRReview mock function in browser-mock.ts
to resolve TypeScript compilation errors.
Changes:
- Added githubPRs translation to en/navigation.json
- Added githubPRs translation to fr/navigation.json
- Added Development Guidelines section to CLAUDE.md with i18n requirements
- Documented translation file locations and namespace usage patterns
- Added deletePRReview mock function to browser-mock.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix ui loading
* Github PR fixes
* improve claude.md
* lints/tests
* fix(github): handle PRs exceeding GitHub's 20K line diff limit
- Add PRTooLargeError exception for large PR detection
- Update pr_diff() to catch and raise PRTooLargeError for HTTP 406 errors
- Gracefully handle large PRs by skipping full diff and using individual file patches
- Add diff_truncated flag to PRContext to track when diff was skipped
- Large PRs will now review successfully using per-file diffs instead of failing
Fixes issue with PR #252 which has 100+ files exceeding the 20,000 line limit.
* fix: implement individual file patch fetching for large PRs
The PR review was getting stuck for large PRs (>20K lines) because when we
skipped the full diff due to GitHub API limits, we had no code to analyze.
The individual file patches were also empty, leaving the AI with just
file names and metadata.
Changes:
- Implemented _get_file_patch() to fetch individual patches via git diff
- Updated PR review engine to build composite diff from file patches when
diff_truncated is True
- Added missing 'state' field to PRContext dataclass
- Limits composite diff to first 50 files for very large PRs
- Shows appropriate warnings when using reconstructed diffs
This allows AI review to proceed with actual code analysis even when the
full PR diff exceeds GitHub's limits.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* 1min reduction
* docs: add GitHub Sponsors funding configuration
Enable the Sponsor button on the repository by adding FUNDING.yml
with the AndyMik90 GitHub Sponsors profile.
* feat(github-pr): add orchestrating agent for thorough PR reviews
Implement a new Opus 4.5 orchestrating agent that performs comprehensive
PR reviews regardless of size. Key changes:
- Add orchestrator_reviewer.py with strategic review workflow
- Add review_tools.py with subagent spawning capabilities
- Add pr_orchestrator.md prompt emphasizing thorough analysis
- Add pr_security_agent.md and pr_quality_agent.md subagent prompts
- Integrate orchestrator into pr_review_engine.py with config flag
- Fix critical bug where findings were extracted but not processed
(indentation issue in _parse_orchestrator_output)
The orchestrator now correctly identifies issues in PRs that were
previously approved as "trivial". Testing showed 7 findings detected
vs 0 before the fix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* i18n
* fix(github-pr): restrict pr_reviewer to read-only permissions
The PR review agent was using qa_reviewer agent type which has Bash
access, allowing it to checkout branches and make changes during
review. Created new pr_reviewer agent type with BASE_READ_TOOLS only
(no Bash, no writes, no auto-claude tools).
This prevents the PR review from accidentally modifying code or
switching branches during analysis.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-pr): robust category mapping and JSON parsing for PR review
The orchestrator PR review was failing to extract findings because:
1. AI generates category names like 'correctness', 'consistency', 'testing'
that aren't in our ReviewCategory enum - added flexible mapping
2. JSON sometimes embedded in markdown code blocks (```json) which broke
parsing - added code block extraction as first parsing attempt
Changes:
- Add _CATEGORY_MAPPING dict to map AI categories to valid enum values
- Add _map_category() helper function with fallback to QUALITY
- Add severity parsing with fallback to MEDIUM
- Add markdown code block detection (```json) before raw JSON parsing
- Add _extract_findings_from_data() helper to reduce code duplication
- Apply same fixes to review_tools.py for subagent parsing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(pr-review): improve post findings UX with batch support and feedback
- Fix post findings failing on own PRs by falling back from REQUEST_CHANGES
to COMMENT when GitHub returns 422 error
- Change status badge to show "Reviewed" instead of "Commented" until
findings are actually posted to GitHub
- Add success notification when findings are posted (auto-dismisses after 3s)
- Add batch posting support: track posted findings, show "Posted" badge,
allow posting remaining findings in additional batches
- Show loading state on button while posting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): resolve stale timestamp and null author bugs
- Fix stale timestamp in batch_issues.py: Move updated_at assignment
BEFORE to_dict() serialization so the saved JSON contains the correct
timestamp instead of the old value
- Fix AttributeError in context_gatherer.py: Handle null author/user
fields when GitHub API returns null for deleted/suspended users
instead of an empty object
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high and medium severity PR review findings
HIGH severity fixes:
- Command Injection in autofix-handlers.ts: Use execFileSync with args array
- Command Injection in pr-handlers.ts (3 locations): Use execFileSync + validation
- Command Injection in triage-handlers.ts: Use execFileSync + label validation
- Token Exposure in bot_detection.py: Pass token via GH_TOKEN env var
MEDIUM severity fixes:
- Environment variable leakage in subprocess-runner.ts: Filter to safe vars only
- Debug logging in subprocess-runner.ts: Only log in development mode
- Delimiter escape bypass in sanitize.py: Use regex pattern for variations
- Insecure file permissions in trust.py: Use os.open with 0o600 mode
- No file locking in learning.py: Use FileLock + atomic_write utilities
- Bare except in confidence.py: Log error with specific exception info
- Fragile module import in pr_review_engine.py: Import at module level
- State transition validation in models.py: Enforce can_transition_to()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR followup
* fix(security): add usedforsecurity=False to MD5 hash calls
MD5 is used for generating unique IDs/cache keys, not for security purposes.
Adding usedforsecurity=False resolves Bandit B324 warnings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(ui): add PR status labels to list view
Add secondary status badges to the PR list showing review state at a glance:
- "Changes Requested" (warning) - PRs with blocking issues (critical/high)
- "Ready to Merge" (green) - PRs with only non-blocking suggestions
- "Ready for Follow-up" (blue) - PRs with new commits since last review
The "Ready for Follow-up" badge uses a cached new commits check from the
store, only shown after the detail view confirms new commits via SHA
comparison. This prevents false positives from PR updatedAt timestamp
changes (which can happen from comments, labels, etc).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR labels
* auto-claude: Initialize subtask-based implementation plan
- Workflow type: feature
- Phases: 3
- Subtasks: 6
- Ready for autonomous implementation
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* chore(deps): bump vitest from 4.0.15 to 4.0.16 in /apps/frontend (#272)
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.0.15 to 4.0.16.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/vitest)
---
updated-dependencies:
- dependency-name: vitest
dependency-version: 4.0.16
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps): bump @electron/rebuild in /apps/frontend (#271)
Bumps [@electron/rebuild](https://github.com/electron/rebuild) from 3.7.2 to 4.0.2.
- [Release notes](https://github.com/electron/rebuild/releases)
- [Commits](https://github.com/electron/rebuild/compare/v3.7.2...v4.0.2)
---
updated-dependencies:
- dependency-name: "@electron/rebuild"
dependency-version: 4.0.2
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(paths): normalize relative paths to posix (#239)
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix: accept bug_fix workflow_type alias during planning (#240)
* fix(planning): accept bug_fix workflow_type alias
* style(planning): ruff format
* fix: refatored common logic
* fix: remove ruff errors
* fix: remove duplicate _normalize_workflow_type method
Remove the incorrectly placed duplicate method inside ContextLoader class.
The module-level function is the correct implementation being used.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): use develop branch for dry-run builds in beta-release workflow (#276)
When dry_run=true, the workflow skipped creating the version tag but
build jobs still tried to checkout that non-existent tag, causing all
4 platform builds to fail with "git failed with exit code 1".
Now build jobs checkout develop branch for dry runs while still using
the version tag for real releases.
Closes: GitHub Actions run #20464082726
* chore(deps): bump typescript-eslint in /apps/frontend (#269)
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.49.0 to 8.50.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.50.1/packages/typescript-eslint)
---
updated-dependencies:
- dependency-name: typescript-eslint
dependency-version: 8.50.1
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* chore(deps): bump jsdom from 26.1.0 to 27.3.0 in /apps/frontend (#268)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 26.1.0 to 27.3.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/26.1.0...27.3.0)
---
updated-dependencies:
- dependency-name: jsdom
dependency-version: 27.3.0
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(ci): use correct electron-builder arch flags (#278)
The project switched from pnpm to npm, which handles script argument
passing differently. pnpm adds a -- separator that caused electron-builder
to ignore the --arch argument, but npm passes it directly.
Since --arch is a deprecated electron-builder argument, use the
recommended flags instead:
- --arch=x64 → --x64
- --arch=arm64 → --arm64
This fixes Mac Intel and ARM64 builds failing with "Unknown argument: arch"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): resolve CodeQL file system race conditions and unused variables (#277)
* fix(security): resolve CodeQL file system race conditions and unused variables
Fix high severity CodeQL alerts:
- Remove TOCTOU (time-of-check-time-of-use) race conditions by eliminating
existsSync checks followed by file operations. Use try-catch instead.
- Files affected: pr-handlers.ts, spec-utils.ts
Fix unused variable warnings:
- Remove unused imports (FeatureModelConfig, FeatureThinkingConfig,
withProjectSyncOrNull, getBackendPath, validateRunner, githubFetch)
- Prefix intentionally unused destructured variables with underscore
- Remove unused local variables (existing, actualEvent)
- Files affected: pr-handlers.ts, autofix-handlers.ts, triage-handlers.ts,
PRDetail.tsx, pr-review-store.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): resolve remaining CodeQL alerts for TOCTOU, network data validation, and unused variables
Address CodeRabbit and CodeQL security alerts from PR #277 review:
- HIGH: Fix 12+ file system race conditions (TOCTOU) by replacing
existsSync() checks with try/catch blocks in pr-handlers.ts,
autofix-handlers.ts, triage-handlers.ts, and spec-utils.ts
- MEDIUM: Add sanitizeNetworkData() function to validate/sanitize
GitHub API data before writing to disk, preventing injection attacks
- Clean up 20+ unused variables, imports, and useless assignments
across frontend components and handlers
- Fix Python Protocol typing in testing.py (add return type annotations)
All changes verified with TypeScript compilation and ESLint (no errors).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): resolve follow-up review API issues
- Fix gh_client.py: use query string syntax for `since` parameter instead
of `-f` flag which sends POST body fields, causing GitHub API errors
- Fix followup_reviewer.py: use raw Anthropic client for message API calls
instead of ClaudeSDKClient which is for agent sessions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(deps): bump @xterm/xterm from 5.5.0 to 6.0.0 in /apps/frontend (#270)
* chore(deps): bump @xterm/xterm from 5.5.0 to 6.0.0 in /apps/frontend
Bumps [@xterm/xterm](https://github.com/xtermjs/xterm.js) from 5.5.0 to 6.0.0.
- [Release notes](https://github.com/xtermjs/xterm.js/releases)
- [Commits](https://github.com/xtermjs/xterm.js/compare/5.5.0...6.0.0)
---
updated-dependencies:
- dependency-name: "@xterm/xterm"
dependency-version: 6.0.0
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* fix(deps): update xterm addons for 6.0.0 compatibility and use public APIs
CRITICAL: Updated all xterm addons to versions compatible with xterm 6.0.0:
- @xterm/addon-fit: ^0.10.0 → ^0.11.0
- @xterm/addon-serialize: ^0.13.0 → ^0.14.0
- @xterm/addon-web-links: ^0.11.0 → ^0.12.0
- @xterm/addon-webgl: ^0.18.0 → ^0.19.0
HIGH: Refactored scroll-controller.ts to use public xterm APIs:
- Replaced internal _core access with public buffer/scroll APIs
- Uses onScroll and onWriteParsed events for scroll tracking
- Uses scrollLines() for scroll position restoration
- Proper IDisposable cleanup for event listeners
- Falls back gracefully if onWriteParsed is not available
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): add write permissions to beta-release update-version job
The update-version job needs contents: write permission to push the
version bump commit and tag to the repository. Without this, the
workflow fails with a 403 error when trying to git push.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: resolve spawn python ENOENT error on Linux by using getAugmentedEnv() (#281)
- Use getAugmentedEnv() in project-context-handlers.ts to ensure Python is in PATH
- Add /usr/bin and /usr/sbin to Linux paths in env-utils.ts for system Python
- Fixes GUI-launched apps not inheriting shell environment on Ubuntu 24.04
Fixes #215
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* feat(python): bundle Python 3.12 with packaged Electron app (#284)
* feat(python): bundle Python 3.12 with packaged Electron app
Resolves issue #258 where users with Python aliases couldn't run the app
because shell aliases aren't visible to Electron's subprocess calls.
Changes:
- Add download-python.cjs script to fetch python-build-standalone
- Bundle Python 3.12.8 in extraResources for packaged apps
- Update python-detector.ts to prioritize bundled Python
- Add Python caching to CI workflows for faster builds
Packaged apps now include Python (~35MB), eliminating the need for users
to have Python installed. Dev mode still falls back to system Python.
Closes #258
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address PR review feedback for Python bundling
Security improvements:
- Add SHA256 checksum verification for downloaded Python binaries
- Replace execSync with spawnSync to prevent command injection
- Add input validation to prevent log injection from CLI args
- Add download timeout (5 minutes) and redirect limit (10)
- Proper file/connection cleanup on errors
Bug fixes:
- Fix platform naming mismatch: use "mac"/"win" (electron-builder)
instead of "darwin"/"win32" (Node.js) for output directories
- Handle empty path edge case in parsePythonCommand
Improvements:
- Add restore-keys to CI cache steps for better cache hit rates
- Improve error messages and logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix mac node.js naming
* security: add SHA256 checksums for all Python platforms
Fetched actual checksums from python-build-standalone release:
- darwin-arm64: abe1de24...
- darwin-x64: 867c1af1...
- win32-x64: 1a702b34...
- linux-x64: 698e53b2...
- linux-arm64: fb983ec8...
All platforms now have cryptographic verification for downloaded
Python binaries, eliminating the supply chain risk.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: add python-runtime to root .gitignore
Ensures bundled Python runtime is ignored from both root and
frontend .gitignore files.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(frontend): validate backend source path before using it (#287)
* fix(frontend): validate backend source path before using it
The path resolver was returning invalid autoBuildPath settings without
validating they contained the required backend files. When settings
pointed to a legacy /auto-claude/ directory (missing requirements.txt
and analyzer.py), the project indexer would fail with "can't open file"
errors.
Now validates that all source paths contain requirements.txt before
returning them, falling back to bundled source path detection when
the configured path is invalid.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* auto-claude: Initialize subtask-based implementation plan
- Workflow type: feature
- Phases: 4
- Subtasks: 9
- Ready for autonomous implementation
Parallel execution enabled: phases 1 and 2 can run simultaneously
* auto-claude: Initialize subtask-based implementation plan
- Workflow type: investigation
- Phases: 5
- Subtasks: 13
- Ready for autonomous implementation
* fix merge conflict check loop
* fix(frontend): add warning when fallback path is also invalid
Address CodeRabbit review feedback - the fallback path in
getBundledSourcePath() was returning an unvalidated path which could
still cause the same analyzer.py error. Now logs a warning when the
fallback path also lacks requirements.txt.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Potential fix for code scanning alert no. 224: Uncontrolled command line (#285)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix(frontend): support archiving tasks across all worktree locations (#286)
* archive across all worktress and if not in folder
* fix(frontend): address PR security and race condition issues
- Add taskId validation to prevent path traversal attacks
- Fix TOCTOU race conditions in archiveTasks by removing existsSync
- Fix TOCTOU race conditions in unarchiveTasks by removing existsSync
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): add explicit GET method to gh api comment fetches (#294)
The gh api command defaults to POST for comment endpoints, causing
GitHub to reject the 'since' query parameter as an invalid POST body
field. Adding --method GET explicitly forces a GET request, allowing
the since parameter to work correctly for fetching comments.
This completes the fix started in f1cc5a09 which only changed from
-f flag to query string syntax but didn't address the HTTP method.
* feat: enhance the logs for the commit linting stage (#293)
* ci: implement enterprise-grade PR quality gates and security scanning
* ci: implement enterprise-grade PR quality gates and security scanning
* fix:pr comments and improve code
* fix: improve commit linting and code quality
* Removed the dependency-review job (i added it)
* fix: address CodeRabbit review comments
- Expand scope pattern to allow uppercase, underscores, slashes, dots
- Add concurrency control to cancel duplicate security scan runs
- Add explanatory comment for Bandit CLI flags
- Remove dependency-review job (requires repo settings)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: update commit lint examples with expanded scope patterns
Show slashes and dots in scope examples to demonstrate
the newly allowed characters (api/users, package.json)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove feature request issue template
Feature requests are directed to GitHub Discussions
via the issue template config.yml
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address security vulnerabilities in service orchestrator
- Fix port parsing crash on malformed docker-compose entries
- Fix shell injection risk by using shlex.split() with shell=False
Prevents crashes when docker-compose.yml contains environment
variables in port mappings (e.g., '${PORT}:8080') and eliminates
shell injection vulnerabilities in subprocess execution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix(ci): improve PR title validation error messages with examples
Add helpful console output when PR title validation fails:
- Show expected format and valid types
- Provide examples of valid PR titles
- Display the user's current title
- Suggest fixes based on keywords in the title
- Handle verb variations (fixed, adding, updated, etc.)
- Show placeholder when description is empty after cleanup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* lower coverage
* feat: improve status gate to label correctly based on required checks
* fix(ci): address PR review findings for security and efficiency
- Add explicit permissions block to ci.yml (least privilege principle)
- Skip duplicate test run for Python 3.12 (tests with coverage only)
- Sanitize PR title in markdown output to prevent injection
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix typo
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat(merge,oauth): add path-aware AI merge resolution and device code streaming (#296)
* improve/merge-confclit-layer
* improve AI resolution
* fix caching on merge conflicts
* imrpove merge layer with rebase
* fix(github): add OAuth authentication to follow-up PR review
The follow-up PR review AI analysis was failing with "Could not resolve
authentication method" because AsyncAnthropic() was instantiated without
credentials. The codebase uses OAuth tokens (not ANTHROPIC_API_KEY), so
the client needs the auth_token parameter.
Uses get_auth_token() from core.auth to retrieve the OAuth token from
environment variables or macOS Keychain, matching how initial reviews
authenticate via create_client().
* fix(merge): add validation to prevent AI writing natural language to files
When AI merge receives truncated file contents (due to character limits),
it sometimes responds with explanations like "I need to see the complete
file contents..." instead of actual merged code. This garbage was being
written directly to source files.
Adds two validation layers after AI merge:
1. Natural language detection - catches patterns like "I need to", "Let me"
2. Syntax validation - uses esbuild to verify TypeScript/JavaScript syntax
If either validation fails, the merge returns an error instead of writing
invalid content to the file.
Also adds project_dir field to ParallelMergeTask to enable syntax validation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(merge): skip git merge when AI already resolved path-mapped files
When AI successfully merges path-mapped files (due to file renames
between branches), the check only looked at `conflicts_resolved` which
was 0 for path-mapped cases. This caused the code to fall through to
`git merge` which then failed with conflicts.
Now also checks `files_merged` and `ai_assisted` stats to determine
if AI has already handled the merge. When files are AI-merged, they're
already written and staged - no need for git merge.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix device code issue with github
* fix(frontend): remember GitHub auth method (OAuth vs PAT) in settings
Previously, after authenticating via GitHub OAuth, the settings page
would show "Personal Access Token" input even though OAuth was used.
This was confusing for users who expected to see their OAuth status.
Added githubAuthMethod field to track how authentication was performed.
Settings UI now shows "Authenticated via GitHub OAuth" when OAuth was
used, with option to switch to manual token if needed. The auth method
persists across settings reopening.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(backend): centralize OAuth client creation in core/client.py
- Add create_message_client() for simple message API calls
- Refactor followup_reviewer.py to use centralized client factory
- Remove direct anthropic.AsyncAnthropic import from followup_reviewer
- Add proper ValueError handling for missing OAuth token
- Update docstrings to document both client factories
This ensures all AI interactions use the centralized OAuth authentication
in core/, avoiding direct ANTHROPIC_API_KEY usage per CLAUDE.md guidelines.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(frontend): remove unused statusColor variable in WorkspaceStatus
Dead code cleanup - the statusColor variable was computed but never
used in the component.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(tests): add BrowserWindow mock to oauth-handlers tests
The sendDeviceCodeToRenderer function uses BrowserWindow.getAllWindows()
which wasn't mocked, causing unhandled rejection errors in tests.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(backend): use ClaudeSDKClient instead of raw anthropic SDK
Remove direct anthropic SDK import from core/client.py and update
followup_reviewer.py to use ClaudeSDKClient directly as per project
conventions. All AI interactions should use claude-agent-sdk.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(backend): add debug logging for AI response in followup_reviewer
Add logging to diagnose why AI review returns no JSON - helps identify
if response is in thinking blocks vs text blocks.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Fix/2.7.2 fixes (#300)
* fix(frontend): prevent false stuck detection for ai_review tasks
Tasks in ai_review status were incorrectly showing "Task Appears Stuck"
in the detail modal. This happened because the isRunning check included
ai_review status, triggering stuck detection when no process was found.
However, ai_review means "all subtasks completed, awaiting QA" - no build
process is expected to be running. This aligns the detail modal logic with
TaskCard which correctly only checks for in_progress status.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* ci(beta-release): use tag-based versioning instead of modifying package.json
Previously the beta-release workflow committed version changes to package.json
on the develop branch, which caused two issues:
1. Permission errors (github-actions[bot] denied push access)
2. Beta versions polluted develop, making merges to main unclean
Now the workflow creates only a git tag and injects the version at build time
using electron-builder's --config.extraMetadata.version flag. This keeps
package.json at the next stable version and avoids any commits to develop.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ollama): add packaged app path resolution for Ollama detector script
The Ollama detection was failing in packaged builds because the
Python script path resolution only checked development paths.
In packaged apps, __dirname points to the app bundle, and the
relative path "../../../backend" doesn't resolve correctly.
Added process.resourcesPath for packaged builds (checked first via
app.isPackaged) which correctly locates the backend scripts in
the Resources folder. Also added DEBUG-only logging to help
troubleshoot script location issues.
Closes #129
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(paths): remove legacy auto-claude path fallbacks
Replace all legacy 'auto-claude/' source path detection with 'apps/backend'.
Services now validate paths using runners/spec_runner.py as the marker
instead of requirements.txt, ensuring only valid backend directories match.
- Remove legacy fallback paths from all getAutoBuildSourcePath() implementations
- Add startup validation in index.ts to skip invalid saved paths
- Update project-initializer to detect apps/backend for local dev projects
- Standardize path detection across all services
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(frontend): address PR review feedback from Auto Claude and bots
Fixes from PR #300 reviews:
CRITICAL:
- path-resolver.ts: Update marker from requirements.txt to runners/spec_runner.py
for consistent backend detection across all files
HIGH:
- useTaskDetail.ts: Restore stuck task detection for ai_review status
(CHANGELOG documents this feature)
- TerminalGrid.tsx: Include legacy terminals without projectPath
(prevents hiding terminals after upgrade)
- memory-handlers.ts: Add packaged app path in OLLAMA_PULL_MODEL handler
(fixes production builds)
MEDIUM:
- OAuthStep.tsx: Stricter profile slug sanitization
(only allow alphanumeric and dashes)
- project-store.ts: Fix regex to not truncate at # in code blocks
(uses \n#{1,6}\s to match valid markdown headings only)
- memory-service.ts: Add backend structure validation with spec_runner.py marker
- subprocess-spawn.test.ts: Update test to use new marker pattern
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(frontend): validate empty profile slug after sanitization
Add validation to prevent empty config directory path when profile name
contains only special characters (e.g., "!!!"). Shows user-friendly error
message requiring at least one letter or number.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix: stop tracking spec files in git (#295)
* fix: stop tracking spec files in git
- Remove git commit instructions from planner.md for spec files
- Spec files (implementation_plan.json, init.sh, build-progress.txt) should be gitignored
- Untrack existing spec files that were accidentally committed
- AI agents should only commit code changes, not spec metadata
The .auto-claude/specs/ directory is gitignored by design - spec files are
local project metadata that shouldn't be version controlled.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(prompts): remove git commit instructions for gitignored spec files
The spec files (build-progress.txt, qa_report.md, implementation_plan.json,
QA_FIX_REQUEST.md) are all stored in .auto-claude/specs/ which is gitignored.
Removed instructions telling agents to commit these files, replaced with
notes explaining they're tracked automatically by the framework.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(build): add --force-local flag to tar on Windows (#303)
On Windows, paths like D:\path are misinterpreted by tar as remote
host:path syntax (Unix tar convention). Adding --force-local tells
tar to treat colons as part of the filename, fixing the extraction
failure in GitHub Actions Windows builds.
Error was: "tar (child): Cannot connect to D: resolve failed"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(build): use PowerShell for tar extraction on Windows
The previous fix using --force-local and path conversion still failed
due to shell escaping issues. PowerShell handles Windows paths natively
and has built-in tar support on Windows 10+, avoiding all path escaping
problems.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): add augmented PATH env to all gh CLI calls
When running from a packaged macOS app (.dmg), the PATH environment
variable doesn't include common locations like /opt/homebrew/bin where
gh is typically installed via Homebrew.
The getAugmentedEnv() function was already being used in some places
but was missing from:
- spawn() call in registerStartGhAuth
- execSync calls for gh auth token, gh api user, gh repo list
- execFileSync calls for gh api, gh repo create
- execFileSync calls in pr-handlers.ts and triage-handlers.ts
This caused "gh: command not found" errors when connecting projects
to GitHub in the packaged app.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(build): use explicit Windows System32 tar path (#308)
The previous PowerShell fix still found Git Bash's /usr/bin/tar which
interprets D: as a remote host. Using the explicit path to Windows'
built-in bsdtar (C:\Windows\System32\tar.exe) avoids this issue.
Windows Server 2019+ (GitHub Actions) has bsdtar in System32.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* chore(ci): cancel in-progress runs (#302)
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
Co-authored-by: Alex <63423455+AlexMadera@users.noreply.github.com>
* fix(python): use venv Python for all services to fix dotenv errors (#311)
* fix(python): use venv Python for all services to fix dotenv errors
Services were spawning Python processes using findPythonCommand() which
returns the bundled Python directly. However, dependencies like python-dotenv
are only installed in the venv created from the bundled Python.
Changes:
- Add getConfiguredPythonPath() helper that returns venv Python when ready
- Update all services to use venv Python instead of bundled Python directly:
- memory-service.ts
- memory-handlers.ts
- agent-process.ts
- changelog-service.ts
- title-generator.ts
- insights/config.ts
- project-context-handlers.ts
- worktree-handlers.ts
- Fix availability checks to use findPythonCommand() (can return null)
- Add python:verify script for bundling verification
The flow now works correctly:
1. App starts → findPythonCommand() finds bundled Python
2. pythonEnvManager creates venv using bundled Python
3. pip installs dependencies (dotenv, claude-agent-sdk, etc.)
4. All services use venv Python → has all dependencies
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix lintin and test
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix(updater): proper semver comparison for pre-release versions (#313)
Fixes the beta auto-update bug where the app was offering downgrades
(e.g., showing v2.7.1 as "new version available" when on v2.7.2-beta.6).
Changes:
- version-manager.ts: New parseVersion() function that separates base
version from pre-release suffix. Updated compareVersions() to handle
pre-release versions correctly (alpha < beta < rc < stable).
- app-updater.ts: Import and use compareVersions() for proper version
comparison instead of simple string inequality.
- Added comprehensive unit tests for version comparison logic.
Pre-release ordering:
- 2.7.1 < 2.7.2-alpha.1 < 2.7.2-beta.1 < 2.7.2-rc.1 < 2.7.2 (stable)
- 2.7.2-beta.6 < 2.7.2-beta.7
* fix(project): fix task status persistence reverting on refresh (#246) (#318)
Correctly validate persisted task status against calculated status.
Previously, if a task was 'in_progress' but had no active subtasks (e.g. still in planning or between phases),
the calculated status 'backlog' would override the stored status, causing the UI to revert to 'Start'.
This fix adds 'in_progress' to the list of active process statuses and explicitly allows 'in_progress' status
to persist when the underlying plan status is also 'in_progress'.
* fix(ci): add auto-updater manifest files and version auto-update (#317)
Combined PR with:
1. Alex's version auto-update changes from PR #316
2. Auto-updater manifest file generation fix
Changes:
- Add --publish never to package scripts to generate .yml manifests
- Update all build jobs to upload .yml files as artifacts
- Update release step to include .yml files in GitHub release
- Auto-bump version in package.json files before tagging
This enables the in-app auto-updater to work properly by ensuring
latest-mac.yml, latest-linux.yml, and latest.yml are published
with each release.
Co-authored-by: Alex <63423455+AlexMadera@users.noreply.github.com>
* f…
…ik90#1038) * feat: Add OpenRouter as LLM/embedding provider (#162) * feat: Add OpenRouter as LLM/embedding provider Add OpenRouter provider support for Graphiti memory integration, enabling access to multiple LLM providers through a single API. Changes: Backend: - Created openrouter_llm.py: OpenRouter LLM provider using OpenAI-compatible API - Created openrouter_embedder.py: OpenRouter embedder provider - Updated config.py: Added OpenRouter to provider enums and configuration - New fields: openrouter_api_key, openrouter_base_url, openrouter_llm_model, openrouter_embedding_model - Validation methods updated for OpenRouter - Updated factory.py: Added OpenRouter to LLM and embedder factories - Updated provider __init__.py files: Exported new OpenRouter functions Frontend: - Updated project.ts types: Added 'openrouter' to provider type unions - GraphitiProviderConfig extended with OpenRouter fields - Updated GraphitiStep.tsx: Added OpenRouter to provider arrays - LLM_PROVIDERS: 'Multi-provider aggregator' - EMBEDDING_PROVIDERS: 'OpenAI-compatible embeddings' - Added OpenRouter API key input field with show/hide toggle - Link to https://openrouter.ai/keys - Updated env-handlers.ts: OpenRouter .env generation and parsing - Template generation for OPENROUTER_* variables - Parsing from .env files with proper type casting Documentation: - Updated .env.example with OpenRouter section - Configuration examples - Popular model recommendations - Example configuration (#6) Fixes #92 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor: address CodeRabbit review comments for OpenRouter - Add globalOpenRouterApiKey to settings types and store updates - Initialize openrouterApiKey from global settings - Update documentation to include OpenRouter in provider lists - Add OpenRouter handling to get_embedding_dimension() method - Add openrouter to provider cleanup list - Add OpenRouter to get_available_providers() function - Clarify Legacy comment for openrouterLlmModel These changes complete the OpenRouter integration by ensuring proper settings persistence and provider detection across the application. * fix: apply ruff formatting to OpenRouter code - Break long error message across multiple lines - Format provider list with one item per line - Fixes lint CI failure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(core): add global spec numbering lock to prevent collisions (#209) Implements distributed file-based locking for spec number coordination across main project and all worktrees. Previously, parallel spec creation could assign the same number to different specs (e.g., 042-bmad-task and 042-gitlab-integration both using number 042). The fix adds SpecNumberLock class that: - Acquires exclusive lock before calculating spec numbers - Scans ALL locations (main project + worktrees) for global maximum - Creates spec directories atomically within the lock - Handles stale locks via PID-based detection with 30s timeout Applied to both Python backend (spec_runner.py flow) and TypeScript frontend (ideation conversion, GitHub/GitLab issue import). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Fix/ideation status sync (#212) * fix(ideation): add missing event forwarders for status sync - Add event forwarders in ideation-handlers.ts for progress, log, type-complete, type-failed, complete, error, and stopped events - Fix ideation-type-complete to load actual ideas array from JSON files instead of emitting only the count Resolves UI getting stuck at 0/3 complete during ideation generation. * fix(ideation): fix UI not updating after actions - Fix getIdeationSummary to count only active ideas (exclude dismissed/archived) This ensures header stats match the visible ideas count - Add transformSessionFromSnakeCase to properly transform session data from backend snake_case to frontend camelCase on ideation-complete event - Transform raw session before emitting ideation-complete event Resolves header showing stale counts after dismissing/deleting ideas. * fix(ideation): improve type safety and async handling in ideation type completion - Replace synchronous readFileSync with async fsPromises.readFile in ideation-type-complete handler - Wrap async file read in IIFE with proper error handling to prevent unhandled promise rejections - Add type validation for IdeationType with VALID_IDEATION_TYPES set and isValidIdeationType guard - Add validateEnabledTypes function to filter out invalid type values and log dropped entries - Handle ENOENT separately * fix(ideation): improve generation state management and error handling - Add explicit isGenerating flag to prevent race conditions during async operations - Implement 5-minute timeout for generation with automatic cleanup and error state - Add ideation-stopped event emission when process is intentionally killed - Replace console.warn/error with proper ideation-error events in agent-queue - Add resetGeneratingTypes helper to transition all generating types to a target state - Filter out dismissed/ * refactor(ideation): improve event listener cleanup and timeout management - Extract event handler functions in ideation-handlers.ts to enable proper cleanup - Return cleanup function from registerIdeationHandlers to remove all listeners - Replace single generationTimeoutId with Map to support multiple concurrent projects - Add clearGenerationTimeout helper to centralize timeout cleanup logic - Extract loadIdeationType IIFE to named function for better error context - Enhance error logging with projectId, * refactor: use async file read for ideation and roadmap session loading - Replace synchronous readFileSync with async fsPromises.readFile - Prevents blocking the event loop during file operations - Consistent with async pattern used elsewhere in the codebase - Improved error handling with proper event emission * fix(agent-queue): improve roadmap completion handling and error reporting - Add transformRoadmapFromSnakeCase to convert backend snake_case to frontend camelCase - Transform raw roadmap data before emitting roadmap-complete event - Add roadmap-error emission for unexpected errors during completion - Add roadmap-error emission when project path is unavailable - Remove duplicate ideation-type-complete emission from error handler (event already emitted in loadIdeationType) - Update error log message * fix: add future annotations import to discovery.py (#229) Adds 'from __future__ import annotations' to spec/discovery.py for Python 3.9+ compatibility with type hints. This completes the Python compatibility fixes that were partially applied in previous commits. All 26 analysis and spec Python files now have the future annotations import. Related: #128 Co-authored-by: Joris Slagter <mail@jorisslagter.nl> * fix: resolve Python detection and backend packaging issues (#241) * fix: resolve Python detection and backend packaging issues - Fix backend packaging path (auto-claude -> backend) to match path-resolver.ts expectations - Add future annotations import to config_parser.py for Python 3.9+ compatibility - Use findPythonCommand() in project-context-handlers to prioritize Homebrew Python - Improve Python detection to prefer Homebrew paths over system Python on macOS This resolves the following issues: - 'analyzer.py not found' error due to incorrect packaging destination - TypeError with 'dict | None' syntax on Python < 3.10 - Wrong Python interpreter being used (system Python instead of Homebrew Python 3.10+) Tested on macOS with packaged app - project index now loads successfully. * refactor: address PR review feedback - Extract findHomebrewPython() helper to eliminate code duplication between findPythonCommand() and getDefaultPythonCommand() - Remove hardcoded version-specific paths (python3.12) and rely only on generic Homebrew symlinks for better maintainability - Remove unnecessary 'from __future__ import annotations' from config_parser.py since backend requires Python 3.12+ where union types are native These changes make the code more maintainable, less fragile to Python version changes, and properly reflect the project's Python 3.12+ requirement. * Feat/Auto Fix Github issues and do extensive AI PR reviews (#250) * feat(github): add GitHub automation system for issues and PRs Implements comprehensive GitHub automation with three major components: 1. Issue Auto-Fix: Automatically creates specs from labeled issues - AutoFixButton component with progress tracking - useAutoFix hook for config and queue management - Backend handlers for spec creation from issues 2. GitHub PRs Tool: AI-powered PR review sidebar - New sidebar tab (Cmd+Shift+P) alongside GitHub Issues - PRList/PRDetail components for viewing PRs - Review system with findings by severity - Post review comments to GitHub 3. Issue Triage: Duplicate/spam/feature-creep detection - Triage handlers with label application - Configurable detection thresholds Also adds: - Debug logging (DEBUG=true) for all GitHub handlers - Backend runners/github module with orchestrator - AI prompts for PR review, triage, duplicate/spam detection - dev:debug npm script for development with logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github-runner): resolve import errors for direct script execution Changes runner.py and orchestrator.py to handle both: - Package import: `from runners.github import ...` - Direct script: `python runners/github/runner.py` Uses try/except pattern for relative vs direct imports. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): correct argparse argument order for runner.py Move --project global argument before subcommand so argparse can correctly parse it. Fixes "unrecognized arguments: --project" error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * logs when debug mode is on * refactor(github): extract service layer and fix linting errors Major refactoring to improve maintainability and code quality: Backend (Python): - Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules: - prompt_manager.py: Prompt template management - response_parsers.py: AI response parsing - pr_review_engine.py: PR review orchestration - triage_engine.py: Issue triage logic - autofix_processor.py: Auto-fix workflow - batch_processor.py: Batch issue handling - Fixed 18 ruff linting errors (F401, C405, C414, E741): - Removed unused imports (BatchValidationResult, AuditAction, locked_json_write) - Optimized collection literals (set([n]) → {n}) - Removed unnecessary list() calls - Renamed ambiguous variable 'l' to 'label' throughout Frontend (TypeScript): - Refactored IPC handlers (19% overall reduction) with shared utilities: - autofix-handlers.ts: 1,042 → 818 lines - pr-handlers.ts: 648 → 543 lines - triage-handlers.ts: 437 lines (no duplication) - Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner - Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status - Split ReviewFindings.tsx into focused components All imports verified, type checks passing, linting clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Revert "Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)" (#251) This reverts commit 348de6dfe793ab111043677c61b8452bc5ecb2cc. * feat: add i18n internationalization system (#248) * Add multilingual support and i18n integration - Implemented i18n framework using `react-i18next` for translation management. - Added support for English and French languages with translation files. - Integrated language selector into settings. - Updated all text strings in UI components to use translation keys. - Ensured smooth language switching with live updates. * Migrate remaining hard-coded strings to i18n system - TaskCard: status labels, review reasons, badges, action buttons - PhaseProgressIndicator: execution phases, progress labels - KanbanBoard: drop zone, show archived, tooltips - CustomModelModal: dialog title, description, labels - ProactiveSwapListener: account switch notifications - AgentProfileSelector: phase labels, custom configuration - GeneralSettings: agent framework option Added translation keys for en/fr locales in tasks.json, common.json, and settings.json for complete i18n coverage. * Add i18n support to dialogs and settings components - AddFeatureDialog: form labels, validation messages, buttons - AddProjectModal: dialog steps, form fields, actions - RateLimitIndicator: rate limit notifications - RateLimitModal: account switching, upgrade prompts - AdvancedSettings: updates and notifications sections - ThemeSettings: theme selection labels - Updated dialogs.json locales (en/fr) * Fix truncated 'ready' message in dialogs locales * Fix backlog terminology in i18n locales Change "Planning"/"Planification" to standard PM term "Backlog" * Migrate settings navigation and integration labels to i18n - AppSettings: nav items, section titles, buttons - IntegrationSettings: Claude accounts, auto-switch, API keys labels - Added settings nav/projectSections/integrations translation keys - Added buttons.saving to common translations * Migrate AgentProfileSettings and Sidebar init dialog to i18n - AgentProfileSettings: migrate phase config labels, section title, description, and all hardcoded strings to settings namespace - Sidebar: migrate init dialog strings to dialogs namespace with common buttons from common namespace - Add new translation keys for agent profile settings and update dialog * Migrate AppSettings navigation labels to i18n - Add useTranslation hook to AppSettings.tsx - Replace hardcoded section labels with dynamic translations - Add projectSections translations for project settings nav - Add rerunWizardDescription translation key * Add explicit typing to notificationItems array Import NotificationSettings type and use keyof to properly type the notification item keys, removing manual type assertion. * fix: update path resolution for ollama_model_detector.py in memory handlers (#263) * ci: implement enterprise-grade PR quality gates and security scanning (#266) * ci: implement enterprise-grade PR quality gates and security scanning * ci: implement enterprise-grade PR quality gates and security scanning * fix:pr comments and improve code * fix: improve commit linting and code quality * Removed the dependency-review job (i added it) * fix: address CodeRabbit review comments - Expand scope pattern to allow uppercase, underscores, slashes, dots - Add concurrency control to cancel duplicate security scan runs - Add explanatory comment for Bandit CLI flags - Remove dependency-review job (requires repo settings) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: update commit lint examples with expanded scope patterns Show slashes and dots in scope examples to demonstrate the newly allowed characters (api/users, package.json) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: remove feature request issue template Feature requests are directed to GitHub Discussions via the issue template config.yml 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address security vulnerabilities in service orchestrator - Fix port parsing crash on malformed docker-compose entries - Fix shell injection risk by using shlex.split() with shell=False Prevents crashes when docker-compose.yml contains environment variables in port mappings (e.g., '${PORT}:8080') and eliminates shell injection vulnerabilities in subprocess execution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * feat(github): add automated PR review with follow-up support (#252) * feat(github): add GitHub automation system for issues and PRs Implements comprehensive GitHub automation with three major components: 1. Issue Auto-Fix: Automatically creates specs from labeled issues - AutoFixButton component with progress tracking - useAutoFix hook for config and queue management - Backend handlers for spec creation from issues 2. GitHub PRs Tool: AI-powered PR review sidebar - New sidebar tab (Cmd+Shift+P) alongside GitHub Issues - PRList/PRDetail components for viewing PRs - Review system with findings by severity - Post review comments to GitHub 3. Issue Triage: Duplicate/spam/feature-creep detection - Triage handlers with label application - Configurable detection thresholds Also adds: - Debug logging (DEBUG=true) for all GitHub handlers - Backend runners/github module with orchestrator - AI prompts for PR review, triage, duplicate/spam detection - dev:debug npm script for development with logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github-runner): resolve import errors for direct script execution Changes runner.py and orchestrator.py to handle both: - Package import: `from runners.github import ...` - Direct script: `python runners/github/runner.py` Uses try/except pattern for relative vs direct imports. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): correct argparse argument order for runner.py Move --project global argument before subcommand so argparse can correctly parse it. Fixes "unrecognized arguments: --project" error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * logs when debug mode is on * refactor(github): extract service layer and fix linting errors Major refactoring to improve maintainability and code quality: Backend (Python): - Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules: - prompt_manager.py: Prompt template management - response_parsers.py: AI response parsing - pr_review_engine.py: PR review orchestration - triage_engine.py: Issue triage logic - autofix_processor.py: Auto-fix workflow - batch_processor.py: Batch issue handling - Fixed 18 ruff linting errors (F401, C405, C414, E741): - Removed unused imports (BatchValidationResult, AuditAction, locked_json_write) - Optimized collection literals (set([n]) → {n}) - Removed unnecessary list() calls - Renamed ambiguous variable 'l' to 'label' throughout Frontend (TypeScript): - Refactored IPC handlers (19% overall reduction) with shared utilities: - autofix-handlers.ts: 1,042 → 818 lines - pr-handlers.ts: 648 → 543 lines - triage-handlers.ts: 437 lines (no duplication) - Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner - Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status - Split ReviewFindings.tsx into focused components All imports verified, type checks passing, linting clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fixes during testing of PR * feat(github): implement PR merge, assign, and comment features - Add auto-assignment when clicking "Run AI Review" - Implement PR merge functionality with squash method - Add ability to post comments on PRs - Display assignees in PR UI - Add Approve and Merge buttons when review passes - Update backend gh_client with pr_merge, pr_comment, pr_assign methods - Create IPC handlers for new PR operations - Update TypeScript interfaces and browser mocks 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Improve PR review AI * fix(github): use temp files for PR review posting to avoid shell escaping issues When posting PR reviews with findings containing special characters (backticks, parentheses, quotes), the shell command was interpreting them as commands instead of literal text, causing syntax errors. Changed both postPRReview and postPRComment handlers to write the body content to temporary files and use gh CLI's --body-file flag instead of --body with inline content. This safely handles ALL special characters without escaping issues. Fixes shell errors when posting reviews with suggested fixes containing code snippets. * fix(i18n): add missing GitHub PRs translation and document i18n requirements Fixed missing translation key for GitHub PRs feature that was causing "items.githubPRs" to display instead of the proper translated text. Added comprehensive i18n guidelines to CLAUDE.md to ensure all future frontend development follows the translation key pattern instead of using hardcoded strings. Also fixed missing deletePRReview mock function in browser-mock.ts to resolve TypeScript compilation errors. Changes: - Added githubPRs translation to en/navigation.json - Added githubPRs translation to fr/navigation.json - Added Development Guidelines section to CLAUDE.md with i18n requirements - Documented translation file locations and namespace usage patterns - Added deletePRReview mock function to browser-mock.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix ui loading * Github PR fixes * improve claude.md * lints/tests * fix(github): handle PRs exceeding GitHub's 20K line diff limit - Add PRTooLargeError exception for large PR detection - Update pr_diff() to catch and raise PRTooLargeError for HTTP 406 errors - Gracefully handle large PRs by skipping full diff and using individual file patches - Add diff_truncated flag to PRContext to track when diff was skipped - Large PRs will now review successfully using per-file diffs instead of failing Fixes issue with PR #252 which has 100+ files exceeding the 20,000 line limit. * fix: implement individual file patch fetching for large PRs The PR review was getting stuck for large PRs (>20K lines) because when we skipped the full diff due to GitHub API limits, we had no code to analyze. The individual file patches were also empty, leaving the AI with just file names and metadata. Changes: - Implemented _get_file_patch() to fetch individual patches via git diff - Updated PR review engine to build composite diff from file patches when diff_truncated is True - Added missing 'state' field to PRContext dataclass - Limits composite diff to first 50 files for very large PRs - Shows appropriate warnings when using reconstructed diffs This allows AI review to proceed with actual code analysis even when the full PR diff exceeds GitHub's limits. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * 1min reduction * docs: add GitHub Sponsors funding configuration Enable the Sponsor button on the repository by adding FUNDING.yml with the AndyMik90 GitHub Sponsors profile. * feat(github-pr): add orchestrating agent for thorough PR reviews Implement a new Opus 4.5 orchestrating agent that performs comprehensive PR reviews regardless of size. Key changes: - Add orchestrator_reviewer.py with strategic review workflow - Add review_tools.py with subagent spawning capabilities - Add pr_orchestrator.md prompt emphasizing thorough analysis - Add pr_security_agent.md and pr_quality_agent.md subagent prompts - Integrate orchestrator into pr_review_engine.py with config flag - Fix critical bug where findings were extracted but not processed (indentation issue in _parse_orchestrator_output) The orchestrator now correctly identifies issues in PRs that were previously approved as "trivial". Testing showed 7 findings detected vs 0 before the fix. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * i18n * fix(github-pr): restrict pr_reviewer to read-only permissions The PR review agent was using qa_reviewer agent type which has Bash access, allowing it to checkout branches and make changes during review. Created new pr_reviewer agent type with BASE_READ_TOOLS only (no Bash, no writes, no auto-claude tools). This prevents the PR review from accidentally modifying code or switching branches during analysis. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github-pr): robust category mapping and JSON parsing for PR review The orchestrator PR review was failing to extract findings because: 1. AI generates category names like 'correctness', 'consistency', 'testing' that aren't in our ReviewCategory enum - added flexible mapping 2. JSON sometimes embedded in markdown code blocks (```json) which broke parsing - added code block extraction as first parsing attempt Changes: - Add _CATEGORY_MAPPING dict to map AI categories to valid enum values - Add _map_category() helper function with fallback to QUALITY - Add severity parsing with fallback to MEDIUM - Add markdown code block detection (```json) before raw JSON parsing - Add _extract_findings_from_data() helper to reduce code duplication - Apply same fixes to review_tools.py for subagent parsing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(pr-review): improve post findings UX with batch support and feedback - Fix post findings failing on own PRs by falling back from REQUEST_CHANGES to COMMENT when GitHub returns 422 error - Change status badge to show "Reviewed" instead of "Commented" until findings are actually posted to GitHub - Add success notification when findings are posted (auto-dismisses after 3s) - Add batch posting support: track posted findings, show "Posted" badge, allow posting remaining findings in additional batches - Show loading state on button while posting 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): resolve stale timestamp and null author bugs - Fix stale timestamp in batch_issues.py: Move updated_at assignment BEFORE to_dict() serialization so the saved JSON contains the correct timestamp instead of the old value - Fix AttributeError in context_gatherer.py: Handle null author/user fields when GitHub API returns null for deleted/suspended users instead of an empty object 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address all high and medium severity PR review findings HIGH severity fixes: - Command Injection in autofix-handlers.ts: Use execFileSync with args array - Command Injection in pr-handlers.ts (3 locations): Use execFileSync + validation - Command Injection in triage-handlers.ts: Use execFileSync + label validation - Token Exposure in bot_detection.py: Pass token via GH_TOKEN env var MEDIUM severity fixes: - Environment variable leakage in subprocess-runner.ts: Filter to safe vars only - Debug logging in subprocess-runner.ts: Only log in development mode - Delimiter escape bypass in sanitize.py: Use regex pattern for variations - Insecure file permissions in trust.py: Use os.open with 0o600 mode - No file locking in learning.py: Use FileLock + atomic_write utilities - Bare except in confidence.py: Log error with specific exception info - Fragile module import in pr_review_engine.py: Import at module level - State transition validation in models.py: Enforce can_transition_to() 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * PR followup * fix(security): add usedforsecurity=False to MD5 hash calls MD5 is used for generating unique IDs/cache keys, not for security purposes. Adding usedforsecurity=False resolves Bandit B324 warnings. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address all high-priority PR review findings Fixes 5 high-priority issues from Auto Claude PR Review: 1. orchestrator_reviewer.py: Token budget tracking now increments total_tokens from API response usage data 2. pr_review_engine.py: Async exceptions now re-raise RuntimeError instead of silently returning empty results 3. batch_issues.py: IssueBatch.save() now uses locked_json_write for atomic file operations with file locking 4. project-middleware.ts: Added validateProjectPath() to prevent path traversal attacks (checks absolute, no .., exists, is dir) 5. orchestrator.py: Exception handling now logs full traceback and preserves exception type/context in error messages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address all high-priority PR review findings Fixes 5 high-priority issues from Auto Claude PR Review: 1. orchestrator_reviewer.py: Token budget tracking now increments total_tokens from API response usage data 2. pr_review_engine.py: Async exceptions now re-raise RuntimeError instead of silently returning empty results 3. batch_issues.py: IssueBatch.save() now uses locked_json_write for atomic file operations with file locking 4. project-middleware.ts: Added validateProjectPath() to prevent path traversal attacks (checks absolute, no .., exists, is dir) 5. orchestrator.py: Exception handling now logs full traceback and preserves exception type/context in error messages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(ui): add PR status labels to list view Add secondary status badges to the PR list showing review state at a glance: - "Changes Requested" (warning) - PRs with blocking issues (critical/high) - "Ready to Merge" (green) - PRs with only non-blocking suggestions - "Ready for Follow-up" (blue) - PRs with new commits since last review The "Ready for Follow-up" badge uses a cached new commits check from the store, only shown after the detail view confirms new commits via SHA comparison. This prevents false positives from PR updatedAt timestamp changes (which can happen from comments, labels, etc). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * PR labels * auto-claude: Initialize subtask-based implementation plan - Workflow type: feature - Phases: 3 - Subtasks: 6 - Ready for autonomous implementation --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * chore(deps): bump vitest from 4.0.15 to 4.0.16 in /apps/frontend (#272) Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.0.15 to 4.0.16. - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/vitest) --- updated-dependencies: - dependency-name: vitest dependency-version: 4.0.16 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @electron/rebuild in /apps/frontend (#271) Bumps [@electron/rebuild](https://github.com/electron/rebuild) from 3.7.2 to 4.0.2. - [Release notes](https://github.com/electron/rebuild/releases) - [Commits](https://github.com/electron/rebuild/compare/v3.7.2...v4.0.2) --- updated-dependencies: - dependency-name: "@electron/rebuild" dependency-version: 4.0.2 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * fix(paths): normalize relative paths to posix (#239) Co-authored-by: danielfrey63 <daniel.frey@sbb.ch> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * fix: accept bug_fix workflow_type alias during planning (#240) * fix(planning): accept bug_fix workflow_type alias * style(planning): ruff format * fix: refatored common logic * fix: remove ruff errors * fix: remove duplicate _normalize_workflow_type method Remove the incorrectly placed duplicate method inside ContextLoader class. The module-level function is the correct implementation being used. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: danielfrey63 <daniel.frey@sbb.ch> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(ci): use develop branch for dry-run builds in beta-release workflow (#276) When dry_run=true, the workflow skipped creating the version tag but build jobs still tried to checkout that non-existent tag, causing all 4 platform builds to fail with "git failed with exit code 1". Now build jobs checkout develop branch for dry runs while still using the version tag for real releases. Closes: GitHub Actions run #20464082726 * chore(deps): bump typescript-eslint in /apps/frontend (#269) Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.49.0 to 8.50.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.50.1/packages/typescript-eslint) --- updated-dependencies: - dependency-name: typescript-eslint dependency-version: 8.50.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * chore(deps): bump jsdom from 26.1.0 to 27.3.0 in /apps/frontend (#268) Bumps [jsdom](https://github.com/jsdom/jsdom) from 26.1.0 to 27.3.0. - [Release notes](https://github.com/jsdom/jsdom/releases) - [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md) - [Commits](https://github.com/jsdom/jsdom/compare/26.1.0...27.3.0) --- updated-dependencies: - dependency-name: jsdom dependency-version: 27.3.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * fix(ci): use correct electron-builder arch flags (#278) The project switched from pnpm to npm, which handles script argument passing differently. pnpm adds a -- separator that caused electron-builder to ignore the --arch argument, but npm passes it directly. Since --arch is a deprecated electron-builder argument, use the recommended flags instead: - --arch=x64 → --x64 - --arch=arm64 → --arm64 This fixes Mac Intel and ARM64 builds failing with "Unknown argument: arch" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): resolve CodeQL file system race conditions and unused variables (#277) * fix(security): resolve CodeQL file system race conditions and unused variables Fix high severity CodeQL alerts: - Remove TOCTOU (time-of-check-time-of-use) race conditions by eliminating existsSync checks followed by file operations. Use try-catch instead. - Files affected: pr-handlers.ts, spec-utils.ts Fix unused variable warnings: - Remove unused imports (FeatureModelConfig, FeatureThinkingConfig, withProjectSyncOrNull, getBackendPath, validateRunner, githubFetch) - Prefix intentionally unused destructured variables with underscore - Remove unused local variables (existing, actualEvent) - Files affected: pr-handlers.ts, autofix-handlers.ts, triage-handlers.ts, PRDetail.tsx, pr-review-store.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): resolve remaining CodeQL alerts for TOCTOU, network data validation, and unused variables Address CodeRabbit and CodeQL security alerts from PR #277 review: - HIGH: Fix 12+ file system race conditions (TOCTOU) by replacing existsSync() checks with try/catch blocks in pr-handlers.ts, autofix-handlers.ts, triage-handlers.ts, and spec-utils.ts - MEDIUM: Add sanitizeNetworkData() function to validate/sanitize GitHub API data before writing to disk, preventing injection attacks - Clean up 20+ unused variables, imports, and useless assignments across frontend components and handlers - Fix Python Protocol typing in testing.py (add return type annotations) All changes verified with TypeScript compilation and ESLint (no errors). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): resolve follow-up review API issues - Fix gh_client.py: use query string syntax for `since` parameter instead of `-f` flag which sends POST body fields, causing GitHub API errors - Fix followup_reviewer.py: use raw Anthropic client for message API calls instead of ClaudeSDKClient which is for agent sessions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore(deps): bump @xterm/xterm from 5.5.0 to 6.0.0 in /apps/frontend (#270) * chore(deps): bump @xterm/xterm from 5.5.0 to 6.0.0 in /apps/frontend Bumps [@xterm/xterm](https://github.com/xtermjs/xterm.js) from 5.5.0 to 6.0.0. - [Release notes](https://github.com/xtermjs/xterm.js/releases) - [Commits](https://github.com/xtermjs/xterm.js/compare/5.5.0...6.0.0) --- updated-dependencies: - dependency-name: "@xterm/xterm" dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * fix(deps): update xterm addons for 6.0.0 compatibility and use public APIs CRITICAL: Updated all xterm addons to versions compatible with xterm 6.0.0: - @xterm/addon-fit: ^0.10.0 → ^0.11.0 - @xterm/addon-serialize: ^0.13.0 → ^0.14.0 - @xterm/addon-web-links: ^0.11.0 → ^0.12.0 - @xterm/addon-webgl: ^0.18.0 → ^0.19.0 HIGH: Refactored scroll-controller.ts to use public xterm APIs: - Replaced internal _core access with public buffer/scroll APIs - Uses onScroll and onWriteParsed events for scroll tracking - Uses scrollLines() for scroll position restoration - Proper IDisposable cleanup for event listeners - Falls back gracefully if onWriteParsed is not available 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(ci): add write permissions to beta-release update-version job The update-version job needs contents: write permission to push the version bump commit and tag to the repository. Without this, the workflow fails with a 403 error when trying to git push. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: resolve spawn python ENOENT error on Linux by using getAugmentedEnv() (#281) - Use getAugmentedEnv() in project-context-handlers.ts to ensure Python is in PATH - Add /usr/bin and /usr/sbin to Linux paths in env-utils.ts for system Python - Fixes GUI-launched apps not inheriting shell environment on Ubuntu 24.04 Fixes #215 Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * feat(python): bundle Python 3.12 with packaged Electron app (#284) * feat(python): bundle Python 3.12 with packaged Electron app Resolves issue #258 where users with Python aliases couldn't run the app because shell aliases aren't visible to Electron's subprocess calls. Changes: - Add download-python.cjs script to fetch python-build-standalone - Bundle Python 3.12.8 in extraResources for packaged apps - Update python-detector.ts to prioritize bundled Python - Add Python caching to CI workflows for faster builds Packaged apps now include Python (~35MB), eliminating the need for users to have Python installed. Dev mode still falls back to system Python. Closes #258 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address PR review feedback for Python bundling Security improvements: - Add SHA256 checksum verification for downloaded Python binaries - Replace execSync with spawnSync to prevent command injection - Add input validation to prevent log injection from CLI args - Add download timeout (5 minutes) and redirect limit (10) - Proper file/connection cleanup on errors Bug fixes: - Fix platform naming mismatch: use "mac"/"win" (electron-builder) instead of "darwin"/"win32" (Node.js) for output directories - Handle empty path edge case in parsePythonCommand Improvements: - Add restore-keys to CI cache steps for better cache hit rates - Improve error messages and logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix mac node.js naming * security: add SHA256 checksums for all Python platforms Fetched actual checksums from python-build-standalone release: - darwin-arm64: abe1de24... - darwin-x64: 867c1af1... - win32-x64: 1a702b34... - linux-x64: 698e53b2... - linux-arm64: fb983ec8... All platforms now have cryptographic verification for downloaded Python binaries, eliminating the supply chain risk. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: add python-runtime to root .gitignore Ensures bundled Python runtime is ignored from both root and frontend .gitignore files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): validate backend source path before using it (#287) * fix(frontend): validate backend source path before using it The path resolver was returning invalid autoBuildPath settings without validating they contained the required backend files. When settings pointed to a legacy /auto-claude/ directory (missing requirements.txt and analyzer.py), the project indexer would fail with "can't open file" errors. Now validates that all source paths contain requirements.txt before returning them, falling back to bundled source path detection when the configured path is invalid. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: Initialize subtask-based implementation plan - Workflow type: feature - Phases: 4 - Subtasks: 9 - Ready for autonomous implementation Parallel execution enabled: phases 1 and 2 can run simultaneously * auto-claude: Initialize subtask-based implementation plan - Workflow type: investigation - Phases: 5 - Subtasks: 13 - Ready for autonomous implementation * fix merge conflict check loop * fix(frontend): add warning when fallback path is also invalid Address CodeRabbit review feedback - the fallback path in getBundledSourcePath() was returning an unvalidated path which could still cause the same analyzer.py error. Now logs a warning when the fallback path also lacks requirements.txt. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Potential fix for code scanning alert no. 224: Uncontrolled command line (#285) Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix(frontend): support archiving tasks across all worktree locations (#286) * archive across all worktress and if not in folder * fix(frontend): address PR security and race condition issues - Add taskId validation to prevent path traversal attacks - Fix TOCTOU race conditions in archiveTasks by removing existsSync - Fix TOCTOU race conditions in unarchiveTasks by removing existsSync 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): add explicit GET method to gh api comment fetches (#294) The gh api command defaults to POST for comment endpoints, causing GitHub to reject the 'since' query parameter as an invalid POST body field. Adding --method GET explicitly forces a GET request, allowing the since parameter to work correctly for fetching comments. This completes the fix started in f1cc5a09 which only changed from -f flag to query string syntax but didn't address the HTTP method. * feat: enhance the logs for the commit linting stage (#293) * ci: implement enterprise-grade PR quality gates and security scanning * ci: implement enterprise-grade PR quality gates and security scanning * fix:pr comments and improve code * fix: improve commit linting and code quality * Removed the dependency-review job (i added it) * fix: address CodeRabbit review comments - Expand scope pattern to allow uppercase, underscores, slashes, dots - Add concurrency control to cancel duplicate security scan runs - Add explanatory comment for Bandit CLI flags - Remove dependency-review job (requires repo settings) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: update commit lint examples with expanded scope patterns Show slashes and dots in scope examples to demonstrate the newly allowed characters (api/users, package.json) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: remove feature request issue template Feature requests are directed to GitHub Discussions via the issue template config.yml 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address security vulnerabilities in service orchestrator - Fix port parsing crash on malformed docker-compose entries - Fix shell injection risk by using shlex.split() with shell=False Prevents crashes when docker-compose.yml contains environment variables in port mappings (e.g., '${PORT}:8080') and eliminates shell injection vulnerabilities in subprocess execution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(ci): improve PR title validation error messages with examples Add helpful console output when PR title validation fails: - Show expected format and valid types - Provide examples of valid PR titles - Display the user's current title - Suggest fixes based on keywords in the title - Handle verb variations (fixed, adding, updated, etc.) - Show placeholder when description is empty after cleanup 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * lower coverage * feat: improve status gate to label correctly based on required checks * fix(ci): address PR review findings for security and efficiency - Add explicit permissions block to ci.yml (least privilege principle) - Skip duplicate test run for Python 3.12 (tests with coverage only) - Sanitize PR title in markdown output to prevent injection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix typo --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * feat(merge,oauth): add path-aware AI merge resolution and device code streaming (#296) * improve/merge-confclit-layer * improve AI resolution * fix caching on merge conflicts * imrpove merge layer with rebase * fix(github): add OAuth authentication to follow-up PR review The follow-up PR review AI analysis was failing with "Could not resolve authentication method" because AsyncAnthropic() was instantiated without credentials. The codebase uses OAuth tokens (not ANTHROPIC_API_KEY), so the client needs the auth_token parameter. Uses get_auth_token() from core.auth to retrieve the OAuth token from environment variables or macOS Keychain, matching how initial reviews authenticate via create_client(). * fix(merge): add validation to prevent AI writing natural language to files When AI merge receives truncated file contents (due to character limits), it sometimes responds with explanations like "I need to see the complete file contents..." instead of actual merged code. This garbage was being written directly to source files. Adds two validation layers after AI merge: 1. Natural language detection - catches patterns like "I need to", "Let me" 2. Syntax validation - uses esbuild to verify TypeScript/JavaScript syntax If either validation fails, the merge returns an error instead of writing invalid content to the file. Also adds project_dir field to ParallelMergeTask to enable syntax validation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(merge): skip git merge when AI already resolved path-mapped files When AI successfully merges path-mapped files (due to file renames between branches), the check only looked at `conflicts_resolved` which was 0 for path-mapped cases. This caused the code to fall through to `git merge` which then failed with conflicts. Now also checks `files_merged` and `ai_assisted` stats to determine if AI has already handled the merge. When files are AI-merged, they're already written and staged - no need for git merge. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix device code issue with github * fix(frontend): remember GitHub auth method (OAuth vs PAT) in settings Previously, after authenticating via GitHub OAuth, the settings page would show "Personal Access Token" input even though OAuth was used. This was confusing for users who expected to see their OAuth status. Added githubAuthMethod field to track how authentication was performed. Settings UI now shows "Authenticated via GitHub OAuth" when OAuth was used, with option to switch to manual token if needed. The auth method persists across settings reopening. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(backend): centralize OAuth client creation in core/client.py - Add create_message_client() for simple message API calls - Refactor followup_reviewer.py to use centralized client factory - Remove direct anthropic.AsyncAnthropic import from followup_reviewer - Add proper ValueError handling for missing OAuth token - Update docstrings to document both client factories This ensures all AI interactions use the centralized OAuth authentication in core/, avoiding direct ANTHROPIC_API_KEY usage per CLAUDE.md guidelines. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): remove unused statusColor variable in WorkspaceStatus Dead code cleanup - the statusColor variable was computed but never used in the component. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(tests): add BrowserWindow mock to oauth-handlers tests The sendDeviceCodeToRenderer function uses BrowserWindow.getAllWindows() which wasn't mocked, causing unhandled rejection errors in tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(backend): use ClaudeSDKClient instead of raw anthropic SDK Remove direct anthropic SDK import from core/client.py and update followup_reviewer.py to use ClaudeSDKClient directly as per project conventions. All AI interactions should use claude-agent-sdk. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(backend): add debug logging for AI response in followup_reviewer Add logging to diagnose why AI review returns no JSON - helps identify if response is in thinking blocks vs text blocks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Fix/2.7.2 fixes (#300) * fix(frontend): prevent false stuck detection for ai_review tasks Tasks in ai_review status were incorrectly showing "Task Appears Stuck" in the detail modal. This happened because the isRunning check included ai_review status, triggering stuck detection when no process was found. However, ai_review means "all subtasks completed, awaiting QA" - no build process is expected to be running. This aligns the detail modal logic with TaskCard which correctly only checks for in_progress status. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * ci(beta-release): use tag-based versioning instead of modifying package.json Previously the beta-release workflow committed version changes to package.json on the develop branch, which caused two issues: 1. Permission errors (github-actions[bot] denied push access) 2. Beta versions polluted develop, making merges to main unclean Now the workflow creates only a git tag and injects the version at build time using electron-builder's --config.extraMetadata.version flag. This keeps package.json at the next stable version and avoids any commits to develop. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ollama): add packaged app path resolution for Ollama detector script The Ollama detection was failing in packaged builds because the Python script path resolution only checked development paths. In packaged apps, __dirname points to the app bundle, and the relative path "../../../backend" doesn't resolve correctly. Added process.resourcesPath for packaged builds (checked first via app.isPackaged) which correctly locates the backend scripts in the Resources folder. Also added DEBUG-only logging to help troubleshoot script location issues. Closes #129 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(paths): remove legacy auto-claude path fallbacks Replace all legacy 'auto-claude/' source path detection with 'apps/backend'. Services now validate paths using runners/spec_runner.py as the marker instead of requirements.txt, ensuring only valid backend directories match. - Remove legacy fallback paths from all getAutoBuildSourcePath() implementations - Add startup validation in index.ts to skip invalid saved paths - Update project-initializer to detect apps/backend for local dev projects - Standardize path detection across all services 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): address PR review feedback from Auto Claude and bots Fixes from PR #300 reviews: CRITICAL: - path-resolver.ts: Update marker from requirements.txt to runners/spec_runner.py for consistent backend detection across all files HIGH: - useTaskDetail.ts: Restore stuck task detection for ai_review status (CHANGELOG documents this feature) - TerminalGrid.tsx: Include legacy terminals without projectPath (prevents hiding terminals after upgrade) - memory-handlers.ts: Add packaged app path in OLLAMA_PULL_MODEL handler (fixes production builds) MEDIUM: - OAuthStep.tsx: Stricter profile slug sanitization (only allow alphanumeric and dashes) - project-store.ts: Fix regex to not truncate at # in code blocks (uses \n#{1,6}\s to match valid markdown headings only) - memory-service.ts: Add backend structure validation with spec_runner.py marker - subprocess-spawn.test.ts: Update test to use new marker pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): validate empty profile slug after sanitization Add validation to prevent empty config directory path when profile name contains only special characters (e.g., "!!!"). Shows user-friendly error message requiring at least one letter or number. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix: stop tracking spec files in git (#295) * fix: stop tracking spec files in git - Remove git commit instructions from planner.md for spec files - Spec files (implementation_plan.json, init.sh, build-progress.txt) should be gitignored - Untrack existing spec files that were accidentally committed - AI agents should only commit code changes, not spec metadata The .auto-claude/specs/ directory is gitignored by design - spec files are local project metadata that shouldn't be version controlled. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(prompts): remove git commit instructions for gitignored spec files The spec files (build-progress.txt, qa_report.md, implementation_plan.json, QA_FIX_REQUEST.md) are all stored in .auto-claude/specs/ which is gitignored. Removed instructions telling agents to commit these files, replaced with notes explaining they're tracked automatically by the framework. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(build): add --force-local flag to tar on Windows (#303) On Windows, paths like D:\path are misinterpreted by tar as remote host:path syntax (Unix tar convention). Adding --force-local tells tar to treat colons as part of the filename, fixing the extraction failure in GitHub Actions Windows builds. Error was: "tar (child): Cannot connect to D: resolve failed" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(build): use PowerShell for tar extraction on Windows The previous fix using --force-local and path conversion still failed due to shell escaping issues. PowerShell handles Windows paths natively and has built-in tar support on Windows 10+, avoiding all path escaping problems. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): add augmented PATH env to all gh CLI calls When running from a packaged macOS app (.dmg), the PATH environment variable doesn't include common locations like /opt/homebrew/bin where gh is typically installed via Homebrew. The getAugmentedEnv() function was already being used in some places but was missing from: - spawn() call in registerStartGhAuth - execSync calls for gh auth token, gh api user, gh repo list - execFileSync calls for gh api, gh repo create - execFileSync calls in pr-handlers.ts and triage-handlers.ts This caused "gh: command not found" errors when connecting projects to GitHub in the packaged app. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(build): use explicit Windows System32 tar path (#308) The previous PowerShell fix still found Git Bash's /usr/bin/tar which interprets D: as a remote host. Using the explicit path to Windows' built-in bsdtar (C:\Windows\System32\tar.exe) avoids this issue. Windows Server 2019+ (GitHub Actions) has bsdtar in System32. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * chore(ci): cancel in-progress runs (#302) Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> Co-authored-by: Alex <63423455+AlexMadera@users.noreply.github.com> * fix(python): use venv Python for all services to fix dotenv errors (#311) * fix(python): use venv Python for all services to fix dotenv errors Services were spawning Python processes using findPythonCommand() which returns the bundled Python directly. However, dependencies like python-dotenv are only installed in the venv created from the bundled Python. Changes: - Add getConfiguredPythonPath() helper that returns venv Python when ready - Update all services to use venv Python instead of bundled Python directly: - memory-service.ts - memory-handlers.ts - agent-process.ts - changelog-service.ts - title-generator.ts - insights/config.ts - project-context-handlers.ts - worktree-handlers.ts - Fix availability checks to use findPythonCommand() (can return null) - Add python:verify script for bundling verification The flow now works correctly: 1. App starts → findPythonCommand() finds bundled Python 2. pythonEnvManager creates venv using bundled Python 3. pip installs dependencies (dotenv, claude-agent-sdk, etc.) 4. All services use venv Python → has all dependencies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix lintin and test --------- Co-authored-by: Claude <noreply@anthropic.com> * fix(updater): proper semver comparison for pre-release versions (#313) Fixes the beta auto-update bug where the app was offering downgrades (e.g., showing v2.7.1 as "new version available" when on v2.7.2-beta.6). Changes: - version-manager.ts: New parseVersion() function that separates base version from pre-release suffix. Updated compareVersions() to handle pre-release versions correctly (alpha < beta < rc < stable). - app-updater.ts: Import and use compareVersions() for proper version comparison instead of simple string inequality. - Added comprehensive unit tests for version comparison logic. Pre-release ordering: - 2.7.1 < 2.7.2-alpha.1 < 2.7.2-beta.1 < 2.7.2-rc.1 < 2.7.2 (stable) - 2.7.2-beta.6 < 2.7.2-beta.7 * fix(project): fix task status persistence reverting on refresh (#246) (#318) Correctly validate persisted task status against calculated status. Previously, if a task was 'in_progress' but had no active subtasks (e.g. still in planning or between phases), the calculated status 'backlog' would override the stored status, causing the UI to revert to 'Start'. This fix adds 'in_progress' to the list of active process statuses and explicitly allows 'in_progress' status to persist when the underlying plan status is also 'in_progress'. * fix(ci): add auto-updater manifest files and version auto-update (#317) Combined PR with: 1. Alex's version auto-update changes from PR #316 2. Auto-updater manifest file generation fix Changes: - Add --publish never to package scripts to generate .yml manifests - Update all build jobs to upload .yml files as artifacts - Update release step to include .yml files in GitHub release - Auto-bump version in package.json files before tagging This enables the in-app auto-updater to work properly by ensuring latest-mac.yml, latest-linux.yml, and latest.yml are published with each release. Co-authored-by: Alex <63423455+AlexMadera@users.noreply.github.com> * f…
…ik90#1038) * feat: Add OpenRouter as LLM/embedding provider (#162) * feat: Add OpenRouter as LLM/embedding provider Add OpenRouter provider support for Graphiti memory integration, enabling access to multiple LLM providers through a single API. Changes: Backend: - Created openrouter_llm.py: OpenRouter LLM provider using OpenAI-compatible API - Created openrouter_embedder.py: OpenRouter embedder provider - Updated config.py: Added OpenRouter to provider enums and configuration - New fields: openrouter_api_key, openrouter_base_url, openrouter_llm_model, openrouter_embedding_model - Validation methods updated for OpenRouter - Updated factory.py: Added OpenRouter to LLM and embedder factories - Updated provider __init__.py files: Exported new OpenRouter functions Frontend: - Updated project.ts types: Added 'openrouter' to provider type unions - GraphitiProviderConfig extended with OpenRouter fields - Updated GraphitiStep.tsx: Added OpenRouter to provider arrays - LLM_PROVIDERS: 'Multi-provider aggregator' - EMBEDDING_PROVIDERS: 'OpenAI-compatible embeddings' - Added OpenRouter API key input field with show/hide toggle - Link to https://openrouter.ai/keys - Updated env-handlers.ts: OpenRouter .env generation and parsing - Template generation for OPENROUTER_* variables - Parsing from .env files with proper type casting Documentation: - Updated .env.example with OpenRouter section - Configuration examples - Popular model recommendations - Example configuration (#6) Fixes #92 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor: address CodeRabbit review comments for OpenRouter - Add globalOpenRouterApiKey to settings types and store updates - Initialize openrouterApiKey from global settings - Update documentation to include OpenRouter in provider lists - Add OpenRouter handling to get_embedding_dimension() method - Add openrouter to provider cleanup list - Add OpenRouter to get_available_providers() function - Clarify Legacy comment for openrouterLlmModel These changes complete the OpenRouter integration by ensuring proper settings persistence and provider detection across the application. * fix: apply ruff formatting to OpenRouter code - Break long error message across multiple lines - Format provider list with one item per line - Fixes lint CI failure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(core): add global spec numbering lock to prevent collisions (#209) Implements distributed file-based locking for spec number coordination across main project and all worktrees. Previously, parallel spec creation could assign the same number to different specs (e.g., 042-bmad-task and 042-gitlab-integration both using number 042). The fix adds SpecNumberLock class that: - Acquires exclusive lock before calculating spec numbers - Scans ALL locations (main project + worktrees) for global maximum - Creates spec directories atomically within the lock - Handles stale locks via PID-based detection with 30s timeout Applied to both Python backend (spec_runner.py flow) and TypeScript frontend (ideation conversion, GitHub/GitLab issue import). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Fix/ideation status sync (#212) * fix(ideation): add missing event forwarders for status sync - Add event forwarders in ideation-handlers.ts for progress, log, type-complete, type-failed, complete, error, and stopped events - Fix ideation-type-complete to load actual ideas array from JSON files instead of emitting only the count Resolves UI getting stuck at 0/3 complete during ideation generation. * fix(ideation): fix UI not updating after actions - Fix getIdeationSummary to count only active ideas (exclude dismissed/archived) This ensures header stats match the visible ideas count - Add transformSessionFromSnakeCase to properly transform session data from backend snake_case to frontend camelCase on ideation-complete event - Transform raw session before emitting ideation-complete event Resolves header showing stale counts after dismissing/deleting ideas. * fix(ideation): improve type safety and async handling in ideation type completion - Replace synchronous readFileSync with async fsPromises.readFile in ideation-type-complete handler - Wrap async file read in IIFE with proper error handling to prevent unhandled promise rejections - Add type validation for IdeationType with VALID_IDEATION_TYPES set and isValidIdeationType guard - Add validateEnabledTypes function to filter out invalid type values and log dropped entries - Handle ENOENT separately * fix(ideation): improve generation state management and error handling - Add explicit isGenerating flag to prevent race conditions during async operations - Implement 5-minute timeout for generation with automatic cleanup and error state - Add ideation-stopped event emission when process is intentionally killed - Replace console.warn/error with proper ideation-error events in agent-queue - Add resetGeneratingTypes helper to transition all generating types to a target state - Filter out dismissed/ * refactor(ideation): improve event listener cleanup and timeout management - Extract event handler functions in ideation-handlers.ts to enable proper cleanup - Return cleanup function from registerIdeationHandlers to remove all listeners - Replace single generationTimeoutId with Map to support multiple concurrent projects - Add clearGenerationTimeout helper to centralize timeout cleanup logic - Extract loadIdeationType IIFE to named function for better error context - Enhance error logging with projectId, * refactor: use async file read for ideation and roadmap session loading - Replace synchronous readFileSync with async fsPromises.readFile - Prevents blocking the event loop during file operations - Consistent with async pattern used elsewhere in the codebase - Improved error handling with proper event emission * fix(agent-queue): improve roadmap completion handling and error reporting - Add transformRoadmapFromSnakeCase to convert backend snake_case to frontend camelCase - Transform raw roadmap data before emitting roadmap-complete event - Add roadmap-error emission for unexpected errors during completion - Add roadmap-error emission when project path is unavailable - Remove duplicate ideation-type-complete emission from error handler (event already emitted in loadIdeationType) - Update error log message * fix: add future annotations import to discovery.py (#229) Adds 'from __future__ import annotations' to spec/discovery.py for Python 3.9+ compatibility with type hints. This completes the Python compatibility fixes that were partially applied in previous commits. All 26 analysis and spec Python files now have the future annotations import. Related: #128 Co-authored-by: Joris Slagter <mail@jorisslagter.nl> * fix: resolve Python detection and backend packaging issues (#241) * fix: resolve Python detection and backend packaging issues - Fix backend packaging path (auto-claude -> backend) to match path-resolver.ts expectations - Add future annotations import to config_parser.py for Python 3.9+ compatibility - Use findPythonCommand() in project-context-handlers to prioritize Homebrew Python - Improve Python detection to prefer Homebrew paths over system Python on macOS This resolves the following issues: - 'analyzer.py not found' error due to incorrect packaging destination - TypeError with 'dict | None' syntax on Python < 3.10 - Wrong Python interpreter being used (system Python instead of Homebrew Python 3.10+) Tested on macOS with packaged app - project index now loads successfully. * refactor: address PR review feedback - Extract findHomebrewPython() helper to eliminate code duplication between findPythonCommand() and getDefaultPythonCommand() - Remove hardcoded version-specific paths (python3.12) and rely only on generic Homebrew symlinks for better maintainability - Remove unnecessary 'from __future__ import annotations' from config_parser.py since backend requires Python 3.12+ where union types are native These changes make the code more maintainable, less fragile to Python version changes, and properly reflect the project's Python 3.12+ requirement. * Feat/Auto Fix Github issues and do extensive AI PR reviews (#250) * feat(github): add GitHub automation system for issues and PRs Implements comprehensive GitHub automation with three major components: 1. Issue Auto-Fix: Automatically creates specs from labeled issues - AutoFixButton component with progress tracking - useAutoFix hook for config and queue management - Backend handlers for spec creation from issues 2. GitHub PRs Tool: AI-powered PR review sidebar - New sidebar tab (Cmd+Shift+P) alongside GitHub Issues - PRList/PRDetail components for viewing PRs - Review system with findings by severity - Post review comments to GitHub 3. Issue Triage: Duplicate/spam/feature-creep detection - Triage handlers with label application - Configurable detection thresholds Also adds: - Debug logging (DEBUG=true) for all GitHub handlers - Backend runners/github module with orchestrator - AI prompts for PR review, triage, duplicate/spam detection - dev:debug npm script for development with logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github-runner): resolve import errors for direct script execution Changes runner.py and orchestrator.py to handle both: - Package import: `from runners.github import ...` - Direct script: `python runners/github/runner.py` Uses try/except pattern for relative vs direct imports. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): correct argparse argument order for runner.py Move --project global argument before subcommand so argparse can correctly parse it. Fixes "unrecognized arguments: --project" error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * logs when debug mode is on * refactor(github): extract service layer and fix linting errors Major refactoring to improve maintainability and code quality: Backend (Python): - Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules: - prompt_manager.py: Prompt template management - response_parsers.py: AI response parsing - pr_review_engine.py: PR review orchestration - triage_engine.py: Issue triage logic - autofix_processor.py: Auto-fix workflow - batch_processor.py: Batch issue handling - Fixed 18 ruff linting errors (F401, C405, C414, E741): - Removed unused imports (BatchValidationResult, AuditAction, locked_json_write) - Optimized collection literals (set([n]) → {n}) - Removed unnecessary list() calls - Renamed ambiguous variable 'l' to 'label' throughout Frontend (TypeScript): - Refactored IPC handlers (19% overall reduction) with shared utilities: - autofix-handlers.ts: 1,042 → 818 lines - pr-handlers.ts: 648 → 543 lines - triage-handlers.ts: 437 lines (no duplication) - Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner - Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status - Split ReviewFindings.tsx into focused components All imports verified, type checks passing, linting clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Revert "Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)" (#251) This reverts commit 348de6dfe793ab111043677c61b8452bc5ecb2cc. * feat: add i18n internationalization system (#248) * Add multilingual support and i18n integration - Implemented i18n framework using `react-i18next` for translation management. - Added support for English and French languages with translation files. - Integrated language selector into settings. - Updated all text strings in UI components to use translation keys. - Ensured smooth language switching with live updates. * Migrate remaining hard-coded strings to i18n system - TaskCard: status labels, review reasons, badges, action buttons - PhaseProgressIndicator: execution phases, progress labels - KanbanBoard: drop zone, show archived, tooltips - CustomModelModal: dialog title, description, labels - ProactiveSwapListener: account switch notifications - AgentProfileSelector: phase labels, custom configuration - GeneralSettings: agent framework option Added translation keys for en/fr locales in tasks.json, common.json, and settings.json for complete i18n coverage. * Add i18n support to dialogs and settings components - AddFeatureDialog: form labels, validation messages, buttons - AddProjectModal: dialog steps, form fields, actions - RateLimitIndicator: rate limit notifications - RateLimitModal: account switching, upgrade prompts - AdvancedSettings: updates and notifications sections - ThemeSettings: theme selection labels - Updated dialogs.json locales (en/fr) * Fix truncated 'ready' message in dialogs locales * Fix backlog terminology in i18n locales Change "Planning"/"Planification" to standard PM term "Backlog" * Migrate settings navigation and integration labels to i18n - AppSettings: nav items, section titles, buttons - IntegrationSettings: Claude accounts, auto-switch, API keys labels - Added settings nav/projectSections/integrations translation keys - Added buttons.saving to common translations * Migrate AgentProfileSettings and Sidebar init dialog to i18n - AgentProfileSettings: migrate phase config labels, section title, description, and all hardcoded strings to settings namespace - Sidebar: migrate init dialog strings to dialogs namespace with common buttons from common namespace - Add new translation keys for agent profile settings and update dialog * Migrate AppSettings navigation labels to i18n - Add useTranslation hook to AppSettings.tsx - Replace hardcoded section labels with dynamic translations - Add projectSections translations for project settings nav - Add rerunWizardDescription translation key * Add explicit typing to notificationItems array Import NotificationSettings type and use keyof to properly type the notification item keys, removing manual type assertion. * fix: update path resolution for ollama_model_detector.py in memory handlers (#263) * ci: implement enterprise-grade PR quality gates and security scanning (#266) * ci: implement enterprise-grade PR quality gates and security scanning * ci: implement enterprise-grade PR quality gates and security scanning * fix:pr comments and improve code * fix: improve commit linting and code quality * Removed the dependency-review job (i added it) * fix: address CodeRabbit review comments - Expand scope pattern to allow uppercase, underscores, slashes, dots - Add concurrency control to cancel duplicate security scan runs - Add explanatory comment for Bandit CLI flags - Remove dependency-review job (requires repo settings) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: update commit lint examples with expanded scope patterns Show slashes and dots in scope examples to demonstrate the newly allowed characters (api/users, package.json) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: remove feature request issue template Feature requests are directed to GitHub Discussions via the issue template config.yml 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address security vulnerabilities in service orchestrator - Fix port parsing crash on malformed docker-compose entries - Fix shell injection risk by using shlex.split() with shell=False Prevents crashes when docker-compose.yml contains environment variables in port mappings (e.g., '${PORT}:8080') and eliminates shell injection vulnerabilities in subprocess execution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * feat(github): add automated PR review with follow-up support (#252) * feat(github): add GitHub automation system for issues and PRs Implements comprehensive GitHub automation with three major components: 1. Issue Auto-Fix: Automatically creates specs from labeled issues - AutoFixButton component with progress tracking - useAutoFix hook for config and queue management - Backend handlers for spec creation from issues 2. GitHub PRs Tool: AI-powered PR review sidebar - New sidebar tab (Cmd+Shift+P) alongside GitHub Issues - PRList/PRDetail components for viewing PRs - Review system with findings by severity - Post review comments to GitHub 3. Issue Triage: Duplicate/spam/feature-creep detection - Triage handlers with label application - Configurable detection thresholds Also adds: - Debug logging (DEBUG=true) for all GitHub handlers - Backend runners/github module with orchestrator - AI prompts for PR review, triage, duplicate/spam detection - dev:debug npm script for development with logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github-runner): resolve import errors for direct script execution Changes runner.py and orchestrator.py to handle both: - Package import: `from runners.github import ...` - Direct script: `python runners/github/runner.py` Uses try/except pattern for relative vs direct imports. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): correct argparse argument order for runner.py Move --project global argument before subcommand so argparse can correctly parse it. Fixes "unrecognized arguments: --project" error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * logs when debug mode is on * refactor(github): extract service layer and fix linting errors Major refactoring to improve maintainability and code quality: Backend (Python): - Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules: - prompt_manager.py: Prompt template management - response_parsers.py: AI response parsing - pr_review_engine.py: PR review orchestration - triage_engine.py: Issue triage logic - autofix_processor.py: Auto-fix workflow - batch_processor.py: Batch issue handling - Fixed 18 ruff linting errors (F401, C405, C414, E741): - Removed unused imports (BatchValidationResult, AuditAction, locked_json_write) - Optimized collection literals (set([n]) → {n}) - Removed unnecessary list() calls - Renamed ambiguous variable 'l' to 'label' throughout Frontend (TypeScript): - Refactored IPC handlers (19% overall reduction) with shared utilities: - autofix-handlers.ts: 1,042 → 818 lines - pr-handlers.ts: 648 → 543 lines - triage-handlers.ts: 437 lines (no duplication) - Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner - Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status - Split ReviewFindings.tsx into focused components All imports verified, type checks passing, linting clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fixes during testing of PR * feat(github): implement PR merge, assign, and comment features - Add auto-assignment when clicking "Run AI Review" - Implement PR merge functionality with squash method - Add ability to post comments on PRs - Display assignees in PR UI - Add Approve and Merge buttons when review passes - Update backend gh_client with pr_merge, pr_comment, pr_assign methods - Create IPC handlers for new PR operations - Update TypeScript interfaces and browser mocks 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Improve PR review AI * fix(github): use temp files for PR review posting to avoid shell escaping issues When posting PR reviews with findings containing special characters (backticks, parentheses, quotes), the shell command was interpreting them as commands instead of literal text, causing syntax errors. Changed both postPRReview and postPRComment handlers to write the body content to temporary files and use gh CLI's --body-file flag instead of --body with inline content. This safely handles ALL special characters without escaping issues. Fixes shell errors when posting reviews with suggested fixes containing code snippets. * fix(i18n): add missing GitHub PRs translation and document i18n requirements Fixed missing translation key for GitHub PRs feature that was causing "items.githubPRs" to display instead of the proper translated text. Added comprehensive i18n guidelines to CLAUDE.md to ensure all future frontend development follows the translation key pattern instead of using hardcoded strings. Also fixed missing deletePRReview mock function in browser-mock.ts to resolve TypeScript compilation errors. Changes: - Added githubPRs translation to en/navigation.json - Added githubPRs translation to fr/navigation.json - Added Development Guidelines section to CLAUDE.md with i18n requirements - Documented translation file locations and namespace usage patterns - Added deletePRReview mock function to browser-mock.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix ui loading * Github PR fixes * improve claude.md * lints/tests * fix(github): handle PRs exceeding GitHub's 20K line diff limit - Add PRTooLargeError exception for large PR detection - Update pr_diff() to catch and raise PRTooLargeError for HTTP 406 errors - Gracefully handle large PRs by skipping full diff and using individual file patches - Add diff_truncated flag to PRContext to track when diff was skipped - Large PRs will now review successfully using per-file diffs instead of failing Fixes issue with PR #252 which has 100+ files exceeding the 20,000 line limit. * fix: implement individual file patch fetching for large PRs The PR review was getting stuck for large PRs (>20K lines) because when we skipped the full diff due to GitHub API limits, we had no code to analyze. The individual file patches were also empty, leaving the AI with just file names and metadata. Changes: - Implemented _get_file_patch() to fetch individual patches via git diff - Updated PR review engine to build composite diff from file patches when diff_truncated is True - Added missing 'state' field to PRContext dataclass - Limits composite diff to first 50 files for very large PRs - Shows appropriate warnings when using reconstructed diffs This allows AI review to proceed with actual code analysis even when the full PR diff exceeds GitHub's limits. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * 1min reduction * docs: add GitHub Sponsors funding configuration Enable the Sponsor button on the repository by adding FUNDING.yml with the AndyMik90 GitHub Sponsors profile. * feat(github-pr): add orchestrating agent for thorough PR reviews Implement a new Opus 4.5 orchestrating agent that performs comprehensive PR reviews regardless of size. Key changes: - Add orchestrator_reviewer.py with strategic review workflow - Add review_tools.py with subagent spawning capabilities - Add pr_orchestrator.md prompt emphasizing thorough analysis - Add pr_security_agent.md and pr_quality_agent.md subagent prompts - Integrate orchestrator into pr_review_engine.py with config flag - Fix critical bug where findings were extracted but not processed (indentation issue in _parse_orchestrator_output) The orchestrator now correctly identifies issues in PRs that were previously approved as "trivial". Testing showed 7 findings detected vs 0 before the fix. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * i18n * fix(github-pr): restrict pr_reviewer to read-only permissions The PR review agent was using qa_reviewer agent type which has Bash access, allowing it to checkout branches and make changes during review. Created new pr_reviewer agent type with BASE_READ_TOOLS only (no Bash, no writes, no auto-claude tools). This prevents the PR review from accidentally modifying code or switching branches during analysis. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github-pr): robust category mapping and JSON parsing for PR review The orchestrator PR review was failing to extract findings because: 1. AI generates category names like 'correctness', 'consistency', 'testing' that aren't in our ReviewCategory enum - added flexible mapping 2. JSON sometimes embedded in markdown code blocks (```json) which broke parsing - added code block extraction as first parsing attempt Changes: - Add _CATEGORY_MAPPING dict to map AI categories to valid enum values - Add _map_category() helper function with fallback to QUALITY - Add severity parsing with fallback to MEDIUM - Add markdown code block detection (```json) before raw JSON parsing - Add _extract_findings_from_data() helper to reduce code duplication - Apply same fixes to review_tools.py for subagent parsing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(pr-review): improve post findings UX with batch support and feedback - Fix post findings failing on own PRs by falling back from REQUEST_CHANGES to COMMENT when GitHub returns 422 error - Change status badge to show "Reviewed" instead of "Commented" until findings are actually posted to GitHub - Add success notification when findings are posted (auto-dismisses after 3s) - Add batch posting support: track posted findings, show "Posted" badge, allow posting remaining findings in additional batches - Show loading state on button while posting 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): resolve stale timestamp and null author bugs - Fix stale timestamp in batch_issues.py: Move updated_at assignment BEFORE to_dict() serialization so the saved JSON contains the correct timestamp instead of the old value - Fix AttributeError in context_gatherer.py: Handle null author/user fields when GitHub API returns null for deleted/suspended users instead of an empty object 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address all high and medium severity PR review findings HIGH severity fixes: - Command Injection in autofix-handlers.ts: Use execFileSync with args array - Command Injection in pr-handlers.ts (3 locations): Use execFileSync + validation - Command Injection in triage-handlers.ts: Use execFileSync + label validation - Token Exposure in bot_detection.py: Pass token via GH_TOKEN env var MEDIUM severity fixes: - Environment variable leakage in subprocess-runner.ts: Filter to safe vars only - Debug logging in subprocess-runner.ts: Only log in development mode - Delimiter escape bypass in sanitize.py: Use regex pattern for variations - Insecure file permissions in trust.py: Use os.open with 0o600 mode - No file locking in learning.py: Use FileLock + atomic_write utilities - Bare except in confidence.py: Log error with specific exception info - Fragile module import in pr_review_engine.py: Import at module level - State transition validation in models.py: Enforce can_transition_to() 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * PR followup * fix(security): add usedforsecurity=False to MD5 hash calls MD5 is used for generating unique IDs/cache keys, not for security purposes. Adding usedforsecurity=False resolves Bandit B324 warnings. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address all high-priority PR review findings Fixes 5 high-priority issues from Auto Claude PR Review: 1. orchestrator_reviewer.py: Token budget tracking now increments total_tokens from API response usage data 2. pr_review_engine.py: Async exceptions now re-raise RuntimeError instead of silently returning empty results 3. batch_issues.py: IssueBatch.save() now uses locked_json_write for atomic file operations with file locking 4. project-middleware.ts: Added validateProjectPath() to prevent path traversal attacks (checks absolute, no .., exists, is dir) 5. orchestrator.py: Exception handling now logs full traceback and preserves exception type/context in error messages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address all high-priority PR review findings Fixes 5 high-priority issues from Auto Claude PR Review: 1. orchestrator_reviewer.py: Token budget tracking now increments total_tokens from API response usage data 2. pr_review_engine.py: Async exceptions now re-raise RuntimeError instead of silently returning empty results 3. batch_issues.py: IssueBatch.save() now uses locked_json_write for atomic file operations with file locking 4. project-middleware.ts: Added validateProjectPath() to prevent path traversal attacks (checks absolute, no .., exists, is dir) 5. orchestrator.py: Exception handling now logs full traceback and preserves exception type/context in error messages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(ui): add PR status labels to list view Add secondary status badges to the PR list showing review state at a glance: - "Changes Requested" (warning) - PRs with blocking issues (critical/high) - "Ready to Merge" (green) - PRs with only non-blocking suggestions - "Ready for Follow-up" (blue) - PRs with new commits since last review The "Ready for Follow-up" badge uses a cached new commits check from the store, only shown after the detail view confirms new commits via SHA comparison. This prevents false positives from PR updatedAt timestamp changes (which can happen from comments, labels, etc). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * PR labels * auto-claude: Initialize subtask-based implementation plan - Workflow type: feature - Phases: 3 - Subtasks: 6 - Ready for autonomous implementation --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * chore(deps): bump vitest from 4.0.15 to 4.0.16 in /apps/frontend (#272) Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.0.15 to 4.0.16. - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/vitest) --- updated-dependencies: - dependency-name: vitest dependency-version: 4.0.16 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @electron/rebuild in /apps/frontend (#271) Bumps [@electron/rebuild](https://github.com/electron/rebuild) from 3.7.2 to 4.0.2. - [Release notes](https://github.com/electron/rebuild/releases) - [Commits](https://github.com/electron/rebuild/compare/v3.7.2...v4.0.2) --- updated-dependencies: - dependency-name: "@electron/rebuild" dependency-version: 4.0.2 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * fix(paths): normalize relative paths to posix (#239) Co-authored-by: danielfrey63 <daniel.frey@sbb.ch> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * fix: accept bug_fix workflow_type alias during planning (#240) * fix(planning): accept bug_fix workflow_type alias * style(planning): ruff format * fix: refatored common logic * fix: remove ruff errors * fix: remove duplicate _normalize_workflow_type method Remove the incorrectly placed duplicate method inside ContextLoader class. The module-level function is the correct implementation being used. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: danielfrey63 <daniel.frey@sbb.ch> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(ci): use develop branch for dry-run builds in beta-release workflow (#276) When dry_run=true, the workflow skipped creating the version tag but build jobs still tried to checkout that non-existent tag, causing all 4 platform builds to fail with "git failed with exit code 1". Now build jobs checkout develop branch for dry runs while still using the version tag for real releases. Closes: GitHub Actions run #20464082726 * chore(deps): bump typescript-eslint in /apps/frontend (#269) Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.49.0 to 8.50.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.50.1/packages/typescript-eslint) --- updated-dependencies: - dependency-name: typescript-eslint dependency-version: 8.50.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * chore(deps): bump jsdom from 26.1.0 to 27.3.0 in /apps/frontend (#268) Bumps [jsdom](https://github.com/jsdom/jsdom) from 26.1.0 to 27.3.0. - [Release notes](https://github.com/jsdom/jsdom/releases) - [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md) - [Commits](https://github.com/jsdom/jsdom/compare/26.1.0...27.3.0) --- updated-dependencies: - dependency-name: jsdom dependency-version: 27.3.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * fix(ci): use correct electron-builder arch flags (#278) The project switched from pnpm to npm, which handles script argument passing differently. pnpm adds a -- separator that caused electron-builder to ignore the --arch argument, but npm passes it directly. Since --arch is a deprecated electron-builder argument, use the recommended flags instead: - --arch=x64 → --x64 - --arch=arm64 → --arm64 This fixes Mac Intel and ARM64 builds failing with "Unknown argument: arch" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): resolve CodeQL file system race conditions and unused variables (#277) * fix(security): resolve CodeQL file system race conditions and unused variables Fix high severity CodeQL alerts: - Remove TOCTOU (time-of-check-time-of-use) race conditions by eliminating existsSync checks followed by file operations. Use try-catch instead. - Files affected: pr-handlers.ts, spec-utils.ts Fix unused variable warnings: - Remove unused imports (FeatureModelConfig, FeatureThinkingConfig, withProjectSyncOrNull, getBackendPath, validateRunner, githubFetch) - Prefix intentionally unused destructured variables with underscore - Remove unused local variables (existing, actualEvent) - Files affected: pr-handlers.ts, autofix-handlers.ts, triage-handlers.ts, PRDetail.tsx, pr-review-store.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): resolve remaining CodeQL alerts for TOCTOU, network data validation, and unused variables Address CodeRabbit and CodeQL security alerts from PR #277 review: - HIGH: Fix 12+ file system race conditions (TOCTOU) by replacing existsSync() checks with try/catch blocks in pr-handlers.ts, autofix-handlers.ts, triage-handlers.ts, and spec-utils.ts - MEDIUM: Add sanitizeNetworkData() function to validate/sanitize GitHub API data before writing to disk, preventing injection attacks - Clean up 20+ unused variables, imports, and useless assignments across frontend components and handlers - Fix Python Protocol typing in testing.py (add return type annotations) All changes verified with TypeScript compilation and ESLint (no errors). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): resolve follow-up review API issues - Fix gh_client.py: use query string syntax for `since` parameter instead of `-f` flag which sends POST body fields, causing GitHub API errors - Fix followup_reviewer.py: use raw Anthropic client for message API calls instead of ClaudeSDKClient which is for agent sessions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore(deps): bump @xterm/xterm from 5.5.0 to 6.0.0 in /apps/frontend (#270) * chore(deps): bump @xterm/xterm from 5.5.0 to 6.0.0 in /apps/frontend Bumps [@xterm/xterm](https://github.com/xtermjs/xterm.js) from 5.5.0 to 6.0.0. - [Release notes](https://github.com/xtermjs/xterm.js/releases) - [Commits](https://github.com/xtermjs/xterm.js/compare/5.5.0...6.0.0) --- updated-dependencies: - dependency-name: "@xterm/xterm" dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * fix(deps): update xterm addons for 6.0.0 compatibility and use public APIs CRITICAL: Updated all xterm addons to versions compatible with xterm 6.0.0: - @xterm/addon-fit: ^0.10.0 → ^0.11.0 - @xterm/addon-serialize: ^0.13.0 → ^0.14.0 - @xterm/addon-web-links: ^0.11.0 → ^0.12.0 - @xterm/addon-webgl: ^0.18.0 → ^0.19.0 HIGH: Refactored scroll-controller.ts to use public xterm APIs: - Replaced internal _core access with public buffer/scroll APIs - Uses onScroll and onWriteParsed events for scroll tracking - Uses scrollLines() for scroll position restoration - Proper IDisposable cleanup for event listeners - Falls back gracefully if onWriteParsed is not available 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(ci): add write permissions to beta-release update-version job The update-version job needs contents: write permission to push the version bump commit and tag to the repository. Without this, the workflow fails with a 403 error when trying to git push. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: resolve spawn python ENOENT error on Linux by using getAugmentedEnv() (#281) - Use getAugmentedEnv() in project-context-handlers.ts to ensure Python is in PATH - Add /usr/bin and /usr/sbin to Linux paths in env-utils.ts for system Python - Fixes GUI-launched apps not inheriting shell environment on Ubuntu 24.04 Fixes #215 Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * feat(python): bundle Python 3.12 with packaged Electron app (#284) * feat(python): bundle Python 3.12 with packaged Electron app Resolves issue #258 where users with Python aliases couldn't run the app because shell aliases aren't visible to Electron's subprocess calls. Changes: - Add download-python.cjs script to fetch python-build-standalone - Bundle Python 3.12.8 in extraResources for packaged apps - Update python-detector.ts to prioritize bundled Python - Add Python caching to CI workflows for faster builds Packaged apps now include Python (~35MB), eliminating the need for users to have Python installed. Dev mode still falls back to system Python. Closes #258 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address PR review feedback for Python bundling Security improvements: - Add SHA256 checksum verification for downloaded Python binaries - Replace execSync with spawnSync to prevent command injection - Add input validation to prevent log injection from CLI args - Add download timeout (5 minutes) and redirect limit (10) - Proper file/connection cleanup on errors Bug fixes: - Fix platform naming mismatch: use "mac"/"win" (electron-builder) instead of "darwin"/"win32" (Node.js) for output directories - Handle empty path edge case in parsePythonCommand Improvements: - Add restore-keys to CI cache steps for better cache hit rates - Improve error messages and logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix mac node.js naming * security: add SHA256 checksums for all Python platforms Fetched actual checksums from python-build-standalone release: - darwin-arm64: abe1de24... - darwin-x64: 867c1af1... - win32-x64: 1a702b34... - linux-x64: 698e53b2... - linux-arm64: fb983ec8... All platforms now have cryptographic verification for downloaded Python binaries, eliminating the supply chain risk. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: add python-runtime to root .gitignore Ensures bundled Python runtime is ignored from both root and frontend .gitignore files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): validate backend source path before using it (#287) * fix(frontend): validate backend source path before using it The path resolver was returning invalid autoBuildPath settings without validating they contained the required backend files. When settings pointed to a legacy /auto-claude/ directory (missing requirements.txt and analyzer.py), the project indexer would fail with "can't open file" errors. Now validates that all source paths contain requirements.txt before returning them, falling back to bundled source path detection when the configured path is invalid. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: Initialize subtask-based implementation plan - Workflow type: feature - Phases: 4 - Subtasks: 9 - Ready for autonomous implementation Parallel execution enabled: phases 1 and 2 can run simultaneously * auto-claude: Initialize subtask-based implementation plan - Workflow type: investigation - Phases: 5 - Subtasks: 13 - Ready for autonomous implementation * fix merge conflict check loop * fix(frontend): add warning when fallback path is also invalid Address CodeRabbit review feedback - the fallback path in getBundledSourcePath() was returning an unvalidated path which could still cause the same analyzer.py error. Now logs a warning when the fallback path also lacks requirements.txt. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Potential fix for code scanning alert no. 224: Uncontrolled command line (#285) Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix(frontend): support archiving tasks across all worktree locations (#286) * archive across all worktress and if not in folder * fix(frontend): address PR security and race condition issues - Add taskId validation to prevent path traversal attacks - Fix TOCTOU race conditions in archiveTasks by removing existsSync - Fix TOCTOU race conditions in unarchiveTasks by removing existsSync 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): add explicit GET method to gh api comment fetches (#294) The gh api command defaults to POST for comment endpoints, causing GitHub to reject the 'since' query parameter as an invalid POST body field. Adding --method GET explicitly forces a GET request, allowing the since parameter to work correctly for fetching comments. This completes the fix started in f1cc5a09 which only changed from -f flag to query string syntax but didn't address the HTTP method. * feat: enhance the logs for the commit linting stage (#293) * ci: implement enterprise-grade PR quality gates and security scanning * ci: implement enterprise-grade PR quality gates and security scanning * fix:pr comments and improve code * fix: improve commit linting and code quality * Removed the dependency-review job (i added it) * fix: address CodeRabbit review comments - Expand scope pattern to allow uppercase, underscores, slashes, dots - Add concurrency control to cancel duplicate security scan runs - Add explanatory comment for Bandit CLI flags - Remove dependency-review job (requires repo settings) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: update commit lint examples with expanded scope patterns Show slashes and dots in scope examples to demonstrate the newly allowed characters (api/users, package.json) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: remove feature request issue template Feature requests are directed to GitHub Discussions via the issue template config.yml 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address security vulnerabilities in service orchestrator - Fix port parsing crash on malformed docker-compose entries - Fix shell injection risk by using shlex.split() with shell=False Prevents crashes when docker-compose.yml contains environment variables in port mappings (e.g., '${PORT}:8080') and eliminates shell injection vulnerabilities in subprocess execution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(ci): improve PR title validation error messages with examples Add helpful console output when PR title validation fails: - Show expected format and valid types - Provide examples of valid PR titles - Display the user's current title - Suggest fixes based on keywords in the title - Handle verb variations (fixed, adding, updated, etc.) - Show placeholder when description is empty after cleanup 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * lower coverage * feat: improve status gate to label correctly based on required checks * fix(ci): address PR review findings for security and efficiency - Add explicit permissions block to ci.yml (least privilege principle) - Skip duplicate test run for Python 3.12 (tests with coverage only) - Sanitize PR title in markdown output to prevent injection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix typo --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * feat(merge,oauth): add path-aware AI merge resolution and device code streaming (#296) * improve/merge-confclit-layer * improve AI resolution * fix caching on merge conflicts * imrpove merge layer with rebase * fix(github): add OAuth authentication to follow-up PR review The follow-up PR review AI analysis was failing with "Could not resolve authentication method" because AsyncAnthropic() was instantiated without credentials. The codebase uses OAuth tokens (not ANTHROPIC_API_KEY), so the client needs the auth_token parameter. Uses get_auth_token() from core.auth to retrieve the OAuth token from environment variables or macOS Keychain, matching how initial reviews authenticate via create_client(). * fix(merge): add validation to prevent AI writing natural language to files When AI merge receives truncated file contents (due to character limits), it sometimes responds with explanations like "I need to see the complete file contents..." instead of actual merged code. This garbage was being written directly to source files. Adds two validation layers after AI merge: 1. Natural language detection - catches patterns like "I need to", "Let me" 2. Syntax validation - uses esbuild to verify TypeScript/JavaScript syntax If either validation fails, the merge returns an error instead of writing invalid content to the file. Also adds project_dir field to ParallelMergeTask to enable syntax validation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(merge): skip git merge when AI already resolved path-mapped files When AI successfully merges path-mapped files (due to file renames between branches), the check only looked at `conflicts_resolved` which was 0 for path-mapped cases. This caused the code to fall through to `git merge` which then failed with conflicts. Now also checks `files_merged` and `ai_assisted` stats to determine if AI has already handled the merge. When files are AI-merged, they're already written and staged - no need for git merge. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix device code issue with github * fix(frontend): remember GitHub auth method (OAuth vs PAT) in settings Previously, after authenticating via GitHub OAuth, the settings page would show "Personal Access Token" input even though OAuth was used. This was confusing for users who expected to see their OAuth status. Added githubAuthMethod field to track how authentication was performed. Settings UI now shows "Authenticated via GitHub OAuth" when OAuth was used, with option to switch to manual token if needed. The auth method persists across settings reopening. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(backend): centralize OAuth client creation in core/client.py - Add create_message_client() for simple message API calls - Refactor followup_reviewer.py to use centralized client factory - Remove direct anthropic.AsyncAnthropic import from followup_reviewer - Add proper ValueError handling for missing OAuth token - Update docstrings to document both client factories This ensures all AI interactions use the centralized OAuth authentication in core/, avoiding direct ANTHROPIC_API_KEY usage per CLAUDE.md guidelines. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): remove unused statusColor variable in WorkspaceStatus Dead code cleanup - the statusColor variable was computed but never used in the component. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(tests): add BrowserWindow mock to oauth-handlers tests The sendDeviceCodeToRenderer function uses BrowserWindow.getAllWindows() which wasn't mocked, causing unhandled rejection errors in tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(backend): use ClaudeSDKClient instead of raw anthropic SDK Remove direct anthropic SDK import from core/client.py and update followup_reviewer.py to use ClaudeSDKClient directly as per project conventions. All AI interactions should use claude-agent-sdk. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(backend): add debug logging for AI response in followup_reviewer Add logging to diagnose why AI review returns no JSON - helps identify if response is in thinking blocks vs text blocks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Fix/2.7.2 fixes (#300) * fix(frontend): prevent false stuck detection for ai_review tasks Tasks in ai_review status were incorrectly showing "Task Appears Stuck" in the detail modal. This happened because the isRunning check included ai_review status, triggering stuck detection when no process was found. However, ai_review means "all subtasks completed, awaiting QA" - no build process is expected to be running. This aligns the detail modal logic with TaskCard which correctly only checks for in_progress status. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * ci(beta-release): use tag-based versioning instead of modifying package.json Previously the beta-release workflow committed version changes to package.json on the develop branch, which caused two issues: 1. Permission errors (github-actions[bot] denied push access) 2. Beta versions polluted develop, making merges to main unclean Now the workflow creates only a git tag and injects the version at build time using electron-builder's --config.extraMetadata.version flag. This keeps package.json at the next stable version and avoids any commits to develop. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ollama): add packaged app path resolution for Ollama detector script The Ollama detection was failing in packaged builds because the Python script path resolution only checked development paths. In packaged apps, __dirname points to the app bundle, and the relative path "../../../backend" doesn't resolve correctly. Added process.resourcesPath for packaged builds (checked first via app.isPackaged) which correctly locates the backend scripts in the Resources folder. Also added DEBUG-only logging to help troubleshoot script location issues. Closes #129 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(paths): remove legacy auto-claude path fallbacks Replace all legacy 'auto-claude/' source path detection with 'apps/backend'. Services now validate paths using runners/spec_runner.py as the marker instead of requirements.txt, ensuring only valid backend directories match. - Remove legacy fallback paths from all getAutoBuildSourcePath() implementations - Add startup validation in index.ts to skip invalid saved paths - Update project-initializer to detect apps/backend for local dev projects - Standardize path detection across all services 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): address PR review feedback from Auto Claude and bots Fixes from PR #300 reviews: CRITICAL: - path-resolver.ts: Update marker from requirements.txt to runners/spec_runner.py for consistent backend detection across all files HIGH: - useTaskDetail.ts: Restore stuck task detection for ai_review status (CHANGELOG documents this feature) - TerminalGrid.tsx: Include legacy terminals without projectPath (prevents hiding terminals after upgrade) - memory-handlers.ts: Add packaged app path in OLLAMA_PULL_MODEL handler (fixes production builds) MEDIUM: - OAuthStep.tsx: Stricter profile slug sanitization (only allow alphanumeric and dashes) - project-store.ts: Fix regex to not truncate at # in code blocks (uses \n#{1,6}\s to match valid markdown headings only) - memory-service.ts: Add backend structure validation with spec_runner.py marker - subprocess-spawn.test.ts: Update test to use new marker pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): validate empty profile slug after sanitization Add validation to prevent empty config directory path when profile name contains only special characters (e.g., "!!!"). Shows user-friendly error message requiring at least one letter or number. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix: stop tracking spec files in git (#295) * fix: stop tracking spec files in git - Remove git commit instructions from planner.md for spec files - Spec files (implementation_plan.json, init.sh, build-progress.txt) should be gitignored - Untrack existing spec files that were accidentally committed - AI agents should only commit code changes, not spec metadata The .auto-claude/specs/ directory is gitignored by design - spec files are local project metadata that shouldn't be version controlled. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(prompts): remove git commit instructions for gitignored spec files The spec files (build-progress.txt, qa_report.md, implementation_plan.json, QA_FIX_REQUEST.md) are all stored in .auto-claude/specs/ which is gitignored. Removed instructions telling agents to commit these files, replaced with notes explaining they're tracked automatically by the framework. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(build): add --force-local flag to tar on Windows (#303) On Windows, paths like D:\path are misinterpreted by tar as remote host:path syntax (Unix tar convention). Adding --force-local tells tar to treat colons as part of the filename, fixing the extraction failure in GitHub Actions Windows builds. Error was: "tar (child): Cannot connect to D: resolve failed" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(build): use PowerShell for tar extraction on Windows The previous fix using --force-local and path conversion still failed due to shell escaping issues. PowerShell handles Windows paths natively and has built-in tar support on Windows 10+, avoiding all path escaping problems. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): add augmented PATH env to all gh CLI calls When running from a packaged macOS app (.dmg), the PATH environment variable doesn't include common locations like /opt/homebrew/bin where gh is typically installed via Homebrew. The getAugmentedEnv() function was already being used in some places but was missing from: - spawn() call in registerStartGhAuth - execSync calls for gh auth token, gh api user, gh repo list - execFileSync calls for gh api, gh repo create - execFileSync calls in pr-handlers.ts and triage-handlers.ts This caused "gh: command not found" errors when connecting projects to GitHub in the packaged app. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(build): use explicit Windows System32 tar path (#308) The previous PowerShell fix still found Git Bash's /usr/bin/tar which interprets D: as a remote host. Using the explicit path to Windows' built-in bsdtar (C:\Windows\System32\tar.exe) avoids this issue. Windows Server 2019+ (GitHub Actions) has bsdtar in System32. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * chore(ci): cancel in-progress runs (#302) Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> Co-authored-by: Alex <63423455+AlexMadera@users.noreply.github.com> * fix(python): use venv Python for all services to fix dotenv errors (#311) * fix(python): use venv Python for all services to fix dotenv errors Services were spawning Python processes using findPythonCommand() which returns the bundled Python directly. However, dependencies like python-dotenv are only installed in the venv created from the bundled Python. Changes: - Add getConfiguredPythonPath() helper that returns venv Python when ready - Update all services to use venv Python instead of bundled Python directly: - memory-service.ts - memory-handlers.ts - agent-process.ts - changelog-service.ts - title-generator.ts - insights/config.ts - project-context-handlers.ts - worktree-handlers.ts - Fix availability checks to use findPythonCommand() (can return null) - Add python:verify script for bundling verification The flow now works correctly: 1. App starts → findPythonCommand() finds bundled Python 2. pythonEnvManager creates venv using bundled Python 3. pip installs dependencies (dotenv, claude-agent-sdk, etc.) 4. All services use venv Python → has all dependencies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix lintin and test --------- Co-authored-by: Claude <noreply@anthropic.com> * fix(updater): proper semver comparison for pre-release versions (#313) Fixes the beta auto-update bug where the app was offering downgrades (e.g., showing v2.7.1 as "new version available" when on v2.7.2-beta.6). Changes: - version-manager.ts: New parseVersion() function that separates base version from pre-release suffix. Updated compareVersions() to handle pre-release versions correctly (alpha < beta < rc < stable). - app-updater.ts: Import and use compareVersions() for proper version comparison instead of simple string inequality. - Added comprehensive unit tests for version comparison logic. Pre-release ordering: - 2.7.1 < 2.7.2-alpha.1 < 2.7.2-beta.1 < 2.7.2-rc.1 < 2.7.2 (stable) - 2.7.2-beta.6 < 2.7.2-beta.7 * fix(project): fix task status persistence reverting on refresh (#246) (#318) Correctly validate persisted task status against calculated status. Previously, if a task was 'in_progress' but had no active subtasks (e.g. still in planning or between phases), the calculated status 'backlog' would override the stored status, causing the UI to revert to 'Start'. This fix adds 'in_progress' to the list of active process statuses and explicitly allows 'in_progress' status to persist when the underlying plan status is also 'in_progress'. * fix(ci): add auto-updater manifest files and version auto-update (#317) Combined PR with: 1. Alex's version auto-update changes from PR #316 2. Auto-updater manifest file generation fix Changes: - Add --publish never to package scripts to generate .yml manifests - Update all build jobs to upload .yml files as artifacts - Update release step to include .yml files in GitHub release - Auto-bump version in package.json files before tagging This enables the in-app auto-updater to work properly by ensuring latest-mac.yml, latest-linux.yml, and latest.yml are published with each release. Co-authored-by: Alex <63423455+AlexMadera@users.noreply.github.com> * f…
…ik90#1038) * feat: Add OpenRouter as LLM/embedding provider (#162) * feat: Add OpenRouter as LLM/embedding provider Add OpenRouter provider support for Graphiti memory integration, enabling access to multiple LLM providers through a single API. Changes: Backend: - Created openrouter_llm.py: OpenRouter LLM provider using OpenAI-compatible API - Created openrouter_embedder.py: OpenRouter embedder provider - Updated config.py: Added OpenRouter to provider enums and configuration - New fields: openrouter_api_key, openrouter_base_url, openrouter_llm_model, openrouter_embedding_model - Validation methods updated for OpenRouter - Updated factory.py: Added OpenRouter to LLM and embedder factories - Updated provider __init__.py files: Exported new OpenRouter functions Frontend: - Updated project.ts types: Added 'openrouter' to provider type unions - GraphitiProviderConfig extended with OpenRouter fields - Updated GraphitiStep.tsx: Added OpenRouter to provider arrays - LLM_PROVIDERS: 'Multi-provider aggregator' - EMBEDDING_PROVIDERS: 'OpenAI-compatible embeddings' - Added OpenRouter API key input field with show/hide toggle - Link to https://openrouter.ai/keys - Updated env-handlers.ts: OpenRouter .env generation and parsing - Template generation for OPENROUTER_* variables - Parsing from .env files with proper type casting Documentation: - Updated .env.example with OpenRouter section - Configuration examples - Popular model recommendations - Example configuration (#6) Fixes #92 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor: address CodeRabbit review comments for OpenRouter - Add globalOpenRouterApiKey to settings types and store updates - Initialize openrouterApiKey from global settings - Update documentation to include OpenRouter in provider lists - Add OpenRouter handling to get_embedding_dimension() method - Add openrouter to provider cleanup list - Add OpenRouter to get_available_providers() function - Clarify Legacy comment for openrouterLlmModel These changes complete the OpenRouter integration by ensuring proper settings persistence and provider detection across the application. * fix: apply ruff formatting to OpenRouter code - Break long error message across multiple lines - Format provider list with one item per line - Fixes lint CI failure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(core): add global spec numbering lock to prevent collisions (#209) Implements distributed file-based locking for spec number coordination across main project and all worktrees. Previously, parallel spec creation could assign the same number to different specs (e.g., 042-bmad-task and 042-gitlab-integration both using number 042). The fix adds SpecNumberLock class that: - Acquires exclusive lock before calculating spec numbers - Scans ALL locations (main project + worktrees) for global maximum - Creates spec directories atomically within the lock - Handles stale locks via PID-based detection with 30s timeout Applied to both Python backend (spec_runner.py flow) and TypeScript frontend (ideation conversion, GitHub/GitLab issue import). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Fix/ideation status sync (#212) * fix(ideation): add missing event forwarders for status sync - Add event forwarders in ideation-handlers.ts for progress, log, type-complete, type-failed, complete, error, and stopped events - Fix ideation-type-complete to load actual ideas array from JSON files instead of emitting only the count Resolves UI getting stuck at 0/3 complete during ideation generation. * fix(ideation): fix UI not updating after actions - Fix getIdeationSummary to count only active ideas (exclude dismissed/archived) This ensures header stats match the visible ideas count - Add transformSessionFromSnakeCase to properly transform session data from backend snake_case to frontend camelCase on ideation-complete event - Transform raw session before emitting ideation-complete event Resolves header showing stale counts after dismissing/deleting ideas. * fix(ideation): improve type safety and async handling in ideation type completion - Replace synchronous readFileSync with async fsPromises.readFile in ideation-type-complete handler - Wrap async file read in IIFE with proper error handling to prevent unhandled promise rejections - Add type validation for IdeationType with VALID_IDEATION_TYPES set and isValidIdeationType guard - Add validateEnabledTypes function to filter out invalid type values and log dropped entries - Handle ENOENT separately * fix(ideation): improve generation state management and error handling - Add explicit isGenerating flag to prevent race conditions during async operations - Implement 5-minute timeout for generation with automatic cleanup and error state - Add ideation-stopped event emission when process is intentionally killed - Replace console.warn/error with proper ideation-error events in agent-queue - Add resetGeneratingTypes helper to transition all generating types to a target state - Filter out dismissed/ * refactor(ideation): improve event listener cleanup and timeout management - Extract event handler functions in ideation-handlers.ts to enable proper cleanup - Return cleanup function from registerIdeationHandlers to remove all listeners - Replace single generationTimeoutId with Map to support multiple concurrent projects - Add clearGenerationTimeout helper to centralize timeout cleanup logic - Extract loadIdeationType IIFE to named function for better error context - Enhance error logging with projectId, * refactor: use async file read for ideation and roadmap session loading - Replace synchronous readFileSync with async fsPromises.readFile - Prevents blocking the event loop during file operations - Consistent with async pattern used elsewhere in the codebase - Improved error handling with proper event emission * fix(agent-queue): improve roadmap completion handling and error reporting - Add transformRoadmapFromSnakeCase to convert backend snake_case to frontend camelCase - Transform raw roadmap data before emitting roadmap-complete event - Add roadmap-error emission for unexpected errors during completion - Add roadmap-error emission when project path is unavailable - Remove duplicate ideation-type-complete emission from error handler (event already emitted in loadIdeationType) - Update error log message * fix: add future annotations import to discovery.py (#229) Adds 'from __future__ import annotations' to spec/discovery.py for Python 3.9+ compatibility with type hints. This completes the Python compatibility fixes that were partially applied in previous commits. All 26 analysis and spec Python files now have the future annotations import. Related: #128 Co-authored-by: Joris Slagter <mail@jorisslagter.nl> * fix: resolve Python detection and backend packaging issues (#241) * fix: resolve Python detection and backend packaging issues - Fix backend packaging path (auto-claude -> backend) to match path-resolver.ts expectations - Add future annotations import to config_parser.py for Python 3.9+ compatibility - Use findPythonCommand() in project-context-handlers to prioritize Homebrew Python - Improve Python detection to prefer Homebrew paths over system Python on macOS This resolves the following issues: - 'analyzer.py not found' error due to incorrect packaging destination - TypeError with 'dict | None' syntax on Python < 3.10 - Wrong Python interpreter being used (system Python instead of Homebrew Python 3.10+) Tested on macOS with packaged app - project index now loads successfully. * refactor: address PR review feedback - Extract findHomebrewPython() helper to eliminate code duplication between findPythonCommand() and getDefaultPythonCommand() - Remove hardcoded version-specific paths (python3.12) and rely only on generic Homebrew symlinks for better maintainability - Remove unnecessary 'from __future__ import annotations' from config_parser.py since backend requires Python 3.12+ where union types are native These changes make the code more maintainable, less fragile to Python version changes, and properly reflect the project's Python 3.12+ requirement. * Feat/Auto Fix Github issues and do extensive AI PR reviews (#250) * feat(github): add GitHub automation system for issues and PRs Implements comprehensive GitHub automation with three major components: 1. Issue Auto-Fix: Automatically creates specs from labeled issues - AutoFixButton component with progress tracking - useAutoFix hook for config and queue management - Backend handlers for spec creation from issues 2. GitHub PRs Tool: AI-powered PR review sidebar - New sidebar tab (Cmd+Shift+P) alongside GitHub Issues - PRList/PRDetail components for viewing PRs - Review system with findings by severity - Post review comments to GitHub 3. Issue Triage: Duplicate/spam/feature-creep detection - Triage handlers with label application - Configurable detection thresholds Also adds: - Debug logging (DEBUG=true) for all GitHub handlers - Backend runners/github module with orchestrator - AI prompts for PR review, triage, duplicate/spam detection - dev:debug npm script for development with logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github-runner): resolve import errors for direct script execution Changes runner.py and orchestrator.py to handle both: - Package import: `from runners.github import ...` - Direct script: `python runners/github/runner.py` Uses try/except pattern for relative vs direct imports. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): correct argparse argument order for runner.py Move --project global argument before subcommand so argparse can correctly parse it. Fixes "unrecognized arguments: --project" error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * logs when debug mode is on * refactor(github): extract service layer and fix linting errors Major refactoring to improve maintainability and code quality: Backend (Python): - Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules: - prompt_manager.py: Prompt template management - response_parsers.py: AI response parsing - pr_review_engine.py: PR review orchestration - triage_engine.py: Issue triage logic - autofix_processor.py: Auto-fix workflow - batch_processor.py: Batch issue handling - Fixed 18 ruff linting errors (F401, C405, C414, E741): - Removed unused imports (BatchValidationResult, AuditAction, locked_json_write) - Optimized collection literals (set([n]) → {n}) - Removed unnecessary list() calls - Renamed ambiguous variable 'l' to 'label' throughout Frontend (TypeScript): - Refactored IPC handlers (19% overall reduction) with shared utilities: - autofix-handlers.ts: 1,042 → 818 lines - pr-handlers.ts: 648 → 543 lines - triage-handlers.ts: 437 lines (no duplication) - Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner - Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status - Split ReviewFindings.tsx into focused components All imports verified, type checks passing, linting clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Revert "Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)" (#251) This reverts commit 348de6dfe793ab111043677c61b8452bc5ecb2cc. * feat: add i18n internationalization system (#248) * Add multilingual support and i18n integration - Implemented i18n framework using `react-i18next` for translation management. - Added support for English and French languages with translation files. - Integrated language selector into settings. - Updated all text strings in UI components to use translation keys. - Ensured smooth language switching with live updates. * Migrate remaining hard-coded strings to i18n system - TaskCard: status labels, review reasons, badges, action buttons - PhaseProgressIndicator: execution phases, progress labels - KanbanBoard: drop zone, show archived, tooltips - CustomModelModal: dialog title, description, labels - ProactiveSwapListener: account switch notifications - AgentProfileSelector: phase labels, custom configuration - GeneralSettings: agent framework option Added translation keys for en/fr locales in tasks.json, common.json, and settings.json for complete i18n coverage. * Add i18n support to dialogs and settings components - AddFeatureDialog: form labels, validation messages, buttons - AddProjectModal: dialog steps, form fields, actions - RateLimitIndicator: rate limit notifications - RateLimitModal: account switching, upgrade prompts - AdvancedSettings: updates and notifications sections - ThemeSettings: theme selection labels - Updated dialogs.json locales (en/fr) * Fix truncated 'ready' message in dialogs locales * Fix backlog terminology in i18n locales Change "Planning"/"Planification" to standard PM term "Backlog" * Migrate settings navigation and integration labels to i18n - AppSettings: nav items, section titles, buttons - IntegrationSettings: Claude accounts, auto-switch, API keys labels - Added settings nav/projectSections/integrations translation keys - Added buttons.saving to common translations * Migrate AgentProfileSettings and Sidebar init dialog to i18n - AgentProfileSettings: migrate phase config labels, section title, description, and all hardcoded strings to settings namespace - Sidebar: migrate init dialog strings to dialogs namespace with common buttons from common namespace - Add new translation keys for agent profile settings and update dialog * Migrate AppSettings navigation labels to i18n - Add useTranslation hook to AppSettings.tsx - Replace hardcoded section labels with dynamic translations - Add projectSections translations for project settings nav - Add rerunWizardDescription translation key * Add explicit typing to notificationItems array Import NotificationSettings type and use keyof to properly type the notification item keys, removing manual type assertion. * fix: update path resolution for ollama_model_detector.py in memory handlers (#263) * ci: implement enterprise-grade PR quality gates and security scanning (#266) * ci: implement enterprise-grade PR quality gates and security scanning * ci: implement enterprise-grade PR quality gates and security scanning * fix:pr comments and improve code * fix: improve commit linting and code quality * Removed the dependency-review job (i added it) * fix: address CodeRabbit review comments - Expand scope pattern to allow uppercase, underscores, slashes, dots - Add concurrency control to cancel duplicate security scan runs - Add explanatory comment for Bandit CLI flags - Remove dependency-review job (requires repo settings) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: update commit lint examples with expanded scope patterns Show slashes and dots in scope examples to demonstrate the newly allowed characters (api/users, package.json) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: remove feature request issue template Feature requests are directed to GitHub Discussions via the issue template config.yml 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address security vulnerabilities in service orchestrator - Fix port parsing crash on malformed docker-compose entries - Fix shell injection risk by using shlex.split() with shell=False Prevents crashes when docker-compose.yml contains environment variables in port mappings (e.g., '${PORT}:8080') and eliminates shell injection vulnerabilities in subprocess execution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * feat(github): add automated PR review with follow-up support (#252) * feat(github): add GitHub automation system for issues and PRs Implements comprehensive GitHub automation with three major components: 1. Issue Auto-Fix: Automatically creates specs from labeled issues - AutoFixButton component with progress tracking - useAutoFix hook for config and queue management - Backend handlers for spec creation from issues 2. GitHub PRs Tool: AI-powered PR review sidebar - New sidebar tab (Cmd+Shift+P) alongside GitHub Issues - PRList/PRDetail components for viewing PRs - Review system with findings by severity - Post review comments to GitHub 3. Issue Triage: Duplicate/spam/feature-creep detection - Triage handlers with label application - Configurable detection thresholds Also adds: - Debug logging (DEBUG=true) for all GitHub handlers - Backend runners/github module with orchestrator - AI prompts for PR review, triage, duplicate/spam detection - dev:debug npm script for development with logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github-runner): resolve import errors for direct script execution Changes runner.py and orchestrator.py to handle both: - Package import: `from runners.github import ...` - Direct script: `python runners/github/runner.py` Uses try/except pattern for relative vs direct imports. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): correct argparse argument order for runner.py Move --project global argument before subcommand so argparse can correctly parse it. Fixes "unrecognized arguments: --project" error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * logs when debug mode is on * refactor(github): extract service layer and fix linting errors Major refactoring to improve maintainability and code quality: Backend (Python): - Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules: - prompt_manager.py: Prompt template management - response_parsers.py: AI response parsing - pr_review_engine.py: PR review orchestration - triage_engine.py: Issue triage logic - autofix_processor.py: Auto-fix workflow - batch_processor.py: Batch issue handling - Fixed 18 ruff linting errors (F401, C405, C414, E741): - Removed unused imports (BatchValidationResult, AuditAction, locked_json_write) - Optimized collection literals (set([n]) → {n}) - Removed unnecessary list() calls - Renamed ambiguous variable 'l' to 'label' throughout Frontend (TypeScript): - Refactored IPC handlers (19% overall reduction) with shared utilities: - autofix-handlers.ts: 1,042 → 818 lines - pr-handlers.ts: 648 → 543 lines - triage-handlers.ts: 437 lines (no duplication) - Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner - Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status - Split ReviewFindings.tsx into focused components All imports verified, type checks passing, linting clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fixes during testing of PR * feat(github): implement PR merge, assign, and comment features - Add auto-assignment when clicking "Run AI Review" - Implement PR merge functionality with squash method - Add ability to post comments on PRs - Display assignees in PR UI - Add Approve and Merge buttons when review passes - Update backend gh_client with pr_merge, pr_comment, pr_assign methods - Create IPC handlers for new PR operations - Update TypeScript interfaces and browser mocks 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Improve PR review AI * fix(github): use temp files for PR review posting to avoid shell escaping issues When posting PR reviews with findings containing special characters (backticks, parentheses, quotes), the shell command was interpreting them as commands instead of literal text, causing syntax errors. Changed both postPRReview and postPRComment handlers to write the body content to temporary files and use gh CLI's --body-file flag instead of --body with inline content. This safely handles ALL special characters without escaping issues. Fixes shell errors when posting reviews with suggested fixes containing code snippets. * fix(i18n): add missing GitHub PRs translation and document i18n requirements Fixed missing translation key for GitHub PRs feature that was causing "items.githubPRs" to display instead of the proper translated text. Added comprehensive i18n guidelines to CLAUDE.md to ensure all future frontend development follows the translation key pattern instead of using hardcoded strings. Also fixed missing deletePRReview mock function in browser-mock.ts to resolve TypeScript compilation errors. Changes: - Added githubPRs translation to en/navigation.json - Added githubPRs translation to fr/navigation.json - Added Development Guidelines section to CLAUDE.md with i18n requirements - Documented translation file locations and namespace usage patterns - Added deletePRReview mock function to browser-mock.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix ui loading * Github PR fixes * improve claude.md * lints/tests * fix(github): handle PRs exceeding GitHub's 20K line diff limit - Add PRTooLargeError exception for large PR detection - Update pr_diff() to catch and raise PRTooLargeError for HTTP 406 errors - Gracefully handle large PRs by skipping full diff and using individual file patches - Add diff_truncated flag to PRContext to track when diff was skipped - Large PRs will now review successfully using per-file diffs instead of failing Fixes issue with PR #252 which has 100+ files exceeding the 20,000 line limit. * fix: implement individual file patch fetching for large PRs The PR review was getting stuck for large PRs (>20K lines) because when we skipped the full diff due to GitHub API limits, we had no code to analyze. The individual file patches were also empty, leaving the AI with just file names and metadata. Changes: - Implemented _get_file_patch() to fetch individual patches via git diff - Updated PR review engine to build composite diff from file patches when diff_truncated is True - Added missing 'state' field to PRContext dataclass - Limits composite diff to first 50 files for very large PRs - Shows appropriate warnings when using reconstructed diffs This allows AI review to proceed with actual code analysis even when the full PR diff exceeds GitHub's limits. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * 1min reduction * docs: add GitHub Sponsors funding configuration Enable the Sponsor button on the repository by adding FUNDING.yml with the AndyMik90 GitHub Sponsors profile. * feat(github-pr): add orchestrating agent for thorough PR reviews Implement a new Opus 4.5 orchestrating agent that performs comprehensive PR reviews regardless of size. Key changes: - Add orchestrator_reviewer.py with strategic review workflow - Add review_tools.py with subagent spawning capabilities - Add pr_orchestrator.md prompt emphasizing thorough analysis - Add pr_security_agent.md and pr_quality_agent.md subagent prompts - Integrate orchestrator into pr_review_engine.py with config flag - Fix critical bug where findings were extracted but not processed (indentation issue in _parse_orchestrator_output) The orchestrator now correctly identifies issues in PRs that were previously approved as "trivial". Testing showed 7 findings detected vs 0 before the fix. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * i18n * fix(github-pr): restrict pr_reviewer to read-only permissions The PR review agent was using qa_reviewer agent type which has Bash access, allowing it to checkout branches and make changes during review. Created new pr_reviewer agent type with BASE_READ_TOOLS only (no Bash, no writes, no auto-claude tools). This prevents the PR review from accidentally modifying code or switching branches during analysis. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github-pr): robust category mapping and JSON parsing for PR review The orchestrator PR review was failing to extract findings because: 1. AI generates category names like 'correctness', 'consistency', 'testing' that aren't in our ReviewCategory enum - added flexible mapping 2. JSON sometimes embedded in markdown code blocks (```json) which broke parsing - added code block extraction as first parsing attempt Changes: - Add _CATEGORY_MAPPING dict to map AI categories to valid enum values - Add _map_category() helper function with fallback to QUALITY - Add severity parsing with fallback to MEDIUM - Add markdown code block detection (```json) before raw JSON parsing - Add _extract_findings_from_data() helper to reduce code duplication - Apply same fixes to review_tools.py for subagent parsing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(pr-review): improve post findings UX with batch support and feedback - Fix post findings failing on own PRs by falling back from REQUEST_CHANGES to COMMENT when GitHub returns 422 error - Change status badge to show "Reviewed" instead of "Commented" until findings are actually posted to GitHub - Add success notification when findings are posted (auto-dismisses after 3s) - Add batch posting support: track posted findings, show "Posted" badge, allow posting remaining findings in additional batches - Show loading state on button while posting 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): resolve stale timestamp and null author bugs - Fix stale timestamp in batch_issues.py: Move updated_at assignment BEFORE to_dict() serialization so the saved JSON contains the correct timestamp instead of the old value - Fix AttributeError in context_gatherer.py: Handle null author/user fields when GitHub API returns null for deleted/suspended users instead of an empty object 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address all high and medium severity PR review findings HIGH severity fixes: - Command Injection in autofix-handlers.ts: Use execFileSync with args array - Command Injection in pr-handlers.ts (3 locations): Use execFileSync + validation - Command Injection in triage-handlers.ts: Use execFileSync + label validation - Token Exposure in bot_detection.py: Pass token via GH_TOKEN env var MEDIUM severity fixes: - Environment variable leakage in subprocess-runner.ts: Filter to safe vars only - Debug logging in subprocess-runner.ts: Only log in development mode - Delimiter escape bypass in sanitize.py: Use regex pattern for variations - Insecure file permissions in trust.py: Use os.open with 0o600 mode - No file locking in learning.py: Use FileLock + atomic_write utilities - Bare except in confidence.py: Log error with specific exception info - Fragile module import in pr_review_engine.py: Import at module level - State transition validation in models.py: Enforce can_transition_to() 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * PR followup * fix(security): add usedforsecurity=False to MD5 hash calls MD5 is used for generating unique IDs/cache keys, not for security purposes. Adding usedforsecurity=False resolves Bandit B324 warnings. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address all high-priority PR review findings Fixes 5 high-priority issues from Auto Claude PR Review: 1. orchestrator_reviewer.py: Token budget tracking now increments total_tokens from API response usage data 2. pr_review_engine.py: Async exceptions now re-raise RuntimeError instead of silently returning empty results 3. batch_issues.py: IssueBatch.save() now uses locked_json_write for atomic file operations with file locking 4. project-middleware.ts: Added validateProjectPath() to prevent path traversal attacks (checks absolute, no .., exists, is dir) 5. orchestrator.py: Exception handling now logs full traceback and preserves exception type/context in error messages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address all high-priority PR review findings Fixes 5 high-priority issues from Auto Claude PR Review: 1. orchestrator_reviewer.py: Token budget tracking now increments total_tokens from API response usage data 2. pr_review_engine.py: Async exceptions now re-raise RuntimeError instead of silently returning empty results 3. batch_issues.py: IssueBatch.save() now uses locked_json_write for atomic file operations with file locking 4. project-middleware.ts: Added validateProjectPath() to prevent path traversal attacks (checks absolute, no .., exists, is dir) 5. orchestrator.py: Exception handling now logs full traceback and preserves exception type/context in error messages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(ui): add PR status labels to list view Add secondary status badges to the PR list showing review state at a glance: - "Changes Requested" (warning) - PRs with blocking issues (critical/high) - "Ready to Merge" (green) - PRs with only non-blocking suggestions - "Ready for Follow-up" (blue) - PRs with new commits since last review The "Ready for Follow-up" badge uses a cached new commits check from the store, only shown after the detail view confirms new commits via SHA comparison. This prevents false positives from PR updatedAt timestamp changes (which can happen from comments, labels, etc). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * PR labels * auto-claude: Initialize subtask-based implementation plan - Workflow type: feature - Phases: 3 - Subtasks: 6 - Ready for autonomous implementation --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * chore(deps): bump vitest from 4.0.15 to 4.0.16 in /apps/frontend (#272) Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.0.15 to 4.0.16. - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/vitest) --- updated-dependencies: - dependency-name: vitest dependency-version: 4.0.16 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @electron/rebuild in /apps/frontend (#271) Bumps [@electron/rebuild](https://github.com/electron/rebuild) from 3.7.2 to 4.0.2. - [Release notes](https://github.com/electron/rebuild/releases) - [Commits](https://github.com/electron/rebuild/compare/v3.7.2...v4.0.2) --- updated-dependencies: - dependency-name: "@electron/rebuild" dependency-version: 4.0.2 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * fix(paths): normalize relative paths to posix (#239) Co-authored-by: danielfrey63 <daniel.frey@sbb.ch> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * fix: accept bug_fix workflow_type alias during planning (#240) * fix(planning): accept bug_fix workflow_type alias * style(planning): ruff format * fix: refatored common logic * fix: remove ruff errors * fix: remove duplicate _normalize_workflow_type method Remove the incorrectly placed duplicate method inside ContextLoader class. The module-level function is the correct implementation being used. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: danielfrey63 <daniel.frey@sbb.ch> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(ci): use develop branch for dry-run builds in beta-release workflow (#276) When dry_run=true, the workflow skipped creating the version tag but build jobs still tried to checkout that non-existent tag, causing all 4 platform builds to fail with "git failed with exit code 1". Now build jobs checkout develop branch for dry runs while still using the version tag for real releases. Closes: GitHub Actions run #20464082726 * chore(deps): bump typescript-eslint in /apps/frontend (#269) Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.49.0 to 8.50.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.50.1/packages/typescript-eslint) --- updated-dependencies: - dependency-name: typescript-eslint dependency-version: 8.50.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * chore(deps): bump jsdom from 26.1.0 to 27.3.0 in /apps/frontend (#268) Bumps [jsdom](https://github.com/jsdom/jsdom) from 26.1.0 to 27.3.0. - [Release notes](https://github.com/jsdom/jsdom/releases) - [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md) - [Commits](https://github.com/jsdom/jsdom/compare/26.1.0...27.3.0) --- updated-dependencies: - dependency-name: jsdom dependency-version: 27.3.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * fix(ci): use correct electron-builder arch flags (#278) The project switched from pnpm to npm, which handles script argument passing differently. pnpm adds a -- separator that caused electron-builder to ignore the --arch argument, but npm passes it directly. Since --arch is a deprecated electron-builder argument, use the recommended flags instead: - --arch=x64 → --x64 - --arch=arm64 → --arm64 This fixes Mac Intel and ARM64 builds failing with "Unknown argument: arch" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): resolve CodeQL file system race conditions and unused variables (#277) * fix(security): resolve CodeQL file system race conditions and unused variables Fix high severity CodeQL alerts: - Remove TOCTOU (time-of-check-time-of-use) race conditions by eliminating existsSync checks followed by file operations. Use try-catch instead. - Files affected: pr-handlers.ts, spec-utils.ts Fix unused variable warnings: - Remove unused imports (FeatureModelConfig, FeatureThinkingConfig, withProjectSyncOrNull, getBackendPath, validateRunner, githubFetch) - Prefix intentionally unused destructured variables with underscore - Remove unused local variables (existing, actualEvent) - Files affected: pr-handlers.ts, autofix-handlers.ts, triage-handlers.ts, PRDetail.tsx, pr-review-store.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): resolve remaining CodeQL alerts for TOCTOU, network data validation, and unused variables Address CodeRabbit and CodeQL security alerts from PR #277 review: - HIGH: Fix 12+ file system race conditions (TOCTOU) by replacing existsSync() checks with try/catch blocks in pr-handlers.ts, autofix-handlers.ts, triage-handlers.ts, and spec-utils.ts - MEDIUM: Add sanitizeNetworkData() function to validate/sanitize GitHub API data before writing to disk, preventing injection attacks - Clean up 20+ unused variables, imports, and useless assignments across frontend components and handlers - Fix Python Protocol typing in testing.py (add return type annotations) All changes verified with TypeScript compilation and ESLint (no errors). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): resolve follow-up review API issues - Fix gh_client.py: use query string syntax for `since` parameter instead of `-f` flag which sends POST body fields, causing GitHub API errors - Fix followup_reviewer.py: use raw Anthropic client for message API calls instead of ClaudeSDKClient which is for agent sessions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore(deps): bump @xterm/xterm from 5.5.0 to 6.0.0 in /apps/frontend (#270) * chore(deps): bump @xterm/xterm from 5.5.0 to 6.0.0 in /apps/frontend Bumps [@xterm/xterm](https://github.com/xtermjs/xterm.js) from 5.5.0 to 6.0.0. - [Release notes](https://github.com/xtermjs/xterm.js/releases) - [Commits](https://github.com/xtermjs/xterm.js/compare/5.5.0...6.0.0) --- updated-dependencies: - dependency-name: "@xterm/xterm" dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * fix(deps): update xterm addons for 6.0.0 compatibility and use public APIs CRITICAL: Updated all xterm addons to versions compatible with xterm 6.0.0: - @xterm/addon-fit: ^0.10.0 → ^0.11.0 - @xterm/addon-serialize: ^0.13.0 → ^0.14.0 - @xterm/addon-web-links: ^0.11.0 → ^0.12.0 - @xterm/addon-webgl: ^0.18.0 → ^0.19.0 HIGH: Refactored scroll-controller.ts to use public xterm APIs: - Replaced internal _core access with public buffer/scroll APIs - Uses onScroll and onWriteParsed events for scroll tracking - Uses scrollLines() for scroll position restoration - Proper IDisposable cleanup for event listeners - Falls back gracefully if onWriteParsed is not available 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(ci): add write permissions to beta-release update-version job The update-version job needs contents: write permission to push the version bump commit and tag to the repository. Without this, the workflow fails with a 403 error when trying to git push. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: resolve spawn python ENOENT error on Linux by using getAugmentedEnv() (#281) - Use getAugmentedEnv() in project-context-handlers.ts to ensure Python is in PATH - Add /usr/bin and /usr/sbin to Linux paths in env-utils.ts for system Python - Fixes GUI-launched apps not inheriting shell environment on Ubuntu 24.04 Fixes #215 Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> * feat(python): bundle Python 3.12 with packaged Electron app (#284) * feat(python): bundle Python 3.12 with packaged Electron app Resolves issue #258 where users with Python aliases couldn't run the app because shell aliases aren't visible to Electron's subprocess calls. Changes: - Add download-python.cjs script to fetch python-build-standalone - Bundle Python 3.12.8 in extraResources for packaged apps - Update python-detector.ts to prioritize bundled Python - Add Python caching to CI workflows for faster builds Packaged apps now include Python (~35MB), eliminating the need for users to have Python installed. Dev mode still falls back to system Python. Closes #258 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address PR review feedback for Python bundling Security improvements: - Add SHA256 checksum verification for downloaded Python binaries - Replace execSync with spawnSync to prevent command injection - Add input validation to prevent log injection from CLI args - Add download timeout (5 minutes) and redirect limit (10) - Proper file/connection cleanup on errors Bug fixes: - Fix platform naming mismatch: use "mac"/"win" (electron-builder) instead of "darwin"/"win32" (Node.js) for output directories - Handle empty path edge case in parsePythonCommand Improvements: - Add restore-keys to CI cache steps for better cache hit rates - Improve error messages and logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix mac node.js naming * security: add SHA256 checksums for all Python platforms Fetched actual checksums from python-build-standalone release: - darwin-arm64: abe1de24... - darwin-x64: 867c1af1... - win32-x64: 1a702b34... - linux-x64: 698e53b2... - linux-arm64: fb983ec8... All platforms now have cryptographic verification for downloaded Python binaries, eliminating the supply chain risk. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: add python-runtime to root .gitignore Ensures bundled Python runtime is ignored from both root and frontend .gitignore files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): validate backend source path before using it (#287) * fix(frontend): validate backend source path before using it The path resolver was returning invalid autoBuildPath settings without validating they contained the required backend files. When settings pointed to a legacy /auto-claude/ directory (missing requirements.txt and analyzer.py), the project indexer would fail with "can't open file" errors. Now validates that all source paths contain requirements.txt before returning them, falling back to bundled source path detection when the configured path is invalid. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: Initialize subtask-based implementation plan - Workflow type: feature - Phases: 4 - Subtasks: 9 - Ready for autonomous implementation Parallel execution enabled: phases 1 and 2 can run simultaneously * auto-claude: Initialize subtask-based implementation plan - Workflow type: investigation - Phases: 5 - Subtasks: 13 - Ready for autonomous implementation * fix merge conflict check loop * fix(frontend): add warning when fallback path is also invalid Address CodeRabbit review feedback - the fallback path in getBundledSourcePath() was returning an unvalidated path which could still cause the same analyzer.py error. Now logs a warning when the fallback path also lacks requirements.txt. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Potential fix for code scanning alert no. 224: Uncontrolled command line (#285) Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix(frontend): support archiving tasks across all worktree locations (#286) * archive across all worktress and if not in folder * fix(frontend): address PR security and race condition issues - Add taskId validation to prevent path traversal attacks - Fix TOCTOU race conditions in archiveTasks by removing existsSync - Fix TOCTOU race conditions in unarchiveTasks by removing existsSync 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): add explicit GET method to gh api comment fetches (#294) The gh api command defaults to POST for comment endpoints, causing GitHub to reject the 'since' query parameter as an invalid POST body field. Adding --method GET explicitly forces a GET request, allowing the since parameter to work correctly for fetching comments. This completes the fix started in f1cc5a09 which only changed from -f flag to query string syntax but didn't address the HTTP method. * feat: enhance the logs for the commit linting stage (#293) * ci: implement enterprise-grade PR quality gates and security scanning * ci: implement enterprise-grade PR quality gates and security scanning * fix:pr comments and improve code * fix: improve commit linting and code quality * Removed the dependency-review job (i added it) * fix: address CodeRabbit review comments - Expand scope pattern to allow uppercase, underscores, slashes, dots - Add concurrency control to cancel duplicate security scan runs - Add explanatory comment for Bandit CLI flags - Remove dependency-review job (requires repo settings) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: update commit lint examples with expanded scope patterns Show slashes and dots in scope examples to demonstrate the newly allowed characters (api/users, package.json) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: remove feature request issue template Feature requests are directed to GitHub Discussions via the issue template config.yml 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address security vulnerabilities in service orchestrator - Fix port parsing crash on malformed docker-compose entries - Fix shell injection risk by using shlex.split() with shell=False Prevents crashes when docker-compose.yml contains environment variables in port mappings (e.g., '${PORT}:8080') and eliminates shell injection vulnerabilities in subprocess execution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(ci): improve PR title validation error messages with examples Add helpful console output when PR title validation fails: - Show expected format and valid types - Provide examples of valid PR titles - Display the user's current title - Suggest fixes based on keywords in the title - Handle verb variations (fixed, adding, updated, etc.) - Show placeholder when description is empty after cleanup 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * lower coverage * feat: improve status gate to label correctly based on required checks * fix(ci): address PR review findings for security and efficiency - Add explicit permissions block to ci.yml (least privilege principle) - Skip duplicate test run for Python 3.12 (tests with coverage only) - Sanitize PR title in markdown output to prevent injection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix typo --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * feat(merge,oauth): add path-aware AI merge resolution and device code streaming (#296) * improve/merge-confclit-layer * improve AI resolution * fix caching on merge conflicts * imrpove merge layer with rebase * fix(github): add OAuth authentication to follow-up PR review The follow-up PR review AI analysis was failing with "Could not resolve authentication method" because AsyncAnthropic() was instantiated without credentials. The codebase uses OAuth tokens (not ANTHROPIC_API_KEY), so the client needs the auth_token parameter. Uses get_auth_token() from core.auth to retrieve the OAuth token from environment variables or macOS Keychain, matching how initial reviews authenticate via create_client(). * fix(merge): add validation to prevent AI writing natural language to files When AI merge receives truncated file contents (due to character limits), it sometimes responds with explanations like "I need to see the complete file contents..." instead of actual merged code. This garbage was being written directly to source files. Adds two validation layers after AI merge: 1. Natural language detection - catches patterns like "I need to", "Let me" 2. Syntax validation - uses esbuild to verify TypeScript/JavaScript syntax If either validation fails, the merge returns an error instead of writing invalid content to the file. Also adds project_dir field to ParallelMergeTask to enable syntax validation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(merge): skip git merge when AI already resolved path-mapped files When AI successfully merges path-mapped files (due to file renames between branches), the check only looked at `conflicts_resolved` which was 0 for path-mapped cases. This caused the code to fall through to `git merge` which then failed with conflicts. Now also checks `files_merged` and `ai_assisted` stats to determine if AI has already handled the merge. When files are AI-merged, they're already written and staged - no need for git merge. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix device code issue with github * fix(frontend): remember GitHub auth method (OAuth vs PAT) in settings Previously, after authenticating via GitHub OAuth, the settings page would show "Personal Access Token" input even though OAuth was used. This was confusing for users who expected to see their OAuth status. Added githubAuthMethod field to track how authentication was performed. Settings UI now shows "Authenticated via GitHub OAuth" when OAuth was used, with option to switch to manual token if needed. The auth method persists across settings reopening. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(backend): centralize OAuth client creation in core/client.py - Add create_message_client() for simple message API calls - Refactor followup_reviewer.py to use centralized client factory - Remove direct anthropic.AsyncAnthropic import from followup_reviewer - Add proper ValueError handling for missing OAuth token - Update docstrings to document both client factories This ensures all AI interactions use the centralized OAuth authentication in core/, avoiding direct ANTHROPIC_API_KEY usage per CLAUDE.md guidelines. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): remove unused statusColor variable in WorkspaceStatus Dead code cleanup - the statusColor variable was computed but never used in the component. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(tests): add BrowserWindow mock to oauth-handlers tests The sendDeviceCodeToRenderer function uses BrowserWindow.getAllWindows() which wasn't mocked, causing unhandled rejection errors in tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(backend): use ClaudeSDKClient instead of raw anthropic SDK Remove direct anthropic SDK import from core/client.py and update followup_reviewer.py to use ClaudeSDKClient directly as per project conventions. All AI interactions should use claude-agent-sdk. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(backend): add debug logging for AI response in followup_reviewer Add logging to diagnose why AI review returns no JSON - helps identify if response is in thinking blocks vs text blocks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Fix/2.7.2 fixes (#300) * fix(frontend): prevent false stuck detection for ai_review tasks Tasks in ai_review status were incorrectly showing "Task Appears Stuck" in the detail modal. This happened because the isRunning check included ai_review status, triggering stuck detection when no process was found. However, ai_review means "all subtasks completed, awaiting QA" - no build process is expected to be running. This aligns the detail modal logic with TaskCard which correctly only checks for in_progress status. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * ci(beta-release): use tag-based versioning instead of modifying package.json Previously the beta-release workflow committed version changes to package.json on the develop branch, which caused two issues: 1. Permission errors (github-actions[bot] denied push access) 2. Beta versions polluted develop, making merges to main unclean Now the workflow creates only a git tag and injects the version at build time using electron-builder's --config.extraMetadata.version flag. This keeps package.json at the next stable version and avoids any commits to develop. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ollama): add packaged app path resolution for Ollama detector script The Ollama detection was failing in packaged builds because the Python script path resolution only checked development paths. In packaged apps, __dirname points to the app bundle, and the relative path "../../../backend" doesn't resolve correctly. Added process.resourcesPath for packaged builds (checked first via app.isPackaged) which correctly locates the backend scripts in the Resources folder. Also added DEBUG-only logging to help troubleshoot script location issues. Closes #129 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(paths): remove legacy auto-claude path fallbacks Replace all legacy 'auto-claude/' source path detection with 'apps/backend'. Services now validate paths using runners/spec_runner.py as the marker instead of requirements.txt, ensuring only valid backend directories match. - Remove legacy fallback paths from all getAutoBuildSourcePath() implementations - Add startup validation in index.ts to skip invalid saved paths - Update project-initializer to detect apps/backend for local dev projects - Standardize path detection across all services 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): address PR review feedback from Auto Claude and bots Fixes from PR #300 reviews: CRITICAL: - path-resolver.ts: Update marker from requirements.txt to runners/spec_runner.py for consistent backend detection across all files HIGH: - useTaskDetail.ts: Restore stuck task detection for ai_review status (CHANGELOG documents this feature) - TerminalGrid.tsx: Include legacy terminals without projectPath (prevents hiding terminals after upgrade) - memory-handlers.ts: Add packaged app path in OLLAMA_PULL_MODEL handler (fixes production builds) MEDIUM: - OAuthStep.tsx: Stricter profile slug sanitization (only allow alphanumeric and dashes) - project-store.ts: Fix regex to not truncate at # in code blocks (uses \n#{1,6}\s to match valid markdown headings only) - memory-service.ts: Add backend structure validation with spec_runner.py marker - subprocess-spawn.test.ts: Update test to use new marker pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(frontend): validate empty profile slug after sanitization Add validation to prevent empty config directory path when profile name contains only special characters (e.g., "!!!"). Shows user-friendly error message requiring at least one letter or number. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix: stop tracking spec files in git (#295) * fix: stop tracking spec files in git - Remove git commit instructions from planner.md for spec files - Spec files (implementation_plan.json, init.sh, build-progress.txt) should be gitignored - Untrack existing spec files that were accidentally committed - AI agents should only commit code changes, not spec metadata The .auto-claude/specs/ directory is gitignored by design - spec files are local project metadata that shouldn't be version controlled. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(prompts): remove git commit instructions for gitignored spec files The spec files (build-progress.txt, qa_report.md, implementation_plan.json, QA_FIX_REQUEST.md) are all stored in .auto-claude/specs/ which is gitignored. Removed instructions telling agents to commit these files, replaced with notes explaining they're tracked automatically by the framework. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(build): add --force-local flag to tar on Windows (#303) On Windows, paths like D:\path are misinterpreted by tar as remote host:path syntax (Unix tar convention). Adding --force-local tells tar to treat colons as part of the filename, fixing the extraction failure in GitHub Actions Windows builds. Error was: "tar (child): Cannot connect to D: resolve failed" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * fix(build): use PowerShell for tar extraction on Windows The previous fix using --force-local and path conversion still failed due to shell escaping issues. PowerShell handles Windows paths natively and has built-in tar support on Windows 10+, avoiding all path escaping problems. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(github): add augmented PATH env to all gh CLI calls When running from a packaged macOS app (.dmg), the PATH environment variable doesn't include common locations like /opt/homebrew/bin where gh is typically installed via Homebrew. The getAugmentedEnv() function was already being used in some places but was missing from: - spawn() call in registerStartGhAuth - execSync calls for gh auth token, gh api user, gh repo list - execFileSync calls for gh api, gh repo create - execFileSync calls in pr-handlers.ts and triage-handlers.ts This caused "gh: command not found" errors when connecting projects to GitHub in the packaged app. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(build): use explicit Windows System32 tar path (#308) The previous PowerShell fix still found Git Bash's /usr/bin/tar which interprets D: as a remote host. Using the explicit path to Windows' built-in bsdtar (C:\Windows\System32\tar.exe) avoids this issue. Windows Server 2019+ (GitHub Actions) has bsdtar in System32. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * chore(ci): cancel in-progress runs (#302) Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> Co-authored-by: Alex <63423455+AlexMadera@users.noreply.github.com> * fix(python): use venv Python for all services to fix dotenv errors (#311) * fix(python): use venv Python for all services to fix dotenv errors Services were spawning Python processes using findPythonCommand() which returns the bundled Python directly. However, dependencies like python-dotenv are only installed in the venv created from the bundled Python. Changes: - Add getConfiguredPythonPath() helper that returns venv Python when ready - Update all services to use venv Python instead of bundled Python directly: - memory-service.ts - memory-handlers.ts - agent-process.ts - changelog-service.ts - title-generator.ts - insights/config.ts - project-context-handlers.ts - worktree-handlers.ts - Fix availability checks to use findPythonCommand() (can return null) - Add python:verify script for bundling verification The flow now works correctly: 1. App starts → findPythonCommand() finds bundled Python 2. pythonEnvManager creates venv using bundled Python 3. pip installs dependencies (dotenv, claude-agent-sdk, etc.) 4. All services use venv Python → has all dependencies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix lintin and test --------- Co-authored-by: Claude <noreply@anthropic.com> * fix(updater): proper semver comparison for pre-release versions (#313) Fixes the beta auto-update bug where the app was offering downgrades (e.g., showing v2.7.1 as "new version available" when on v2.7.2-beta.6). Changes: - version-manager.ts: New parseVersion() function that separates base version from pre-release suffix. Updated compareVersions() to handle pre-release versions correctly (alpha < beta < rc < stable). - app-updater.ts: Import and use compareVersions() for proper version comparison instead of simple string inequality. - Added comprehensive unit tests for version comparison logic. Pre-release ordering: - 2.7.1 < 2.7.2-alpha.1 < 2.7.2-beta.1 < 2.7.2-rc.1 < 2.7.2 (stable) - 2.7.2-beta.6 < 2.7.2-beta.7 * fix(project): fix task status persistence reverting on refresh (#246) (#318) Correctly validate persisted task status against calculated status. Previously, if a task was 'in_progress' but had no active subtasks (e.g. still in planning or between phases), the calculated status 'backlog' would override the stored status, causing the UI to revert to 'Start'. This fix adds 'in_progress' to the list of active process statuses and explicitly allows 'in_progress' status to persist when the underlying plan status is also 'in_progress'. * fix(ci): add auto-updater manifest files and version auto-update (#317) Combined PR with: 1. Alex's version auto-update changes from PR #316 2. Auto-updater manifest file generation fix Changes: - Add --publish never to package scripts to generate .yml manifests - Update all build jobs to upload .yml files as artifacts - Update release step to include .yml files in GitHub release - Auto-bump version in package.json files before tagging This enables the in-app auto-updater to work properly by ensuring latest-mac.yml, latest-linux.yml, and latest.yml are published with each release. Co-authored-by: Alex <63423455+AlexMadera@users.noreply.github.com> * f…
* docs: Add Git Flow branching strategy to CONTRIBUTING.md
- Add comprehensive branching strategy documentation
- Explain main, develop, feature, fix, release, and hotfix branches
- Clarify that all PRs should target develop (not main)
- Add release process documentation for maintainers
- Update PR process to branch from develop
- Expand table of contents with new sections
* Feature/apps restructure v2.7.2 (#138)
* refactor: restructure project to Apps/frontend and Apps/backend
- Move auto-claude-ui to Apps/frontend with feature-based architecture
- Move auto-claude to Apps/backend
- Switch from pnpm to npm for frontend
- Update Node.js requirement to v24.12.0 LTS
- Add pre-commit hooks for lint, typecheck, and security audit
- Add commit-msg hook for conventional commits
- Fix CommonJS compatibility issues (postcss.config, postinstall scripts)
- Update README with comprehensive setup and contribution guidelines
- Configure ESLint to ignore .cjs files
- 0 npm vulnerabilities
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(refactor): clean code and move to npm
* feat(refactor): clean code and move to npm
* chore: update to v2.7.0, remove Docker deps (LadybugDB is embedded)
* feat: v2.8.0 - update workflows and configs for Apps/ structure, npm
* fix: resolve Python lint errors (F401, I001)
* fix: update test paths for Apps/backend structure
* fix: add missing facade files and update paths for Apps/backend structure
- Fix ruff lint error I001 in auto_claude_tools.py
- Create missing facade files to match upstream (agent, ci_discovery, critique, etc.)
- Update test paths from auto-claude/ to Apps/backend/
- Update .pre-commit-config.yaml paths for Apps/ structure
- Add pytest to pre-commit hooks (skip slow/integration/Windows-incompatible tests)
- Fix Unicode encoding in test_agent_architecture.py for Windows
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat: improve readme
* fix: new path
* fix: correct release workflow and docs for Apps/ restructure
- Fix ARM64 macOS build: pnpm → npm, auto-claude-ui → Apps/frontend
- Fix artifact upload paths in release.yml
- Update Node.js version to 24 for consistency
- Update CLI-USAGE.md with Apps/backend paths
- Update RELEASE.md with Apps/frontend/package.json paths
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: rename Apps/ to apps/ and fix backend path resolution
- Rename Apps/ folder to apps/ for consistency with JS/Node conventions
- Update all path references across CI/CD workflows, docs, and config files
- Fix frontend Python path resolver to look for 'backend' instead of 'auto-claude'
- Update path-resolver.ts to correctly find apps/backend in development mode
This completes the Apps restructure from PR #122 and prepares for v2.8.0 release.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(electron): correct preload script path from .js to .mjs
electron-vite builds the preload script as ESM (index.mjs) but the main
process was looking for CommonJS (index.js). This caused the preload to
fail silently, making the app fall back to browser mock mode with fake
data and non-functional IPC handlers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* - Introduced `dev:debug` script to enable debugging during development.
- Added `dev:mcp` script for running the frontend in MCP mode.
These enhancements streamline the development process for frontend developers.
* refactor(memory): make Graphiti memory mandatory and remove Docker dependency
Memory is now a core component of Auto Claude rather than optional:
- Python 3.12+ is required for the backend (not just memory layer)
- Graphiti is enabled by default in .env.example
- Removed all FalkorDB/Docker references (migrated to embedded LadybugDB)
- Deleted guides/DOCKER-SETUP.md and docker-handlers.ts
- Updated onboarding UI to remove "optional" language
- Updated all documentation to reflect LadybugDB architecture
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add cross-platform Windows support for npm scripts
- Add scripts/install-backend.js for cross-platform Python venv setup
- Auto-detects Python 3.12 (py -3.12 on Windows, python3.12 on Unix)
- Handles platform-specific venv paths
- Add scripts/test-backend.js for cross-platform pytest execution
- Update package.json to use Node.js scripts instead of shell commands
- Update CONTRIBUTING.md with correct paths and instructions:
- apps/backend/ and apps/frontend/ paths
- Python 3.12 requirement (memory system now required)
- Platform-specific install commands (winget, brew, apt)
- npm instead of pnpm
- Quick Start section with npm run install:all
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* remove doc
* fix(frontend): correct Ollama detector script path after apps restructure
The Ollama status check was failing because memory-handlers.ts
was looking for ollama_model_detector.py at auto-claude/ but the
script is now at apps/backend/ after the directory restructure.
This caused "Ollama not running" to display even when Ollama was
actually running and accessible.
* chore: bump version to 2.7.2
Downgrade version from 2.8.0 to 2.7.2 as the Apps/ restructure
is better suited as a patch release rather than a minor release.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: update package-lock.json for Windows compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs(contributing): add hotfix workflow and update paths for apps/ structure
Add Git Flow hotfix workflow documentation with step-by-step guide
and ASCII diagram showing the branching strategy.
Update all paths from auto-claude/auto-claude-ui to apps/backend/apps/frontend
and migrate package manager references from pnpm to npm to match the
new project structure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): remove duplicate ARM64 build from Intel runner
The Intel runner was building both x64 and arm64 architectures,
while a separate ARM64 runner also builds arm64 natively. This
caused duplicate ARM64 builds, wasting CI resources.
Now each runner builds only its native architecture:
- Intel runner: x64 only
- ARM64 runner: arm64 only
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Alex Madera <e.a_madera@hotmail.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Feat: Ollama download progress tracking with new apps structure (#141)
* feat(ollama): add real-time download progress tracking for model downloads
Implement comprehensive download progress tracking with:
- NDJSON parsing for streaming progress data from Ollama API
- Real-time speed calculation (MB/s, KB/s, B/s) with useRef for delta tracking
- Time remaining estimation based on download speed
- Animated progress bars in OllamaModelSelector component
- IPC event streaming from main process to renderer
- Proper listener management with cleanup functions
Changes:
- memory-handlers.ts: Parse NDJSON from Ollama stderr, emit progress events
- OllamaModelSelector.tsx: Display progress bars with speed and time remaining
- project-api.ts: Implement onDownloadProgress listener with cleanup
- ipc.ts types: Define onDownloadProgress listener interface
- infrastructure-mock.ts: Add mock implementation for browser testing
This allows users to see real-time feedback when downloading Ollama models,
including percentage complete, current download speed, and estimated time remaining.
* test: add focused test coverage for Ollama download progress feature
Add unit tests for the critical paths of the real-time download progress tracking:
- Progress calculation tests (52 tests): Speed/time/percentage calculations with comprehensive edge case coverage (zero speeds, NaN, Infinity, large numbers)
- NDJSON parser tests (33 tests): Streaming JSON parsing from Ollama, buffer management for incomplete lines, error handling
All 562 unit tests passing with clean dependencies. Tests focus on critical mathematical logic and data processing - the most important paths that need verification.
Test coverage:
✅ Speed calculation and formatting (B/s, KB/s, MB/s)
✅ Time remaining calculations (seconds, minutes, hours)
✅ Percentage clamping (0-100%)
✅ NDJSON streaming with partial line buffering
✅ Invalid JSON handling
✅ Real Ollama API responses
✅ Multi-chunk streaming scenarios
* docs: add comprehensive JSDoc docstrings for Ollama download progress feature
- Enhanced OllamaModelSelector component with detailed JSDoc
* Documented component props, behavior, and usage examples
* Added docstrings to internal functions (checkInstalledModels, handleDownload, handleSelect)
* Explained progress tracking algorithm and useRef usage
- Improved memory-handlers.ts documentation
* Added docstring to main registerMemoryHandlers function
* Documented all Ollama-related IPC handlers (check-status, list-embedding-models, pull-model)
* Added JSDoc to executeOllamaDetector helper function
* Documented interface types (OllamaStatus, OllamaModel, OllamaEmbeddingModel, OllamaPullResult)
* Explained NDJSON parsing and progress event structure
- Enhanced test file documentation
* Added docstrings to NDJSON parser test utilities with algorithm explanation
* Documented all calculation functions (speed, time, percentage)
* Added detailed comments on formatting and bounds-checking logic
- Improved overall code maintainability
* Docstring coverage now meets 80%+ threshold for code review
* Clear explanation of progress tracking implementation details
* Better context for future maintainers working with download streaming
* feat: add batch task creation and management CLI commands
- Handle batch task creation from JSON files
- Show status of all specs in project
- Cleanup tool for completed specs
- Full integration with new apps/backend structure
- Compatible with implementation_plan.json workflow
* test: add batch task test file and testing checklist
- batch_test.json: Sample tasks for testing batch creation
- TESTING_CHECKLIST.md: Comprehensive testing guide for Ollama and batch tasks
- Includes UI testing steps, CLI testing steps, and edge cases
- Ready for manual and automated testing
* chore: update package-lock.json to match v2.7.2
* test: update checklist with verification results and architecture validation
* docs: add comprehensive implementation summary for Ollama + Batch features
* docs: add comprehensive Phase 2 testing guide with checklists and procedures
* docs: add NEXT_STEPS guide for Phase 2 testing
* fix: resolve merge conflict in project-api.ts from Ollama feature cherry-pick
* fix: remove duplicate Ollama check status handler registration
* test: update checklist with Phase 2 bug findings and fixes
---------
Co-authored-by: ray <ray@rays-MacBook-Pro.local>
* fix: resolve Python environment race condition (#142)
Implemented promise queue pattern in PythonEnvManager to handle
concurrent initialization requests. Previously, multiple simultaneous
requests (e.g., startup + merge) would fail with "Already
initializing" error.
Also fixed parsePythonCommand() to handle file paths with spaces by
checking file existence before splitting on whitespace.
Changes:
- Added initializationPromise field to queue concurrent requests
- Split initialize() into public and private _doInitialize()
- Enhanced parsePythonCommand() with existsSync() check
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* fix: remove legacy path from auto-claude source detection (#148)
Removes the legacy 'auto-claude' path from the possiblePaths array
in agent-process.ts. This path was from before the monorepo
restructure (v2.7.2) and is no longer needed.
The legacy path was causing spec_runner.py to be looked up at the
wrong location:
- OLD (wrong): /path/to/auto-claude/auto-claude/runners/spec_runner.py
- NEW (correct): /path/to/apps/backend/runners/spec_runner.py
This aligns with the new monorepo structure where all backend code
lives in apps/backend/.
Fixes #147
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* Fix/linear 400 error
* fix: Linear API authentication and GraphQL types
- Remove Bearer prefix from Authorization header (Linear API keys are sent directly)
- Change GraphQL variable types from String! to ID! for teamId and issue IDs
- Improve error handling to show detailed Linear API error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: Radix Select empty value error in Linear import modal
Use '__all__' sentinel value instead of empty string for "All projects"
option, as Radix Select does not allow empty string values.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add CodeRabbit configuration file
Introduce a new .coderabbit.yaml file to configure CodeRabbit settings, including review profiles, automatic review options, path filters, and specific instructions for different file types. This enhances the code review process by providing tailored guidelines for Python, TypeScript, and test files.
* fix: correct GraphQL types for Linear team queries
Linear API uses different types for different queries:
- team(id:) expects String!
- issues(filter: { team: { id: { eq: } } }) expects ID!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: refresh task list after Linear import
Call loadTasks() after successful Linear import to update the kanban
board without requiring a page reload.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* cleanup
* cleanup
* fix: address CodeRabbit review comments for Linear integration
- Fix unsafe JSON parsing: check response.ok before parsing JSON to handle
non-JSON error responses (e.g., 503 from proxy) gracefully
- Use ID! type instead of String! for teamId in LINEAR_GET_PROJECTS query
for GraphQL type consistency
- Remove debug console.log (ESLint config only allows warn/error)
- Refresh task list on partial import success (imported > 0) instead of
requiring full success
- Fix pre-existing TypeScript and lint issues blocking commit
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* version sync logic
* lints for develop branch
* chore: update CI workflow to include develop branch
- Modified the CI configuration to trigger on pushes and pull requests to both main and develop branches, enhancing the workflow for development and integration processes.
* fix: update project directory auto-detection for apps/backend structure
The project directory auto-detection was checking for the old `auto-claude/`
directory name but needed to check for `apps/backend/`. When running from
`apps/backend/`, the directory name is `backend` not `auto-claude`, so the
check would fail and `project_dir` would incorrectly remain as `apps/backend/`
instead of resolving to the project root (2 levels up).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use GraphQL variables instead of string interpolation in LINEAR_GET_ISSUES
Replace direct string interpolation of teamId and linearProjectId with
proper GraphQL variables. This prevents potential query syntax errors if
IDs contain special characters like double quotes, and aligns with the
variable-based approach used elsewhere in the file.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ui): correct logging level and await loadTasks on import complete
- Change console.warn to console.log for import success messages
(warn is incorrect severity for normal completion)
- Make onImportComplete callback async and await loadTasks()
to prevent potential unhandled promise rejections
Applies CodeRabbit review feedback across 3 LinearTaskImportModal usages.
* fix(hooks): use POSIX-compliant find instead of bash glob
The pre-commit hook uses #!/bin/sh but had bash-specific ** glob
pattern for staging ruff-formatted files. The ** pattern only works
in bash with globstar enabled - in POSIX sh it expands literally
and won't match subdirectories, causing formatted files in nested
directories to not be staged.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(task): stop running process when task status changes away from in_progress
When a user drags a running task back to Planning (or any other column),
the process was not being stopped, leaving a "ghost" process that
prevented deletion with "Cannot delete a running task" error.
Now the task process is automatically killed when status changes away
from in_progress, ensuring the process state stays in sync with the UI.
* feat: Add UI scale feature with 75-200% range (#125)
* feat: add UI scale feature
* refactor: extract UI scale bounds to shared constants
* fix: duplicated import
* fix: hide status badge when execution phase badge is showing (#154)
* fix: analyzer Python compatibility and settings integration
Fixes project index analyzer failing with TypeError on Python type hints.
Changes:
- Added 'from __future__ import annotations' to all analysis modules
- Fixed project discovery to support new analyzer JSON format
- Read Python path directly from settings.json instead of pythonEnvManager
- Added stderr/stdout logging for analyzer debugging
Resolves 'Discovered 0 files' and 'TypeError: unsupported operand type' issues.
* auto-claude: subtask-1-1 - Hide status badge when execution phase badge is showing
When a task has an active execution (planning, coding, etc.), the
execution phase badge already displays the correct state with a spinner.
The status badge was also rendering, causing duplicate/confusing badges
(e.g., both "Planning" and "Pending" showing at the same time).
This fix wraps the status badge in a conditional that only renders when
there's no active execution, eliminating the redundant badge display.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ipc): remove unused pythonEnvManager parameter and fix ES6 import
Address CodeRabbit review feedback:
- Remove unused pythonEnvManager parameter from registerProjectContextHandlers
and registerContextHandlers (the code reads Python path directly from
settings.json instead)
- Replace require('electron').app with proper ES6 import for consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(lint): fix import sorting in analysis module
Run ruff --fix to resolve I001 lint errors after merging develop.
All 23 files in apps/backend/analysis/ now have properly sorted imports.
---------
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix/PRs from old main setup to apps structure (#185)
* fix(core): add task persistence, terminal handling, and HTTP 300 fixes
Consolidated bug fixes from PRs #168, #170, #171:
- Task persistence (#168): Scan worktrees for tasks on app restart
to prevent loss of in-progress work and wasted API credits. Tasks
in .worktrees/*/specs are now loaded and deduplicated with main.
- Terminal buttons (#170): Fix "Open Terminal" buttons silently
failing on macOS by properly awaiting createTerminal() Promise.
Added useTerminalHandler hook with loading states and error display.
- HTTP 300 errors (#171): Handle branch/tag name collisions that
cause update failures. Added validation script to prevent conflicts
before releases and user-friendly error messages with manual
download links.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(platform): add path resolution, spaces handling, and XDG support
This commit consolidates multiple bug fixes from community PRs:
- PR #187: Path resolution fix - Update path detection to find apps/backend
instead of legacy auto-claude directory after v2.7.2 restructure
- PR #182/#155: Python path spaces fix - Improve parsePythonCommand() to
handle quoted paths and paths containing spaces without splitting
- PR #161: Ollama detection fix - Add new apps structure paths for
ollama_model_detector.py script discovery
- PR #160: AppImage support - Add XDG Base Directory compliant paths for
Linux sandboxed environments (AppImage, Flatpak, Snap). New files:
- config-paths.ts: XDG path utilities
- fs-utils.ts: Filesystem utilities with fallback support
- PR #159: gh CLI PATH fix - Add getAugmentedEnv() utility to include
common binary locations (Homebrew, snap, local) in PATH for child
processes. Fixes gh CLI not found when app launched from Finder/Dock.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit/Cursor review comments on PR #185
Fixes from code review:
- http-client.ts: Use GITHUB_CONFIG instead of hardcoded owner in HTTP 300 error message
- validate-release.js: Fix substring matching bug in branch detection that could cause false positives (e.g., v2.7 matching v2.7.2)
- bump-version.js: Remove unnecessary try-catch wrapper (exec() already exits on failure)
- execution-handlers.ts: Capture original subtask status before mutation for accurate logging
- fs-utils.ts: Add error handling to safeWriteFile with proper logging
Dismissed as trivial/not applicable:
- config-paths.ts: Exhaustive switch check (over-engineering)
- env-utils.ts: PATH priority documentation (existing comments sufficient)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address additional CodeRabbit review comments (round 2)
Fixes from second round of code review:
- fs-utils.ts: Wrap test file cleanup in try-catch for Windows file locking
- fs-utils.ts: Add error handling to safeReadFile for consistency with safeWriteFile
- http-client.ts: Use GITHUB_CONFIG in fetchJson (missed in first round)
- validate-release.js: Exclude symbolic refs (origin/HEAD -> origin/main) from branch check
- python-detector.ts: Return cleanPath instead of pythonPath for empty input edge case
Dismissed as trivial/not applicable:
- execution-handlers.ts: Redundant checkSubtasksCompletion call (micro-optimization)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat/beta-release (#190)
* chore: update README version to 2.7.1
Updated the version badge and download links in the README to reflect the new release version 2.7.1, ensuring users have the correct information for downloading the latest builds.
* feat(releases): add beta release system with user opt-in
Implements a complete beta release workflow that allows users to opt-in
to receiving pre-release versions. This enables testing new features
before they're included in stable releases.
Changes:
- Add beta-release.yml workflow for creating beta releases from develop
- Add betaUpdates setting with UI toggle in Settings > Updates
- Add update channel support to electron-updater (beta vs latest)
- Extract shared settings-utils.ts to reduce code duplication
- Add prepare-release.yml workflow for automated release preparation
- Document beta release process in CONTRIBUTING.md and RELEASE.md
Users can enable beta updates in Settings > Updates, and maintainers
can trigger beta releases via the GitHub Actions workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* workflow update
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Feat/beta release (#193)
* chore: update README version to 2.7.1
Updated the version badge and download links in the README to reflect the new release version 2.7.1, ensuring users have the correct information for downloading the latest builds.
* feat(releases): add beta release system with user opt-in
Implements a complete beta release workflow that allows users to opt-in
to receiving pre-release versions. This enables testing new features
before they're included in stable releases.
Changes:
- Add beta-release.yml workflow for creating beta releases from develop
- Add betaUpdates setting with UI toggle in Settings > Updates
- Add update channel support to electron-updater (beta vs latest)
- Extract shared settings-utils.ts to reduce code duplication
- Add prepare-release.yml workflow for automated release preparation
- Document beta release process in CONTRIBUTING.md and RELEASE.md
Users can enable beta updates in Settings > Updates, and maintainers
can trigger beta releases via the GitHub Actions workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* workflow update
* ci(github): update Discord link and redirect feature requests to discussions
Update Discord invite link to correct URL (QhRnz9m5HE) across all GitHub
templates and workflows. Redirect feature requests from issue template
to GitHub Discussions for better community engagement.
Changes:
- config.yml: Add feature request link to Discussions, fix Discord URL
- question.yml: Update Discord link in pre-question guidance
- welcome.yml: Update Discord link in first-time contributor message
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): correct welcome workflow PR message (#206)
- Change branch reference from main to develop
- Fix contribution guide link to use full URL
- Remove hyphen from "Auto Claude" in welcome message
* fix: Add Python 3.10+ version validation and GitHub Actions Python setup (#180 #167) (#208)
This fixes critical bug where macOS users with default Python 3.9.6 couldn't use Auto-Claude because claude-agent-sdk requires Python 3.10+.
Root Cause:
- Auto-Claude doesn't bundle Python, relies on system Python
- python-detector.ts accepted any Python 3.x without checking minimum version
- macOS ships with Python 3.9.6 by default (incompatible)
- GitHub Actions runners didn't explicitly set Python version
Changes:
1. python-detector.ts:
- Added getPythonVersion() to extract version from command
- Added validatePythonVersion() to check if >= 3.10.0
- Updated findPythonCommand() to skip Python < 3.10 with clear error messages
2. python-env-manager.ts:
- Import and use findPythonCommand() (already has version validation)
- Simplified findSystemPython() to use shared validation logic
- Updated error message from "Python 3.9+" to "Python 3.10+" with download link
3. .github/workflows/release.yml:
- Added Python 3.11 setup to all 4 build jobs (macOS Intel, macOS ARM64, Windows, Linux)
- Ensures consistent Python version across all platforms during build
Impact:
- macOS users with Python 3.9 now see clear error with download link
- macOS users with Python 3.10+ work normally
- CI/CD builds use consistent Python 3.11
- Prevents "ModuleNotFoundError: dotenv" and dependency install failures
Fixes #180, #167
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* feat: Add OpenRouter as LLM/embedding provider (#162)
* feat: Add OpenRouter as LLM/embedding provider
Add OpenRouter provider support for Graphiti memory integration,
enabling access to multiple LLM providers through a single API.
Changes:
Backend:
- Created openrouter_llm.py: OpenRouter LLM provider using OpenAI-compatible API
- Created openrouter_embedder.py: OpenRouter embedder provider
- Updated config.py: Added OpenRouter to provider enums and configuration
- New fields: openrouter_api_key, openrouter_base_url, openrouter_llm_model, openrouter_embedding_model
- Validation methods updated for OpenRouter
- Updated factory.py: Added OpenRouter to LLM and embedder factories
- Updated provider __init__.py files: Exported new OpenRouter functions
Frontend:
- Updated project.ts types: Added 'openrouter' to provider type unions
- GraphitiProviderConfig extended with OpenRouter fields
- Updated GraphitiStep.tsx: Added OpenRouter to provider arrays
- LLM_PROVIDERS: 'Multi-provider aggregator'
- EMBEDDING_PROVIDERS: 'OpenAI-compatible embeddings'
- Added OpenRouter API key input field with show/hide toggle
- Link to https://openrouter.ai/keys
- Updated env-handlers.ts: OpenRouter .env generation and parsing
- Template generation for OPENROUTER_* variables
- Parsing from .env files with proper type casting
Documentation:
- Updated .env.example with OpenRouter section
- Configuration examples
- Popular model recommendations
- Example configuration (#6)
Fixes #92
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* refactor: address CodeRabbit review comments for OpenRouter
- Add globalOpenRouterApiKey to settings types and store updates
- Initialize openrouterApiKey from global settings
- Update documentation to include OpenRouter in provider lists
- Add OpenRouter handling to get_embedding_dimension() method
- Add openrouter to provider cleanup list
- Add OpenRouter to get_available_providers() function
- Clarify Legacy comment for openrouterLlmModel
These changes complete the OpenRouter integration by ensuring proper
settings persistence and provider detection across the application.
* fix: apply ruff formatting to OpenRouter code
- Break long error message across multiple lines
- Format provider list with one item per line
- Fixes lint CI failure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix(core): add global spec numbering lock to prevent collisions (#209)
Implements distributed file-based locking for spec number coordination
across main project and all worktrees. Previously, parallel spec creation
could assign the same number to different specs (e.g., 042-bmad-task and
042-gitlab-integration both using number 042).
The fix adds SpecNumberLock class that:
- Acquires exclusive lock before calculating spec numbers
- Scans ALL locations (main project + worktrees) for global maximum
- Creates spec directories atomically within the lock
- Handles stale locks via PID-based detection with 30s timeout
Applied to both Python backend (spec_runner.py flow) and TypeScript
frontend (ideation conversion, GitHub/GitLab issue import).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Fix/ideation status sync (#212)
* fix(ideation): add missing event forwarders for status sync
- Add event forwarders in ideation-handlers.ts for progress, log,
type-complete, type-failed, complete, error, and stopped events
- Fix ideation-type-complete to load actual ideas array from JSON files
instead of emitting only the count
Resolves UI getting stuck at 0/3 complete during ideation generation.
* fix(ideation): fix UI not updating after actions
- Fix getIdeationSummary to count only active ideas (exclude dismissed/archived)
This ensures header stats match the visible ideas count
- Add transformSessionFromSnakeCase to properly transform session data
from backend snake_case to frontend camelCase on ideation-complete event
- Transform raw session before emitting ideation-complete event
Resolves header showing stale counts after dismissing/deleting ideas.
* fix(ideation): improve type safety and async handling in ideation type completion
- Replace synchronous readFileSync with async fsPromises.readFile in ideation-type-complete handler
- Wrap async file read in IIFE with proper error handling to prevent unhandled promise rejections
- Add type validation for IdeationType with VALID_IDEATION_TYPES set and isValidIdeationType guard
- Add validateEnabledTypes function to filter out invalid type values and log dropped entries
- Handle ENOENT separately
* fix(ideation): improve generation state management and error handling
- Add explicit isGenerating flag to prevent race conditions during async operations
- Implement 5-minute timeout for generation with automatic cleanup and error state
- Add ideation-stopped event emission when process is intentionally killed
- Replace console.warn/error with proper ideation-error events in agent-queue
- Add resetGeneratingTypes helper to transition all generating types to a target state
- Filter out dismissed/
* refactor(ideation): improve event listener cleanup and timeout management
- Extract event handler functions in ideation-handlers.ts to enable proper cleanup
- Return cleanup function from registerIdeationHandlers to remove all listeners
- Replace single generationTimeoutId with Map to support multiple concurrent projects
- Add clearGenerationTimeout helper to centralize timeout cleanup logic
- Extract loadIdeationType IIFE to named function for better error context
- Enhance error logging with projectId,
* refactor: use async file read for ideation and roadmap session loading
- Replace synchronous readFileSync with async fsPromises.readFile
- Prevents blocking the event loop during file operations
- Consistent with async pattern used elsewhere in the codebase
- Improved error handling with proper event emission
* fix(agent-queue): improve roadmap completion handling and error reporting
- Add transformRoadmapFromSnakeCase to convert backend snake_case to frontend camelCase
- Transform raw roadmap data before emitting roadmap-complete event
- Add roadmap-error emission for unexpected errors during completion
- Add roadmap-error emission when project path is unavailable
- Remove duplicate ideation-type-complete emission from error handler (event already emitted in loadIdeationType)
- Update error log message
* fix: add future annotations import to discovery.py (#229)
Adds 'from __future__ import annotations' to spec/discovery.py for
Python 3.9+ compatibility with type hints.
This completes the Python compatibility fixes that were partially
applied in previous commits. All 26 analysis and spec Python files
now have the future annotations import.
Related: #128
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* fix: resolve Python detection and backend packaging issues (#241)
* fix: resolve Python detection and backend packaging issues
- Fix backend packaging path (auto-claude -> backend) to match path-resolver.ts expectations
- Add future annotations import to config_parser.py for Python 3.9+ compatibility
- Use findPythonCommand() in project-context-handlers to prioritize Homebrew Python
- Improve Python detection to prefer Homebrew paths over system Python on macOS
This resolves the following issues:
- 'analyzer.py not found' error due to incorrect packaging destination
- TypeError with 'dict | None' syntax on Python < 3.10
- Wrong Python interpreter being used (system Python instead of Homebrew Python 3.10+)
Tested on macOS with packaged app - project index now loads successfully.
* refactor: address PR review feedback
- Extract findHomebrewPython() helper to eliminate code duplication between
findPythonCommand() and getDefaultPythonCommand()
- Remove hardcoded version-specific paths (python3.12) and rely only on
generic Homebrew symlinks for better maintainability
- Remove unnecessary 'from __future__ import annotations' from config_parser.py
since backend requires Python 3.12+ where union types are native
These changes make the code more maintainable, less fragile to Python version
changes, and properly reflect the project's Python 3.12+ requirement.
* Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Revert "Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)" (#251)
This reverts commit 348de6dfe793ab111043677c61b8452bc5ecb2cc.
* feat: add i18n internationalization system (#248)
* Add multilingual support and i18n integration
- Implemented i18n framework using `react-i18next` for translation management.
- Added support for English and French languages with translation files.
- Integrated language selector into settings.
- Updated all text strings in UI components to use translation keys.
- Ensured smooth language switching with live updates.
* Migrate remaining hard-coded strings to i18n system
- TaskCard: status labels, review reasons, badges, action buttons
- PhaseProgressIndicator: execution phases, progress labels
- KanbanBoard: drop zone, show archived, tooltips
- CustomModelModal: dialog title, description, labels
- ProactiveSwapListener: account switch notifications
- AgentProfileSelector: phase labels, custom configuration
- GeneralSettings: agent framework option
Added translation keys for en/fr locales in tasks.json, common.json,
and settings.json for complete i18n coverage.
* Add i18n support to dialogs and settings components
- AddFeatureDialog: form labels, validation messages, buttons
- AddProjectModal: dialog steps, form fields, actions
- RateLimitIndicator: rate limit notifications
- RateLimitModal: account switching, upgrade prompts
- AdvancedSettings: updates and notifications sections
- ThemeSettings: theme selection labels
- Updated dialogs.json locales (en/fr)
* Fix truncated 'ready' message in dialogs locales
* Fix backlog terminology in i18n locales
Change "Planning"/"Planification" to standard PM term "Backlog"
* Migrate settings navigation and integration labels to i18n
- AppSettings: nav items, section titles, buttons
- IntegrationSettings: Claude accounts, auto-switch, API keys labels
- Added settings nav/projectSections/integrations translation keys
- Added buttons.saving to common translations
* Migrate AgentProfileSettings and Sidebar init dialog to i18n
- AgentProfileSettings: migrate phase config labels, section title,
description, and all hardcoded strings to settings namespace
- Sidebar: migrate init dialog strings to dialogs namespace with
common buttons from common namespace
- Add new translation keys for agent profile settings and update dialog
* Migrate AppSettings navigation labels to i18n
- Add useTranslation hook to AppSettings.tsx
- Replace hardcoded section labels with dynamic translations
- Add projectSections translations for project settings nav
- Add rerunWizardDescription translation key
* Add explicit typing to notificationItems array
Import NotificationSettings type and use keyof to properly type
the notification item keys, removing manual type assertion.
* fix: update path resolution for ollama_model_detector.py in memory handlers (#263)
* ci: implement enterprise-grade PR quality gates and security scanning (#266)
* ci: implement enterprise-grade PR quality gates and security scanning
* ci: implement enterprise-grade PR quality gates and security scanning
* fix:pr comments and improve code
* fix: improve commit linting and code quality
* Removed the dependency-review job (i added it)
* fix: address CodeRabbit review comments
- Expand scope pattern to allow uppercase, underscores, slashes, dots
- Add concurrency control to cancel duplicate security scan runs
- Add explanatory comment for Bandit CLI flags
- Remove dependency-review job (requires repo settings)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: update commit lint examples with expanded scope patterns
Show slashes and dots in scope examples to demonstrate
the newly allowed characters (api/users, package.json)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove feature request issue template
Feature requests are directed to GitHub Discussions
via the issue template config.yml
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address security vulnerabilities in service orchestrator
- Fix port parsing crash on malformed docker-compose entries
- Fix shell injection risk by using shlex.split() with shell=False
Prevents crashes when docker-compose.yml contains environment
variables in port mappings (e.g., '${PORT}:8080') and eliminates
shell injection vulnerabilities in subprocess execution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat(github): add automated PR review with follow-up support (#252)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fixes during testing of PR
* feat(github): implement PR merge, assign, and comment features
- Add auto-assignment when clicking "Run AI Review"
- Implement PR merge functionality with squash method
- Add ability to post comments on PRs
- Display assignees in PR UI
- Add Approve and Merge buttons when review passes
- Update backend gh_client with pr_merge, pr_comment, pr_assign methods
- Create IPC handlers for new PR operations
- Update TypeScript interfaces and browser mocks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Improve PR review AI
* fix(github): use temp files for PR review posting to avoid shell escaping issues
When posting PR reviews with findings containing special characters (backticks,
parentheses, quotes), the shell command was interpreting them as commands instead
of literal text, causing syntax errors.
Changed both postPRReview and postPRComment handlers to write the body content
to temporary files and use gh CLI's --body-file flag instead of --body with
inline content. This safely handles ALL special characters without escaping issues.
Fixes shell errors when posting reviews with suggested fixes containing code snippets.
* fix(i18n): add missing GitHub PRs translation and document i18n requirements
Fixed missing translation key for GitHub PRs feature that was causing
"items.githubPRs" to display instead of the proper translated text.
Added comprehensive i18n guidelines to CLAUDE.md to ensure all future
frontend development follows the translation key pattern instead of
using hardcoded strings.
Also fixed missing deletePRReview mock function in browser-mock.ts
to resolve TypeScript compilation errors.
Changes:
- Added githubPRs translation to en/navigation.json
- Added githubPRs translation to fr/navigation.json
- Added Development Guidelines section to CLAUDE.md with i18n requirements
- Documented translation file locations and namespace usage patterns
- Added deletePRReview mock function to browser-mock.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix ui loading
* Github PR fixes
* improve claude.md
* lints/tests
* fix(github): handle PRs exceeding GitHub's 20K line diff limit
- Add PRTooLargeError exception for large PR detection
- Update pr_diff() to catch and raise PRTooLargeError for HTTP 406 errors
- Gracefully handle large PRs by skipping full diff and using individual file patches
- Add diff_truncated flag to PRContext to track when diff was skipped
- Large PRs will now review successfully using per-file diffs instead of failing
Fixes issue with PR #252 which has 100+ files exceeding the 20,000 line limit.
* fix: implement individual file patch fetching for large PRs
The PR review was getting stuck for large PRs (>20K lines) because when we
skipped the full diff due to GitHub API limits, we had no code to analyze.
The individual file patches were also empty, leaving the AI with just
file names and metadata.
Changes:
- Implemented _get_file_patch() to fetch individual patches via git diff
- Updated PR review engine to build composite diff from file patches when
diff_truncated is True
- Added missing 'state' field to PRContext dataclass
- Limits composite diff to first 50 files for very large PRs
- Shows appropriate warnings when using reconstructed diffs
This allows AI review to proceed with actual code analysis even when the
full PR diff exceeds GitHub's limits.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* 1min reduction
* docs: add GitHub Sponsors funding configuration
Enable the Sponsor button on the repository by adding FUNDING.yml
with the AndyMik90 GitHub Sponsors profile.
* feat(github-pr): add orchestrating agent for thorough PR reviews
Implement a new Opus 4.5 orchestrating agent that performs comprehensive
PR reviews regardless of size. Key changes:
- Add orchestrator_reviewer.py with strategic review workflow
- Add review_tools.py with subagent spawning capabilities
- Add pr_orchestrator.md prompt emphasizing thorough analysis
- Add pr_security_agent.md and pr_quality_agent.md subagent prompts
- Integrate orchestrator into pr_review_engine.py with config flag
- Fix critical bug where findings were extracted but not processed
(indentation issue in _parse_orchestrator_output)
The orchestrator now correctly identifies issues in PRs that were
previously approved as "trivial". Testing showed 7 findings detected
vs 0 before the fix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* i18n
* fix(github-pr): restrict pr_reviewer to read-only permissions
The PR review agent was using qa_reviewer agent type which has Bash
access, allowing it to checkout branches and make changes during
review. Created new pr_reviewer agent type with BASE_READ_TOOLS only
(no Bash, no writes, no auto-claude tools).
This prevents the PR review from accidentally modifying code or
switching branches during analysis.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-pr): robust category mapping and JSON parsing for PR review
The orchestrator PR review was failing to extract findings because:
1. AI generates category names like 'correctness', 'consistency', 'testing'
that aren't in our ReviewCategory enum - added flexible mapping
2. JSON sometimes embedded in markdown code blocks (```json) which broke
parsing - added code block extraction as first parsing attempt
Changes:
- Add _CATEGORY_MAPPING dict to map AI categories to valid enum values
- Add _map_category() helper function with fallback to QUALITY
- Add severity parsing with fallback to MEDIUM
- Add markdown code block detection (```json) before raw JSON parsing
- Add _extract_findings_from_data() helper to reduce code duplication
- Apply same fixes to review_tools.py for subagent parsing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(pr-review): improve post findings UX with batch support and feedback
- Fix post findings failing on own PRs by falling back from REQUEST_CHANGES
to COMMENT when GitHub returns 422 error
- Change status badge to show "Reviewed" instead of "Commented" until
findings are actually posted to GitHub
- Add success notification when findings are posted (auto-dismisses after 3s)
- Add batch posting support: track posted findings, show "Posted" badge,
allow posting remaining findings in additional batches
- Show loading state on button while posting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): resolve stale timestamp and null author bugs
- Fix stale timestamp in batch_issues.py: Move updated_at assignment
BEFORE to_dict() serialization so the saved JSON contains the correct
timestamp instead of the old value
- Fix AttributeError in context_gatherer.py: Handle null author/user
fields when GitHub API returns null for deleted/suspended users
instead of an empty object
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high and medium severity PR review findings
HIGH severity fixes:
- Command Injection in autofix-handlers.ts: Use execFileSync with args array
- Command Injection in pr-handlers.ts (3 locations): Use execFileSync + validation
- Command Injection in triage-handlers.ts: Use execFileSync + label validation
- Token Exposure in bot_detection.py: Pass token via GH_TOKEN env var
MEDIUM severity fixes:
- Environment variable leakage in subprocess-runner.ts: Filter to safe vars only
- Debug logging in subprocess-runner.ts: Only log in development mode
- Delimiter escape bypass in sanitize.py: Use regex pattern for variations
- Insecure file permissions in trust.py: Use os.open with 0o600 mode
- No file locking in learning.py: Use FileLock + atomic_write utilities
- Bare except in confidence.py: Log error with specific exception info
- Fragile module import in pr_review_engine.py: Import at module level
- State transition validation in models.py: Enforce can_transition_to()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR followup
* fix(security): add usedforsecurity=False to MD5 hash calls
MD5 is used for generating unique IDs/cache keys, not for security purposes.
Adding usedforsecurity=False resolves Bandit B324 warnings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(ui): add PR status labels to list view
Add secondary status badges to the PR list showing review state at a glance:
- "Changes Requested" (warning) - PRs with blocking issues (critical/high)
- "Ready to Merge" (green) - PRs with only non-blocking suggestions
- "Ready for Follow-up" (blue) - PRs with new commits since last review
The "Ready for Follow-up" badge uses a cached new commits check from the
store, only shown after the detail view confirms new commits via SHA
comparison. This prevents false positives from PR updatedAt timestamp
changes (which can happen from comments, labels, etc).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR labels
* auto-claude: Initialize subtask-based implementation plan
- Workflow type: feature
- Phases: 3
- Subtasks: 6
- Ready for autonomous implementation
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* chore(deps): bump vitest from 4.0.15 to 4.0.16 in /apps/frontend (#272)
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.0.15 to 4.0.16.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/vitest)
---
updated-dependencies:
- dependency-name: vitest
dependency-version: 4.0.16
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps): bump @electron/rebuild in /apps/frontend (#271)
Bumps [@electron/rebuild](https://github.com/electron/rebuild) from 3.7.2 to 4.0.2.
- [Release notes](https://github.com/electron/rebuild/releases)
- [Commits](https://github.com/electron/rebuild/compare/v3.7.2...v4.0.2)
---
updated-dependencies:
- dependency-name: "@electron/rebuild"
dependency-version: 4.0.2
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(paths): normalize relative paths to posix (#239)
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix: accept bug_fix workflow_type alias during planning (#240)
* fix(planning): accept bug_fix workflow_type alias
* style(planning): ruff format
* fix: refatored common logic
* fix: remove ruff errors
* fix: remove duplicate _normalize_workflow_type method
Remove the incorrectly placed duplicate method inside ContextLoader class.
The module-level function is the correct implementation being used.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): use develop branch for dry-run builds in beta-release workflow (#276)
When dry_run=true, the workflow skipped creating the version tag but
build jobs still tried to checkout that non-existent tag, causing all
4 platform builds to fail with "git failed with exit code 1".
Now build jobs checkout develop branch for dry runs while still using
the version tag for real releases.
Closes: GitHub Actions run #20464082726
* chore(deps): bump typescript-eslint in /apps/frontend (#269)
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.49.0 to 8.50.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.50.1/packages/typescript-eslint)
---
updated-dependencies:
- dependency-name: typescript-eslint
dependency-version: 8.50.1
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* chore(deps): bump jsdom from 26.1.0 to 27.3.0 in /apps/frontend (#268)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 26.1.0 to 27.3.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/26.1.0...27.3.0)
---
updated-dependencies:
- dependency-name: jsdom
dependency-version: 27.3.0
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(ci): use correct electron-builder arch flags (#278)
The project switched from pnpm to npm, which handles script argument
passing differently. pnpm adds a -- separator that caused electron-builder
to ignore the --arch argument, but npm passes it directly.
Since --arch is a deprecated electron-builder argument, use the
recommended flags instead:
- --arch=x64 → --x64
- --arch=arm64 → --arm64
This fixes Mac Intel and ARM64 builds failing with "Unknown argument: arch"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): resolve CodeQL file system race conditions and unused variables (#277)
* fix(security): resolve CodeQL file system race conditions and unused variables
Fix high severity CodeQL alerts:
- Remove TOCTOU (time-of-check-time-of-use) race conditions by eliminating
existsSync checks followed by file operations. Use try-catch instead.
- Files affected: pr-handlers.ts, spec-utils.ts
Fix unused variable warnings:
- Remove unused imports (FeatureModelCon…
* docs: Add Git Flow branching strategy to CONTRIBUTING.md
- Add comprehensive branching strategy documentation
- Explain main, develop, feature, fix, release, and hotfix branches
- Clarify that all PRs should target develop (not main)
- Add release process documentation for maintainers
- Update PR process to branch from develop
- Expand table of contents with new sections
* Feature/apps restructure v2.7.2 (#138)
* refactor: restructure project to Apps/frontend and Apps/backend
- Move auto-claude-ui to Apps/frontend with feature-based architecture
- Move auto-claude to Apps/backend
- Switch from pnpm to npm for frontend
- Update Node.js requirement to v24.12.0 LTS
- Add pre-commit hooks for lint, typecheck, and security audit
- Add commit-msg hook for conventional commits
- Fix CommonJS compatibility issues (postcss.config, postinstall scripts)
- Update README with comprehensive setup and contribution guidelines
- Configure ESLint to ignore .cjs files
- 0 npm vulnerabilities
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(refactor): clean code and move to npm
* feat(refactor): clean code and move to npm
* chore: update to v2.7.0, remove Docker deps (LadybugDB is embedded)
* feat: v2.8.0 - update workflows and configs for Apps/ structure, npm
* fix: resolve Python lint errors (F401, I001)
* fix: update test paths for Apps/backend structure
* fix: add missing facade files and update paths for Apps/backend structure
- Fix ruff lint error I001 in auto_claude_tools.py
- Create missing facade files to match upstream (agent, ci_discovery, critique, etc.)
- Update test paths from auto-claude/ to Apps/backend/
- Update .pre-commit-config.yaml paths for Apps/ structure
- Add pytest to pre-commit hooks (skip slow/integration/Windows-incompatible tests)
- Fix Unicode encoding in test_agent_architecture.py for Windows
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat: improve readme
* fix: new path
* fix: correct release workflow and docs for Apps/ restructure
- Fix ARM64 macOS build: pnpm → npm, auto-claude-ui → Apps/frontend
- Fix artifact upload paths in release.yml
- Update Node.js version to 24 for consistency
- Update CLI-USAGE.md with Apps/backend paths
- Update RELEASE.md with Apps/frontend/package.json paths
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: rename Apps/ to apps/ and fix backend path resolution
- Rename Apps/ folder to apps/ for consistency with JS/Node conventions
- Update all path references across CI/CD workflows, docs, and config files
- Fix frontend Python path resolver to look for 'backend' instead of 'auto-claude'
- Update path-resolver.ts to correctly find apps/backend in development mode
This completes the Apps restructure from PR #122 and prepares for v2.8.0 release.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(electron): correct preload script path from .js to .mjs
electron-vite builds the preload script as ESM (index.mjs) but the main
process was looking for CommonJS (index.js). This caused the preload to
fail silently, making the app fall back to browser mock mode with fake
data and non-functional IPC handlers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* - Introduced `dev:debug` script to enable debugging during development.
- Added `dev:mcp` script for running the frontend in MCP mode.
These enhancements streamline the development process for frontend developers.
* refactor(memory): make Graphiti memory mandatory and remove Docker dependency
Memory is now a core component of Auto Claude rather than optional:
- Python 3.12+ is required for the backend (not just memory layer)
- Graphiti is enabled by default in .env.example
- Removed all FalkorDB/Docker references (migrated to embedded LadybugDB)
- Deleted guides/DOCKER-SETUP.md and docker-handlers.ts
- Updated onboarding UI to remove "optional" language
- Updated all documentation to reflect LadybugDB architecture
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add cross-platform Windows support for npm scripts
- Add scripts/install-backend.js for cross-platform Python venv setup
- Auto-detects Python 3.12 (py -3.12 on Windows, python3.12 on Unix)
- Handles platform-specific venv paths
- Add scripts/test-backend.js for cross-platform pytest execution
- Update package.json to use Node.js scripts instead of shell commands
- Update CONTRIBUTING.md with correct paths and instructions:
- apps/backend/ and apps/frontend/ paths
- Python 3.12 requirement (memory system now required)
- Platform-specific install commands (winget, brew, apt)
- npm instead of pnpm
- Quick Start section with npm run install:all
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* remove doc
* fix(frontend): correct Ollama detector script path after apps restructure
The Ollama status check was failing because memory-handlers.ts
was looking for ollama_model_detector.py at auto-claude/ but the
script is now at apps/backend/ after the directory restructure.
This caused "Ollama not running" to display even when Ollama was
actually running and accessible.
* chore: bump version to 2.7.2
Downgrade version from 2.8.0 to 2.7.2 as the Apps/ restructure
is better suited as a patch release rather than a minor release.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: update package-lock.json for Windows compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs(contributing): add hotfix workflow and update paths for apps/ structure
Add Git Flow hotfix workflow documentation with step-by-step guide
and ASCII diagram showing the branching strategy.
Update all paths from auto-claude/auto-claude-ui to apps/backend/apps/frontend
and migrate package manager references from pnpm to npm to match the
new project structure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): remove duplicate ARM64 build from Intel runner
The Intel runner was building both x64 and arm64 architectures,
while a separate ARM64 runner also builds arm64 natively. This
caused duplicate ARM64 builds, wasting CI resources.
Now each runner builds only its native architecture:
- Intel runner: x64 only
- ARM64 runner: arm64 only
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Alex Madera <e.a_madera@hotmail.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Feat: Ollama download progress tracking with new apps structure (#141)
* feat(ollama): add real-time download progress tracking for model downloads
Implement comprehensive download progress tracking with:
- NDJSON parsing for streaming progress data from Ollama API
- Real-time speed calculation (MB/s, KB/s, B/s) with useRef for delta tracking
- Time remaining estimation based on download speed
- Animated progress bars in OllamaModelSelector component
- IPC event streaming from main process to renderer
- Proper listener management with cleanup functions
Changes:
- memory-handlers.ts: Parse NDJSON from Ollama stderr, emit progress events
- OllamaModelSelector.tsx: Display progress bars with speed and time remaining
- project-api.ts: Implement onDownloadProgress listener with cleanup
- ipc.ts types: Define onDownloadProgress listener interface
- infrastructure-mock.ts: Add mock implementation for browser testing
This allows users to see real-time feedback when downloading Ollama models,
including percentage complete, current download speed, and estimated time remaining.
* test: add focused test coverage for Ollama download progress feature
Add unit tests for the critical paths of the real-time download progress tracking:
- Progress calculation tests (52 tests): Speed/time/percentage calculations with comprehensive edge case coverage (zero speeds, NaN, Infinity, large numbers)
- NDJSON parser tests (33 tests): Streaming JSON parsing from Ollama, buffer management for incomplete lines, error handling
All 562 unit tests passing with clean dependencies. Tests focus on critical mathematical logic and data processing - the most important paths that need verification.
Test coverage:
✅ Speed calculation and formatting (B/s, KB/s, MB/s)
✅ Time remaining calculations (seconds, minutes, hours)
✅ Percentage clamping (0-100%)
✅ NDJSON streaming with partial line buffering
✅ Invalid JSON handling
✅ Real Ollama API responses
✅ Multi-chunk streaming scenarios
* docs: add comprehensive JSDoc docstrings for Ollama download progress feature
- Enhanced OllamaModelSelector component with detailed JSDoc
* Documented component props, behavior, and usage examples
* Added docstrings to internal functions (checkInstalledModels, handleDownload, handleSelect)
* Explained progress tracking algorithm and useRef usage
- Improved memory-handlers.ts documentation
* Added docstring to main registerMemoryHandlers function
* Documented all Ollama-related IPC handlers (check-status, list-embedding-models, pull-model)
* Added JSDoc to executeOllamaDetector helper function
* Documented interface types (OllamaStatus, OllamaModel, OllamaEmbeddingModel, OllamaPullResult)
* Explained NDJSON parsing and progress event structure
- Enhanced test file documentation
* Added docstrings to NDJSON parser test utilities with algorithm explanation
* Documented all calculation functions (speed, time, percentage)
* Added detailed comments on formatting and bounds-checking logic
- Improved overall code maintainability
* Docstring coverage now meets 80%+ threshold for code review
* Clear explanation of progress tracking implementation details
* Better context for future maintainers working with download streaming
* feat: add batch task creation and management CLI commands
- Handle batch task creation from JSON files
- Show status of all specs in project
- Cleanup tool for completed specs
- Full integration with new apps/backend structure
- Compatible with implementation_plan.json workflow
* test: add batch task test file and testing checklist
- batch_test.json: Sample tasks for testing batch creation
- TESTING_CHECKLIST.md: Comprehensive testing guide for Ollama and batch tasks
- Includes UI testing steps, CLI testing steps, and edge cases
- Ready for manual and automated testing
* chore: update package-lock.json to match v2.7.2
* test: update checklist with verification results and architecture validation
* docs: add comprehensive implementation summary for Ollama + Batch features
* docs: add comprehensive Phase 2 testing guide with checklists and procedures
* docs: add NEXT_STEPS guide for Phase 2 testing
* fix: resolve merge conflict in project-api.ts from Ollama feature cherry-pick
* fix: remove duplicate Ollama check status handler registration
* test: update checklist with Phase 2 bug findings and fixes
---------
Co-authored-by: ray <ray@rays-MacBook-Pro.local>
* fix: resolve Python environment race condition (#142)
Implemented promise queue pattern in PythonEnvManager to handle
concurrent initialization requests. Previously, multiple simultaneous
requests (e.g., startup + merge) would fail with "Already
initializing" error.
Also fixed parsePythonCommand() to handle file paths with spaces by
checking file existence before splitting on whitespace.
Changes:
- Added initializationPromise field to queue concurrent requests
- Split initialize() into public and private _doInitialize()
- Enhanced parsePythonCommand() with existsSync() check
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* fix: remove legacy path from auto-claude source detection (#148)
Removes the legacy 'auto-claude' path from the possiblePaths array
in agent-process.ts. This path was from before the monorepo
restructure (v2.7.2) and is no longer needed.
The legacy path was causing spec_runner.py to be looked up at the
wrong location:
- OLD (wrong): /path/to/auto-claude/auto-claude/runners/spec_runner.py
- NEW (correct): /path/to/apps/backend/runners/spec_runner.py
This aligns with the new monorepo structure where all backend code
lives in apps/backend/.
Fixes #147
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* Fix/linear 400 error
* fix: Linear API authentication and GraphQL types
- Remove Bearer prefix from Authorization header (Linear API keys are sent directly)
- Change GraphQL variable types from String! to ID! for teamId and issue IDs
- Improve error handling to show detailed Linear API error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: Radix Select empty value error in Linear import modal
Use '__all__' sentinel value instead of empty string for "All projects"
option, as Radix Select does not allow empty string values.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add CodeRabbit configuration file
Introduce a new .coderabbit.yaml file to configure CodeRabbit settings, including review profiles, automatic review options, path filters, and specific instructions for different file types. This enhances the code review process by providing tailored guidelines for Python, TypeScript, and test files.
* fix: correct GraphQL types for Linear team queries
Linear API uses different types for different queries:
- team(id:) expects String!
- issues(filter: { team: { id: { eq: } } }) expects ID!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: refresh task list after Linear import
Call loadTasks() after successful Linear import to update the kanban
board without requiring a page reload.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* cleanup
* cleanup
* fix: address CodeRabbit review comments for Linear integration
- Fix unsafe JSON parsing: check response.ok before parsing JSON to handle
non-JSON error responses (e.g., 503 from proxy) gracefully
- Use ID! type instead of String! for teamId in LINEAR_GET_PROJECTS query
for GraphQL type consistency
- Remove debug console.log (ESLint config only allows warn/error)
- Refresh task list on partial import success (imported > 0) instead of
requiring full success
- Fix pre-existing TypeScript and lint issues blocking commit
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* version sync logic
* lints for develop branch
* chore: update CI workflow to include develop branch
- Modified the CI configuration to trigger on pushes and pull requests to both main and develop branches, enhancing the workflow for development and integration processes.
* fix: update project directory auto-detection for apps/backend structure
The project directory auto-detection was checking for the old `auto-claude/`
directory name but needed to check for `apps/backend/`. When running from
`apps/backend/`, the directory name is `backend` not `auto-claude`, so the
check would fail and `project_dir` would incorrectly remain as `apps/backend/`
instead of resolving to the project root (2 levels up).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use GraphQL variables instead of string interpolation in LINEAR_GET_ISSUES
Replace direct string interpolation of teamId and linearProjectId with
proper GraphQL variables. This prevents potential query syntax errors if
IDs contain special characters like double quotes, and aligns with the
variable-based approach used elsewhere in the file.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ui): correct logging level and await loadTasks on import complete
- Change console.warn to console.log for import success messages
(warn is incorrect severity for normal completion)
- Make onImportComplete callback async and await loadTasks()
to prevent potential unhandled promise rejections
Applies CodeRabbit review feedback across 3 LinearTaskImportModal usages.
* fix(hooks): use POSIX-compliant find instead of bash glob
The pre-commit hook uses #!/bin/sh but had bash-specific ** glob
pattern for staging ruff-formatted files. The ** pattern only works
in bash with globstar enabled - in POSIX sh it expands literally
and won't match subdirectories, causing formatted files in nested
directories to not be staged.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(task): stop running process when task status changes away from in_progress
When a user drags a running task back to Planning (or any other column),
the process was not being stopped, leaving a "ghost" process that
prevented deletion with "Cannot delete a running task" error.
Now the task process is automatically killed when status changes away
from in_progress, ensuring the process state stays in sync with the UI.
* feat: Add UI scale feature with 75-200% range (#125)
* feat: add UI scale feature
* refactor: extract UI scale bounds to shared constants
* fix: duplicated import
* fix: hide status badge when execution phase badge is showing (#154)
* fix: analyzer Python compatibility and settings integration
Fixes project index analyzer failing with TypeError on Python type hints.
Changes:
- Added 'from __future__ import annotations' to all analysis modules
- Fixed project discovery to support new analyzer JSON format
- Read Python path directly from settings.json instead of pythonEnvManager
- Added stderr/stdout logging for analyzer debugging
Resolves 'Discovered 0 files' and 'TypeError: unsupported operand type' issues.
* auto-claude: subtask-1-1 - Hide status badge when execution phase badge is showing
When a task has an active execution (planning, coding, etc.), the
execution phase badge already displays the correct state with a spinner.
The status badge was also rendering, causing duplicate/confusing badges
(e.g., both "Planning" and "Pending" showing at the same time).
This fix wraps the status badge in a conditional that only renders when
there's no active execution, eliminating the redundant badge display.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ipc): remove unused pythonEnvManager parameter and fix ES6 import
Address CodeRabbit review feedback:
- Remove unused pythonEnvManager parameter from registerProjectContextHandlers
and registerContextHandlers (the code reads Python path directly from
settings.json instead)
- Replace require('electron').app with proper ES6 import for consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(lint): fix import sorting in analysis module
Run ruff --fix to resolve I001 lint errors after merging develop.
All 23 files in apps/backend/analysis/ now have properly sorted imports.
---------
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix/PRs from old main setup to apps structure (#185)
* fix(core): add task persistence, terminal handling, and HTTP 300 fixes
Consolidated bug fixes from PRs #168, #170, #171:
- Task persistence (#168): Scan worktrees for tasks on app restart
to prevent loss of in-progress work and wasted API credits. Tasks
in .worktrees/*/specs are now loaded and deduplicated with main.
- Terminal buttons (#170): Fix "Open Terminal" buttons silently
failing on macOS by properly awaiting createTerminal() Promise.
Added useTerminalHandler hook with loading states and error display.
- HTTP 300 errors (#171): Handle branch/tag name collisions that
cause update failures. Added validation script to prevent conflicts
before releases and user-friendly error messages with manual
download links.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(platform): add path resolution, spaces handling, and XDG support
This commit consolidates multiple bug fixes from community PRs:
- PR #187: Path resolution fix - Update path detection to find apps/backend
instead of legacy auto-claude directory after v2.7.2 restructure
- PR #182/#155: Python path spaces fix - Improve parsePythonCommand() to
handle quoted paths and paths containing spaces without splitting
- PR #161: Ollama detection fix - Add new apps structure paths for
ollama_model_detector.py script discovery
- PR #160: AppImage support - Add XDG Base Directory compliant paths for
Linux sandboxed environments (AppImage, Flatpak, Snap). New files:
- config-paths.ts: XDG path utilities
- fs-utils.ts: Filesystem utilities with fallback support
- PR #159: gh CLI PATH fix - Add getAugmentedEnv() utility to include
common binary locations (Homebrew, snap, local) in PATH for child
processes. Fixes gh CLI not found when app launched from Finder/Dock.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit/Cursor review comments on PR #185
Fixes from code review:
- http-client.ts: Use GITHUB_CONFIG instead of hardcoded owner in HTTP 300 error message
- validate-release.js: Fix substring matching bug in branch detection that could cause false positives (e.g., v2.7 matching v2.7.2)
- bump-version.js: Remove unnecessary try-catch wrapper (exec() already exits on failure)
- execution-handlers.ts: Capture original subtask status before mutation for accurate logging
- fs-utils.ts: Add error handling to safeWriteFile with proper logging
Dismissed as trivial/not applicable:
- config-paths.ts: Exhaustive switch check (over-engineering)
- env-utils.ts: PATH priority documentation (existing comments sufficient)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address additional CodeRabbit review comments (round 2)
Fixes from second round of code review:
- fs-utils.ts: Wrap test file cleanup in try-catch for Windows file locking
- fs-utils.ts: Add error handling to safeReadFile for consistency with safeWriteFile
- http-client.ts: Use GITHUB_CONFIG in fetchJson (missed in first round)
- validate-release.js: Exclude symbolic refs (origin/HEAD -> origin/main) from branch check
- python-detector.ts: Return cleanPath instead of pythonPath for empty input edge case
Dismissed as trivial/not applicable:
- execution-handlers.ts: Redundant checkSubtasksCompletion call (micro-optimization)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat/beta-release (#190)
* chore: update README version to 2.7.1
Updated the version badge and download links in the README to reflect the new release version 2.7.1, ensuring users have the correct information for downloading the latest builds.
* feat(releases): add beta release system with user opt-in
Implements a complete beta release workflow that allows users to opt-in
to receiving pre-release versions. This enables testing new features
before they're included in stable releases.
Changes:
- Add beta-release.yml workflow for creating beta releases from develop
- Add betaUpdates setting with UI toggle in Settings > Updates
- Add update channel support to electron-updater (beta vs latest)
- Extract shared settings-utils.ts to reduce code duplication
- Add prepare-release.yml workflow for automated release preparation
- Document beta release process in CONTRIBUTING.md and RELEASE.md
Users can enable beta updates in Settings > Updates, and maintainers
can trigger beta releases via the GitHub Actions workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* workflow update
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Feat/beta release (#193)
* chore: update README version to 2.7.1
Updated the version badge and download links in the README to reflect the new release version 2.7.1, ensuring users have the correct information for downloading the latest builds.
* feat(releases): add beta release system with user opt-in
Implements a complete beta release workflow that allows users to opt-in
to receiving pre-release versions. This enables testing new features
before they're included in stable releases.
Changes:
- Add beta-release.yml workflow for creating beta releases from develop
- Add betaUpdates setting with UI toggle in Settings > Updates
- Add update channel support to electron-updater (beta vs latest)
- Extract shared settings-utils.ts to reduce code duplication
- Add prepare-release.yml workflow for automated release preparation
- Document beta release process in CONTRIBUTING.md and RELEASE.md
Users can enable beta updates in Settings > Updates, and maintainers
can trigger beta releases via the GitHub Actions workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* workflow update
* ci(github): update Discord link and redirect feature requests to discussions
Update Discord invite link to correct URL (QhRnz9m5HE) across all GitHub
templates and workflows. Redirect feature requests from issue template
to GitHub Discussions for better community engagement.
Changes:
- config.yml: Add feature request link to Discussions, fix Discord URL
- question.yml: Update Discord link in pre-question guidance
- welcome.yml: Update Discord link in first-time contributor message
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): correct welcome workflow PR message (#206)
- Change branch reference from main to develop
- Fix contribution guide link to use full URL
- Remove hyphen from "Auto Claude" in welcome message
* fix: Add Python 3.10+ version validation and GitHub Actions Python setup (#180 #167) (#208)
This fixes critical bug where macOS users with default Python 3.9.6 couldn't use Auto-Claude because claude-agent-sdk requires Python 3.10+.
Root Cause:
- Auto-Claude doesn't bundle Python, relies on system Python
- python-detector.ts accepted any Python 3.x without checking minimum version
- macOS ships with Python 3.9.6 by default (incompatible)
- GitHub Actions runners didn't explicitly set Python version
Changes:
1. python-detector.ts:
- Added getPythonVersion() to extract version from command
- Added validatePythonVersion() to check if >= 3.10.0
- Updated findPythonCommand() to skip Python < 3.10 with clear error messages
2. python-env-manager.ts:
- Import and use findPythonCommand() (already has version validation)
- Simplified findSystemPython() to use shared validation logic
- Updated error message from "Python 3.9+" to "Python 3.10+" with download link
3. .github/workflows/release.yml:
- Added Python 3.11 setup to all 4 build jobs (macOS Intel, macOS ARM64, Windows, Linux)
- Ensures consistent Python version across all platforms during build
Impact:
- macOS users with Python 3.9 now see clear error with download link
- macOS users with Python 3.10+ work normally
- CI/CD builds use consistent Python 3.11
- Prevents "ModuleNotFoundError: dotenv" and dependency install failures
Fixes #180, #167
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* feat: Add OpenRouter as LLM/embedding provider (#162)
* feat: Add OpenRouter as LLM/embedding provider
Add OpenRouter provider support for Graphiti memory integration,
enabling access to multiple LLM providers through a single API.
Changes:
Backend:
- Created openrouter_llm.py: OpenRouter LLM provider using OpenAI-compatible API
- Created openrouter_embedder.py: OpenRouter embedder provider
- Updated config.py: Added OpenRouter to provider enums and configuration
- New fields: openrouter_api_key, openrouter_base_url, openrouter_llm_model, openrouter_embedding_model
- Validation methods updated for OpenRouter
- Updated factory.py: Added OpenRouter to LLM and embedder factories
- Updated provider __init__.py files: Exported new OpenRouter functions
Frontend:
- Updated project.ts types: Added 'openrouter' to provider type unions
- GraphitiProviderConfig extended with OpenRouter fields
- Updated GraphitiStep.tsx: Added OpenRouter to provider arrays
- LLM_PROVIDERS: 'Multi-provider aggregator'
- EMBEDDING_PROVIDERS: 'OpenAI-compatible embeddings'
- Added OpenRouter API key input field with show/hide toggle
- Link to https://openrouter.ai/keys
- Updated env-handlers.ts: OpenRouter .env generation and parsing
- Template generation for OPENROUTER_* variables
- Parsing from .env files with proper type casting
Documentation:
- Updated .env.example with OpenRouter section
- Configuration examples
- Popular model recommendations
- Example configuration (#6)
Fixes #92
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* refactor: address CodeRabbit review comments for OpenRouter
- Add globalOpenRouterApiKey to settings types and store updates
- Initialize openrouterApiKey from global settings
- Update documentation to include OpenRouter in provider lists
- Add OpenRouter handling to get_embedding_dimension() method
- Add openrouter to provider cleanup list
- Add OpenRouter to get_available_providers() function
- Clarify Legacy comment for openrouterLlmModel
These changes complete the OpenRouter integration by ensuring proper
settings persistence and provider detection across the application.
* fix: apply ruff formatting to OpenRouter code
- Break long error message across multiple lines
- Format provider list with one item per line
- Fixes lint CI failure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix(core): add global spec numbering lock to prevent collisions (#209)
Implements distributed file-based locking for spec number coordination
across main project and all worktrees. Previously, parallel spec creation
could assign the same number to different specs (e.g., 042-bmad-task and
042-gitlab-integration both using number 042).
The fix adds SpecNumberLock class that:
- Acquires exclusive lock before calculating spec numbers
- Scans ALL locations (main project + worktrees) for global maximum
- Creates spec directories atomically within the lock
- Handles stale locks via PID-based detection with 30s timeout
Applied to both Python backend (spec_runner.py flow) and TypeScript
frontend (ideation conversion, GitHub/GitLab issue import).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Fix/ideation status sync (#212)
* fix(ideation): add missing event forwarders for status sync
- Add event forwarders in ideation-handlers.ts for progress, log,
type-complete, type-failed, complete, error, and stopped events
- Fix ideation-type-complete to load actual ideas array from JSON files
instead of emitting only the count
Resolves UI getting stuck at 0/3 complete during ideation generation.
* fix(ideation): fix UI not updating after actions
- Fix getIdeationSummary to count only active ideas (exclude dismissed/archived)
This ensures header stats match the visible ideas count
- Add transformSessionFromSnakeCase to properly transform session data
from backend snake_case to frontend camelCase on ideation-complete event
- Transform raw session before emitting ideation-complete event
Resolves header showing stale counts after dismissing/deleting ideas.
* fix(ideation): improve type safety and async handling in ideation type completion
- Replace synchronous readFileSync with async fsPromises.readFile in ideation-type-complete handler
- Wrap async file read in IIFE with proper error handling to prevent unhandled promise rejections
- Add type validation for IdeationType with VALID_IDEATION_TYPES set and isValidIdeationType guard
- Add validateEnabledTypes function to filter out invalid type values and log dropped entries
- Handle ENOENT separately
* fix(ideation): improve generation state management and error handling
- Add explicit isGenerating flag to prevent race conditions during async operations
- Implement 5-minute timeout for generation with automatic cleanup and error state
- Add ideation-stopped event emission when process is intentionally killed
- Replace console.warn/error with proper ideation-error events in agent-queue
- Add resetGeneratingTypes helper to transition all generating types to a target state
- Filter out dismissed/
* refactor(ideation): improve event listener cleanup and timeout management
- Extract event handler functions in ideation-handlers.ts to enable proper cleanup
- Return cleanup function from registerIdeationHandlers to remove all listeners
- Replace single generationTimeoutId with Map to support multiple concurrent projects
- Add clearGenerationTimeout helper to centralize timeout cleanup logic
- Extract loadIdeationType IIFE to named function for better error context
- Enhance error logging with projectId,
* refactor: use async file read for ideation and roadmap session loading
- Replace synchronous readFileSync with async fsPromises.readFile
- Prevents blocking the event loop during file operations
- Consistent with async pattern used elsewhere in the codebase
- Improved error handling with proper event emission
* fix(agent-queue): improve roadmap completion handling and error reporting
- Add transformRoadmapFromSnakeCase to convert backend snake_case to frontend camelCase
- Transform raw roadmap data before emitting roadmap-complete event
- Add roadmap-error emission for unexpected errors during completion
- Add roadmap-error emission when project path is unavailable
- Remove duplicate ideation-type-complete emission from error handler (event already emitted in loadIdeationType)
- Update error log message
* fix: add future annotations import to discovery.py (#229)
Adds 'from __future__ import annotations' to spec/discovery.py for
Python 3.9+ compatibility with type hints.
This completes the Python compatibility fixes that were partially
applied in previous commits. All 26 analysis and spec Python files
now have the future annotations import.
Related: #128
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* fix: resolve Python detection and backend packaging issues (#241)
* fix: resolve Python detection and backend packaging issues
- Fix backend packaging path (auto-claude -> backend) to match path-resolver.ts expectations
- Add future annotations import to config_parser.py for Python 3.9+ compatibility
- Use findPythonCommand() in project-context-handlers to prioritize Homebrew Python
- Improve Python detection to prefer Homebrew paths over system Python on macOS
This resolves the following issues:
- 'analyzer.py not found' error due to incorrect packaging destination
- TypeError with 'dict | None' syntax on Python < 3.10
- Wrong Python interpreter being used (system Python instead of Homebrew Python 3.10+)
Tested on macOS with packaged app - project index now loads successfully.
* refactor: address PR review feedback
- Extract findHomebrewPython() helper to eliminate code duplication between
findPythonCommand() and getDefaultPythonCommand()
- Remove hardcoded version-specific paths (python3.12) and rely only on
generic Homebrew symlinks for better maintainability
- Remove unnecessary 'from __future__ import annotations' from config_parser.py
since backend requires Python 3.12+ where union types are native
These changes make the code more maintainable, less fragile to Python version
changes, and properly reflect the project's Python 3.12+ requirement.
* Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Revert "Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)" (#251)
This reverts commit 348de6dfe793ab111043677c61b8452bc5ecb2cc.
* feat: add i18n internationalization system (#248)
* Add multilingual support and i18n integration
- Implemented i18n framework using `react-i18next` for translation management.
- Added support for English and French languages with translation files.
- Integrated language selector into settings.
- Updated all text strings in UI components to use translation keys.
- Ensured smooth language switching with live updates.
* Migrate remaining hard-coded strings to i18n system
- TaskCard: status labels, review reasons, badges, action buttons
- PhaseProgressIndicator: execution phases, progress labels
- KanbanBoard: drop zone, show archived, tooltips
- CustomModelModal: dialog title, description, labels
- ProactiveSwapListener: account switch notifications
- AgentProfileSelector: phase labels, custom configuration
- GeneralSettings: agent framework option
Added translation keys for en/fr locales in tasks.json, common.json,
and settings.json for complete i18n coverage.
* Add i18n support to dialogs and settings components
- AddFeatureDialog: form labels, validation messages, buttons
- AddProjectModal: dialog steps, form fields, actions
- RateLimitIndicator: rate limit notifications
- RateLimitModal: account switching, upgrade prompts
- AdvancedSettings: updates and notifications sections
- ThemeSettings: theme selection labels
- Updated dialogs.json locales (en/fr)
* Fix truncated 'ready' message in dialogs locales
* Fix backlog terminology in i18n locales
Change "Planning"/"Planification" to standard PM term "Backlog"
* Migrate settings navigation and integration labels to i18n
- AppSettings: nav items, section titles, buttons
- IntegrationSettings: Claude accounts, auto-switch, API keys labels
- Added settings nav/projectSections/integrations translation keys
- Added buttons.saving to common translations
* Migrate AgentProfileSettings and Sidebar init dialog to i18n
- AgentProfileSettings: migrate phase config labels, section title,
description, and all hardcoded strings to settings namespace
- Sidebar: migrate init dialog strings to dialogs namespace with
common buttons from common namespace
- Add new translation keys for agent profile settings and update dialog
* Migrate AppSettings navigation labels to i18n
- Add useTranslation hook to AppSettings.tsx
- Replace hardcoded section labels with dynamic translations
- Add projectSections translations for project settings nav
- Add rerunWizardDescription translation key
* Add explicit typing to notificationItems array
Import NotificationSettings type and use keyof to properly type
the notification item keys, removing manual type assertion.
* fix: update path resolution for ollama_model_detector.py in memory handlers (#263)
* ci: implement enterprise-grade PR quality gates and security scanning (#266)
* ci: implement enterprise-grade PR quality gates and security scanning
* ci: implement enterprise-grade PR quality gates and security scanning
* fix:pr comments and improve code
* fix: improve commit linting and code quality
* Removed the dependency-review job (i added it)
* fix: address CodeRabbit review comments
- Expand scope pattern to allow uppercase, underscores, slashes, dots
- Add concurrency control to cancel duplicate security scan runs
- Add explanatory comment for Bandit CLI flags
- Remove dependency-review job (requires repo settings)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: update commit lint examples with expanded scope patterns
Show slashes and dots in scope examples to demonstrate
the newly allowed characters (api/users, package.json)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove feature request issue template
Feature requests are directed to GitHub Discussions
via the issue template config.yml
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address security vulnerabilities in service orchestrator
- Fix port parsing crash on malformed docker-compose entries
- Fix shell injection risk by using shlex.split() with shell=False
Prevents crashes when docker-compose.yml contains environment
variables in port mappings (e.g., '${PORT}:8080') and eliminates
shell injection vulnerabilities in subprocess execution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat(github): add automated PR review with follow-up support (#252)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fixes during testing of PR
* feat(github): implement PR merge, assign, and comment features
- Add auto-assignment when clicking "Run AI Review"
- Implement PR merge functionality with squash method
- Add ability to post comments on PRs
- Display assignees in PR UI
- Add Approve and Merge buttons when review passes
- Update backend gh_client with pr_merge, pr_comment, pr_assign methods
- Create IPC handlers for new PR operations
- Update TypeScript interfaces and browser mocks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Improve PR review AI
* fix(github): use temp files for PR review posting to avoid shell escaping issues
When posting PR reviews with findings containing special characters (backticks,
parentheses, quotes), the shell command was interpreting them as commands instead
of literal text, causing syntax errors.
Changed both postPRReview and postPRComment handlers to write the body content
to temporary files and use gh CLI's --body-file flag instead of --body with
inline content. This safely handles ALL special characters without escaping issues.
Fixes shell errors when posting reviews with suggested fixes containing code snippets.
* fix(i18n): add missing GitHub PRs translation and document i18n requirements
Fixed missing translation key for GitHub PRs feature that was causing
"items.githubPRs" to display instead of the proper translated text.
Added comprehensive i18n guidelines to CLAUDE.md to ensure all future
frontend development follows the translation key pattern instead of
using hardcoded strings.
Also fixed missing deletePRReview mock function in browser-mock.ts
to resolve TypeScript compilation errors.
Changes:
- Added githubPRs translation to en/navigation.json
- Added githubPRs translation to fr/navigation.json
- Added Development Guidelines section to CLAUDE.md with i18n requirements
- Documented translation file locations and namespace usage patterns
- Added deletePRReview mock function to browser-mock.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix ui loading
* Github PR fixes
* improve claude.md
* lints/tests
* fix(github): handle PRs exceeding GitHub's 20K line diff limit
- Add PRTooLargeError exception for large PR detection
- Update pr_diff() to catch and raise PRTooLargeError for HTTP 406 errors
- Gracefully handle large PRs by skipping full diff and using individual file patches
- Add diff_truncated flag to PRContext to track when diff was skipped
- Large PRs will now review successfully using per-file diffs instead of failing
Fixes issue with PR #252 which has 100+ files exceeding the 20,000 line limit.
* fix: implement individual file patch fetching for large PRs
The PR review was getting stuck for large PRs (>20K lines) because when we
skipped the full diff due to GitHub API limits, we had no code to analyze.
The individual file patches were also empty, leaving the AI with just
file names and metadata.
Changes:
- Implemented _get_file_patch() to fetch individual patches via git diff
- Updated PR review engine to build composite diff from file patches when
diff_truncated is True
- Added missing 'state' field to PRContext dataclass
- Limits composite diff to first 50 files for very large PRs
- Shows appropriate warnings when using reconstructed diffs
This allows AI review to proceed with actual code analysis even when the
full PR diff exceeds GitHub's limits.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* 1min reduction
* docs: add GitHub Sponsors funding configuration
Enable the Sponsor button on the repository by adding FUNDING.yml
with the AndyMik90 GitHub Sponsors profile.
* feat(github-pr): add orchestrating agent for thorough PR reviews
Implement a new Opus 4.5 orchestrating agent that performs comprehensive
PR reviews regardless of size. Key changes:
- Add orchestrator_reviewer.py with strategic review workflow
- Add review_tools.py with subagent spawning capabilities
- Add pr_orchestrator.md prompt emphasizing thorough analysis
- Add pr_security_agent.md and pr_quality_agent.md subagent prompts
- Integrate orchestrator into pr_review_engine.py with config flag
- Fix critical bug where findings were extracted but not processed
(indentation issue in _parse_orchestrator_output)
The orchestrator now correctly identifies issues in PRs that were
previously approved as "trivial". Testing showed 7 findings detected
vs 0 before the fix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* i18n
* fix(github-pr): restrict pr_reviewer to read-only permissions
The PR review agent was using qa_reviewer agent type which has Bash
access, allowing it to checkout branches and make changes during
review. Created new pr_reviewer agent type with BASE_READ_TOOLS only
(no Bash, no writes, no auto-claude tools).
This prevents the PR review from accidentally modifying code or
switching branches during analysis.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-pr): robust category mapping and JSON parsing for PR review
The orchestrator PR review was failing to extract findings because:
1. AI generates category names like 'correctness', 'consistency', 'testing'
that aren't in our ReviewCategory enum - added flexible mapping
2. JSON sometimes embedded in markdown code blocks (```json) which broke
parsing - added code block extraction as first parsing attempt
Changes:
- Add _CATEGORY_MAPPING dict to map AI categories to valid enum values
- Add _map_category() helper function with fallback to QUALITY
- Add severity parsing with fallback to MEDIUM
- Add markdown code block detection (```json) before raw JSON parsing
- Add _extract_findings_from_data() helper to reduce code duplication
- Apply same fixes to review_tools.py for subagent parsing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(pr-review): improve post findings UX with batch support and feedback
- Fix post findings failing on own PRs by falling back from REQUEST_CHANGES
to COMMENT when GitHub returns 422 error
- Change status badge to show "Reviewed" instead of "Commented" until
findings are actually posted to GitHub
- Add success notification when findings are posted (auto-dismisses after 3s)
- Add batch posting support: track posted findings, show "Posted" badge,
allow posting remaining findings in additional batches
- Show loading state on button while posting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): resolve stale timestamp and null author bugs
- Fix stale timestamp in batch_issues.py: Move updated_at assignment
BEFORE to_dict() serialization so the saved JSON contains the correct
timestamp instead of the old value
- Fix AttributeError in context_gatherer.py: Handle null author/user
fields when GitHub API returns null for deleted/suspended users
instead of an empty object
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high and medium severity PR review findings
HIGH severity fixes:
- Command Injection in autofix-handlers.ts: Use execFileSync with args array
- Command Injection in pr-handlers.ts (3 locations): Use execFileSync + validation
- Command Injection in triage-handlers.ts: Use execFileSync + label validation
- Token Exposure in bot_detection.py: Pass token via GH_TOKEN env var
MEDIUM severity fixes:
- Environment variable leakage in subprocess-runner.ts: Filter to safe vars only
- Debug logging in subprocess-runner.ts: Only log in development mode
- Delimiter escape bypass in sanitize.py: Use regex pattern for variations
- Insecure file permissions in trust.py: Use os.open with 0o600 mode
- No file locking in learning.py: Use FileLock + atomic_write utilities
- Bare except in confidence.py: Log error with specific exception info
- Fragile module import in pr_review_engine.py: Import at module level
- State transition validation in models.py: Enforce can_transition_to()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR followup
* fix(security): add usedforsecurity=False to MD5 hash calls
MD5 is used for generating unique IDs/cache keys, not for security purposes.
Adding usedforsecurity=False resolves Bandit B324 warnings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(ui): add PR status labels to list view
Add secondary status badges to the PR list showing review state at a glance:
- "Changes Requested" (warning) - PRs with blocking issues (critical/high)
- "Ready to Merge" (green) - PRs with only non-blocking suggestions
- "Ready for Follow-up" (blue) - PRs with new commits since last review
The "Ready for Follow-up" badge uses a cached new commits check from the
store, only shown after the detail view confirms new commits via SHA
comparison. This prevents false positives from PR updatedAt timestamp
changes (which can happen from comments, labels, etc).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR labels
* auto-claude: Initialize subtask-based implementation plan
- Workflow type: feature
- Phases: 3
- Subtasks: 6
- Ready for autonomous implementation
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* chore(deps): bump vitest from 4.0.15 to 4.0.16 in /apps/frontend (#272)
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.0.15 to 4.0.16.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/vitest)
---
updated-dependencies:
- dependency-name: vitest
dependency-version: 4.0.16
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps): bump @electron/rebuild in /apps/frontend (#271)
Bumps [@electron/rebuild](https://github.com/electron/rebuild) from 3.7.2 to 4.0.2.
- [Release notes](https://github.com/electron/rebuild/releases)
- [Commits](https://github.com/electron/rebuild/compare/v3.7.2...v4.0.2)
---
updated-dependencies:
- dependency-name: "@electron/rebuild"
dependency-version: 4.0.2
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(paths): normalize relative paths to posix (#239)
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix: accept bug_fix workflow_type alias during planning (#240)
* fix(planning): accept bug_fix workflow_type alias
* style(planning): ruff format
* fix: refatored common logic
* fix: remove ruff errors
* fix: remove duplicate _normalize_workflow_type method
Remove the incorrectly placed duplicate method inside ContextLoader class.
The module-level function is the correct implementation being used.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): use develop branch for dry-run builds in beta-release workflow (#276)
When dry_run=true, the workflow skipped creating the version tag but
build jobs still tried to checkout that non-existent tag, causing all
4 platform builds to fail with "git failed with exit code 1".
Now build jobs checkout develop branch for dry runs while still using
the version tag for real releases.
Closes: GitHub Actions run #20464082726
* chore(deps): bump typescript-eslint in /apps/frontend (#269)
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.49.0 to 8.50.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.50.1/packages/typescript-eslint)
---
updated-dependencies:
- dependency-name: typescript-eslint
dependency-version: 8.50.1
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* chore(deps): bump jsdom from 26.1.0 to 27.3.0 in /apps/frontend (#268)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 26.1.0 to 27.3.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/26.1.0...27.3.0)
---
updated-dependencies:
- dependency-name: jsdom
dependency-version: 27.3.0
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(ci): use correct electron-builder arch flags (#278)
The project switched from pnpm to npm, which handles script argument
passing differently. pnpm adds a -- separator that caused electron-builder
to ignore the --arch argument, but npm passes it directly.
Since --arch is a deprecated electron-builder argument, use the
recommended flags instead:
- --arch=x64 → --x64
- --arch=arm64 → --arm64
This fixes Mac Intel and ARM64 builds failing with "Unknown argument: arch"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): resolve CodeQL file system race conditions and unused variables (#277)
* fix(security): resolve CodeQL file system race conditions and unused variables
Fix high severity CodeQL alerts:
- Remove TOCTOU (time-of-check-time-of-use) race conditions by eliminating
existsSync checks followed by file operations. Use try-catch instead.
- Files affected: pr-handlers.ts, spec-utils.ts
Fix unused variable warnings:
- Remove unused imports (FeatureModelCo…
* docs: Add Git Flow branching strategy to CONTRIBUTING.md
- Add comprehensive branching strategy documentation
- Explain main, develop, feature, fix, release, and hotfix branches
- Clarify that all PRs should target develop (not main)
- Add release process documentation for maintainers
- Update PR process to branch from develop
- Expand table of contents with new sections
* Feature/apps restructure v2.7.2 (#138)
* refactor: restructure project to Apps/frontend and Apps/backend
- Move auto-claude-ui to Apps/frontend with feature-based architecture
- Move auto-claude to Apps/backend
- Switch from pnpm to npm for frontend
- Update Node.js requirement to v24.12.0 LTS
- Add pre-commit hooks for lint, typecheck, and security audit
- Add commit-msg hook for conventional commits
- Fix CommonJS compatibility issues (postcss.config, postinstall scripts)
- Update README with comprehensive setup and contribution guidelines
- Configure ESLint to ignore .cjs files
- 0 npm vulnerabilities
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(refactor): clean code and move to npm
* feat(refactor): clean code and move to npm
* chore: update to v2.7.0, remove Docker deps (LadybugDB is embedded)
* feat: v2.8.0 - update workflows and configs for Apps/ structure, npm
* fix: resolve Python lint errors (F401, I001)
* fix: update test paths for Apps/backend structure
* fix: add missing facade files and update paths for Apps/backend structure
- Fix ruff lint error I001 in auto_claude_tools.py
- Create missing facade files to match upstream (agent, ci_discovery, critique, etc.)
- Update test paths from auto-claude/ to Apps/backend/
- Update .pre-commit-config.yaml paths for Apps/ structure
- Add pytest to pre-commit hooks (skip slow/integration/Windows-incompatible tests)
- Fix Unicode encoding in test_agent_architecture.py for Windows
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat: improve readme
* fix: new path
* fix: correct release workflow and docs for Apps/ restructure
- Fix ARM64 macOS build: pnpm → npm, auto-claude-ui → Apps/frontend
- Fix artifact upload paths in release.yml
- Update Node.js version to 24 for consistency
- Update CLI-USAGE.md with Apps/backend paths
- Update RELEASE.md with Apps/frontend/package.json paths
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: rename Apps/ to apps/ and fix backend path resolution
- Rename Apps/ folder to apps/ for consistency with JS/Node conventions
- Update all path references across CI/CD workflows, docs, and config files
- Fix frontend Python path resolver to look for 'backend' instead of 'auto-claude'
- Update path-resolver.ts to correctly find apps/backend in development mode
This completes the Apps restructure from PR #122 and prepares for v2.8.0 release.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(electron): correct preload script path from .js to .mjs
electron-vite builds the preload script as ESM (index.mjs) but the main
process was looking for CommonJS (index.js). This caused the preload to
fail silently, making the app fall back to browser mock mode with fake
data and non-functional IPC handlers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* - Introduced `dev:debug` script to enable debugging during development.
- Added `dev:mcp` script for running the frontend in MCP mode.
These enhancements streamline the development process for frontend developers.
* refactor(memory): make Graphiti memory mandatory and remove Docker dependency
Memory is now a core component of Auto Claude rather than optional:
- Python 3.12+ is required for the backend (not just memory layer)
- Graphiti is enabled by default in .env.example
- Removed all FalkorDB/Docker references (migrated to embedded LadybugDB)
- Deleted guides/DOCKER-SETUP.md and docker-handlers.ts
- Updated onboarding UI to remove "optional" language
- Updated all documentation to reflect LadybugDB architecture
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add cross-platform Windows support for npm scripts
- Add scripts/install-backend.js for cross-platform Python venv setup
- Auto-detects Python 3.12 (py -3.12 on Windows, python3.12 on Unix)
- Handles platform-specific venv paths
- Add scripts/test-backend.js for cross-platform pytest execution
- Update package.json to use Node.js scripts instead of shell commands
- Update CONTRIBUTING.md with correct paths and instructions:
- apps/backend/ and apps/frontend/ paths
- Python 3.12 requirement (memory system now required)
- Platform-specific install commands (winget, brew, apt)
- npm instead of pnpm
- Quick Start section with npm run install:all
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* remove doc
* fix(frontend): correct Ollama detector script path after apps restructure
The Ollama status check was failing because memory-handlers.ts
was looking for ollama_model_detector.py at auto-claude/ but the
script is now at apps/backend/ after the directory restructure.
This caused "Ollama not running" to display even when Ollama was
actually running and accessible.
* chore: bump version to 2.7.2
Downgrade version from 2.8.0 to 2.7.2 as the Apps/ restructure
is better suited as a patch release rather than a minor release.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: update package-lock.json for Windows compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs(contributing): add hotfix workflow and update paths for apps/ structure
Add Git Flow hotfix workflow documentation with step-by-step guide
and ASCII diagram showing the branching strategy.
Update all paths from auto-claude/auto-claude-ui to apps/backend/apps/frontend
and migrate package manager references from pnpm to npm to match the
new project structure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): remove duplicate ARM64 build from Intel runner
The Intel runner was building both x64 and arm64 architectures,
while a separate ARM64 runner also builds arm64 natively. This
caused duplicate ARM64 builds, wasting CI resources.
Now each runner builds only its native architecture:
- Intel runner: x64 only
- ARM64 runner: arm64 only
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Alex Madera <e.a_madera@hotmail.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Feat: Ollama download progress tracking with new apps structure (#141)
* feat(ollama): add real-time download progress tracking for model downloads
Implement comprehensive download progress tracking with:
- NDJSON parsing for streaming progress data from Ollama API
- Real-time speed calculation (MB/s, KB/s, B/s) with useRef for delta tracking
- Time remaining estimation based on download speed
- Animated progress bars in OllamaModelSelector component
- IPC event streaming from main process to renderer
- Proper listener management with cleanup functions
Changes:
- memory-handlers.ts: Parse NDJSON from Ollama stderr, emit progress events
- OllamaModelSelector.tsx: Display progress bars with speed and time remaining
- project-api.ts: Implement onDownloadProgress listener with cleanup
- ipc.ts types: Define onDownloadProgress listener interface
- infrastructure-mock.ts: Add mock implementation for browser testing
This allows users to see real-time feedback when downloading Ollama models,
including percentage complete, current download speed, and estimated time remaining.
* test: add focused test coverage for Ollama download progress feature
Add unit tests for the critical paths of the real-time download progress tracking:
- Progress calculation tests (52 tests): Speed/time/percentage calculations with comprehensive edge case coverage (zero speeds, NaN, Infinity, large numbers)
- NDJSON parser tests (33 tests): Streaming JSON parsing from Ollama, buffer management for incomplete lines, error handling
All 562 unit tests passing with clean dependencies. Tests focus on critical mathematical logic and data processing - the most important paths that need verification.
Test coverage:
✅ Speed calculation and formatting (B/s, KB/s, MB/s)
✅ Time remaining calculations (seconds, minutes, hours)
✅ Percentage clamping (0-100%)
✅ NDJSON streaming with partial line buffering
✅ Invalid JSON handling
✅ Real Ollama API responses
✅ Multi-chunk streaming scenarios
* docs: add comprehensive JSDoc docstrings for Ollama download progress feature
- Enhanced OllamaModelSelector component with detailed JSDoc
* Documented component props, behavior, and usage examples
* Added docstrings to internal functions (checkInstalledModels, handleDownload, handleSelect)
* Explained progress tracking algorithm and useRef usage
- Improved memory-handlers.ts documentation
* Added docstring to main registerMemoryHandlers function
* Documented all Ollama-related IPC handlers (check-status, list-embedding-models, pull-model)
* Added JSDoc to executeOllamaDetector helper function
* Documented interface types (OllamaStatus, OllamaModel, OllamaEmbeddingModel, OllamaPullResult)
* Explained NDJSON parsing and progress event structure
- Enhanced test file documentation
* Added docstrings to NDJSON parser test utilities with algorithm explanation
* Documented all calculation functions (speed, time, percentage)
* Added detailed comments on formatting and bounds-checking logic
- Improved overall code maintainability
* Docstring coverage now meets 80%+ threshold for code review
* Clear explanation of progress tracking implementation details
* Better context for future maintainers working with download streaming
* feat: add batch task creation and management CLI commands
- Handle batch task creation from JSON files
- Show status of all specs in project
- Cleanup tool for completed specs
- Full integration with new apps/backend structure
- Compatible with implementation_plan.json workflow
* test: add batch task test file and testing checklist
- batch_test.json: Sample tasks for testing batch creation
- TESTING_CHECKLIST.md: Comprehensive testing guide for Ollama and batch tasks
- Includes UI testing steps, CLI testing steps, and edge cases
- Ready for manual and automated testing
* chore: update package-lock.json to match v2.7.2
* test: update checklist with verification results and architecture validation
* docs: add comprehensive implementation summary for Ollama + Batch features
* docs: add comprehensive Phase 2 testing guide with checklists and procedures
* docs: add NEXT_STEPS guide for Phase 2 testing
* fix: resolve merge conflict in project-api.ts from Ollama feature cherry-pick
* fix: remove duplicate Ollama check status handler registration
* test: update checklist with Phase 2 bug findings and fixes
---------
Co-authored-by: ray <ray@rays-MacBook-Pro.local>
* fix: resolve Python environment race condition (#142)
Implemented promise queue pattern in PythonEnvManager to handle
concurrent initialization requests. Previously, multiple simultaneous
requests (e.g., startup + merge) would fail with "Already
initializing" error.
Also fixed parsePythonCommand() to handle file paths with spaces by
checking file existence before splitting on whitespace.
Changes:
- Added initializationPromise field to queue concurrent requests
- Split initialize() into public and private _doInitialize()
- Enhanced parsePythonCommand() with existsSync() check
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* fix: remove legacy path from auto-claude source detection (#148)
Removes the legacy 'auto-claude' path from the possiblePaths array
in agent-process.ts. This path was from before the monorepo
restructure (v2.7.2) and is no longer needed.
The legacy path was causing spec_runner.py to be looked up at the
wrong location:
- OLD (wrong): /path/to/auto-claude/auto-claude/runners/spec_runner.py
- NEW (correct): /path/to/apps/backend/runners/spec_runner.py
This aligns with the new monorepo structure where all backend code
lives in apps/backend/.
Fixes #147
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* Fix/linear 400 error
* fix: Linear API authentication and GraphQL types
- Remove Bearer prefix from Authorization header (Linear API keys are sent directly)
- Change GraphQL variable types from String! to ID! for teamId and issue IDs
- Improve error handling to show detailed Linear API error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: Radix Select empty value error in Linear import modal
Use '__all__' sentinel value instead of empty string for "All projects"
option, as Radix Select does not allow empty string values.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add CodeRabbit configuration file
Introduce a new .coderabbit.yaml file to configure CodeRabbit settings, including review profiles, automatic review options, path filters, and specific instructions for different file types. This enhances the code review process by providing tailored guidelines for Python, TypeScript, and test files.
* fix: correct GraphQL types for Linear team queries
Linear API uses different types for different queries:
- team(id:) expects String!
- issues(filter: { team: { id: { eq: } } }) expects ID!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: refresh task list after Linear import
Call loadTasks() after successful Linear import to update the kanban
board without requiring a page reload.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* cleanup
* cleanup
* fix: address CodeRabbit review comments for Linear integration
- Fix unsafe JSON parsing: check response.ok before parsing JSON to handle
non-JSON error responses (e.g., 503 from proxy) gracefully
- Use ID! type instead of String! for teamId in LINEAR_GET_PROJECTS query
for GraphQL type consistency
- Remove debug console.log (ESLint config only allows warn/error)
- Refresh task list on partial import success (imported > 0) instead of
requiring full success
- Fix pre-existing TypeScript and lint issues blocking commit
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* version sync logic
* lints for develop branch
* chore: update CI workflow to include develop branch
- Modified the CI configuration to trigger on pushes and pull requests to both main and develop branches, enhancing the workflow for development and integration processes.
* fix: update project directory auto-detection for apps/backend structure
The project directory auto-detection was checking for the old `auto-claude/`
directory name but needed to check for `apps/backend/`. When running from
`apps/backend/`, the directory name is `backend` not `auto-claude`, so the
check would fail and `project_dir` would incorrectly remain as `apps/backend/`
instead of resolving to the project root (2 levels up).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use GraphQL variables instead of string interpolation in LINEAR_GET_ISSUES
Replace direct string interpolation of teamId and linearProjectId with
proper GraphQL variables. This prevents potential query syntax errors if
IDs contain special characters like double quotes, and aligns with the
variable-based approach used elsewhere in the file.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ui): correct logging level and await loadTasks on import complete
- Change console.warn to console.log for import success messages
(warn is incorrect severity for normal completion)
- Make onImportComplete callback async and await loadTasks()
to prevent potential unhandled promise rejections
Applies CodeRabbit review feedback across 3 LinearTaskImportModal usages.
* fix(hooks): use POSIX-compliant find instead of bash glob
The pre-commit hook uses #!/bin/sh but had bash-specific ** glob
pattern for staging ruff-formatted files. The ** pattern only works
in bash with globstar enabled - in POSIX sh it expands literally
and won't match subdirectories, causing formatted files in nested
directories to not be staged.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(task): stop running process when task status changes away from in_progress
When a user drags a running task back to Planning (or any other column),
the process was not being stopped, leaving a "ghost" process that
prevented deletion with "Cannot delete a running task" error.
Now the task process is automatically killed when status changes away
from in_progress, ensuring the process state stays in sync with the UI.
* feat: Add UI scale feature with 75-200% range (#125)
* feat: add UI scale feature
* refactor: extract UI scale bounds to shared constants
* fix: duplicated import
* fix: hide status badge when execution phase badge is showing (#154)
* fix: analyzer Python compatibility and settings integration
Fixes project index analyzer failing with TypeError on Python type hints.
Changes:
- Added 'from __future__ import annotations' to all analysis modules
- Fixed project discovery to support new analyzer JSON format
- Read Python path directly from settings.json instead of pythonEnvManager
- Added stderr/stdout logging for analyzer debugging
Resolves 'Discovered 0 files' and 'TypeError: unsupported operand type' issues.
* auto-claude: subtask-1-1 - Hide status badge when execution phase badge is showing
When a task has an active execution (planning, coding, etc.), the
execution phase badge already displays the correct state with a spinner.
The status badge was also rendering, causing duplicate/confusing badges
(e.g., both "Planning" and "Pending" showing at the same time).
This fix wraps the status badge in a conditional that only renders when
there's no active execution, eliminating the redundant badge display.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ipc): remove unused pythonEnvManager parameter and fix ES6 import
Address CodeRabbit review feedback:
- Remove unused pythonEnvManager parameter from registerProjectContextHandlers
and registerContextHandlers (the code reads Python path directly from
settings.json instead)
- Replace require('electron').app with proper ES6 import for consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(lint): fix import sorting in analysis module
Run ruff --fix to resolve I001 lint errors after merging develop.
All 23 files in apps/backend/analysis/ now have properly sorted imports.
---------
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix/PRs from old main setup to apps structure (#185)
* fix(core): add task persistence, terminal handling, and HTTP 300 fixes
Consolidated bug fixes from PRs #168, #170, #171:
- Task persistence (#168): Scan worktrees for tasks on app restart
to prevent loss of in-progress work and wasted API credits. Tasks
in .worktrees/*/specs are now loaded and deduplicated with main.
- Terminal buttons (#170): Fix "Open Terminal" buttons silently
failing on macOS by properly awaiting createTerminal() Promise.
Added useTerminalHandler hook with loading states and error display.
- HTTP 300 errors (#171): Handle branch/tag name collisions that
cause update failures. Added validation script to prevent conflicts
before releases and user-friendly error messages with manual
download links.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(platform): add path resolution, spaces handling, and XDG support
This commit consolidates multiple bug fixes from community PRs:
- PR #187: Path resolution fix - Update path detection to find apps/backend
instead of legacy auto-claude directory after v2.7.2 restructure
- PR #182/#155: Python path spaces fix - Improve parsePythonCommand() to
handle quoted paths and paths containing spaces without splitting
- PR #161: Ollama detection fix - Add new apps structure paths for
ollama_model_detector.py script discovery
- PR #160: AppImage support - Add XDG Base Directory compliant paths for
Linux sandboxed environments (AppImage, Flatpak, Snap). New files:
- config-paths.ts: XDG path utilities
- fs-utils.ts: Filesystem utilities with fallback support
- PR #159: gh CLI PATH fix - Add getAugmentedEnv() utility to include
common binary locations (Homebrew, snap, local) in PATH for child
processes. Fixes gh CLI not found when app launched from Finder/Dock.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit/Cursor review comments on PR #185
Fixes from code review:
- http-client.ts: Use GITHUB_CONFIG instead of hardcoded owner in HTTP 300 error message
- validate-release.js: Fix substring matching bug in branch detection that could cause false positives (e.g., v2.7 matching v2.7.2)
- bump-version.js: Remove unnecessary try-catch wrapper (exec() already exits on failure)
- execution-handlers.ts: Capture original subtask status before mutation for accurate logging
- fs-utils.ts: Add error handling to safeWriteFile with proper logging
Dismissed as trivial/not applicable:
- config-paths.ts: Exhaustive switch check (over-engineering)
- env-utils.ts: PATH priority documentation (existing comments sufficient)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address additional CodeRabbit review comments (round 2)
Fixes from second round of code review:
- fs-utils.ts: Wrap test file cleanup in try-catch for Windows file locking
- fs-utils.ts: Add error handling to safeReadFile for consistency with safeWriteFile
- http-client.ts: Use GITHUB_CONFIG in fetchJson (missed in first round)
- validate-release.js: Exclude symbolic refs (origin/HEAD -> origin/main) from branch check
- python-detector.ts: Return cleanPath instead of pythonPath for empty input edge case
Dismissed as trivial/not applicable:
- execution-handlers.ts: Redundant checkSubtasksCompletion call (micro-optimization)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat/beta-release (#190)
* chore: update README version to 2.7.1
Updated the version badge and download links in the README to reflect the new release version 2.7.1, ensuring users have the correct information for downloading the latest builds.
* feat(releases): add beta release system with user opt-in
Implements a complete beta release workflow that allows users to opt-in
to receiving pre-release versions. This enables testing new features
before they're included in stable releases.
Changes:
- Add beta-release.yml workflow for creating beta releases from develop
- Add betaUpdates setting with UI toggle in Settings > Updates
- Add update channel support to electron-updater (beta vs latest)
- Extract shared settings-utils.ts to reduce code duplication
- Add prepare-release.yml workflow for automated release preparation
- Document beta release process in CONTRIBUTING.md and RELEASE.md
Users can enable beta updates in Settings > Updates, and maintainers
can trigger beta releases via the GitHub Actions workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* workflow update
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Feat/beta release (#193)
* chore: update README version to 2.7.1
Updated the version badge and download links in the README to reflect the new release version 2.7.1, ensuring users have the correct information for downloading the latest builds.
* feat(releases): add beta release system with user opt-in
Implements a complete beta release workflow that allows users to opt-in
to receiving pre-release versions. This enables testing new features
before they're included in stable releases.
Changes:
- Add beta-release.yml workflow for creating beta releases from develop
- Add betaUpdates setting with UI toggle in Settings > Updates
- Add update channel support to electron-updater (beta vs latest)
- Extract shared settings-utils.ts to reduce code duplication
- Add prepare-release.yml workflow for automated release preparation
- Document beta release process in CONTRIBUTING.md and RELEASE.md
Users can enable beta updates in Settings > Updates, and maintainers
can trigger beta releases via the GitHub Actions workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* workflow update
* ci(github): update Discord link and redirect feature requests to discussions
Update Discord invite link to correct URL (QhRnz9m5HE) across all GitHub
templates and workflows. Redirect feature requests from issue template
to GitHub Discussions for better community engagement.
Changes:
- config.yml: Add feature request link to Discussions, fix Discord URL
- question.yml: Update Discord link in pre-question guidance
- welcome.yml: Update Discord link in first-time contributor message
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): correct welcome workflow PR message (#206)
- Change branch reference from main to develop
- Fix contribution guide link to use full URL
- Remove hyphen from "Auto Claude" in welcome message
* fix: Add Python 3.10+ version validation and GitHub Actions Python setup (#180 #167) (#208)
This fixes critical bug where macOS users with default Python 3.9.6 couldn't use Auto-Claude because claude-agent-sdk requires Python 3.10+.
Root Cause:
- Auto-Claude doesn't bundle Python, relies on system Python
- python-detector.ts accepted any Python 3.x without checking minimum version
- macOS ships with Python 3.9.6 by default (incompatible)
- GitHub Actions runners didn't explicitly set Python version
Changes:
1. python-detector.ts:
- Added getPythonVersion() to extract version from command
- Added validatePythonVersion() to check if >= 3.10.0
- Updated findPythonCommand() to skip Python < 3.10 with clear error messages
2. python-env-manager.ts:
- Import and use findPythonCommand() (already has version validation)
- Simplified findSystemPython() to use shared validation logic
- Updated error message from "Python 3.9+" to "Python 3.10+" with download link
3. .github/workflows/release.yml:
- Added Python 3.11 setup to all 4 build jobs (macOS Intel, macOS ARM64, Windows, Linux)
- Ensures consistent Python version across all platforms during build
Impact:
- macOS users with Python 3.9 now see clear error with download link
- macOS users with Python 3.10+ work normally
- CI/CD builds use consistent Python 3.11
- Prevents "ModuleNotFoundError: dotenv" and dependency install failures
Fixes #180, #167
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* feat: Add OpenRouter as LLM/embedding provider (#162)
* feat: Add OpenRouter as LLM/embedding provider
Add OpenRouter provider support for Graphiti memory integration,
enabling access to multiple LLM providers through a single API.
Changes:
Backend:
- Created openrouter_llm.py: OpenRouter LLM provider using OpenAI-compatible API
- Created openrouter_embedder.py: OpenRouter embedder provider
- Updated config.py: Added OpenRouter to provider enums and configuration
- New fields: openrouter_api_key, openrouter_base_url, openrouter_llm_model, openrouter_embedding_model
- Validation methods updated for OpenRouter
- Updated factory.py: Added OpenRouter to LLM and embedder factories
- Updated provider __init__.py files: Exported new OpenRouter functions
Frontend:
- Updated project.ts types: Added 'openrouter' to provider type unions
- GraphitiProviderConfig extended with OpenRouter fields
- Updated GraphitiStep.tsx: Added OpenRouter to provider arrays
- LLM_PROVIDERS: 'Multi-provider aggregator'
- EMBEDDING_PROVIDERS: 'OpenAI-compatible embeddings'
- Added OpenRouter API key input field with show/hide toggle
- Link to https://openrouter.ai/keys
- Updated env-handlers.ts: OpenRouter .env generation and parsing
- Template generation for OPENROUTER_* variables
- Parsing from .env files with proper type casting
Documentation:
- Updated .env.example with OpenRouter section
- Configuration examples
- Popular model recommendations
- Example configuration (#6)
Fixes #92
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* refactor: address CodeRabbit review comments for OpenRouter
- Add globalOpenRouterApiKey to settings types and store updates
- Initialize openrouterApiKey from global settings
- Update documentation to include OpenRouter in provider lists
- Add OpenRouter handling to get_embedding_dimension() method
- Add openrouter to provider cleanup list
- Add OpenRouter to get_available_providers() function
- Clarify Legacy comment for openrouterLlmModel
These changes complete the OpenRouter integration by ensuring proper
settings persistence and provider detection across the application.
* fix: apply ruff formatting to OpenRouter code
- Break long error message across multiple lines
- Format provider list with one item per line
- Fixes lint CI failure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix(core): add global spec numbering lock to prevent collisions (#209)
Implements distributed file-based locking for spec number coordination
across main project and all worktrees. Previously, parallel spec creation
could assign the same number to different specs (e.g., 042-bmad-task and
042-gitlab-integration both using number 042).
The fix adds SpecNumberLock class that:
- Acquires exclusive lock before calculating spec numbers
- Scans ALL locations (main project + worktrees) for global maximum
- Creates spec directories atomically within the lock
- Handles stale locks via PID-based detection with 30s timeout
Applied to both Python backend (spec_runner.py flow) and TypeScript
frontend (ideation conversion, GitHub/GitLab issue import).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Fix/ideation status sync (#212)
* fix(ideation): add missing event forwarders for status sync
- Add event forwarders in ideation-handlers.ts for progress, log,
type-complete, type-failed, complete, error, and stopped events
- Fix ideation-type-complete to load actual ideas array from JSON files
instead of emitting only the count
Resolves UI getting stuck at 0/3 complete during ideation generation.
* fix(ideation): fix UI not updating after actions
- Fix getIdeationSummary to count only active ideas (exclude dismissed/archived)
This ensures header stats match the visible ideas count
- Add transformSessionFromSnakeCase to properly transform session data
from backend snake_case to frontend camelCase on ideation-complete event
- Transform raw session before emitting ideation-complete event
Resolves header showing stale counts after dismissing/deleting ideas.
* fix(ideation): improve type safety and async handling in ideation type completion
- Replace synchronous readFileSync with async fsPromises.readFile in ideation-type-complete handler
- Wrap async file read in IIFE with proper error handling to prevent unhandled promise rejections
- Add type validation for IdeationType with VALID_IDEATION_TYPES set and isValidIdeationType guard
- Add validateEnabledTypes function to filter out invalid type values and log dropped entries
- Handle ENOENT separately
* fix(ideation): improve generation state management and error handling
- Add explicit isGenerating flag to prevent race conditions during async operations
- Implement 5-minute timeout for generation with automatic cleanup and error state
- Add ideation-stopped event emission when process is intentionally killed
- Replace console.warn/error with proper ideation-error events in agent-queue
- Add resetGeneratingTypes helper to transition all generating types to a target state
- Filter out dismissed/
* refactor(ideation): improve event listener cleanup and timeout management
- Extract event handler functions in ideation-handlers.ts to enable proper cleanup
- Return cleanup function from registerIdeationHandlers to remove all listeners
- Replace single generationTimeoutId with Map to support multiple concurrent projects
- Add clearGenerationTimeout helper to centralize timeout cleanup logic
- Extract loadIdeationType IIFE to named function for better error context
- Enhance error logging with projectId,
* refactor: use async file read for ideation and roadmap session loading
- Replace synchronous readFileSync with async fsPromises.readFile
- Prevents blocking the event loop during file operations
- Consistent with async pattern used elsewhere in the codebase
- Improved error handling with proper event emission
* fix(agent-queue): improve roadmap completion handling and error reporting
- Add transformRoadmapFromSnakeCase to convert backend snake_case to frontend camelCase
- Transform raw roadmap data before emitting roadmap-complete event
- Add roadmap-error emission for unexpected errors during completion
- Add roadmap-error emission when project path is unavailable
- Remove duplicate ideation-type-complete emission from error handler (event already emitted in loadIdeationType)
- Update error log message
* fix: add future annotations import to discovery.py (#229)
Adds 'from __future__ import annotations' to spec/discovery.py for
Python 3.9+ compatibility with type hints.
This completes the Python compatibility fixes that were partially
applied in previous commits. All 26 analysis and spec Python files
now have the future annotations import.
Related: #128
Co-authored-by: Joris Slagter <mail@jorisslagter.nl>
* fix: resolve Python detection and backend packaging issues (#241)
* fix: resolve Python detection and backend packaging issues
- Fix backend packaging path (auto-claude -> backend) to match path-resolver.ts expectations
- Add future annotations import to config_parser.py for Python 3.9+ compatibility
- Use findPythonCommand() in project-context-handlers to prioritize Homebrew Python
- Improve Python detection to prefer Homebrew paths over system Python on macOS
This resolves the following issues:
- 'analyzer.py not found' error due to incorrect packaging destination
- TypeError with 'dict | None' syntax on Python < 3.10
- Wrong Python interpreter being used (system Python instead of Homebrew Python 3.10+)
Tested on macOS with packaged app - project index now loads successfully.
* refactor: address PR review feedback
- Extract findHomebrewPython() helper to eliminate code duplication between
findPythonCommand() and getDefaultPythonCommand()
- Remove hardcoded version-specific paths (python3.12) and rely only on
generic Homebrew symlinks for better maintainability
- Remove unnecessary 'from __future__ import annotations' from config_parser.py
since backend requires Python 3.12+ where union types are native
These changes make the code more maintainable, less fragile to Python version
changes, and properly reflect the project's Python 3.12+ requirement.
* Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Revert "Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)" (#251)
This reverts commit 348de6dfe793ab111043677c61b8452bc5ecb2cc.
* feat: add i18n internationalization system (#248)
* Add multilingual support and i18n integration
- Implemented i18n framework using `react-i18next` for translation management.
- Added support for English and French languages with translation files.
- Integrated language selector into settings.
- Updated all text strings in UI components to use translation keys.
- Ensured smooth language switching with live updates.
* Migrate remaining hard-coded strings to i18n system
- TaskCard: status labels, review reasons, badges, action buttons
- PhaseProgressIndicator: execution phases, progress labels
- KanbanBoard: drop zone, show archived, tooltips
- CustomModelModal: dialog title, description, labels
- ProactiveSwapListener: account switch notifications
- AgentProfileSelector: phase labels, custom configuration
- GeneralSettings: agent framework option
Added translation keys for en/fr locales in tasks.json, common.json,
and settings.json for complete i18n coverage.
* Add i18n support to dialogs and settings components
- AddFeatureDialog: form labels, validation messages, buttons
- AddProjectModal: dialog steps, form fields, actions
- RateLimitIndicator: rate limit notifications
- RateLimitModal: account switching, upgrade prompts
- AdvancedSettings: updates and notifications sections
- ThemeSettings: theme selection labels
- Updated dialogs.json locales (en/fr)
* Fix truncated 'ready' message in dialogs locales
* Fix backlog terminology in i18n locales
Change "Planning"/"Planification" to standard PM term "Backlog"
* Migrate settings navigation and integration labels to i18n
- AppSettings: nav items, section titles, buttons
- IntegrationSettings: Claude accounts, auto-switch, API keys labels
- Added settings nav/projectSections/integrations translation keys
- Added buttons.saving to common translations
* Migrate AgentProfileSettings and Sidebar init dialog to i18n
- AgentProfileSettings: migrate phase config labels, section title,
description, and all hardcoded strings to settings namespace
- Sidebar: migrate init dialog strings to dialogs namespace with
common buttons from common namespace
- Add new translation keys for agent profile settings and update dialog
* Migrate AppSettings navigation labels to i18n
- Add useTranslation hook to AppSettings.tsx
- Replace hardcoded section labels with dynamic translations
- Add projectSections translations for project settings nav
- Add rerunWizardDescription translation key
* Add explicit typing to notificationItems array
Import NotificationSettings type and use keyof to properly type
the notification item keys, removing manual type assertion.
* fix: update path resolution for ollama_model_detector.py in memory handlers (#263)
* ci: implement enterprise-grade PR quality gates and security scanning (#266)
* ci: implement enterprise-grade PR quality gates and security scanning
* ci: implement enterprise-grade PR quality gates and security scanning
* fix:pr comments and improve code
* fix: improve commit linting and code quality
* Removed the dependency-review job (i added it)
* fix: address CodeRabbit review comments
- Expand scope pattern to allow uppercase, underscores, slashes, dots
- Add concurrency control to cancel duplicate security scan runs
- Add explanatory comment for Bandit CLI flags
- Remove dependency-review job (requires repo settings)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: update commit lint examples with expanded scope patterns
Show slashes and dots in scope examples to demonstrate
the newly allowed characters (api/users, package.json)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove feature request issue template
Feature requests are directed to GitHub Discussions
via the issue template config.yml
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address security vulnerabilities in service orchestrator
- Fix port parsing crash on malformed docker-compose entries
- Fix shell injection risk by using shlex.split() with shell=False
Prevents crashes when docker-compose.yml contains environment
variables in port mappings (e.g., '${PORT}:8080') and eliminates
shell injection vulnerabilities in subprocess execution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat(github): add automated PR review with follow-up support (#252)
* feat(github): add GitHub automation system for issues and PRs
Implements comprehensive GitHub automation with three major components:
1. Issue Auto-Fix: Automatically creates specs from labeled issues
- AutoFixButton component with progress tracking
- useAutoFix hook for config and queue management
- Backend handlers for spec creation from issues
2. GitHub PRs Tool: AI-powered PR review sidebar
- New sidebar tab (Cmd+Shift+P) alongside GitHub Issues
- PRList/PRDetail components for viewing PRs
- Review system with findings by severity
- Post review comments to GitHub
3. Issue Triage: Duplicate/spam/feature-creep detection
- Triage handlers with label application
- Configurable detection thresholds
Also adds:
- Debug logging (DEBUG=true) for all GitHub handlers
- Backend runners/github module with orchestrator
- AI prompts for PR review, triage, duplicate/spam detection
- dev:debug npm script for development with logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-runner): resolve import errors for direct script execution
Changes runner.py and orchestrator.py to handle both:
- Package import: `from runners.github import ...`
- Direct script: `python runners/github/runner.py`
Uses try/except pattern for relative vs direct imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): correct argparse argument order for runner.py
Move --project global argument before subcommand so argparse can
correctly parse it. Fixes "unrecognized arguments: --project" error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* logs when debug mode is on
* refactor(github): extract service layer and fix linting errors
Major refactoring to improve maintainability and code quality:
Backend (Python):
- Extracted orchestrator.py (2,600 → 835 lines, 68% reduction) into 7 service modules:
- prompt_manager.py: Prompt template management
- response_parsers.py: AI response parsing
- pr_review_engine.py: PR review orchestration
- triage_engine.py: Issue triage logic
- autofix_processor.py: Auto-fix workflow
- batch_processor.py: Batch issue handling
- Fixed 18 ruff linting errors (F401, C405, C414, E741):
- Removed unused imports (BatchValidationResult, AuditAction, locked_json_write)
- Optimized collection literals (set([n]) → {n})
- Removed unnecessary list() calls
- Renamed ambiguous variable 'l' to 'label' throughout
Frontend (TypeScript):
- Refactored IPC handlers (19% overall reduction) with shared utilities:
- autofix-handlers.ts: 1,042 → 818 lines
- pr-handlers.ts: 648 → 543 lines
- triage-handlers.ts: 437 lines (no duplication)
- Created utils layer: logger, ipc-communicator, project-middleware, subprocess-runner
- Split github-store.ts into focused stores: issues, pr-review, investigation, sync-status
- Split ReviewFindings.tsx into focused components
All imports verified, type checks passing, linting clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fixes during testing of PR
* feat(github): implement PR merge, assign, and comment features
- Add auto-assignment when clicking "Run AI Review"
- Implement PR merge functionality with squash method
- Add ability to post comments on PRs
- Display assignees in PR UI
- Add Approve and Merge buttons when review passes
- Update backend gh_client with pr_merge, pr_comment, pr_assign methods
- Create IPC handlers for new PR operations
- Update TypeScript interfaces and browser mocks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Improve PR review AI
* fix(github): use temp files for PR review posting to avoid shell escaping issues
When posting PR reviews with findings containing special characters (backticks,
parentheses, quotes), the shell command was interpreting them as commands instead
of literal text, causing syntax errors.
Changed both postPRReview and postPRComment handlers to write the body content
to temporary files and use gh CLI's --body-file flag instead of --body with
inline content. This safely handles ALL special characters without escaping issues.
Fixes shell errors when posting reviews with suggested fixes containing code snippets.
* fix(i18n): add missing GitHub PRs translation and document i18n requirements
Fixed missing translation key for GitHub PRs feature that was causing
"items.githubPRs" to display instead of the proper translated text.
Added comprehensive i18n guidelines to CLAUDE.md to ensure all future
frontend development follows the translation key pattern instead of
using hardcoded strings.
Also fixed missing deletePRReview mock function in browser-mock.ts
to resolve TypeScript compilation errors.
Changes:
- Added githubPRs translation to en/navigation.json
- Added githubPRs translation to fr/navigation.json
- Added Development Guidelines section to CLAUDE.md with i18n requirements
- Documented translation file locations and namespace usage patterns
- Added deletePRReview mock function to browser-mock.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix ui loading
* Github PR fixes
* improve claude.md
* lints/tests
* fix(github): handle PRs exceeding GitHub's 20K line diff limit
- Add PRTooLargeError exception for large PR detection
- Update pr_diff() to catch and raise PRTooLargeError for HTTP 406 errors
- Gracefully handle large PRs by skipping full diff and using individual file patches
- Add diff_truncated flag to PRContext to track when diff was skipped
- Large PRs will now review successfully using per-file diffs instead of failing
Fixes issue with PR #252 which has 100+ files exceeding the 20,000 line limit.
* fix: implement individual file patch fetching for large PRs
The PR review was getting stuck for large PRs (>20K lines) because when we
skipped the full diff due to GitHub API limits, we had no code to analyze.
The individual file patches were also empty, leaving the AI with just
file names and metadata.
Changes:
- Implemented _get_file_patch() to fetch individual patches via git diff
- Updated PR review engine to build composite diff from file patches when
diff_truncated is True
- Added missing 'state' field to PRContext dataclass
- Limits composite diff to first 50 files for very large PRs
- Shows appropriate warnings when using reconstructed diffs
This allows AI review to proceed with actual code analysis even when the
full PR diff exceeds GitHub's limits.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* 1min reduction
* docs: add GitHub Sponsors funding configuration
Enable the Sponsor button on the repository by adding FUNDING.yml
with the AndyMik90 GitHub Sponsors profile.
* feat(github-pr): add orchestrating agent for thorough PR reviews
Implement a new Opus 4.5 orchestrating agent that performs comprehensive
PR reviews regardless of size. Key changes:
- Add orchestrator_reviewer.py with strategic review workflow
- Add review_tools.py with subagent spawning capabilities
- Add pr_orchestrator.md prompt emphasizing thorough analysis
- Add pr_security_agent.md and pr_quality_agent.md subagent prompts
- Integrate orchestrator into pr_review_engine.py with config flag
- Fix critical bug where findings were extracted but not processed
(indentation issue in _parse_orchestrator_output)
The orchestrator now correctly identifies issues in PRs that were
previously approved as "trivial". Testing showed 7 findings detected
vs 0 before the fix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* i18n
* fix(github-pr): restrict pr_reviewer to read-only permissions
The PR review agent was using qa_reviewer agent type which has Bash
access, allowing it to checkout branches and make changes during
review. Created new pr_reviewer agent type with BASE_READ_TOOLS only
(no Bash, no writes, no auto-claude tools).
This prevents the PR review from accidentally modifying code or
switching branches during analysis.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github-pr): robust category mapping and JSON parsing for PR review
The orchestrator PR review was failing to extract findings because:
1. AI generates category names like 'correctness', 'consistency', 'testing'
that aren't in our ReviewCategory enum - added flexible mapping
2. JSON sometimes embedded in markdown code blocks (```json) which broke
parsing - added code block extraction as first parsing attempt
Changes:
- Add _CATEGORY_MAPPING dict to map AI categories to valid enum values
- Add _map_category() helper function with fallback to QUALITY
- Add severity parsing with fallback to MEDIUM
- Add markdown code block detection (```json) before raw JSON parsing
- Add _extract_findings_from_data() helper to reduce code duplication
- Apply same fixes to review_tools.py for subagent parsing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(pr-review): improve post findings UX with batch support and feedback
- Fix post findings failing on own PRs by falling back from REQUEST_CHANGES
to COMMENT when GitHub returns 422 error
- Change status badge to show "Reviewed" instead of "Commented" until
findings are actually posted to GitHub
- Add success notification when findings are posted (auto-dismisses after 3s)
- Add batch posting support: track posted findings, show "Posted" badge,
allow posting remaining findings in additional batches
- Show loading state on button while posting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(github): resolve stale timestamp and null author bugs
- Fix stale timestamp in batch_issues.py: Move updated_at assignment
BEFORE to_dict() serialization so the saved JSON contains the correct
timestamp instead of the old value
- Fix AttributeError in context_gatherer.py: Handle null author/user
fields when GitHub API returns null for deleted/suspended users
instead of an empty object
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high and medium severity PR review findings
HIGH severity fixes:
- Command Injection in autofix-handlers.ts: Use execFileSync with args array
- Command Injection in pr-handlers.ts (3 locations): Use execFileSync + validation
- Command Injection in triage-handlers.ts: Use execFileSync + label validation
- Token Exposure in bot_detection.py: Pass token via GH_TOKEN env var
MEDIUM severity fixes:
- Environment variable leakage in subprocess-runner.ts: Filter to safe vars only
- Debug logging in subprocess-runner.ts: Only log in development mode
- Delimiter escape bypass in sanitize.py: Use regex pattern for variations
- Insecure file permissions in trust.py: Use os.open with 0o600 mode
- No file locking in learning.py: Use FileLock + atomic_write utilities
- Bare except in confidence.py: Log error with specific exception info
- Fragile module import in pr_review_engine.py: Import at module level
- State transition validation in models.py: Enforce can_transition_to()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR followup
* fix(security): add usedforsecurity=False to MD5 hash calls
MD5 is used for generating unique IDs/cache keys, not for security purposes.
Adding usedforsecurity=False resolves Bandit B324 warnings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): address all high-priority PR review findings
Fixes 5 high-priority issues from Auto Claude PR Review:
1. orchestrator_reviewer.py: Token budget tracking now increments
total_tokens from API response usage data
2. pr_review_engine.py: Async exceptions now re-raise RuntimeError
instead of silently returning empty results
3. batch_issues.py: IssueBatch.save() now uses locked_json_write
for atomic file operations with file locking
4. project-middleware.ts: Added validateProjectPath() to prevent
path traversal attacks (checks absolute, no .., exists, is dir)
5. orchestrator.py: Exception handling now logs full traceback and
preserves exception type/context in error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(ui): add PR status labels to list view
Add secondary status badges to the PR list showing review state at a glance:
- "Changes Requested" (warning) - PRs with blocking issues (critical/high)
- "Ready to Merge" (green) - PRs with only non-blocking suggestions
- "Ready for Follow-up" (blue) - PRs with new commits since last review
The "Ready for Follow-up" badge uses a cached new commits check from the
store, only shown after the detail view confirms new commits via SHA
comparison. This prevents false positives from PR updatedAt timestamp
changes (which can happen from comments, labels, etc).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* PR labels
* auto-claude: Initialize subtask-based implementation plan
- Workflow type: feature
- Phases: 3
- Subtasks: 6
- Ready for autonomous implementation
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* chore(deps): bump vitest from 4.0.15 to 4.0.16 in /apps/frontend (#272)
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.0.15 to 4.0.16.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/vitest)
---
updated-dependencies:
- dependency-name: vitest
dependency-version: 4.0.16
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(deps): bump @electron/rebuild in /apps/frontend (#271)
Bumps [@electron/rebuild](https://github.com/electron/rebuild) from 3.7.2 to 4.0.2.
- [Release notes](https://github.com/electron/rebuild/releases)
- [Commits](https://github.com/electron/rebuild/compare/v3.7.2...v4.0.2)
---
updated-dependencies:
- dependency-name: "@electron/rebuild"
dependency-version: 4.0.2
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(paths): normalize relative paths to posix (#239)
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix: accept bug_fix workflow_type alias during planning (#240)
* fix(planning): accept bug_fix workflow_type alias
* style(planning): ruff format
* fix: refatored common logic
* fix: remove ruff errors
* fix: remove duplicate _normalize_workflow_type method
Remove the incorrectly placed duplicate method inside ContextLoader class.
The module-level function is the correct implementation being used.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): use develop branch for dry-run builds in beta-release workflow (#276)
When dry_run=true, the workflow skipped creating the version tag but
build jobs still tried to checkout that non-existent tag, causing all
4 platform builds to fail with "git failed with exit code 1".
Now build jobs checkout develop branch for dry runs while still using
the version tag for real releases.
Closes: GitHub Actions run #20464082726
* chore(deps): bump typescript-eslint in /apps/frontend (#269)
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.49.0 to 8.50.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.50.1/packages/typescript-eslint)
---
updated-dependencies:
- dependency-name: typescript-eslint
dependency-version: 8.50.1
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* chore(deps): bump jsdom from 26.1.0 to 27.3.0 in /apps/frontend (#268)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 26.1.0 to 27.3.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/26.1.0...27.3.0)
---
updated-dependencies:
- dependency-name: jsdom
dependency-version: 27.3.0
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
* fix(ci): use correct electron-builder arch flags (#278)
The project switched from pnpm to npm, which handles script argument
passing differently. pnpm adds a -- separator that caused electron-builder
to ignore the --arch argument, but npm passes it directly.
Since --arch is a deprecated electron-builder argument, use the
recommended flags instead:
- --arch=x64 → --x64
- --arch=arm64 → --arm64
This fixes Mac Intel and ARM64 builds failing with "Unknown argument: arch"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(security): resolve CodeQL file system race conditions and unused variables (#277)
* fix(security): resolve CodeQL file system race conditions and unused variables
Fix high severity CodeQL alerts:
- Remove TOCTOU (time-of-check-time-of-use) race conditions by eliminating
existsSync checks followed by file operations. Use try-catch instead.
- Files affected: pr-handlers.ts, spec-utils.ts
Fix unused variable warnings:
- Remove unused imports (FeatureModelCon…
Base Branch
developbranch (required for all feature/fix PRs)main(hotfix only - maintainers)Description
Adds the functionality for maintainers and users of Auto Claude to handle Github issues in full auto and also do extensive PR reviews much faster.
Related Issue
Closes #
Type of Change
Area
Commit Message Format
Follow conventional commits:
<type>: <subject>Types: feat, fix, docs, style, refactor, test, chore
Example:
feat: add user authentication systemChecklist
developbranchCI/Testing Requirements
Screenshots
Feature Toggle
use_feature_nameBreaking Changes
Breaking: Yes / No
Details:
Summary by CodeRabbit
Release Notes
Chores
New Features
✏️ Tip: You can customize this high-level summary in your review settings.