Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ venv/
ENV/
env/
.conda/
.envs/

# Testing
.pytest_cache/
Expand Down Expand Up @@ -168,4 +169,5 @@ OPUS_ANALYSIS_AND_IDEAS.md

# Auto Claude generated files
.security-key
/shared_docs
/shared_docs
tmpclaude*
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ if git diff --cached --name-only | grep -q "^apps/backend/.*\.py$"; then
echo "$STAGED_PY_FILES" | xargs git add
fi
else
echo "Warning: ruff not found, skipping Python linting. Install with: uv pip install ruff"
echo "⚠️ Warning: ruff not found, skipping Python linting. Install with: uv pip install ruff"
fi

# Run pytest (skip slow/integration tests and Windows-incompatible tests for pre-commit speed)
Expand Down
68 changes: 65 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ Auto Claude is a multi-agent autonomous coding framework that builds software th
autonomous-coding/
├── apps/
│ ├── backend/ # Python backend/CLI - ALL agent logic lives here
│ │ ├── core/ # Client, auth, security
│ │ ├── core/ # Client, auth, security, git provider detection
│ │ ├── agents/ # Agent implementations
│ │ ├── spec_agents/ # Spec creation agents
│ │ ├── integrations/ # Graphiti, Linear, GitHub
│ │ ├── runners/ # GitHub & GitLab automation
│ │ ├── integrations/ # Graphiti, Linear
│ │ └── prompts/ # Agent system prompts
│ └── frontend/ # Electron desktop UI
├── guides/ # Documentation
Expand Down Expand Up @@ -195,6 +196,8 @@ See [RELEASE.md](RELEASE.md) for detailed release process documentation.
**Integrations:**
- **linear_updater.py** - Optional Linear integration for progress tracking
- **runners/github/** - GitHub Issues & PRs automation
- **runners/gitlab/** - GitLab Issues & MRs automation
- **core/git_provider.py** - Multi-provider support (GitHub, GitLab) with auto-detection
- **Electron MCP** - E2E testing integration for QA agents (Chrome DevTools Protocol)
- Enabled with `ELECTRON_MCP_ENABLED=true` in `.env`
- Allows QA agents to interact with running Electron app
Expand Down Expand Up @@ -237,7 +240,7 @@ main (user's branch)
**Key principles:**
- ONE branch per spec (`auto-claude/{spec-name}`)
- Parallel work uses subagents (agent decides when to spawn)
- NO automatic pushes to GitHub - user controls when to push
- NO automatic pushes to remote (GitHub/GitLab) - user controls when to push
- User reviews in spec worktree (`.worktrees/{spec-name}/`)
- Final merge: spec branch → main (after user approval)

Expand All @@ -248,6 +251,65 @@ main (user's branch)
4. User runs `--merge` to add to their project
5. User pushes to remote when ready

### Git Provider Support

Auto Claude supports both **GitHub** and **GitLab** for pull request / merge request creation:

**Configuration:**
- **Per-project setting** in project settings UI or `.env` file
- **Options**: Auto-detect (default), GitHub, GitLab
- **Auto-detection**: Parses git remote URL to determine provider
- `github.com` → Uses GitHub (`gh pr create`)
- `gitlab.com` → Uses GitLab (`glab mr create`)
- Self-hosted GitLab instances also supported (e.g., `gitlab.mycompany.com`)
- Unknown/no remote → Defaults to GitHub

**CLI Requirements:**
- **GitHub**: Requires `gh` CLI installed and authenticated
- Install: `brew install gh` (macOS), `scoop install gh` (Windows), `sudo apt install gh` (Linux)
- Authenticate: `gh auth login`
- More info: https://cli.github.com/
- **GitLab**: Requires `glab` CLI installed and authenticated
- Install: `brew install glab` (macOS), `scoop install glab` (Windows)
- Download: https://gitlab.com/gitlab-org/cli/-/releases
- Authenticate: `glab auth login`
Comment on lines +268 to +275
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Use Markdown link syntax for URLs.

The bare URLs should be converted to proper Markdown links for consistency with documentation standards.

📝 Suggested fix
 - **GitHub**: Requires `gh` CLI installed and authenticated
   - Install: `brew install gh` (macOS), `scoop install gh` (Windows), `sudo apt install gh` (Linux)
   - Authenticate: `gh auth login`
-  - More info: https://cli.github.com/
+  - More info: [GitHub CLI](https://cli.github.com/)
 - **GitLab**: Requires `glab` CLI installed and authenticated
   - Install: `brew install glab` (macOS), `scoop install glab` (Windows)
-  - Download: https://gitlab.com/gitlab-org/cli/-/releases
+  - Download: [GitLab CLI releases](https://gitlab.com/gitlab-org/cli/-/releases)
   - Authenticate: `glab auth login`
📝 Committable suggestion

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

Suggested change
- **GitHub**: Requires `gh` CLI installed and authenticated
- Install: `brew install gh` (macOS), `scoop install gh` (Windows), `sudo apt install gh` (Linux)
- Authenticate: `gh auth login`
- More info: https://cli.github.com/
- **GitLab**: Requires `glab` CLI installed and authenticated
- Install: `brew install glab` (macOS), `scoop install glab` (Windows)
- Download: https://gitlab.com/gitlab-org/cli/-/releases
- Authenticate: `glab auth login`
- **GitHub**: Requires `gh` CLI installed and authenticated
- Install: `brew install gh` (macOS), `scoop install gh` (Windows), `sudo apt install gh` (Linux)
- Authenticate: `gh auth login`
- More info: [GitHub CLI](https://cli.github.com/)
- **GitLab**: Requires `glab` CLI installed and authenticated
- Install: `brew install glab` (macOS), `scoop install glab` (Windows)
- Download: [GitLab CLI releases](https://gitlab.com/gitlab-org/cli/-/releases)
- Authenticate: `glab auth login`
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

271-271: Bare URL used

(MD034, no-bare-urls)


274-274: Bare URL used

(MD034, no-bare-urls)

🤖 Prompt for AI Agents
In `@CLAUDE.md` around lines 268 - 275, Replace the bare URLs under the "GitHub"
and "GitLab" sections with Markdown link syntax: change "More info:
https://cli.github.com/" to "More info: [GitHub CLI](https://cli.github.com/)"
(or similar descriptive text) and change "Download:
https://gitlab.com/gitlab-org/cli/-/releases" to "Download: [GitLab CLI
releases](https://gitlab.com/gitlab-org/cli/-/releases)"; keep the surrounding
bullets and commands intact and apply the same Markdown link style for any other
bare URLs in those "GitHub" and "GitLab" lines.


**Configuration Options:**

*In Project Settings UI:*
1. Open project settings
2. Expand "Git Provider Settings"
3. Choose: Auto-detect (recommended), GitHub, or GitLab

*In `.env` file:*

```bash
# Set git provider (optional, defaults to auto-detect)
GIT_PROVIDER=auto # auto | github | gitlab
```

**Example Usage:**

```bash
# Auto-detect provider from git remote (default)
python run.py --spec 001 --create-pr

# Works automatically with both:
# - [email protected]:user/repo.git → Creates GitHub PR using gh CLI
# - [email protected]:user/repo.git → Creates GitLab MR using glab CLI
```

**Provider Detection Logic:**
1. **Explicit setting** (if gitProvider is "github" or "gitlab") → Use that provider
2. **Auto-detect** (if gitProvider is "auto" or not set) → Parse git remote URL
3. **Fallback** (if no remote or unknown) → Default to GitHub

**Implementation Details:**
- Detection: `apps/backend/core/git_provider.py`
- GitHub PR creation: `apps/backend/core/worktree.py` (`_create_github_pr()`)
- GitLab MR creation: `apps/backend/core/worktree.py` (`_create_gitlab_mr()`)
- UI settings: `apps/frontend/src/renderer/components/project-settings/IntegrationSettings.tsx`

### Contributing to Upstream

**CRITICAL: When submitting PRs to AndyMik90/Auto-Claude, always target the `develop` branch, NOT `main`.**
Expand Down
60 changes: 60 additions & 0 deletions PR_DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
## Summary

This PR implements comprehensive Conda environment management for Auto Claude, enabling isolated Python environments at both application and project levels. It also includes significant Windows/PowerShell compatibility fixes to ensure reliable terminal integration across platforms.
Comment on lines +1 to +3
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use an H1 as the first heading.

Markdownlint MD041: first line should be a top-level heading.

✏️ Suggested fix
-## Summary
+# Summary
📝 Committable suggestion

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

Suggested change
## Summary
This PR implements comprehensive Conda environment management for Auto Claude, enabling isolated Python environments at both application and project levels. It also includes significant Windows/PowerShell compatibility fixes to ensure reliable terminal integration across platforms.
# Summary
This PR implements comprehensive Conda environment management for Auto Claude, enabling isolated Python environments at both application and project levels. It also includes significant Windows/PowerShell compatibility fixes to ensure reliable terminal integration across platforms.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🤖 Prompt for AI Agents
In `@PR_DESCRIPTION.md` around lines 1 - 3, Change the first heading from a
level-2 to a level-1 heading so the file starts with a top-level heading;
replace the existing "## Summary" line with "# Summary" (search for the "##
Summary" heading in PR_DESCRIPTION.md and update it to "# Summary") to satisfy
Markdownlint MD041.


### Key Features

- **Conda Detection Service**: Automatically detects conda installations across OS-specific locations (miniconda, anaconda, mambaforge)
- **Application-Level Environment**: Managed conda env at `~/miniconda3/envs/auto-claude` using `apps/backend/requirements.txt`
- **Project-Level Environments**: Self-contained environments in `.envs/<project-name>/` within each project
- **Automatic Terminal Activation**: Conda environments auto-activate when opening terminals for configured projects
- **Cross-Platform Activation Scripts**: Generated scripts for CMD, PowerShell, and Bash
- **VS Code Integration**: Auto-generated `.code-workspace` files with conda terminal profiles
- **Python Version Detection**: Parses `requirements.txt`, `pyproject.toml`, and `environment.yml` for version constraints

### Windows Compatibility Fixes

- Added `windowsHide: true` to all spawn calls to prevent console window popups
- Fixed PowerShell command syntax (`;` instead of `&&`, `$env:PATH=` instead of `PATH=`)
- Platform-aware shell escaping (PowerShell uses `''` for quotes, bash uses `'\''`)
- Added `pathWasModified` optimization to skip unnecessary PATH modifications (eliminates massive PATH echo)
- PowerShell-specific conda activation using init scripts

## Test plan

- [ ] **Conda Detection**: Open App Settings > Paths, verify conda installation detected
- [ ] **App Env Setup**: Click "Setup Auto Claude Environment", verify stepper completes
- [ ] **Project Toggle**: Enable conda env for a project in Project Settings > General
- [ ] **Project Env Setup**: Navigate to Python Env section, run setup, verify environment created
- [ ] **Terminal Activation**: Open terminal for conda-enabled project, verify env activates automatically
- [ ] **Windows Popup**: Verify no external PowerShell windows appear during operations
- [ ] **Connect Claude (Windows)**: Click "Connect Claude", verify PowerShell syntax works without errors
- [ ] **Settings Persistence**: Navigate away and back, verify all conda settings retained

## Files Changed

### New Files (11)
- `conda-detector.ts` - Conda installation detection service
- `conda-env-manager.ts` - Environment creation and management
- `conda-workspace-generator.ts` - VS Code workspace file generation
- `conda-project-structure.ts` - Project structure detection (pure-python vs mixed)
- `conda-handlers.ts` - IPC handlers for conda operations
- `conda-api.ts` - Preload API for renderer access
- `PythonEnvSettings.tsx` - Project-level Python environment settings UI
- `CondaSetupWizard.tsx` - Multi-step setup wizard with progress
- `CondaDetectionDisplay.tsx` - Conda detection status display
- `useCondaSetup.ts` - React hook for setup progress
- `conda.ts` - TypeScript type definitions

### Modified Files (48)
Comment on lines +36 to +49
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add blank lines around section headings.

Markdownlint MD022 expects blank lines before/after headings.

✏️ Suggested fix
-### New Files (11)
+### New Files (11)

 ...
-### Modified Files (48)
+### Modified Files (48)
📝 Committable suggestion

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

Suggested change
### New Files (11)
- `conda-detector.ts` - Conda installation detection service
- `conda-env-manager.ts` - Environment creation and management
- `conda-workspace-generator.ts` - VS Code workspace file generation
- `conda-project-structure.ts` - Project structure detection (pure-python vs mixed)
- `conda-handlers.ts` - IPC handlers for conda operations
- `conda-api.ts` - Preload API for renderer access
- `PythonEnvSettings.tsx` - Project-level Python environment settings UI
- `CondaSetupWizard.tsx` - Multi-step setup wizard with progress
- `CondaDetectionDisplay.tsx` - Conda detection status display
- `useCondaSetup.ts` - React hook for setup progress
- `conda.ts` - TypeScript type definitions
### Modified Files (48)
### New Files (11)
- `conda-detector.ts` - Conda installation detection service
- `conda-env-manager.ts` - Environment creation and management
- `conda-project-structure.ts` - Project structure detection (pure-python vs mixed)
- `conda-handlers.ts` - IPC handlers for conda operations
- `conda-api.ts` - Preload API for renderer access
- `PythonEnvSettings.tsx` - Project-level Python environment settings UI
- `CondaSetupWizard.tsx` - Multi-step setup wizard with progress
- `CondaDetectionDisplay.tsx` - Conda detection status display
- `useCondaSetup.ts` - React hook for setup progress
- `conda.ts` - TypeScript type definitions
### Modified Files (48)
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

36-36: 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 `@PR_DESCRIPTION.md` around lines 36 - 49, The PR_DESCRIPTION.md headings lack
surrounding blank lines required by markdownlint MD022; add a blank line before
and after each top-level and subsection heading (e.g., "New Files (11)", the
list block beneath it, and "Modified Files (48)") so each heading is separated
from adjacent text or lists, ensuring every heading has an empty line above and
below throughout the file.

- Terminal integration: `pty-manager.ts`, `terminal-lifecycle.ts`, `terminal-manager.ts`
- Claude integration: `claude-cli-utils.ts`, `claude-integration-handler.ts`
- Shell utilities: `shell-escape.ts`, `env-utils.ts`
- Settings UI: `GeneralSettings.tsx`, `AppSettings.tsx`, `ProjectSettingsContent.tsx`
- IPC handlers: Various handlers with `windowsHide` fixes
- Type definitions: `settings.ts`, `project.ts`, `terminal.ts`, `ipc.ts`
- i18n: English and French translation files

---

Generated with [Claude Code](https://claude.ai/code)
37 changes: 37 additions & 0 deletions apps/backend/agents/coder.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from recovery import RecoveryManager
from security.constants import PROJECT_DIR_ENV_VAR
from task_logger import (
LogEntryType,
LogPhase,
get_task_logger,
)
Expand All @@ -55,6 +56,7 @@
print_key_value,
print_status,
)
from user_feedback import get_unread_feedback

from .base import AUTO_CONTINUE_DELAY_SECONDS, HUMAN_INTERVENTION_FILE
from .memory_manager import debug_memory_system_status, get_graphiti_context
Expand Down Expand Up @@ -247,6 +249,30 @@
subtask_id = next_subtask.get("id") if next_subtask else None
phase_name = next_subtask.get("phase_name") if next_subtask else None

# Check for unread user feedback before starting this subtask
unread_feedback = get_unread_feedback(spec_dir)
feedback_text = None
if unread_feedback:
# Combine all unread feedback messages with their ACTUAL indices from full list
# unread_feedback is now a list of (actual_index, feedback_dict) tuples
feedback_messages = []
for actual_idx, fb in unread_feedback:
msg = fb.get("message", "")
timestamp = fb.get("timestamp", "")
# Use actual_idx so agent knows the correct index for mark_feedback_read tool
feedback_messages.append(f"[Index {actual_idx}] [{timestamp}]\n{msg}")
feedback_text = "\n\n".join(feedback_messages)

Check warning

Code scanning / CodeQL

Variable defined multiple times Warning

This assignment to 'feedback_text' is unnecessary as it is
redefined
before this value is used.

# Log feedback detection to task_logs.json (visible in UI)
task_logger = get_task_logger(spec_dir)
if task_logger:
task_logger.log(
content=f"USER FEEDBACK DETECTED - {len(unread_feedback)} unread feedback item(s) will be incorporated into this subtask",
entry_type=LogEntryType.INFO,
phase=LogPhase.CODING,
print_to_console=True,
)

Comment on lines +252 to +275
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Pass a string path into get_unread_feedback.

The helper signature expects str, but spec_dir is a Path. Convert to str (or update the helper signature) to avoid type/behavior mismatches once the stub is implemented.

🛠️ Suggested fix
-        unread_feedback = get_unread_feedback(spec_dir)
+        unread_feedback = get_unread_feedback(str(spec_dir))
🤖 Prompt for AI Agents
In `@apps/backend/agents/coder.py` around lines 252 - 275, get_unread_feedback
expects a string path but spec_dir is a Path; change the call to pass
str(spec_dir) (or otherwise convert to a string) when invoking
get_unread_feedback so the helper receives a str, e.g., replace
get_unread_feedback(spec_dir) with get_unread_feedback(str(spec_dir)); also
ensure any other calls nearby (e.g., get_task_logger) remain compatible or are
similarly converted if they require a str.

# Update status for this session
status_manager.update_session(iteration)
if phase_name:
Expand Down Expand Up @@ -476,6 +502,17 @@
if sync_spec_to_source(spec_dir, source_spec_dir):
print_status("Implementation plan synced to main project", "success")

# Show plan statistics
from implementation_plan import ImplementationPlan
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For better code organization and to follow standard Python conventions (PEP 8), it's recommended to move this import to the top of the file with the other imports. If this is a local import to avoid a circular dependency, please add a comment explaining why.


plan = ImplementationPlan.load(spec_dir / "implementation_plan.json")
total_phases = len(plan.phases)
total_subtasks = sum(len(p.subtasks) for p in plan.phases)
print_status(
f"Planning complete: {total_phases} phase(s), {total_subtasks} subtask(s)",
"success",
)

# Handle session status
if status == "complete":
# Don't emit COMPLETE here - subtasks are done but QA hasn't run yet
Expand Down
Loading
Loading