├── .clinerules-architect ├── .clinerules-ask ├── .clinerules-captain ├── .clinerules-code ├── .clinerules-debug ├── .clinerules-test ├── .gitignore ├── .roomodes ├── README.md ├── boomerang_tasks_implementation_plan.md ├── coverage ├── lcov-report │ ├── ContextBuilder.ts.html │ ├── FileSystemScanner.ts.html │ ├── RegistryUpdater.ts.html │ ├── TaskScanner.ts.html │ ├── base.css │ ├── block-navigation.js │ ├── components │ │ ├── ContextBuilder.ts.html │ │ ├── FileSystemScanner.ts.html │ │ ├── RegistryUpdater.ts.html │ │ ├── TaskManager.ts.html │ │ ├── TaskScanner.ts.html │ │ ├── index.html │ │ └── interfaces │ │ │ ├── Task.ts.html │ │ │ └── index.html │ ├── favicon.png │ ├── index.html │ ├── prettify.css │ ├── prettify.js │ ├── sort-arrow-sprite.png │ └── sorter.js └── lcov.info ├── default-system-prompt.md ├── dist ├── TaskScanner.d.ts ├── TaskScanner.js ├── TaskScanner.js.map ├── cli │ ├── captain.d.ts │ ├── captain.js │ ├── captain.js.map │ ├── index.d.ts │ ├── index.js │ ├── index.js.map │ ├── memory-bank.d.ts │ ├── memory-bank.js │ └── memory-bank.js.map ├── index.d.ts ├── index.js ├── index.js.map ├── roo.d.ts ├── roo.js ├── roo.js.map └── scanner │ └── components │ ├── ContextBuilder.d.ts │ ├── ContextBuilder.js │ ├── ContextBuilder.js.map │ ├── FileSystemScanner.d.ts │ ├── FileSystemScanner.js │ ├── FileSystemScanner.js.map │ ├── RegistryUpdater.d.ts │ ├── RegistryUpdater.js │ ├── RegistryUpdater.js.map │ ├── TaskManager.d.ts │ ├── TaskManager.js │ ├── TaskManager.js.map │ ├── TaskScanner.d.ts │ ├── TaskScanner.js │ ├── TaskScanner.js.map │ └── interfaces │ ├── Task.d.ts │ ├── Task.js │ └── Task.js.map ├── docs ├── installation-guide.md └── memory-bank-usage.md ├── jest.config.js ├── package.json ├── refactoring_plan.md ├── rooflow-captainmode-docs ├── captain-mode-implementation.md ├── captain-mode.md ├── mode-management.md └── project-scan-feature.md ├── rooflow-captainmode-supportfiles ├── CONTRIBUTING.md ├── LICENSE └── insert-variables.sh ├── scripts ├── init.js └── postinstall.js ├── src ├── TaskScanner.ts ├── cli │ ├── captain.ts │ ├── index.ts │ └── memory-bank.ts ├── index.js ├── index.ts ├── memory-bank │ ├── MemoryBankIntegration.md │ ├── MemoryBankManager.ts │ ├── MemoryBankSynchronizer.ts │ └── __tests__ │ │ └── MemoryBankSynchronizer.test.ts ├── roo.js ├── roo.ts └── scanner │ ├── components │ ├── ContextBuilder.js │ ├── ContextBuilder.ts │ ├── FileSystemScanner.js │ ├── FileSystemScanner.ts │ ├── RegistryUpdater.js │ ├── RegistryUpdater.ts │ ├── TaskManager.ts │ ├── TaskScanner.js │ ├── TaskScanner.ts │ ├── __tests__ │ │ ├── ContextBuilder.test.ts │ │ ├── FileSystemScanner.test.ts │ │ ├── RegistryUpdater.test.ts │ │ ├── TaskManager.test.ts │ │ └── TaskScanner.test.ts │ └── interfaces │ │ └── Task.ts │ └── tests │ ├── ContextBuilder.test.ts │ ├── FileSystemScanner.test.ts │ ├── RegistryUpdater.test.ts │ └── TaskScanner.test.ts ├── test └── tsconfig.json /.clinerules-architect: -------------------------------------------------------------------------------- 1 | mode: architect 2 | 3 | identity: 4 | name: Architect 5 | description: "Focuses on system design, documentation structure, and project organization. Initializes and manages the project's Memory Bank, guides high-level design, and coordinates mode interactions." 6 | 7 | memory_bank_strategy: 8 | initialization: | 9 | - **CHECK FOR MEMORY BANK:** 10 | 11 | * First, check if the memory-bank/ directory exists. 12 | 13 | 14 | . 15 | false 16 | 17 | * If memory-bank DOES exist, skip immediately to `if_memory_bank_exists`. 18 | -------------------------------------------------------------------------------- /.clinerules-captain: -------------------------------------------------------------------------------- 1 | mode: captain 2 | 3 | identity: 4 | name: Captain 5 | description: "Project orchestration and task management mode, responsible for breaking down complex tasks and delegating to specialized modes." 6 | 7 | capabilities: 8 | overview: "Orchestrates project tasks, manages Memory Bank, and coordinates between modes." 9 | initial_context: "Project structure and task registry from Memory Bank." 10 | key_features: 11 | - "Task decomposition and delegation" 12 | - "Progress tracking" 13 | - "Mode coordination" 14 | - "Memory Bank management" 15 | - "Boomerang task handling" 16 | 17 | memory_bank_strategy: 18 | initialization: | 19 | - **CHECK FOR MEMORY BANK AND TASK REGISTRY:** 20 | 21 | * First, check if memory-bank/ exists and contains taskRegistry.md 22 | 23 | 24 | memory-bank 25 | false 26 | 27 | - If memory-bank exists but taskRegistry.md doesn't, create it 28 | - Then proceed with standard memory bank initialization 29 | 30 | mode_collaboration: 31 | architect: 32 | - Receive high-level design decisions 33 | - Request architectural review 34 | - Handle system structure changes 35 | code: 36 | - Delegate implementation tasks 37 | - Track coding progress 38 | - Receive completion updates 39 | test: 40 | - Coordinate testing efforts 41 | - Monitor test results 42 | - Handle test-driven tasks 43 | debug: 44 | - Manage issue investigation 45 | - Track bug fixes 46 | - Coordinate debugging efforts 47 | ask: 48 | - Request documentation 49 | - Gather project information 50 | - Share knowledge base updates 51 | 52 | mode_triggers: 53 | incoming: 54 | - condition: task_completed 55 | action: "Update task registry and delegate next task" 56 | - condition: task_blocked 57 | action: "Analyze blocker and coordinate resolution" 58 | - condition: needs_review 59 | action: "Coordinate review process with appropriate mode" 60 | outgoing: 61 | - condition: implementation_needed 62 | target: "code" 63 | - condition: testing_required 64 | target: "test" 65 | - condition: documentation_needed 66 | target: "ask" 67 | - condition: debug_required 68 | target: "debug" 69 | - condition: design_review_needed 70 | target: "architect" 71 | 72 | task_management: 73 | delegation_rules: 74 | - "Match task type to mode expertise" 75 | - "Consider mode availability and current workload" 76 | - "Track dependencies between tasks" 77 | - "Monitor task completion status" 78 | progress_tracking: 79 | - "Update task registry on state changes" 80 | - "Log mode transitions in Memory Bank" 81 | - "Track completion metrics" 82 | - "Monitor blockers and dependencies" 83 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | memory-bank/ 2 | !src/memory-bank/ 3 | dev/ 4 | .vscode 5 | .roomodes 6 | .roo/ 7 | node_modules/ 8 | package-lock.json 9 | !config/ 10 | .rooignore 11 | !config/.rooignore -------------------------------------------------------------------------------- /.roomodes: -------------------------------------------------------------------------------- 1 | { 2 | "customModes": [ 3 | { 4 | "slug": "test", 5 | "name": "Test", 6 | "roleDefinition": "You are Roo's Test mode, responsible for test-driven development, test execution, and quality assurance. You write test cases before implementation, validate code against requirements, analyze test results, and coordinate with other modes for fixes. You collaborate with Architect mode for test strategy, Code mode for implementation, Debug mode for failures, and Ask mode for clarification. You have READ access to all files, can execute tests, and can update Memory Bank during UMB commands.", 7 | "groups": [ 8 | "read", 9 | "browser", 10 | "command", 11 | "edit", 12 | "mcp" 13 | ], 14 | "source": "project" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RooFlow Captain Mode Implementation 2 | 3 | This repository contains the implementation of the Captain Mode for RooFlow, developed by Martin. The Captain Mode serves as a project orchestrator and task manager, providing enhanced project coordination and workflow efficiency. 4 | 5 | ## 🎯 Overview 6 | 7 | This implementation enhances the Captain Mode with: 8 | - Advanced task dependency tracking 9 | - Project metrics monitoring 10 | - Automated mode transitions 11 | - Comprehensive task registry system 12 | 13 | ## 🔧 Key Components 14 | 15 | ### Task Registry System 16 | - Tracks active and completed tasks 17 | - Manages task dependencies 18 | - Records mode transitions 19 | - Monitors project metrics 20 | 21 | ### Enhanced Mode Transitions 22 | - Automatic switching between specialized modes 23 | - Return triggers for task completion 24 | - Post-return action handling 25 | - Context preservation during transitions 26 | 27 | ### Project Metrics 28 | - Task completion time tracking 29 | - Mode transition analysis 30 | - Dependency chain monitoring 31 | - Progress visualization 32 | 33 | ## 📂 Project Structure 34 | 35 | ``` 36 | . 37 | ├── rooflow-captainmode-docs/ 38 | │ ├── captain-mode.md # Captain mode documentation 39 | │ └── captain-mode-implementation.md # Implementation details 40 | ├── memory-bank/ 41 | │ ├── activeContext.md # Tracks the current session's context 42 | │ ├── decisionLog.md # Records architectural and implementation decisions 43 | │ ├── productContext.md # Provides a high-level overview of the project 44 | │ ├── progress.md # Tracks the progress of the project 45 | │ ├── systemPatterns.md # (Optional) Documents recurring patterns and standards 46 | │ └── taskRegistry.md # Task tracking system 47 | ├── .roo/ 48 | │ ├── cline_custom_modes.json # Mode configurations 49 | │ └── custom-instructions.yaml # Mode instructions 50 | ├── .clinerules-architect # Architect mode rules 51 | ├── .clinerules-ask # Ask mode rules 52 | ├── .clinerules-captain # Captain mode rules 53 | ├── .clinerules-code # Code mode rules 54 | ├── .clinerules-debug # Debug mode rules 55 | ├── .clinerules-test # Test mode rules 56 | ├── rooflow-captainmode-supportfiles/ # Supporting files 57 | │ ├── LICENSE 58 | │ ├── CONTRIBUTING.md 59 | │ └── insert-variables.sh 60 | ├── .rooignore # Roo ignore patterns 61 | └── README.md # This file (or rooflow-captainmode-README.md if a README.md already exists) 62 | ``` 63 | 64 | ## 💥 npm Package 65 | 66 | RooFlow Captain Mode is available as an npm package for easy integration into your projects: 67 | 68 | ```bash 69 | npm install rooflow-captainmode --save-dev 70 | ``` 71 | 72 | The package provides: 73 | - All necessary configuration files 74 | - Command-line tools for managing tasks and the memory bank 75 | - Automatic setup and initialization 76 | 77 | ### npm Scripts 78 | 79 | ```bash 80 | # Initialize RooFlow Captain Mode in your project 81 | npx rooflow-captainmode init 82 | 83 | # Manage tasks 84 | npx rooflow-captainmode tasks list 85 | npx rooflow-captainmode tasks create "Task description" --mode code 86 | 87 | # Manage memory bank 88 | npx rooflow-captainmode memory-bank status 89 | npx rooflow-captainmode memory-bank create 90 | ``` 91 | 92 | For more information, see the [Installation Guide](docs/installation-guide.md). 93 | 94 | ## 🚀 Features 95 | 96 | 1. **Task Dependencies** 97 | - Dependency tracking in task registry 98 | - Blocking/blocked status management 99 | - Automated prioritization based on dependencies 100 | 101 | 2. **Project Metrics** 102 | - Completion time tracking 103 | - Mode transition monitoring 104 | - Task pattern analysis 105 | - Progress insights 106 | 107 | 3. **Mode-Specific Context** 108 | - Specialized context preservation 109 | - Seamless context transfer 110 | - Mode-specific data storage 111 | 112 | 4. **Task Validation** 113 | - Completion criteria verification 114 | - Handoff checklists 115 | - Context validation 116 | 117 | ## ⚙️ Installation 118 | 119 | ### Quick Start 120 | 121 | 1. Install via npm (recommended): 122 | ```bash 123 | npm install rooflow-captainmode --save-dev 124 | npx rooflow-captainmode init 125 | ``` 126 | 127 | 2. Open your project in VS Code with the Roo Code extension installed. 128 | 129 | 3. Select "Captain" mode in the Roo Code chat panel. 130 | 131 | ### Detailed Installation 132 | 133 | For detailed installation instructions, configuration options, and usage examples, see the [Installation Guide](docs/installation-guide.md). 134 | 135 | ### Manual Installation 136 | 137 | If you prefer to manually install: 138 | 139 | 1. Clone or download the repository from GitHub. 140 | 2. Copy the necessary configuration files to your project. 141 | 3. Open the project in VS Code with the Roo Code extension installed. 142 | 4. Select the desired mode in the Roo Code chat panel. 143 | 144 | ## 🤝 Contributing 145 | 146 | Contributions are welcome! Please check the [CONTRIBUTING.md](rooflow-captainmode-supportfiles/CONTRIBUTING.md) file for guidelines. 147 | 148 | ## 📝 License 149 | 150 | [Apache 2.0](rooflow-captainmode-supportfiles/LICENSE) 151 | -------------------------------------------------------------------------------- /boomerang_tasks_implementation_plan.md: -------------------------------------------------------------------------------- 1 | ### Implementation Plan: Boomerang Tasks in Captain Mode 2 | 3 | 1. **Update Captain Mode Configuration:** 4 | * Ensure the `captain` mode definition in `.roomodes` includes the necessary permissions and groups (read, browser, command, mcp, edit). 5 | * Add a `memory_bank_strategy` section to the `captain` mode definition to specify how it interacts with the Memory Bank. 6 | * Add `mode_collaboration` and `mode_triggers` to define how Captain mode interacts with other modes. 7 | 8 | 2. **Implement Boomerang Task Logic:** 9 | * Modify the Captain mode's core logic to handle task delegation and tracking using the Boomerang Tasks pattern. 10 | * Implement a mechanism to monitor the status of delegated tasks and trigger transitions based on task completion, errors, or other events. 11 | * Update the `taskRegistry.md` file to reflect the current status of tasks and mode transitions. 12 | 13 | 3. **Update Task Registry:** 14 | * Modify the `taskRegistry.md` file to include additional fields for tracking task dependencies, metrics, and mode transitions. 15 | * Implement a mechanism to automatically update the task registry when tasks are created, completed, or transitioned between modes. 16 | 17 | 4. **Validation:** 18 | * Validate task delegation, progress tracking, and mode transitions while working on the implementation. 19 | * Ensure that the Memory Bank is properly updated and that the context is preserved across sessions. 20 | 21 | 5. **Documentation:** 22 | * Update the Captain Mode documentation to reflect the changes made during the implementation process. 23 | * Include migration guides, API documentation, and usage examples. 24 | 25 | ### Implementation Steps 26 | 27 | 1. **Configuration Updates:** 28 | * Update `.roomodes` to include Captain mode definition with correct permissions and groups. 29 | * Update `.clinerules-captain` to define the memory bank strategy and mode collaboration settings. 30 | 31 | 2. **Core Logic Implementation:** 32 | * Modify `src/roo.ts` to implement the Boomerang Tasks functionality. 33 | * Implement task delegation logic based on task type and mode expertise. 34 | * Implement task status tracking and mode transition triggers. 35 | 36 | 3. **Task Registry Updates:** 37 | * Modify `memory-bank/taskRegistry.md` to include additional fields for tracking task dependencies, metrics, and mode transitions. 38 | * Implement a mechanism to automatically update the task registry when tasks are created, completed, or transitioned between modes. 39 | 40 | 4. **Validation:** 41 | * Validate task delegation, progress tracking, and mode transitions while working on the implementation. 42 | * Ensure that the Memory Bank is properly updated and that the context is preserved across sessions. 43 | 44 | 5. **Documentation:** 45 | * Update the Captain Mode documentation to reflect the changes made during the implementation process. 46 | * Include migration guides, API documentation, and usage examples. 47 | 48 | ### Mermaid Diagram 49 | 50 | ```mermaid 51 | graph LR 52 | A[Start] --> B{Configuration Updates}; 53 | B --> C{Implement Boomerang Task Logic}; 54 | C --> D{Update Task Registry}; 55 | D --> E{Validation}; 56 | E --> F{Documentation}; 57 | F --> G[End]; -------------------------------------------------------------------------------- /coverage/lcov-report/base.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin:0; padding: 0; 3 | height: 100%; 4 | } 5 | body { 6 | font-family: Helvetica Neue, Helvetica, Arial; 7 | font-size: 14px; 8 | color:#333; 9 | } 10 | .small { font-size: 12px; } 11 | *, *:after, *:before { 12 | -webkit-box-sizing:border-box; 13 | -moz-box-sizing:border-box; 14 | box-sizing:border-box; 15 | } 16 | h1 { font-size: 20px; margin: 0;} 17 | h2 { font-size: 14px; } 18 | pre { 19 | font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; 20 | margin: 0; 21 | padding: 0; 22 | -moz-tab-size: 2; 23 | -o-tab-size: 2; 24 | tab-size: 2; 25 | } 26 | a { color:#0074D9; text-decoration:none; } 27 | a:hover { text-decoration:underline; } 28 | .strong { font-weight: bold; } 29 | .space-top1 { padding: 10px 0 0 0; } 30 | .pad2y { padding: 20px 0; } 31 | .pad1y { padding: 10px 0; } 32 | .pad2x { padding: 0 20px; } 33 | .pad2 { padding: 20px; } 34 | .pad1 { padding: 10px; } 35 | .space-left2 { padding-left:55px; } 36 | .space-right2 { padding-right:20px; } 37 | .center { text-align:center; } 38 | .clearfix { display:block; } 39 | .clearfix:after { 40 | content:''; 41 | display:block; 42 | height:0; 43 | clear:both; 44 | visibility:hidden; 45 | } 46 | .fl { float: left; } 47 | @media only screen and (max-width:640px) { 48 | .col3 { width:100%; max-width:100%; } 49 | .hide-mobile { display:none!important; } 50 | } 51 | 52 | .quiet { 53 | color: #7f7f7f; 54 | color: rgba(0,0,0,0.5); 55 | } 56 | .quiet a { opacity: 0.7; } 57 | 58 | .fraction { 59 | font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; 60 | font-size: 10px; 61 | color: #555; 62 | background: #E8E8E8; 63 | padding: 4px 5px; 64 | border-radius: 3px; 65 | vertical-align: middle; 66 | } 67 | 68 | div.path a:link, div.path a:visited { color: #333; } 69 | table.coverage { 70 | border-collapse: collapse; 71 | margin: 10px 0 0 0; 72 | padding: 0; 73 | } 74 | 75 | table.coverage td { 76 | margin: 0; 77 | padding: 0; 78 | vertical-align: top; 79 | } 80 | table.coverage td.line-count { 81 | text-align: right; 82 | padding: 0 5px 0 20px; 83 | } 84 | table.coverage td.line-coverage { 85 | text-align: right; 86 | padding-right: 10px; 87 | min-width:20px; 88 | } 89 | 90 | table.coverage td span.cline-any { 91 | display: inline-block; 92 | padding: 0 5px; 93 | width: 100%; 94 | } 95 | .missing-if-branch { 96 | display: inline-block; 97 | margin-right: 5px; 98 | border-radius: 3px; 99 | position: relative; 100 | padding: 0 4px; 101 | background: #333; 102 | color: yellow; 103 | } 104 | 105 | .skip-if-branch { 106 | display: none; 107 | margin-right: 10px; 108 | position: relative; 109 | padding: 0 4px; 110 | background: #ccc; 111 | color: white; 112 | } 113 | .missing-if-branch .typ, .skip-if-branch .typ { 114 | color: inherit !important; 115 | } 116 | .coverage-summary { 117 | border-collapse: collapse; 118 | width: 100%; 119 | } 120 | .coverage-summary tr { border-bottom: 1px solid #bbb; } 121 | .keyline-all { border: 1px solid #ddd; } 122 | .coverage-summary td, .coverage-summary th { padding: 10px; } 123 | .coverage-summary tbody { border: 1px solid #bbb; } 124 | .coverage-summary td { border-right: 1px solid #bbb; } 125 | .coverage-summary td:last-child { border-right: none; } 126 | .coverage-summary th { 127 | text-align: left; 128 | font-weight: normal; 129 | white-space: nowrap; 130 | } 131 | .coverage-summary th.file { border-right: none !important; } 132 | .coverage-summary th.pct { } 133 | .coverage-summary th.pic, 134 | .coverage-summary th.abs, 135 | .coverage-summary td.pct, 136 | .coverage-summary td.abs { text-align: right; } 137 | .coverage-summary td.file { white-space: nowrap; } 138 | .coverage-summary td.pic { min-width: 120px !important; } 139 | .coverage-summary tfoot td { } 140 | 141 | .coverage-summary .sorter { 142 | height: 10px; 143 | width: 7px; 144 | display: inline-block; 145 | margin-left: 0.5em; 146 | background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; 147 | } 148 | .coverage-summary .sorted .sorter { 149 | background-position: 0 -20px; 150 | } 151 | .coverage-summary .sorted-desc .sorter { 152 | background-position: 0 -10px; 153 | } 154 | .status-line { height: 10px; } 155 | /* yellow */ 156 | .cbranch-no { background: yellow !important; color: #111; } 157 | /* dark red */ 158 | .red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } 159 | .low .chart { border:1px solid #C21F39 } 160 | .highlighted, 161 | .highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ 162 | background: #C21F39 !important; 163 | } 164 | /* medium red */ 165 | .cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } 166 | /* light red */ 167 | .low, .cline-no { background:#FCE1E5 } 168 | /* light green */ 169 | .high, .cline-yes { background:rgb(230,245,208) } 170 | /* medium green */ 171 | .cstat-yes { background:rgb(161,215,106) } 172 | /* dark green */ 173 | .status-line.high, .high .cover-fill { background:rgb(77,146,33) } 174 | .high .chart { border:1px solid rgb(77,146,33) } 175 | /* dark yellow (gold) */ 176 | .status-line.medium, .medium .cover-fill { background: #f9cd0b; } 177 | .medium .chart { border:1px solid #f9cd0b; } 178 | /* light yellow */ 179 | .medium { background: #fff4c2; } 180 | 181 | .cstat-skip { background: #ddd; color: #111; } 182 | .fstat-skip { background: #ddd; color: #111 !important; } 183 | .cbranch-skip { background: #ddd !important; color: #111; } 184 | 185 | span.cline-neutral { background: #eaeaea; } 186 | 187 | .coverage-summary td.empty { 188 | opacity: .5; 189 | padding-top: 4px; 190 | padding-bottom: 4px; 191 | line-height: 1; 192 | color: #888; 193 | } 194 | 195 | .cover-fill, .cover-empty { 196 | display:inline-block; 197 | height: 12px; 198 | } 199 | .chart { 200 | line-height: 0; 201 | } 202 | .cover-empty { 203 | background: white; 204 | } 205 | .cover-full { 206 | border-right: none !important; 207 | } 208 | pre.prettyprint { 209 | border: none !important; 210 | padding: 0 !important; 211 | margin: 0 !important; 212 | } 213 | .com { color: #999 !important; } 214 | .ignore-none { color: #999; font-weight: normal; } 215 | 216 | .wrapper { 217 | min-height: 100%; 218 | height: auto !important; 219 | height: 100%; 220 | margin: 0 auto -48px; 221 | } 222 | .footer, .push { 223 | height: 48px; 224 | } 225 | -------------------------------------------------------------------------------- /coverage/lcov-report/block-navigation.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | var jumpToCode = (function init() { 3 | // Classes of code we would like to highlight in the file view 4 | var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; 5 | 6 | // Elements to highlight in the file listing view 7 | var fileListingElements = ['td.pct.low']; 8 | 9 | // We don't want to select elements that are direct descendants of another match 10 | var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` 11 | 12 | // Selecter that finds elements on the page to which we can jump 13 | var selector = 14 | fileListingElements.join(', ') + 15 | ', ' + 16 | notSelector + 17 | missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` 18 | 19 | // The NodeList of matching elements 20 | var missingCoverageElements = document.querySelectorAll(selector); 21 | 22 | var currentIndex; 23 | 24 | function toggleClass(index) { 25 | missingCoverageElements 26 | .item(currentIndex) 27 | .classList.remove('highlighted'); 28 | missingCoverageElements.item(index).classList.add('highlighted'); 29 | } 30 | 31 | function makeCurrent(index) { 32 | toggleClass(index); 33 | currentIndex = index; 34 | missingCoverageElements.item(index).scrollIntoView({ 35 | behavior: 'smooth', 36 | block: 'center', 37 | inline: 'center' 38 | }); 39 | } 40 | 41 | function goToPrevious() { 42 | var nextIndex = 0; 43 | if (typeof currentIndex !== 'number' || currentIndex === 0) { 44 | nextIndex = missingCoverageElements.length - 1; 45 | } else if (missingCoverageElements.length > 1) { 46 | nextIndex = currentIndex - 1; 47 | } 48 | 49 | makeCurrent(nextIndex); 50 | } 51 | 52 | function goToNext() { 53 | var nextIndex = 0; 54 | 55 | if ( 56 | typeof currentIndex === 'number' && 57 | currentIndex < missingCoverageElements.length - 1 58 | ) { 59 | nextIndex = currentIndex + 1; 60 | } 61 | 62 | makeCurrent(nextIndex); 63 | } 64 | 65 | return function jump(event) { 66 | if ( 67 | document.getElementById('fileSearch') === document.activeElement && 68 | document.activeElement != null 69 | ) { 70 | // if we're currently focused on the search input, we don't want to navigate 71 | return; 72 | } 73 | 74 | switch (event.which) { 75 | case 78: // n 76 | case 74: // j 77 | goToNext(); 78 | break; 79 | case 66: // b 80 | case 75: // k 81 | case 80: // p 82 | goToPrevious(); 83 | break; 84 | } 85 | }; 86 | })(); 87 | window.addEventListener('keydown', jumpToCode); 88 | -------------------------------------------------------------------------------- /coverage/lcov-report/components/interfaces/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for components/interfaces 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files components/interfaces

