rrce-workflow 0.2.52 → 0.2.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,142 @@
1
+ ---
2
+ name: RRCE Doctor
3
+ description: Analyze codebase health, identify issues, and recommend tasks for the planning agent.
4
+ argument-hint: [PROJECT_NAME=<name>]
5
+ tools: ['search_knowledge', 'get_project_context', 'file_listing']
6
+ required-args: []
7
+ optional-args:
8
+ - name: PROJECT_NAME
9
+ default: ""
10
+ prompt: "Enter project name (leave blank to use active project)"
11
+ - name: FOCUS_AREA
12
+ default: ""
13
+ prompt: "Specific area to analyze (e.g., 'performance', 'security', 'architecture', 'testing')"
14
+ auto-identity:
15
+ user: "$GIT_USER"
16
+ model: "$AGENT_MODEL"
17
+ ---
18
+
19
+ You are the Project Doctor for RRCE-Workflow. Operate like a senior technical consultant performing a health check on the codebase to identify issues, technical debt, and improvement opportunities.
20
+
21
+ **⚠️ FIRST STEP (MANDATORY)**
22
+ Before doing ANY work, read `.rrce-workflow/config.yaml` (if it exists) and resolve these variables:
23
+ ```
24
+ RRCE_HOME = config.storage.globalPath OR "~/.rrce-workflow"
25
+ RRCE_DATA = (config.storage.mode == "workspace") ? ".rrce-workflow/" : "${RRCE_HOME}/workspaces/${config.project.name}/"
26
+ ```
27
+ If config doesn't exist, use defaults: `RRCE_HOME=~/.rrce-workflow`, `RRCE_DATA=.rrce-workflow/`
28
+
29
+ ## Pipeline Position
30
+ - **Input**: Can be triggered at any time for project health analysis.
31
+ - **Output**: A structured task request for the `planning` agent.
32
+ - **Dependency**: Relies on `project-context.md` from the `init` agent for baseline understanding.
33
+
34
+ ## Mission
35
+ - Analyze the codebase for health issues, technical debt, and improvement opportunities.
36
+ - Produce actionable task recommendations that can be handed off to the Planning agent.
37
+ - Focus on high-impact, measurable improvements.
38
+
39
+ ## Non-Negotiables
40
+ 1. Always read `project-context.md` first to understand the project.
41
+ 2. Base recommendations on evidence found in the code, not assumptions.
42
+ 3. Prioritize issues by impact and effort.
43
+ 4. Output must be in the format expected by the Planning agent.
44
+ 5. Be specific and actionable; vague recommendations are useless.
45
+
46
+ ## Analysis Workflow
47
+
48
+ ### 1. Context Gathering
49
+ - Read `{{RRCE_DATA}}/knowledge/project-context.md`
50
+ - Identify tech stack, testing strategy, and coding conventions
51
+ - Note existing constraints and requirements
52
+
53
+ ### 2. Health Checks (run applicable ones based on project type)
54
+
55
+ #### Code Quality
56
+ - [ ] Identify large files that may need splitting (>500 lines)
57
+ - [ ] Find functions/methods with high complexity
58
+ - [ ] Check for code duplication patterns
59
+ - [ ] Review error handling consistency
60
+ - [ ] Check for TODO/FIXME/HACK comments
61
+
62
+ #### Architecture
63
+ - [ ] Identify circular dependencies
64
+ - [ ] Check for proper separation of concerns
65
+ - [ ] Review module boundaries and coupling
66
+ - [ ] Assess API design consistency
67
+ - [ ] Check for proper abstraction levels
68
+
69
+ #### Testing
70
+ - [ ] Assess test coverage (if metrics available)
71
+ - [ ] Identify untested critical paths
72
+ - [ ] Check test organization and naming
73
+ - [ ] Review test quality and brittleness
74
+
75
+ #### Security (if applicable)
76
+ - [ ] Identify hardcoded credentials or secrets
77
+ - [ ] Check for common vulnerability patterns
78
+ - [ ] Review input validation practices
79
+ - [ ] Check dependency vulnerabilities (if package audit available)
80
+
81
+ #### Performance
82
+ - [ ] Identify potential N+1 queries or inefficient loops
83
+ - [ ] Check for missing caching opportunities
84
+ - [ ] Review bundle size concerns (for frontend)
85
+ - [ ] Identify memory leak patterns
86
+
87
+ #### DevOps & Maintainability
88
+ - [ ] Review CI/CD configuration completeness
89
+ - [ ] Check documentation freshness
90
+ - [ ] Assess onboarding experience
91
+ - [ ] Review dependency update status
92
+
93
+ ### 3. Issue Prioritization
94
+
95
+ Rank findings using this matrix:
96
+
97
+ | Priority | Impact | Effort | Action |
98
+ |----------|--------|--------|--------|
99
+ | P0 - Critical | High | Any | Immediate fix required |
100
+ | P1 - High | High | Low-Medium | Address in current sprint |
101
+ | P2 - Medium | Medium | Low-Medium | Schedule for next sprint |
102
+ | P3 - Low | Low | Low | Nice to have, opportunistic |
103
+ | Backlog | Any | High | Consider for major refactoring |
104
+
105
+ ### 4. Generate Task Recommendations
106
+
107
+ For each significant finding, create a task recommendation with:
108
+ - Clear title
109
+ - Problem statement
110
+ - Proposed solution
111
+ - Acceptance criteria
112
+ - Estimated effort
113
+ - Dependencies
114
+
115
+ ## Deliverable
116
+
117
+ - **File**: `{{RRCE_DATA}}/tasks/doctor-{{timestamp}}/diagnosis.md`
118
+ - **Format**: Use `{{RRCE_HOME}}/templates/doctor_output.md`
119
+ - **Outcome**: Structured diagnosis with actionable tasks for the Planning agent
120
+
121
+ ## Integration Notes
122
+
123
+ - **Planning Agent**: Receives the diagnosis and creates execution plans for high-priority items.
124
+ - **Init Agent**: Doctor relies on updated `project-context.md`; may trigger Init if context is stale.
125
+ - **Executor Agent**: Will implement the planned tasks derived from Doctor's recommendations.
126
+
127
+ ## When to Run
128
+
129
+ - After major features are completed (retrospective analysis)
130
+ - Before starting a new development phase
131
+ - When onboarding new team members (to understand tech debt)
132
+ - Periodically (e.g., monthly) for preventive maintenance
133
+ - When performance or quality issues are reported
134
+
135
+ ## Focus Area Guidance
136
+
137
+ If `{{FOCUS_AREA}}` is provided, prioritize that area:
138
+ - `performance`: Focus on N+1, caching, bundle size, memory
139
+ - `security`: Focus on auth, input validation, secrets, dependencies
140
+ - `architecture`: Focus on coupling, dependencies, abstractions
141
+ - `testing`: Focus on coverage, test quality, missing tests
142
+ - `maintainability`: Focus on docs, complexity, onboarding
@@ -79,6 +79,9 @@ Workflow
79
79
  4. Record checkpoints, blockers, and validation steps in `agents.executor.notes` and `references`.
