UNPKG

aios-core

Version:

Synkra AIOS: AI-Orchestrated System for Full Stack Development - Core Framework

422 lines (332 loc) 18.5 kB
workflow: id: auto-worktree name: Auto-Worktree - Automatic Isolated Development Environment version: "1.0" description: >- Automatically creates and manages isolated worktrees for story development. Triggered when @dev starts working on a story, ensuring parallel development capability and clean isolation between different development tasks. Part of the Auto-Claude ADE (Autonomous Development Engine) infrastructure. type: automation project_types: - aios-development - autonomous-development - parallel-development # ═══════════════════════════════════════════════════════════════════════════════════ # TRIGGER CONFIGURATION # ═══════════════════════════════════════════════════════════════════════════════════ triggers: # Primary trigger: When @dev starts a story - event: story_started agent: dev condition: projectConfig.autoWorktree.enabled === true action: create_worktree # Secondary trigger: When @po assigns a story - event: story_assigned agent: po condition: projectConfig.autoWorktree.createOnAssign === true action: create_worktree # Manual trigger: Explicit command - event: command command: "*auto-worktree" action: interactive_flow # ═══════════════════════════════════════════════════════════════════════════════════ # CONFIGURATION # ═══════════════════════════════════════════════════════════════════════════════════ config: # Enable automatic worktree creation enabled: true # Create worktree when story is assigned (before development starts) createOnAssign: false # Automatically switch to worktree after creation autoSwitch: true # Show worktree creation summary verbose: true # Cleanup stale worktrees before creating new one autoCleanup: false # Maximum worktrees before requiring cleanup maxWorktrees: 10 # Days before worktree is considered stale staleDays: 30 # ═══════════════════════════════════════════════════════════════════════════════════ # PRE-FLIGHT CHECKS # ═══════════════════════════════════════════════════════════════════════════════════ pre_flight: enabled: true checks: - id: git_repo description: Verify git repository command: git rev-parse --is-inside-work-tree blocking: true error: "Not a git repository. Auto-worktree requires git." - id: worktree_support description: Verify git worktree support command: git worktree list blocking: true error: "Git worktree not supported. Requires git >= 2.5." - id: worktree_manager description: Verify WorktreeManager available file_exists: .aios-core/infrastructure/scripts/worktree-manager.js blocking: true error: "WorktreeManager not found. AIOS infrastructure incomplete." - id: check_limit description: Check worktree limit not exceeded script: | const WorktreeManager = require('./.aios-core/infrastructure/scripts/worktree-manager.js'); const manager = new WorktreeManager(); const count = await manager.getCount(); return count.total < manager.maxWorktrees; blocking: false warning: "Approaching worktree limit. Consider cleanup." # ═══════════════════════════════════════════════════════════════════════════════════ # WORKFLOW SEQUENCE # ═══════════════════════════════════════════════════════════════════════════════════ sequence: # ═════════════════════════════════════════════════════════════════════════════════ # STEP 1: EXTRACT STORY CONTEXT # ═════════════════════════════════════════════════════════════════════════════════ - step: extract_story_context phase: 1 phase_name: "Extract Context" action: extract_story_info description: >- Extract story information from the trigger context. Determines the story ID to use for worktree naming. script: | // Extract story ID from various sources function extractStoryId(context) { // From explicit parameter if (context.storyId) return context.storyId; // From story file path if (context.storyFile) { const match = context.storyFile.match(/story-(\d+\.\d+)/); if (match) return match[1]; } // From current task if (context.currentTask?.storyId) return context.currentTask.storyId; // From git branch (if following convention) const branch = await execGit(['branch', '--show-current']); const branchMatch = branch.match(/story[-\/](\d+\.\d+)/i); if (branchMatch) return branchMatch[1]; return null; } const storyId = extractStoryId(context); if (!storyId) { throw new Error('Could not determine story ID. Please provide explicitly.'); } return { storyId }; outputs: - storyId # ═════════════════════════════════════════════════════════════════════════════════ # STEP 2: CHECK EXISTING WORKTREE # ═════════════════════════════════════════════════════════════════════════════════ - step: check_existing phase: 2 phase_name: "Check Existing" action: check_worktree_exists description: >- Check if a worktree already exists for this story. If exists, skip creation and optionally switch to it. script: | const WorktreeManager = require('./.aios-core/infrastructure/scripts/worktree-manager.js'); const manager = new WorktreeManager(); const exists = await manager.exists(storyId); if (exists) { const info = await manager.get(storyId); return { exists: true, worktree: info, action: config.autoSwitch ? 'switch' : 'skip' }; } return { exists: false, action: 'create' }; outputs: - exists - worktree - action on_exists: log: "Worktree already exists for story {storyId}" skip_to: switch_worktree # ═════════════════════════════════════════════════════════════════════════════════ # STEP 3: AUTO-CLEANUP (OPTIONAL) # ═════════════════════════════════════════════════════════════════════════════════ - step: auto_cleanup phase: 3 phase_name: "Auto Cleanup" action: cleanup_stale_worktrees condition: config.autoCleanup === true description: >- Automatically clean up stale worktrees before creating a new one. Only runs if autoCleanup is enabled in config. script: | const WorktreeManager = require('./.aios-core/infrastructure/scripts/worktree-manager.js'); const manager = new WorktreeManager(); const removed = await manager.cleanupStale(); return { cleaned: removed.length, removedIds: removed }; outputs: - cleaned - removedIds on_cleanup: log: "Cleaned up {cleaned} stale worktrees" # ═════════════════════════════════════════════════════════════════════════════════ # STEP 4: CREATE WORKTREE # ═════════════════════════════════════════════════════════════════════════════════ - step: create_worktree phase: 4 phase_name: "Create Worktree" action: create_isolated_worktree description: >- Create a new isolated worktree for the story. Creates branch auto-claude/{storyId} and working directory. task: create-worktree.md inputs: story_id: "{storyId}" script: | const WorktreeManager = require('./.aios-core/infrastructure/scripts/worktree-manager.js'); const manager = new WorktreeManager(); try { const worktree = await manager.create(storyId); return { success: true, worktree: worktree, path: worktree.path, branch: worktree.branch }; } catch (error) { return { success: false, error: error.message }; } outputs: - success - worktree - path - branch - error on_success: log: "Created worktree at {path}" on_failure: action: halt error: "Failed to create worktree: {error}" # ═════════════════════════════════════════════════════════════════════════════════ # STEP 5: SWITCH TO WORKTREE (OPTIONAL) # ═════════════════════════════════════════════════════════════════════════════════ - step: switch_worktree phase: 5 phase_name: "Switch Context" action: switch_to_worktree condition: config.autoSwitch === true description: >- Automatically switch working context to the new worktree. Updates shell environment and notifies user. script: | const worktreePath = worktree?.path || path; // Note: Cannot actually change parent process cwd // Instead, provide instructions and set environment hint console.log(`\n📂 Switch to worktree:`); console.log(` cd ${worktreePath}\n`); // Set environment variable for shell integration process.env.AIOS_WORKTREE = worktreePath; process.env.AIOS_STORY = storyId; return { worktreePath, instructions: `cd ${worktreePath}` }; outputs: - worktreePath - instructions # ═════════════════════════════════════════════════════════════════════════════════ # STEP 6: DISPLAY SUMMARY # ═════════════════════════════════════════════════════════════════════════════════ - step: display_summary phase: 6 phase_name: "Summary" action: show_summary condition: config.verbose === true description: >- Display workflow completion summary with worktree details and next steps for the developer. template: | ╔══════════════════════════════════════════════════════════════╗ ║ 🌲 Auto-Worktree Complete ║ ╚══════════════════════════════════════════════════════════════╝ Story: {storyId} Worktree: {worktree.path} Branch: {worktree.branch} Status: {worktree.status} ───────────────────────────────────────────────────────────────── 📌 Quick Reference: Navigate: cd {worktree.path} Status: *list-worktrees Merge: *merge-worktree {storyId} Remove: *remove-worktree {storyId} ───────────────────────────────────────────────────────────────── 💡 You are now working in an isolated environment. Changes here won't affect the main branch until merged. # ═══════════════════════════════════════════════════════════════════════════════════ # WORKFLOW COMPLETION # ═══════════════════════════════════════════════════════════════════════════════════ completion: success_message: "Worktree ready for story {storyId}" outputs: - storyId - worktree - path - branch next_steps: - "Navigate to worktree: cd {path}" - "Start development in isolation" - "When done: *merge-worktree {storyId}" # ═══════════════════════════════════════════════════════════════════════════════════ # ERROR HANDLING # ═══════════════════════════════════════════════════════════════════════════════════ error_handling: max_worktrees_reached: message: "Maximum worktrees limit ({maxWorktrees}) reached" suggestion: "Run *cleanup-worktrees to remove stale worktrees" action: halt worktree_creation_failed: message: "Failed to create worktree" suggestion: "Check git status and try again" action: halt story_id_not_found: message: "Could not determine story ID" suggestion: "Provide story ID explicitly: *auto-worktree STORY-42" action: prompt # ═══════════════════════════════════════════════════════════════════════════════════ # INTEGRATION # ═══════════════════════════════════════════════════════════════════════════════════ integration: # Integration with @dev agent dev_agent: hook: on_story_start action: trigger_workflow pass_context: true # Integration with project status project_status: update_on_create: true field: activeWorktree # Integration with status.json status_json: track_worktrees: true include_in_context: true # ═══════════════════════════════════════════════════════════════════════════════════ # METADATA # ═══════════════════════════════════════════════════════════════════════════════════ metadata: story: "1.4" epic: "Epic 1 - Worktree Manager" created: "2026-01-28" author: "@architect (Aria)" dependencies: - worktree-manager.js - create-worktree.md tags: - automation - worktree - isolation - ade