diff --git a/.claude/commands/agent-work-orders/commit.md b/.claude/commands/agent-work-orders/commit.md new file mode 100644 index 00000000..14f8d834 --- /dev/null +++ b/.claude/commands/agent-work-orders/commit.md @@ -0,0 +1,55 @@ +# Create Git Commit + +Create an atomic git commit with a properly formatted commit message following best practices for the uncommited changes or these specific files if specified. + +Specific files (skip if not specified): + +- File 1: $1 +- File 2: $2 +- File 3: $3 +- File 4: $4 +- File 5: $5 + +## Instructions + +**Commit Message Format:** + +- Use conventional commits: `: ` +- Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore` +- Present tense (e.g., "add", "fix", "update", not "added", "fixed", "updated") +- 50 characters or less for the subject line +- Lowercase subject line +- No period at the end +- Be specific and descriptive + +**Examples:** + +- `feat: add web search tool with structured logging` +- `fix: resolve type errors in middleware` +- `test: add unit tests for config module` +- `docs: update CLAUDE.md with testing guidelines` +- `refactor: simplify logging configuration` +- `chore: update dependencies` + +**Atomic Commits:** + +- One logical change per commit +- If you've made multiple unrelated changes, consider splitting into separate commits +- Commit should be self-contained and not break the build + +**IMPORTANT** + +- NEVER mention claude code, anthropic, co authored by or anything similar in the commit messages + +## Run + +1. Review changes: `git diff HEAD` +2. Check status: `git status` +3. Stage changes: `git add -A` +4. Create commit: `git commit -m ": "` + +## Report + +- Output the commit message used +- Confirm commit was successful with commit hash +- List files that were committed diff --git a/.claude/commands/agent-work-orders/execute.md b/.claude/commands/agent-work-orders/execute.md new file mode 100644 index 00000000..427973e6 --- /dev/null +++ b/.claude/commands/agent-work-orders/execute.md @@ -0,0 +1,27 @@ +# Execute PRP Plan + +Implement a feature plan from the PRPs directory by following its Step by Step Tasks section. + +## Variables + +Plan file: $ARGUMENTS + +## Instructions + +- Read the entire plan file carefully +- Execute **every step** in the "Step by Step Tasks" section in order, top to bottom +- Follow the "Testing Strategy" to create proper unit and integration tests +- Complete all "Validation Commands" at the end +- Ensure all linters pass and all tests pass before finishing +- Follow CLAUDE.md guidelines for type safety, logging, and docstrings + +## When done + +- Move the PRP file to the completed directory in PRPs/features/completed + +## Report + +- Summarize completed work in a concise bullet point list +- Show files and lines changed: `git diff --stat` +- Confirm all validation commands passed +- Note any deviations from the plan (if any) diff --git a/.claude/commands/agent-work-orders/noqa.md b/.claude/commands/agent-work-orders/noqa.md new file mode 100644 index 00000000..7bf8a67c --- /dev/null +++ b/.claude/commands/agent-work-orders/noqa.md @@ -0,0 +1,176 @@ +# NOQA Analysis and Resolution + +Find all noqa/type:ignore comments in the codebase, investigate why they exist, and provide recommendations for resolution or justification. + +## Instructions + +**Step 1: Find all NOQA comments** + +- Use Grep tool to find all noqa comments: pattern `noqa|type:\s*ignore` +- Use output_mode "content" with line numbers (-n flag) +- Search across all Python files (type: "py") +- Document total count of noqa comments found + +**Step 2: For EACH noqa comment (repeat this process):** + +- Read the file containing the noqa comment with sufficient context (at least 10 lines before and after) +- Identify the specific linting rule or type error being suppressed +- Understand the code's purpose and why the suppression was added +- Investigate if the suppression is still necessary or can be resolved + +**Step 3: Investigation checklist for each noqa:** + +- What specific error/warning is being suppressed? (e.g., `type: ignore[arg-type]`, `noqa: F401`) +- Why was the suppression necessary? (legacy code, false positive, legitimate limitation, technical debt) +- Can the underlying issue be fixed? (refactor code, update types, improve imports) +- What would it take to remove the suppression? (effort estimate, breaking changes, architectural changes) +- Is the suppression justified long-term? (external library limitation, Python limitation, intentional design) + +**Step 4: Research solutions:** + +- Check if newer versions of tools (mypy, ruff) handle the case better +- Look for alternative code patterns that avoid the suppression +- Consider if type stubs or Protocol definitions could help +- Evaluate if refactoring would be worthwhile + +## Report Format + +Create a markdown report file (create the reports directory if not created yet): `PRPs/reports/noqa-analysis-{YYYY-MM-DD}.md` + +Use this structure for the report: + +````markdown +# NOQA Analysis Report + +**Generated:** {date} +**Total NOQA comments found:** {count} + +--- + +## Summary + +- Total suppressions: {count} +- Can be removed: {count} +- Should remain: {count} +- Requires investigation: {count} + +--- + +## Detailed Analysis + +### 1. {File path}:{line number} + +**Location:** `{file_path}:{line_number}` + +**Suppression:** `{noqa comment or type: ignore}` + +**Code context:** + +```python +{relevant code snippet} +``` +```` + +**Why it exists:** +{explanation of why the suppression was added} + +**Options to resolve:** + +1. {Option 1: description} + - Effort: {Low/Medium/High} + - Breaking: {Yes/No} + - Impact: {description} + +2. {Option 2: description} + - Effort: {Low/Medium/High} + - Breaking: {Yes/No} + - Impact: {description} + +**Tradeoffs:** + +- {Tradeoff 1} +- {Tradeoff 2} + +**Recommendation:** {Remove | Keep | Refactor} +{Justification for recommendation} + +--- + +{Repeat for each noqa comment} + +```` + +## Example Analysis Entry + +```markdown +### 1. src/shared/config.py:45 + +**Location:** `src/shared/config.py:45` + +**Suppression:** `# type: ignore[assignment]` + +**Code context:** +```python +@property +def openai_api_key(self) -> str: + key = os.getenv("OPENAI_API_KEY") + if not key: + raise ValueError("OPENAI_API_KEY not set") + return key # type: ignore[assignment] +```` + +**Why it exists:** +MyPy cannot infer that the ValueError prevents None from being returned, so it thinks the return type could be `str | None`. + +**Options to resolve:** + +1. Use assert to help mypy narrow the type + - Effort: Low + - Breaking: No + - Impact: Cleaner code, removes suppression + +2. Add explicit cast with typing.cast() + - Effort: Low + - Breaking: No + - Impact: More verbose but type-safe + +3. Refactor to use separate validation method + - Effort: Medium + - Breaking: No + - Impact: Better separation of concerns + +**Tradeoffs:** + +- Option 1 (assert) is cleanest but asserts can be disabled with -O flag +- Option 2 (cast) is most explicit but adds import and verbosity +- Option 3 is most robust but requires more refactoring + +**Recommendation:** Remove (use Option 1) +Replace the type:ignore with an assert statement after the if check. This helps mypy understand the control flow while maintaining runtime safety. The assert will never fail in practice since the ValueError is raised first. + +**Implementation:** + +```python +@property +def openai_api_key(self) -> str: + key = os.getenv("OPENAI_API_KEY") + if not key: + raise ValueError("OPENAI_API_KEY not set") + assert key is not None # Help mypy understand control flow + return key +``` + +``` + +## Report + +After completing the analysis: + +- Output the path to the generated report file +- Summarize findings: + - Total suppressions found + - How many can be removed immediately (low effort) + - How many should remain (justified) + - How many need deeper investigation or refactoring +- Highlight any quick wins (suppressions that can be removed with minimal effort) +``` diff --git a/.claude/commands/agent-work-orders/planning.md b/.claude/commands/agent-work-orders/planning.md new file mode 100644 index 00000000..039377b0 --- /dev/null +++ b/.claude/commands/agent-work-orders/planning.md @@ -0,0 +1,176 @@ +# Feature Planning + +Create a new plan to implement the `PRP` using the exact specified markdown `PRP Format`. Follow the `Instructions` to create the plan use the `Relevant Files` to focus on the right files. + +## Variables + +FEATURE $1 $2 + +## Instructions + +- IMPORTANT: You're writing a plan to implement a net new feature based on the `Feature` that will add value to the application. +- IMPORTANT: The `Feature` describes the feature that will be implemented but remember we're not implementing a new feature, we're creating the plan that will be used to implement the feature based on the `PRP Format` below. +- Create the plan in the `PRPs/features/` directory with filename: `{descriptive-name}.md` + - Replace `{descriptive-name}` with a short, descriptive name based on the feature (e.g., "add-auth-system", "implement-search", "create-dashboard") +- Use the `PRP Format` below to create the plan. +- Deeply research the codebase to understand existing patterns, architecture, and conventions before planning the feature. +- If no patterns are established or are unclear ask the user for clarifications while providing best recommendations and options +- IMPORTANT: Replace every in the `PRP Format` with the requested value. Add as much detail as needed to implement the feature successfully. +- Use your reasoning model: THINK HARD about the feature requirements, design, and implementation approach. +- Follow existing patterns and conventions in the codebase. Don't reinvent the wheel. +- Design for extensibility and maintainability. +- Deeply do web research to understand the latest trends and technologies in the field. +- Figure out latest best practices and library documentation. +- Include links to relevant resources and documentation with anchor tags for easy navigation. +- If you need a new library, use `uv add ` and report it in the `Notes` section. +- Read `CLAUDE.md` for project principles, logging rules, testing requirements, and docstring style. +- All code MUST have type annotations (strict mypy enforcement). +- Use Google-style docstrings for all functions, classes, and modules. +- Every new file in `src/` MUST have a corresponding test file in `tests/`. +- Respect requested files in the `Relevant Files` section. + +## Relevant Files + +Focus on the following files and vertical slice structure: + +**Core Files:** + +- `CLAUDE.md` - Project instructions, logging rules, testing requirements, docstring style + app/backend core files + app/frontend core files + +## PRP Format + +```md +# Feature: + +## Feature Description + + + +## User Story + +As a +I want to +So that + +## Problem Statement + + + +## Solution Statement + + + +## Relevant Files + +Use these files to implement the feature: + + + +## Relevant research docstring + +Use these documentation files and links to help with understanding the technology to use: + +- [Documentation Link 1](https://example.com/doc1) + - [Anchor tag] + - [Short summary] +- [Documentation Link 2](https://example.com/doc2) + - [Anchor tag] + - [Short summary] + +## Implementation Plan + +### Phase 1: Foundation + + + +### Phase 2: Core Implementation + + + +### Phase 3: Integration + + + +## Step by Step Tasks + +IMPORTANT: Execute every step in order, top to bottom. + + + +/test_.py` +- Add integration test in `tests/integration/` if needed> + +## Testing Strategy + +See `CLAUDE.md` for complete testing requirements. Every file in `src/` must have a corresponding test file in `tests/`. + +### Unit Tests + + + +### Integration Tests + + + +### Edge Cases + + + +## Acceptance Criteria + + + +## Validation Commands + +Execute every command to validate the feature works correctly with zero regressions. + + + +**Required validation commands:** + +- `uv run ruff check src/` - Lint check must pass +- `uv run mypy src/` - Type check must pass +- `uv run pytest tests/ -v` - All tests must pass with zero regressions + +**Run server and test core endpoints:** + +- Start server: @.claude/start-server +- Test endpoints with curl (at minimum: health check, main functionality) +- Verify structured logs show proper correlation IDs and context +- Stop server after validation + +## Notes + + +``` + +## Feature + +Extract the feature details from the `issue_json` variable (parse the JSON and use the title and body fields). + +## Report + +- Summarize the work you've just done in a concise bullet point list. +- Include the full path to the plan file you created (e.g., `PRPs/features/add-auth-system.md`) diff --git a/.claude/commands/agent-work-orders/prime.md b/.claude/commands/agent-work-orders/prime.md new file mode 100644 index 00000000..436ba62a --- /dev/null +++ b/.claude/commands/agent-work-orders/prime.md @@ -0,0 +1,28 @@ +# Prime + +Execute the following sections to understand the codebase before starting new work, then summarize your understanding. + +## Run + +- List all tracked files: `git ls-files` +- Show project structure: `tree -I '.venv|__pycache__|*.pyc|.pytest_cache|.mypy_cache|.ruff_cache' -L 3` + +## Read + +- `CLAUDE.md` - Core project instructions, principles, logging rules, testing requirements +- `python/src/agent_work_orders` - Project overview and setup (if exists) + +- Identify core files in the agent work orders directory to understand what we are woerking on and its intent + +## Report + +Provide a concise summary of: + +1. **Project Purpose**: What this application does +2. **Architecture**: Key patterns (vertical slice, FastAPI + Pydantic AI) +3. **Core Principles**: TYPE SAFETY, KISS, YAGNI +4. **Tech Stack**: Main dependencies and tools +5. **Key Requirements**: Logging, testing, type annotations +6. **Current State**: What's implemented + +Keep the summary brief (5-10 bullet points) and focused on what you need to know to contribute effectively. diff --git a/.claude/commands/agent-work-orders/prp-review.md b/.claude/commands/agent-work-orders/prp-review.md new file mode 100644 index 00000000..c4ce29d4 --- /dev/null +++ b/.claude/commands/agent-work-orders/prp-review.md @@ -0,0 +1,89 @@ +# Code Review + +Review implemented work against a PRP specification to ensure code quality, correctness, and adherence to project standards. + +## Variables + +Plan file: $ARGUMENTS (e.g., `PRPs/features/add-web-search.md`) + +## Instructions + +**Understand the Changes:** + +- Check current branch: `git branch` +- Review changes: `git diff origin/main` (or `git diff HEAD` if not on a branch) +- Read the PRP plan file to understand requirements + +**Code Quality Review:** + +- **Type Safety**: Verify all functions have type annotations, mypy passes +- **Logging**: Check structured logging is used correctly (event names, context, exception handling) +- **Docstrings**: Ensure Google-style docstrings on all functions/classes +- **Testing**: Verify unit tests exist for all new files, integration tests if needed +- **Architecture**: Confirm vertical slice structure is followed +- **CLAUDE.md Compliance**: Check adherence to core principles (KISS, YAGNI, TYPE SAFETY) + +**Validation Ruff for BE and Biome for FE:** + +- Run linters: `uv run ruff check src/ && uv run mypy src/` +- Run tests: `uv run pytest tests/ -v` +- Start server and test endpoints with curl (if applicable) +- Verify structured logs show proper correlation IDs and context + +**Issue Severity:** + +- `blocker` - Must fix before merge (breaks build, missing tests, type errors, security issues) +- `major` - Should fix (missing logging, incomplete docstrings, poor patterns) +- `minor` - Nice to have (style improvements, optimization opportunities) + +## Report + +Return ONLY valid JSON (no markdown, no explanations) save to [report-#.json] in prps/reports directory create the directory if it doesn't exist. Output will be parsed with JSON.parse(). + +### Output Structure + +```json +{ + "success": "boolean - true if NO BLOCKER issues, false if BLOCKER issues exist", + "review_summary": "string - 2-4 sentences: what was built, does it match spec, quality assessment", + "review_issues": [ + { + "issue_number": "number - issue index", + "file_path": "string - file with the issue (if applicable)", + "issue_description": "string - what's wrong", + "issue_resolution": "string - how to fix it", + "severity": "string - blocker|major|minor" + } + ], + "validation_results": { + "linting_passed": "boolean", + "type_checking_passed": "boolean", + "tests_passed": "boolean", + "api_endpoints_tested": "boolean - true if endpoints were tested with curl" + } +} +``` + +## Example Success Review + +```json +{ + "success": true, + "review_summary": "The web search tool has been implemented with proper type annotations, structured logging, and comprehensive tests. The implementation follows the vertical slice architecture and matches all spec requirements. Code quality is high with proper error handling and documentation.", + "review_issues": [ + { + "issue_number": 1, + "file_path": "src/tools/web_search/tool.py", + "issue_description": "Missing debug log for API response", + "issue_resolution": "Add logger.debug with response metadata", + "severity": "minor" + } + ], + "validation_results": { + "linting_passed": true, + "type_checking_passed": true, + "tests_passed": true, + "api_endpoints_tested": true + } +} +``` diff --git a/.claude/commands/agent-work-orders/start-server.md b/.claude/commands/agent-work-orders/start-server.md new file mode 100644 index 00000000..58a7ce2f --- /dev/null +++ b/.claude/commands/agent-work-orders/start-server.md @@ -0,0 +1,33 @@ +# Start Servers + +Start both the FastAPI backend and React frontend development servers with hot reload. + +## Run + +### Run in the background with bash tool + +- Ensure you are in the right PWD +- Use the Bash tool to run the servers in the background so you can read the shell outputs +- IMPORTANT: run `git ls-files` first so you know where directories are located before you start + +### Backend Server (FastAPI) + +- Navigate to backend: `cd app/backend` +- Start server in background: `uv sync && uv run python run_api.py` +- Wait 2-3 seconds for startup +- Test health endpoint: `curl http://localhost:8000/health` +- Test products endpoint: `curl http://localhost:8000/api/products` + +### Frontend Server (Bun + React) + +- Navigate to frontend: `cd ../app/frontend` +- Start server in background: `bun install && bun dev` +- Wait 2-3 seconds for startup +- Frontend should be accessible at `http://localhost:3000` + +## Report + +- Confirm backend is running on `http://localhost:8000` +- Confirm frontend is running on `http://localhost:3000` +- Show the health check response from backend +- Mention: "Backend logs will show structured JSON logging for all requests" diff --git a/.env.example b/.env.example index 9647c8fa..2218e2a2 100644 --- a/.env.example +++ b/.env.example @@ -27,15 +27,56 @@ SUPABASE_SERVICE_KEY= LOGFIRE_TOKEN= LOG_LEVEL=INFO +# Claude API Key (Required for Agent Work Orders) +# Get your API key from: https://console.anthropic.com/ +# Required for the agent work orders service to execute Claude CLI commands +ANTHROPIC_API_KEY= + +# GitHub Personal Access Token (Required for Agent Work Orders PR creation) +# Get your token from: https://github.com/settings/tokens +# Required scopes: repo, workflow +# The agent work orders service uses this for gh CLI authentication to create PRs +GITHUB_PAT_TOKEN= + # Service Ports Configuration # These ports are used for external access to the services HOST=localhost ARCHON_SERVER_PORT=8181 ARCHON_MCP_PORT=8051 ARCHON_AGENTS_PORT=8052 +# Agent Work Orders Port (Optional - only needed if feature is enabled) +# Leave unset or comment out if you don't plan to use agent work orders +AGENT_WORK_ORDERS_PORT=8053 ARCHON_UI_PORT=3737 ARCHON_DOCS_PORT=3838 +# Agent Work Orders Feature (Optional) +# Enable the agent work orders microservice for automated task execution +# Default: false (feature disabled) +# Set to "true" to enable: ENABLE_AGENT_WORK_ORDERS=true +# When enabled, requires Claude API key and GitHub PAT (see above) +ENABLE_AGENT_WORK_ORDERS=false + +# Agent Work Orders Service Configuration (Optional) +# Only needed if ENABLE_AGENT_WORK_ORDERS=true +# Set these if running agent work orders service independently +# SERVICE_DISCOVERY_MODE: Controls how services find each other +# - "local": Services run on localhost with different ports +# - "docker_compose": Services use Docker container names +SERVICE_DISCOVERY_MODE=local + +# Service URLs (for agent work orders service to call other services) +# These are automatically configured based on SERVICE_DISCOVERY_MODE +# Only override if you need custom service URLs +# ARCHON_SERVER_URL=http://localhost:8181 +# ARCHON_MCP_URL=http://localhost:8051 + +# Agent Work Orders Persistence +# STATE_STORAGE_TYPE: "memory" (default, ephemeral) or "file" (persistent) +# FILE_STATE_DIRECTORY: Directory for file-based state storage +STATE_STORAGE_TYPE=file +FILE_STATE_DIRECTORY=agent-work-orders-state + # Frontend Configuration # VITE_ALLOWED_HOSTS: Comma-separated list of additional hosts allowed for Vite dev server # Example: VITE_ALLOWED_HOSTS=192.168.1.100,myhost.local,example.com diff --git a/.gitignore b/.gitignore index d1e415cb..7a5f4d0e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ __pycache__ PRPs/local PRPs/completed/ PRPs/stories/ +PRPs/examples +PRPs/features +PRPs/specs PRPs/reviews/ /logs/ .zed @@ -12,6 +15,15 @@ tmp/ temp/ UAT/ +# Temporary validation/report markdown files +/*_RESULTS.md +/*_SUMMARY.md +/*_REPORT.md +/*_SUCCESS.md +/*_COMPLETION*.md +/ACTUAL_*.md +/VALIDATION_*.md + .DS_Store # Local release notes testing diff --git a/CLAUDE.md b/CLAUDE.md index 85bbcf31..fbe5b801 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -104,12 +104,19 @@ uv run ruff check # Run linter uv run ruff check --fix # Auto-fix linting issues uv run mypy src/ # Type check +# Agent Work Orders Service (independent microservice) +make agent-work-orders # Run agent work orders service locally on 8053 +# Or manually: +uv run python -m uvicorn src.agent_work_orders.server:app --port 8053 --reload + # Docker operations docker compose up --build -d # Start all services docker compose --profile backend up -d # Backend only (for hybrid dev) -docker compose logs -f archon-server # View server logs -docker compose logs -f archon-mcp # View MCP server logs -docker compose restart archon-server # Restart after code changes +docker compose --profile work-orders up -d # Include agent work orders service +docker compose logs -f archon-server # View server logs +docker compose logs -f archon-mcp # View MCP server logs +docker compose logs -f archon-agent-work-orders # View agent work orders service logs +docker compose restart archon-server # Restart after code changes docker compose down # Stop all services docker compose down -v # Stop and remove volumes ``` @@ -120,8 +127,19 @@ docker compose down -v # Stop and remove volumes # Hybrid development (recommended) - backend in Docker, frontend local make dev # Or manually: docker compose --profile backend up -d && cd archon-ui-main && npm run dev +# Hybrid with Agent Work Orders Service - backend in Docker, agent work orders local +make dev-work-orders # Starts backend in Docker, prompts to run agent service in separate terminal +# Then in separate terminal: +make agent-work-orders # Start agent work orders service locally + # Full Docker mode make dev-docker # Or: docker compose up --build -d +docker compose --profile work-orders up -d # Include agent work orders service + +# All Local (3 terminals) - for agent work orders service development +# Terminal 1: uv run python -m uvicorn src.server.main:app --port 8181 --reload +# Terminal 2: make agent-work-orders +# Terminal 3: cd archon-ui-main && npm run dev # Run linters before committing make lint # Runs both frontend and backend linters diff --git a/Makefile b/Makefile index 5fafd66a..632153c7 100644 --- a/Makefile +++ b/Makefile @@ -5,23 +5,27 @@ SHELL := /bin/bash # Docker compose command - prefer newer 'docker compose' plugin over standalone 'docker-compose' COMPOSE ?= $(shell docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose") -.PHONY: help dev dev-docker stop test test-fe test-be lint lint-fe lint-be clean install check +.PHONY: help dev dev-docker dev-docker-full dev-work-orders dev-hybrid-work-orders stop test test-fe test-be lint lint-fe lint-be clean install check agent-work-orders help: @echo "Archon Development Commands" @echo "===========================" - @echo " make dev - Backend in Docker, frontend local (recommended)" - @echo " make dev-docker - Everything in Docker" - @echo " make stop - Stop all services" - @echo " make test - Run all tests" - @echo " make test-fe - Run frontend tests only" - @echo " make test-be - Run backend tests only" - @echo " make lint - Run all linters" - @echo " make lint-fe - Run frontend linter only" - @echo " make lint-be - Run backend linter only" - @echo " make clean - Remove containers and volumes" - @echo " make install - Install dependencies" - @echo " make check - Check environment setup" + @echo " make dev - Backend in Docker, frontend local (recommended)" + @echo " make dev-docker - Backend + frontend in Docker" + @echo " make dev-docker-full - Everything in Docker (server + mcp + ui + work orders)" + @echo " make dev-hybrid-work-orders - Server + MCP in Docker, UI + work orders local (2 terminals)" + @echo " make dev-work-orders - Backend in Docker, agent work orders local, frontend local" + @echo " make agent-work-orders - Run agent work orders service locally" + @echo " make stop - Stop all services" + @echo " make test - Run all tests" + @echo " make test-fe - Run frontend tests only" + @echo " make test-be - Run backend tests only" + @echo " make lint - Run all linters" + @echo " make lint-fe - Run frontend linter only" + @echo " make lint-be - Run backend linter only" + @echo " make clean - Remove containers and volumes" + @echo " make install - Install dependencies" + @echo " make check - Check environment setup" # Install dependencies install: @@ -54,18 +58,73 @@ dev: check VITE_ARCHON_SERVER_HOST=$${HOST:-} \ npm run dev -# Full Docker development +# Full Docker development (backend + frontend, no work orders) dev-docker: check - @echo "Starting full Docker environment..." + @echo "Starting Docker environment (backend + frontend)..." @$(COMPOSE) --profile full up -d --build - @echo "✓ All services running" + @echo "✓ Services running" @echo "Frontend: http://localhost:3737" @echo "API: http://localhost:8181" +# Full Docker with all services (server + mcp + ui + agent work orders) +dev-docker-full: check + @echo "Starting full Docker environment with agent work orders..." + @$(COMPOSE) up archon-server archon-mcp archon-frontend archon-agent-work-orders -d --build + @set -a; [ -f .env ] && . ./.env; set +a; \ + echo "✓ All services running"; \ + echo "Frontend: http://localhost:3737"; \ + echo "API: http://$${HOST:-localhost}:$${ARCHON_SERVER_PORT:-8181}"; \ + echo "MCP: http://$${HOST:-localhost}:$${ARCHON_MCP_PORT:-8051}"; \ + echo "Agent Work Orders: http://$${HOST:-localhost}:$${AGENT_WORK_ORDERS_PORT:-8053}" + +# Agent work orders service locally (standalone) +agent-work-orders: + @echo "Starting Agent Work Orders service locally..." + @set -a; [ -f .env ] && . ./.env; set +a; \ + export SERVICE_DISCOVERY_MODE=local; \ + export ARCHON_SERVER_URL=http://localhost:$${ARCHON_SERVER_PORT:-8181}; \ + export ARCHON_MCP_URL=http://localhost:$${ARCHON_MCP_PORT:-8051}; \ + export AGENT_WORK_ORDERS_PORT=$${AGENT_WORK_ORDERS_PORT:-8053}; \ + cd python && uv run python -m uvicorn src.agent_work_orders.server:app --host 0.0.0.0 --port $${AGENT_WORK_ORDERS_PORT:-8053} --reload + +# Hybrid development with agent work orders (backend in Docker, agent work orders local, frontend local) +dev-work-orders: check + @echo "Starting hybrid development with agent work orders..." + @echo "Backend: Docker | Agent Work Orders: Local | Frontend: Local" + @$(COMPOSE) up archon-server archon-mcp -d --build + @set -a; [ -f .env ] && . ./.env; set +a; \ + echo "Backend running at http://$${HOST:-localhost}:$${ARCHON_SERVER_PORT:-8181}"; \ + echo "Starting agent work orders service..."; \ + echo "Run in separate terminal: make agent-work-orders"; \ + echo "Starting frontend..."; \ + cd archon-ui-main && \ + VITE_ARCHON_SERVER_PORT=$${ARCHON_SERVER_PORT:-8181} \ + VITE_ARCHON_SERVER_HOST=$${HOST:-} \ + npm run dev + +# Hybrid development: Server + MCP in Docker, UI + Work Orders local (requires 2 terminals) +dev-hybrid-work-orders: check + @echo "Starting hybrid development: Server + MCP in Docker, UI + Work Orders local" + @echo "================================================================" + @$(COMPOSE) up archon-server archon-mcp -d --build + @set -a; [ -f .env ] && . ./.env; set +a; \ + echo ""; \ + echo "✓ Server + MCP running in Docker"; \ + echo " Server: http://$${HOST:-localhost}:$${ARCHON_SERVER_PORT:-8181}"; \ + echo " MCP: http://$${HOST:-localhost}:$${ARCHON_MCP_PORT:-8051}"; \ + echo ""; \ + echo "Next steps:"; \ + echo " 1. Terminal 1 (this one): Press Ctrl+C when done"; \ + echo " 2. Terminal 2: make agent-work-orders"; \ + echo " 3. Terminal 3: cd archon-ui-main && npm run dev"; \ + echo ""; \ + echo "Or use 'make dev-docker-full' to run everything in Docker."; \ + @read -p "Press Enter to continue or Ctrl+C to stop..." _ + # Stop all services stop: @echo "Stopping all services..." - @$(COMPOSE) --profile backend --profile frontend --profile full down + @$(COMPOSE) --profile backend --profile frontend --profile full --profile work-orders down @echo "✓ Services stopped" # Run all tests diff --git a/PRPs/ai_docs/cc_cli_ref.md b/PRPs/ai_docs/cc_cli_ref.md new file mode 100644 index 00000000..78572716 --- /dev/null +++ b/PRPs/ai_docs/cc_cli_ref.md @@ -0,0 +1,89 @@ +# CLI reference + +> Complete reference for Claude Code command-line interface, including commands and flags. + +## CLI commands + +| Command | Description | Example | +| :--------------------------------- | :--------------------------------------------- | :----------------------------------------------------------------- | +| `claude` | Start interactive REPL | `claude` | +| `claude "query"` | Start REPL with initial prompt | `claude "explain this project"` | +| `claude -p "query"` | Query via SDK, then exit | `claude -p "explain this function"` | +| `cat file \| claude -p "query"` | Process piped content | `cat logs.txt \| claude -p "explain"` | +| `claude -c` | Continue most recent conversation | `claude -c` | +| `claude -c -p "query"` | Continue via SDK | `claude -c -p "Check for type errors"` | +| `claude -r "" "query"` | Resume session by ID | `claude -r "abc123" "Finish this PR"` | +| `claude update` | Update to latest version | `claude update` | +| `claude mcp` | Configure Model Context Protocol (MCP) servers | See the [Claude Code MCP documentation](/en/docs/claude-code/mcp). | + +## CLI flags + +Customize Claude Code's behavior with these command-line flags: + +| Flag | Description | Example | +| :------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------- | +| `--add-dir` | Add additional working directories for Claude to access (validates each path exists as a directory) | `claude --add-dir ../apps ../lib` | +| `--agents` | Define custom [subagents](/en/docs/claude-code/sub-agents) dynamically via JSON (see below for format) | `claude --agents '{"reviewer":{"description":"Reviews code","prompt":"You are a code reviewer"}}'` | +| `--allowedTools` | A list of tools that should be allowed without prompting the user for permission, in addition to [settings.json files](/en/docs/claude-code/settings) | `"Bash(git log:*)" "Bash(git diff:*)" "Read"` | +| `--disallowedTools` | A list of tools that should be disallowed without prompting the user for permission, in addition to [settings.json files](/en/docs/claude-code/settings) | `"Bash(git log:*)" "Bash(git diff:*)" "Edit"` | +| `--print`, `-p` | Print response without interactive mode (see [SDK documentation](/en/docs/claude-code/sdk) for programmatic usage details) | `claude -p "query"` | +| `--append-system-prompt` | Append to system prompt (only with `--print`) | `claude --append-system-prompt "Custom instruction"` | +| `--output-format` | Specify output format for print mode (options: `text`, `json`, `stream-json`) | `claude -p "query" --output-format json` | +| `--input-format` | Specify input format for print mode (options: `text`, `stream-json`) | `claude -p --output-format json --input-format stream-json` | +| `--include-partial-messages` | Include partial streaming events in output (requires `--print` and `--output-format=stream-json`) | `claude -p --output-format stream-json --include-partial-messages "query"` | +| `--verbose` | Enable verbose logging, shows full turn-by-turn output (helpful for debugging in both print and interactive modes) | `claude --verbose` | +| `--max-turns` | Limit the number of agentic turns in non-interactive mode | `claude -p --max-turns 3 "query"` | +| `--model` | Sets the model for the current session with an alias for the latest model (`sonnet` or `opus`) or a model's full name | `claude --model claude-sonnet-4-5-20250929` | +| `--permission-mode` | Begin in a specified [permission mode](iam#permission-modes) | `claude --permission-mode plan` | +| `--permission-prompt-tool` | Specify an MCP tool to handle permission prompts in non-interactive mode | `claude -p --permission-prompt-tool mcp_auth_tool "query"` | +| `--resume` | Resume a specific session by ID, or by choosing in interactive mode | `claude --resume abc123 "query"` | +| `--continue` | Load the most recent conversation in the current directory | `claude --continue` | +| `--dangerously-skip-permissions` | Skip permission prompts (use with caution) | `claude --dangerously-skip-permissions` | + + + The `--output-format json` flag is particularly useful for scripting and + automation, allowing you to parse Claude's responses programmatically. + + +### Agents flag format + +The `--agents` flag accepts a JSON object that defines one or more custom subagents. Each subagent requires a unique name (as the key) and a definition object with the following fields: + +| Field | Required | Description | +| :------------ | :------- | :-------------------------------------------------------------------------------------------------------------- | +| `description` | Yes | Natural language description of when the subagent should be invoked | +| `prompt` | Yes | The system prompt that guides the subagent's behavior | +| `tools` | No | Array of specific tools the subagent can use (e.g., `["Read", "Edit", "Bash"]`). If omitted, inherits all tools | +| `model` | No | Model alias to use: `sonnet`, `opus`, or `haiku`. If omitted, uses the default subagent model | + +Example: + +```bash theme={null} +claude --agents '{ + "code-reviewer": { + "description": "Expert code reviewer. Use proactively after code changes.", + "prompt": "You are a senior code reviewer. Focus on code quality, security, and best practices.", + "tools": ["Read", "Grep", "Glob", "Bash"], + "model": "sonnet" + }, + "debugger": { + "description": "Debugging specialist for errors and test failures.", + "prompt": "You are an expert debugger. Analyze errors, identify root causes, and provide fixes." + } +}' +``` + +For more details on creating and using subagents, see the [subagents documentation](/en/docs/claude-code/sub-agents). + +For detailed information about print mode (`-p`) including output formats, +streaming, verbose logging, and programmatic usage, see the +[SDK documentation](/en/docs/claude-code/sdk). + +## See also + +- [Interactive mode](/en/docs/claude-code/interactive-mode) - Shortcuts, input modes, and interactive features +- [Slash commands](/en/docs/claude-code/slash-commands) - Interactive session commands +- [Quickstart guide](/en/docs/claude-code/quickstart) - Getting started with Claude Code +- [Common workflows](/en/docs/claude-code/common-workflows) - Advanced workflows and patterns +- [Settings](/en/docs/claude-code/settings) - Configuration options +- [SDK documentation](/en/docs/claude-code/sdk) - Programmatic usage and integrations diff --git a/archon-ui-main/.env.example b/archon-ui-main/.env.example new file mode 100644 index 00000000..284c8ea7 --- /dev/null +++ b/archon-ui-main/.env.example @@ -0,0 +1,13 @@ +# Frontend Environment Configuration + +# Agent Work Orders Service (Optional) +# Only set if agent work orders service runs on different host/port than main server +# Default: Uses proxy through main server at /api/agent-work-orders +# Set to the base URL (without /api/agent-work-orders path) +# VITE_AGENT_WORK_ORDERS_URL=http://localhost:8053 + +# Development Tools +# Show TanStack Query DevTools (for developers only) +# Set to "true" to enable the DevTools panel in bottom right corner +# Defaults to "false" for end users +VITE_SHOW_DEVTOOLS=false diff --git a/archon-ui-main/package-lock.json b/archon-ui-main/package-lock.json index 37b3e9a7..6e17b02d 100644 --- a/archon-ui-main/package-lock.json +++ b/archon-ui-main/package-lock.json @@ -8,6 +8,7 @@ "name": "archon-ui", "version": "0.1.0", "dependencies": { + "@hookform/resolvers": "^3.10.0", "@mdxeditor/editor": "^3.42.0", "@radix-ui/react-alert-dialog": "^1.1.15", "@radix-ui/react-checkbox": "^1.3.3", @@ -34,6 +35,7 @@ "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.3.1", + "react-hook-form": "^7.54.2", "react-icons": "^5.5.0", "react-markdown": "^10.1.0", "react-router-dom": "^6.26.2", @@ -1709,6 +1711,15 @@ "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", "license": "MIT" }, + "node_modules/@hookform/resolvers": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.10.0.tgz", + "integrity": "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==", + "license": "MIT", + "peerDependencies": { + "react-hook-form": "^7.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", diff --git a/archon-ui-main/package.json b/archon-ui-main/package.json index 576b78ae..5a9f6c9d 100644 --- a/archon-ui-main/package.json +++ b/archon-ui-main/package.json @@ -54,6 +54,8 @@ "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.3.1", + "react-hook-form": "^7.54.2", + "@hookform/resolvers": "^3.10.0", "react-icons": "^5.5.0", "react-markdown": "^10.1.0", "react-router-dom": "^6.26.2", diff --git a/archon-ui-main/src/App.tsx b/archon-ui-main/src/App.tsx index 36e0d375..904ac41e 100644 --- a/archon-ui-main/src/App.tsx +++ b/archon-ui-main/src/App.tsx @@ -14,6 +14,8 @@ import { SettingsProvider, useSettings } from './contexts/SettingsContext'; import { TooltipProvider } from './features/ui/primitives/tooltip'; import { ProjectPage } from './pages/ProjectPage'; import StyleGuidePage from './pages/StyleGuidePage'; +import { AgentWorkOrdersPage } from './pages/AgentWorkOrdersPage'; +import { AgentWorkOrderDetailPage } from './pages/AgentWorkOrderDetailPage'; import { DisconnectScreenOverlay } from './components/DisconnectScreenOverlay'; import { ErrorBoundaryWithBugReport } from './components/bug-report/ErrorBoundaryWithBugReport'; import { MigrationBanner } from './components/ui/MigrationBanner'; @@ -43,6 +45,8 @@ const AppRoutes = () => { ) : ( } /> )} + } /> + } /> ); }; diff --git a/archon-ui-main/src/components/layout/Navigation.tsx b/archon-ui-main/src/components/layout/Navigation.tsx index 3547b5fb..3758ea14 100644 --- a/archon-ui-main/src/components/layout/Navigation.tsx +++ b/archon-ui-main/src/components/layout/Navigation.tsx @@ -1,4 +1,4 @@ -import { BookOpen, Palette, Settings } from "lucide-react"; +import { BookOpen, Bot, Palette, Settings } from "lucide-react"; import type React from "react"; import { Link, useLocation } from "react-router-dom"; // TEMPORARY: Use old SettingsContext until settings are migrated @@ -34,6 +34,12 @@ export function Navigation({ className }: NavigationProps) { label: "Knowledge Base", enabled: true, }, + { + path: "/agent-work-orders", + icon: , + label: "Agent Work Orders", + enabled: true, + }, { path: "/mcp", icon: ( diff --git a/archon-ui-main/src/features/agent-work-orders/components/CreateWorkOrderDialog.tsx b/archon-ui-main/src/features/agent-work-orders/components/CreateWorkOrderDialog.tsx new file mode 100644 index 00000000..a3ed9bf6 --- /dev/null +++ b/archon-ui-main/src/features/agent-work-orders/components/CreateWorkOrderDialog.tsx @@ -0,0 +1,237 @@ +/** + * CreateWorkOrderDialog Component + * + * Modal dialog for creating new agent work orders with form validation. + * Includes repository URL, sandbox type, user request, and command selection. + */ + +import { zodResolver } from "@hookform/resolvers/zod"; +import { useId, useState } from "react"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; +import { Button } from "@/features/ui/primitives/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/features/ui/primitives/dialog"; +import { useCreateWorkOrder } from "../hooks/useAgentWorkOrderQueries"; +import type { WorkflowStep } from "../types"; + +const workOrderSchema = z.object({ + repository_url: z.string().url("Must be a valid URL"), + sandbox_type: z.enum(["git_branch", "git_worktree"]), + user_request: z.string().min(10, "Request must be at least 10 characters"), + github_issue_number: z.string().optional(), +}); + +type WorkOrderFormData = z.infer; + +interface CreateWorkOrderDialogProps { + /** Whether dialog is open */ + open: boolean; + /** Callback when dialog should close */ + onClose: () => void; + /** Callback when work order is created */ + onSuccess?: (workOrderId: string) => void; +} + +const ALL_COMMANDS: WorkflowStep[] = ["create-branch", "planning", "execute", "commit", "create-pr"]; + +const COMMAND_LABELS: Record = { + "create-branch": "Create Branch", + planning: "Planning", + execute: "Execute", + commit: "Commit", + "create-pr": "Create PR", + "prp-review": "PRP Review", +}; + +export function CreateWorkOrderDialog({ open, onClose, onSuccess }: CreateWorkOrderDialogProps) { + const [selectedCommands, setSelectedCommands] = useState(ALL_COMMANDS); + const createWorkOrder = useCreateWorkOrder(); + const formId = useId(); + + const { + register, + handleSubmit, + formState: { errors }, + reset, + } = useForm({ + resolver: zodResolver(workOrderSchema), + defaultValues: { + sandbox_type: "git_branch", + }, + }); + + const handleClose = () => { + reset(); + setSelectedCommands(ALL_COMMANDS); + onClose(); + }; + + const onSubmit = async (data: WorkOrderFormData) => { + createWorkOrder.mutate( + { + ...data, + selected_commands: selectedCommands, + github_issue_number: data.github_issue_number || null, + }, + { + onSuccess: (result) => { + handleClose(); + onSuccess?.(result.agent_work_order_id); + }, + }, + ); + }; + + const toggleCommand = (command: WorkflowStep) => { + setSelectedCommands((prev) => (prev.includes(command) ? prev.filter((c) => c !== command) : [...prev, command])); + }; + + const setPreset = (preset: "full" | "planning" | "no-pr") => { + switch (preset) { + case "full": + setSelectedCommands(ALL_COMMANDS); + break; + case "planning": + setSelectedCommands(["create-branch", "planning"]); + break; + case "no-pr": + setSelectedCommands(["create-branch", "planning", "execute", "commit"]); + break; + } + }; + + return ( + + + + Create Agent Work Order + Configure and launch a new AI-driven development workflow + + +
+
+ + + {errors.repository_url &&

{errors.repository_url.message}

} +
+ +
+ + +
+ +
+ +