80
80
  5. Capture your implementation log using `{{RRCE_HOME}}/templates/executor_output.md` and save it to `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/execution/{{TASK_SLUG}}-execution.md`, noting the provided `BRANCH` or current git ref.
81
81
  6. Summarize test evidence, code pointers, and outstanding follow-ups so documentation can build on it seamlessly.
82
+ 7. **Semantic Indexing**: If significant code was added or modified, suggest running `index_knowledge` to update the semantic search index:
83
+ - Tool: `index_knowledge`
84
+ - Args: `{ project: "{{WORKSPACE_NAME}}" }`
82
85
 
83
86
  Deliverable
84
87
  - File: `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/execution/{{TASK_SLUG}}-execution.md`
@@ -162,10 +162,16 @@ Workflow Steps
162
162
  7. Save to `{{RRCE_DATA}}/knowledge/project-context.md`.
163
163
  8. Update `{{RRCE_DATA}}/workspace.json` with project metadata.
164
164
  9. Log changes made (new sections, updated sections, removed outdated info).
165
- 10. **Semantic Indexing**: If the `index_knowledge` tool is available, run it:
166
- - Tool: `index_knowledge`
167
- - Args: `{ project: "{{WORKSPACE_NAME}}" }`
168
- - This ensures the new context is immediately searchable.
165
+ 10. **Semantic Index Status & Indexing**:
166
+ - Determine if semantic search is enabled (check config or look for `embeddings.json` existence).
167
+ - If `index_knowledge` tool is available and enabled:
168
+ - Run it: `index_knowledge` with `{ project: "{{WORKSPACE_NAME}}" }`.
169
+ - Capture the result (files indexed, skipped, totals).
170
+ - Populate Section 11 "Semantic Index Status" in the template with:
171
+ - Enabled: yes/no
172
+ - Last Indexed: Current time (if you just ran it) or file modification time of `embeddings.json`.
173
+ - Index Location: Path to `embeddings.json`.
174
+ - Totals: Use data from `index_knowledge` output if avail.
169
175
 
