diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 1756cef..3a3867f 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -21,7 +21,10 @@ "Bash(https://n8n.oky.sh/api/v1/workflows )", "Bash(https://n8n.oky.sh/api/v1/workflows/tOdWpWVbsGUmP9QJ )", "Bash(https://n8n.oky.sh/api/v1/workflows/tOdWpWVbsGUmP9QJ/activate)", - "Bash(API_KEY=\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5YWM2MTg5ZC1kOWZiLTQ1N2UtODkzZS0yN2I5YWYzZmE3MzgiLCJpc3MiOiJuOG4iLCJhdWQiOiJwdWJsaWMtYXBpIiwiaWF0IjoxNzY0NjIxMTc4LCJleHAiOjE3NjcxMzIwMDB9.urB8gThO3nbFoLfXmvDs3BI6Qydx9JrTkWc9xU8iJQE\")" + "Bash(API_KEY=\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5YWM2MTg5ZC1kOWZiLTQ1N2UtODkzZS0yN2I5YWYzZmE3MzgiLCJpc3MiOiJuOG4iLCJhdWQiOiJwdWJsaWMtYXBpIiwiaWF0IjoxNzY0NjIxMTc4LCJleHAiOjE3NjcxMzIwMDB9.urB8gThO3nbFoLfXmvDs3BI6Qydx9JrTkWc9xU8iJQE\")", + "Bash(for id in CvKyoi6xFCJvEs78 EQ3pvaLgoVByu0vW Fuguumqhqv8sNqFY poCDP1AP1TVxj0CL rZa1luRls099lT81 sBwUfCBwgXAUj7eG)", + "Bash(do:*)", + "Bash(done:*)" ], "deny": [], "ask": [] diff --git a/N8N_OPENHANDS_WORKFLOW_FINAL.json b/N8N_OPENHANDS_WORKFLOW_FINAL.json deleted file mode 100644 index 8262853..0000000 --- a/N8N_OPENHANDS_WORKFLOW_FINAL.json +++ /dev/null @@ -1,247 +0,0 @@ -{ - "updatedAt": "2025-12-01T21:42:43.122Z", - "createdAt": "2025-12-01T21:42:43.020Z", - "id": "j1MmXaRhDjvkRSLa", - "name": "Gitea \u2192 OpenHands - FIXED WITH PASSTHROUGH", - "description": null, - "active": true, - "isArchived": false, - "nodes": [ - { - "parameters": { - "httpMethod": "POST", - "path": "openhands-fixed-test", - "options": {} - }, - "id": "webhook-trigger", - "name": "Gitea Webhook", - "type": "n8n-nodes-base.webhook", - "typeVersion": 1.1, - "position": [ - 240, - 300 - ], - "webhookId": "openhands-fixed-test" - }, - { - "parameters": { - "jsCode": "// CORRECT: Data is in $json.body\nconst payload = $json.body;\n\nconst repoName = payload.repository?.name || 'unknown';\nconst repoFullName = payload.repository?.full_name || 'unknown';\nconst repoCloneUrl = payload.repository?.clone_url || '';\nconst branch = payload.ref?.replace('refs/heads/', '') || 'main';\nconst commitSha = payload.after || '';\nconst commitMessage = payload.commits?.[0]?.message || 'No message';\nconst pusher = payload.pusher?.username || 'unknown';\n\nconst task = 'Build and test project ' + repoFullName + ' on branch ' + branch + '. ' +\n 'Latest commit: \"' + commitMessage + '\". ' +\n 'Clone the repository from ' + repoCloneUrl + ' and run: npm install && npm test && npm build. ' +\n 'Report any errors found.';\n\nreturn {\n repo_name: repoName,\n repo_full_name: repoFullName,\n repo_clone_url: repoCloneUrl,\n branch: branch,\n commit_sha: commitSha,\n commit_message: commitMessage,\n pusher: pusher,\n task: task,\n timestamp: new Date().toISOString(),\n status: 'PENDING',\n retry_count: 0\n};" - }, - "id": "extract-repo-info", - "name": "Extract Repo Info", - "type": "n8n-nodes-base.code", - "typeVersion": 2, - "position": [ - 460, - 300 - ] - }, - { - "parameters": { - "command": "={{ 'sh /home/bam/claude/mvp-factory/openhands-sdk-wrapper-sh.sh \"' + $json.task + '\"' }}", - "sessionId": "fixed-session", - "authentication": "privateKey", - "options": { - "passThrough": true - } - }, - "id": "execute-sdk-ssh", - "name": "Start OpenHands Build - FIXED", - "type": "n8n-nodes-base.ssh", - "typeVersion": 1, - "position": [ - 680, - 300 - ], - "credentials": { - "sshPrivateKey": { - "id": "v2BMXeCFGpXaoIyb", - "name": "SSH Private Key account" - } - } - }, - { - "parameters": { - "amount": 10, - "unit": "seconds" - }, - "id": "wait-initial", - "name": "Wait 10s for Initialization", - "type": "n8n-nodes-base.wait", - "typeVersion": 1.1, - "position": [ - 900, - 300 - ] - }, - { - "parameters": { - "jsCode": "// FIXED: Get repo data from previous node using $node\nconst sshOutput = $json;\nconst repoData = $node[\"Extract Repo Info\"].json;\n\n// Merge the SSH output with the original repo data\nreturn {\n ...repoData,\n code: sshOutput.code,\n signal: sshOutput.signal,\n stdout: sshOutput.stdout,\n stderr: sshOutput.stderr,\n status: 'SUCCESS',\n message: 'Build completed successfully',\n timestamp: new Date().toISOString()\n};" - }, - "id": "check-build-status", - "name": "Check Build Status - Data Check", - "type": "n8n-nodes-base.code", - "typeVersion": 2, - "position": [ - 1120, - 300 - ] - }, - { - "parameters": { - "jsCode": "// Format build response\nconst item = $json;\n\n// Log what we received for debugging\nconsole.log('Final item received:', JSON.stringify(item, null, 2));\n\nconst result = {\n status: item.status || 'SUCCESS',\n repo: item.repo_full_name || 'unknown',\n branch: item.branch || 'main',\n commit: item.commit_sha ? item.commit_sha.substring(0, 8) : 'N/A',\n message: item.message || 'Build completed',\n timestamp: new Date().toISOString(),\n retry_count: item.retry_count || 0\n};\n\n// Add emoji\nif (result.status === 'SUCCESS') {\n result.emoji = '\u2705';\n} else if (result.status === 'FAILED') {\n result.emoji = '\u274c';\n} else {\n result.emoji = '\u26a0\ufe0f';\n}\n\nreturn result;" - }, - "id": "format-response", - "name": "Format Build Response - FINAL", - "type": "n8n-nodes-base.code", - "typeVersion": 2, - "position": [ - 1340, - 300 - ] - }, - { - "parameters": { - "respondWith": "json", - "responseBody": "={{ $json }}", - "options": {} - }, - "id": "send-response", - "name": "Send Response", - "type": "n8n-nodes-base.respondToWebhook", - "typeVersion": 1.1, - "position": [ - 1560, - 300 - ] - } - ], - "connections": { - "Gitea Webhook": { - "main": [ - [ - { - "node": "Extract Repo Info", - "type": "main", - "index": 0 - } - ] - ] - }, - "Extract Repo Info": { - "main": [ - [ - { - "node": "Start OpenHands Build - FIXED", - "type": "main", - "index": 0 - } - ] - ] - }, - "Start OpenHands Build - FIXED": { - "main": [ - [ - { - "node": "Wait 10s for Initialization", - "type": "main", - "index": 0 - } - ] - ] - }, - "Wait 10s for Initialization": { - "main": [ - [ - { - "node": "Check Build Status - Data Check", - "type": "main", - "index": 0 - } - ] - ] - }, - "Check Build Status - Data Check": { - "main": [ - [ - { - "node": "Format Build Response - FINAL", - "type": "main", - "index": 0 - } - ] - ] - }, - "Format Build Response - FINAL": { - "main": [ - [ - { - "node": "Send Response", - "type": "main", - "index": 0 - } - ] - ] - } - }, - "settings": { - "executionOrder": "v1", - "callerPolicy": "workflowsFromSameOwner", - "availableInMCP": false - }, - "staticData": {}, - "meta": null, - "pinData": null, - "versionId": "e98dcf53-4f3e-4eee-8a18-6b7bc4ca7c70", - "versionCounter": 3, - "triggerCount": 1, - "shared": [ - { - "updatedAt": "2025-12-01T21:42:43.023Z", - "createdAt": "2025-12-01T21:42:43.023Z", - "role": "workflow:owner", - "workflowId": "j1MmXaRhDjvkRSLa", - "projectId": "18Ie3sGopJUKowvQ", - "project": { - "updatedAt": "2025-11-28T21:55:42.833Z", - "createdAt": "2025-11-28T21:54:40.915Z", - "id": "18Ie3sGopJUKowvQ", - "name": "pi raj ", - "type": "personal", - "icon": null, - "description": null, - "projectRelations": [ - { - "updatedAt": "2025-11-28T21:54:40.915Z", - "createdAt": "2025-11-28T21:54:40.915Z", - "userId": "9ac6189d-d9fb-457e-893e-27b9af3fa738", - "projectId": "18Ie3sGopJUKowvQ", - "user": { - "updatedAt": "2025-12-01T18:14:07.000Z", - "createdAt": "2025-11-28T21:54:40.486Z", - "id": "9ac6189d-d9fb-457e-893e-27b9af3fa738", - "email": "aidev@oky.sh", - "firstName": "pi", - "lastName": "raj", - "personalizationAnswers": { - "version": "v4", - "personalization_survey_submitted_at": "2025-11-28T21:55:59.720Z", - "personalization_survey_n8n_version": "1.121.3" - }, - "settings": { - "userActivated": true, - "firstSuccessfulWorkflowId": "hwbFEoEIgGyjV0He", - "userActivatedAt": 1764591198155 - }, - "disabled": false, - "mfaEnabled": false, - "lastActiveAt": "2025-12-01", - "isPending": false - } - } - ] - } - } - ], - "tags": [] -} \ No newline at end of file diff --git a/PHASE3-BUILD-TEST-WORKFLOW.md b/PHASE3-BUILD-TEST-WORKFLOW.md new file mode 100644 index 0000000..6db352e --- /dev/null +++ b/PHASE3-BUILD-TEST-WORKFLOW.md @@ -0,0 +1,395 @@ +# Phase 3: Build Test Workflow - Documentation + +**Status:** โœ… ACTIVE +**Workflow ID:** `EG9SCUWgbkdtr8Gm` +**Webhook URL:** `https://n8n.oky.sh/webhook/openhands-build-test` +**Created:** 2025-12-02 +**Active:** Yes + +--- + +## ๐ŸŽฏ Purpose + +Autonomous build/test system that: +- โœ… Executes builds automatically +- โœ… Detects failures +- โœ… Provides feedback to OpenHands +- โœ… Retries with improved instructions +- โœ… Updates commit status in Gitea +- โœ… Prevents infinite loops with max retry limit (3) + +--- + +## ๐Ÿ”„ Workflow Flow + +### High-Level Process + +``` +[1] Git Push (Developer) + โ†“ +[2] Filter OpenHands Commits (skip if message contains "openhands") + โ†“ +[3] Prepare Build Task (initialize retry counter) + โ†“ +[4] Execute OpenHands (run build/test) + โ†“ +[5] Analyze Build Result (check success/failure) + โ†“ +[6] Decision: Build Success? + โ”œโ”€ YES โ†’ [7] Update Gitea Success โ†’ [8] Respond + โ””โ”€ NO โ†’ [9] Check Retry Count + โ”œโ”€ < 3 โ†’ Back to [3] (retry with error feedback) + โ””โ”€ โ‰ฅ 3 โ†’ [8] Respond with failure +``` + +--- + +## ๐Ÿ“Š Node Details + +### 1. Gitea Webhook +- **Type:** Webhook Trigger +- **Path:** `openhands-build-test` +- **Method:** POST +- **Purpose:** Receives push events from Gitea + +### 2. Filter OpenHands Commits +- **Type:** Code Node +- **Purpose:** Detects commits made by OpenHands and skips them to prevent infinite loop +- **Logic:** + ```javascript + if (commitMsg.toLowerCase().includes('openhands')) { + return { skip: true, reason: 'OpenHands commit detected' }; + } + ``` + +### 3. Should Skip? +- **Type:** IF Node +- **Condition:** `skip === true` +- **Branches:** + - TRUE โ†’ Commit Skipped (exit workflow) + - FALSE โ†’ Prepare Build Task (continue) + +### 4. Prepare Build Task +- **Type:** Code Node +- **Purpose:** + - Increments retry counter using `$getWorkflowStaticData('global')` + - Checks if max retries (3) exceeded + - Builds task message with error feedback (if retry) +- **Retry Logic:** + ```javascript + staticData.retry_count = (staticData.retry_count || 0) + 1; + if (retryCount >= 3) { + return { action: 'FAIL', status: 'FAILED' }; + } + ``` + +### 5. Execute OpenHands +- **Type:** SSH Node +- **Command:** + ```bash + sh /home/bam/openhands-sdk-wrapper-sh.sh "" "" + ``` +- **Purpose:** Runs OpenHands SDK to build/test the project + +### 6. Analyze Build Result +- **Type:** Code Node +- **Purpose:** Determines if build succeeded or failed +- **Success Indicators:** + - Exit code = 0 + - Contains "passing", "โœ“", "PASS" + - Contains "success" or "build complete" +- **Failure Indicators:** + - Exit code โ‰  0 + - Contains "failing", "โœ—", "FAIL" + - Contains "error" in stderr + +### 7. Build Success? +- **Type:** IF Node +- **Condition:** `build_result.status === 'SUCCESS'` +- **Branches:** + - TRUE โ†’ Handle Success + - FALSE โ†’ Handle Failure + +### 8. Handle Success +- **Type:** Code Node +- **Purpose:** + - Formats success message + - Resets retry counter to 0 + - Returns completion status +- **Output:** + ```javascript + { + status: 'SUCCESS', + action: 'COMPLETED', + message: 'โœ… BUILD SUCCESSFUL', + retry_count: X, + build_result: {...} + } + ``` + +### 9. Update Gitea Success +- **Type:** SSH Node +- **Purpose:** Updates commit status in Gitea +- **API Call:** + ```bash + curl -X POST "https://git.oky.sh/api/v1/repos/{owner}/{repo}/statuses/{sha}" \ + -H "Authorization: token {GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"state\": \"success\", \"description\": \"Build successful after X attempt(s)\"}" + ``` + +### 10. Handle Failure +- **Type:** Code Node +- **Purpose:** + - Formats failure message with error details + - Calculates remaining retry attempts + - Determines if should retry or give up +- **Logic:** + ```javascript + const remaining = max_retries - retry_count; + const willRetry = remaining > 0; + return { + action: willRetry ? 'RETRY' : 'GIVE_UP', + will_retry: willRetry + }; + ``` + +### 11. Get Token +- **Type:** SSH Node +- **Purpose:** Reads Gitea API token from `/home/bam/.gitea_api_token` + +### 12. Commit Skipped +- **Type:** Code Node +- **Purpose:** Handles skipped OpenHands commits +- **Output:** + ```javascript + { + status: 'SKIPPED', + message: 'OpenHands commit - skipped to prevent loop' + } + ``` + +### 13. Respond +- **Type:** Respond to Webhook +- **Purpose:** Returns final response to webhook caller + +--- + +## ๐Ÿ” Retry Loop Flow + +### On Failure (retry_count < 3): +``` +Handle Failure โ†’ Prepare Build Task โ†’ Execute OpenHands โ†’ [LOOP] +``` + +**Task Message on Retry:** +``` +๐Ÿ”„ BUILD RETRY - Attempt 2/3 + +Previous build FAILED with errors: +[ERROR_DETAILS] + +Please fix these issues and rebuild the project in /home/bam/claude/[repo] + +Steps: +1. Analyze the errors above +2. Fix the code +3. Run tests (npm test or appropriate command) +4. If tests pass, commit with message: "OpenHands: Build successful" +``` + +### On Max Retries (retry_count >= 3): +``` +Handle Failure โ†’ Respond with GIVE_UP status +``` + +--- + +## ๐Ÿš€ How to Use + +### Step 1: Developer Pushes Code +```bash +cd /path/to/repo +git add . +git commit -m "Add new feature" +git push origin main +``` + +### Step 2: Webhook Triggered +- Gitea sends POST to `https://n8n.oky.sh/webhook/openhands-build-test` +- Workflow starts processing + +### Step 3: OpenHands Builds +- Executes in project directory +- Runs build commands (npm install, npm test, etc.) +- Commits fixes with message: "OpenHands: Build successful" + +### Step 4: Loop Prevention +- If OpenHands commits changes, workflow skips it (no infinite loop) +- Only processes commits from developers + +### Step 5: Status Updates +- **Success:** Gitea commit status = โœ… success +- **Failure:** After 3 attempts, status = โŒ failure + +--- + +## ๐Ÿ“ Testing + +### Manual Test +```bash +curl -X POST https://n8n.oky.sh/webhook/openhands-build-test \ + -H "Content-Type: application/json" \ + -d '{ + "repository": { + "name": "phase3-test", + "full_name": "gitadmin/phase3-test" + }, + "ref": "refs/heads/main", + "after": "abc123", + "commits": [{"message": "Test commit"}] + }' +``` + +### Real Repository Test +1. Make changes to `/home/bam/claude/phase3-test/` +2. Commit with message: "Test build" +3. Push to Gitea +4. Watch workflow execute +5. Check logs in `/home/bam/claude/phase3-test/openhands-task.log` + +--- + +## ๐Ÿ” Configuration + +### Required Files +- **OpenHands SDK:** `/tmp/software-agent-sdk` +- **Wrapper Script:** `/home/bam/openhands-sdk-wrapper-sh.sh` +- **Gitea Token:** `/home/bam/.gitea_api_token` +- **SSH Key:** `/home/bam/.ssh/n8n_key` + +### Environment Variables +- OpenHands API keys in `/home/bam/openhands/.env` +- MiniMax API key configured +- DeepSeek API key configured + +--- + +## ๐Ÿ“Š Logging + +### Log Files +- **Task Log:** `/home/bam/claude/phase3-test/openhands-task.log` (clean summary) +- **Full Log:** `/home/bam/claude/phase3-test/openhands-full.log` (detailed) + +### Log Contents +**openhands-task.log:** +``` +======================================== +OpenHands Task Summary: Tue Dec 2 02:30:13 PM UTC 2025 +======================================== + +TASK TO EXECUTE: +[Task description] + +FILES CREATED/MODIFIED: +[File operations] + +COMMANDS EXECUTED: +[Commands run] + +RESULT: SUCCESS +``` + +--- + +## โš™๏ธ Workflow Settings + +- **Execution Order:** v1 +- **Caller Policy:** workflowsFromSameOwner +- **Available in MCP:** false +- **Active:** true + +--- + +## ๐Ÿ”ง Troubleshooting + +### Issue: Workflow Not Triggered +- Check Gitea webhook configuration +- Verify webhook URL is correct +- Check n8n logs for errors + +### Issue: OpenHands Not Creating Files +- Verify workspace directory exists +- Check SSH credentials +- Review OpenHands logs + +### Issue: Infinite Loop +- Ensure commit messages contain "OpenHands" when committing +- Check filter logic is working + +### Issue: Gitea Status Not Updated +- Verify Gitea API token is valid +- Check token permissions +- Ensure token is in `/home/bam/.gitea_api_token` + +--- + +## ๐Ÿ“ˆ Monitoring + +### Check Workflow Status +```bash +# List workflows +curl -s https://n8n.oky.sh/api/v1/workflows \ + -H "X-N8N-API-KEY: $(cat /home/bam/.n8n_api_key)" \ + | jq '.data[] | select(.id=="EG9SCUWgbkdtr8Gm") | {name, active, updatedAt}' + +# Check execution history +curl -s https://n8n.oky.sh/api/v1/workflow-runs?workflowId=EG9SCUWgbkdtr8Gm \ + -H "X-N8N-API-KEY: $(cat /home/bam/.n8n_api_key)" +``` + +### View Logs +```bash +# Task log +tail -f /home/bam/claude/phase3-test/openhands-task.log + +# Full log +tail -f /home/bam/claude/phase3-test/openhands-full.log +``` + +--- + +## โœ… Success Criteria + +- [x] Workflow created and activated +- [x] Loop prevention working (skips OpenHands commits) +- [x] Retry logic implemented (max 3 attempts) +- [x] Error feedback provided to OpenHands +- [x] Gitea status updates working +- [x] Logging system operational +- [x] End-to-end test passing + +--- + +## ๐ŸŽ‰ Conclusion + +The Phase 3 Build Test Workflow is now fully operational! It provides autonomous build/test capabilities similar to agent.minimax.io, with proper loop prevention and retry logic. + +**Key Features:** +- Automatic build and test execution +- Intelligent retry with error feedback +- Loop prevention for OpenHands commits +- Gitea commit status integration +- Comprehensive logging +- Max 3 retry attempts to prevent infinite loops + +**Next Steps:** +1. Test with real repository changes +2. Monitor workflow executions +3. Adjust build commands as needed for different project types + +--- + +**Created:** 2025-12-02 +**Status:** โœ… Production Ready +**Documentation Version:** 1.0 diff --git a/phase3-code-snippets.md b/phase3-code-snippets.md new file mode 100644 index 0000000..82986c6 --- /dev/null +++ b/phase3-code-snippets.md @@ -0,0 +1,398 @@ +# Phase 3: Ready-to-Copy Code Snippets + +## ๐Ÿ“‹ Node 3: Initialize Retry Counter + +```javascript +// Initialize retry counter in workflow staticData +$workflow.staticData = $workflow.staticData || {}; + +// Initialize or increment retry count +$workflow.staticData.retry_count = ($workflow.staticData.retry_count || 0); + +// Preserve repo data from previous node +const repoData = $node["Extract Repo Info"].json; + +return { + ...repoData, + retry_count: 0, + status: 'INITIALIZED', + attempt: 1 +}; +``` + +--- + +## ๐Ÿ“‹ Node 4: Execute OpenHands Build (Enhanced) + +### Part A: Command (in SSH node) + +```javascript +// Enhanced task with retry feedback +const repoData = $node["Extract Repo Info"].json; +const retryCount = $node["Initialize Retry Counter"].json.retry_count; +const buildDir = `/workspace/${repoData.repo_name}`; + +// Base task +let task = `Build and test the project at ${buildDir}. + +Execute the following steps: +1. cd ${buildDir} +2. If package.json exists: npm install +3. If build script exists: npm run build +4. Report build status (success/failure) +5. Capture and report any errors + +Repository: ${repoData.repo_name} +Branch: ${repoData.branch} +Commit: ${repoData.commit_sha.substring(0, 8)} +`; + +// Add feedback if this is a retry +if (retryCount > 0) { + const previousOutput = $node["Check Build Results"].json; + const errorDetails = previousOutput?.error_message || 'Unknown error'; + + task += ` + +PREVIOUS BUILD FAILED (Attempt ${retryCount}): +Error Details: +${errorDetails} + +Please analyze the previous errors and fix them. Be thorough and ensure all issues are resolved before attempting the build again. + +This is retry attempt #${retryCount + 1}. Please be extremely careful and fix ALL problems.`; +} + +// Execute via SDK wrapper +return `sh /home/bam/openhands-sdk-wrapper-sh.sh "${task.replace(/"/g, '\\"')}"`; +``` + +### Part B: Data Preservation (below the command in same SSH node) + +```javascript +const sshOutput = $json; +const repoData = $node["Extract Repo Info"].json; +const retryCount = $node["Initialize Retry Counter"].json.retry_count; + +return { + ...repoData, // Preserve repository data + code: sshOutput.code, + stdout: sshOutput.stdout, + stderr: sshOutput.stderr, + status: sshOutput.code === 0 ? 'SUCCESS' : 'FAILED', + retry_count: retryCount, + attempt: retryCount + 1 +}; +``` + +--- + +## ๐Ÿ“‹ Node 6: Evaluate Build Results + +```javascript +// Get OpenHands output +const openhandsOutput = $json; + +// Determine success/failure +const buildSuccess = openhandsOutput.code === 0; + +// Collect errors if build failed +let errorDetails = ''; +if (!buildSuccess) { + // Prefer stderr, fallback to stdout + errorDetails = openhandsOutput.stderr || openhandsOutput.stdout || 'Build failed with no error output'; +} + +// Return structured results +return { + ...openhandsOutput, // Preserve all data + build_success: buildSuccess, + error_details: errorDetails, + timestamp: new Date().toISOString() +}; +``` + +--- + +## ๐Ÿ“‹ Node 8: Update Gitea Success (HTTP Node) + +### Configuration Tab: + +**Method:** POST +**URL:** +``` +https://git.oky.sh/api/v1/repos/{{ $node["Extract Repo Info"].json.owner }}/{{ $node["Extract Repo Info"].json.repo_name }}/statuses/{{ $node["Extract Repo Info"].json.commit_sha }} +``` + +**Headers:** +- **Header 1:** + - Name: `X-Gitea-Token` + - Value: `{YOUR_GITEA_API_TOKEN}` +- **Header 2:** + - Name: `Content-Type` + - Value: `application/json` + +**Body:** +```json +{ + "state": "success", + "description": "โœ… Build passed after {{ $node["Initialize Retry Counter"].json.retry_count }} attempt(s)", + "context": "openhands/autonomous-build", + "target_url": "https://n8n.oky.sh" +} +``` + +### Response Handling (in Code mode): + +```javascript +// Preserve data and add Gitea response +const giteaResponse = $json; +const previousData = $node["Extract Repo Info"].json; + +return { + ...previousData, + gitea_status: 'success', + gitea_response: giteaResponse, + final_status: 'SUCCESS', + build_success: true +}; +``` + +--- + +## ๐Ÿ“‹ Node 9: Format Error for Retry + +```javascript +// Get build results and repo data +const buildResults = $node["Check Build Results"].json; +const repoData = $node["Extract Repo Info"].json; +const retryCount = $node["Initialize Retry Counter"].json.retry_count; + +// Format comprehensive error message +const errorMsg = `Build failed with the following errors: + +REPOSITORY: ${repoData.repo_name} +BRANCH: ${repoData.branch} +COMMIT: ${repoData.commit_sha.substring(0, 8)} +ATTEMPT: ${retryCount + 1}/3 + +ERROR DETAILS: +${buildResults.error_details} + +BUILD OUTPUT (stderr): +${buildResults.stderr || 'No stderr output'} + +BUILD OUTPUT (stdout): +${buildResults.stdout || 'No stdout output'} + +NEXT STEPS: +Please analyze these errors and fix all issues to ensure a successful build. +Focus on: +1. Dependency issues (npm install errors) +2. Build script failures +3. Code syntax errors +4. Configuration problems + +After fixing, the project should build successfully with: npm install && npm run build + +This is attempt ${retryCount + 1} of 3. You have ${2 - retryCount} retry(s) remaining.`; + +return { + ...repoData, + ...buildResults, + status: 'FAILED', + error_message: errorMsg, + retry_count: retryCount, + can_retry: retryCount < 2, // < 3 total attempts + formatted_error: errorMsg +}; +``` + +--- + +## ๐Ÿ“‹ Node 11: Final Response + +### For Success Path: + +```javascript +// Format success response +const repoData = $node["Extract Repo Info"].json; +const retryCount = $node["Initialize Retry Counter"].json.retry_count; + +const successResponse = { + status: 'SUCCESS', + repo: repoData.repo_name, + branch: repoData.branch, + commit: repoData.commit_sha.substring(0, 8), + attempts: retryCount + 1, + message: 'Build completed successfully โœ…', + timestamp: new Date().toISOString(), + gitea_status: 'success' +}; + +return successResponse; +``` + +### For Failure Path: + +```javascript +// Format failure response +const repoData = $node["Extract Repo Info"].json; +const errorData = $node["Format Error for Retry"].json; + +const failureResponse = { + status: 'FAILED', + repo: repoData.repo_name, + branch: repoData.branch, + commit: repoData.commit_sha.substring(0, 8), + attempts: errorData.retry_count + 1, + max_attempts: 3, + message: 'Build failed after 3 attempts โŒ', + errors: errorData.error_details, + timestamp: new Date().toISOString(), + gitea_status: 'failure', + next_steps: 'Please review the error messages and fix the issues manually before pushing again.' +}; + +return failureResponse; +``` + +--- + +## ๐Ÿ“‹ HTTP Response Node + +```javascript +const response = $json; +return [ + { + statusCode: response.status === 'SUCCESS' ? 200 : 500, + body: response + } +]; +``` + +--- + +## ๐Ÿ”ง Decision Node Configurations + +### Node 7: "Build OK?" (IF Node) + +**Mode:** Expression +**Value 1:** +``` +{{ $json.build_success }} +``` +**Operation:** Equal +**Value 2:** +``` +true +``` + +### Node 10: "Can We Retry?" (IF Node) + +**Mode:** Expression +**Value 1:** +``` +{{ $json.can_retry }} +``` +**Operation:** Equal +**Value 2:** +``` +true +``` + +--- + +## ๐Ÿ“‹ Quick Setup Commands + +### Generate Gitea Token + +```bash +# Method 1: API (requires admin token) +curl -X POST https://git.oky.sh/api/v1/users/gitadmin/tokens \ + -H "X-Gitea-Token: {ADMIN_TOKEN_HERE}" \ + -H "Content-Type: application/json" \ + -d '{"name": "n8n-autonomous-build", "scopes": ["repo", "admin:repo_hook"]}' + +# Method 2: UI +# 1. https://git.oky.sh/user/settings/applications +# 2. Generate Token โ†’ n8n-autonomous-build +# 3. Copy token (format: gho_...) +``` + +### Store Token Securely + +```bash +echo "GITEA_API_TOKEN=gho_your_token_here" > /home/bam/.gitea_token +chmod 600 /home/bam/.gitea_token +``` + +--- + +## ๐Ÿงช Test Commands + +### Test Workflow Manually + +```bash +curl -X POST https://n8n.oky.sh/webhook/openhands-autonomous-build \ + -H "Content-Type: application/json" \ + -d '{ + "repository": { + "name": "test-project", + "full_name": "gitadmin/test-project", + "owner": {"name": "gitadmin", "username": "gitadmin"} + }, + "ref": "refs/heads/main", + "after": "abc123def456789012345678901234567890abcd", + "pusher": {"name": "testuser"} + }' +``` + +### Create Test Repository + +```bash +curl -X POST https://git.oky.sh/api/v1/user/repos \ + -H "X-Gitea-Token: {YOUR_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "autonomous-build-test", + "description": "Phase 3 test repository" + }' +``` + +--- + +## โœ… Implementation Checklist + +### Before Starting + +- [ ] Read phase3-implementation-plan.md +- [ ] Generate Gitea API token +- [ ] Store token in secure location +- [ ] Have test repository ready + +### During Implementation + +- [ ] Add Node 3: Initialize Retry Counter +- [ ] Modify Node 2: Extract Repo Info (add fields) +- [ ] Modify Node 4: Enhance OpenHands Build command + data preservation +- [ ] Modify Node 5: Ensure Wait is 10s +- [ ] Modify Node 6: Update Check Build Results +- [ ] Add Node 7: Decision - Build OK? +- [ ] Add Node 8: Update Gitea Success +- [ ] Add Node 9: Format Error for Retry +- [ ] Add Node 10: Check Retry Count +- [ ] Modify Node 11: Final Response (both paths) +- [ ] Update HTTP Response + +### After Implementation + +- [ ] Test success path +- [ ] Test retry with fixable errors +- [ ] Test max retries (3 attempts) +- [ ] Test with real project +- [ ] Verify Gitea status updates + +--- + +**Ready to copy & paste! ๐Ÿš€** diff --git a/phase3-implementation-plan.md b/phase3-implementation-plan.md new file mode 100644 index 0000000..9bed235 --- /dev/null +++ b/phase3-implementation-plan.md @@ -0,0 +1,862 @@ +# Phase 3 Implementation Plan: Autonomous Build Test MVP + +**Date:** 2025-12-02 +**Estimated Duration:** 4-5 hours +**Current Workflow:** ID j1MmXaRhDjvkRSLa (7 nodes) โ†’ Target: 11 nodes + +--- + +## ๐Ÿ“‹ EXECUTIVE SUMMARY + +Transform the current 7-node basic workflow into a production-ready autonomous CI/CD system with: +- Retry logic (max 3 attempts) +- Error feedback to OpenHands +- Gitea commit status updates +- Real project build testing + +**Current State:** +- โœ… Workflow active: `j1MmXaRhDjvkRSLa` +- โœ… SSH credentials configured: `/home/bam/.ssh/n8n_key` +- โœ… OpenHands SDK wrapper: `/home/bam/openhands-sdk-wrapper-sh.sh` +- โœ… API keys available: MiniMax & DeepSeek + +--- + +## ๐ŸŽฏ IMPLEMENTATION ROADMAP + +### Phase 3 Workflow Design (11 Nodes) + +``` +[1] Gitea Webhook (existing) + โ†“ +[2] Extract Repo Info (modify existing) + โ†“ +[3] Initialize Retry Counter (NEW) + โ†“ +[4] Start OpenHands Build (modify existing) + โ†“ +[5] Wait for Completion (modify existing) + โ†“ +[6] Check Build Results (modify existing) + โ†“ +[7] Decision: Build OK? (NEW) + โ”œโ”€ YES โ†’ [8] Update Gitea Success โ†’ [11] Success Response + โ””โ”€ NO โ†’ [9] Format Error Feedback (NEW) + โ†“ + [10] Check Retry Count (NEW) + โ”œโ”€ < 3 โ†’ Loop back to [4] + โ””โ”€ โ‰ฅ 3 โ†’ Update Gitea Failure โ†’ [11] Final Failure +``` + +--- + +## ๐Ÿ“ STEP-BY-STEP IMPLEMENTATION + +### STEP 1: Setup Test Repository (20 min) + +**Action:** Create a test repository with intentional build errors + +```bash +# Via Gitea API +curl -X POST https://git.oky.sh/api/v1/user/repos \ + -H "X-Gitea-Token: {YOUR_GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "autonomous-build-test", + "description": "Phase 3 test repository with intentional errors", + "private": false + }' + +# Alternative: Use Gitea UI +# 1. Go to https://git.oky.sh +# 2. Click "+" โ†’ New Repository +# 3. Name: autonomous-build-test +# 4. Create with sample Node.js project +``` + +**Sample Test Files:** + +`package.json` (with intentional error): +```json +{ + "name": "autonomous-build-test", + "version": "1.0.0", + "scripts": { + "build": "node build.js" + }, + "dependencies": { + "express": "^4.18.2" + } +} +``` + +`build.js` (intentional syntax error): +```javascript +// This will fail - missing closing brace +const express = require('express'); +const app = express(); + +app.get('/', (req, res) => { + res.send('Hello World!' + // Missing closing brace +}); + +app.listen(3000); +console.log('Server running'); +``` + +### STEP 2: Configure Gitea Webhook (15 min) + +**Action:** Set up webhook to trigger n8n workflow + +1. **Go to Repository Settings:** + - Navigate to: https://git.oky.sh/gitadmin/autonomous-build-test + - Settings โ†’ Webhooks + +2. **Add Webhook:** + - URL: `https://n8n.oky.sh/webhook/openhands-autonomous-build` + - Trigger: Push events + - HTTP Method: POST + - Active: โœ“ + - Save + +3. **Test Webhook:** + - Click "Test Delivery" + - Should see 200 OK response + +### STEP 3: Modify n8n Workflow Structure (60 min) + +**Current Workflow (7 nodes):** +``` +1. Gitea Webhook +2. Extract Repo Info +3. Start OpenHands Build +4. Wait 10s +5. Check Build Status +6. Format Response +7. Send Response +``` + +**Target Workflow (11 nodes):** + +#### Node 1: Gitea Webhook โœ… (Existing) +**Configuration:** +- Path: `/webhook/openhands-autonomous-build` +- HTTP Method: POST +- No changes needed + +#### Node 2: Extract Repo Info โœ… (Modify Existing) +**Current Code:** +```javascript +// Keep existing code, add repo info extraction +const data = $json; + +// Extract repository information +const repoData = { + repo_name: data.repository?.name || 'unknown', + repo_full_name: data.repository?.full_name || 'unknown', + owner: data.repository?.owner?.name || data.repository?.owner?.username || 'unknown', + branch: data.ref?.replace('refs/heads/', '') || 'main', + commit_sha: data.after || 'unknown', + pusher: data.pusher?.name || 'unknown' +}; + +return repoData; +``` + +**Changes:** Add `repo_name`, `owner`, `branch`, `commit_sha` fields + +#### Node 3: Initialize Retry Counter (NEW) +**Type:** Code Node +**Name:** "Initialize Retry Counter" + +**Code:** +```javascript +// Initialize retry counter in workflow staticData +$workflow.staticData = $workflow.staticData || {}; + +// Initialize or increment retry count +$workflow.staticData.retry_count = ($workflow.staticData.retry_count || 0); + +// Preserve repo data from previous node +const repoData = $node["Extract Repo Info"].json; + +return { + ...repoData, + retry_count: 0, + status: 'INITIALIZED', + attempt: 1 +}; +``` + +**Configuration:** +- Execute Once: False (important for retry loops) + +#### Node 4: Start OpenHands Build (Modify Existing) +**Type:** SSH Node +**Name:** "Execute OpenHands Build" + +**Configuration:** +``` +Authentication: Private Key +Host: localhost +User: bam +Private Key: /home/bam/.ssh/n8n_key +Timeout: 300000 (5 minutes) +``` + +**Command (JavaScript - Enhanced with feedback):** +```javascript +// Enhanced task with retry feedback +const repoData = $node["Extract Repo Info"].json; +const retryCount = $node["Initialize Retry Counter"].json.retry_count; +const buildDir = `/workspace/${repoData.repo_name}`; + +// Base task +let task = `Build and test the project at ${buildDir}. + +Execute the following steps: +1. cd ${buildDir} +2. If package.json exists: npm install +3. If build script exists: npm run build +4. Report build status (success/failure) +5. Capture and report any errors + +Repository: ${repoData.repo_name} +Branch: ${repoData.branch} +Commit: ${repoData.commit_sha.substring(0, 8)} +`; + +// Add feedback if this is a retry +if (retryCount > 0) { + const previousOutput = $node["Check Build Results"].json; + const errorDetails = previousOutput?.error_message || 'Unknown error'; + + task += ` + +PREVIOUS BUILD FAILED (Attempt ${retryCount}): +Error Details: +${errorDetails} + +Please analyze the previous errors and fix them. Be thorough and ensure all issues are resolved before attempting the build again. + +This is retry attempt #${retryCount + 1}. Please be extremely careful and fix ALL problems.`; +} + +// Execute via SDK wrapper +return `sh /home/bam/openhands-sdk-wrapper-sh.sh "${task.replace(/"/g, '\\"')}"`; +``` + +**Data Preservation (CRITICAL):** +```javascript +const sshOutput = $json; +const repoData = $node["Extract Repo Info"].json; +const retryCount = $node["Initialize Retry Counter"].json.retry_count; + +return { + ...repoData, // Preserve repository data + code: sshOutput.code, + stdout: sshOutput.stdout, + stderr: sshOutput.stderr, + status: sshOutput.code === 0 ? 'SUCCESS' : 'FAILED', + retry_count: retryCount, + attempt: retryCount + 1 +}; +``` + +#### Node 5: Wait for Completion (Modify Existing) +**Type:** Wait Node +**Name:** "Wait for Build Completion" + +**Configuration:** +- Amount: 10 +- Unit: Seconds +- No changes to existing configuration + +#### Node 6: Check Build Results (Modify Existing) +**Type:** Code Node +**Name:** "Evaluate Build Results" + +**Code:** +```javascript +// Get OpenHands output +const openhandsOutput = $json; + +// Determine success/failure +const buildSuccess = openhandsOutput.code === 0; + +// Collect errors if build failed +let errorDetails = ''; +if (!buildSuccess) { + // Prefer stderr, fallback to stdout + errorDetails = openhandsOutput.stderr || openhandsOutput.stdout || 'Build failed with no error output'; +} + +// Return structured results +return { + ...openhandsOutput, // Preserve all data + build_success: buildSuccess, + error_details: errorDetails, + timestamp: new Date().toISOString() +}; +``` + +#### Node 7: Decision: Build OK? (NEW) +**Type:** IF Node +**Name:** "Decision: Build Success?" + +**Configuration:** +``` +Condition: JSON +Value 1: {{ $json.build_success }} +Operation: Equal +Value 2: true +``` + +**True Path (YES):** โ†’ Node 8 (Update Gitea Success) +**False Path (NO):** โ†’ Node 9 (Format Error Feedback) + +#### Node 8: Update Gitea Success (NEW) +**Type:** HTTP Request Node +**Name:** "Update Gitea - Success" + +**Configuration:** +``` +Method: POST +URL: https://git.oky.sh/api/v1/repos/{{ $node["Extract Repo Info"].json.owner }}/{{ $node["Extract Repo Info"].json.repo_name }}/statuses/{{ $node["Extract Repo Info"].json.commit_sha }} +Headers: + - X-Gitea-Token: {YOUR_GITEA_API_TOKEN} + - Content-Type: application/json + +Body: +{ + "state": "success", + "description": "โœ… Build passed after {{ $node["Initialize Retry Counter"].json.retry_count }} attempt(s)", + "context": "openhands/autonomous-build", + "target_url": "https://n8n.oky.sh" +} +``` + +**Response Handling:** +```javascript +// Preserve data and add Gitea response +const giteaResponse = $json; +const previousData = $node["Extract Repo Info"].json; + +return { + ...previousData, + gitea_status: 'success', + gitea_response: giteaResponse, + final_status: 'SUCCESS', + build_success: true +}; +``` + +#### Node 9: Format Error Feedback (NEW) +**Type:** Code Node +**Name:** "Format Error for Retry" + +**Code:** +```javascript +// Get build results and repo data +const buildResults = $node["Check Build Results"].json; +const repoData = $node["Extract Repo Info"].json; +const retryCount = $node["Initialize Retry Counter"].json.retry_count; + +// Format comprehensive error message +const errorMsg = `Build failed with the following errors: + +REPOSITORY: ${repoData.repo_name} +BRANCH: ${repoData.branch} +COMMIT: ${repoData.commit_sha.substring(0, 8)} +ATTEMPT: ${retryCount + 1}/3 + +ERROR DETAILS: +${buildResults.error_details} + +BUILD OUTPUT (stderr): +${buildResults.stderr || 'No stderr output'} + +BUILD OUTPUT (stdout): +${buildResults.stdout || 'No stdout output'} + +NEXT STEPS: +Please analyze these errors and fix all issues to ensure a successful build. +Focus on: +1. Dependency issues (npm install errors) +2. Build script failures +3. Code syntax errors +4. Configuration problems + +After fixing, the project should build successfully with: npm install && npm run build + +This is attempt ${retryCount + 1} of 3. You have ${2 - retryCount} retry(s) remaining.`; +``` + +**Return:** +```javascript +return { + ...repoData, + ...buildResults, + status: 'FAILED', + error_message: errorMsg, + retry_count: retryCount, + can_retry: retryCount < 2, // < 3 total attempts + formatted_error: errorMsg +}; +``` + +#### Node 10: Check Retry Count (NEW) +**Type:** IF Node +**Name:** "Can We Retry?" + +**Configuration:** +``` +Condition: JSON +Value 1: {{ $json.can_retry }} +Operation: Equal +Value 2: true +``` + +**True Path (YES - Can Retry):** โ†’ Loop back to Node 4 +**False Path (NO - Max Retries):** โ†’ Node 11 (Final Failure) + +#### Node 11: Final Response (Modify Existing) +**Type:** Code Node +**Name:** "Final Response" + +**Success Path Code:** +```javascript +// Format success response +const repoData = $node["Extract Repo Info"].json; +const retryCount = $node["Initialize Retry Counter"].json.retry_count; + +const successResponse = { + status: 'SUCCESS', + repo: repoData.repo_name, + branch: repoData.branch, + commit: repoData.commit_sha.substring(0, 8), + attempts: retryCount + 1, + message: 'Build completed successfully โœ…', + timestamp: new Date().toISOString(), + gitea_status: 'success' +}; + +return successResponse; +``` + +**Failure Path Code:** +```javascript +// Format failure response +const repoData = $node["Extract Repo Info"].json; +const errorData = $node["Format Error for Retry"].json; + +const failureResponse = { + status: 'FAILED', + repo: repoData.repo_name, + branch: repoData.branch, + commit: repoData.commit_sha.substring(0, 8), + attempts: errorData.retry_count + 1, + max_attempts: 3, + message: 'Build failed after 3 attempts โŒ', + errors: errorData.error_details, + timestamp: new Date().toISOString(), + gitea_status: 'failure', + next_steps: 'Please review the error messages and fix the issues manually before pushing again.' +}; + +return failureResponse; +``` + +**HTTP Response Node:** +```javascript +const response = $json; +return [ + { + statusCode: response.status === 'SUCCESS' ? 200 : 500, + body: response + } +]; +``` + +--- + +## ๐Ÿ”ง CONFIGURATION CHECKLIST + +### Credentials Required + +- [ ] **n8n API Key:** `/home/bam/.n8n_api_key` โœ… +- [ ] **SSH Key:** `/home/bam/.ssh/n8n_key` โœ… +- [ ] **OpenHands API Keys:** `/home/bam/openhands/.env` โœ… +- [ ] **Gitea API Token:** โš ๏ธ NEED TO GENERATE + +### Generate Gitea API Token + +```bash +# Via Gitea API (or use UI) +curl -X POST https://git.oky.sh/api/v1/users/gitadmin/tokens \ + -H "X-Gitea-Token: {ADMIN_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "n8n-autonomous-build", + "scopes": ["repo", "admin:repo_hook"] + }' + +# OR via UI: +# 1. Go to https://git.oky.sh/user/settings/applications +# 2. Click "Generate Token" +# 3. Name: n8n-autonomous-build +# 4. Scopes: repo, admin:repo_hook +# 5. Copy token (will look like: gho_xxxxxxxxxxxxxxxxx) +``` + +Store token securely: +```bash +echo "GITEA_API_TOKEN=gho_xxxxxxxxxxxxxxxxx" > /home/bam/.gitea_token +chmod 600 /home/bam/.gitea_token +``` + +--- + +## ๐Ÿงช TESTING STRATEGY + +### Test 1: Success Path (30 min) + +**Setup:** +```bash +# Create clean test repo +git clone https://git.oky.sh/gitadmin/test-success.git +cd test-success + +# Create valid package.json +cat > package.json << 'EOF' +{ + "name": "test-success", + "version": "1.0.0", + "scripts": { + "build": "echo 'Build successful'" + } +} +EOF + +# Create simple build script +cat > build.js << 'EOF' +console.log('Build completed successfully!'); +process.exit(0); +EOF + +# Commit and push +git add . +git commit -m "Test successful build" +git push origin main +``` + +**Expected Results:** +1. Webhook triggered โœ… +2. Workflow executes โœ… +3. OpenHands builds successfully โœ… +4. Gitea status: "success" โœ… +5. Response: 200 OK โœ… + +**Success Criteria:** +```json +{ + "status": "SUCCESS", + "attempts": 1, + "gitea_status": "success" +} +``` + +### Test 2: Retry Logic with Fixable Errors (45 min) + +**Setup:** +```bash +# Clone test repo +git clone https://git.oky.sh/gitadmin/autonomous-build-test.git +cd autonomous-build-test + +# Fix the syntax error in build.js +cat > build.js << 'EOF' +// Fixed version - proper closing braces +const express = require('express'); +const app = express(); + +app.get('/', (req, res) => { + res.send('Hello World!'); // Now properly closed +}); + +app.listen(3000, () => { + console.log('Server running'); +}); +EOF + +# Commit and push +git add . +git commit -m "Fix: Corrected syntax errors in build.js" +git push origin main +``` + +**Expected Flow:** +1. **1st Attempt:** Fails (syntax error) +2. **2nd Attempt:** OpenHands receives feedback, fixes error +3. **3rd Attempt:** Succeeds โœ… + +**Success Criteria:** +```json +{ + "status": "SUCCESS", + "attempts": 3, + "message": "Build completed successfully โœ…", + "gitea_status": "success" +} +``` + +### Test 3: Max Retries with Persistent Errors (45 min) + +**Setup:** +```bash +# Force persistent error +cat > build.js << 'EOF' +// This will always fail +console.error('Intentional error - will not fix'); +process.exit(1); +EOF + +git add . +git commit -m "Test: Persistent error (should fail after 3 attempts)" +git push origin main +``` + +**Expected Flow:** +1. **1st Attempt:** Fails +2. **2nd Attempt:** Fails +3. **3rd Attempt:** Fails +4. **Stops:** Max retries exceeded โŒ + +**Success Criteria:** +```json +{ + "status": "FAILED", + "attempts": 3, + "max_attempts": 3, + "message": "Build failed after 3 attempts โŒ", + "gitea_status": "failure" +} +``` + +### Test 4: Real Project Build (45 min) + +**Setup:** +Use actual MVP project: +```bash +# Clone real project +git clone https://git.oky.sh/gitadmin/mvp-project.git +cd mvp-project + +# Make a small change +echo "// Test change" >> README.md + +# Commit and push +git add . +git commit -m "Test: Trigger autonomous build" +git push origin main +``` + +**Success Criteria:** +- OpenHands executes full build +- Dependencies installed correctly +- Build completes or fails with clear errors +- Retry logic works if needed + +--- + +## ๐Ÿšจ TROUBLESHOOTING GUIDE + +### Issue 1: Retry Count Always 0 + +**Symptom:** Workflow doesn't retry, always shows attempt 1 + +**Solution:** Check Node 3 configuration +```javascript +// MUST initialize staticData +$workflow.staticData = $workflow.staticData || {}; +$workflow.staticData.retry_count = ($workflow.staticData.retry_count || 0) + 1; +``` + +### Issue 2: Gitea Status Not Updating + +**Symptom:** Commit status stays "pending" or doesn't appear + +**Diagnosis:** +```bash +# Check token permissions +curl -H "X-Gitea-Token: {YOUR_TOKEN}" \ + https://git.oky.sh/api/v1/user + +# Should return user info +``` + +**Solution:** +1. Ensure token has "repo" scope +2. Check URL format: `/api/v1/repos/{owner}/{repo}/statuses/{sha}` +3. Verify commit_sha is correct (40 character SHA) + +### Issue 3: Workflow Hangs After OpenHands + +**Symptom:** Workflow stops at Node 4 or Node 5 + +**Solution:** +1. **Check Wait Node:** Set to 10 seconds minimum +2. **Check SSH Timeout:** Set to 300000ms (5 minutes) +3. **Check SSH Authentication:** Test manually +```bash +ssh -i /home/bam/.ssh/n8n_key bam@localhost "echo 'SSH works'" +``` + +### Issue 4: OpenHands Not Using Feedback + +**Symptom:** Retry attempts show same errors + +**Solution:** Check Node 4 command generation +```javascript +// Must include previous error in task +if (retryCount > 0) { + task += ` + +PREVIOUS BUILD FAILED: +${errorDetails}`; +} +``` + +### Issue 5: Data Lost in Retry Loop + +**Symptom:** Repository info missing on retry + +**Solution:** Check data preservation in Node 4 +```javascript +return { + ...repoData, // โ† CRITICAL: Preserve repo data + code: sshOutput.code, + stdout: sshOutput.stdout, + stderr: sshOutput.stderr, + status: 'SUCCESS' +}; +``` + +--- + +## ๐Ÿ“Š MONITORING & DEBUGGING + +### Enable Workflow Debugging + +**In n8n UI:** +1. Open workflow โ†’ Toggle "Save Manual Executions" +2. View execution history +3. Check each node's input/output + +### Key Metrics to Track + +- **Success Rate:** % of builds that succeed +- **Retry Efficiency:** Avg attempts per build +- **Build Time:** Duration from push to completion +- **Error Categories:** Type of failures + +### Debug Commands + +```bash +# Check OpenHands execution +tail -f /tmp/openhands_execution_*.log + +# Test SSH manually +ssh -i /home/bam/.ssh/n8n_key bam@localhost \ + "sh /home/bam/openhands-sdk-wrapper-sh.sh 'Test task'" + +# Check workflow status +curl -H "X-N8N-API-KEY: {TOKEN}" \ + https://n8n.oky.sh/api/v1/workflows/j1MmXaRhDjvkRSLa +``` + +--- + +## โฑ๏ธ TIME-BOXED IMPLEMENTATION + +### Session 1 (2 hours): Core Workflow +- [ ] Step 1: Setup test repository (20 min) +- [ ] Step 2: Configure Gitea webhook (15 min) +- [ ] Step 3: Add nodes 3, 7, 8, 9, 10 (45 min) +- [ ] Test success path (30 min) +- [ ] Buffer for issues (10 min) + +### Session 2 (2 hours): Retry Logic +- [ ] Test failure path with fixable errors (45 min) +- [ ] Test max retries (45 min) +- [ ] Debug and fix issues (30 min) + +### Session 3 (1 hour): Real Project & Documentation +- [ ] Test with real project (45 min) +- [ ] Document workflow (15 min) + +--- + +## โœ… SUCCESS CRITERIA + +**Must Have:** +- [ ] End-to-end workflow completes (push โ†’ build โ†’ response) +- [ ] OpenHands executes autonomously +- [ ] Retry counter prevents infinite loops (max 3) +- [ ] Error feedback improves retry attempts +- [ ] Gitea commit status updates (success/failure) +- [ ] Works with real projects + +**Verification:** +```bash +# Test workflow manually +curl -X POST https://n8n.oky.sh/webhook/openhands-autonomous-build \ + -H "Content-Type: application/json" \ + -d '{ + "repository": {"name": "test-repo", "full_name": "gitadmin/test-repo"}, + "ref": "refs/heads/main", + "after": "abc123def456" + }' +``` + +**Expected Response:** +```json +{ + "status": "SUCCESS", + "attempts": 1, + "repo": "test-repo", + "branch": "main", + "gitea_status": "success" +} +``` + +--- + +## ๐Ÿ“š REFERENCE FILES + +- **Phase 3 Plan:** `/home/bam/claude/mvp-factory/phase3.md` +- **SDK Wrapper:** `/home/bam/openhands-sdk-wrapper-sh.sh` +- **n8n API Docs:** `/home/bam/claude/mvp-factory/n8n-api.md` +- **Phase 2 Learnings:** `/home/bam/claude/mvp-factory/phase2.md` +- **Data Preservation:** `/home/bam/claude/mvp-factory/N8N_DATA_PRESERVATION_SOLUTION.md` + +--- + +## ๐ŸŽ‰ FINAL NOTES + +**Key Reminders:** +1. **Data Preservation:** Always use `$node["Node Name"].json` pattern +2. **Retry Counter:** Initialize with `$workflow.staticData = $workflow.staticData || {}` +3. **SSH Timeout:** Set to 5 minutes minimum +4. **Wait Node:** 10 seconds between nodes +5. **Gitea Token:** Must have "repo" scope for status updates + +**Workflow ID:** `j1MmXaRhDjvkRSLa` +**Target Webhook:** `https://n8n.oky.sh/webhook/openhands-autonomous-build` + +--- + +**Implementation Ready โœ…** +**Estimated Total Time:** 4-5 hours +**Can proceed immediately** diff --git a/phase3-implementation-summary.md b/phase3-implementation-summary.md new file mode 100644 index 0000000..8480562 --- /dev/null +++ b/phase3-implementation-summary.md @@ -0,0 +1,344 @@ +# Phase 3 Implementation Summary + +**Date Created:** 2025-12-02 +**Implementation Target:** Autonomous Build Test MVP +**Estimated Duration:** 4-5 hours + +--- + +## ๐Ÿ“ฆ DOCUMENTATION PACKAGE CREATED + +I've created a complete implementation package for Phase 3 with 5 comprehensive documents: + +### 1. **phase3.md** (Original Plan - 12 KB) +- Original detailed plan +- Time estimates and timeline +- Overview and goals +- Test sequence strategy + +### 2. **phase3-implementation-plan.md** (Main Guide - 21 KB) โญ +**Primary document for implementation** +- Complete step-by-step guide +- All 11 nodes detailed +- Configuration instructions +- Success criteria +- Troubleshooting guide + +### 3. **phase3-code-snippets.md** (Code Reference - 9.1 KB) +**Ready-to-copy code for each node** +- Node 3: Initialize Retry Counter code +- Node 4: Execute OpenHands Build (enhanced) +- Node 6: Evaluate Build Results code +- Node 8: Update Gitea Success (HTTP config) +- Node 9: Format Error for Retry code +- Node 11: Final Response (both paths) +- Decision node configurations +- Quick test commands + +### 4. **phase3-quickstart.md** (Quick Start - 5.6 KB) +**5-minute setup guide** +- Generate Gitea token +- Create test repository +- Configure webhook +- Implementation checklist +- Critical reminders + +### 5. **phase3-workflow-diagram.md** (Visual Guide - 15 KB) +**Complete workflow visualization** +- ASCII diagram of 11-node flow +- Data flow patterns +- Retry flow details +- Success/failure paths +- Timeline and execution flow +- Node configuration matrix + +--- + +## ๐ŸŽฏ IMPLEMENTATION OVERVIEW + +### Current State +- โœ… **Workflow ID:** `j1MmXaRhDjvkRSLa` (7 nodes) +- โœ… **n8n Instance:** https://n8n.oky.sh +- โœ… **OpenHands SDK:** Working via SSH +- โœ… **SSH Credentials:** Configured +- โœ… **API Keys:** MiniMax & DeepSeek available + +### Target State +- **11-node autonomous CI/CD workflow** +- **Retry logic:** Max 3 attempts +- **Error feedback:** To OpenHands +- **Gitea status:** Auto-updates +- **Real project testing:** Functional + +--- + +## ๐Ÿ“‹ STEP-BY-STEP APPROACH + +### Phase A: Preparation (20 min) +1. Generate Gitea API token (repo + admin:repo_hook scopes) +2. Create test repository: `autonomous-build-test` +3. Configure webhook: `/webhook/openhands-autonomous-build` + +### Phase B: Add New Nodes (90 min) +1. **Node 3:** Initialize Retry Counter (Code node) +2. **Node 7:** Decision - Build OK? (IF node) +3. **Node 8:** Update Gitea Success (HTTP node) +4. **Node 9:** Format Error for Retry (Code node) +5. **Node 10:** Check Retry Count (IF node) + +### Phase C: Modify Existing Nodes (60 min) +1. **Node 2:** Extract Repo Info (add fields) +2. **Node 4:** OpenHands Build (enhance + preserve data) +3. **Node 6:** Check Build Results (add success check) +4. **Node 11:** Final Response (support both paths) + +### Phase D: Test (90 min) +1. Success path test +2. Retry with fixable errors +3. Max retries (3 attempts) +4. Real project test + +--- + +## ๐Ÿ”ง WORKFLOW ARCHITECTURE + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [1] Webhook โ”‚ Receives Gitea push +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [2] Extract โ”‚ Parse commit info +โ”‚ Repo Info โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [3] Init โ”‚ โ”‚ [11] Final โ”‚ +โ”‚ Retry โ”‚ โ”‚ Response โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [4] OpenHandsโ”‚ Execute build +โ”‚ Build โ”‚ (with error feedback) +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [5] Wait โ”‚ 10 seconds +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [6] Check โ”‚ Evaluate results +โ”‚ Results โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [7] Decision โ”‚ Build OK? +โ”‚ Build OK? โ”‚ +โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ โ”‚ + โ”‚ โ”œโ”€ YES โ†’ [8] Gitea Success โ†’ [11] + โ”‚ โ”‚ + โ”‚ โ””โ”€ NO โ†’ [9] Format Error + โ”‚ โ†“ + โ”‚ [10] Retry Check + โ”‚ โ”‚ + โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ” + โ”‚ โ”‚ โ”‚ + โ”‚ โ–ผ โ–ผ + โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ โ”‚ Loop โ”‚ โ”‚ [11] โ”‚ + โ”‚ โ”‚ to [4] โ”‚ โ”‚Final โ”‚ + โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +--- + +## ๐Ÿ’พ KEY CODE PATTERNS + +### 1. Data Preservation (Critical!) +```javascript +const sshOutput = $json; +const repoData = $node["Extract Repo Info"].json; + +return { + ...repoData, // โ† PRESERVE INPUT + code: sshOutput.code, + stdout: sshOutput.stdout, + stderr: sshOutput.stderr +}; +``` + +### 2. Retry Counter Initialization +```javascript +$workflow.staticData = $workflow.staticData || {}; +$workflow.staticData.retry_count = ($workflow.staticData.retry_count || 0) + 1; +``` + +### 3. Error Feedback Loop +```javascript +if (retryCount > 0) { + task += ` + +PREVIOUS BUILD FAILED: +${errorDetails}`; +} +``` + +### 4. Gitea Status Update +```javascript +POST https://git.oky.sh/api/v1/repos/{owner}/{repo}/statuses/{sha} +{ + "state": "success", + "description": "โœ… Build passed after 2 attempt(s)", + "context": "openhands/autonomous-build" +} +``` + +--- + +## ๐Ÿ“Š SUCCESS CRITERIA + +### Must Have โœ… +- [ ] End-to-end workflow completes (push โ†’ build โ†’ response) +- [ ] OpenHands executes autonomously +- [ ] Retry counter prevents infinite loops (max 3) +- [ ] Error feedback improves subsequent attempts +- [ ] Gitea commit status updates (success/failure) +- [ ] Works with real projects + +### Validation Tests +1. **Test Success Path:** Valid code builds in 1 attempt +2. **Test Retry Logic:** Fixable errors resolve in 2-3 attempts +3. **Test Max Retries:** Persistent errors fail after 3 attempts +4. **Test Real Project:** Actual MVP project builds successfully + +--- + +## ๐Ÿงช QUICK TEST COMMANDS + +### Manual Workflow Trigger +```bash +curl -X POST https://n8n.oky.sh/webhook/openhands-autonomous-build \ + -H "Content-Type: application/json" \ + -d '{ + "repository": {"name": "test-project", "full_name": "gitadmin/test-project"}, + "ref": "refs/heads/main", + "after": "abc123def456789012345678901234567890abcd" + }' +``` + +### Create Test Repository +```bash +curl -X POST https://git.oky.sh/api/v1/user/repos \ + -H "X-Gitea-Token: {YOUR_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{"name":"autonomous-build-test"}' +``` + +### Test SSH Connectivity +```bash +ssh -i /home/bam/.ssh/n8n_key bam@localhost \ + "sh /home/bam/openhands-sdk-wrapper-sh.sh 'Test connection'" +``` + +--- + +## ๐Ÿšจ CRITICAL WARNINGS + +### โš ๏ธ Data Loss Prevention +- SSH nodes **overwrite ALL data** +- Must use `$node["Node Name"].json` pattern +- Always preserve repo data: `...repoData` + +### โš ๏ธ Retry Counter +- Must initialize: `$workflow.staticData = $workflow.staticData || {}` +- Increment: `$workflow.staticData.retry_count = ($workflow.staticData.retry_count || 0) + 1` +- Check: `if (retryCount >= 3) return fail;` + +### โš ๏ธ Gitea Token +- Required for status updates +- Must have scopes: `repo` + `admin:repo_hook` +- Format: `gho_...` or `gsat_...` + +### โš ๏ธ SSH Configuration +- Host: `localhost` +- User: `bam` +- Key: `/home/bam/.ssh/n8n_key` +- Timeout: `300000` (5 minutes) + +--- + +## ๐Ÿ“ž IMPLEMENTATION SEQUENCE + +### Start Here โญ +1. **Read:** `phase3-implementation-plan.md` (complete guide) +2. **Copy code from:** `phase3-code-snippets.md` +3. **Reference:** `phase3-workflow-diagram.md` (visual guide) +4. **Quick setup:** `phase3-quickstart.md` (5-min checklist) + +### Use Todo List +```bash +# Progress tracking +# Mark items as completed: +TodoWrite --todos "[...]" # Update status +``` + +--- + +## ๐Ÿ“š FILE LOCATIONS + +All documentation in: `/home/bam/claude/mvp-factory/` + +``` +phase3.md (Original plan) +phase3-implementation-plan.md (Main implementation guide) โญ +phase3-code-snippets.md (Copy-paste code) +phase3-quickstart.md (Quick start) +phase3-workflow-diagram.md (Visual diagram) +phase3-implementation-summary.md (This file) +``` + +--- + +## ๐ŸŽ‰ READY TO IMPLEMENT + +### Everything You Need โœ… +- โœ… Complete documentation (5 files, 62 KB) +- โœ… Ready-to-copy code snippets +- โœ… Visual workflow diagrams +- โœ… Step-by-step instructions +- โœ… Troubleshooting guide +- โœ… Test commands +- โœ… Success criteria checklist + +### Next Steps +1. **Read** `phase3-implementation-plan.md` +2. **Generate** Gitea API token +3. **Start** with Node 3 (Initialize Retry Counter) +4. **Follow** code snippets from `phase3-code-snippets.md` +5. **Test** using commands in `phase3-quickstart.md` + +### Time Estimate +- **Setup:** 30 minutes +- **Implementation:** 2-3 hours +- **Testing:** 1-2 hours +- **Total:** 4-5 hours + +--- + +**Status: Implementation Ready** ๐Ÿš€ + +All documentation and code snippets are prepared and ready to use immediately. + +--- + +*Implementation Summary - Created: 2025-12-02* +*All Phase 3 documentation complete* diff --git a/phase3-quickstart.md b/phase3-quickstart.md new file mode 100644 index 0000000..5deddf5 --- /dev/null +++ b/phase3-quickstart.md @@ -0,0 +1,240 @@ +# Phase 3 Quick Start Guide + +**Goal:** Transform 7-node workflow โ†’ 11-node autonomous CI/CD with retry logic +**Time:** 4-5 hours +**Workflow ID:** `j1MmXaRhDjvkRSLa` + +--- + +## ๐Ÿš€ 5-MINUTE SETUP + +### 1. Get Gitea Token (Required for Status Updates) + +```bash +# UI Method (Easiest): +# 1. Go to https://git.oky.sh/user/settings/applications +# 2. Click "Generate Token" +# 3. Name: n8n-autonomous-build +# 4. Scopes: repo, admin:repo_hook +# 5. Copy token (format: gho_...) +``` + +### 2. Create Test Repository + +```bash +# Via API: +curl -X POST https://git.oky.sh/api/v1/user/repos \ + -H "X-Gitea-Token: {YOUR_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{"name":"autonomous-build-test","description":"Phase 3 test repo"}' + +# Or via UI: +# https://git.oky.sh โ†’ + โ†’ New Repository +``` + +### 3. Configure Webhook + +1. Go to: `https://git.oky.sh/gitadmin/autonomous-build-test/settings/hooks` +2. Add Webhook: + - URL: `https://n8n.oky.sh/webhook/openhands-autonomous-build` + - Trigger: Push events + - Active: โœ“ + +--- + +## ๐Ÿ“‹ IMPLEMENTATION CHECKLIST + +### Phase A: Add New Nodes (90 min) + +- [ ] **Node 3:** Initialize Retry Counter + - Type: Code + - Code: See `phase3-code-snippets.md` โ†’ "Node 3" + +- [ ] **Node 7:** Decision - Build OK? + - Type: IF + - Condition: `$json.build_success == true` + +- [ ] **Node 8:** Update Gitea Success + - Type: HTTP + - URL: `https://git.oky.sh/api/v1/repos/{owner}/{repo}/statuses/{sha}` + - Token: `{YOUR_GITEA_API_TOKEN}` + +- [ ] **Node 9:** Format Error for Retry + - Type: Code + - Code: See `phase3-code-snippets.md` โ†’ "Node 9" + +- [ ] **Node 10:** Check Retry Count + - Type: IF + - Condition: `$json.can_retry == true` + +### Phase B: Modify Existing Nodes (60 min) + +- [ ] **Node 2:** Extract Repo Info + - Add: `repo_name`, `owner`, `branch`, `commit_sha` + +- [ ] **Node 4:** Execute OpenHands Build + - Enhance command with error feedback + - Add data preservation pattern + +- [ ] **Node 6:** Check Build Results + - Add: `build_success`, `error_details` + +- [ ] **Node 11:** Final Response + - Support both success AND failure paths + +### Phase C: Test (90 min) + +- [ ] Test 1: Success Path (30 min) +- [ ] Test 2: Retry with Fixable Errors (30 min) +- [ ] Test 3: Max Retries (3 attempts) (30 min) + +--- + +## ๐Ÿ“š KEY RESOURCES + +| File | Purpose | +|------|---------| +| `phase3-implementation-plan.md` | Complete implementation guide (11 nodes) | +| `phase3-code-snippets.md` | Ready-to-copy code for each node | +| `phase3-quickstart.md` | This file - quick start guide | +| `phase3.md` | Original Phase 3 plan | + +--- + +## ๐Ÿ”ง NODES BREAKDOWN + +### Current Workflow (7 nodes) +``` +[1] Gitea Webhook +[2] Extract Repo Info +[3] Start OpenHands Build +[4] Wait 10s +[5] Check Build Status +[6] Format Response +[7] Send Response +``` + +### Target Workflow (11 nodes) +``` +[1] Gitea Webhook +[2] Extract Repo Info (MODIFY) +[3] Initialize Retry Counter (NEW) +[4] Start OpenHands Build (MODIFY) +[5] Wait 10s +[6] Check Build Results (MODIFY) +[7] Decision: Build OK? (NEW) + โ”œโ”€ YES โ†’ [8] Update Gitea Success โ†’ [11] Response + โ””โ”€ NO โ†’ [9] Format Error Feedback + โ†“ + [10] Check Retry Count + โ”œโ”€ YES โ†’ Loop to [4] + โ””โ”€ NO โ†’ [11] Final Response +``` + +--- + +## โš ๏ธ CRITICAL REMINDERS + +### 1. Data Preservation Pattern +**ALWAYS use this in SSH nodes:** +```javascript +const sshOutput = $json; +const repoData = $node["Extract Repo Info"].json; + +return { + ...repoData, // โ† PRESERVE INPUT DATA + code: sshOutput.code, + stdout: sshOutput.stdout, + stderr: sshOutput.stderr +}; +``` + +### 2. Retry Counter Initialization +**MUST initialize in Node 3:** +```javascript +$workflow.staticData = $workflow.staticData || {}; +$workflow.staticData.retry_count = ($workflow.staticData.retry_count || 0) + 1; +``` + +### 3. SSH Node Configuration +``` +Host: localhost +User: bam +Private Key: /home/bam/.ssh/n8n_key +Timeout: 300000 (5 minutes) +``` + +--- + +## ๐Ÿงช QUICK TESTS + +### Test 1: Manual Workflow Trigger + +```bash +curl -X POST https://n8n.oky.sh/webhook/openhands-autonomous-build \ + -H "Content-Type: application/json" \ + -d '{ + "repository": { + "name": "test-project", + "full_name": "gitadmin/test-project", + "owner": {"name": "gitadmin", "username": "gitadmin"} + }, + "ref": "refs/heads/main", + "after": "abc123def456789012345678901234567890abcd" + }' +``` + +### Test 2: SSH Connectivity + +```bash +ssh -i /home/bam/.ssh/n8n_key bam@localhost \ + "sh /home/bam/openhands-sdk-wrapper-sh.sh 'Test connection'" +``` + +--- + +## ๐Ÿ“Š SUCCESS CRITERIA + +โœ… **End-to-end completes:** Push โ†’ Build โ†’ Response +โœ… **Retry works:** Max 3 attempts, then stop +โœ… **Gitea status:** Updates to success/failure +โœ… **Error feedback:** OpenHands receives previous errors +โœ… **Real projects:** Works with actual MVP project + +--- + +## ๐Ÿ†˜ TROUBLESHOOTING + +| Problem | Quick Fix | +|---------|-----------| +| Retry count always 0 | Initialize `$workflow.staticData` | +| Gitea status not updating | Check token has "repo" scope | +| Workflow hangs | Increase SSH timeout to 5 min | +| Data lost in loop | Use `$node["Node Name"].json` pattern | +| Same errors on retry | Include error in task string | + +--- + +## ๐Ÿ“ž CURRENT STATUS + +- โœ… Phase 2 Complete +- โœ… Workflow ID: `j1MmXaRhDjvkRSLa` +- โœ… OpenHands SDK: Working +- โœ… n8n + Gitea: Configured +- โณ Phase 3: Ready to implement + +--- + +## ๐ŸŽฏ NEXT STEPS + +1. **Now:** Read `phase3-implementation-plan.md` +2. **Then:** Generate Gitea token +3. **Then:** Start with Node 3 (Initialize Retry Counter) +4. **Follow:** `phase3-code-snippets.md` for exact code + +**Total Time:** 4-5 hours +**Can start immediately! ๐Ÿš€** + +--- + +*Quick Start Guide - Last Updated: 2025-12-02* diff --git a/phase3-workflow-current.json b/phase3-workflow-current.json new file mode 100644 index 0000000..d19f359 --- /dev/null +++ b/phase3-workflow-current.json @@ -0,0 +1 @@ +{"updatedAt":"2025-12-02T17:29:22.862Z","createdAt":"2025-12-02T17:28:18.023Z","id":"fy6ooiuhTyQrOhlv","name":"Phase 3: TASK.md Driven with Retry (FIXED)","description":null,"active":true,"isArchived":false,"nodes":[{"parameters":{"httpMethod":"POST","path":"openhands-build-test","options":{}},"id":"webhook","name":"Gitea Webhook","type":"n8n-nodes-base.webhook","typeVersion":1.1,"position":[240,300],"webhookId":"openhands-build-test"},{"parameters":{"jsCode":"const payload = $json.body || $json;\n\nconst repoName = payload.repository?.name || 'vue-ai-agency';\nconst repoFullName = payload.repository?.full_name || 'gitadmin/vue-ai-agency';\nconst branch = payload.ref?.replace('refs/heads/', '') || 'main';\nconst commitSha = payload.after || '';\nconst commitMsg = payload.commits?.[0]?.message || '';\n\n// SKIP: Detect OpenHands commits to prevent infinite loop\nif (commitMsg.toLowerCase().includes('openhands')) {\n return {\n skip: true,\n reason: 'OpenHands commit detected - skipping',\n repo_name: repoName,\n commit_message: commitMsg\n };\n}\n\nconst projectDir = '/home/bam/claude/' + repoName;\n\nreturn {\n skip: false,\n repo_name: repoName,\n repo_full_name: repoFullName,\n branch: branch,\n commit_sha: commitSha,\n commit_message: commitMsg,\n project_dir: projectDir,\n timestamp: new Date().toISOString()\n};"},"id":"extract-info","name":"Extract Info","type":"n8n-nodes-base.code","typeVersion":2,"position":[460,300]},{"parameters":{"command":"cat /home/bam/.gitea_api_token","sessionId":"get-token","authentication":"privateKey","options":{}},"id":"get-token","name":"Get Token","type":"n8n-nodes-base.ssh","typeVersion":1,"position":[460,500],"credentials":{"sshPrivateKey":{"id":"v2BMXeCFGpXaoIyb","name":"SSH Private Key account"}}},{"parameters":{"conditions":{"boolean":[{"value1":"={{ $json.skip }}","value2":true}]}},"id":"check-skip","name":"Should Skip?","type":"n8n-nodes-base.if","typeVersion":1,"position":[680,300]},{"parameters":{"command":"={{ 'cat ' + $json.project_dir + '/TASK.md 2>/dev/null || echo \"No TASK.md found\"' }}","sessionId":"read-task","authentication":"privateKey","options":{}},"id":"read-task-file","name":"Read TASK.md","type":"n8n-nodes-base.ssh","typeVersion":1,"position":[900,300],"credentials":{"sshPrivateKey":{"id":"v2BMXeCFGpXaoIyb","name":"SSH Private Key account"}}},{"parameters":{"jsCode":"// Get retry counter from workflow static data\nconst staticData = $getWorkflowStaticData('global');\nstaticData.retry_count = (staticData.retry_count || 0) + 1;\n\nconst retryCount = staticData.retry_count;\n\n// FAIL: Max retries exceeded\nif (retryCount >= 3) {\n return {\n action: 'FAIL',\n status: 'FAILED',\n retry_count: retryCount,\n max_retries: 3,\n message: `โŒ Build failed after 3 attempts`,\n repo: $json.repo_full_name,\n commit_sha: $json.commit_sha\n };\n}\n\nconst sshOutput = $json;\nconst repoData = $node['Extract Info'].json;\nconst tokenData = $node['Get Token'].json;\n\nconst taskContent = sshOutput.stdout?.trim() || '';\nconst hasTask = taskContent && !taskContent.includes('No TASK.md found');\n\nif (!hasTask) {\n return {\n status: 'SKIPPED',\n message: 'No TASK.md found',\n retry_count: retryCount\n };\n}\n\n// Build task message\nlet taskMsg = '';\nconst prevResult = $input.first()?.json?.build_result;\n\nif (prevResult && prevResult.status === 'FAILED') {\n // Retry with error feedback\n taskMsg = `๐Ÿ”„ BUILD RETRY - Attempt ${retryCount}/3\\n\\n` +\n `Previous build FAILED with errors:\\n` +\n `${prevResult.errors || 'Unknown error'}\\n\\n` +\n `Please review the task and fix these issues:\\n\\n` +\n `Working in directory ${repoData.project_dir}:\\n\\n` +\n `Read and implement the following task from TASK.md:\\n\\n` +\n `${taskContent}\\n\\n` +\n `After completing the task, rename TASK.md to TASK_DONE.md`;\n} else {\n // Initial build\n taskMsg = `Working in directory ${repoData.project_dir}:\\n\\n` +\n `Read and implement the following task from TASK.md:\\n\\n` +\n `${taskContent}\\n\\n` +\n `After completing the task, rename TASK.md to TASK_DONE.md`;\n}\n\nreturn {\n action: 'RETRY',\n status: 'IN_PROGRESS',\n retry_count: retryCount,\n max_retries: 3,\n task: taskMsg,\n repo: repoData.repo_full_name,\n commit_sha: repoData.commit_sha,\n project_dir: repoData.project_dir,\n gitea_token: tokenData.stdout || tokenData\n};"},"id":"prepare-task","name":"Prepare Task with Retry","type":"n8n-nodes-base.code","typeVersion":2,"position":[1120,300]},{"parameters":{"command":"={{ 'sh /home/bam/openhands-sdk-wrapper-sh.sh \"' + $json.task.replace(/\"/g, '\\\\\"') + '\" \"' + $json.project_dir + '\"' }}","sessionId":"openhands-task","authentication":"privateKey","options":{}},"id":"run-openhands","name":"Run OpenHands","type":"n8n-nodes-base.ssh","typeVersion":1,"position":[1340,300],"credentials":{"sshPrivateKey":{"id":"v2BMXeCFGpXaoIyb","name":"SSH Private Key account"}}},{"parameters":{"jsCode":"const sshOutput = $json;\nconst buildData = $node['Prepare Task with Retry'].json;\n\nconst stdout = sshOutput.stdout || '';\nconst stderr = sshOutput.stderr || '';\nconst exitCode = sshOutput.code || 0;\n\n// DETERMINE BUILD STATUS\nlet status = 'FAILED';\nlet errors = '';\n\n// Check for common success patterns\nconst hasTestPassing = stdout.includes('passing') || stdout.includes('โœ“') || stdout.includes('PASS');\nconst hasSuccessKeyword = stdout.includes('success') || stdout.includes('build complete');\nconst hasNoErrors = !stderr || (stderr.length < 50 && !stderr.toLowerCase().includes('error'));\n\n// Check for failure patterns\nconst hasFailingTests = stdout.includes('failing') || stdout.includes('โœ—') || stdout.includes('FAIL');\nconst hasErrors = stderr.toLowerCase().includes('error') || stderr.toLowerCase().includes('fail');\n\n// Determine status\nif (exitCode === 0 && (hasTestPassing || hasSuccessKeyword || hasNoErrors)) {\n status = 'SUCCESS';\n} else if (hasFailingTests || hasErrors || exitCode !== 0) {\n status = 'FAILED';\n errors = stderr || stdout || `Process exited with code ${exitCode}`;\n}\n\nreturn {\n ...buildData,\n build_result: {\n status: status,\n exit_code: exitCode,\n stdout: stdout.substring(0, 2000),\n stderr: stderr.substring(0, 2000),\n errors: errors.substring(0, 1000)\n }\n};"},"id":"analyze-result","name":"Analyze Result","type":"n8n-nodes-base.code","typeVersion":2,"position":[1560,300]},{"parameters":{"conditions":{"string":[{"value1":"={{ $json.build_result.status }}","operation":"equal","value2":"SUCCESS"}]}},"id":"success-check","name":"Build Success?","type":"n8n-nodes-base.if","typeVersion":1,"position":[1780,300]},{"parameters":{"command":"={{ 'cd ' + $json.project_dir + ' && git add -A && git commit -m \"OpenHands: Build successful\" && git push origin main 2>&1 || echo \"Nothing to commit\"' }}","sessionId":"git-push","authentication":"privateKey","options":{}},"id":"git-commit-push","name":"Git Commit & Push","type":"n8n-nodes-base.ssh","typeVersion":1,"position":[2000,200],"credentials":{"sshPrivateKey":{"id":"v2BMXeCFGpXaoIyb","name":"SSH Private Key account"}}},{"parameters":{"jsCode":"const buildResult = $json.build_result;\nconst buildData = $node['Prepare Task with Retry'].json;\n\n// SUCCESS RESPONSE\nconst successMessage = `โœ… BUILD SUCCESSFUL\\n\\n` +\n `Repository: ${buildData.repo}\\n` +\n `Commit: ${buildData.commit_sha}\\n` +\n `Attempt: ${buildData.retry_count}/3\\n\\n` +\n `Result: Build completed successfully!\\n\\n` +\n `OpenHands has successfully built and tested the project.\\n` +\n `The commit status has been updated in Gitea.`;\n\n// Reset retry counter on success\nconst staticData = $getWorkflowStaticData('global');\nstaticData.retry_count = 0;\n\nreturn {\n status: 'SUCCESS',\n action: 'COMPLETED',\n message: successMessage,\n repo: buildData.repo,\n commit_sha: buildData.commit_sha,\n retry_count: buildData.retry_count,\n build_result: buildResult\n};"},"id":"handle-success","name":"Handle Success","type":"n8n-nodes-base.code","typeVersion":2,"position":[2220,200]},{"parameters":{"command":"={{ 'curl -X POST \"https://git.oky.sh/api/v1/repos/' + $json.repo.split('/')[0] + '/' + $json.repo.split('/')[1] + '/statuses/' + $json.commit_sha + '\" -H \"Authorization: token ' + $json.gitea_token + '\" -H \"Content-Type: application/json\" -d \"{\\\"state\\\": \\\"success\\\", \\\"description\\\": \\\"Build successful after \" + $json.retry_count + \" attempt(s)\\\", \\\"context\\\": \\\"openhands-ci\\\"}\" -s' }}","sessionId":"update-gitea-success","authentication":"privateKey","options":{}},"id":"update-gitea-success","name":"Update Gitea Success","type":"n8n-nodes-base.ssh","typeVersion":1,"position":[2440,200],"credentials":{"sshPrivateKey":{"id":"v2BMXeCFGpXaoIyb","name":"SSH Private Key account"}}},{"parameters":{"jsCode":"const buildResult = $json.build_result;\nconst buildData = $node['Prepare Task with Retry'].json;\n\n// FAILURE RESPONSE\nconst remaining = buildData.max_retries - buildData.retry_count;\nconst willRetry = remaining > 0;\n\nconst failureMessage = `โŒ BUILD FAILED (Attempt ${buildData.retry_count}/${buildData.max_retries})\\n\\n` +\n `Repository: ${buildData.repo}\\n` +\n `Commit: ${buildData.commit_sha}\\n\\n` +\n `Errors:\\n${buildResult.errors}\\n\\n` +\n (willRetry\n ? `โณ Will retry (${remaining} attempts remaining)`\n : `โš ๏ธ MAX RETRIES REACHED - Build failed permanently`);\n\nreturn {\n status: 'FAILED',\n action: willRetry ? 'RETRY' : 'GIVE_UP',\n message: failureMessage,\n repo: buildData.repo,\n commit_sha: buildData.commit_sha,\n retry_count: buildData.retry_count,\n remaining: remaining,\n build_result: buildResult,\n will_retry: willRetry\n};"},"id":"handle-failure","name":"Handle Failure","type":"n8n-nodes-base.code","typeVersion":2,"position":[2000,400]},{"parameters":{"respondWith":"json","responseBody":"={{ $json }}","options":{}},"id":"respond","name":"Respond","type":"n8n-nodes-base.respondToWebhook","typeVersion":1.1,"position":[2660,300]},{"parameters":{"jsCode":"return {\n status: 'SKIPPED',\n message: 'OpenHands commit - skipped to prevent loop',\n timestamp: new Date().toISOString()\n};"},"id":"skip-message","name":"Skip Message","type":"n8n-nodes-base.code","typeVersion":2,"position":[900,500]}],"connections":{"Gitea Webhook":{"main":[[{"node":"Extract Info","type":"main","index":0}]]},"Extract Info":{"main":[[{"node":"Get Token","type":"main","index":0}]]},"Get Token":{"main":[[{"node":"Should Skip?","type":"main","index":0}]]},"Should Skip?":{"main":[[{"node":"Skip Message","type":"main","index":0}],[{"node":"Read TASK.md","type":"main","index":0}]]},"Read TASK.md":{"main":[[{"node":"Prepare Task with Retry","type":"main","index":0}]]},"Prepare Task with Retry":{"main":[[{"node":"Run OpenHands","type":"main","index":0}]]},"Run OpenHands":{"main":[[{"node":"Analyze Result","type":"main","index":0}]]},"Analyze Result":{"main":[[{"node":"Build Success?","type":"main","index":0}]]},"Build Success?":{"main":[[{"node":"Git Commit & Push","type":"main","index":0}],[{"node":"Handle Failure","type":"main","index":0}]]},"Git Commit & Push":{"main":[[{"node":"Handle Success","type":"main","index":0}]]},"Handle Success":{"main":[[{"node":"Update Gitea Success","type":"main","index":0}]]},"Update Gitea Success":{"main":[[{"node":"Respond","type":"main","index":0}]]},"Handle Failure":{"main":[[{"node":"Respond","type":"main","index":0}],[{"node":"Prepare Task with Retry","type":"main","index":0}]]},"Skip Message":{"main":[[{"node":"Respond","type":"main","index":0}]]}},"settings":{"executionOrder":"v1","callerPolicy":"workflowsFromSameOwner","availableInMCP":false},"staticData":null,"meta":null,"pinData":null,"versionId":"5c85a30d-72df-4aaf-8849-d186ad6b59e5","versionCounter":3,"triggerCount":1,"shared":[{"updatedAt":"2025-12-02T17:28:18.025Z","createdAt":"2025-12-02T17:28:18.025Z","role":"workflow:owner","workflowId":"fy6ooiuhTyQrOhlv","projectId":"18Ie3sGopJUKowvQ","project":{"updatedAt":"2025-11-28T21:55:42.833Z","createdAt":"2025-11-28T21:54:40.915Z","id":"18Ie3sGopJUKowvQ","name":"pi raj ","type":"personal","icon":null,"description":null,"projectRelations":[{"updatedAt":"2025-11-28T21:54:40.915Z","createdAt":"2025-11-28T21:54:40.915Z","userId":"9ac6189d-d9fb-457e-893e-27b9af3fa738","projectId":"18Ie3sGopJUKowvQ","user":{"updatedAt":"2025-12-02T07:18:21.000Z","createdAt":"2025-11-28T21:54:40.486Z","id":"9ac6189d-d9fb-457e-893e-27b9af3fa738","email":"aidev@oky.sh","firstName":"pi","lastName":"raj","personalizationAnswers":{"version":"v4","personalization_survey_submitted_at":"2025-11-28T21:55:59.720Z","personalization_survey_n8n_version":"1.121.3"},"settings":{"userActivated":true,"firstSuccessfulWorkflowId":"hwbFEoEIgGyjV0He","userActivatedAt":1764591198155},"disabled":false,"mfaEnabled":false,"lastActiveAt":"2025-12-01","isPending":false}}]}}],"tags":[]} \ No newline at end of file diff --git a/phase3-workflow-diagram.md b/phase3-workflow-diagram.md new file mode 100644 index 0000000..cf9c730 --- /dev/null +++ b/phase3-workflow-diagram.md @@ -0,0 +1,267 @@ +# Phase 3 Workflow Diagram + +## Current Workflow (7 Nodes) โ†’ Target Workflow (11 Nodes) + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ PHASE 3: AUTONOMOUS BUILD TEST โ”‚ +โ”‚ Workflow ID: j1MmXaRhDjvkRSLa โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [1] Gitea โ”‚ Webhook: /webhook/openhands-autonomous-build +โ”‚ Webhook โ”‚ Trigger: Push events +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [2] Extract โ”‚ Code Node +โ”‚ Repo Info โ”‚ Extract: repo_name, owner, branch, commit_sha +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [3] Initialize โ”‚ Code Node โ˜… NEW +โ”‚ Retry Count โ”‚ Initialize: $workflow.staticData.retry_count = 0 +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [4] OpenHands โ”‚ SSH Node โ˜… MODIFIED +โ”‚ Build โ”‚ - Enhanced task with error feedback + โ”‚ - Data preservation pattern + โ”‚ - Retry logic on loop back + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [5] Wait โ”‚ Wait Node (10 seconds) +โ”‚ 10s โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [6] Check โ”‚ Code Node โ˜… MODIFIED +โ”‚ Build โ”‚ Add: build_success, error_details +โ”‚ Results โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [7] Decision โ”‚ IF Node โ˜… NEW +โ”‚ Build OK? โ”‚ Condition: build_success == true +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ โ”‚ + โ–ผ โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ [8] Update โ”‚ โ”‚ [9] Format Errorโ”‚ Code Node โ˜… NEW +โ”‚ Gitea โ”‚ โ”‚ for Retry โ”‚ Format: error_message +โ”‚ Success โ”‚ โ”‚ โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ โ”‚ + โ”‚ โ–ผ + โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ โ”‚ [10] Check Retryโ”‚ IF Node โ˜… NEW + โ”‚ โ”‚ Count โ”‚ Condition: can_retry == true + โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ โ”‚ + โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ โ”‚ โ”‚ + โ”‚ โ–ผ โ–ผ + โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ โ”‚ Loop back to โ”‚ โ”‚ [11] Final โ”‚ Code Node + โ”‚ โ”‚ Node 4 โ”‚ โ”‚ Response โ”‚ โ˜… MODIFIED + โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ (Failure) โ”‚ + โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ [12] HTTP โ”‚ Respond to Webhook + โ”‚ Response โ”‚ Status: 200/500 + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + DATA FLOW PATTERNS +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + +[2] Extract Repo Info โ”€โ”€โ”€โ” + โ”‚ Output: { +[3] Initialize Retry โ”€โ”€โ”€โ”€โ”ค repo_name, owner, branch, + โ”‚ commit_sha, retry_count +[4] OpenHands โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค } โ†“ + โ”‚ +[4] preserves data โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ–บ return { + โ”‚ ...repoData, โ† PRESERVE + โ”‚ code, stdout, + โ”‚ stderr, status +[6] Check Results โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค } + โ”‚ โ†“ + โ”‚ +[7] Decision โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ–บ build_success? โ†’ true/false + โ”‚ +[8] Update Gitea โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค On success โ†’ POST to Gitea API + โ”‚ +[9] Format Error โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค On failure โ†’ Format comprehensive error + โ”‚ +[10] Retry Check โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค can_retry? โ†’ true/false + โ”‚ +[4] Loop back โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค If true โ†’ Back to OpenHands with feedback + โ”‚ If false โ†’ Final failure + โ”‚ +[11] Final Response โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ–บ SUCCESS or FAILED with details + +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + RETRY FLOW DETAIL +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + +Attempt 1: + [3] retry_count = 0 โ†’ [4] OpenHands (first attempt) โ†’ [6] Check โ†’ [7] FAIL + โ†’ [9] Format Error โ†’ [10] Check: can_retry? YES (0 < 2) โ†’ Loop to [4] + +Attempt 2: + [3] retry_count = 1 โ†’ [4] OpenHands (with error feedback) โ†’ [6] Check โ†’ [7] FAIL + โ†’ [9] Format Error โ†’ [10] Check: can_retry? YES (1 < 2) โ†’ Loop to [4] + +Attempt 3: + [3] retry_count = 2 โ†’ [4] OpenHands (with error feedback) โ†’ [6] Check โ†’ [7] FAIL + โ†’ [9] Format Error โ†’ [10] Check: can_retry? NO (2 โ‰ฎ 2) โ†’ [11] Final Failure + +Stop: Max retries (3) exceeded + +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + SUCCESS FLOW +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + +Attempt 1 (Success): + [3] retry_count = 0 โ†’ [4] OpenHands (first attempt) โ†’ [6] Check โ†’ [7] SUCCESS + โ†’ [8] Update Gitea โ†’ [11] Final Response (Success) + +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + KEY IMPLEMENTATION NOTES +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + +โš ๏ธ CRITICAL: Data Preservation Pattern + In Node 4 (SSH), ALWAYS preserve previous node data: + ``` + return { + ...repoData, // โ† This line is CRITICAL + code: sshOutput.code, + stdout: sshOutput.stdout, + stderr: sshOutput.stderr + }; + ``` + +โš ๏ธ CRITICAL: Retry Counter Initialization + In Node 3, MUST initialize staticData: + ``` + $workflow.staticData = $workflow.staticData || {}; + $workflow.staticData.retry_count = ($workflow.staticData.retry_count || 0) + 1; + ``` + +โš ๏ธ CRITICAL: Error Feedback Loop + In Node 4, include previous errors in task: + ``` + if (retryCount > 0) { + task += `PREVIOUS BUILD FAILED:\n${errorDetails}`; + } + ``` + +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + NODE CONFIGURATIONS +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + +Node Type Matrix: + +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ Node โ”‚ Type โ”‚ Key Configuration โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ 1 โ”‚ Webhook โ”‚ Path: /webhook/openhands-autonomous-build โ”‚ +โ”‚ 2 โ”‚ Code โ”‚ Extract repo data โ”‚ +โ”‚ 3 โ”‚ Code โ”‚ Initialize $workflow.staticData.retry_count โ”‚ +โ”‚ 4 โ”‚ SSH โ”‚ Host: localhost, Timeout: 300000ms โ”‚ +โ”‚ 5 โ”‚ Wait โ”‚ 10 seconds โ”‚ +โ”‚ 6 โ”‚ Code โ”‚ Evaluate build_success โ”‚ +โ”‚ 7 โ”‚ IF โ”‚ Condition: build_success == true โ”‚ +โ”‚ 8 โ”‚ HTTP โ”‚ POST Gitea API โ”‚ +โ”‚ 9 โ”‚ Code โ”‚ Format error with feedback โ”‚ +โ”‚ 10 โ”‚ IF โ”‚ Condition: can_retry == true โ”‚ +โ”‚ 11 โ”‚ Code โ”‚ Final SUCCESS/FAILED response โ”‚ +โ”‚ 12 โ”‚ Respond to Web โ”‚ Return HTTP 200/500 โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + GITEA STATUS UPDATES +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + +Success Path (Node 8): + POST https://git.oky.sh/api/v1/repos/{owner}/{repo}/statuses/{sha} + Body: { + "state": "success", + "description": "โœ… Build passed after {retry_count} attempt(s)", + "context": "openhands/autonomous-build" + } + +Failure Path (Node 11): + POST https://git.oky.sh/api/v1/repos/{owner}/{repo}/statuses/{sha} + Body: { + "state": "failure", + "description": "โŒ Build failed after 3 attempts", + "context": "openhands/autonomous-build" + } + +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + EXECUTION TIMELINE +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + +Success (No Retry): + T+0s โ†’ Webhook received + T+5s โ†’ OpenHands starts build + T+15s โ†’ Build complete, result checked + T+16s โ†’ Gitea status updated + T+17s โ†’ Response sent + +Success (After 2 Retries): + T+0s โ†’ Webhook received + T+5s โ†’ 1st OpenHands attempt + T+15s โ†’ 1st failure, formatted + T+20s โ†’ 2nd OpenHands attempt (with feedback) + T+30s โ†’ 2nd failure, formatted + T+35s โ†’ 3rd OpenHands attempt (with feedback) + T+45s โ†’ 3rd success + T+46s โ†’ Gitea status updated + T+47s โ†’ Response sent + +Failure (Max Retries): + T+0s โ†’ Webhook received + T+5s โ†’ 1st OpenHands attempt + T+15s โ†’ 1st failure + T+20s โ†’ 2nd OpenHands attempt + T+30s โ†’ 2nd failure + T+35s โ†’ 3rd OpenHands attempt + T+45s โ†’ 3rd failure + T+46s โ†’ Gitea status updated (failure) + T+47s โ†’ Response sent (max retries exceeded) + +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + FILE REFERENCES +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + +๐Ÿ“„ Documentation: + - phase3.md (Original plan) + - phase3-implementation-plan.md (Detailed guide) + - phase3-code-snippets.md (Ready-to-copy code) + - phase3-quickstart.md (Quick start) + +๐Ÿ”ง Configuration: + - n8n API Key: /home/bam/.n8n_api_key + - SSH Key: /home/bam/.ssh/n8n_key + - OpenHands: /home/bam/openhands-sdk-wrapper-sh.sh + +๐Ÿงช Testing: + - Test repo: autonomous-build-test + - Webhook: /webhook/openhands-autonomous-build + +โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• diff --git a/vue_okys_agency_prompt.md b/vue_okys_agency_prompt.md new file mode 100644 index 0000000..d51a813 --- /dev/null +++ b/vue_okys_agency_prompt.md @@ -0,0 +1,382 @@ +# AUTONOMOUS BUILD MISSION: OKYSH Agency Website v2 + +You are an autonomous agent with a critical mission: build a production-ready Vue.js website through iterative testing and self-correction. + +## ๐ŸŽฏ PROJECT REQUIREMENTS + +**Website:** OKYSH - AI Development Agency +**Tech Stack:** Vue 3, Vite, TailwindCSS, GSAP animations +**Sections:** Hero, Services, About, Tech Stack, Portfolio, Contact Form, Footer + +## ๐Ÿ”„ AUTONOMOUS WORKFLOW - FOLLOW STRICTLY + +### โš™๏ธ ITERATION TRACKING +Before starting, create a file: `build-log.md` to track your progress. +After EACH phase, append to this file: +``` +## Iteration X - [Phase Name] +Status: [Success/Failed] +Errors: [list if any] +Actions taken: [what you did] +Next step: [what's next] +``` + +--- + +### ๐Ÿ“ฆ PHASE 1: INITIAL SETUP + +**Tasks:** +1. Create project structure +2. Install dependencies with `package.json` that includes: + - vue@^3.4.0 + - vite@^5.0.0 + - tailwindcss@^3.4.0 + - @vitejs/plugin-vue + - autoprefixer, postcss +3. Create `vite.config.js` with: +```js + server: { + host: '0.0.0.0', + port: 3002, + allowedHosts: 'all' + } +``` +4. Create `tailwind.config.js` with COMPLETE color palette (primary, accent, dark) + - **CRITICAL:** Include ALL shades 50-950 for primary color + - primary-400 MUST exist +5. Setup basic Vue app structure + +**Self-Check:** +```bash +ls -la # Verify all files created +cat tailwind.config.js # Verify colors include 400 shade +``` + +**Success Criteria:** +- [ ] All config files exist +- [ ] package.json valid +- [ ] tailwind.config.js has primary-50 through primary-950 + +**Log your progress to build-log.md before proceeding** + +--- + +### ๐Ÿ—๏ธ PHASE 2: BUILD VALIDATION LOOP + +**DO NOT PROCEED UNTIL BUILD SUCCEEDS** + +**Tasks:** +1. Run: `npm install` +2. Capture output and check for errors +3. If install fails: + - Read error message carefully + - Identify the issue (version conflict? missing dep?) + - Fix package.json + - GO BACK TO STEP 1 +4. Run: `npm run build` +5. Capture build output +6. If build fails: + - Read FULL error message + - Common issues: + * Missing Tailwind colors (bg-primary-XXX not defined) + * Import errors (wrong paths) + * Syntax errors + - Fix the SPECIFIC issue mentioned + - GO BACK TO STEP 1 + +**Self-Check Commands:** +```bash +npm install 2>&1 | tee install.log +echo "Install exit code: $?" + +npm run build 2>&1 | tee build.log +echo "Build exit code: $?" + +# Check if dist/ was created +ls -la dist/ +``` + +**Success Criteria:** +- [ ] npm install exit code = 0 +- [ ] npm run build exit code = 0 +- [ ] dist/ directory exists with index.html + +**MAXIMUM 5 ATTEMPTS:** If still failing after 5 tries, STOP and report: +``` +ESCALATION NEEDED: Build failing after 5 attempts +Last error: [paste error] +Attempts made: [list what you tried] +``` + +**Log your progress before proceeding** + +--- + +### ๐Ÿš€ PHASE 3: DEV SERVER VALIDATION + +**Tasks:** +1. Start dev server in background: +```bash + npm run dev > dev-server.log 2>&1 & + DEV_PID=$! + echo $DEV_PID > dev-server.pid +``` +2. Wait 15 seconds for startup +3. Check if server is running: +```bash + sleep 15 + curl -s -o /dev/null -w "%{http_code}" http://localhost:3002 +``` +4. If curl returns 000 or fails: + - Read dev-server.log for errors + - Kill process: `kill $(cat dev-server.pid)` + - Fix the issue + - GO BACK TO PHASE 2 (rebuild might be needed) +5. If curl returns 200: + - Proceed to next phase + +**Self-Check:** +```bash +# Is port listening? +netstat -tlnp | grep 3002 + +# Can we reach it? +curl -I http://localhost:3002 + +# Any errors in log? +tail -20 dev-server.log +``` + +**Success Criteria:** +- [ ] Port 3002 is listening +- [ ] curl returns HTTP 200 +- [ ] No error messages in dev-server.log + +**MAXIMUM 3 ATTEMPTS** + +**Log your progress before proceeding** + +--- + +### ๐ŸŒ PHASE 4: BASIC CONTENT VALIDATION + +**Tasks:** +1. Fetch homepage HTML: +```bash + curl -s http://localhost:3002 > homepage.html +``` +2. Check if content exists: +```bash + # Should have substantial content + wc -c homepage.html # Should be > 1000 bytes + + # Should have Vue app mount + grep 'id="app"' homepage.html + + # Should load Vue + grep -i "vue" homepage.html +``` +3. If homepage is empty or too small: + - Check browser console errors (you'll need to simulate this) + - Likely issues: + * Vue not mounting + * JavaScript errors + * Missing components + - Fix and GO BACK TO PHASE 2 + +**Self-Check:** +```bash +echo "Homepage size: $(wc -c < homepage.html) bytes" +echo "Contains #app div: $(grep -c 'id="app"' homepage.html)" +echo "Vue referenced: $(grep -ic vue homepage.html)" +``` + +**Success Criteria:** +- [ ] homepage.html > 1000 bytes +- [ ] Contains id="app" +- [ ] References Vue + +**Log your progress before proceeding** + +--- + +### โœ… PHASE 5: COMPONENT VALIDATION + +**Tasks:** +1. Verify all required components exist: +```bash + ls src/components/Navigation.vue + ls src/components/Hero.vue + ls src/components/Services.vue + ls src/components/AboutUs.vue + ls src/components/TechStack.vue + ls src/components/Portfolio.vue + ls src/components/ContactForm.vue + ls src/components/Footer.vue +``` +2. Check each component for common errors: +```bash + # Check for syntax errors + for file in src/components/*.vue; do + echo "Checking $file" + # Look for unclosed tags, etc + grep -c '' "$file" + done +``` +3. If any component missing or broken: + - Create or fix it + - Ensure proper Vue 3 syntax + - GO BACK TO PHASE 2 (rebuild) + +**Success Criteria:** +- [ ] All 8 components exist +- [ ] Each has matching open/close tags +- [ ] No obvious syntax errors + +**Log your progress before proceeding** + +--- + +### ๐ŸŽจ PHASE 6: STYLING VALIDATION + +**Tasks:** +1. Check if Tailwind is working: +```bash + # Inspect generated CSS + curl -s http://localhost:3002/src/style.css | head -50 +``` +2. Common Tailwind issues: + - Colors not defined (bg-primary-XXX) + - @apply with undefined classes + - PostCSS not processing +3. If styling broken: + - Fix tailwind.config.js + - Fix CSS files + - GO BACK TO PHASE 2 + +**Self-Check:** +```bash +# Check tailwind.config.js has all colors +grep -A 20 "primary:" tailwind.config.js +``` + +**Success Criteria:** +- [ ] Tailwind colors fully defined +- [ ] CSS loads without errors +- [ ] No PostCSS warnings + +**Log your progress before proceeding** + +--- + +### ๐Ÿ“Š PHASE 7: FINAL CHECKLIST + +**Before declaring success, verify:** +```bash +# 1. Clean build +npm run build && echo "โœ… Build: PASS" || echo "โŒ Build: FAIL" + +# 2. Dev server runs +pkill -f "vite" # Kill old server +npm run dev > /tmp/vite.log 2>&1 & +sleep 10 +curl -s http://localhost:3002 > /dev/null && echo "โœ… Server: PASS" || echo "โŒ Server: FAIL" + +# 3. Content exists +CONTENT_SIZE=$(curl -s http://localhost:3002 | wc -c) +[ $CONTENT_SIZE -gt 1000 ] && echo "โœ… Content: PASS" || echo "โŒ Content: FAIL" + +# 4. All components exist +COMPONENTS=$(ls src/components/*.vue 2>/dev/null | wc -l) +[ $COMPONENTS -eq 8 ] && echo "โœ… Components: PASS" || echo "โŒ Components: FAIL" + +# 5. Configs valid +[ -f vite.config.js ] && echo "โœ… Vite config: PASS" || echo "โŒ Vite config: FAIL" +[ -f tailwind.config.js ] && echo "โœ… Tailwind config: PASS" || echo "โŒ Tailwind config: FAIL" +``` + +**ALL MUST PASS** + +--- + +### ๐Ÿ“ PHASE 8: FINAL REPORT + +Create `DEPLOYMENT_READY.md` with: +```markdown +# OKYSH Website - Autonomous Build Report + +## Build Status: [SUCCESS/FAILED] + +## Iterations Completed: X + +## Phase Results: +- Phase 1 (Setup): [โœ…/โŒ] +- Phase 2 (Build): [โœ…/โŒ] - X attempts +- Phase 3 (Dev Server): [โœ…/โŒ] - X attempts +- Phase 4 (Content): [โœ…/โŒ] +- Phase 5 (Components): [โœ…/โŒ] +- Phase 6 (Styling): [โœ…/โŒ] +- Phase 7 (Final Check): [โœ…/โŒ] + +## Issues Encountered: +1. [Issue 1 and how you fixed it] +2. [Issue 2 and how you fixed it] + +## Final Checklist: +- [ ] npm run build: SUCCESS +- [ ] npm run dev: RUNNING on port 3002 +- [ ] Homepage size: XXX bytes +- [ ] All 8 components exist +- [ ] No console errors +- [ ] Tailwind working + +## Ready for Deployment: [YES/NO] + +## Access: +- Dev Server: http://localhost:3002 +- Build Output: ./dist/ + +## Next Steps: +[What human should do next] +``` + +--- + +## ๐Ÿšจ CRITICAL RULES + +1. **NEVER skip a phase** - each builds on the previous +2. **ALWAYS check exit codes** - don't assume success +3. **READ error messages COMPLETELY** - don't guess +4. **LOG after each phase** - maintain build-log.md +5. **STOP after max attempts** - don't infinite loop +6. **CREATE files for debugging** - save logs, outputs +7. **TEST before proceeding** - verify each phase works + +## ๐ŸŽฏ SUCCESS DEFINITION + +You have succeeded when: +- โœ… All phases completed +- โœ… DEPLOYMENT_READY.md shows all green checkmarks +- โœ… Dev server accessible at http://localhost:3002 +- โœ… Website displays all sections +- โœ… No errors in any logs + +## ๐Ÿšซ FAILURE DEFINITION + +Stop and report if: +- โŒ Any phase fails after max attempts +- โŒ Build errors can't be resolved +- โŒ Dev server won't start after 3 tries +- โŒ You're repeating the same fix (stuck in loop) + +--- + +## ๐Ÿ BEGIN NOW + +Start with Phase 1. Create build-log.md as your first action. +Track everything. Test thoroughly. Be autonomous but disciplined. + +Your success is measured by producing a working website, not by speed. + +GO!