├── .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 |
58 |
59 | Filter:
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | File |
70 | |
71 | Statements |
72 | |
73 | Branches |
74 | |
75 | Functions |
76 | |
77 | Lines |
78 | |
79 |
80 |
81 |
82 | Task.ts |
83 |
84 |
85 | |
86 | 100% |
87 | 6/6 |
88 | 100% |
89 | 2/2 |
90 | 100% |
91 | 1/1 |
92 | 100% |
93 | 6/6 |
94 |
95 |
96 |
97 |
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 |
58 |
59 | Filter:
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | File |
70 | |
71 | Statements |
72 | |
73 | Branches |
74 | |
75 | Functions |
76 | |
77 | Lines |
78 | |
79 |
80 |
81 |
82 | components |
83 |
84 |
85 | |
86 | 94.1% |
87 | 319/339 |
88 | 80.15% |
89 | 105/131 |
90 | 100% |
91 | 52/52 |
92 | 94.49% |
93 | 309/327 |
94 |
95 |
96 |
97 | components/interfaces |
98 |
99 |
100 | |
101 | 100% |
102 | 6/6 |
103 | 100% |
104 | 2/2 |
105 | 100% |
106 | 1/1 |
107 | 100% |
108 | 6/6 |
109 |
110 |
111 |
112 |
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('', 'Decision rationale')
63 | .argument('', '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('', 'Pattern name')
81 | .argument('', 'Pattern type (Coding, Architectural, Testing)')
82 | .argument('', '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('', 'Source mode')
106 | .argument('', 'Target mode')
107 | .argument('', '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":";;AAKA,0DA+HC;AAlID,wEAAqE;AAGrE,SAAgB,uBAAuB,CAAC,OAAgB,EAAE,GAAQ;IAChE,MAAM,iBAAiB,GAAG,OAAO;SAC9B,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,iCAAiC,CAAC,CAAC;IAElD,iBAAiB;SACd,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,0BAA0B,CAAC;SACvC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,iBAAiB,GAAG,IAAI,qCAAiB,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,UAAU,EAAE,CAAC;QAEpD,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAEzD,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC/E,CAAC;QAED,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,iBAAiB;SACd,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,iBAAiB,GAAG,IAAI,qCAAiB,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;QAE1D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAC9C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,CAAC,KAAK,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,iBAAiB;SACd,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,gCAAgC,CAAC;SAC7C,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,iBAAiB,GAAG,IAAI,qCAAiB,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC,kBAAkB,EAAE,CAAC;QAEzE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;YACjD,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;YAC/C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,CAAC,KAAK,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,iBAAiB;SACd,OAAO,CAAC,iBAAiB,CAAC;SAC1B,WAAW,CAAC,sCAAsC,CAAC;SACnD,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;SACrC,QAAQ,CAAC,aAAa,EAAE,oBAAoB,CAAC;SAC7C,QAAQ,CAAC,kBAAkB,EAAE,wBAAwB,CAAC;SACtD,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,SAAiB,EAAE,cAAsB,EAAE,EAAE;QACzE,MAAM,iBAAiB,GAAG,IAAI,qCAAiB,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;QAExF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC3C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,CAAC,KAAK,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,iBAAiB;SACd,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,4CAA4C,CAAC;SACzD,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;SAClC,QAAQ,CAAC,QAAQ,EAAE,+CAA+C,CAAC;SACnE,QAAQ,CAAC,eAAe,EAAE,qBAAqB,CAAC;SAChD,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,IAAY,EAAE,WAAmB,EAAE,EAAE;QAChE,MAAM,iBAAiB,GAAG,IAAI,qCAAiB,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QAEnE,wBAAwB;QACxB,MAAM,WAAW,GAAG,IAA8C,CAAC;QACnE,IAAI,CAAC,CAAC,QAAQ,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAClE,OAAO,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;YACtF,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;QAE3F,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC1C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,CAAC,KAAK,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,iBAAiB;SACd,OAAO,CAAC,wBAAwB,CAAC;SACjC,WAAW,CAAC,6CAA6C,CAAC;SAC1D,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;SACtC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC;SACpC,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,MAAc,EAAE,MAAc,EAAE,EAAE;QACjE,MAAM,iBAAiB,GAAG,IAAI,qCAAiB,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAEtF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAClD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,CAAC,KAAK,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
--------------------------------------------------------------------------------
/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;
17 | updateTaskStatus(taskId: string, newStatus: TaskStatus): Promise;
18 | delegateTask(taskId: string, toMode: string, reason: string): Promise;
19 | getTaskReport(): Promise;
20 | createMemoryBank(): Promise;
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;
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;
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;
35 | scanProject(options?: ScanOptions): Promise;
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;
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;
17 | getTask(id: string): Task | undefined;
18 | getAllTasks(): Task[];
19 | updateTask(id: string, updates: Partial): Promise;
20 | updateTaskStatus(id: string, newStatus: TaskStatus): Promise;
21 | switchTaskMode(id: string, toMode: string, reason: string): Promise;
22 | generateReport(): Promise;
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;
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;
22 | byPriority: Map;
23 | byLabel: Map;
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;
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;
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;
26 | byPriority?: Map;
27 | byLabel?: Map;
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;
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: ['/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=] [--include-history] [--output-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;
32 | byPriority: Map;
33 | byLabel: Map;
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 {
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 {
111 | const tasks: DiscoveredTask[] = [];
112 | const statistics = {
113 | totalTasks: 0,
114 | byType: new Map(),
115 | byPriority: new Map(),
116 | byLabel: new Map()
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();
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('', 'Task description')
32 | .argument('', 'Target mode (architect, code, test, debug, ask)')
33 | .option('-d, --depends ', '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('', 'Task ID')
44 | .argument('', 'Target mode (architect, code, test, debug, ask)')
45 | .argument('', '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('', 'Task ID')
55 | .argument('', '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('', 'Target mode (architect, code, test, debug, ask)')
69 | .argument('', '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('', 'Decision title')
70 | .argument('', 'Decision rationale')
71 | .argument('', '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('', 'Pattern name')
90 | .argument('', 'Pattern type (Coding, Architectural, Testing)')
91 | .argument('', '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('', 'Source mode')
118 | .argument('', 'Target mode')
119 | .argument('', '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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
43 | await this.taskManager.updateTaskStatus(taskId, newStatus);
44 | }
45 |
46 | async delegateTask(taskId: string, toMode: string, reason: string): Promise {
47 | await this.taskManager.switchTaskMode(taskId, toMode, reason);
48 | }
49 |
50 | async getTaskReport(): Promise {
51 | return await this.taskManager.generateReport();
52 | }
53 |
54 | async createMemoryBank(): Promise {
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 {
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 {
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 {
116 | const fileScanner = new FileSystemScanner(this.rootPath);
117 | return fileScanner.scanProject();
118 | }
119 |
120 | private async scanTasks(): Promise {
121 | const taskScanner = new TaskScanner(this.options.taskScanOptions);
122 | return taskScanner.scanDirectory(this.rootPath);
123 | }
124 |
125 | private async extractDocumentation(): Promise {
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();
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;
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 = 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 {
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 {
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 {
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 {
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 {
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 {
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;
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;
30 | byPriority?: Map;
31 | byLabel?: Map;
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;
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;
9 | const mockedPath = path as jest.Mocked;
10 |
11 | const TEST_DIR = '/test/project';
12 |
13 | describe('TaskScanner', () => {
14 | let mockFiles: Map;
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 | }
--------------------------------------------------------------------------------