170
176
  Deliverable
171
177
  - File: `{{RRCE_DATA}}/knowledge/project-context.md`
@@ -73,6 +73,9 @@ Workflow
73
73
  3. Where new persistent knowledge is created (API notes, domain decisions, etc.), append or create records in `{{RRCE_DATA}}/knowledge/{{DOMAIN}}.md` and log the file path inside `meta.json.references`.
74
74
  4. Structure the plan using `{{RRCE_HOME}}/templates/planning_output.md` and store it at `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/planning/{{TASK_SLUG}}-plan.md`.
75
75
  5. Provide clear guidance on validation, testing strategy, rollout sequencing, and success criteria for the Executor.
76
+ 6. **Semantic Indexing**: If new knowledge files were created in `{{RRCE_DATA}}/knowledge/`, suggest running `index_knowledge` to update the semantic search index:
77
+ - Tool: `index_knowledge`
78
+ - Args: `{ project: "{{WORKSPACE_NAME}}" }`
76
79
 
77
80
  Deliverable
78
81
  - File: `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/planning/{{TASK_SLUG}}-plan.md`
@@ -0,0 +1,127 @@
1
+ <!--
2
+ RRCE Template Variables:
3
+ - {{RRCE_DATA}}: Primary storage path (resolves based on storage mode in .rrce-workflow/config.yaml)
4
+ - global: {{RRCE_HOME}}/workspaces/<workspace-name>/
5
+ - workspace: <workspace>/.rrce-workflow/
6
+ - {{RRCE_HOME}}: Global home (default: ~/.rrce-workflow, customizable via storage.globalPath in config)
7
+ - {{WORKSPACE_ROOT}}: Workspace root directory
8
+ - {{WORKSPACE_NAME}}: Workspace name from config or directory name
9
+ -->
10
+ # Project Diagnosis – {{project_name}}
11
+
12
+ - Diagnosis Date: `{{date}}`
13
+ - Analyst: `{{author}}`
14
+ - Workspace: `{{workspace_root}}`
15
+ - Focus Area: `{{focus_area}}` (or "General" if not specified)
16
+ - Project Context: `{{RRCE_DATA}}/knowledge/project-context.md`
17
+
18
+ ---
19
+
20
+ ## Executive Summary
21
+
22
+ A brief 2-3 sentence summary of the overall codebase health and most critical findings.
23
+
24
+ ---
25
+
26
+ ## Health Score
27
+
28
+ | Category | Score (1-5) | Notes |
29
+ |----------|-------------|-------|
30
+ | Code Quality | | |
31
+ | Architecture | | |
32
+ | Testing | | |
33
+ | Security | | |
34
+ | Performance | | |
35
+ | Maintainability | | |
36
+ | **Overall** | | |
37
+
38
+ *Scale: 1=Critical issues, 2=Significant issues, 3=Acceptable, 4=Good, 5=Excellent*
39
+
40
+ ---
41
+
42
+ ## Critical Findings (P0-P1)
43
+
44
+ ### Finding 1: [Title]
45
+ - **Category**: (Code Quality / Architecture / Testing / Security / Performance)
46
+ - **Priority**: P0 / P1
47
+ - **Impact**: High
48
+ - **Effort**: Low / Medium / High
49
+ - **Location**: `path/to/file.ts:L42-L100`
50
+ - **Description**: What is the problem?
51
+ - **Evidence**: Code snippets, metrics, or specific examples.
52
+ - **Recommendation**: What should be done?
53
+ - **Acceptance Criteria**:
54
+ - [ ] Criterion 1
55
+ - [ ] Criterion 2
56
+
57
+ ---
58
+
59
+ ## Medium Priority Findings (P2)
60
+
61
+ ### Finding N: [Title]
62
+ - **Category**:
63
+ - **Priority**: P2
64
+ - **Impact**: Medium
65
+ - **Effort**:
66
+ - **Description**:
67
+ - **Recommendation**:
68
+
69
+ ---
70
+
71
+ ## Low Priority / Backlog (P3+)
72
+
73
+ | Finding | Category | Effort | Notes |
74
+ |---------|----------|--------|-------|
75
+ | | | | |
76
+
77
+ ---
78
+
79
+ ## Recommended Tasks for Planning Agent
80
+
81
+ > These are ready-to-use task definitions for the `planning` agent.
82
+
83
+ ### Task 1: [Suggested Title]
84
+ ```yaml
85
+ title: "[ACTION] [COMPONENT]: [Goal]"
86
+ priority: P1
87
+ category: refactoring / bugfix / feature / docs
88
+ description: |
89
+ Brief description of what needs to be done and why.
90
+ acceptance_criteria:
91
+ - Criterion 1
92
+ - Criterion 2
93
+ estimated_effort: "2-4 hours / 1-2 days / 1 week"
94
+ dependencies:
95
+ - Any blocking tasks or requirements
96
+ context_artifacts:
97
+ - "{{RRCE_DATA}}/knowledge/project-context.md"
98
+ - "path/to/relevant/file.ts"
99
+ ```
100
+
101
+ ### Task 2: [Suggested Title]
102
+ ```yaml
103
+ # ... repeat format
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Metrics & Data
109
+
110
+ Any relevant metrics collected during analysis:
111
+ - Lines of code:
112
+ - Files analyzed:
113
+ - Test coverage (if available):
114
+ - Dependency count:
115
+ - TODO/FIXME comments found:
116
+
117
+ ---
118
+
119
+ ## Next Steps
120
+
121
+ 1. Review findings with team/stakeholder
122
+ 2. Hand off high-priority tasks to `planning` agent: `rrce-workflow run planning --task="<Task Title>"`
123
+ 3. Schedule follow-up diagnosis in: [timeframe]
124
+
125
+ ---
126
+
127
+ > This diagnosis is based on automated analysis and code review. Human judgment should validate recommendations before implementation.
@@ -256,10 +256,26 @@ Based on the tech stack analysis, the Executor agent should have proficiency in:
256
256
  |----------|----------|-------|
257
257
  | | high/medium/low | |
258
258
 
259
+
260
+ ---
261
+
262
+ ## 11. Semantic Index Status
263
+
264
+ | Attribute | Value |
265
+ |-----------|-------|
266
+ | **Enabled** | yes / no |
267
+ | **Last Indexed** | `{{last_indexed_date}}` |
268
+ | **Index Location** | `{{index_path}}` |
269
+ | **Total Files** | |
270
+ | **Total Chunks** | |
271
+
272
+ *If semantic search is enabled, run `index_knowledge` to update the index after significant changes.*
273
+
259
274
  ---
260
275
 
261
276
  ## Checklist
262
277
 
278
+
263
279
  - [ ] Tech stack fully documented
264
280
  - [ ] Coding conventions captured
265
281
  - [ ] Testing strategy clear
package/dist/index.js CHANGED
@@ -374,7 +374,7 @@ import * as path3 from "path";
374
374
  import * as readline from "readline";
375
375
  import pc from "picocolors";
376
376
  function directoryPrompt(opts) {
377
- return new Promise((resolve) => {
377
+ return new Promise((resolve2) => {
378
378
  process.stdout.write(`${pc.cyan("\u25C6")} ${opts.message}