23 |
24 | 25 |
26 | 100% 27 | Statements 28 | 6/6 29 |
30 | 31 | 32 |
33 | 100% 34 | Branches 35 | 2/2 36 |
37 | 38 | 39 |
40 | 100% 41 | Functions 42 | 1/1 43 |
44 | 45 | 46 |
47 | 100% 48 | Lines 49 | 6/6 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
FileStatementsBranchesFunctionsLines
Task.ts 84 |
85 |
100%6/6100%2/2100%1/1100%6/6
98 |
99 |
100 |
101 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /coverage/lcov-report/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shipdocs/RooFlow-captainmode/e5e455225729a4bfcc53e2d253a4cd621e065bdd/coverage/lcov-report/favicon.png -------------------------------------------------------------------------------- /coverage/lcov-report/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for All files 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files

23 |
24 | 25 |
26 | 94.2% 27 | Statements 28 | 325/345 29 |
30 | 31 | 32 |
33 | 80.45% 34 | Branches 35 | 107/133 36 |
37 | 38 | 39 |
40 | 100% 41 | Functions 42 | 53/53 43 |
44 | 45 | 46 |
47 | 94.59% 48 | Lines 49 | 315/333 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 |
FileStatementsBranchesFunctionsLines
components 84 |
85 |
94.1%319/33980.15%105/131100%52/5294.49%309/327
components/interfaces 99 |
100 |
100%6/6100%2/2100%1/1100%6/6
113 |
114 |
115 |
116 | 121 | 122 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /coverage/lcov-report/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} 2 | -------------------------------------------------------------------------------- /coverage/lcov-report/sort-arrow-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shipdocs/RooFlow-captainmode/e5e455225729a4bfcc53e2d253a4cd621e065bdd/coverage/lcov-report/sort-arrow-sprite.png -------------------------------------------------------------------------------- /dist/TaskScanner.d.ts: -------------------------------------------------------------------------------- 1 | export type Priority = 'low' | 'medium' | 'high' | 'none' | undefined; 2 | export interface TaskMarker { 3 | type: 'TODO' | 'FIXME' | 'NOTE' | 'HACK' | 'BUG' | 'ISSUE'; 4 | description: string; 5 | priority?: Priority; 6 | assignee?: string; 7 | labels: string[]; 8 | } 9 | export interface TaskLocation { 10 | filePath: string; 11 | lineNumber: number; 12 | columnNumber: number; 13 | context: string; 14 | } 15 | export interface DiscoveredTask { 16 | marker: TaskMarker; 17 | location: TaskLocation; 18 | } 19 | export interface TaskScanResults { 20 | tasks: DiscoveredTask[]; 21 | statistics: { 22 | totalTasks: number; 23 | byType: Map; 24 | byPriority: Map; 25 | byLabel: Map; 26 | }; 27 | } 28 | export interface TaskScanOptions { 29 | include?: string[]; 30 | exclude?: string[]; 31 | customMarkers?: string[]; 32 | } 33 | export declare class TaskScanner { 34 | private readonly options; 35 | private static readonly DEFAULT_MARKERS; 36 | private static readonly MARKER_PATTERN; 37 | private static readonly PRIORITY_PATTERN; 38 | private static readonly LABEL_PATTERN; 39 | private static readonly ASSIGNEE_PATTERN; 40 | constructor(options?: TaskScanOptions); 41 | scanFile(filePath: string): Promise; 42 | scanDirectory(dirPath: string): Promise; 43 | private getFilesToScan; 44 | private extractPriority; 45 | private extractLabels; 46 | private extractAssignee; 47 | } 48 | -------------------------------------------------------------------------------- /dist/TaskScanner.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"TaskScanner.js","sourceRoot":"","sources":["../src/TaskScanner.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/cli/captain.d.ts: -------------------------------------------------------------------------------- 1 | import { Command } from 'commander'; 2 | import { TaskStatus } from '../scanner/components/interfaces/Task'; 3 | import { Roo } from '../roo'; 4 | export declare class Captain { 5 | constructor(); 6 | notifyTaskCreated(taskId: string, mode: string): void; 7 | updateTaskStatus(taskId: string, newStatus: TaskStatus): void; 8 | switchMode(mode: string): void; 9 | } 10 | export declare function setupCaptainCommands(program: Command, roo: Roo): void; 11 | -------------------------------------------------------------------------------- /dist/cli/captain.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.Captain = void 0; 4 | exports.setupCaptainCommands = setupCaptainCommands; 5 | const Task_1 = require("../scanner/components/interfaces/Task"); 6 | class Captain { 7 | constructor() { 8 | // Initialize captain 9 | } 10 | notifyTaskCreated(taskId, mode) { 11 | // Handle task creation notification 12 | } 13 | updateTaskStatus(taskId, newStatus) { 14 | // Handle task status update 15 | } 16 | switchMode(mode) { 17 | // Handle mode switching 18 | } 19 | } 20 | exports.Captain = Captain; 21 | function setupCaptainCommands(program, roo) { 22 | program 23 | .command('task:create') 24 | .description('Create a new task and assign it to a mode') 25 | .argument('', 'Task description') 26 | .argument('', 'Target mode (architect, code, test, debug, ask)') 27 | .option('-d, --depends ', 'Comma-separated list of dependent task IDs') 28 | .action((description, mode, options) => { 29 | const dependencies = options.depends ? options.depends.split(',') : undefined; 30 | const taskId = roo.createTask(description, mode, dependencies); 31 | console.log(`Created task ${taskId}`); 32 | }); 33 | program 34 | .command('task:delegate') 35 | .description('Delegate a task to another mode') 36 | .argument('', 'Task ID') 37 | .argument('', 'Target mode (architect, code, test, debug, ask)') 38 | .argument('', 'Reason for delegation') 39 | .action((taskId, mode, reason) => { 40 | roo.delegateTask(taskId, mode, reason); 41 | console.log(`Delegated task ${taskId} to ${mode}`); 42 | }); 43 | program 44 | .command('task:status') 45 | .description('Update task status') 46 | .argument('', 'Task ID') 47 | .argument('', 'New status (pending, in_progress, blocked, completed, cancelled)') 48 | .action((taskId, status) => { 49 | const taskStatus = status.toUpperCase(); 50 | if (!Task_1.TaskStatus[taskStatus]) { 51 | throw new Error('Invalid status. Must be one of: pending, in_progress, blocked, completed, cancelled'); 52 | } 53 | roo.updateTaskStatus(taskId, Task_1.TaskStatus[taskStatus]); 54 | console.log(`Updated task ${taskId} status to ${status}`); 55 | }); 56 | program 57 | .command('mode:switch') 58 | .description('Switch to another mode') 59 | .argument('', 'Target mode (architect, code, test, debug, ask)') 60 | .argument('', 'Reason for switching') 61 | .action((mode, reason) => { 62 | //captain.switchMode(mode, reason); 63 | console.log(`Switched to ${mode} mode`); 64 | }); 65 | } 66 | //# sourceMappingURL=captain.js.map -------------------------------------------------------------------------------- /dist/cli/captain.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"captain.js","sourceRoot":"","sources":["../../src/cli/captain.ts"],"names":[],"mappings":";;;AA0BA,oDA+CC;AAxED,gEAAmE;AAOnE,MAAa,OAAO;IAChB;QACI,qBAAqB;IACzB,CAAC;IAED,iBAAiB,CAAC,MAAc,EAAE,IAAY;QAC1C,oCAAoC;IACxC,CAAC;IAED,gBAAgB,CAAC,MAAc,EAAE,SAAqB;QAClD,4BAA4B;IAChC,CAAC;IAED,UAAU,CAAC,IAAY;QACnB,wBAAwB;IAC5B,CAAC;CACJ;AAhBD,0BAgBC;AAED,SAAgB,oBAAoB,CAAC,OAAgB,EAAE,GAAQ;IAC3D,OAAO;SACF,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,2CAA2C,CAAC;SACxD,QAAQ,CAAC,eAAe,EAAE,kBAAkB,CAAC;SAC7C,QAAQ,CAAC,QAAQ,EAAE,iDAAiD,CAAC;SACrE,MAAM,CAAC,yBAAyB,EAAE,4CAA4C,CAAC;SAC/E,MAAM,CAAC,CAAC,WAAmB,EAAE,IAAY,EAAE,OAAoB,EAAE,EAAE;QAChE,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9E,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEP,OAAO;SACF,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,iCAAiC,CAAC;SAC9C,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;SAC/B,QAAQ,CAAC,QAAQ,EAAE,iDAAiD,CAAC;SACrE,QAAQ,CAAC,UAAU,EAAE,uBAAuB,CAAC;SAC7C,MAAM,CAAC,CAAC,MAAc,EAAE,IAAY,EAAE,MAAc,EAAE,EAAE;QACrD,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,OAAO,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEP,OAAO;SACF,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,oBAAoB,CAAC;SACjC,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;SAC/B,QAAQ,CAAC,UAAU,EAAE,kEAAkE,CAAC;SACxF,MAAM,CAAC,CAAC,MAAc,EAAE,MAAc,EAAE,EAAE;QACvC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,EAA6B,CAAC;QACnE,IAAI,CAAC,iBAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,qFAAqF,CAAC,CAAC;QAC3G,CAAC;QACD,GAAG,CAAC,gBAAgB,CAAC,MAAM,EAAE,iBAAU,CAAC,UAAU,CAAC,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,cAAc,MAAM,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEP,OAAO;SACF,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,wBAAwB,CAAC;SACrC,QAAQ,CAAC,QAAQ,EAAE,iDAAiD,CAAC;SACrE,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;SAC5C,MAAM,CAAC,CAAC,IAAY,EAAE,MAAc,EAAE,EAAE;QACrC,mCAAmC;QACnC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,OAAO,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACX,CAAC"} -------------------------------------------------------------------------------- /dist/cli/index.d.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | export {}; 3 | -------------------------------------------------------------------------------- /dist/cli/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | "use strict"; 3 | Object.defineProperty(exports, "__esModule", { value: true }); 4 | const commander_1 = require("commander"); 5 | const captain_1 = require("./captain"); 6 | const roo_1 = require("../roo"); 7 | const program = new commander_1.Command(); 8 | const roo = new roo_1.Roo(); 9 | const captain = new captain_1.Captain(); 10 | program 11 | .name('roo') 12 | .description('Roo CLI - Project Orchestration and Task Management') 13 | .version('1.0.0'); 14 | (0, captain_1.setupCaptainCommands)(program, roo); 15 | program.parse(process.argv); 16 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/cli/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,uCAA0D;AAC1D,gCAA6B;AAE7B,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAC9B,MAAM,GAAG,GAAG,IAAI,SAAG,EAAE,CAAC;AACtB,MAAM,OAAO,GAAG,IAAI,iBAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,qDAAqD,CAAC;KAClE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,IAAA,8BAAoB,EAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAEnC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"} -------------------------------------------------------------------------------- /dist/cli/memory-bank.d.ts: -------------------------------------------------------------------------------- 1 | import { Command } from 'commander'; 2 | import { Roo } from '../roo'; 3 | export declare function setupMemoryBankCommands(program: Command, roo: Roo): void; 4 | -------------------------------------------------------------------------------- /dist/cli/memory-bank.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.setupMemoryBankCommands = setupMemoryBankCommands; 4 | const MemoryBankManager_1 = require("../memory-bank/MemoryBankManager"); 5 | function setupMemoryBankCommands(program, roo) { 6 | const memoryBankCommand = program 7 | .command('memory-bank') 8 | .description('Memory Bank management commands'); 9 | memoryBankCommand 10 | .command('status') 11 | .description('Check Memory Bank status') 12 | .action(async () => { 13 | const memoryBankManager = new MemoryBankManager_1.MemoryBankManager(roo.getRootPath()); 14 | const status = await memoryBankManager.initialize(); 15 | console.log('Memory Bank Status:'); 16 | console.log(`- Active: ${status.active ? 'Yes' : 'No'}`); 17 | if (status.lastSynchronized) { 18 | console.log(`- Last Synchronized: ${status.lastSynchronized.toISOString()}`); 19 | } 20 | if (status.missingFiles && status.missingFiles.length > 0) { 21 | console.log(`- Missing Files: ${status.missingFiles.join(', ')}`); 22 | } 23 | }); 24 | memoryBankCommand 25 | .command('create') 26 | .description('Create Memory Bank if it does not exist') 27 | .action(async () => { 28 | const memoryBankManager = new MemoryBankManager_1.MemoryBankManager(roo.getRootPath()); 29 | const result = await memoryBankManager.createMemoryBank(); 30 | if (result.success) { 31 | console.log('Memory Bank created successfully'); 32 | console.log(`Created files: ${result.updatedFiles.join(', ')}`); 33 | } 34 | else { 35 | console.error('Failed to create Memory Bank'); 36 | if (result.errors) { 37 | console.error(`Errors: ${result.errors.join(', ')}`); 38 | } 39 | } 40 | }); 41 | memoryBankCommand 42 | .command('validate') 43 | .description('Validate Memory Bank structure') 44 | .action(async () => { 45 | const memoryBankManager = new MemoryBankManager_1.MemoryBankManager(roo.getRootPath()); 46 | const result = await memoryBankManager.synchronizer.validateMemoryBank(); 47 | if (result.success) { 48 | console.log('Memory Bank validation successful'); 49 | console.log(`Found files: ${result.updatedFiles.join(', ')}`); 50 | } 51 | else { 52 | console.error('Memory Bank validation failed'); 53 | if (result.errors) { 54 | console.error(`Errors: ${result.errors.join(', ')}`); 55 | } 56 | } 57 | }); 58 | memoryBankCommand 59 | .command('record-decision') 60 | .description('Record a decision in the Memory Bank') 61 | .argument('', 'Decision title') 62 | .argument('<rationale>', 'Decision rationale') 63 | .argument('<implementation>', 'Implementation details') 64 | .action(async (title, rationale, implementation) => { 65 | const memoryBankManager = new MemoryBankManager_1.MemoryBankManager(roo.getRootPath()); 66 | const result = await memoryBankManager.recordDecision(title, rationale, implementation); 67 | if (result.success) { 68 | console.log('Decision recorded successfully'); 69 | } 70 | else { 71 | console.error('Failed to record decision'); 72 | if (result.errors) { 73 | console.error(`Errors: ${result.errors.join(', ')}`); 74 | } 75 | } 76 | }); 77 | memoryBankCommand 78 | .command('record-pattern') 79 | .description('Record a system pattern in the Memory Bank') 80 | .argument('<name>', 'Pattern name') 81 | .argument('<type>', 'Pattern type (Coding, Architectural, Testing)') 82 | .argument('<description>', 'Pattern description') 83 | .action(async (name, type, description) => { 84 | const memoryBankManager = new MemoryBankManager_1.MemoryBankManager(roo.getRootPath()); 85 | // Validate pattern type 86 | const patternType = type; 87 | if (!['Coding', 'Architectural', 'Testing'].includes(patternType)) { 88 | console.error('Invalid pattern type. Must be one of: Coding, Architectural, Testing'); 89 | return; 90 | } 91 | const result = await memoryBankManager.recordSystemPattern(name, patternType, description); 92 | if (result.success) { 93 | console.log('Pattern recorded successfully'); 94 | } 95 | else { 96 | console.error('Failed to record pattern'); 97 | if (result.errors) { 98 | console.error(`Errors: ${result.errors.join(', ')}`); 99 | } 100 | } 101 | }); 102 | memoryBankCommand 103 | .command('record-mode-transition') 104 | .description('Record a mode transition in the Memory Bank') 105 | .argument('<from-mode>', 'Source mode') 106 | .argument('<to-mode>', 'Target mode') 107 | .argument('<reason>', 'Transition reason') 108 | .action(async (fromMode, toMode, reason) => { 109 | const memoryBankManager = new MemoryBankManager_1.MemoryBankManager(roo.getRootPath()); 110 | const result = await memoryBankManager.recordModeTransition(fromMode, toMode, reason); 111 | if (result.success) { 112 | console.log('Mode transition recorded successfully'); 113 | } 114 | else { 115 | console.error('Failed to record mode transition'); 116 | if (result.errors) { 117 | console.error(`Errors: ${result.errors.join(', ')}`); 118 | } 119 | } 120 | }); 121 | } 122 | //# sourceMappingURL=memory-bank.js.map -------------------------------------------------------------------------------- /dist/cli/memory-bank.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"memory-bank.js","sourceRoot":"","sources":["../../src/cli/memory-bank.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | import { FileSystemScanner } from './scanner/components/FileSystemScanner'; 2 | import type { FileStats, FileNode, ScanOptions, ProjectStructure } from './scanner/components/FileSystemScanner'; 3 | import { TaskScanner } from './scanner/components/TaskScanner'; 4 | import type { TaskMarker, TaskLocation, DiscoveredTask, TaskScanResults, TaskScanOptions, Priority } from './scanner/components/TaskScanner'; 5 | import { ContextBuilder } from './scanner/components/ContextBuilder'; 6 | import type { ProjectMetadata, ProjectContext, ContextBuilderOptions } from './scanner/components/ContextBuilder'; 7 | import { RegistryUpdater } from './scanner/components/RegistryUpdater'; 8 | import type { RegistryUpdaterOptions } from './scanner/components/RegistryUpdater'; 9 | export { FileSystemScanner, TaskScanner, ContextBuilder, RegistryUpdater }; 10 | export type { FileStats, FileNode, ScanOptions, ProjectStructure, TaskMarker, TaskLocation, DiscoveredTask, TaskScanResults, TaskScanOptions, Priority, ProjectMetadata, ProjectContext, ContextBuilderOptions, RegistryUpdaterOptions }; 11 | export declare const DEFAULT_SCAN_OPTIONS: ScanOptions; 12 | export declare const formatSize: (bytes: number) => string; 13 | export declare const getProjectSummaryMarkdown: (summary: ProjectStructure["summary"]) => string; 14 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.getProjectSummaryMarkdown = exports.formatSize = exports.DEFAULT_SCAN_OPTIONS = exports.RegistryUpdater = exports.ContextBuilder = exports.TaskScanner = exports.FileSystemScanner = void 0; 4 | const FileSystemScanner_1 = require("./scanner/components/FileSystemScanner"); 5 | Object.defineProperty(exports, "FileSystemScanner", { enumerable: true, get: function () { return FileSystemScanner_1.FileSystemScanner; } }); 6 | const TaskScanner_1 = require("./scanner/components/TaskScanner"); 7 | Object.defineProperty(exports, "TaskScanner", { enumerable: true, get: function () { return TaskScanner_1.TaskScanner; } }); 8 | const ContextBuilder_1 = require("./scanner/components/ContextBuilder"); 9 | Object.defineProperty(exports, "ContextBuilder", { enumerable: true, get: function () { return ContextBuilder_1.ContextBuilder; } }); 10 | const RegistryUpdater_1 = require("./scanner/components/RegistryUpdater"); 11 | Object.defineProperty(exports, "RegistryUpdater", { enumerable: true, get: function () { return RegistryUpdater_1.RegistryUpdater; } }); 12 | // Re-export default configuration 13 | exports.DEFAULT_SCAN_OPTIONS = { 14 | depth: Infinity, 15 | excludePatterns: [] 16 | }; 17 | // Export utility functions 18 | const formatSize = (bytes) => { 19 | const units = ['B', 'KB', 'MB', 'GB', 'TB']; 20 | let size = bytes; 21 | let unitIndex = 0; 22 | while (size >= 1024 && unitIndex < units.length - 1) { 23 | size /= 1024; 24 | unitIndex++; 25 | } 26 | return `${size.toFixed(2)} ${units[unitIndex]}`; 27 | }; 28 | exports.formatSize = formatSize; 29 | const getProjectSummaryMarkdown = (summary) => { 30 | const fileTypes = Array.from(summary.fileTypes.entries()) 31 | .sort((a, b) => b[1] - a[1]) 32 | .map(([ext, count]) => { 33 | return `- ${ext}: ${count} files`; 34 | }) 35 | .join('\n'); 36 | return `# Project Scan Summary 37 | 38 | ## Statistics 39 | - Total Files: ${summary.totalFiles} 40 | - Total Directories: ${summary.totalDirs} 41 | - Total Size: ${(0, exports.formatSize)(summary.totalSize)} 42 | 43 | ## File Types 44 | ${fileTypes} 45 | `; 46 | }; 47 | exports.getProjectSummaryMarkdown = getProjectSummaryMarkdown; 48 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,8EAA2E;AAUzE,kGAVO,qCAAiB,OAUP;AARnB,kEAA+D;AAS7D,4FATO,yBAAW,OASP;AAPb,wEAAqE;AAQnE,+FARO,+BAAc,OAQP;AANhB,0EAAuE;AAOrE,gGAPO,iCAAe,OAOP;AAoBjB,kCAAkC;AACrB,QAAA,oBAAoB,GAAgB;IAC/C,KAAK,EAAE,QAAQ;IACf,eAAe,EAAE,EAAE;CACpB,CAAC;AAEF,2BAA2B;AACpB,MAAM,UAAU,GAAG,CAAC,KAAa,EAAU,EAAE;IAClD,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5C,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,OAAO,IAAI,IAAI,IAAI,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,IAAI,IAAI,IAAI,CAAC;QACb,SAAS,EAAE,CAAC;IACd,CAAC;IAED,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;AAClD,CAAC,CAAC;AAXW,QAAA,UAAU,cAWrB;AAEK,MAAM,yBAAyB,GAAG,CAAC,OAAoC,EAAU,EAAE;IACxF,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;SACtD,IAAI,CAAC,CAAC,CAAmB,EAAE,CAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;SAC/D,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAmB,EAAE,EAAE;QACtC,OAAO,KAAK,GAAG,KAAK,KAAK,QAAQ,CAAC;IACpC,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;;;iBAGQ,OAAO,CAAC,UAAU;uBACZ,OAAO,CAAC,SAAS;gBACxB,IAAA,kBAAU,EAAC,OAAO,CAAC,SAAS,CAAC;;;EAG3C,SAAS;CACV,CAAC;AACF,CAAC,CAAC;AAlBW,QAAA,yBAAyB,6BAkBpC"} -------------------------------------------------------------------------------- /dist/roo.d.ts: -------------------------------------------------------------------------------- 1 | import { TaskStatus } from './scanner/components/interfaces/Task'; 2 | import { TaskManager } from './scanner/components/TaskManager'; 3 | import { Captain } from './cli/captain'; 4 | import { Command } from 'commander'; 5 | interface RooOptions { 6 | rootPath?: string; 7 | taskManager?: TaskManager; 8 | captain?: Captain; 9 | } 10 | export declare class Roo { 11 | private readonly taskManager; 12 | private readonly captain; 13 | private readonly rootPath; 14 | constructor(options?: RooOptions); 15 | getRootPath(): string; 16 | createTask(description: string, targetMode: string, dependencies?: string[]): Promise<string>; 17 | updateTaskStatus(taskId: string, newStatus: TaskStatus): Promise<void>; 18 | delegateTask(taskId: string, toMode: string, reason: string): Promise<void>; 19 | getTaskReport(): Promise<string>; 20 | createMemoryBank(): Promise<boolean>; 21 | private resolvePath; 22 | } 23 | export declare function setupRooCommands(program: Command, roo: Roo): void; 24 | export { TaskStatus }; 25 | -------------------------------------------------------------------------------- /dist/roo.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || (function () { 19 | var ownKeys = function(o) { 20 | ownKeys = Object.getOwnPropertyNames || function (o) { 21 | var ar = []; 22 | for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; 23 | return ar; 24 | }; 25 | return ownKeys(o); 26 | }; 27 | return function (mod) { 28 | if (mod && mod.__esModule) return mod; 29 | var result = {}; 30 | if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); 31 | __setModuleDefault(result, mod); 32 | return result; 33 | }; 34 | })(); 35 | Object.defineProperty(exports, "__esModule", { value: true }); 36 | exports.TaskStatus = exports.Roo = void 0; 37 | exports.setupRooCommands = setupRooCommands; 38 | const Task_1 = require("./scanner/components/interfaces/Task"); 39 | Object.defineProperty(exports, "TaskStatus", { enumerable: true, get: function () { return Task_1.TaskStatus; } }); 40 | const TaskManager_1 = require("./scanner/components/TaskManager"); 41 | const captain_1 = require("./cli/captain"); 42 | const memory_bank_1 = require("./cli/memory-bank"); 43 | const path = __importStar(require("path")); 44 | class Roo { 45 | constructor(options = {}) { 46 | this.rootPath = options.rootPath || process.cwd(); 47 | this.taskManager = options.taskManager || new TaskManager_1.TaskManager(this.rootPath); 48 | this.captain = options.captain || new captain_1.Captain(); 49 | } 50 | getRootPath() { 51 | return this.rootPath; 52 | } 53 | async createTask(description, targetMode, dependencies) { 54 | const task = await this.taskManager.createTask({ 55 | description, 56 | assignedMode: targetMode, 57 | title: description.split('\n')[0], 58 | dependencies 59 | }); 60 | // Update the captain about the new task 61 | this.captain.notifyTaskCreated(task.id, targetMode); 62 | return task.id; 63 | } 64 | async updateTaskStatus(taskId, newStatus) { 65 | await this.taskManager.updateTaskStatus(taskId, newStatus); 66 | } 67 | async delegateTask(taskId, toMode, reason) { 68 | await this.taskManager.switchTaskMode(taskId, toMode, reason); 69 | } 70 | async getTaskReport() { 71 | return await this.taskManager.generateReport(); 72 | } 73 | async createMemoryBank() { 74 | return await this.taskManager.createMemoryBank(); 75 | } 76 | resolvePath(relativePath) { 77 | return path.resolve(this.rootPath, relativePath); 78 | } 79 | } 80 | exports.Roo = Roo; 81 | function setupRooCommands(program, roo) { 82 | (0, captain_1.setupCaptainCommands)(program, roo); 83 | (0, memory_bank_1.setupMemoryBankCommands)(program, roo); 84 | } 85 | //# sourceMappingURL=roo.js.map -------------------------------------------------------------------------------- /dist/roo.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"roo.js","sourceRoot":"","sources":["../src/roo.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,4CAGC;AAjED,+DAAkE;AAmEzD,2FAnEA,iBAAU,OAmEA;AAlEnB,kEAA+D;AAC/D,2CAA8D;AAC9D,mDAA4D;AAC5D,2CAA6B;AAS7B,MAAa,GAAG;IAKd,YAAY,UAAsB,EAAE;QAClC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAClD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI,yBAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,iBAAO,EAAE,CAAC;IAClD,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,WAAmB,EAAE,UAAkB,EAAE,YAAuB;QAC/E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;YAC7C,WAAW;YACX,YAAY,EAAE,UAAU;YACxB,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjC,YAAY;SACb,CAAC,CAAC;QAEH,wCAAwC;QACxC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,EAAE,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,MAAc,EAAE,SAAqB;QAC1D,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAc,EAAE,MAAc,EAAE,MAAc;QAC/D,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC;IACnD,CAAC;IAEO,WAAW,CAAC,YAAoB;QACtC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACnD,CAAC;CACF;AA/CD,kBA+CC;AAED,SAAgB,gBAAgB,CAAC,OAAgB,EAAE,GAAQ;IACzD,IAAA,8BAAoB,EAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACnC,IAAA,qCAAuB,EAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AACxC,CAAC"} -------------------------------------------------------------------------------- /dist/scanner/components/ContextBuilder.d.ts: -------------------------------------------------------------------------------- 1 | import { ProjectStructure } from './FileSystemScanner'; 2 | import { TaskScanResults, TaskScanOptions } from './TaskScanner'; 3 | export interface ProjectMetadata { 4 | name?: string; 5 | version?: string; 6 | description?: string; 7 | license?: string; 8 | authors?: string[]; 9 | dependencies?: string[]; 10 | devDependencies?: string[]; 11 | } 12 | export interface ProjectContext { 13 | metadata: ProjectMetadata; 14 | fileSystem: ProjectStructure; 15 | tasks: TaskScanResults; 16 | documentation: string[]; 17 | } 18 | export interface ContextBuilderOptions { 19 | includeDocumentation?: string[]; 20 | excludeDocumentation?: string[]; 21 | taskScanOptions?: TaskScanOptions; 22 | } 23 | export declare class ContextBuilder { 24 | private readonly rootPath; 25 | private readonly options; 26 | constructor(rootPath: string, options?: ContextBuilderOptions); 27 | buildContext(): Promise<ProjectContext>; 28 | private extractMetadata; 29 | private parseMetadataFromMarkdown; 30 | private scanFileSystem; 31 | private scanTasks; 32 | private extractDocumentation; 33 | } 34 | -------------------------------------------------------------------------------- /dist/scanner/components/ContextBuilder.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"ContextBuilder.js","sourceRoot":"","sources":["../../../src/scanner/components/ContextBuilder.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/scanner/components/FileSystemScanner.d.ts: -------------------------------------------------------------------------------- 1 | export interface FileStats { 2 | size: number; 3 | lastModified: Date; 4 | type: 'file' | 'directory' | 'symlink'; 5 | } 6 | export interface FileNode { 7 | path: string; 8 | name: string; 9 | type: 'file' | 'directory' | 'symlink'; 10 | stats: FileStats; 11 | children?: FileNode[]; 12 | } 13 | export interface ProjectStructure { 14 | root: FileNode; 15 | summary: { 16 | totalFiles: number; 17 | totalDirs: number; 18 | fileTypes: Map<string, number>; 19 | totalSize: number; 20 | }; 21 | } 22 | export interface ScanOptions { 23 | depth?: number; 24 | excludePatterns?: string[]; 25 | } 26 | export declare class FileSystemScanner { 27 | private readonly rootPath; 28 | private currentOptions; 29 | private fileTypeStats; 30 | private ignorePatterns; 31 | private summary; 32 | constructor(rootPath: string, defaultOptions?: ScanOptions); 33 | addIgnorePatterns(patterns: string[]): void; 34 | getFileTypeStats(): Map<string, number>; 35 | scanProject(options?: ScanOptions): Promise<ProjectStructure>; 36 | private scanDirectory; 37 | private getFileType; 38 | private shouldExclude; 39 | } 40 | -------------------------------------------------------------------------------- /dist/scanner/components/FileSystemScanner.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"FileSystemScanner.js","sourceRoot":"","sources":["../../../src/scanner/components/FileSystemScanner.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/scanner/components/RegistryUpdater.d.ts: -------------------------------------------------------------------------------- 1 | import { ProjectContext } from './ContextBuilder'; 2 | export interface RegistryEntry { 3 | taskId: string; 4 | type: string; 5 | description: string; 6 | priority?: string; 7 | assignee?: string; 8 | labels: string[]; 9 | file: string; 10 | line: number; 11 | status: 'active' | 'completed'; 12 | created: string; 13 | updated: string; 14 | } 15 | export interface RegistryUpdaterOptions { 16 | memoryBankUri: string; 17 | taskRegistryPath: string; 18 | } 19 | export declare class RegistryUpdater { 20 | private readonly rootPath; 21 | private readonly options; 22 | private registryPath; 23 | constructor(rootPath: string, options: RegistryUpdaterOptions); 24 | updateRegistry(context: ProjectContext): Promise<void>; 25 | private convertTasksToEntries; 26 | private convertTaskToEntry; 27 | private generateTaskId; 28 | private generateRegistryMarkdown; 29 | private generateStatsSections; 30 | private updateMemoryBank; 31 | } 32 | -------------------------------------------------------------------------------- /dist/scanner/components/RegistryUpdater.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"RegistryUpdater.js","sourceRoot":"","sources":["../../../src/scanner/components/RegistryUpdater.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/scanner/components/TaskManager.d.ts: -------------------------------------------------------------------------------- 1 | import { Task, TaskStatus } from './interfaces/Task'; 2 | import { MemoryBankManager } from '../../memory-bank/MemoryBankManager'; 3 | export declare class TaskManager { 4 | private tasks; 5 | private memoryBankManager?; 6 | private rootPath?; 7 | constructor(rootPath?: string); 8 | createTask(params: { 9 | description: string; 10 | assignedMode: string; 11 | title?: string; 12 | priority?: number; 13 | assignees?: string[]; 14 | labels?: string[]; 15 | dependencies?: string[]; 16 | }): Promise<Task>; 17 | getTask(id: string): Task | undefined; 18 | getAllTasks(): Task[]; 19 | updateTask(id: string, updates: Partial<Task>): Promise<Task>; 20 | updateTaskStatus(id: string, newStatus: TaskStatus): Promise<void>; 21 | switchTaskMode(id: string, toMode: string, reason: string): Promise<void>; 22 | generateReport(): Promise<string>; 23 | /** 24 | * Gets the memory bank manager instance 25 | */ 26 | getMemoryBankManager(): MemoryBankManager | undefined; 27 | /** 28 | * Creates a memory bank if it doesn't exist 29 | */ 30 | createMemoryBank(): Promise<boolean>; 31 | } 32 | -------------------------------------------------------------------------------- /dist/scanner/components/TaskManager.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"TaskManager.js","sourceRoot":"","sources":["../../../src/scanner/components/TaskManager.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/scanner/components/TaskScanner.d.ts: -------------------------------------------------------------------------------- 1 | export type Priority = 'low' | 'medium' | 'high' | undefined; 2 | export interface TaskMarker { 3 | type: 'TODO' | 'FIXME' | 'NOTE' | 'HACK' | 'BUG' | 'ISSUE'; 4 | description: string; 5 | priority?: Priority; 6 | assignee?: string; 7 | labels: string[]; 8 | } 9 | export interface TaskLocation { 10 | filePath: string; 11 | lineNumber: number; 12 | columnNumber: number; 13 | context: string; 14 | } 15 | export interface DiscoveredTask { 16 | marker: TaskMarker; 17 | location: TaskLocation; 18 | } 19 | export interface TaskStatistics { 20 | totalTasks: number; 21 | byType: Map<string, number>; 22 | byPriority: Map<string, number>; 23 | byLabel: Map<string, number>; 24 | } 25 | export interface TaskScanResults { 26 | tasks: DiscoveredTask[]; 27 | statistics: TaskStatistics; 28 | } 29 | export interface TaskScanOptions { 30 | include?: string[]; 31 | exclude?: string[]; 32 | customMarkers?: string[]; 33 | } 34 | export declare class TaskScanner { 35 | private readonly options; 36 | private static readonly DEFAULT_MARKERS; 37 | private static readonly MARKER_PATTERN; 38 | private static readonly EXCLAMATION_PATTERN; 39 | private static readonly ASSIGNEE_PATTERN; 40 | private static readonly LABEL_PATTERN; 41 | private readonly markers; 42 | constructor(options?: TaskScanOptions); 43 | scanDirectory(dirPath: string): Promise<TaskScanResults>; 44 | private getFilesToScan; 45 | private scanFile; 46 | private extractPriority; 47 | private extractAssignee; 48 | private extractLabels; 49 | private getTaskContext; 50 | } 51 | -------------------------------------------------------------------------------- /dist/scanner/components/TaskScanner.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"TaskScanner.js","sourceRoot":"","sources":["../../../src/scanner/components/TaskScanner.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/scanner/components/interfaces/Task.d.ts: -------------------------------------------------------------------------------- 1 | export interface TaskLocation { 2 | file: string; 3 | line: number; 4 | column?: number; 5 | } 6 | export interface DiscoveredTask { 7 | type: string; 8 | description: string; 9 | priority?: number; 10 | assignees?: string[]; 11 | labels?: string[]; 12 | location: TaskLocation; 13 | lineContent: string; 14 | metadata?: Record<string, unknown>; 15 | } 16 | export interface TaskScanOptions { 17 | include?: string[]; 18 | exclude?: string[]; 19 | customMarkers?: string[]; 20 | } 21 | export interface TaskScanResult { 22 | tasks: DiscoveredTask[]; 23 | statistics: { 24 | totalTasks: number; 25 | byType: Map<string, number>; 26 | byPriority?: Map<number, number>; 27 | byLabel?: Map<string, number>; 28 | }; 29 | } 30 | export interface TaskScannerOptions { 31 | markers?: string[]; 32 | assigneePrefix?: string; 33 | labelPrefix?: string; 34 | priorityPattern?: RegExp; 35 | } 36 | export declare enum TaskStatus { 37 | PENDING = "pending", 38 | IN_PROGRESS = "in_progress", 39 | BLOCKED = "blocked", 40 | COMPLETED = "completed", 41 | FAILED = "failed" 42 | } 43 | export interface TaskTransition { 44 | from: TaskStatus; 45 | to: TaskStatus; 46 | by?: string; 47 | at: Date; 48 | comment?: string; 49 | fromMode?: string; 50 | toMode?: string; 51 | reason?: string; 52 | timestamp?: Date; 53 | } 54 | export interface Task { 55 | id: string; 56 | title: string; 57 | description: string; 58 | status: TaskStatus; 59 | priority: number; 60 | assignees: string[]; 61 | labels: string[]; 62 | created: Date; 63 | updated?: Date; 64 | transitions?: TaskTransition[]; 65 | metadata?: Record<string, unknown>; 66 | location?: TaskLocation; 67 | assignedMode?: string; 68 | modeChain?: string[]; 69 | notes?: string; 70 | dependencies?: string[]; 71 | } 72 | -------------------------------------------------------------------------------- /dist/scanner/components/interfaces/Task.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.TaskStatus = void 0; 4 | // Task Management Interfaces 5 | var TaskStatus; 6 | (function (TaskStatus) { 7 | TaskStatus["PENDING"] = "pending"; 8 | TaskStatus["IN_PROGRESS"] = "in_progress"; 9 | TaskStatus["BLOCKED"] = "blocked"; 10 | TaskStatus["COMPLETED"] = "completed"; 11 | TaskStatus["FAILED"] = "failed"; 12 | })(TaskStatus || (exports.TaskStatus = TaskStatus = {})); 13 | //# sourceMappingURL=Task.js.map -------------------------------------------------------------------------------- /dist/scanner/components/interfaces/Task.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Task.js","sourceRoot":"","sources":["../../../../src/scanner/components/interfaces/Task.ts"],"names":[],"mappings":";;;AAyCA,6BAA6B;AAC7B,IAAY,UAMX;AAND,WAAY,UAAU;IACpB,iCAAmB,CAAA;IACnB,yCAA2B,CAAA;IAC3B,iCAAmB,CAAA;IACnB,qCAAuB,CAAA;IACvB,+BAAiB,CAAA;AACnB,CAAC,EANW,UAAU,0BAAV,UAAU,QAMrB"} -------------------------------------------------------------------------------- /docs/installation-guide.md: -------------------------------------------------------------------------------- 1 | # RooFlow Captain Mode Installation Guide 2 | 3 | This guide provides detailed instructions for installing and using the RooFlow Captain Mode with the VSCode Roo-Code extension in your projects. 4 | 5 | ## Prerequisites 6 | 7 | Before installing RooFlow Captain Mode, ensure you have: 8 | 9 | 1. **Visual Studio Code** - [Download and install VSCode](https://code.visualstudio.com/download) 10 | 2. **Roo Code Extension** - Install from the [VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=roo-code.roo-code) 11 | 3. **Node.js** (v14 or higher) - [Download and install Node.js](https://nodejs.org/en/download/) 12 | 4. **npm** (usually comes with Node.js) 13 | 14 | ## Installation Options 15 | 16 | There are two ways to install RooFlow Captain Mode: 17 | 18 | ### Option 1: Using npm (Recommended) 19 | 20 | 1. Open your terminal or command prompt 21 | 2. Navigate to your project directory 22 | 3. Install RooFlow Captain Mode as a dependency: 23 | 24 | ```bash 25 | npm install rooflow-captainmode --save-dev 26 | ``` 27 | 28 | 4. Initialize RooFlow Captain Mode in your project: 29 | 30 | ```bash 31 | npx rooflow-captainmode init 32 | ``` 33 | 34 | This will create all necessary configuration files and the memory-bank directory in your project. 35 | 36 | ### Option 2: Manual Installation 37 | 38 | 1. Clone the RooFlow Captain Mode repository: 39 | 40 | ```bash 41 | git clone https://github.com/shipdocs/RooFlow-captainmode.git 42 | ``` 43 | 44 | 2. Copy the following files and directories to your project: 45 | - `.clinerules-*` files (all mode rule files) 46 | - `.roo/` directory 47 | - `memory-bank/` directory (or create it if you want to start fresh) 48 | 49 | ## Configuration 50 | 51 | After installation, you'll need to configure RooFlow Captain Mode for your project: 52 | 53 | 1. **Mode Configuration**: 54 | - The `.roo/cline_custom_modes.json` file contains mode configurations 55 | - You can customize the available modes and their descriptions 56 | 57 | 2. **Memory Bank Setup**: 58 | - The `memory-bank/` directory contains files for maintaining project context 59 | - You can initialize these files with your project-specific information 60 | 61 | ## Using RooFlow Captain Mode with VSCode 62 | 63 | 1. **Open your project in VSCode**: 64 | ```bash 65 | code /path/to/your/project 66 | ``` 67 | 68 | 2. **Access the Roo Code Extension**: 69 | - Click on the Roo Code icon in the VSCode sidebar 70 | - Or use the keyboard shortcut (default: `Ctrl+Shift+R` or `Cmd+Shift+R` on Mac) 71 | 72 | 3. **Select Captain Mode**: 73 | - In the Roo Code chat panel, click on the mode selector at the top 74 | - Select "Captain" from the available modes 75 | 76 | 4. **Start Using Captain Mode**: 77 | - Describe your project or task to Captain Mode 78 | - Let Captain Mode orchestrate your project by breaking down tasks and delegating to specialized modes 79 | 80 | ## Command Line Interface 81 | 82 | RooFlow Captain Mode provides a CLI for managing tasks and the memory bank: 83 | 84 | ```bash 85 | # View task registry 86 | npx rooflow-captainmode tasks list 87 | 88 | # Create a new task 89 | npx rooflow-captainmode tasks create "Implement feature X" --mode code 90 | 91 | # Check Memory Bank status 92 | npx rooflow-captainmode memory-bank status 93 | 94 | # Create Memory Bank if it doesn't exist 95 | npx rooflow-captainmode memory-bank create 96 | ``` 97 | 98 | ## Memory Bank Management 99 | 100 | The Memory Bank is a key component of RooFlow Captain Mode. It maintains project context across different modes and sessions: 101 | 102 | 1. **Memory Bank Files**: 103 | - `activeContext.md` - Current session context 104 | - `decisionLog.md` - Architectural and implementation decisions 105 | - `productContext.md` - Project overview 106 | - `progress.md` - Project progress 107 | - `systemPatterns.md` - Recurring patterns and standards 108 | - `taskRegistry.md` - Task tracking 109 | 110 | 2. **Accessing Memory Bank**: 111 | - Through the Roo Code chat panel 112 | - Via the command line interface 113 | - Directly editing the files (not recommended) 114 | 115 | ## Troubleshooting 116 | 117 | If you encounter issues with RooFlow Captain Mode: 118 | 119 | 1. **Check Configuration Files**: 120 | - Verify JSON syntax in `.roo/cline_custom_modes.json` 121 | - Check YAML syntax in `.roo/custom-instructions.yaml` 122 | 123 | 2. **Restart VSCode**: 124 | - After making configuration changes, restart VSCode 125 | 126 | 3. **Check Memory Bank**: 127 | - Ensure the `memory-bank/` directory exists and is writable 128 | - Verify that all required files exist in the memory bank 129 | 130 | 4. **Update Roo Code Extension**: 131 | - Ensure you have the latest version of the Roo Code extension 132 | 133 | ## Example Workflow 134 | 135 | Here's an example of how to use RooFlow Captain Mode in a project: 136 | 137 | 1. **Start in Captain Mode**: 138 | - Select "Captain" in the Roo Code chat panel 139 | 140 | 2. **Describe Your Project**: 141 | - "I want to build a weather dashboard application" 142 | 143 | 3. **Captain Mode Analysis**: 144 | - Captain Mode breaks down the task into subtasks 145 | - Delegates to specialized modes (Architect, Code, Test, etc.) 146 | 147 | 4. **Task Delegation**: 148 | - Captain Mode delegates the first task (e.g., to Architect Mode) 149 | - When Architect Mode completes, control returns to Captain Mode 150 | - Captain Mode delegates the next task, and so on 151 | 152 | 5. **Project Completion**: 153 | - Captain Mode maintains the task registry and project context throughout 154 | - You can track progress in the `memory-bank/progress.md` file 155 | 156 | ## Additional Resources 157 | 158 | - [Memory Bank Usage Guide](memory-bank-usage.md) 159 | - [Captain Mode Documentation](../rooflow-captainmode-docs/captain-mode.md) 160 | - [Project Scan Feature](../rooflow-captainmode-docs/project-scan-feature.md) 161 | - [Mode Management Guide](../rooflow-captainmode-docs/mode-management.md) 162 | -------------------------------------------------------------------------------- /docs/memory-bank-usage.md: -------------------------------------------------------------------------------- 1 | # Memory Bank Usage Guide 2 | 3 | ## Overview 4 | 5 | The Memory Bank system provides persistent context across different modes and chat sessions in RooFlow Captain Mode. This guide explains how to use and maintain the Memory Bank. 6 | 7 | ## Memory Bank Files 8 | 9 | The Memory Bank consists of several key files: 10 | 11 | 1. **activeContext.md** - Tracks the current session's context 12 | 2. **decisionLog.md** - Records architectural and implementation decisions 13 | 3. **productContext.md** - Provides a high-level overview of the project 14 | 4. **progress.md** - Tracks the progress of the project 15 | 5. **systemPatterns.md** - Documents recurring patterns and standards 16 | 6. **taskRegistry.md** - Task tracking system 17 | 18 | ## Command Line Interface 19 | 20 | The Memory Bank can be managed through the command line interface: 21 | 22 | ```bash 23 | # Check Memory Bank status 24 | roo memory-bank status 25 | 26 | # Create Memory Bank if it doesn't exist 27 | roo memory-bank create 28 | 29 | # Validate Memory Bank structure 30 | roo memory-bank validate 31 | 32 | # Record a decision 33 | roo memory-bank record-decision "Decision Title" "Rationale" "Implementation Details" 34 | 35 | # Record a system pattern 36 | roo memory-bank record-pattern "Pattern Name" "Architectural" "Pattern Description" 37 | 38 | # Record a mode transition 39 | roo memory-bank record-mode-transition "code" "test" "Ready for testing" 40 | ``` 41 | 42 | ## Programmatic Usage 43 | 44 | The Memory Bank can also be used programmatically: 45 | 46 | ```typescript 47 | import { Roo } from './roo'; 48 | import { TaskStatus } from './scanner/components/interfaces/Task'; 49 | 50 | // Create a Roo instance 51 | const roo = new Roo(); 52 | 53 | // Create a task (automatically updates Memory Bank) 54 | const taskId = await roo.createTask('Implement feature X', 'code'); 55 | 56 | // Update task status (automatically updates Memory Bank) 57 | await roo.updateTaskStatus(taskId, TaskStatus.IN_PROGRESS); 58 | 59 | // Delegate task to another mode (automatically updates Memory Bank) 60 | await roo.delegateTask(taskId, 'test', 'Ready for testing'); 61 | 62 | // Create Memory Bank if it doesn't exist 63 | const created = await roo.createMemoryBank(); 64 | ``` 65 | 66 | ## Cross-Mode Synchronization 67 | 68 | The Memory Bank ensures that context is maintained across different modes: 69 | 70 | 1. When a task is delegated to another mode, the transition is recorded in: 71 | - taskRegistry.md 72 | - activeContext.md 73 | - progress.md 74 | 75 | 2. When a decision is made, it is recorded in: 76 | - decisionLog.md 77 | 78 | 3. When a system pattern is identified, it is recorded in: 79 | - systemPatterns.md 80 | 81 | ## Best Practices 82 | 83 | 1. **Regular Updates**: Update the Memory Bank regularly to maintain accurate context. 84 | 2. **Detailed Descriptions**: Provide detailed descriptions when creating tasks, recording decisions, or documenting patterns. 85 | 3. **Mode Transitions**: Always record mode transitions with clear reasons. 86 | 4. **Task Dependencies**: Specify task dependencies to maintain a clear workflow. 87 | 5. **Validation**: Periodically validate the Memory Bank structure to ensure integrity. 88 | 89 | ## Troubleshooting 90 | 91 | If you encounter issues with the Memory Bank: 92 | 93 | 1. **Check Status**: Run `roo memory-bank status` to check the Memory Bank status. 94 | 2. **Validate Structure**: Run `roo memory-bank validate` to validate the Memory Bank structure. 95 | 3. **Create Missing Files**: If files are missing, run `roo memory-bank create` to create them. 96 | 4. **Check Permissions**: Ensure you have write permissions to the Memory Bank directory. 97 | 5. **Check Logs**: Check the console output for error messages. 98 | 99 | ## Monitoring and Maintenance 100 | 101 | To monitor and maintain the Memory Bank: 102 | 103 | 1. **Regular Backups**: Periodically back up the Memory Bank directory. 104 | 2. **Clean Up**: Remove completed tasks that are no longer relevant. 105 | 3. **Update Context**: Keep the active context up to date with the current focus. 106 | 4. **Review Decisions**: Periodically review decisions to ensure they are still valid. 107 | 5. **Update Patterns**: Update system patterns as the project evolves. 108 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: 'ts-jest', 4 | testEnvironment: 'node', 5 | testMatch: ['**/*.test.ts'], 6 | roots: ['<rootDir>/src'], 7 | moduleFileExtensions: ['ts', 'js', 'json', 'node'], 8 | verbose: true, 9 | collectCoverage: true, 10 | coverageDirectory: 'coverage', 11 | coverageReporters: ['text', 'lcov'], 12 | coveragePathIgnorePatterns: [ 13 | '/node_modules/', 14 | '/dist/', 15 | '/coverage/' 16 | ] 17 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rooflow-captainmode", 3 | "version": "1.0.0", 4 | "description": "Captain Mode implementation for RooFlow with Memory Bank and task management", 5 | "main": "dist/index.js", 6 | "bin": { 7 | "roo": "dist/roo.js", 8 | "captain": "dist/cli/index.js", 9 | "rooflow-captainmode": "dist/cli/index.js" 10 | }, 11 | "scripts": { 12 | "build": "tsc", 13 | "build:roo": "tsc src/roo.ts", 14 | "build:captain": "tsc src/cli/index.ts", 15 | "test": "jest", 16 | "lint": "eslint src/**/*.ts", 17 | "dev": "ts-node src/index.ts", 18 | "postinstall": "node scripts/postinstall.js", 19 | "init": "node scripts/init.js" 20 | }, 21 | "dependencies": { 22 | "commander": "^13.1.0", 23 | "glob": "^8.1.0", 24 | "ignore": "^5.2.4", 25 | "uuid": "^11.1.0" 26 | }, 27 | "devDependencies": { 28 | "@types/glob": "^8.1.0", 29 | "@types/jest": "^29.5.0", 30 | "@types/node": "^18.15.11", 31 | "@types/uuid": "^10.0.0", 32 | "@typescript-eslint/eslint-plugin": "^5.57.1", 33 | "@typescript-eslint/parser": "^5.57.1", 34 | "eslint": "^8.37.0", 35 | "jest": "^29.5.0", 36 | "ts-jest": "^29.1.0", 37 | "ts-node": "^10.9.1", 38 | "typescript": "^5.0.3" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /refactoring_plan.md: -------------------------------------------------------------------------------- 1 | # Refactoring Plan: RooFlow to roo-code-memory-bank 2 | 3 | ## Overview 4 | 5 | This document outlines the plan for refactoring the current project to use roo-code-memory-bank instead of RooFlow, and to implement the captain mode with Boomerang Tasks. 6 | 7 | ## Goals 8 | 9 | * Migrate the project to use roo-code-memory-bank for persistent project context. 10 | * Implement captain mode using Boomerang Tasks for improved task management. 11 | * Preserve existing scanner component functionality. 12 | * Maintain current test coverage levels. 13 | 14 | ## Plan 15 | 16 | 1. **Understand Current Project:** 17 | * Review the existing project structure, components, and functionalities. 18 | * Identify key modules like TaskScanner, ContextBuilder, RegistryUpdater, and FileSystemScanner. 19 | * Analyze the current implementation of Captain Mode and its interactions with other modes. 20 | * **Action:** Review `src/roo.ts`, `src/scanner/components/*`, `.clinerules-*`, and `.roomodes` 21 | 22 | 2. **Explore `roo-code-memory-bank`:** 23 | * Clone and examine the `roo-code-memory-bank` repository. 24 | * Understand its core components, architecture, and memory bank implementation. 25 | * Identify how it handles tasks, context, and persistence. 26 | * Pay special attention to the mode collaboration and triggers. 27 | * **Action:** Clone `https://github.com/GreatScottyMac/roo-code-memory-bank` to `reference/memory-bank` 28 | 29 | 3. **Analyze Boomerang Tasks:** 30 | * Study the Boomerang Tasks documentation to understand its features and implementation. 31 | * Identify how it manages task dependencies, metrics, and mode transitions. 32 | * Understand how it interacts with the memory bank. 33 | * **Action:** Review `https://docs.roocode.com/features/boomerang-tasks/` 34 | 35 | 4. **Identify Core Components:** 36 | * List the essential components from both the current project and `roo-code-memory-bank`. 37 | * **Current Project:** TaskScanner, ContextBuilder, RegistryUpdater, FileSystemScanner, Captain Mode 38 | * **roo-code-memory-bank:** Memory Bank system, Mode collaboration, Mode triggers 39 | * Determine which components can be reused, refactored, or need to be created from scratch. 40 | 41 | 5. **Map Current to New:** 42 | * Create a mapping between the current project's components and the corresponding components in `roo-code-memory-bank`. 43 | * TaskScanner --> Task Management in `roo-code-memory-bank` 44 | * ContextBuilder --> Memory Bank context management 45 | * RegistryUpdater --> Task Registry in `roo-code-memory-bank` 46 | * FileSystemScanner --> Project Structure Analysis in `roo-code-memory-bank` 47 | * Captain Mode --> Captain Mode with Boomerang Tasks 48 | * Identify any missing components or functionalities that need to be implemented. 49 | 50 | 6. **Design Refactoring Plan:** 51 | * Develop a step-by-step plan for refactoring the current project to align with the architecture of `roo-code-memory-bank`. 52 | * Include details on code migration, database schema changes (if any), and API updates. 53 | * Ensure that the existing scanner component functionality is preserved. 54 | * Create a new branch for the refactoring work. 55 | 56 | 7. **Define Boomerang Integration:** 57 | * Outline how to integrate the Boomerang Tasks functionality into the refactored project. 58 | * Specify the changes needed in the captain mode to support boomerang tasks. 59 | * Define the task workflow and how it interacts with the Memory Bank. 60 | 61 | 8. **Update Memory Bank:** 62 | * Update the Memory Bank files (`activeContext.md`, `productContext.md`, `progress.md`, `decisionLog.md`, `systemPatterns.md`, `taskRegistry.md`) to reflect the changes made during the refactoring process. 63 | * Ensure that the context is preserved across mode transitions. 64 | 65 | 9. **Document Changes:** 66 | * Create a detailed documentation outlining the changes made during the refactoring process. 67 | * Include migration guides, API documentation, and usage examples. 68 | 69 | 10. **Get User Approval:** 70 | * Present the refactoring plan and documentation to the user for review and approval. 71 | * Incorporate any feedback or suggestions from the user. 72 | 73 | 11. **Switch to Code Mode:** 74 | * Once the user approves the plan, switch to code mode to implement the changes. 75 | 76 | 12. **Implement Changes:** 77 | * Start by integrating the `roo-code-memory-bank` framework into the project. 78 | * Migrate the scanner components to work with the new framework. 79 | * Implement the Boomerang Tasks functionality in the captain mode. 80 | * Update the Memory Bank files to reflect the changes. 81 | 82 | 13. **Test and Validate:** 83 | * Thoroughly test the refactored project to ensure that it works as expected. 84 | * Validate that the Memory Bank is properly updated and that the context is preserved across sessions. 85 | * Maintain current test coverage levels. 86 | 87 | ## Refactoring Process 88 | 89 | ```mermaid 90 | graph LR 91 | A[Analyze Existing Code] --> B(Integrate roo-code-memory-bank); 92 | B --> C{Migrate Scanner Components}; 93 | C -- Yes --> D(Implement Boomerang Tasks); 94 | C -- No --> E(Implement Boomerang Tasks); 95 | D --> F{Update Memory Bank}; 96 | E --> F; 97 | F --> G[Test and Validate]; -------------------------------------------------------------------------------- /rooflow-captainmode-docs/captain-mode-implementation.md: -------------------------------------------------------------------------------- 1 | # Captain Mode Implementation Plan 2 | 3 | ## Current Gaps Identified 4 | 5 | 1. Task Registry Missing 6 | - The documented taskRegistry.md file in Memory Bank is not implemented 7 | - No formal structure for tracking tasks and their status 8 | 9 | 2. Mode Configuration Missing 10 | - Captain mode not defined in cline_custom_modes.json 11 | - No specific role definition for captain mode 12 | - Missing file access permissions configuration 13 | 14 | 3. Mode Delegation System 15 | - No explicit implementation of delegation logic 16 | - Missing handoff protocols between modes 17 | - No progress tracking mechanism 18 | 19 | ## Implementation Plan 20 | 21 | ### 1. Configuration Updates 22 | 23 | Captain Mode needs to be added to cline_custom_modes.json with the following structure: 24 | 25 | ```json 26 | { 27 | "slug": "captain", 28 | "name": "Captain", 29 | "roleDefinition": "You are Roo's Captain mode, responsible for project orchestration, task division, and coordination between specialized agents.", 30 | "groups": [ 31 | "read", 32 | "browser", 33 | "command", 34 | "mcp", 35 | "edit" 36 | ], 37 | "source": "global", 38 | "customInstructions": { 39 | "mode_collaboration": { 40 | // Mode collaboration settings 41 | }, 42 | "mode_triggers": { 43 | // Mode transition triggers 44 | }, 45 | "memory_bank_strategy": { 46 | // Memory bank integration 47 | } 48 | } 49 | } 50 | ``` 51 | 52 | ### 2. Memory Bank Integration 53 | 54 | #### Task Registry Template (taskRegistry.md) 55 | 56 | ```markdown 57 | # Task Registry 58 | 59 | ## Active Tasks 60 | 61 | | Task ID | Description | Assigned Mode | Status | Created | Updated | 62 | |---------|-------------|---------------|--------|---------|---------| 63 | | [ID] | [Desc] | [Mode] | [Status]| [Date] | [Date] | 64 | 65 | ## Completed Tasks 66 | 67 | | Task ID | Description | Mode Chain | Completed | Notes | 68 | |---------|-------------|------------|-----------|-------| 69 | | [ID] | [Desc] | [Modes] | [Date] | [Notes]| 70 | 71 | ## Mode Transitions 72 | 73 | | Timestamp | From Mode | To Mode | Reason | 74 | |-----------|-----------|---------|--------| 75 | | [Time] | [Mode] | [Mode] | [Why] | 76 | ``` 77 | 78 | ### 3. Mode Delegation Rules 79 | 80 | 1. Task Assignment Logic: 81 | - Architecture & Design → Architect Mode 82 | - Implementation → Code Mode 83 | - Testing & QA → Test Mode 84 | - Troubleshooting → Debug Mode 85 | - Research & Documentation → Ask Mode 86 | 87 | 2. Transition Triggers: 88 | - Task completion 89 | - Dependency resolution 90 | - Blocker identification 91 | - Resource requirements 92 | 93 | 3. Progress Tracking: 94 | - Task status updates 95 | - Mode transition logging 96 | - Completion criteria validation 97 | 98 | ## Implementation Steps 99 | 100 | 1. Create initial configuration files 101 | 2. Setup task registry system 102 | 3. Implement mode delegation logic 103 | 4. Create transition protocols 104 | 5. Test and validate functionality 105 | 106 | ## Future Enhancements 107 | 108 | 1. Automated task status updates 109 | 2. Enhanced progress visualization 110 | 3. Task dependency tracking 111 | 4. Performance metrics collection 112 | 5. Initial project scanning (see project-scan-feature.md) 113 | - Automated project structure analysis 114 | - Task discovery from existing codebase 115 | - Context building from project history 116 | - Integration with memory bank system -------------------------------------------------------------------------------- /rooflow-captainmode-docs/captain-mode.md: -------------------------------------------------------------------------------- 1 | # Captain Mode for RooFlow 2 | 3 | ## Overview 4 | 5 | Captain Mode is a project orchestration and task management mode for RooFlow. It serves as the central coordinator for your project, breaking down complex tasks into manageable subtasks and delegating them to specialized modes (Architect, Code, Test, Debug, Ask). 6 | 7 | ## Key Features 8 | 9 | - **Project Orchestration**: Maintains a high-level view of the entire project 10 | - **Task Decomposition**: Breaks down complex tasks into smaller, well-defined subtasks 11 | - **Task Delegation**: Assigns tasks to the most appropriate specialized modes 12 | - **Progress Tracking**: Monitors task status and project progress 13 | - **Memory Bank Management**: Ensures project context is maintained and updated 14 | 15 | ## When to Use Captain Mode 16 | 17 | Captain Mode is ideal for: 18 | 19 | - Starting new projects that require coordination between multiple aspects 20 | - Managing complex features that span multiple domains 21 | - Organizing work across different specialized areas 22 | - Maintaining project overview and ensuring coherent progress 23 | - Coordinating between different team members or AI agents 24 | 25 | ## How to Use Captain Mode 26 | 27 | 1. **Start in Captain Mode**: Begin your session in Captain Mode to get a project overview 28 | ``` 29 | /mode captain 30 | ``` 31 | 32 | 2. **Describe Your Project or Task**: Provide a high-level description of what you want to accomplish 33 | 34 | 3. **Let Captain Mode Orchestrate**: The Captain will: 35 | - Analyze requirements 36 | - Break down the task into subtasks 37 | - Delegate to specialized modes 38 | - Track progress 39 | - Maintain project context 40 | 41 | 4. **Review Task Registry**: Captain Mode maintains a `taskRegistry.md` file in the Memory Bank that tracks all tasks, their status, and outcomes 42 | 43 | ## Task Registry 44 | 45 | Captain Mode introduces a new Memory Bank file called `taskRegistry.md` that tracks: 46 | 47 | - Active tasks and their current status 48 | - Completed tasks and their outcomes 49 | - Task assignments to specific modes 50 | - Creation and completion dates 51 | 52 | ## Mode Delegation 53 | 54 | Captain Mode delegates tasks based on specialized expertise: 55 | 56 | - **Architect Mode**: System design, architecture, component relationships 57 | - **Code Mode**: Implementation, refactoring, API development 58 | - **Test Mode**: Test planning, implementation, execution 59 | - **Debug Mode**: Issue investigation, bug fixing, troubleshooting 60 | - **Ask Mode**: Research, information gathering, concept explanation 61 | 62 | ## Example Workflow 63 | 64 | 1. Start in Captain Mode 65 | 2. Describe your project: "I want to build a weather dashboard application" 66 | 3. Captain Mode analyzes the request and breaks it down: 67 | - Architecture design (Architect Mode) 68 | - API integration (Code Mode) 69 | - UI implementation (Code Mode) 70 | - Testing strategy (Test Mode) 71 | - Documentation (Ask Mode) 72 | 4. Captain Mode delegates the first task (e.g., to Architect Mode) 73 | 5. When Architect Mode completes its task, control returns to Captain Mode 74 | 6. Captain Mode delegates the next task, and so on 75 | 7. Captain Mode maintains the task registry and project context throughout 76 | 77 | ## Benefits of Captain Mode 78 | 79 | - **Reduced Context Pollution**: Each mode focuses only on its specialized area 80 | - **Improved Organization**: Clear task breakdown and assignment 81 | - **Better Progress Tracking**: Centralized task registry 82 | - **Enhanced Project Coherence**: Maintained high-level overview 83 | - **Optimized Resource Usage**: Right mode for the right task 84 | -------------------------------------------------------------------------------- /rooflow-captainmode-docs/mode-management.md: -------------------------------------------------------------------------------- 1 | # Mode Management in RooFlow 2 | 3 | This document provides guidance on managing and troubleshooting modes in RooFlow, including the enhanced Captain mode. 4 | 5 | ## Verification Steps 6 | 7 | After installing or updating modes: 8 | 9 | 1. Restart Visual Studio Code 10 | 2. Open the Roo Code chat panel 11 | 3. Click the mode selector (top of chat panel) 12 | 4. Verify that all modes are listed and available 13 | 5. Test the Captain mode to ensure it: 14 | - Can access the task registry 15 | - Properly delegates tasks 16 | - Successfully transitions between modes 17 | - Updates the memory bank correctly 18 | 19 | ## Troubleshooting 20 | 21 | If you encounter issues: 22 | 23 | 1. Configuration Files: 24 | - Verify JSON syntax in `.roo/cline_custom_modes.json` 25 | - Check YAML syntax in `.roo/custom-instructions.yaml` 26 | - Ensure all files are in their correct locations 27 | 28 | 2. File Permissions: 29 | - `.roo/` directory and its contents should be readable 30 | - `memory-bank/` directory should be readable and writable 31 | - `.rooignore` should be readable 32 | 33 | 3. Memory Bank: 34 | - Verify that `taskRegistry.md` exists in the `memory-bank/` directory 35 | - Check that the memory bank is being updated properly 36 | - Ensure mode transitions are being recorded 37 | 38 | 4. Mode Transitions: 39 | - Confirm that mode switching triggers are working 40 | - Verify that context is preserved during transitions 41 | - Check that task status updates properly 42 | 43 | 5. General Steps: 44 | - Restart VS Code after making configuration changes 45 | - Check the VS Code Developer Tools console for error messages 46 | - Verify that the Roo Code extension is up to date 47 | 48 | ## Support 49 | 50 | If you need help or encounter issues: 51 | 52 | 1. Check the documentation in the `docs/` directory 53 | 2. Review the Captain mode implementation details 54 | 3. File an issue on the GitHub repository with: 55 | - Description of the problem 56 | - Steps to reproduce 57 | - Relevant error messages 58 | - Configuration file contents (if applicable) -------------------------------------------------------------------------------- /rooflow-captainmode-docs/project-scan-feature.md: -------------------------------------------------------------------------------- 1 | # Project Scan Feature Proposal 2 | 3 | ## Overview 4 | Implementation of an initial project scan feature for the memory bank system to provide context and task awareness when RooFlow is introduced to an existing project. 5 | 6 | ## Functionality 7 | 8 | ### 1. Project Structure Analysis 9 | - Scan directory structure and file types 10 | - Identify key project components (src, tests, docs, etc.) 11 | - Map dependencies and relationships between components 12 | - Create project structure summary in memory bank 13 | 14 | ### 2. Task Discovery 15 | - Scan for TODO comments and issue markers 16 | - Identify incomplete or ongoing work 17 | - Create initial task entries in taskRegistry.md 18 | - Tag tasks with appropriate modes based on content 19 | 20 | ### 3. Context Building 21 | - Parse documentation files for project context 22 | - Analyze commit history for recent changes 23 | - Create baseline context in activeContext.md 24 | - Map technical debt and potential improvement areas 25 | 26 | ### 4. Integration Points 27 | - Scan should be triggered via explicit command 28 | - Results stored in memory-bank/projectScan.md 29 | - Updates taskRegistry.md with discovered tasks 30 | - Initializes activeContext.md with baseline data 31 | 32 | ## Implementation Plan 33 | 34 | 1. Add Project Scan Command 35 | ```bash 36 | roo scan-project [--depth=<n>] [--include-history] [--output-format=<format>] 37 | ``` 38 | 39 | 2. Scanner Components 40 | - FileSystemScanner: Maps project structure 41 | - TaskScanner: Identifies and categorizes tasks 42 | - ContextBuilder: Creates initial context 43 | - RegistryUpdater: Populates task registry 44 | 45 | 3. Output Documents 46 | - projectScan.md: Scan results and analysis 47 | - Initial taskRegistry.md entries 48 | - Baseline activeContext.md 49 | 50 | 4. Integration with Existing Features 51 | - Links with mode delegation system 52 | - Updates task registry format 53 | - Preserves existing context if present 54 | 55 | ## Success Criteria 56 | - Accurate project structure mapping 57 | - Meaningful task discovery 58 | - Useful initial context 59 | - Performance on large codebases 60 | - Non-destructive to existing data 61 | 62 | ## Benefits 63 | 1. Faster onboarding to existing projects 64 | 2. Automated task discovery 65 | 3. Immediate context availability 66 | 4. Structured project understanding -------------------------------------------------------------------------------- /rooflow-captainmode-supportfiles/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to RooFlow 2 | 3 | Thank you for your interest in contributing to RooFlow! We welcome contributions from everyone. This document outlines how to contribute to the project. 4 | 5 | ## Ways to Contribute 6 | 7 | * **Bug Reports:** If you find a bug, please open an issue on the GitHub repository, providing a clear description of the problem, steps to reproduce it, and your expected vs. actual results. Include the Roo version, VS Code version, and operating system. 8 | * **Feature Requests:** If you have an idea for a new feature, open an issue on GitHub and describe the feature, its benefits, and any potential implementation details. 9 | * **Code Contributions:** If you want to contribute code (bug fixes, new features, improvements), please follow these steps: 10 | 1. **Fork the Repository:** Create a fork of the RooFlow repository on GitHub. 11 | 2. **Create a Branch:** Create a new branch for your changes (e.g., `feature/my-new-feature` or `bugfix/issue-123`). Use descriptive branch names. 12 | 3. **Make Changes:** Make your changes, following the coding style and conventions of the project. 13 | 4. **Test Thoroughly:** Ensure your changes work correctly and don't introduce new issues. Test with and without an existing Memory Bank. Test the UMB command. 14 | 5. **Commit Changes:** Commit your changes with clear and descriptive commit messages. 15 | 6. **Push to Your Fork:** Push your branch to your forked repository. 16 | 7. **Create a Pull Request:** Create a pull request from your branch to the `main` branch of the RooFlow repository. Clearly describe your changes and the problem they solve or the feature they add. 17 | * **Documentation:** Improvements to the documentation (README, etc.) are also welcome. Follow the same process as for code contributions. 18 | 19 | ## Development Setup 20 | 21 | To develop RooFlow, you'll need: 22 | 23 | 1. **VS Code:** Install Visual Studio Code. 24 | 2. **Roo Code Extension:** Install the Roo Code extension from the VS Code Marketplace. 25 | 3. **Git:** Install Git for version control. 26 | 4. **Node.js and npm (likely):** While RooFlow itself doesn't have *code* in the traditional sense, the Roo Code extension likely uses Node.js and npm for its build process. If you're modifying the `system-prompt-[mode]` files, you *might* need to rebuild the extension. Check the Roo Code documentation for specific instructions. 27 | 28 | **Project Structure:** 29 | 30 | The RooFlow project consists of the following files, which you should place in your project's root directory: 31 | 32 | * `.roo/`: A directory containing the system prompts. 33 | * `system-prompt-captain`: System prompt for Captain mode (project orchestration). 34 | * `system-prompt-architect`: System prompt for Architect mode. 35 | * `system-prompt-code`: System prompt for Code mode. 36 | * `system-prompt-debug`: System prompt for Debug mode. 37 | * `system-prompt-ask`: System prompt for Ask mode. 38 | * `system-prompt-test`: System prompt for Test mode. 39 | * `cline_custom_modes.json`: Defines an optional global Default mode. 40 | * `.rooignore`: So Roo doesn't ignore memory-bank/ if it's gitignored. 41 | * `.roomodes`: Defines the custom Captain and Test modes. 42 | * `README.md`: This file. 43 | * `projectBrief.md`: Optional project brief. 44 | 45 | **Memory Bank:** 46 | 47 | The `memory-bank/` directory is created automatically by RooFlow. Do *not* create it manually. Captain mode adds a `taskRegistry.md` file to track tasks and their status. 48 | 49 | **Testing:** 50 | 51 | * **Test Thoroughly:** Before submitting any changes, test them thoroughly in various scenarios. 52 | * **Memory Bank Presence/Absence:** Test with and without an existing Memory Bank. 53 | * **UMB Command:** Test the "Update Memory Bank" (UMB) command to ensure it works correctly. 54 | * **Mode Switching:** Test switching between different modes. 55 | * **Error Handling:** Test how RooFlow handles errors and unexpected situations. 56 | 57 | ## Coding Style 58 | 59 | * **YAML:** The `system-prompt-[mode]` files use YAML format. Use consistent indentation (2 spaces) and follow YAML best practices. 60 | * **Markdown:** The Memory Bank files (`.md`) use Markdown format. 61 | * **Clarity:** Write clear, concise, and unambiguous instructions. 62 | * **Comments**: Use comments within the YAML files to explain complex logic. 63 | 64 | ## Pull Request Guidelines 65 | 66 | * **Descriptive Title:** Use a clear and descriptive title for your pull request. 67 | * **Detailed Description:** Provide a detailed description of your changes, including the motivation for the changes, the approach taken, and any relevant context. 68 | * **Link to Issue:** If your pull request addresses an existing issue, link to the issue in the description. 69 | * **Small, Focused Changes:** Prefer smaller, focused pull requests over large, monolithic ones. 70 | * **Tests:** Include tests for any new functionality or bug fixes. 71 | 72 | ## Code of Conduct 73 | 74 | Please be respectful and constructive in all interactions. 75 | 76 | By contributing to RooFlow, you agree to abide by the terms of the [Apache 2.0 License](LICENSE). 77 | -------------------------------------------------------------------------------- /rooflow-captainmode-supportfiles/insert-variables.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # --- Get Environment Variables Correctly --- 4 | if [[ "$(uname)" == "Darwin" ]]; then 5 | # macOS specific 6 | OS="macOS $(sw_vers -productVersion)" 7 | SED_IN_PLACE=(-i "") 8 | else 9 | # Linux specific 10 | OS=$(uname -s -r) 11 | SED_IN_PLACE=(-i) 12 | fi 13 | 14 | SHELL="bash" # Hardcode to bash since we're explicitly using it 15 | HOME=$(echo "$HOME") # Use existing $HOME, but quote it 16 | WORKSPACE=$(pwd) 17 | 18 | # --- Construct Paths --- 19 | GLOBAL_SETTINGS="$HOME/.vscode-server/data/User/globalStorage/rooveterinaryinc.roo-cline/settings/cline_custom_modes.json" 20 | MCP_LOCATION="$HOME/.local/share/Roo-Code/MCP" 21 | MCP_SETTINGS="$HOME/.vscode-server/data/User/globalStorage/rooveterinaryinc.roo-cline/settings/cline_mcp_settings.json" 22 | 23 | # --- Directory Setup --- 24 | ROO_DIR="$WORKSPACE/.roo" 25 | 26 | # Check if the .roo directory exists 27 | if [ ! -d "$ROO_DIR" ]; then 28 | echo "Error: .roo directory not found in $WORKSPACE" 29 | exit 1 30 | fi 31 | 32 | # --- Function to escape strings for sed --- 33 | escape_for_sed() { 34 | echo "$1" | sed 's/[\/&]/\\&/g' 35 | } 36 | 37 | # --- Perform Replacements using sed --- 38 | find "$ROO_DIR" -type f -name "system-prompt-*" -print0 | while IFS= read -r -d $'\0' file; do 39 | echo "Processing: $file" 40 | 41 | # Basic variables - using sed with escaped strings 42 | sed "${SED_IN_PLACE[@]}" "s/OS_PLACEHOLDER/$(escape_for_sed "$OS")/g" "$file" 43 | sed "${SED_IN_PLACE[@]}" "s/SHELL_PLACEHOLDER/$(escape_for_sed "$SHELL")/g" "$file" 44 | sed "${SED_IN_PLACE[@]}" "s|HOME_PLACEHOLDER|$(escape_for_sed "$HOME")|g" "$file" 45 | sed "${SED_IN_PLACE[@]}" "s|WORKSPACE_PLACEHOLDER|$(escape_for_sed "$WORKSPACE")|g" "$file" 46 | 47 | # Complex paths - using sed with escaped strings 48 | sed "${SED_IN_PLACE[@]}" "s|GLOBAL_SETTINGS_PLACEHOLDER|$(escape_for_sed "$GLOBAL_SETTINGS")|g" "$file" 49 | sed "${SED_IN_PLACE[@]}" "s|MCP_LOCATION_PLACEHOLDER|$(escape_for_sed "$MCP_LOCATION")|g" "$file" 50 | sed "${SED_IN_PLACE[@]}" "s|MCP_SETTINGS_PLACEHOLDER|$(escape_for_sed "$MCP_SETTINGS")|g" "$file" 51 | 52 | echo "Completed: $file" 53 | done 54 | 55 | echo "Done." -------------------------------------------------------------------------------- /scripts/init.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Initialization script for rooflow-captainmode 5 | * This script initializes the RooFlow Captain Mode in the user's project by creating 6 | * all necessary configuration files and directories. 7 | */ 8 | 9 | const fs = require('fs'); 10 | const path = require('path'); 11 | const { execSync } = require('child_process'); 12 | 13 | // Get the project root directory 14 | const projectRoot = process.cwd(); 15 | // Get the package root directory 16 | const packageRoot = path.join(__dirname, '..'); 17 | 18 | console.log('Initializing RooFlow Captain Mode in your project...'); 19 | 20 | // Create directories 21 | const directories = [ 22 | '.roo', 23 | 'memory-bank' 24 | ]; 25 | 26 | directories.forEach(dir => { 27 | const dirPath = path.join(projectRoot, dir); 28 | if (!fs.existsSync(dirPath)) { 29 | console.log(`Creating directory: ${dir}`); 30 | fs.mkdirSync(dirPath, { recursive: true }); 31 | } else { 32 | console.log(`Directory already exists: ${dir}`); 33 | } 34 | }); 35 | 36 | // Copy configuration files 37 | const configFiles = [ 38 | '.clinerules-architect', 39 | '.clinerules-ask', 40 | '.clinerules-captain', 41 | '.clinerules-code', 42 | '.clinerules-debug', 43 | '.clinerules-test', 44 | '.rooignore', 45 | '.roo/cline_custom_modes.json', 46 | '.roo/custom-instructions.yaml' 47 | ]; 48 | 49 | configFiles.forEach(file => { 50 | const sourcePath = path.join(packageRoot, file); 51 | const destPath = path.join(projectRoot, file); 52 | 53 | if (fs.existsSync(sourcePath)) { 54 | if (!fs.existsSync(destPath)) { 55 | console.log(`Copying file: ${file}`); 56 | fs.copyFileSync(sourcePath, destPath); 57 | } else { 58 | console.log(`File already exists: ${file}`); 59 | } 60 | } else { 61 | console.warn(`Source file not found: ${file}`); 62 | } 63 | }); 64 | 65 | // Create memory bank files 66 | const memoryBankFiles = [ 67 | { 68 | name: 'activeContext.md', 69 | content: '# Active Context\n\nThis file tracks the project\'s current status, including recent changes, current goals, and open questions.\n\n## Current Focus\n\n* Initial project setup\n* Defining project requirements\n* Setting up development environment\n\n[' + new Date().toISOString().replace('T', ' ').substring(0, 19) + '] - Memory Bank initialized\n' 70 | }, 71 | { 72 | name: 'decisionLog.md', 73 | content: '# Decision Log\n\nThis file records architectural and implementation decisions using a list format.\n\n## Decision: Initialize RooFlow Captain Mode\n\n* Decision: Initialize RooFlow Captain Mode for project management\n\n* Rationale: \n * Need for structured task management\n * Requirement for persistent context across sessions\n * Improved project organization\n\n* Implementation Details:\n * Set up Memory Bank structure\n * Configure mode transitions\n * Initialize task registry\n\n[' + new Date().toISOString().replace('T', ' ').substring(0, 19) + '] - Decision recorded\n' 74 | }, 75 | { 76 | name: 'productContext.md', 77 | content: '# Product Context\n\nThis file provides a high-level overview of the project, including its purpose, goals, and key features.\n\n## Project Overview\n\n[Add your project description here]\n\n## Key Features\n\n* [Feature 1]\n* [Feature 2]\n* [Feature 3]\n\n## Technical Stack\n\n* [Technology 1]\n* [Technology 2]\n* [Technology 3]\n\n## Project Timeline\n\n* Start Date: [Date]\n* Milestone 1: [Date]\n* Milestone 2: [Date]\n* Target Completion: [Date]\n\n[' + new Date().toISOString().replace('T', ' ').substring(0, 19) + '] - Product context initialized\n' 78 | }, 79 | { 80 | name: 'progress.md', 81 | content: '# Progress\n\nThis file tracks the project\'s progress using a task list format.\n\n[' + new Date().toISOString().replace('T', ' ').substring(0, 19) + '] - Memory Bank initialized\n\n## Current Tasks\n\n* Set up project structure\n* Configure development environment\n* Define initial requirements\n\n## Next Steps\n\n* Implement core functionality\n* Set up testing framework\n* Create documentation\n' 82 | }, 83 | { 84 | name: 'systemPatterns.md', 85 | content: '# System Patterns\n\nThis file documents recurring patterns and standards used in the project.\n\n## Coding Patterns\n\n* [Add your coding patterns here]\n\n## Architectural Patterns\n\n* [Add your architectural patterns here]\n\n## Testing Patterns\n\n* [Add your testing patterns here]\n\n[' + new Date().toISOString().replace('T', ' ').substring(0, 19) + '] - System patterns initialized\n' 86 | }, 87 | { 88 | name: 'taskRegistry.md', 89 | content: '# Task Registry\n\nThis file maintains a registry of tasks, their status, and dependencies.\n\n[' + new Date().toISOString().replace('T', ' ').substring(0, 19) + '] - Task registry initialized\n\n## Active Tasks\n\n* Project Setup\n * Status: In Progress\n * Dependencies: None\n * Description: Set up the project structure and configuration\n\n## Planned Tasks\n\n* Core Implementation\n * Status: Planned\n * Dependencies: Project Setup\n * Description: Implement core functionality\n\n* Testing Framework\n * Status: Planned\n * Dependencies: Project Setup\n * Description: Set up testing framework and write tests\n\n* Documentation\n * Status: Planned\n * Dependencies: Core Implementation\n * Description: Create project documentation\n' 90 | } 91 | ]; 92 | 93 | memoryBankFiles.forEach(file => { 94 | const filePath = path.join(projectRoot, 'memory-bank', file.name); 95 | if (!fs.existsSync(filePath)) { 96 | console.log(`Creating memory bank file: ${file.name}`); 97 | fs.writeFileSync(filePath, file.content); 98 | } else { 99 | console.log(`Memory bank file already exists: ${file.name}`); 100 | } 101 | }); 102 | 103 | console.log(''); 104 | console.log('RooFlow Captain Mode has been successfully initialized in your project!'); 105 | console.log(''); 106 | console.log('To use RooFlow Captain Mode:'); 107 | console.log('1. Open your project in VS Code'); 108 | console.log('2. Ensure the Roo Code extension is installed'); 109 | console.log('3. Select "Captain" mode in the Roo Code chat panel'); 110 | console.log(''); 111 | console.log('For more information, see the documentation at:'); 112 | console.log(' https://github.com/shipdocs/RooFlow-captainmode'); 113 | -------------------------------------------------------------------------------- /scripts/postinstall.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Post-installation script for rooflow-captainmode 5 | * This script runs after the package is installed and checks if the user wants to initialize 6 | * the RooFlow Captain Mode in their project. 7 | */ 8 | 9 | const fs = require('fs'); 10 | const path = require('path'); 11 | const { execSync } = require('child_process'); 12 | 13 | // Get the project root directory (where the package is installed) 14 | const projectRoot = process.env.INIT_CWD || process.cwd(); 15 | 16 | console.log('Thank you for installing RooFlow Captain Mode!'); 17 | console.log(''); 18 | console.log('To initialize RooFlow Captain Mode in your project, run:'); 19 | console.log(' npx rooflow-captainmode init'); 20 | console.log(''); 21 | console.log('This will create all necessary configuration files and the memory-bank directory in your project.'); 22 | console.log(''); 23 | console.log('For more information, see the documentation at:'); 24 | console.log(' https://github.com/shipdocs/RooFlow-captainmode'); 25 | -------------------------------------------------------------------------------- /src/TaskScanner.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs/promises'; 2 | import * as path from 'path'; 3 | import * as glob from 'glob'; 4 | 5 | export type Priority = 'low' | 'medium' | 'high' | 'none' | undefined; 6 | 7 | export interface TaskMarker { 8 | type: 'TODO' | 'FIXME' | 'NOTE' | 'HACK' | 'BUG' | 'ISSUE'; 9 | description: string; 10 | priority?: Priority; 11 | assignee?: string; 12 | labels: string[]; 13 | } 14 | 15 | export interface TaskLocation { 16 | filePath: string; 17 | lineNumber: number; 18 | columnNumber: number; 19 | context: string; 20 | } 21 | 22 | export interface DiscoveredTask { 23 | marker: TaskMarker; 24 | location: TaskLocation; 25 | } 26 | 27 | export interface TaskScanResults { 28 | tasks: DiscoveredTask[]; 29 | statistics: { 30 | totalTasks: number; 31 | byType: Map<string, number>; 32 | byPriority: Map<string, number>; 33 | byLabel: Map<string, number>; 34 | }; 35 | } 36 | 37 | export interface TaskScanOptions { 38 | include?: string[]; 39 | exclude?: string[]; 40 | customMarkers?: string[]; 41 | } 42 | 43 | export class TaskScanner { 44 | private static readonly DEFAULT_MARKERS = [ 45 | 'TODO', 46 | 'FIXME', 47 | 'NOTE', 48 | 'HACK', 49 | 'BUG', 50 | 'ISSUE' 51 | ]; 52 | 53 | private static readonly MARKER_PATTERN = /(?:\/\/|\/\*|#)\s*(@?)(?:(TODO|FIXME|NOTE|HACK|BUG|ISSUE))(?:\(([^)]+)\))?:?\s*([^]*?)(?=\n|$)/gi; 54 | private static readonly PRIORITY_PATTERN = /(!{1,3})/g; 55 | private static readonly LABEL_PATTERN = /@(\w+)/g; 56 | private static readonly ASSIGNEE_PATTERN = /\bas:(@?\w+)\b/i; 57 | 58 | constructor(private readonly options: TaskScanOptions = {}) {} 59 | 60 | async scanFile(filePath: string): Promise<DiscoveredTask[]> { 61 | try { 62 | const content = await fs.readFile(filePath, 'utf-8'); 63 | const lines = content.split('\n'); 64 | const tasks: DiscoveredTask[] = []; 65 | 66 | for (let i = 0; i < lines.length; i++) { 67 | const line = lines[i]; 68 | const matches = Array.from(line.matchAll(TaskScanner.MARKER_PATTERN)); 69 | 70 | for (const match of matches) { 71 | const [fullMatch, isAnnotation, type, meta, description] = match; 72 | const startColumn = match.index || 0; 73 | 74 | // Extract priority from both meta and description 75 | const combinedText = `${meta || ''} ${description}`; 76 | const priority = this.extractPriority(combinedText); 77 | 78 | const labels = this.extractLabels(description); 79 | const assignee = this.extractAssignee(description); 80 | 81 | const contextStart = Math.max(0, i - 2); 82 | const contextEnd = Math.min(lines.length, i + 3); 83 | const context = lines.slice(contextStart, contextEnd).join('\n'); 84 | 85 | tasks.push({ 86 | marker: { 87 | type: type.toUpperCase() as TaskMarker['type'], 88 | description: description.trim(), 89 | priority, 90 | assignee, 91 | labels 92 | }, 93 | location: { 94 | filePath, 95 | lineNumber: i + 1, 96 | columnNumber: startColumn + 1, 97 | context 98 | } 99 | }); 100 | } 101 | } 102 | 103 | return tasks; 104 | } catch (error) { 105 | console.error(`Error scanning file ${filePath}:`, error); 106 | return []; 107 | } 108 | } 109 | 110 | async scanDirectory(dirPath: string): Promise<TaskScanResults> { 111 | const tasks: DiscoveredTask[] = []; 112 | const statistics = { 113 | totalTasks: 0, 114 | byType: new Map<string, number>(), 115 | byPriority: new Map<string, number>(), 116 | byLabel: new Map<string, number>() 117 | }; 118 | 119 | try { 120 | const files = this.getFilesToScan(dirPath); 121 | 122 | for (const file of files) { 123 | const fileTasks = await this.scanFile(file); 124 | tasks.push(...fileTasks); 125 | 126 | // Update statistics 127 | for (const task of fileTasks) { 128 | statistics.totalTasks++; 129 | 130 | // Count by type 131 | const typeCount = statistics.byType.get(task.marker.type) || 0; 132 | statistics.byType.set(task.marker.type, typeCount + 1); 133 | 134 | // Count by priority 135 | const priority = task.marker.priority === undefined ? 'none' : task.marker.priority; 136 | const priorityCount = statistics.byPriority.get(priority) || 0; 137 | statistics.byPriority.set(priority, priorityCount + 1); 138 | 139 | // Count by label 140 | for (const label of task.marker.labels) { 141 | const labelCount = statistics.byLabel.get(label) || 0; 142 | statistics.byLabel.set(label, labelCount + 1); 143 | } 144 | } 145 | } 146 | 147 | return { tasks, statistics }; 148 | } catch (error) { 149 | console.error(`Error scanning directory ${dirPath}:`, error); 150 | return { tasks, statistics }; 151 | } 152 | } 153 | 154 | private getFilesToScan(dirPath: string): string[] { 155 | try { 156 | const include = this.options.include || ['**/*']; 157 | const exclude = this.options.exclude || []; 158 | 159 | const files = new Set<string>(); 160 | 161 | for (const pattern of include) { 162 | const matches = glob.sync(pattern, { 163 | cwd: dirPath, 164 | ignore: exclude, 165 | nodir: true, 166 | absolute: true 167 | }); 168 | matches.forEach(file => files.add(file)); 169 | } 170 | 171 | return Array.from(files); 172 | } catch (error) { 173 | console.error(`Error getting files to scan in ${dirPath}:`, error); 174 | return []; 175 | } 176 | } 177 | 178 | private extractPriority(text: string): Priority | undefined { 179 | const matches = Array.from(text.matchAll(TaskScanner.PRIORITY_PATTERN)); 180 | if (!matches.length) return undefined; 181 | 182 | const maxExclamations = Math.max(...matches.map(m => m[1].length)); 183 | return maxExclamations === 3 ? 'high' : 184 | maxExclamations === 2 ? 'medium' : 185 | maxExclamations === 1 ? 'low' : undefined; 186 | } 187 | 188 | private extractLabels(text: string): string[] { 189 | const matches = Array.from(text.matchAll(TaskScanner.LABEL_PATTERN)); 190 | return matches.map(match => match[1]).filter(Boolean); 191 | } 192 | 193 | private extractAssignee(text: string): string | undefined { 194 | const match = text.match(TaskScanner.ASSIGNEE_PATTERN); 195 | return match ? match[1] : undefined; 196 | } 197 | } -------------------------------------------------------------------------------- /src/cli/captain.ts: -------------------------------------------------------------------------------- 1 | import { Command } from 'commander'; 2 | import { TaskStatus } from '../scanner/components/interfaces/Task'; 3 | import { Roo } from '../roo'; 4 | 5 | interface TaskOptions { 6 | depends?: string; 7 | } 8 | 9 | export class Captain { 10 | constructor() { 11 | // Initialize captain 12 | } 13 | 14 | notifyTaskCreated(taskId: string, mode: string): void { 15 | // Handle task creation notification 16 | } 17 | 18 | updateTaskStatus(taskId: string, newStatus: TaskStatus): void { 19 | // Handle task status update 20 | } 21 | 22 | switchMode(mode: string): void { 23 | // Handle mode switching 24 | } 25 | } 26 | 27 | export function setupCaptainCommands(program: Command, roo: Roo): void { 28 | program 29 | .command('task:create') 30 | .description('Create a new task and assign it to a mode') 31 | .argument('<description>', 'Task description') 32 | .argument('<mode>', 'Target mode (architect, code, test, debug, ask)') 33 | .option('-d, --depends <taskIds>', 'Comma-separated list of dependent task IDs') 34 | .action((description: string, mode: string, options: TaskOptions) => { 35 | const dependencies = options.depends ? options.depends.split(',') : undefined; 36 | const taskId = roo.createTask(description, mode, dependencies); 37 | console.log(`Created task ${taskId}`); 38 | }); 39 | 40 | program 41 | .command('task:delegate') 42 | .description('Delegate a task to another mode') 43 | .argument('<taskId>', 'Task ID') 44 | .argument('<mode>', 'Target mode (architect, code, test, debug, ask)') 45 | .argument('<reason>', 'Reason for delegation') 46 | .action((taskId: string, mode: string, reason: string) => { 47 | roo.delegateTask(taskId, mode, reason); 48 | console.log(`Delegated task ${taskId} to ${mode}`); 49 | }); 50 | 51 | program 52 | .command('task:status') 53 | .description('Update task status') 54 | .argument('<taskId>', 'Task ID') 55 | .argument('<status>', 'New status (pending, in_progress, blocked, completed, cancelled)') 56 | .action((taskId: string, status: string) => { 57 | const taskStatus = status.toUpperCase() as keyof typeof TaskStatus; 58 | if (!TaskStatus[taskStatus]) { 59 | throw new Error('Invalid status. Must be one of: pending, in_progress, blocked, completed, cancelled'); 60 | } 61 | roo.updateTaskStatus(taskId, TaskStatus[taskStatus]); 62 | console.log(`Updated task ${taskId} status to ${status}`); 63 | }); 64 | 65 | program 66 | .command('mode:switch') 67 | .description('Switch to another mode') 68 | .argument('<mode>', 'Target mode (architect, code, test, debug, ask)') 69 | .argument('<reason>', 'Reason for switching') 70 | .action((mode: string, reason: string) => { 71 | //captain.switchMode(mode, reason); 72 | console.log(`Switched to ${mode} mode`); 73 | }); 74 | } -------------------------------------------------------------------------------- /src/cli/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { Command } from 'commander'; 3 | import { setupCaptainCommands, Captain } from './captain'; 4 | import { Roo } from '../roo'; 5 | 6 | const program = new Command(); 7 | const roo = new Roo(); 8 | const captain = new Captain(); 9 | 10 | program 11 | .name('roo') 12 | .description('Roo CLI - Project Orchestration and Task Management') 13 | .version('1.0.0'); 14 | 15 | setupCaptainCommands(program, roo); 16 | 17 | program.parse(process.argv); -------------------------------------------------------------------------------- /src/cli/memory-bank.ts: -------------------------------------------------------------------------------- 1 | import { Command } from 'commander'; 2 | import { Roo } from '../roo'; 3 | import { MemoryBankManager } from '../memory-bank/MemoryBankManager'; 4 | import * as path from 'path'; 5 | 6 | export function setupMemoryBankCommands(program: Command, roo: Roo): void { 7 | const memoryBankCommand = program 8 | .command('memory-bank') 9 | .description('Memory Bank management commands'); 10 | 11 | memoryBankCommand 12 | .command('status') 13 | .description('Check Memory Bank status') 14 | .action(async () => { 15 | const memoryBankManager = new MemoryBankManager(roo.getRootPath()); 16 | const status = await memoryBankManager.initialize(); 17 | 18 | console.log('Memory Bank Status:'); 19 | console.log(`- Active: ${status.active ? 'Yes' : 'No'}`); 20 | 21 | if (status.lastSynchronized) { 22 | console.log(`- Last Synchronized: ${status.lastSynchronized.toISOString()}`); 23 | } 24 | 25 | if (status.missingFiles && status.missingFiles.length > 0) { 26 | console.log(`- Missing Files: ${status.missingFiles.join(', ')}`); 27 | } 28 | }); 29 | 30 | memoryBankCommand 31 | .command('create') 32 | .description('Create Memory Bank if it does not exist') 33 | .action(async () => { 34 | const memoryBankManager = new MemoryBankManager(roo.getRootPath()); 35 | const result = await memoryBankManager.createMemoryBank(); 36 | 37 | if (result.success) { 38 | console.log('Memory Bank created successfully'); 39 | console.log(`Created files: ${result.updatedFiles.join(', ')}`); 40 | } else { 41 | console.error('Failed to create Memory Bank'); 42 | if (result.errors) { 43 | console.error(`Errors: ${result.errors.join(', ')}`); 44 | } 45 | } 46 | }); 47 | 48 | memoryBankCommand 49 | .command('validate') 50 | .description('Validate Memory Bank structure') 51 | .action(async () => { 52 | const memoryBankManager = new MemoryBankManager(roo.getRootPath()); 53 | const result = await memoryBankManager.synchronizer.validateMemoryBank(); 54 | 55 | if (result.success) { 56 | console.log('Memory Bank validation successful'); 57 | console.log(`Found files: ${result.updatedFiles.join(', ')}`); 58 | } else { 59 | console.error('Memory Bank validation failed'); 60 | if (result.errors) { 61 | console.error(`Errors: ${result.errors.join(', ')}`); 62 | } 63 | } 64 | }); 65 | 66 | memoryBankCommand 67 | .command('record-decision') 68 | .description('Record a decision in the Memory Bank') 69 | .argument('<title>', 'Decision title') 70 | .argument('<rationale>', 'Decision rationale') 71 | .argument('<implementation>', 'Implementation details') 72 | .action(async (title: string, rationale: string, implementation: string) => { 73 | const memoryBankManager = new MemoryBankManager(roo.getRootPath()); 74 | const result = await memoryBankManager.recordDecision(title, rationale, implementation); 75 | 76 | if (result.success) { 77 | console.log('Decision recorded successfully'); 78 | } else { 79 | console.error('Failed to record decision'); 80 | if (result.errors) { 81 | console.error(`Errors: ${result.errors.join(', ')}`); 82 | } 83 | } 84 | }); 85 | 86 | memoryBankCommand 87 | .command('record-pattern') 88 | .description('Record a system pattern in the Memory Bank') 89 | .argument('<name>', 'Pattern name') 90 | .argument('<type>', 'Pattern type (Coding, Architectural, Testing)') 91 | .argument('<description>', 'Pattern description') 92 | .action(async (name: string, type: string, description: string) => { 93 | const memoryBankManager = new MemoryBankManager(roo.getRootPath()); 94 | 95 | // Validate pattern type 96 | const patternType = type as 'Coding' | 'Architectural' | 'Testing'; 97 | if (!['Coding', 'Architectural', 'Testing'].includes(patternType)) { 98 | console.error('Invalid pattern type. Must be one of: Coding, Architectural, Testing'); 99 | return; 100 | } 101 | 102 | const result = await memoryBankManager.recordSystemPattern(name, patternType, description); 103 | 104 | if (result.success) { 105 | console.log('Pattern recorded successfully'); 106 | } else { 107 | console.error('Failed to record pattern'); 108 | if (result.errors) { 109 | console.error(`Errors: ${result.errors.join(', ')}`); 110 | } 111 | } 112 | }); 113 | 114 | memoryBankCommand 115 | .command('record-mode-transition') 116 | .description('Record a mode transition in the Memory Bank') 117 | .argument('<from-mode>', 'Source mode') 118 | .argument('<to-mode>', 'Target mode') 119 | .argument('<reason>', 'Transition reason') 120 | .action(async (fromMode: string, toMode: string, reason: string) => { 121 | const memoryBankManager = new MemoryBankManager(roo.getRootPath()); 122 | const result = await memoryBankManager.recordModeTransition(fromMode, toMode, reason); 123 | 124 | if (result.success) { 125 | console.log('Mode transition recorded successfully'); 126 | } else { 127 | console.error('Failed to record mode transition'); 128 | if (result.errors) { 129 | console.error(`Errors: ${result.errors.join(', ')}`); 130 | } 131 | } 132 | }); 133 | } 134 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.getProjectSummaryMarkdown = exports.formatSize = exports.DEFAULT_SCAN_OPTIONS = exports.RegistryUpdater = exports.ContextBuilder = exports.TaskScanner = exports.FileSystemScanner = void 0; 4 | var FileSystemScanner_1 = require("./scanner/components/FileSystemScanner"); 5 | Object.defineProperty(exports, "FileSystemScanner", { enumerable: true, get: function () { return FileSystemScanner_1.FileSystemScanner; } }); 6 | var TaskScanner_1 = require("./scanner/components/TaskScanner"); 7 | Object.defineProperty(exports, "TaskScanner", { enumerable: true, get: function () { return TaskScanner_1.TaskScanner; } }); 8 | var ContextBuilder_1 = require("./scanner/components/ContextBuilder"); 9 | Object.defineProperty(exports, "ContextBuilder", { enumerable: true, get: function () { return ContextBuilder_1.ContextBuilder; } }); 10 | var RegistryUpdater_1 = require("./scanner/components/RegistryUpdater"); 11 | Object.defineProperty(exports, "RegistryUpdater", { enumerable: true, get: function () { return RegistryUpdater_1.RegistryUpdater; } }); 12 | // Re-export default configuration 13 | exports.DEFAULT_SCAN_OPTIONS = { 14 | depth: Infinity, 15 | excludePatterns: [], 16 | includeHidden: false 17 | }; 18 | // Export utility functions 19 | var formatSize = function (bytes) { 20 | var units = ['B', 'KB', 'MB', 'GB', 'TB']; 21 | var size = bytes; 22 | var unitIndex = 0; 23 | while (size >= 1024 && unitIndex < units.length - 1) { 24 | size /= 1024; 25 | unitIndex++; 26 | } 27 | return "".concat(size.toFixed(2), " ").concat(units[unitIndex]); 28 | }; 29 | exports.formatSize = formatSize; 30 | var getProjectSummaryMarkdown = function (summary) { 31 | var fileTypes = Array.from(summary.fileTypes.entries()) 32 | .sort(function (a, b) { return b[1] - a[1]; }) 33 | .map(function (entry) { 34 | var ext = entry[0], count = entry[1]; 35 | return "- ".concat(ext, ": ").concat(count, " files"); 36 | }) 37 | .join('\n'); 38 | return "# Project Scan Summary\n\n## Statistics\n- Total Files: ".concat(summary.totalFiles, "\n- Total Directories: ").concat(summary.totalDirs, "\n- Total Size: ").concat((0, exports.formatSize)(summary.totalSize), "\n\n## File Types\n").concat(fileTypes, "\n"); 39 | }; 40 | exports.getProjectSummaryMarkdown = getProjectSummaryMarkdown; 41 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { FileSystemScanner } from './scanner/components/FileSystemScanner'; 2 | import type { FileStats, FileNode, ScanOptions, ProjectStructure } from './scanner/components/FileSystemScanner'; 3 | import { TaskScanner } from './scanner/components/TaskScanner'; 4 | import type { TaskMarker, TaskLocation, DiscoveredTask, TaskScanResults, TaskScanOptions, Priority } from './scanner/components/TaskScanner'; 5 | import { ContextBuilder } from './scanner/components/ContextBuilder'; 6 | import type { ProjectMetadata, ProjectContext, ContextBuilderOptions } from './scanner/components/ContextBuilder'; 7 | import { RegistryUpdater } from './scanner/components/RegistryUpdater'; 8 | import type { RegistryUpdaterOptions } from './scanner/components/RegistryUpdater'; 9 | 10 | export { 11 | FileSystemScanner, 12 | TaskScanner, 13 | ContextBuilder, 14 | RegistryUpdater 15 | }; 16 | 17 | export type { 18 | FileStats, 19 | FileNode, 20 | ScanOptions, 21 | ProjectStructure, 22 | TaskMarker, 23 | TaskLocation, 24 | DiscoveredTask, 25 | TaskScanResults, 26 | TaskScanOptions, 27 | Priority, 28 | ProjectMetadata, 29 | ProjectContext, 30 | ContextBuilderOptions, 31 | RegistryUpdaterOptions 32 | }; 33 | 34 | // Re-export default configuration 35 | export const DEFAULT_SCAN_OPTIONS: ScanOptions = { 36 | depth: Infinity, 37 | excludePatterns: [] 38 | }; 39 | 40 | // Export utility functions 41 | export const formatSize = (bytes: number): string => { 42 | const units = ['B', 'KB', 'MB', 'GB', 'TB']; 43 | let size = bytes; 44 | let unitIndex = 0; 45 | 46 | while (size >= 1024 && unitIndex < units.length - 1) { 47 | size /= 1024; 48 | unitIndex++; 49 | } 50 | 51 | return `${size.toFixed(2)} ${units[unitIndex]}`; 52 | }; 53 | 54 | export const getProjectSummaryMarkdown = (summary: ProjectStructure['summary']): string => { 55 | const fileTypes = Array.from(summary.fileTypes.entries()) 56 | .sort((a: [string, number], b: [string, number]) => b[1] - a[1]) 57 | .map(([ext, count]: [string, number]) => { 58 | return `- ${ext}: ${count} files`; 59 | }) 60 | .join('\n'); 61 | 62 | return `# Project Scan Summary 63 | 64 | ## Statistics 65 | - Total Files: ${summary.totalFiles} 66 | - Total Directories: ${summary.totalDirs} 67 | - Total Size: ${formatSize(summary.totalSize)} 68 | 69 | ## File Types 70 | ${fileTypes} 71 | `; 72 | }; -------------------------------------------------------------------------------- /src/memory-bank/MemoryBankIntegration.md: -------------------------------------------------------------------------------- 1 | # Memory Bank Integration Documentation 2 | 3 | This document describes how the Memory Bank system is integrated with the RooFlow Captain Mode implementation. 4 | 5 | ## Overview 6 | 7 | The Memory Bank system provides persistent context across different modes and chat sessions. It consists of several key files: 8 | 9 | 1. **activeContext.md** - Tracks the current session's context 10 | 2. **decisionLog.md** - Records architectural and implementation decisions 11 | 3. **productContext.md** - Provides a high-level overview of the project 12 | 4. **progress.md** - Tracks the progress of the project 13 | 5. **systemPatterns.md** - Documents recurring patterns and standards 14 | 6. **taskRegistry.md** - Task tracking system 15 | 16 | ## Integration Components 17 | 18 | The Memory Bank integration consists of the following components: 19 | 20 | 1. **MemoryBankSynchronizer** - Handles file operations and synchronization 21 | 2. **MemoryBankManager** - Manages the Memory Bank lifecycle and status 22 | 3. **TaskManager Integration** - Connects task management with Memory Bank 23 | 24 | ## Usage 25 | 26 | ### Initializing the Memory Bank 27 | 28 | ```typescript 29 | // Create a TaskManager with Memory Bank support 30 | const taskManager = new TaskManager('/path/to/project'); 31 | 32 | // Check if Memory Bank exists 33 | const memoryBankManager = taskManager.getMemoryBankManager(); 34 | if (memoryBankManager) { 35 | const status = await memoryBankManager.initialize(); 36 | console.log(`Memory Bank active: ${status.active}`); 37 | } else { 38 | // Create Memory Bank if needed 39 | const created = await taskManager.createMemoryBank(); 40 | console.log(`Memory Bank created: ${created}`); 41 | } 42 | ``` 43 | 44 | ### Task Management with Memory Bank 45 | 46 | ```typescript 47 | // Create a task (automatically updates Memory Bank) 48 | const task = await taskManager.createTask({ 49 | description: 'Implement feature X', 50 | assignedMode: 'code' 51 | }); 52 | 53 | // Update task status (automatically updates Memory Bank) 54 | await taskManager.updateTaskStatus(task.id, TaskStatus.IN_PROGRESS); 55 | 56 | // Switch task mode (automatically updates Memory Bank) 57 | await taskManager.switchTaskMode(task.id, 'test', 'Ready for testing'); 58 | ``` 59 | 60 | ### Direct Memory Bank Operations 61 | 62 | ```typescript 63 | const memoryBankManager = taskManager.getMemoryBankManager(); 64 | if (memoryBankManager) { 65 | // Record a decision 66 | await memoryBankManager.recordDecision( 67 | 'Use TypeScript for implementation', 68 | 'Better type safety and developer experience', 69 | 'Configure TypeScript compiler options for strict mode' 70 | ); 71 | 72 | // Record a system pattern 73 | await memoryBankManager.recordSystemPattern( 74 | 'Repository Pattern', 75 | 'Architectural', 76 | 'Use repository pattern for data access layer' 77 | ); 78 | } 79 | ``` 80 | 81 | ## Cross-Mode Synchronization 82 | 83 | The Memory Bank system ensures that context is maintained across different modes: 84 | 85 | 1. When a task is delegated to another mode, the transition is recorded 86 | 2. The active context is updated to reflect the current focus 87 | 3. Progress is tracked across mode transitions 88 | 4. Decisions and system patterns are accessible to all modes 89 | 90 | ## Testing 91 | 92 | The Memory Bank system includes comprehensive tests: 93 | 94 | 1. **MemoryBankSynchronizer.test.ts** - Tests file operations and synchronization 95 | 2. **TaskManager.test.ts** - Tests integration with task management 96 | 97 | Run tests with: 98 | 99 | ```bash 100 | npm test 101 | ``` 102 | -------------------------------------------------------------------------------- /src/memory-bank/MemoryBankManager.ts: -------------------------------------------------------------------------------- 1 | import { Task } from '../scanner/components/interfaces/Task'; 2 | import { MemoryBankSynchronizer, SynchronizationResult } from './MemoryBankSynchronizer'; 3 | 4 | export interface MemoryBankStatus { 5 | active: boolean; 6 | lastSynchronized?: Date; 7 | missingFiles?: string[]; 8 | } 9 | 10 | export class MemoryBankManager { 11 | public synchronizer: MemoryBankSynchronizer; 12 | private status: MemoryBankStatus = { active: false }; 13 | 14 | constructor(private readonly rootPath: string) { 15 | this.synchronizer = new MemoryBankSynchronizer(rootPath); 16 | } 17 | 18 | /** 19 | * Initializes the memory bank and checks its status 20 | */ 21 | async initialize(): Promise<MemoryBankStatus> { 22 | try { 23 | const validationResult = await this.synchronizer.validateMemoryBank(); 24 | 25 | this.status = { 26 | active: validationResult.success, 27 | lastSynchronized: new Date(), 28 | missingFiles: validationResult.errors 29 | }; 30 | 31 | return this.status; 32 | } catch (error) { 33 | this.status = { 34 | active: false, 35 | missingFiles: ['Memory bank initialization failed'] 36 | }; 37 | return this.status; 38 | } 39 | } 40 | 41 | /** 42 | * Gets the current status of the memory bank 43 | */ 44 | getStatus(): MemoryBankStatus { 45 | return this.status; 46 | } 47 | 48 | /** 49 | * Updates the memory bank with task information 50 | */ 51 | async updateTasks(tasks: Task[]): Promise<SynchronizationResult> { 52 | const result = await this.synchronizer.synchronizeTasks(tasks); 53 | 54 | if (result.success) { 55 | this.status.lastSynchronized = new Date(); 56 | this.status.active = true; 57 | } 58 | 59 | return result; 60 | } 61 | 62 | /** 63 | * Records a mode transition in the memory bank 64 | */ 65 | async recordModeTransition(fromMode: string, toMode: string, reason: string): Promise<SynchronizationResult> { 66 | const result = await this.synchronizer.synchronizeModeTransition(fromMode, toMode, reason); 67 | 68 | if (result.success) { 69 | this.status.lastSynchronized = new Date(); 70 | this.status.active = true; 71 | } 72 | 73 | return result; 74 | } 75 | 76 | /** 77 | * Records a decision in the memory bank 78 | */ 79 | async recordDecision(title: string, rationale: string, implementation: string): Promise<SynchronizationResult> { 80 | const result = await this.synchronizer.recordDecision(title, rationale, implementation); 81 | 82 | if (result.success) { 83 | this.status.lastSynchronized = new Date(); 84 | this.status.active = true; 85 | } 86 | 87 | return result; 88 | } 89 | 90 | /** 91 | * Records a system pattern in the memory bank 92 | */ 93 | async recordSystemPattern( 94 | patternName: string, 95 | patternType: 'Coding' | 'Architectural' | 'Testing', 96 | description: string 97 | ): Promise<SynchronizationResult> { 98 | const result = await this.synchronizer.updateSystemPattern(patternName, patternType, description); 99 | 100 | if (result.success) { 101 | this.status.lastSynchronized = new Date(); 102 | this.status.active = true; 103 | } 104 | 105 | return result; 106 | } 107 | 108 | /** 109 | * Creates a complete memory bank structure if it doesn't exist 110 | */ 111 | async createMemoryBank(): Promise<SynchronizationResult> { 112 | try { 113 | // Create basic structure for all required files 114 | const tasks: Task[] = []; 115 | await this.synchronizer.synchronizeTasks(tasks); 116 | 117 | // Record initial decision 118 | await this.synchronizer.recordDecision( 119 | 'Memory Bank Implementation', 120 | 'Need for persistent context across chat sessions\nCross-mode collaboration requirements\nProject history tracking requirements\nStandardized decision and progress tracking', 121 | 'Core configuration files\nMemory Bank structure\nUpdate mechanisms\nCross-mode synchronization' 122 | ); 123 | 124 | // Add basic system patterns 125 | await this.synchronizer.updateSystemPattern( 126 | 'Memory Bank File Structure', 127 | 'Architectural', 128 | 'Core configuration files\nMemory Bank directory with mandatory files\nStandardized file naming and content structure' 129 | ); 130 | 131 | // Validate the memory bank 132 | const validationResult = await this.synchronizer.validateMemoryBank(); 133 | 134 | this.status = { 135 | active: validationResult.success, 136 | lastSynchronized: new Date(), 137 | missingFiles: validationResult.errors 138 | }; 139 | 140 | return { 141 | success: validationResult.success, 142 | updatedFiles: validationResult.updatedFiles, 143 | errors: validationResult.errors 144 | }; 145 | } catch (error) { 146 | const message = error instanceof Error ? error.message : String(error); 147 | return { 148 | success: false, 149 | updatedFiles: [], 150 | errors: [message] 151 | }; 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/roo.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | "use strict"; 3 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 4 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 5 | return new (P || (P = Promise))(function (resolve, reject) { 6 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 7 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 8 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 9 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 10 | }); 11 | }; 12 | var __generator = (this && this.__generator) || function (thisArg, body) { 13 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); 14 | return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 15 | function verb(n) { return function (v) { return step([n, v]); }; } 16 | function step(op) { 17 | if (f) throw new TypeError("Generator is already executing."); 18 | while (g && (g = 0, op[0] && (_ = 0)), _) try { 19 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 20 | if (y = 0, t) op = [op[0] & 2, t.value]; 21 | switch (op[0]) { 22 | case 0: case 1: t = op; break; 23 | case 4: _.label++; return { value: op[1], done: false }; 24 | case 5: _.label++; y = op[1]; op = [0]; continue; 25 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 26 | default: 27 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 28 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 29 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 30 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 31 | if (t[2]) _.ops.pop(); 32 | _.trys.pop(); continue; 33 | } 34 | op = body.call(thisArg, _); 35 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 36 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 37 | } 38 | }; 39 | Object.defineProperty(exports, "__esModule", { value: true }); 40 | var ContextBuilder_1 = require("./scanner/components/ContextBuilder"); 41 | var RegistryUpdater_1 = require("./scanner/components/RegistryUpdater"); 42 | var index_1 = require("./index"); 43 | var rootPath = process.cwd(); 44 | function main() { 45 | return __awaiter(this, void 0, void 0, function () { 46 | var contextBuilder, context, registryUpdater; 47 | return __generator(this, function (_a) { 48 | switch (_a.label) { 49 | case 0: 50 | contextBuilder = new ContextBuilder_1.ContextBuilder(rootPath); 51 | return [4 /*yield*/, contextBuilder.buildContext()]; 52 | case 1: 53 | context = _a.sent(); 54 | registryUpdater = new RegistryUpdater_1.RegistryUpdater(rootPath, { 55 | memoryBankUri: 'memory-bank/taskRegistry.md', 56 | taskRegistryPath: 'memory-bank/taskRegistry.md' 57 | }); 58 | return [4 /*yield*/, registryUpdater.updateRegistry(context)]; 59 | case 2: 60 | _a.sent(); 61 | console.log((0, index_1.getProjectSummaryMarkdown)(context.fileSystem.summary)); 62 | return [2 /*return*/]; 63 | } 64 | }); 65 | }); 66 | } 67 | main().catch(function (error) { 68 | console.error('An error occurred:', error); 69 | process.exit(1); 70 | }); 71 | -------------------------------------------------------------------------------- /src/roo.ts: -------------------------------------------------------------------------------- 1 | import { TaskStatus } from './scanner/components/interfaces/Task'; 2 | import { TaskManager } from './scanner/components/TaskManager'; 3 | import { Captain, setupCaptainCommands } from './cli/captain'; 4 | import { setupMemoryBankCommands } from './cli/memory-bank'; 5 | import * as path from 'path'; 6 | import { Command } from 'commander'; 7 | 8 | interface RooOptions { 9 | rootPath?: string; 10 | taskManager?: TaskManager; 11 | captain?: Captain; 12 | } 13 | 14 | export class Roo { 15 | private readonly taskManager: TaskManager; 16 | private readonly captain: Captain; 17 | private readonly rootPath: string; 18 | 19 | constructor(options: RooOptions = {}) { 20 | this.rootPath = options.rootPath || process.cwd(); 21 | this.taskManager = options.taskManager || new TaskManager(this.rootPath); 22 | this.captain = options.captain || new Captain(); 23 | } 24 | 25 | getRootPath(): string { 26 | return this.rootPath; 27 | } 28 | 29 | async createTask(description: string, targetMode: string, dependencies?: string[]): Promise<string> { 30 | const task = await this.taskManager.createTask({ 31 | description, 32 | assignedMode: targetMode, 33 | title: description.split('\n')[0], 34 | dependencies 35 | }); 36 | 37 | // Update the captain about the new task 38 | this.captain.notifyTaskCreated(task.id, targetMode); 39 | return task.id; 40 | } 41 | 42 | async updateTaskStatus(taskId: string, newStatus: TaskStatus): Promise<void> { 43 | await this.taskManager.updateTaskStatus(taskId, newStatus); 44 | } 45 | 46 | async delegateTask(taskId: string, toMode: string, reason: string): Promise<void> { 47 | await this.taskManager.switchTaskMode(taskId, toMode, reason); 48 | } 49 | 50 | async getTaskReport(): Promise<string> { 51 | return await this.taskManager.generateReport(); 52 | } 53 | 54 | async createMemoryBank(): Promise<boolean> { 55 | return await this.taskManager.createMemoryBank(); 56 | } 57 | 58 | private resolvePath(relativePath: string): string { 59 | return path.resolve(this.rootPath, relativePath); 60 | } 61 | } 62 | 63 | export function setupRooCommands(program: Command, roo: Roo): void { 64 | setupCaptainCommands(program, roo); 65 | setupMemoryBankCommands(program, roo); 66 | } 67 | 68 | export { TaskStatus }; -------------------------------------------------------------------------------- /src/scanner/components/ContextBuilder.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs/promises'; 2 | import * as path from 'path'; 3 | import { FileSystemScanner, ProjectStructure } from './FileSystemScanner'; 4 | import { TaskScanner, TaskScanResults, TaskScanOptions } from './TaskScanner'; 5 | import * as glob from 'glob'; 6 | 7 | export interface ProjectMetadata { 8 | name?: string; 9 | version?: string; 10 | description?: string; 11 | license?: string; 12 | authors?: string[]; 13 | dependencies?: string[]; 14 | devDependencies?: string[]; 15 | } 16 | 17 | export interface ProjectContext { 18 | metadata: ProjectMetadata; 19 | fileSystem: ProjectStructure; 20 | tasks: TaskScanResults; 21 | documentation: string[]; 22 | } 23 | 24 | export interface ContextBuilderOptions { 25 | includeDocumentation?: string[]; 26 | excludeDocumentation?: string[]; 27 | taskScanOptions?: TaskScanOptions; 28 | } 29 | 30 | export class ContextBuilder { 31 | constructor( 32 | private readonly rootPath: string, 33 | private readonly options: ContextBuilderOptions = {} 34 | ) {} 35 | 36 | async buildContext(): Promise<ProjectContext> { 37 | const metadata = await this.extractMetadata(); 38 | const fileSystem = await this.scanFileSystem(); 39 | const tasks = await this.scanTasks(); 40 | const documentation = await this.extractDocumentation(); 41 | 42 | return { 43 | metadata, 44 | fileSystem, 45 | tasks, 46 | documentation 47 | }; 48 | } 49 | 50 | private async extractMetadata(): Promise<ProjectMetadata> { 51 | try { 52 | // Try reading from package.json first 53 | const packagePath = path.join(this.rootPath, 'package.json'); 54 | try { 55 | const packageContent = await fs.readFile(packagePath, 'utf-8'); 56 | const packageJson = JSON.parse(packageContent); 57 | return { 58 | name: packageJson.name, 59 | version: packageJson.version, 60 | description: packageJson.description, 61 | license: packageJson.license, 62 | authors: packageJson.authors, 63 | dependencies: packageJson.dependencies ? Object.keys(packageJson.dependencies) : [], 64 | devDependencies: packageJson.devDependencies ? Object.keys(packageJson.devDependencies) : [] 65 | }; 66 | } catch (e) { 67 | // If no package.json, try productContext.md 68 | const productContextPath = path.join(this.rootPath, 'memory-bank/productContext.md'); 69 | let productContextContent: string; 70 | try { 71 | productContextContent = await fs.readFile(productContextPath, 'utf-8'); 72 | } catch (e) { 73 | console.warn("Could not read productContext.md, using default metadata"); 74 | return {}; 75 | } 76 | 77 | return this.parseMetadataFromMarkdown(productContextContent); 78 | } 79 | } catch (error) { 80 | console.error('Error extracting metadata:', error); 81 | return {}; 82 | } 83 | } 84 | 85 | private parseMetadataFromMarkdown(markdownContent: string): ProjectMetadata { 86 | const metadata: ProjectMetadata = {}; 87 | 88 | // Extract project name 89 | const nameMatch = markdownContent.match(/## Project Goal\s*\n\s*\*([^*]+)/); 90 | if (nameMatch && nameMatch[1]) { 91 | metadata.name = nameMatch[1].trim(); 92 | } 93 | 94 | // Extract project description 95 | const descriptionMatch = markdownContent.match(/## Key Features\s*\n\s*\*([^*]+)/); 96 | if (descriptionMatch && descriptionMatch[1]) { 97 | metadata.description = descriptionMatch[1].trim(); 98 | } 99 | 100 | // Extract version if available 101 | const versionMatch = markdownContent.match(/## Version\s*\n\s*\*([^*]+)/); 102 | if (versionMatch && versionMatch[1]) { 103 | metadata.version = versionMatch[1].trim(); 104 | } 105 | 106 | // Extract license if available 107 | const licenseMatch = markdownContent.match(/## License\s*\n\s*\*([^*]+)/); 108 | if (licenseMatch && licenseMatch[1]) { 109 | metadata.license = licenseMatch[1].trim(); 110 | } 111 | 112 | return metadata; 113 | } 114 | 115 | private async scanFileSystem(): Promise<ProjectStructure> { 116 | const fileScanner = new FileSystemScanner(this.rootPath); 117 | return fileScanner.scanProject(); 118 | } 119 | 120 | private async scanTasks(): Promise<TaskScanResults> { 121 | const taskScanner = new TaskScanner(this.options.taskScanOptions); 122 | return taskScanner.scanDirectory(this.rootPath); 123 | } 124 | 125 | private async extractDocumentation(): Promise<string[]> { 126 | try { 127 | const includePatterns = this.options.includeDocumentation || [ 128 | '**/*.md', 129 | '**/doc/**/*', 130 | '**/docs/**/*', 131 | '**/documentation/**/*', 132 | 'README*' 133 | ]; 134 | const excludePatterns = this.options.excludeDocumentation || [ 135 | 'node_modules/**', 136 | 'dist/**', 137 | 'build/**', 138 | 'coverage/**' 139 | ]; 140 | 141 | const docFiles = new Set<string>(); 142 | 143 | for (const pattern of includePatterns) { 144 | const matches = glob.sync(pattern, { 145 | cwd: this.rootPath, 146 | ignore: excludePatterns, 147 | nodir: true, 148 | absolute: true 149 | }); 150 | matches.forEach(file => docFiles.add(file)); 151 | } 152 | 153 | const documentationContents = await Promise.all( 154 | Array.from(docFiles).map(async file => { 155 | try { 156 | const content = await fs.readFile(file, 'utf-8'); 157 | const relativePath = path.relative(this.rootPath, file); 158 | return `# ${relativePath}\n\n${content}`; 159 | } catch (error) { 160 | console.error(`Error reading documentation file ${file}:`, error); 161 | return ''; 162 | } 163 | }) 164 | ); 165 | 166 | return documentationContents.filter(content => content !== ''); 167 | } catch (error) { 168 | console.error('Error extracting documentation:', error); 169 | return []; 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/scanner/components/FileSystemScanner.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs/promises'; 2 | import { Stats } from 'fs'; 3 | import * as path from 'path'; 4 | import { PathLike } from 'fs'; 5 | 6 | export interface FileStats { 7 | size: number; 8 | lastModified: Date; 9 | type: 'file' | 'directory' | 'symlink'; 10 | } 11 | 12 | export interface FileNode { 13 | path: string; 14 | name: string; 15 | type: 'file' | 'directory' | 'symlink'; 16 | stats: FileStats; 17 | children?: FileNode[]; 18 | } 19 | 20 | export interface ProjectStructure { 21 | root: FileNode; 22 | summary: { 23 | totalFiles: number; 24 | totalDirs: number; 25 | fileTypes: Map<string, number>; 26 | totalSize: number; 27 | }; 28 | } 29 | 30 | export interface ScanOptions { 31 | depth?: number; 32 | excludePatterns?: string[]; 33 | } 34 | 35 | export class FileSystemScanner { 36 | private currentOptions: ScanOptions; 37 | private fileTypeStats: Map<string, number> = new Map(); 38 | private ignorePatterns: string[] = ['node_modules/**/*']; 39 | private summary: ProjectStructure['summary']; 40 | 41 | constructor( 42 | private readonly rootPath: string, 43 | defaultOptions: ScanOptions = {} 44 | ) { 45 | this.currentOptions = defaultOptions; 46 | this.summary = { 47 | totalFiles: 0, 48 | totalDirs: 0, 49 | fileTypes: new Map(), 50 | totalSize: 0 51 | }; 52 | } 53 | 54 | public addIgnorePatterns(patterns: string[]): void { 55 | this.ignorePatterns.push(...patterns); 56 | } 57 | 58 | public getFileTypeStats(): Map<string, number> { 59 | if (!this.fileTypeStats.size) { 60 | throw new Error('No file stats available. Run scanProject first.'); 61 | } 62 | return new Map(this.fileTypeStats); 63 | } 64 | 65 | async scanProject(options?: ScanOptions): Promise<ProjectStructure> { 66 | // Reset counters 67 | this.summary.totalFiles = 0; 68 | this.summary.totalDirs = 0; 69 | this.summary.totalSize = 0; 70 | this.summary.fileTypes.clear(); 71 | this.fileTypeStats.clear(); 72 | 73 | // Merge options 74 | this.currentOptions = { ...this.currentOptions, ...options }; 75 | 76 | try { 77 | const root = await this.scanDirectory(this.rootPath, 0); 78 | this.fileTypeStats = this.summary.fileTypes; 79 | return { root, summary: { ...this.summary } }; 80 | } catch (error) { 81 | const message = error instanceof Error ? error.message : String(error); 82 | throw new Error(`Failed to scan project at ${this.rootPath}: ${message}`); 83 | } 84 | } 85 | 86 | private async scanDirectory(dirPath: string, currentDepth: number): Promise<FileNode> { 87 | const stats = await fs.stat(dirPath); 88 | const name = path.basename(dirPath); 89 | const type = this.getFileType(stats); 90 | 91 | // Early exit if path should be excluded 92 | const relativePath = path.relative(this.rootPath, dirPath); 93 | if (relativePath && this.shouldExclude(relativePath)) { 94 | throw new Error('EXCLUDED_PATH'); 95 | } 96 | 97 | const node: FileNode = { 98 | path: dirPath, 99 | name, 100 | type, 101 | stats: { 102 | size: stats.size, 103 | lastModified: stats.mtime, 104 | type 105 | } 106 | }; 107 | 108 | if (stats.isDirectory()) { 109 | // Don't count excluded directories 110 | if (!this.shouldExclude(relativePath)) { 111 | this.summary.totalDirs++; 112 | } 113 | 114 | // Check depth limit 115 | if (this.currentOptions.depth !== undefined && currentDepth >= this.currentOptions.depth) { 116 | return node; 117 | } 118 | 119 | try { 120 | const entries = await fs.readdir(dirPath, { withFileTypes: true }); 121 | node.children = []; 122 | 123 | // Process child entries 124 | for (const entry of entries) { 125 | const fullPath = path.join(dirPath, entry.name); 126 | const relPath = path.relative(this.rootPath, fullPath); 127 | 128 | if (!this.shouldExclude(relPath)) { 129 | try { 130 | const childNode = await this.scanDirectory(fullPath, currentDepth + 1); 131 | node.children.push(childNode); 132 | } catch (error) { 133 | if (error instanceof Error && error.message === 'EXCLUDED_PATH') { 134 | continue; 135 | } 136 | throw error; 137 | } 138 | } 139 | } 140 | 141 | // Sort children by name 142 | node.children.sort((a, b) => a.name.localeCompare(b.name)); 143 | } catch (error) { 144 | const message = error instanceof Error ? error.message : String(error); 145 | console.error(`Error scanning directory ${dirPath}:`, message); 146 | node.children = []; 147 | } 148 | } else if (stats.isFile()) { 149 | this.summary.totalFiles++; 150 | this.summary.totalSize += stats.size; 151 | 152 | const ext = path.extname(name).toLowerCase(); 153 | const currentCount = this.summary.fileTypes.get(ext) || 0; 154 | this.summary.fileTypes.set(ext, currentCount + 1); 155 | } 156 | 157 | return node; 158 | } 159 | 160 | private getFileType(stats: Stats): FileNode['type'] { 161 | if (stats.isFile()) return 'file'; 162 | if (stats.isDirectory()) return 'directory'; 163 | if (stats.isSymbolicLink()) return 'symlink'; 164 | return 'file'; // Default to file for other types 165 | } 166 | 167 | private shouldExclude(relativePath: string): boolean { 168 | if (!relativePath) return false; 169 | 170 | const patterns = [...(this.currentOptions.excludePatterns || []), ...this.ignorePatterns]; 171 | if (!patterns.length) return false; 172 | 173 | return patterns.some(pattern => { 174 | // Convert glob pattern to regex 175 | const regexPattern = pattern 176 | .replace(/\./g, '\\.') 177 | .replace(/\*\*/g, '__DOUBLE_STAR__') 178 | .replace(/\*/g, '[^/]*') 179 | .replace(/__DOUBLE_STAR__/g, '.*'); 180 | 181 | const regex = new RegExp(`^${regexPattern}$`); 182 | return regex.test(relativePath); 183 | }); 184 | } 185 | } -------------------------------------------------------------------------------- /src/scanner/components/RegistryUpdater.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs/promises'; 2 | import * as path from 'path'; 3 | import { createHash } from 'crypto'; 4 | import { ProjectContext } from './ContextBuilder'; 5 | import { TaskScanResults, DiscoveredTask } from './TaskScanner'; 6 | 7 | export interface RegistryEntry { 8 | taskId: string; 9 | type: string; 10 | description: string; 11 | priority?: string; 12 | assignee?: string; 13 | labels: string[]; 14 | file: string; 15 | line: number; 16 | status: 'active' | 'completed'; 17 | created: string; 18 | updated: string; 19 | } 20 | 21 | export interface RegistryUpdaterOptions { 22 | memoryBankUri: string; 23 | taskRegistryPath: string; 24 | } 25 | 26 | export class RegistryUpdater { 27 | private registryPath: string; 28 | 29 | constructor( 30 | private readonly rootPath: string, 31 | private readonly options: RegistryUpdaterOptions 32 | ) { 33 | this.registryPath = path.resolve(rootPath, options.taskRegistryPath); 34 | } 35 | 36 | async updateRegistry(context: ProjectContext): Promise<void> { 37 | try { 38 | // Convert tasks to registry entries 39 | const entries = await this.convertTasksToEntries(context.tasks); 40 | 41 | // Generate markdown content 42 | const markdown = this.generateRegistryMarkdown(entries, context); 43 | 44 | // Create necessary directories 45 | await fs.mkdir(path.dirname(this.registryPath), { recursive: true }); 46 | 47 | // Write to registry file 48 | await fs.writeFile(this.registryPath, markdown, 'utf-8'); 49 | 50 | // Update memory bank if available 51 | await this.updateMemoryBank(entries, context); 52 | 53 | console.log('Registry updated successfully'); 54 | } catch (error) { 55 | console.error('Error updating registry:', error); 56 | throw error; 57 | } 58 | } 59 | 60 | private async convertTasksToEntries(taskResults: TaskScanResults): Promise<RegistryEntry[]> { 61 | const now = new Date().toISOString(); 62 | return taskResults.tasks.map(task => this.convertTaskToEntry(task, now)); 63 | } 64 | 65 | private convertTaskToEntry(task: DiscoveredTask, timestamp: string): RegistryEntry { 66 | const relativePath = path.relative(this.rootPath, task.location.filePath); 67 | 68 | return { 69 | taskId: this.generateTaskId(task), 70 | type: task.marker.type, 71 | description: task.marker.description, 72 | priority: task.marker.priority, 73 | assignee: task.marker.assignee, 74 | labels: task.marker.labels, 75 | file: relativePath, 76 | line: task.location.lineNumber, 77 | status: 'active', 78 | created: timestamp, 79 | updated: timestamp 80 | }; 81 | } 82 | 83 | private generateTaskId(task: DiscoveredTask): string { 84 | // Generate a consistent hash based on file location and content 85 | const uniqueKey = Buffer.from( 86 | `${task.location.filePath}:${task.location.lineNumber}:${task.location.columnNumber}:${task.marker.type}:${task.marker.description}` 87 | ).toString('base64'); 88 | 89 | // Create MD5 hash and take first 8 characters 90 | const hash = createHash('md5') 91 | .update(uniqueKey) 92 | .digest('hex') 93 | .substring(0, 8); 94 | 95 | return `TASK-${hash}`; 96 | } 97 | 98 | private generateRegistryMarkdown(entries: RegistryEntry[], context: ProjectContext): string { 99 | const lines: string[] = [ 100 | '# Task Registry', 101 | '', 102 | '## Project Context', 103 | '```json', 104 | JSON.stringify({ 105 | name: context.metadata.name, 106 | version: context.metadata.version, 107 | totalFiles: context.fileSystem.summary.totalFiles, 108 | totalTasks: context.tasks.statistics.totalTasks 109 | }, null, 2), 110 | '```', 111 | '' 112 | ]; 113 | 114 | // Add active tasks section only if there are tasks 115 | if (entries.length > 0) { 116 | lines.push( 117 | '## Active Tasks', 118 | '', 119 | '| Task ID | Type | Description | Priority | Assignee | Labels | File | Line |', 120 | '|---------|------|-------------|----------|----------|--------|------|------|' 121 | ); 122 | 123 | const activeTasks = entries.filter(entry => entry.status === 'active'); 124 | for (const task of activeTasks) { 125 | lines.push( 126 | `| ${task.taskId} | ${task.type} | ${task.description} | ${task.priority || '-'} | ${task.assignee || '-'} | ${task.labels.join(', ') || '-'} | ${task.file} | ${task.line} |` 127 | ); 128 | } 129 | 130 | lines.push(''); 131 | } 132 | 133 | // Add empty stats section if no tasks 134 | const stats = this.generateStatsSections(context); 135 | lines.push(...stats); 136 | 137 | return lines.join('\n'); 138 | } 139 | 140 | private generateStatsSections(context: ProjectContext): string[] { 141 | const lines: string[] = ['## Task Statistics', '']; 142 | 143 | if (context.tasks.statistics.totalTasks > 0) { 144 | lines.push( 145 | '### By Type', 146 | '```json', 147 | JSON.stringify(Object.fromEntries(context.tasks.statistics.byType), null, 2), 148 | '```', 149 | '', 150 | '### By Priority', 151 | '```json', 152 | JSON.stringify(Object.fromEntries(context.tasks.statistics.byPriority), null, 2), 153 | '```', 154 | '', 155 | '### By Label', 156 | '```json', 157 | JSON.stringify(Object.fromEntries(context.tasks.statistics.byLabel), null, 2), 158 | '```' 159 | ); 160 | } else { 161 | lines.push( 162 | '### By Type', 163 | '```json', 164 | '{}', 165 | '```', 166 | '', 167 | '### By Priority', 168 | '```json', 169 | '{}', 170 | '```', 171 | '', 172 | '### By Label', 173 | '```json', 174 | '{}', 175 | '```' 176 | ); 177 | } 178 | 179 | return lines; 180 | } 181 | 182 | private async updateMemoryBank(entries: RegistryEntry[], context: ProjectContext): Promise<void> { 183 | // Log memory bank update for now (actual implementation would use a Memory Bank interface) 184 | const updateData = { 185 | taskCount: entries.length, 186 | contextSummary: { 187 | name: context.metadata.name, 188 | version: context.metadata.version, 189 | totalFiles: context.fileSystem.summary.totalFiles, 190 | totalTasks: context.tasks.statistics.totalTasks 191 | } 192 | }; 193 | console.log(`Would update memory bank at ${this.options.memoryBankUri} with:`, updateData); 194 | } 195 | } -------------------------------------------------------------------------------- /src/scanner/components/__tests__/TaskManager.test.ts: -------------------------------------------------------------------------------- 1 | import { TaskManager } from '../TaskManager'; 2 | import { TaskStatus } from '../interfaces/Task'; 3 | 4 | describe('TaskManager', () => { 5 | let taskManager: TaskManager; 6 | 7 | beforeEach(() => { 8 | taskManager = new TaskManager(); 9 | }); 10 | 11 | describe('createTask', () => { 12 | it('should create a task with required fields', async () => { 13 | const description = 'Test task'; 14 | const mode = 'test'; 15 | 16 | const task = await taskManager.createTask({ 17 | description, 18 | assignedMode: mode, 19 | title: 'Test Task', 20 | priority: 1, 21 | assignees: ['@user1'], 22 | labels: ['test'] 23 | }); 24 | 25 | expect(task).toBeDefined(); 26 | expect(task.id).toBeTruthy(); 27 | expect(task.description).toBe(description); 28 | expect(task.assignedMode).toBe(mode); 29 | expect(task.status).toBe(TaskStatus.PENDING); 30 | expect(task.created).toBeInstanceOf(Date); 31 | expect(task.updated).toBeInstanceOf(Date); 32 | }); 33 | 34 | it('should create task with minimal fields', async () => { 35 | const task = await taskManager.createTask({ 36 | description: 'Test task', 37 | assignedMode: 'test' 38 | }); 39 | 40 | expect(task).toBeDefined(); 41 | expect(task.id).toBeTruthy(); 42 | expect(task.status).toBe(TaskStatus.PENDING); 43 | }); 44 | }); 45 | 46 | describe('updateTaskStatus', () => { 47 | it('should update task status and add transition', async () => { 48 | const task = await taskManager.createTask({ 49 | description: 'Test task', 50 | assignedMode: 'test' 51 | }); 52 | 53 | await taskManager.updateTaskStatus(task.id, TaskStatus.IN_PROGRESS); 54 | const updatedTask = taskManager.getTask(task.id); 55 | 56 | expect(updatedTask).toBeDefined(); 57 | expect(updatedTask?.status).toBe(TaskStatus.IN_PROGRESS); 58 | expect(updatedTask?.transitions).toHaveLength(1); 59 | expect(updatedTask?.transitions?.[0].from).toBe(TaskStatus.PENDING); 60 | expect(updatedTask?.transitions?.[0].to).toBe(TaskStatus.IN_PROGRESS); 61 | }); 62 | 63 | it('should throw error for non-existent task', async () => { 64 | await expect(taskManager.updateTaskStatus('non-existent', TaskStatus.IN_PROGRESS)) 65 | .rejects.toThrow(); 66 | }); 67 | }); 68 | 69 | describe('switchTaskMode', () => { 70 | it('should switch task mode and add transition', async () => { 71 | const task = await taskManager.createTask({ 72 | description: 'Test task', 73 | assignedMode: 'test' 74 | }); 75 | await taskManager.switchTaskMode(task.id, 'code', 'Testing mode transition'); 76 | 77 | const updatedTask = taskManager.getTask(task.id); 78 | expect(updatedTask?.assignedMode).toBe('code'); 79 | expect(updatedTask?.modeChain).toContain('code'); 80 | expect(updatedTask?.transitions).toHaveLength(1); 81 | expect(updatedTask?.transitions?.[0].fromMode).toBe('test'); 82 | expect(updatedTask?.transitions?.[0].toMode).toBe('code'); 83 | }); 84 | 85 | it('should throw error for non-existent task', async () => { 86 | await expect(taskManager.switchTaskMode('non-existent', 'code', 'reason')) 87 | .rejects.toThrow(); 88 | }); 89 | }); 90 | 91 | describe('updateTask', () => { 92 | it('should update task fields', async () => { 93 | const task = await taskManager.createTask({ 94 | description: 'Test task', 95 | assignedMode: 'test' 96 | }); 97 | 98 | const updates = { 99 | description: 'Updated description', 100 | labels: ['new-label'], 101 | notes: 'test note' 102 | }; 103 | 104 | const updatedTask = await taskManager.updateTask(task.id, updates); 105 | 106 | expect(updatedTask.description).toBe(updates.description); 107 | expect(updatedTask.labels).toEqual(updates.labels); 108 | expect(updatedTask.notes).toBe(updates.notes); 109 | expect(updatedTask.updated).toBeInstanceOf(Date); 110 | }); 111 | 112 | it('should not allow modification of id or created fields', async () => { 113 | const task = await taskManager.createTask({ 114 | description: 'Test task', 115 | assignedMode: 'test' 116 | }); 117 | 118 | const originalId = task.id; 119 | const originalCreated = task.created; 120 | 121 | await taskManager.updateTask(task.id, { 122 | id: 'new-id', 123 | created: new Date(2020, 1, 1) 124 | }); 125 | 126 | const updatedTask = taskManager.getTask(task.id); 127 | expect(updatedTask?.id).toBe(originalId); 128 | expect(updatedTask?.created).toBe(originalCreated); 129 | }); 130 | }); 131 | 132 | describe('generateReport', () => { 133 | it('should generate report with tasks and transitions', async () => { 134 | const task1 = await taskManager.createTask({ 135 | description: 'Active task', 136 | assignedMode: 'code' 137 | }); 138 | 139 | const task2 = await taskManager.createTask({ 140 | description: 'Completed task', 141 | assignedMode: 'test' 142 | }); 143 | 144 | await taskManager.updateTaskStatus(task2.id, TaskStatus.COMPLETED); 145 | await taskManager.switchTaskMode(task1.id, 'test', 'Testing'); 146 | 147 | const report = await taskManager.generateReport(); 148 | 149 | expect(report).toContain('Active Tasks'); 150 | expect(report).toContain('Completed Tasks'); 151 | expect(report).toContain('Mode Transitions'); 152 | expect(report).toContain(task1.id); 153 | expect(report).toContain(task2.id); 154 | expect(report).toContain('code → test'); 155 | }); 156 | }); 157 | 158 | describe('Memory Bank integration', () => { 159 | it('should get memory bank manager', () => { 160 | const taskManagerWithPath = new TaskManager('/test/path'); 161 | const memoryBankManager = taskManagerWithPath.getMemoryBankManager(); 162 | 163 | expect(memoryBankManager).toBeDefined(); 164 | }); 165 | 166 | it('should create memory bank', async () => { 167 | // Mock implementation to avoid actual file system operations 168 | const taskManagerWithPath = new TaskManager('/test/path'); 169 | const mockMemoryBankManager = taskManagerWithPath.getMemoryBankManager(); 170 | 171 | if (mockMemoryBankManager) { 172 | // Mock the createMemoryBank method 173 | const originalMethod = mockMemoryBankManager.createMemoryBank; 174 | mockMemoryBankManager.createMemoryBank = jest.fn().mockResolvedValue({ success: true, updatedFiles: [] }); 175 | 176 | const result = await taskManagerWithPath.createMemoryBank(); 177 | expect(result).toBe(true); 178 | 179 | // Restore original method 180 | mockMemoryBankManager.createMemoryBank = originalMethod; 181 | } 182 | }); 183 | }); 184 | }); -------------------------------------------------------------------------------- /src/scanner/components/interfaces/Task.ts: -------------------------------------------------------------------------------- 1 | // Task Discovery Interfaces 2 | export interface TaskLocation { 3 | file: string; 4 | line: number; 5 | column?: number; 6 | } 7 | 8 | export interface DiscoveredTask { 9 | type: string; 10 | description: string; 11 | priority?: number; 12 | assignees?: string[]; 13 | labels?: string[]; 14 | location: TaskLocation; 15 | lineContent: string; 16 | metadata?: Record<string, unknown>; 17 | } 18 | 19 | export interface TaskScanOptions { 20 | include?: string[]; 21 | exclude?: string[]; 22 | customMarkers?: string[]; 23 | } 24 | 25 | export interface TaskScanResult { 26 | tasks: DiscoveredTask[]; 27 | statistics: { 28 | totalTasks: number; 29 | byType: Map<string, number>; 30 | byPriority?: Map<number, number>; 31 | byLabel?: Map<string, number>; 32 | }; 33 | } 34 | 35 | export interface TaskScannerOptions { 36 | markers?: string[]; 37 | assigneePrefix?: string; 38 | labelPrefix?: string; 39 | priorityPattern?: RegExp; 40 | } 41 | 42 | // Task Management Interfaces 43 | export enum TaskStatus { 44 | PENDING = 'pending', 45 | IN_PROGRESS = 'in_progress', 46 | BLOCKED = 'blocked', 47 | COMPLETED = 'completed', 48 | FAILED = 'failed' 49 | } 50 | 51 | export interface TaskTransition { 52 | from: TaskStatus; 53 | to: TaskStatus; 54 | by?: string; 55 | at: Date; 56 | comment?: string; 57 | fromMode?: string; 58 | toMode?: string; 59 | reason?: string; 60 | timestamp?: Date; 61 | } 62 | 63 | export interface Task { 64 | id: string; 65 | title: string; 66 | description: string; 67 | status: TaskStatus; 68 | priority: number; 69 | assignees: string[]; 70 | labels: string[]; 71 | created: Date; 72 | updated?: Date; 73 | transitions?: TaskTransition[]; 74 | metadata?: Record<string, unknown>; 75 | location?: TaskLocation; 76 | assignedMode?: string; 77 | modeChain?: string[]; 78 | notes?: string; 79 | dependencies?: string[]; 80 | } -------------------------------------------------------------------------------- /src/scanner/tests/ContextBuilder.test.ts: -------------------------------------------------------------------------------- 1 | import { ContextBuilder } from '../components/ContextBuilder'; 2 | import * as fs from 'fs/promises'; 3 | import * as path from 'path'; 4 | 5 | const TEST_DIR = path.join(__dirname, '../../..', 'test-context'); 6 | 7 | describe('ContextBuilder', () => { 8 | beforeAll(async () => { 9 | // Create test project structure 10 | await fs.mkdir(TEST_DIR, { recursive: true }); 11 | await fs.writeFile( 12 | path.join(TEST_DIR, 'package.json'), 13 | `{ 14 | "name": "test-project", 15 | "version": "1.0.0", 16 | "description": "Test project for context builder", 17 | "license": "MIT", 18 | "authors": ["Test Author"], 19 | "dependencies": {"dep1": "1.0.0"}, 20 | "devDependencies": {"devDep1": "2.0.0"} 21 | }` 22 | ); 23 | await fs.writeFile(path.join(TEST_DIR, 'test.txt'), 'Test file content'); 24 | }); 25 | 26 | afterAll(async () => { 27 | await fs.rm(TEST_DIR, { recursive: true, force: true }); 28 | }); 29 | 30 | it('should build project context correctly', async () => { 31 | const contextBuilder = new ContextBuilder(TEST_DIR); 32 | const context = await contextBuilder.buildContext(); 33 | 34 | // Check metadata 35 | expect(context.metadata.name).toBe('test-project'); 36 | expect(context.metadata.version).toBe('1.0.0'); 37 | expect(context.metadata.description).toBe('Test project for context builder'); 38 | expect(context.metadata.license).toBe('MIT'); 39 | expect(context.metadata.authors).toEqual(['Test Author']); 40 | expect(context.metadata.dependencies).toEqual(['dep1']); 41 | expect(context.metadata.devDependencies).toEqual(['devDep1']); 42 | 43 | // Check file system 44 | expect(context.fileSystem.root.name).toBe('test-context'); 45 | expect(context.fileSystem.summary.totalFiles).toBeGreaterThanOrEqual(1); 46 | 47 | // Check tasks 48 | expect(context.tasks.statistics.totalTasks).toBe(0); 49 | 50 | // Check documentation 51 | expect(context.documentation).toEqual([]); 52 | }); 53 | }); -------------------------------------------------------------------------------- /src/scanner/tests/RegistryUpdater.test.ts: -------------------------------------------------------------------------------- 1 | import { RegistryUpdater, RegistryUpdaterOptions } from '../components/RegistryUpdater'; 2 | import { ProjectContext } from '../components/ContextBuilder'; 3 | 4 | describe('RegistryUpdater', () => { 5 | it('should call updateRegistry', async () => { 6 | const rootPath = './'; 7 | const options: RegistryUpdaterOptions = { 8 | memoryBankUri: 'test', 9 | taskRegistryPath: 'test' 10 | }; 11 | const registryUpdater = new RegistryUpdater(rootPath, options); 12 | 13 | const context: ProjectContext = { 14 | metadata: {}, 15 | fileSystem: {root: {path: 'test', name: 'test', type: 'directory', stats: {size: 0, lastModified: new Date(), type: 'directory'}}, summary: {totalFiles: 0, totalDirs: 0, fileTypes: new Map(), totalSize: 0}}, 16 | tasks: {tasks: [], statistics: {totalTasks: 0, byType: new Map(), byPriority: new Map(), byLabel: new Map()}}, 17 | documentation: [] 18 | }; 19 | 20 | const consoleLogSpy = jest.spyOn(console, 'log'); 21 | 22 | await registryUpdater.updateRegistry(context); 23 | 24 | expect(consoleLogSpy).toHaveBeenCalledWith('Updating registry with context:', context); 25 | }); 26 | }); -------------------------------------------------------------------------------- /src/scanner/tests/TaskScanner.test.ts: -------------------------------------------------------------------------------- 1 | import { TaskScanner } from '../components/TaskScanner'; 2 | import * as fs from 'fs/promises'; 3 | import * as path from 'path'; 4 | 5 | jest.mock('fs/promises'); 6 | jest.mock('path'); 7 | 8 | const mockedFs = fs as jest.Mocked<typeof fs>; 9 | const mockedPath = path as jest.Mocked<typeof path>; 10 | 11 | const TEST_DIR = '/test/project'; 12 | 13 | describe('TaskScanner', () => { 14 | let mockFiles: Map<string, string>; 15 | 16 | beforeEach(() => { 17 | jest.clearAllMocks(); 18 | 19 | mockFiles = new Map([ 20 | [`${TEST_DIR}/src/test.ts`, ` 21 | // TODO: Implement error handling 22 | function test() { 23 | // FIXME: This is broken 24 | console.log('test'); 25 | // NOTE: Add validation 26 | } 27 | `] 28 | ]); 29 | 30 | mockedPath.join.mockImplementation((...paths) => paths.join('/')); 31 | mockedPath.relative.mockImplementation((from, to) => to.replace(from + '/', '')); 32 | mockedPath.basename.mockImplementation(filePath => filePath.split('/').pop() || ''); 33 | 34 | mockedFs.readFile.mockImplementation(async (filePath) => { 35 | const filePathString = filePath.toString(); 36 | console.log('readFile mock:', filePathString); 37 | const content = mockFiles.get(filePathString); 38 | if (!content) throw new Error(`File not found: ${filePathString}`); 39 | console.log('readFile content:', content); 40 | return Buffer.from(content); 41 | }); 42 | }); 43 | 44 | describe('scanDirectory', () => { 45 | it('should scan files for tasks', async () => { 46 | const scanner = new TaskScanner(); 47 | const result = await scanner.scanDirectory(TEST_DIR); 48 | 49 | expect(result.tasks).toHaveLength(3); 50 | expect(result.statistics.totalTasks).toBe(3); 51 | }); 52 | 53 | it('should categorize tasks by type', async () => { 54 | const scanner = new TaskScanner(); 55 | const result = await scanner.scanDirectory(TEST_DIR); 56 | 57 | expect(result.statistics.byType.get('TODO')).toBe(1); 58 | expect(result.statistics.byType.get('FIXME')).toBe(1); 59 | expect(result.statistics.byType.get('NOTE')).toBe(1); 60 | }); 61 | 62 | it('should handle file read errors', async () => { 63 | mockedFs.readFile.mockRejectedValueOnce(new Error('Read error')); 64 | const scanner = new TaskScanner(); 65 | const result = await scanner.scanDirectory(TEST_DIR); 66 | 67 | expect(result.tasks).toHaveLength(0); 68 | }); 69 | 70 | it('should handle invalid marker formats', async () => { 71 | mockFiles.set(`${TEST_DIR}/example.ts`, ` 72 | // INVALID FORMAT 73 | // TODO without colon 74 | // NOTE:without space 75 | `); 76 | 77 | const scanner = new TaskScanner(); 78 | const result = await scanner.scanDirectory(TEST_DIR); 79 | 80 | expect(result.tasks).toHaveLength(0); 81 | }); 82 | 83 | it('should parse complex marker formats', async () => { 84 | mockFiles.set(`${TEST_DIR}/example.ts`, ` 85 | // TODO(@user1): High priority task [p1] 86 | // FIXME(@user2, @user3): Needs review #bug 87 | // NOTE(@team): Consider refactoring [tech-debt] 88 | `); 89 | 90 | const scanner = new TaskScanner(); 91 | const result = await scanner.scanDirectory(TEST_DIR); 92 | 93 | expect(result.tasks).toHaveLength(3); 94 | expect(result.tasks[0].marker.assignee).toBe('@user1'); 95 | expect(result.tasks[0].marker.labels).toContain('p1'); 96 | }); 97 | 98 | it('should aggregate multi-line task descriptions', async () => { 99 | mockFiles.set(`${TEST_DIR}/example.ts`, ` 100 | // TODO: This is a multi-line task 101 | // that continues here 102 | // and ends here 103 | `); 104 | 105 | const scanner = new TaskScanner(); 106 | const result = await scanner.scanDirectory(TEST_DIR); 107 | 108 | expect(result.tasks).toHaveLength(1); 109 | expect(result.tasks[0].marker.description).toContain('continues here'); 110 | expect(result.tasks[0].marker.description).toContain('ends here'); 111 | }); 112 | 113 | it('should track task locations accurately', async () => { 114 | const scanner = new TaskScanner(); 115 | const result = await scanner.scanDirectory(TEST_DIR); 116 | 117 | expect(result.tasks[0].location.filePath).toBe('src/test.ts'); 118 | expect(result.tasks[0].location.lineNumber).toBeDefined(); 119 | }); 120 | }); 121 | }); -------------------------------------------------------------------------------- /test: -------------------------------------------------------------------------------- 1 | # Task Registry 2 | 3 | ## Project Context 4 | ```json 5 | { 6 | "totalFiles": 0, 7 | "totalTasks": 0 8 | } 9 | ``` 10 | 11 | ## Task Statistics 12 | 13 | ### By Type 14 | ```json 15 | {} 16 | ``` 17 | 18 | ### By Priority 19 | ```json 20 | {} 21 | ``` 22 | 23 | ### By Label 24 | ```json 25 | {} 26 | ``` -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": ["ES2020", "dom"], 6 | "declaration": true, 7 | "outDir": "./dist", 8 | "rootDir": "./src", 9 | "strict": true, 10 | "esModuleInterop": true, 11 | "allowSyntheticDefaultImports": true, 12 | "skipLibCheck": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "types": ["node", "jest"], 17 | "downlevelIteration": true 18 | }, 19 | "include": ["src/**/*"], 20 | "exclude": ["node_modules", "**/*.test.ts"] 21 | } --------------------------------------------------------------------------------