rrce-workflow 0.2.53 → 0.2.55
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.
- package/agent-core/prompts/doctor.md +142 -0
- package/agent-core/prompts/executor.md +3 -0
- package/agent-core/prompts/init.md +10 -4
- package/agent-core/prompts/planning_orchestrator.md +3 -0
- package/agent-core/templates/doctor_output.md +127 -0
- package/agent-core/templates/init_output.md +16 -0
- package/dist/index.js +192 -32
- package/package.json +1 -1
|
@@ -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
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
|
|
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((
|
|
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
|
-
|
|
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
|
-
|
|
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() {
|
|
@@ -1161,7 +1167,6 @@ function installAgentPrompts(config, workspacePath, dataPaths) {
|
|
|
1161
1167
|
}
|
|
1162
1168
|
}
|
|
1163
1169
|
function createWorkspaceConfig(config, workspacePath, workspaceName) {
|
|
1164
|
-
if (config.storageMode !== "workspace") return;
|
|
1165
1170
|
const configPath = path10.join(workspacePath, ".rrce-workflow", "config.yaml");
|
|
1166
1171
|
ensureDir(path10.dirname(configPath));
|
|
1167
1172
|
let content = `# RRCE-Workflow Configuration
|
|
@@ -1468,11 +1473,25 @@ var init_rag = __esm({
|
|
|
1468
1473
|
}
|
|
1469
1474
|
}
|
|
1470
1475
|
/**
|
|
1471
|
-
* Index a file
|
|
1476
|
+
* Index a file (smart: skips if mtime unchanged)
|
|
1477
|
+
* @param filePath Absolute path to the file
|
|
1478
|
+
* @param content File content
|
|
1479
|
+
* @param mtime Optional modification time (if not provided, always re-indexes)
|
|
1480
|
+
* @returns true if file was indexed, false if skipped
|
|
1472
1481
|
*/
|
|
1473
|
-
async indexFile(filePath, content) {
|
|
1482
|
+
async indexFile(filePath, content, mtime) {
|
|
1474
1483
|
this.loadIndex();
|
|
1475
1484
|
if (!this.index) throw new Error("Index not initialized");
|
|
1485
|
+
if (!this.index.fileMetadata) {
|
|
1486
|
+
this.index.fileMetadata = {};
|
|
1487
|
+
}
|
|
1488
|
+
if (mtime !== void 0 && this.index.fileMetadata[filePath]) {
|
|
1489
|
+
const existingMeta = this.index.fileMetadata[filePath];
|
|
1490
|
+
if (existingMeta.mtime === mtime) {
|
|
1491
|
+
logger.debug(`RAG: Skipping unchanged file ${filePath}`);
|
|
1492
|
+
return false;
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1476
1495
|
logger.info(`RAG: Indexing file ${filePath}`);
|
|
1477
1496
|
this.index.chunks = this.index.chunks.filter((c) => c.filePath !== filePath);
|
|
1478
1497
|
const chunks = this.chunkContent(content);
|
|
@@ -1482,10 +1501,16 @@ var init_rag = __esm({
|
|
|
1482
1501
|
id: `${filePath}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
1483
1502
|
filePath,
|
|
1484
1503
|
content: chunkText,
|
|
1485
|
-
embedding
|
|
1504
|
+
embedding,
|
|
1505
|
+
mtime
|
|
1486
1506
|
});
|
|
1487
1507
|
}
|
|
1508
|
+
this.index.fileMetadata[filePath] = {
|
|
1509
|
+
mtime: mtime ?? Date.now(),
|
|
1510
|
+
chunkCount: chunks.length
|
|
1511
|
+
};
|
|
1488
1512
|
this.saveIndex();
|
|
1513
|
+
return true;
|
|
1489
1514
|
}
|
|
1490
1515
|
/**
|
|
1491
1516
|
* Remove a file from index
|
|
@@ -1495,11 +1520,36 @@ var init_rag = __esm({
|
|
|
1495
1520
|
if (!this.index) return;
|
|
1496
1521
|
const initialCount = this.index.chunks.length;
|
|
1497
1522
|
this.index.chunks = this.index.chunks.filter((c) => c.filePath !== filePath);
|
|
1523
|
+
if (this.index.fileMetadata) {
|
|
1524
|
+
delete this.index.fileMetadata[filePath];
|
|
1525
|
+
}
|
|
1498
1526
|
if (this.index.chunks.length !== initialCount) {
|
|
1499
1527
|
logger.info(`RAG: Removed file ${filePath} from index (${initialCount - this.index.chunks.length} chunks removed)`);
|
|
1500
1528
|
this.saveIndex();
|
|
1501
1529
|
}
|
|
1502
1530
|
}
|
|
1531
|
+
/**
|
|
1532
|
+
* Get index statistics
|
|
1533
|
+
*/
|
|
1534
|
+
getStats() {
|
|
1535
|
+
this.loadIndex();
|
|
1536
|
+
if (!this.index) return { totalChunks: 0, totalFiles: 0 };
|
|
1537
|
+
const fileCount = this.index.fileMetadata ? Object.keys(this.index.fileMetadata).length : 0;
|
|
1538
|
+
return {
|
|
1539
|
+
totalChunks: this.index.chunks.length,
|
|
1540
|
+
totalFiles: fileCount,
|
|
1541
|
+
lastFullIndex: this.index.lastFullIndex
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
/**
|
|
1545
|
+
* Mark the last full index timestamp
|
|
1546
|
+
*/
|
|
1547
|
+
markFullIndex() {
|
|
1548
|
+
this.loadIndex();
|
|
1549
|
+
if (!this.index) return;
|
|
1550
|
+
this.index.lastFullIndex = Date.now();
|
|
1551
|
+
this.saveIndex();
|
|
1552
|
+
}
|
|
1503
1553
|
/**
|
|
1504
1554
|
* Search the index
|
|
1505
1555
|
*/
|
|
@@ -1735,31 +1785,102 @@ async function indexKnowledge(projectName, force = false) {
|
|
|
1735
1785
|
const projects = getExposedProjects();
|
|
1736
1786
|
const project = projects.find((p) => p.name === projectName || p.path && p.path === projectName);
|
|
1737
1787
|
if (!project) {
|
|
1738
|
-
return { success: false, message: `Project '${projectName}' not found`, filesIndexed: 0 };
|
|
1788
|
+
return { success: false, message: `Project '${projectName}' not found`, filesIndexed: 0, filesSkipped: 0 };
|
|
1739
1789
|
}
|
|
1740
1790
|
const projConfig = config.projects.find(
|
|
1741
1791
|
(p) => p.path && p.path === project.dataPath || !p.path && p.name === project.name
|
|
1742
1792
|
);
|
|
1743
1793
|
if (!projConfig?.semanticSearch?.enabled) {
|
|
1744
|
-
return { success: false, message: "Semantic Search is not enabled for this project", filesIndexed: 0 };
|
|
1745
|
-
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1794
|
+
return { success: false, message: "Semantic Search is not enabled for this project", filesIndexed: 0, filesSkipped: 0 };
|
|
1795
|
+
}
|
|
1796
|
+
const scanRoot = project.path || project.dataPath;
|
|
1797
|
+
if (!fs13.existsSync(scanRoot)) {
|
|
1798
|
+
return { success: false, message: "Project root not found", filesIndexed: 0, filesSkipped: 0 };
|
|
1799
|
+
}
|
|
1800
|
+
const INDEXABLE_EXTENSIONS = [
|
|
1801
|
+
".ts",
|
|
1802
|
+
".tsx",
|
|
1803
|
+
".js",
|
|
1804
|
+
".jsx",
|
|
1805
|
+
".mjs",
|
|
1806
|
+
".cjs",
|
|
1807
|
+
".py",
|
|
1808
|
+
".pyw",
|
|
1809
|
+
".go",
|
|
1810
|
+
".rs",
|
|
1811
|
+
".java",
|
|
1812
|
+
".kt",
|
|
1813
|
+
".kts",
|
|
1814
|
+
".c",
|
|
1815
|
+
".cpp",
|
|
1816
|
+
".h",
|
|
1817
|
+
".hpp",
|
|
1818
|
+
".cs",
|
|
1819
|
+
".rb",
|
|
1820
|
+
".php",
|
|
1821
|
+
".swift",
|
|
1822
|
+
".md",
|
|
1823
|
+
".mdx",
|
|
1824
|
+
".json",
|
|
1825
|
+
".yaml",
|
|
1826
|
+
".yml",
|
|
1827
|
+
".toml",
|
|
1828
|
+
".sh",
|
|
1829
|
+
".bash",
|
|
1830
|
+
".zsh",
|
|
1831
|
+
".sql",
|
|
1832
|
+
".html",
|
|
1833
|
+
".css",
|
|
1834
|
+
".scss",
|
|
1835
|
+
".sass",
|
|
1836
|
+
".less"
|
|
1837
|
+
];
|
|
1838
|
+
const SKIP_DIRS = ["node_modules", ".git", "dist", "build", ".next", "__pycache__", "venv", ".venv", "target", "vendor"];
|
|
1749
1839
|
try {
|
|
1750
|
-
const indexPath = path14.join(project.knowledgePath, "embeddings.json");
|
|
1840
|
+
const indexPath = path14.join(project.knowledgePath || path14.join(scanRoot, ".rrce-workflow", "knowledge"), "embeddings.json");
|
|
1751
1841
|
const rag = new RAGService(indexPath, projConfig.semanticSearch.model);
|
|
1752
|
-
|
|
1753
|
-
let
|
|
1754
|
-
|
|
1755
|
-
const
|
|
1756
|
-
const
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1842
|
+
let indexed = 0;
|
|
1843
|
+
let skipped = 0;
|
|
1844
|
+
const scanDir = async (dir) => {
|
|
1845
|
+
const entries = fs13.readdirSync(dir, { withFileTypes: true });
|
|
1846
|
+
for (const entry of entries) {
|
|
1847
|
+
const fullPath = path14.join(dir, entry.name);
|
|
1848
|
+
if (entry.isDirectory()) {
|
|
1849
|
+
if (SKIP_DIRS.includes(entry.name) || entry.name.startsWith(".")) {
|
|
1850
|
+
continue;
|
|
1851
|
+
}
|
|
1852
|
+
await scanDir(fullPath);
|
|
1853
|
+
} else if (entry.isFile()) {
|
|
1854
|
+
const ext = path14.extname(entry.name).toLowerCase();
|
|
1855
|
+
if (!INDEXABLE_EXTENSIONS.includes(ext)) {
|
|
1856
|
+
continue;
|
|
1857
|
+
}
|
|
1858
|
+
try {
|
|
1859
|
+
const stat = fs13.statSync(fullPath);
|
|
1860
|
+
const mtime = force ? void 0 : stat.mtimeMs;
|
|
1861
|
+
const content = fs13.readFileSync(fullPath, "utf-8");
|
|
1862
|
+
const wasIndexed = await rag.indexFile(fullPath, content, mtime);
|
|
1863
|
+
if (wasIndexed) {
|
|
1864
|
+
indexed++;
|
|
1865
|
+
} else {
|
|
1866
|
+
skipped++;
|
|
1867
|
+
}
|
|
1868
|
+
} catch (err) {
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1873
|
+
await scanDir(scanRoot);
|
|
1874
|
+
rag.markFullIndex();
|
|
1875
|
+
const stats = rag.getStats();
|
|
1876
|
+
return {
|
|
1877
|
+
success: true,
|
|
1878
|
+
message: `Indexed ${indexed} files, skipped ${skipped} unchanged. Total: ${stats.totalChunks} chunks from ${stats.totalFiles} files.`,
|
|
1879
|
+
filesIndexed: indexed,
|
|
1880
|
+
filesSkipped: skipped
|
|
1881
|
+
};
|
|
1761
1882
|
} catch (error) {
|
|
1762
|
-
return { success: false, message: `Indexing failed: ${error}`, filesIndexed: 0 };
|
|
1883
|
+
return { success: false, message: `Indexing failed: ${error}`, filesIndexed: 0, filesSkipped: 0 };
|
|
1763
1884
|
}
|
|
1764
1885
|
}
|
|
1765
1886
|
function getContextPreamble() {
|
|
@@ -1906,7 +2027,10 @@ function getAllPrompts() {
|
|
|
1906
2027
|
required: false
|
|
1907
2028
|
})));
|
|
1908
2029
|
}
|
|
2030
|
+
const filename = p.filePath.split("/").pop() || "";
|
|
2031
|
+
const id = filename.replace(/\.md$/, "");
|
|
1909
2032
|
return {
|
|
2033
|
+
id,
|
|
1910
2034
|
name: p.frontmatter.name,
|
|
1911
2035
|
description: p.frontmatter.description,
|
|
1912
2036
|
arguments: args,
|
|
@@ -1915,7 +2039,11 @@ function getAllPrompts() {
|
|
|
1915
2039
|
});
|
|
1916
2040
|
}
|
|
1917
2041
|
function getPromptDef(name) {
|
|
1918
|
-
|
|
2042
|
+
const all = getAllPrompts();
|
|
2043
|
+
const search = name.toLowerCase();
|
|
2044
|
+
return all.find(
|
|
2045
|
+
(p) => p.name === name || p.id === name || p.name.toLowerCase() === search || p.id.toLowerCase() === search
|
|
2046
|
+
);
|
|
1919
2047
|
}
|
|
1920
2048
|
function renderPrompt(content, args) {
|
|
1921
2049
|
let rendered = content;
|
|
@@ -2635,14 +2763,46 @@ var init_Overview = __esm({
|
|
|
2635
2763
|
return /* @__PURE__ */ jsxs(Box2, { flexDirection: "column", flexGrow: 1, children: [
|
|
2636
2764
|
/* @__PURE__ */ jsx2(Header, {}),
|
|
2637
2765
|
/* @__PURE__ */ jsxs(Box2, { borderStyle: "round", padding: 1, borderColor: "white", flexDirection: "column", flexGrow: 1, children: [
|
|
2638
|
-
/* @__PURE__ */
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2766
|
+
/* @__PURE__ */ jsxs(Box2, { justifyContent: "space-between", children: [
|
|
2767
|
+
/* @__PURE__ */ jsxs(Box2, { flexDirection: "column", children: [
|
|
2768
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, underline: true, children: "System Status" }),
|
|
2769
|
+
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, children: [
|
|
2770
|
+
/* @__PURE__ */ jsx2(Text2, { children: "Integrations Installed: " }),
|
|
2771
|
+
/* @__PURE__ */ jsx2(Text2, { color: stats.installedIntegrations > 0 ? "green" : "yellow", children: stats.installedIntegrations })
|
|
2772
|
+
] }),
|
|
2773
|
+
/* @__PURE__ */ jsxs(Box2, { children: [
|
|
2774
|
+
/* @__PURE__ */ jsx2(Text2, { children: "Server Port: " }),
|
|
2775
|
+
/* @__PURE__ */ jsx2(Text2, { color: "cyan", children: serverStatus.port })
|
|
2776
|
+
] })
|
|
2777
|
+
] }),
|
|
2778
|
+
/* @__PURE__ */ jsxs(Box2, { flexDirection: "column", marginLeft: 4, children: [
|
|
2779
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, underline: true, children: "Quick Start" }),
|
|
2780
|
+
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, flexDirection: "column", children: [
|
|
2781
|
+
/* @__PURE__ */ jsx2(Text2, { children: '1. Install "MCP" extension in VSCode / Antigravity' }),
|
|
2782
|
+
/* @__PURE__ */ jsx2(Text2, { children: "2. Configure Extension to use this server:" }),
|
|
2783
|
+
/* @__PURE__ */ jsx2(Text2, { color: "dim", children: " (This is handled automatically by 'Install to IDE')" }),
|
|
2784
|
+
/* @__PURE__ */ jsx2(Text2, { children: "3. In your Agent IDE, ask:" }),
|
|
2785
|
+
/* @__PURE__ */ jsx2(Text2, { color: "cyan", children: ' "Use the rrce tools to analyze this project"' })
|
|
2786
|
+
] })
|
|
2787
|
+
] })
|
|
2642
2788
|
] }),
|
|
2643
|
-
/* @__PURE__ */ jsxs(Box2, { children: [
|
|
2644
|
-
/* @__PURE__ */ jsx2(Text2, { children: "
|
|
2645
|
-
/* @__PURE__ */
|
|
2789
|
+
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, borderStyle: "single", borderColor: "gray", flexDirection: "column", paddingX: 1, children: [
|
|
2790
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, children: "Usage Tips:" }),
|
|
2791
|
+
/* @__PURE__ */ jsxs(Text2, { children: [
|
|
2792
|
+
"\u2022 ",
|
|
2793
|
+
/* @__PURE__ */ jsx2(Text2, { color: "yellow", children: "init" }),
|
|
2794
|
+
': "Initialize project context"'
|
|
2795
|
+
] }),
|
|
2796
|
+
/* @__PURE__ */ jsxs(Text2, { children: [
|
|
2797
|
+
"\u2022 ",
|
|
2798
|
+
/* @__PURE__ */ jsx2(Text2, { color: "yellow", children: "plan" }),
|
|
2799
|
+
': "Create a plan for [task]"'
|
|
2800
|
+
] }),
|
|
2801
|
+
/* @__PURE__ */ jsxs(Text2, { children: [
|
|
2802
|
+
"\u2022 ",
|
|
2803
|
+
/* @__PURE__ */ jsx2(Text2, { color: "yellow", children: "doctor" }),
|
|
2804
|
+
': "Check project health"'
|
|
2805
|
+
] })
|
|
2646
2806
|
] }),
|
|
2647
2807
|
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, flexDirection: "column", children: [
|
|
2648
2808
|
/* @__PURE__ */ jsx2(Text2, { color: "dim", children: "Controls:" }),
|