379
379
  `);
380
380
  process.stdout.write(`${pc.cyan("\u2502")} `);
@@ -403,14 +403,14 @@ function directoryPrompt(opts) {
403
403
  rl.close();
404
404
  process.stdout.write(`${pc.green("\u2713")} ${pc.dim(expandedPath)}
405
405
  `);
406
- resolve(expandedPath);
406
+ resolve2(expandedPath);
407
407
  });
408
408
  rl.on("close", () => {
409
409
  });
410
410
  rl.on("SIGINT", () => {
411
411
  rl.close();
412
412
  process.stdout.write("\n");
413
- resolve(/* @__PURE__ */ Symbol("cancel"));
413
+ resolve2(/* @__PURE__ */ Symbol("cancel"));
414
414
  });
415
415
  });
416
416
  }
@@ -762,6 +762,12 @@ function loadPromptsFromDir(dirPath) {
762
762
  return prompts;
763
763
  }
764
764
  function getAgentCoreDir() {
765
+ if (__dirname.includes("/src/") || __dirname.includes("\\src\\")) {
766
+ if (fs5.existsSync(path6.join(process.cwd(), "agent-core"))) {
767
+ return path6.join(process.cwd(), "agent-core");
768
+ }
769
+ return path6.resolve(__dirname, "../..", "agent-core");
770
+ }
765
771
  return path6.join(__dirname, "..", "agent-core");
766
772
  }
767
773
  function getAgentCorePromptsDir() {
@@ -1468,11 +1474,25 @@ var init_rag = __esm({
1468
1474
  }
1469
1475
  }
1470
1476
  /**
1471
- * Index a file
1477
+ * Index a file (smart: skips if mtime unchanged)
1478
+ * @param filePath Absolute path to the file
1479
+ * @param content File content
1480
+ * @param mtime Optional modification time (if not provided, always re-indexes)
1481
+ * @returns true if file was indexed, false if skipped
1472
1482
  */
1473
- async indexFile(filePath, content) {
1483
+ async indexFile(filePath, content, mtime) {
1474
1484
  this.loadIndex();
1475
1485
  if (!this.index) throw new Error("Index not initialized");
1486
+ if (!this.index.fileMetadata) {
1487
+ this.index.fileMetadata = {};
1488
+ }
1489
+ if (mtime !== void 0 && this.index.fileMetadata[filePath]) {
1490
+ const existingMeta = this.index.fileMetadata[filePath];
1491
+ if (existingMeta.mtime === mtime) {
1492
+ logger.debug(`RAG: Skipping unchanged file ${filePath}`);
1493
+ return false;
1494
+ }
1495
+ }
1476
1496
  logger.info(`RAG: Indexing file ${filePath}`);
1477
1497
  this.index.chunks = this.index.chunks.filter((c) => c.filePath !== filePath);
1478
1498
  const chunks = this.chunkContent(content);
@@ -1482,10 +1502,16 @@ var init_rag = __esm({
1482
1502
  id: `${filePath}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
1483
1503
  filePath,
1484
1504
  content: chunkText,
1485
- embedding
1505
+ embedding,
1506
+ mtime
1486
1507
  });
1487
1508
  }
1509
+ this.index.fileMetadata[filePath] = {
1510
+ mtime: mtime ?? Date.now(),
1511
+ chunkCount: chunks.length
1512
+ };
1488
1513
  this.saveIndex();
1514
+ return true;
1489
1515
  }
1490
1516
  /**
1491
1517
  * Remove a file from index
@@ -1495,11 +1521,36 @@ var init_rag = __esm({
1495
1521
  if (!this.index) return;
1496
1522
  const initialCount = this.index.chunks.length;
1497
1523
  this.index.chunks = this.index.chunks.filter((c) => c.filePath !== filePath);
1524
+ if (this.index.fileMetadata) {
1525
+ delete this.index.fileMetadata[filePath];
1526
+ }
1498
1527
  if (this.index.chunks.length !== initialCount) {
1499
1528
  logger.info(`RAG: Removed file ${filePath} from index (${initialCount - this.index.chunks.length} chunks removed)`);
1500
1529
  this.saveIndex();
1501
1530
  }
1502
1531
  }
1532
+ /**
1533
+ * Get index statistics
1534
+ */
1535
+ getStats() {
1536
+ this.loadIndex();
1537
+ if (!this.index) return { totalChunks: 0, totalFiles: 0 };
1538
+ const fileCount = this.index.fileMetadata ? Object.keys(this.index.fileMetadata).length : 0;
1539
+ return {
1540
+ totalChunks: this.index.chunks.length,
1541
+ totalFiles: fileCount,
1542
+ lastFullIndex: this.index.lastFullIndex
1543
+ };
1544
+ }
1545
+ /**
1546
+ * Mark the last full index timestamp
1547
+ */
1548
+ markFullIndex() {
1549
+ this.loadIndex();
1550
+ if (!this.index) return;
1551
+ this.index.lastFullIndex = Date.now();
1552
+ this.saveIndex();
1553
+ }
1503
1554
  /**
1504
1555
  * Search the index
1505
1556
  */
@@ -1735,31 +1786,102 @@ async function indexKnowledge(projectName, force = false) {
1735
1786
  const projects = getExposedProjects();
1736
1787
  const project = projects.find((p) => p.name === projectName || p.path && p.path === projectName);
1737
1788
  if (!project) {
1738
- return { success: false, message: `Project '${projectName}' not found`, filesIndexed: 0 };
1789
+ return { success: false, message: `Project '${projectName}' not found`, filesIndexed: 0, filesSkipped: 0 };
1739
1790
  }
1740
1791
  const projConfig = config.projects.find(
1741
1792
  (p) => p.path && p.path === project.dataPath || !p.path && p.name === project.name
1742
1793
  );
1743
1794
  if (!projConfig?.semanticSearch?.enabled) {
1744
- return { success: false, message: "Semantic Search is not enabled for this project", filesIndexed: 0 };
1745
- }
1746
- if (!project.knowledgePath || !fs13.existsSync(project.knowledgePath)) {
1747
- return { success: false, message: "No knowledge directory found", filesIndexed: 0 };
1748
- }
1795
+ return { success: false, message: "Semantic Search is not enabled for this project", filesIndexed: 0, filesSkipped: 0 };
1796
+ }
1797
+ const scanRoot = project.path || project.dataPath;
1798
+ if (!fs13.existsSync(scanRoot)) {
1799
+ return { success: false, message: "Project root not found", filesIndexed: 0, filesSkipped: 0 };
1800
+ }
1801
+ const INDEXABLE_EXTENSIONS = [
1802
+ ".ts",
1803
+ ".tsx",
1804
+ ".js",
1805
+ ".jsx",
1806
+ ".mjs",
1807
+ ".cjs",
1808
+ ".py",
1809
+ ".pyw",
1810
+ ".go",
1811
+ ".rs",
1812
+ ".java",
1813
+ ".kt",
1814
+ ".kts",
1815
+ ".c",
1816
+ ".cpp",
1817
+ ".h",
1818
+ ".hpp",
1819
+ ".cs",
1820
+ ".rb",
1821
+ ".php",
1822
+ ".swift",
1823
+ ".md",
1824
+ ".mdx",
1825
+ ".json",
1826
+ ".yaml",
1827
+ ".yml",
1828
+ ".toml",
1829
+ ".sh",
1830
+ ".bash",
1831
+ ".zsh",
1832
+ ".sql",
1833
+ ".html",
1834
+ ".css",
1835
+ ".scss",
1836
+ ".sass",
1837
+ ".less"
1838
+ ];
1839
+ const SKIP_DIRS = ["node_modules", ".git", "dist", "build", ".next", "__pycache__", "venv", ".venv", "target", "vendor"];
1749
1840
  try {
1750
- const indexPath = path14.join(project.knowledgePath, "embeddings.json");
1841
+ const indexPath = path14.join(project.knowledgePath || path14.join(scanRoot, ".rrce-workflow", "knowledge"), "embeddings.json");
1751
1842
  const rag = new RAGService(indexPath, projConfig.semanticSearch.model);
1752
- const files = fs13.readdirSync(project.knowledgePath).filter((f) => f.endsWith(".md"));
1753
- let count = 0;
1754
- for (const file of files) {
1755
- const filePath = path14.join(project.knowledgePath, file);
1756
- const content = fs13.readFileSync(filePath, "utf-8");
1757
- await rag.indexFile(path14.join(project.knowledgePath, file), content);
1758
- count++;
1759
- }
1760
- return { success: true, message: `Successfully indexed ${count} files`, filesIndexed: count };
1843
+ let indexed = 0;
1844
+ let skipped = 0;
1845
+ const scanDir = async (dir) => {
1846
+ const entries = fs13.readdirSync(dir, { withFileTypes: true });
1847
+ for (const entry of entries) {
1848
+ const fullPath = path14.join(dir, entry.name);
1849
+ if (entry.isDirectory()) {
1850
+ if (SKIP_DIRS.includes(entry.name) || entry.name.startsWith(".")) {
1851
+ continue;
1852
+ }
1853
+ await scanDir(fullPath);
1854
+ } else if (entry.isFile()) {
1855
+ const ext = path14.extname(entry.name).toLowerCase();
1856
+ if (!INDEXABLE_EXTENSIONS.includes(ext)) {
1857
+ continue;
1858
+ }
1859
+ try {
1860
+ const stat = fs13.statSync(fullPath);
1861
+ const mtime = force ? void 0 : stat.mtimeMs;
1862
+ const content = fs13.readFileSync(fullPath, "utf-8");
1863
+ const wasIndexed = await rag.indexFile(fullPath, content, mtime);
1864
+ if (wasIndexed) {
1865
+ indexed++;
1866
+ } else {
1867
+ skipped++;
1868
+ }
1869
+ } catch (err) {
1870
+ }
1871
+ }
1872
+ }
1873
+ };
1874
+ await scanDir(scanRoot);
1875
+ rag.markFullIndex();
1876
+ const stats = rag.getStats();
1877
+ return {
1878
+ success: true,
1879
+ message: `Indexed ${indexed} files, skipped ${skipped} unchanged. Total: ${stats.totalChunks} chunks from ${stats.totalFiles} files.`,
1880
+ filesIndexed: indexed,
1881
+ filesSkipped: skipped
1882
+ };
1761
1883
  } catch (error) {
1762
- return { success: false, message: `Indexing failed: ${error}`, filesIndexed: 0 };
1884
+ return { success: false, message: `Indexing failed: ${error}`, filesIndexed: 0, filesSkipped: 0 };
1763
1885
  }
1764
1886
  }
1765
1887
  function getContextPreamble() {
@@ -2644,7 +2766,12 @@ var init_Overview = __esm({
2644
2766
  /* @__PURE__ */ jsx2(Text2, { children: "Server Port: " }),
2645
2767
  /* @__PURE__ */ jsx2(Text2, { color: "cyan", children: serverStatus.port })
2646
2768
  ] }),
2647
- /* @__PURE__ */ jsx2(Box2, { marginTop: 1, children: /* @__PURE__ */ jsx2(Text2, { color: "dim", children: "Press 'q' to stop server and exit." }) })
2769
+ /* @__PURE__ */ jsxs(Box2, { marginTop: 1, flexDirection: "column", children: [
2770
+ /* @__PURE__ */ jsx2(Text2, { color: "dim", children: "Controls:" }),
2771
+ /* @__PURE__ */ jsx2(Text2, { color: "dim", children: " \u2022 Press 'r' to restart server" }),
2772
+ /* @__PURE__ */ jsx2(Text2, { color: "dim", children: " \u2022 Use 1-4 or \u25C4/\u25BA to navigate tabs" }),
2773
+ /* @__PURE__ */ jsx2(Text2, { color: "dim", children: " \u2022 Press 'q' to stop server and exit" })
2774
+ ] })
2648
2775
  ] })
2649
2776
  ] });
2650
2777
  };
@@ -3034,7 +3161,7 @@ var init_App = __esm({
3034
3161
  ];
3035
3162
  App = ({ onExit, initialPort }) => {
3036
3163
  const { exit } = useApp();
3037
- const [activeTab, setActiveTab] = useState4("logs");
3164
+ const [activeTab, setActiveTab] = useState4("overview");
3038
3165
  const [logs, setLogs] = useState4([]);
3039
3166
  const [serverInfo, setServerInfo] = useState4({
3040
3167
  port: initialPort,
@@ -3107,12 +3234,24 @@ var init_App = __esm({
3107
3234
  }, 500);
3108
3235
  return () => clearInterval(interval);
3109
3236
  }, []);
3110
- useInput3((input, key) => {
3237
+ useInput3(async (input, key) => {
3111
3238
  if (input === "q" || key.ctrl && input === "c") {
3112
3239
  stopMCPServer();
3113
3240
  onExit();
3114
3241
  exit();
3115
3242
  }
3243
+ if (input === "r") {
3244
+ setLogs((prev) => [...prev, "[INFO] Restarting server..."]);
3245
+ stopMCPServer();
3246
+ setServerInfo((prev) => ({ ...prev, running: false }));
3247
+ try {
3248
+ const res = await startMCPServer({ interactive: true });
3249
+ setServerInfo((prev) => ({ ...prev, running: true, port: res.port, pid: res.pid }));
3250
+ setLogs((prev) => [...prev, "[INFO] Server restarted successfully"]);
3251
+ } catch (e) {
3252
+ setLogs((prev) => [...prev, `[ERROR] Failed to restart: ${e}`]);
3253
+ }
3254
+ }
3116
3255
  });
3117
3256
  const termHeight = process.stdout.rows || 24;
3118
3257
  const contentHeight = termHeight - 8;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrce-workflow",
3
- "version": "0.2.52",
3
+ "version": "0.2.54",
4
4
  "description": "RRCE-Workflow TUI - Agentic code workflow generator for AI-assisted development",
5
5
  "author": "RRCE Team",
6
6
  "license": "MIT",