ai-sdlc 0.2.0-alpha.5 → 0.2.0-alpha.50
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/README.md +53 -1058
- package/dist/agents/implementation.d.ts +6 -0
- package/dist/agents/implementation.d.ts.map +1 -1
- package/dist/agents/implementation.js +151 -13
- package/dist/agents/implementation.js.map +1 -1
- package/dist/agents/index.d.ts +2 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +2 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/orchestrator.d.ts +61 -0
- package/dist/agents/orchestrator.d.ts.map +1 -0
- package/dist/agents/orchestrator.js +443 -0
- package/dist/agents/orchestrator.js.map +1 -0
- package/dist/agents/planning.d.ts +1 -1
- package/dist/agents/planning.d.ts.map +1 -1
- package/dist/agents/planning.js +55 -4
- package/dist/agents/planning.js.map +1 -1
- package/dist/agents/refinement.d.ts.map +1 -1
- package/dist/agents/refinement.js +22 -3
- package/dist/agents/refinement.js.map +1 -1
- package/dist/agents/research.d.ts +85 -1
- package/dist/agents/research.d.ts.map +1 -1
- package/dist/agents/research.js +506 -16
- package/dist/agents/research.js.map +1 -1
- package/dist/agents/review.d.ts +77 -2
- package/dist/agents/review.d.ts.map +1 -1
- package/dist/agents/review.js +615 -93
- package/dist/agents/review.js.map +1 -1
- package/dist/agents/rework.d.ts.map +1 -1
- package/dist/agents/rework.js +22 -3
- package/dist/agents/rework.js.map +1 -1
- package/dist/agents/single-task.d.ts +41 -0
- package/dist/agents/single-task.d.ts.map +1 -0
- package/dist/agents/single-task.js +357 -0
- package/dist/agents/single-task.js.map +1 -0
- package/dist/agents/state-assessor.d.ts +3 -3
- package/dist/agents/state-assessor.d.ts.map +1 -1
- package/dist/agents/state-assessor.js +6 -6
- package/dist/agents/state-assessor.js.map +1 -1
- package/dist/agents/test-pattern-detector.d.ts +49 -0
- package/dist/agents/test-pattern-detector.d.ts.map +1 -0
- package/dist/agents/test-pattern-detector.js +273 -0
- package/dist/agents/test-pattern-detector.js.map +1 -0
- package/dist/agents/verification.d.ts +11 -0
- package/dist/agents/verification.d.ts.map +1 -1
- package/dist/agents/verification.js +97 -12
- package/dist/agents/verification.js.map +1 -1
- package/dist/cli/commands/migrate.js +1 -1
- package/dist/cli/commands/migrate.js.map +1 -1
- package/dist/cli/commands.d.ts +65 -3
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +1108 -204
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/daemon.js +20 -3
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/runner.d.ts.map +1 -1
- package/dist/cli/runner.js +19 -11
- package/dist/cli/runner.js.map +1 -1
- package/dist/core/auth.d.ts +43 -0
- package/dist/core/auth.d.ts.map +1 -1
- package/dist/core/auth.js +105 -1
- package/dist/core/auth.js.map +1 -1
- package/dist/core/client.d.ts +6 -0
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +57 -3
- package/dist/core/client.js.map +1 -1
- package/dist/core/config.d.ts +24 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +100 -3
- package/dist/core/config.js.map +1 -1
- package/dist/core/conflict-detector.d.ts +108 -0
- package/dist/core/conflict-detector.d.ts.map +1 -0
- package/dist/core/conflict-detector.js +413 -0
- package/dist/core/conflict-detector.js.map +1 -0
- package/dist/core/git-utils.d.ts +28 -0
- package/dist/core/git-utils.d.ts.map +1 -0
- package/dist/core/git-utils.js +146 -0
- package/dist/core/git-utils.js.map +1 -0
- package/dist/core/index.d.ts +19 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +19 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/kanban.d.ts +1 -1
- package/dist/core/kanban.d.ts.map +1 -1
- package/dist/core/kanban.js +7 -6
- package/dist/core/kanban.js.map +1 -1
- package/dist/core/llm-utils.d.ts +103 -0
- package/dist/core/llm-utils.d.ts.map +1 -0
- package/dist/core/llm-utils.js +368 -0
- package/dist/core/llm-utils.js.map +1 -0
- package/dist/core/logger.d.ts +92 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +221 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/story-logger.d.ts +102 -0
- package/dist/core/story-logger.d.ts.map +1 -0
- package/dist/core/story-logger.js +265 -0
- package/dist/core/story-logger.js.map +1 -0
- package/dist/core/story.d.ts +89 -20
- package/dist/core/story.d.ts.map +1 -1
- package/dist/core/story.js +297 -52
- package/dist/core/story.js.map +1 -1
- package/dist/core/task-parser.d.ts +59 -0
- package/dist/core/task-parser.d.ts.map +1 -0
- package/dist/core/task-parser.js +235 -0
- package/dist/core/task-parser.js.map +1 -0
- package/dist/core/task-progress.d.ts +92 -0
- package/dist/core/task-progress.d.ts.map +1 -0
- package/dist/core/task-progress.js +280 -0
- package/dist/core/task-progress.js.map +1 -0
- package/dist/core/workflow-state.d.ts +45 -6
- package/dist/core/workflow-state.d.ts.map +1 -1
- package/dist/core/workflow-state.js +201 -12
- package/dist/core/workflow-state.js.map +1 -1
- package/dist/core/worktree.d.ts +77 -0
- package/dist/core/worktree.d.ts.map +1 -0
- package/dist/core/worktree.js +246 -0
- package/dist/core/worktree.js.map +1 -0
- package/dist/index.js +135 -5
- package/dist/index.js.map +1 -1
- package/dist/services/error-classifier.d.ts +119 -0
- package/dist/services/error-classifier.d.ts.map +1 -0
- package/dist/services/error-classifier.js +182 -0
- package/dist/services/error-classifier.js.map +1 -0
- package/dist/types/index.d.ts +336 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +4 -1
package/dist/agents/research.js
CHANGED
|
@@ -3,16 +3,176 @@ import path from 'path';
|
|
|
3
3
|
import { glob } from 'glob';
|
|
4
4
|
import { parseStory, appendToSection, updateStoryField } from '../core/story.js';
|
|
5
5
|
import { runAgentQuery } from '../core/client.js';
|
|
6
|
-
|
|
6
|
+
import { getLogger } from '../core/logger.js';
|
|
7
|
+
const RESEARCH_SYSTEM_PROMPT = `You are a technical research specialist analyzing how to implement a user story by deeply examining the existing codebase.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
1. Identify relevant existing code patterns in the codebase
|
|
10
|
-
2. Suggest which files/modules need to be modified
|
|
11
|
-
3. Research external best practices if applicable
|
|
12
|
-
4. Identify potential challenges or risks
|
|
13
|
-
5. Note any dependencies or prerequisites
|
|
9
|
+
## Research Methodology
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
**Phase 1: Problem Understanding**
|
|
12
|
+
- Parse the story requirements to extract core needs
|
|
13
|
+
- Identify key terms and concepts that map to codebase elements
|
|
14
|
+
- Clarify the scope: what is being asked vs what is NOT being asked
|
|
15
|
+
|
|
16
|
+
**Phase 2: Codebase Exploration**
|
|
17
|
+
- Use the provided codebase context to locate relevant code
|
|
18
|
+
- Trace dependencies and call chains from entry points
|
|
19
|
+
- Identify architectural boundaries and interfaces
|
|
20
|
+
- Find similar implementations that can serve as templates
|
|
21
|
+
|
|
22
|
+
**Phase 3: Solution Mapping**
|
|
23
|
+
- Map story requirements to specific code locations
|
|
24
|
+
- Identify the change surface area (all affected files)
|
|
25
|
+
- Consider alternative approaches and trade-offs
|
|
26
|
+
- Determine the sequence of changes (what depends on what)
|
|
27
|
+
|
|
28
|
+
## Required Output Structure
|
|
29
|
+
|
|
30
|
+
Your research MUST include these five sections:
|
|
31
|
+
|
|
32
|
+
### Problem Summary
|
|
33
|
+
[Restate the problem in your own words to confirm understanding. What is the core goal?]
|
|
34
|
+
|
|
35
|
+
### Codebase Context
|
|
36
|
+
[Describe relevant architecture, patterns, and existing implementations you found. Reference specific files and patterns.]
|
|
37
|
+
|
|
38
|
+
### Files Requiring Changes
|
|
39
|
+
|
|
40
|
+
For each file that needs modification:
|
|
41
|
+
- **Path**: \`path/to/file\`
|
|
42
|
+
- **Change Type**: [Create New | Modify Existing | Delete]
|
|
43
|
+
- **Reason**: [Why this file needs to change]
|
|
44
|
+
- **Specific Changes**: [What aspects need modification]
|
|
45
|
+
- **Dependencies**: [What other changes must happen first]
|
|
46
|
+
|
|
47
|
+
### Testing Strategy
|
|
48
|
+
- **Test Files to Modify**: [Existing test files that need updates]
|
|
49
|
+
- **New Tests Needed**: [New test files or test cases required]
|
|
50
|
+
- **Test Scenarios**: [Specific scenarios to cover: happy path, edge cases, error handling]
|
|
51
|
+
|
|
52
|
+
### Additional Context
|
|
53
|
+
- **Relevant Patterns**: [Existing code patterns to follow for consistency]
|
|
54
|
+
- **Potential Risks**: [Things to watch out for, breaking changes]
|
|
55
|
+
- **Performance Considerations**: [If applicable]
|
|
56
|
+
- **Security Implications**: [If applicable]
|
|
57
|
+
|
|
58
|
+
## Quality Standards
|
|
59
|
+
- Be SPECIFIC about file paths (e.g., \`src/core/story.ts:42\` not just "the story module")
|
|
60
|
+
- Reference existing patterns when suggesting new code
|
|
61
|
+
- Identify at least 3-5 relevant files in the codebase
|
|
62
|
+
- Provide concrete examples, not abstract concepts
|
|
63
|
+
- If you cannot find relevant code, say so explicitly`;
|
|
64
|
+
/**
|
|
65
|
+
* Keywords that indicate a story is purely internal and does not require web research.
|
|
66
|
+
* These keywords suggest refactoring, code organization, or internal maintenance tasks.
|
|
67
|
+
*/
|
|
68
|
+
const WEB_RESEARCH_INTERNAL_KEYWORDS = [
|
|
69
|
+
'refactor internal',
|
|
70
|
+
'move function',
|
|
71
|
+
'rename variable',
|
|
72
|
+
'rename function',
|
|
73
|
+
'move utility',
|
|
74
|
+
'internal refactor',
|
|
75
|
+
'move code',
|
|
76
|
+
'reorganize internal',
|
|
77
|
+
];
|
|
78
|
+
/**
|
|
79
|
+
* Keywords that indicate external dependencies or integrations requiring web research.
|
|
80
|
+
* These keywords suggest the need for library documentation, API references, or best practices.
|
|
81
|
+
*/
|
|
82
|
+
const WEB_RESEARCH_EXTERNAL_KEYWORDS = [
|
|
83
|
+
'integrate',
|
|
84
|
+
'api',
|
|
85
|
+
'library',
|
|
86
|
+
'framework',
|
|
87
|
+
'best practices',
|
|
88
|
+
'npm package',
|
|
89
|
+
'external',
|
|
90
|
+
'third-party',
|
|
91
|
+
'sdk',
|
|
92
|
+
'documentation',
|
|
93
|
+
'webhook',
|
|
94
|
+
'rest api',
|
|
95
|
+
'graphql',
|
|
96
|
+
'oauth',
|
|
97
|
+
'authentication provider',
|
|
98
|
+
];
|
|
99
|
+
/**
|
|
100
|
+
* Web research prompt template for supplementary research phase.
|
|
101
|
+
* Instructs the agent on tool usage, FAR evaluation, and output formatting.
|
|
102
|
+
*/
|
|
103
|
+
const WEB_RESEARCH_PROMPT_TEMPLATE = (storyTitle, storyContent, codebaseContext) => `You are performing supplementary web research for a software development story.
|
|
104
|
+
|
|
105
|
+
**Story Title**: ${storyTitle}
|
|
106
|
+
|
|
107
|
+
**Story Content**:
|
|
108
|
+
${storyContent}
|
|
109
|
+
|
|
110
|
+
**Codebase Context** (already analyzed):
|
|
111
|
+
${codebaseContext}... [truncated]
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Web Research Instructions
|
|
116
|
+
|
|
117
|
+
You have access to these web research tools:
|
|
118
|
+
|
|
119
|
+
1. **Context7** (if available) - Use FIRST for library/framework documentation
|
|
120
|
+
- Best for: npm packages, Python libraries, popular frameworks
|
|
121
|
+
- Example: "Search Context7 for React Query documentation on data fetching"
|
|
122
|
+
|
|
123
|
+
2. **WebSearch** - Use for community knowledge and best practices
|
|
124
|
+
- Best for: Stack Overflow patterns, blog posts, tutorials
|
|
125
|
+
- Example: "Search the web for TypeScript error handling best practices"
|
|
126
|
+
|
|
127
|
+
3. **WebFetch** - Use to read specific authoritative URLs
|
|
128
|
+
- Best for: Official documentation, specific articles
|
|
129
|
+
- Example: "Fetch https://docs.anthropic.com/claude/reference"
|
|
130
|
+
|
|
131
|
+
## Research Strategy
|
|
132
|
+
|
|
133
|
+
- Try Context7 FIRST for any npm packages or popular frameworks mentioned in the story
|
|
134
|
+
- Fall back to WebSearch for general solutions and community patterns
|
|
135
|
+
- Use WebFetch only when you have specific authoritative URLs to read
|
|
136
|
+
- Limit research to 3-5 high-quality sources to avoid information overload
|
|
137
|
+
- Focus on actionable information that directly addresses the story requirements
|
|
138
|
+
|
|
139
|
+
## Output Format
|
|
140
|
+
|
|
141
|
+
For EACH finding, provide:
|
|
142
|
+
|
|
143
|
+
### [Topic Name]
|
|
144
|
+
**Source**: [Context7 - Library Name] or [Web Search Result] or [URL]
|
|
145
|
+
**FAR Score**: Factuality: [1-5], Actionability: [1-5], Relevance: [1-5]
|
|
146
|
+
**Justification**: [Why these scores? How does this help the story?]
|
|
147
|
+
|
|
148
|
+
[Finding content with code examples, patterns, or instructions]
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## FAR Scale Definitions
|
|
153
|
+
|
|
154
|
+
**Factuality (1-5)**: How accurate and verifiable is the information?
|
|
155
|
+
- 1: Unverified/speculative
|
|
156
|
+
- 3: Community knowledge (Stack Overflow, blogs)
|
|
157
|
+
- 5: Official documentation or peer-reviewed
|
|
158
|
+
|
|
159
|
+
**Actionability (1-5)**: Can this be directly applied to the task?
|
|
160
|
+
- 1: Abstract concepts only
|
|
161
|
+
- 3: General patterns or approaches
|
|
162
|
+
- 5: Copy-paste code examples or step-by-step instructions
|
|
163
|
+
|
|
164
|
+
**Relevance (1-5)**: How closely does this match the story requirements?
|
|
165
|
+
- 1: Tangentially related
|
|
166
|
+
- 3: Related but not specific to story
|
|
167
|
+
- 5: Directly addresses a story acceptance criterion
|
|
168
|
+
|
|
169
|
+
## Important Notes
|
|
170
|
+
|
|
171
|
+
- If web tools are unavailable (offline, not configured), simply state: "Web research tools unavailable - skipping web research"
|
|
172
|
+
- If a finding contradicts patterns in the codebase context, note the discrepancy and defer to local patterns
|
|
173
|
+
- Focus on NEW information not already present in codebase analysis
|
|
174
|
+
|
|
175
|
+
Begin web research now. Provide 3-5 high-quality findings with FAR evaluations.`;
|
|
16
176
|
/**
|
|
17
177
|
* Research Agent
|
|
18
178
|
*
|
|
@@ -25,6 +185,8 @@ export async function runResearchAgent(storyPath, sdlcRoot, options = {}) {
|
|
|
25
185
|
try {
|
|
26
186
|
// Gather codebase context
|
|
27
187
|
const codebaseContext = await gatherCodebaseContext(sdlcRoot);
|
|
188
|
+
// Sanitize codebase context before including in prompt (prevent prompt injection)
|
|
189
|
+
const sanitizedContext = sanitizeCodebaseContext(codebaseContext);
|
|
28
190
|
// Build the prompt, including rework context if this is a refinement iteration
|
|
29
191
|
let prompt = `Please research how to implement this story:
|
|
30
192
|
|
|
@@ -34,7 +196,7 @@ Story content:
|
|
|
34
196
|
${story.content}
|
|
35
197
|
|
|
36
198
|
Codebase context:
|
|
37
|
-
${
|
|
199
|
+
${sanitizedContext}`;
|
|
38
200
|
if (options.reworkContext) {
|
|
39
201
|
prompt += `
|
|
40
202
|
|
|
@@ -62,11 +224,33 @@ Format your response as markdown for the Research section of the story.`;
|
|
|
62
224
|
workingDirectory: path.dirname(sdlcRoot),
|
|
63
225
|
onProgress: options.onProgress,
|
|
64
226
|
});
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
227
|
+
// Sanitize research content before storage (prevent ANSI/markdown injection)
|
|
228
|
+
const sanitizedResearch = sanitizeWebResearchContent(researchContent);
|
|
229
|
+
// Append codebase research to the story
|
|
230
|
+
await appendToSection(story, 'Research', sanitizedResearch);
|
|
231
|
+
changesMade.push('Added codebase research findings');
|
|
232
|
+
// Phase 2: Web Research (conditional)
|
|
233
|
+
if (shouldPerformWebResearch(story, sanitizedContext)) {
|
|
234
|
+
const webResearchContent = await performWebResearch(story, sanitizedContext, path.dirname(sdlcRoot), options.onProgress);
|
|
235
|
+
if (webResearchContent.trim()) {
|
|
236
|
+
// Sanitize web research content before storage (prevent ANSI/markdown injection)
|
|
237
|
+
const sanitizedWebResearch = sanitizeWebResearchContent(webResearchContent);
|
|
238
|
+
// Re-parse story to get updated content after codebase research
|
|
239
|
+
const updatedStory = parseStory(storyPath);
|
|
240
|
+
await appendToSection(updatedStory, 'Research', '\n## Web Research Findings\n\n' + sanitizedWebResearch);
|
|
241
|
+
changesMade.push('Added web research findings');
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
getLogger().info('web-research', 'Web research returned empty - tools may be unavailable');
|
|
245
|
+
changesMade.push('Web research skipped: tools unavailable');
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
changesMade.push('Web research skipped: no external dependencies detected');
|
|
250
|
+
}
|
|
251
|
+
// Mark research as complete - re-parse to get latest content including web research
|
|
252
|
+
const finalStory = parseStory(storyPath);
|
|
253
|
+
await updateStoryField(finalStory, 'research_complete', true);
|
|
70
254
|
changesMade.push('Marked research_complete: true');
|
|
71
255
|
return {
|
|
72
256
|
success: true,
|
|
@@ -84,9 +268,19 @@ Format your response as markdown for the Research section of the story.`;
|
|
|
84
268
|
}
|
|
85
269
|
}
|
|
86
270
|
/**
|
|
87
|
-
* Gather context about the codebase for research
|
|
271
|
+
* Gather context about the codebase for research.
|
|
272
|
+
*
|
|
273
|
+
* Collects information about:
|
|
274
|
+
* - Project configuration files (package.json, tsconfig.json, etc.)
|
|
275
|
+
* - Directory structure
|
|
276
|
+
* - Source files
|
|
277
|
+
* - Test files (for understanding testing patterns)
|
|
278
|
+
* - Configuration files (for discovering config patterns)
|
|
279
|
+
*
|
|
280
|
+
* @param sdlcRoot - Path to the .ai-sdlc directory
|
|
281
|
+
* @returns Formatted context string with codebase information
|
|
88
282
|
*/
|
|
89
|
-
async function gatherCodebaseContext(sdlcRoot) {
|
|
283
|
+
export async function gatherCodebaseContext(sdlcRoot) {
|
|
90
284
|
const workingDir = path.dirname(sdlcRoot);
|
|
91
285
|
const context = [];
|
|
92
286
|
// Check for common project files
|
|
@@ -136,6 +330,302 @@ async function gatherCodebaseContext(sdlcRoot) {
|
|
|
136
330
|
catch {
|
|
137
331
|
// Ignore glob errors
|
|
138
332
|
}
|
|
333
|
+
// Look for test files (helps identify testing patterns)
|
|
334
|
+
try {
|
|
335
|
+
const testFiles = await glob('**/*.test.{ts,js,tsx,jsx}', {
|
|
336
|
+
cwd: workingDir,
|
|
337
|
+
ignore: ['node_modules/**', 'dist/**', 'build/**'],
|
|
338
|
+
});
|
|
339
|
+
// Also look for tests in dedicated test directories
|
|
340
|
+
const testDirFiles = await glob('{tests,test,__tests__}/**/*.{ts,js,tsx,jsx}', {
|
|
341
|
+
cwd: workingDir,
|
|
342
|
+
ignore: ['node_modules/**'],
|
|
343
|
+
});
|
|
344
|
+
const allTestFiles = [...new Set([...testFiles, ...testDirFiles])];
|
|
345
|
+
if (allTestFiles.length > 0) {
|
|
346
|
+
context.push(`=== Test Files ===\n${allTestFiles.slice(0, 15).join('\n')}`);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
// Ignore glob errors
|
|
351
|
+
}
|
|
352
|
+
// Look for configuration files (helps identify config patterns)
|
|
353
|
+
try {
|
|
354
|
+
const configFiles = await glob('**/*.config.{ts,js,json,mjs,cjs}', {
|
|
355
|
+
cwd: workingDir,
|
|
356
|
+
ignore: ['node_modules/**', 'dist/**'],
|
|
357
|
+
});
|
|
358
|
+
// Also look for common config file patterns
|
|
359
|
+
const commonConfigs = await glob('{.eslintrc*,.prettierrc*,jest.config.*,vitest.config.*,vite.config.*}', {
|
|
360
|
+
cwd: workingDir,
|
|
361
|
+
dot: true,
|
|
362
|
+
});
|
|
363
|
+
const allConfigFiles = [...new Set([...configFiles, ...commonConfigs])];
|
|
364
|
+
if (allConfigFiles.length > 0) {
|
|
365
|
+
context.push(`=== Config Files ===\n${allConfigFiles.slice(0, 10).join('\n')}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
catch {
|
|
369
|
+
// Ignore glob errors
|
|
370
|
+
}
|
|
139
371
|
return context.join('\n\n') || 'No codebase context available.';
|
|
140
372
|
}
|
|
373
|
+
/**
|
|
374
|
+
* Determine if web research would add value based on story content and codebase context.
|
|
375
|
+
*
|
|
376
|
+
* Web research is triggered when:
|
|
377
|
+
* 1. External dependencies are referenced (libraries, APIs, frameworks)
|
|
378
|
+
* 2. Unfamiliar APIs/patterns are mentioned
|
|
379
|
+
* 3. Library-specific documentation is needed
|
|
380
|
+
* 4. Best practices are requested
|
|
381
|
+
*
|
|
382
|
+
* Web research is skipped when:
|
|
383
|
+
* - Topic is purely internal (refactoring, moving code, internal utilities)
|
|
384
|
+
* - No external dependencies mentioned
|
|
385
|
+
*/
|
|
386
|
+
export function shouldPerformWebResearch(story, codebaseContext) {
|
|
387
|
+
const content = story.content.toLowerCase();
|
|
388
|
+
const title = story.frontmatter.title.toLowerCase();
|
|
389
|
+
const combinedText = `${title} ${content}`;
|
|
390
|
+
// Skip if purely internal keywords are dominant
|
|
391
|
+
for (const keyword of WEB_RESEARCH_INTERNAL_KEYWORDS) {
|
|
392
|
+
if (combinedText.includes(keyword)) {
|
|
393
|
+
// Sanitize keyword for logging (prevent log injection)
|
|
394
|
+
getLogger().info('web-research', `Skipping web research: purely internal topic detected (${sanitizeForLogging(keyword)})`);
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
// Trigger if external library/API/framework mentioned
|
|
399
|
+
for (const keyword of WEB_RESEARCH_EXTERNAL_KEYWORDS) {
|
|
400
|
+
if (combinedText.includes(keyword)) {
|
|
401
|
+
// Sanitize keyword for logging (prevent log injection)
|
|
402
|
+
getLogger().info('web-research', `Web research triggered: external keyword detected (${sanitizeForLogging(keyword)})`);
|
|
403
|
+
return true;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
// Check for package.json mentions (suggests npm dependencies)
|
|
407
|
+
if (codebaseContext.includes('package.json') &&
|
|
408
|
+
(combinedText.includes('npm') || combinedText.includes('install') || combinedText.includes('dependency'))) {
|
|
409
|
+
getLogger().info('web-research', 'Web research triggered: npm dependency context detected');
|
|
410
|
+
return true;
|
|
411
|
+
}
|
|
412
|
+
// Default: skip web research for codebase-only topics
|
|
413
|
+
getLogger().info('web-research', 'Skipping web research: no external dependencies detected');
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Maximum input length to prevent DoS attacks.
|
|
418
|
+
* Set to 10,000 chars to accommodate long research findings
|
|
419
|
+
* while preventing memory exhaustion from malicious inputs.
|
|
420
|
+
*/
|
|
421
|
+
const MAX_INPUT_LENGTH = 10000;
|
|
422
|
+
/**
|
|
423
|
+
* Maximum log string length for readability and security.
|
|
424
|
+
* Prevents log injection and maintains log file readability.
|
|
425
|
+
*/
|
|
426
|
+
const MAX_LOG_LENGTH = 200;
|
|
427
|
+
/**
|
|
428
|
+
* Sanitize web research content for safe storage and display.
|
|
429
|
+
* Removes ANSI escape sequences, control characters, and potential injection vectors.
|
|
430
|
+
*
|
|
431
|
+
* Security rationale: Web research content comes from external sources (LLM, web tools)
|
|
432
|
+
* and must be sanitized before storage to prevent:
|
|
433
|
+
* - ANSI injection (terminal control sequence attacks)
|
|
434
|
+
* - Markdown injection (malicious formatting)
|
|
435
|
+
* - Control character injection (null bytes, bell characters, etc.)
|
|
436
|
+
*
|
|
437
|
+
* @param text - Raw web research content from external source
|
|
438
|
+
* @returns Sanitized text safe for storage in markdown files
|
|
439
|
+
*/
|
|
440
|
+
export function sanitizeWebResearchContent(text) {
|
|
441
|
+
if (!text)
|
|
442
|
+
return '';
|
|
443
|
+
// Enforce maximum length to prevent DoS
|
|
444
|
+
if (text.length > MAX_INPUT_LENGTH) {
|
|
445
|
+
text = text.substring(0, MAX_INPUT_LENGTH);
|
|
446
|
+
}
|
|
447
|
+
// Remove ANSI CSI sequences (colors, cursor movement) - e.g., \x1B[31m
|
|
448
|
+
text = text.replace(/\x1B\[[^a-zA-Z\x1B]*[a-zA-Z]?/g, '');
|
|
449
|
+
// Remove OSC sequences (hyperlinks, window titles) - terminated by BEL (\x07) or ST (\x1B\\)
|
|
450
|
+
text = text.replace(/\x1B\][^\x07]*\x07/g, '');
|
|
451
|
+
text = text.replace(/\x1B\][^\x1B]*\x1B\\/g, '');
|
|
452
|
+
// Remove any remaining standalone escape characters
|
|
453
|
+
text = text.replace(/\x1B/g, '');
|
|
454
|
+
// Remove control characters (0x00-0x08, 0x0B-0x0C, 0x0E-0x1F, 0x7F-0x9F)
|
|
455
|
+
// eslint-disable-next-line no-control-regex
|
|
456
|
+
text = text.replace(/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F-\x9F]/g, '');
|
|
457
|
+
// Normalize Unicode to prevent homograph attacks and ensure consistent representation
|
|
458
|
+
text = text.normalize('NFC');
|
|
459
|
+
// Validate markdown structure - escape dangerous patterns
|
|
460
|
+
// Triple backticks could be used to break out of code blocks
|
|
461
|
+
text = text.replace(/```/g, '\\`\\`\\`');
|
|
462
|
+
return text;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Sanitize text for logging to prevent log injection attacks.
|
|
466
|
+
* Replaces newlines with spaces and truncates for readability.
|
|
467
|
+
*
|
|
468
|
+
* Security rationale: Log injection attacks use newlines to inject fake log entries.
|
|
469
|
+
* By replacing newlines with spaces, we ensure each log() call produces exactly one log line.
|
|
470
|
+
*
|
|
471
|
+
* @param text - Raw text that will be logged
|
|
472
|
+
* @returns Sanitized text safe for logging (single line, truncated)
|
|
473
|
+
*/
|
|
474
|
+
export function sanitizeForLogging(text) {
|
|
475
|
+
if (!text)
|
|
476
|
+
return '';
|
|
477
|
+
// Remove ANSI escape sequences
|
|
478
|
+
text = text.replace(/\x1B\[[^a-zA-Z\x1B]*[a-zA-Z]?/g, '');
|
|
479
|
+
text = text.replace(/\x1B\][^\x07]*\x07/g, '');
|
|
480
|
+
text = text.replace(/\x1B\][^\x1B]*\x1B\\/g, '');
|
|
481
|
+
text = text.replace(/\x1B/g, '');
|
|
482
|
+
// Replace newlines and carriage returns with spaces to prevent log injection
|
|
483
|
+
text = text.replace(/[\n\r]/g, ' ');
|
|
484
|
+
// Truncate to reasonable length for logs
|
|
485
|
+
if (text.length > MAX_LOG_LENGTH) {
|
|
486
|
+
text = text.substring(0, MAX_LOG_LENGTH) + '...';
|
|
487
|
+
}
|
|
488
|
+
return text.trim();
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Sanitize codebase context before including in LLM prompts.
|
|
492
|
+
* Escapes dangerous patterns that could cause prompt injection.
|
|
493
|
+
*
|
|
494
|
+
* Security rationale: Codebase files may contain malicious content from:
|
|
495
|
+
* - Compromised dependencies
|
|
496
|
+
* - Malicious commits
|
|
497
|
+
* - Untrusted contributors
|
|
498
|
+
*
|
|
499
|
+
* We must prevent prompt injection by escaping patterns that could:
|
|
500
|
+
* - Terminate the prompt early (triple backticks)
|
|
501
|
+
* - Inject commands or instructions
|
|
502
|
+
* - Confuse the LLM's understanding of structure
|
|
503
|
+
*
|
|
504
|
+
* @param text - Raw codebase context
|
|
505
|
+
* @returns Sanitized text safe for LLM prompts
|
|
506
|
+
*/
|
|
507
|
+
export function sanitizeCodebaseContext(text) {
|
|
508
|
+
if (!text)
|
|
509
|
+
return '';
|
|
510
|
+
// Remove ANSI escape sequences
|
|
511
|
+
text = text.replace(/\x1B\[[^a-zA-Z\x1B]*[a-zA-Z]?/g, '');
|
|
512
|
+
text = text.replace(/\x1B\][^\x07]*\x07/g, '');
|
|
513
|
+
text = text.replace(/\x1B\][^\x1B]*\x1B\\/g, '');
|
|
514
|
+
text = text.replace(/\x1B/g, '');
|
|
515
|
+
// Escape triple backticks to prevent breaking out of code blocks
|
|
516
|
+
text = text.replace(/```/g, '\\`\\`\\`');
|
|
517
|
+
// Validate UTF-8 boundaries at truncation points
|
|
518
|
+
// If we need to truncate, ensure we don't split multi-byte characters
|
|
519
|
+
if (text.length > MAX_INPUT_LENGTH) {
|
|
520
|
+
// Use substring which is UTF-16 safe, then validate
|
|
521
|
+
let truncated = text.substring(0, MAX_INPUT_LENGTH);
|
|
522
|
+
// Check if we split a surrogate pair (0xD800-0xDFFF)
|
|
523
|
+
const lastCharCode = truncated.charCodeAt(truncated.length - 1);
|
|
524
|
+
if (lastCharCode >= 0xD800 && lastCharCode <= 0xDFFF) {
|
|
525
|
+
// We split a surrogate pair, remove the incomplete character
|
|
526
|
+
truncated = truncated.substring(0, truncated.length - 1);
|
|
527
|
+
}
|
|
528
|
+
text = truncated;
|
|
529
|
+
}
|
|
530
|
+
return text;
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Parse FAR evaluation from web research finding text.
|
|
534
|
+
* Expected format from LLM:
|
|
535
|
+
* **FAR Score**: Factuality: 5, Actionability: 4, Relevance: 5
|
|
536
|
+
* **Justification**: Official documentation provides...
|
|
537
|
+
*
|
|
538
|
+
* Returns default scores (2, 2, 2) with parsingSucceeded: false if parsing fails.
|
|
539
|
+
* Default of 2 (rather than 3) indicates uncertainty rather than average quality.
|
|
540
|
+
*
|
|
541
|
+
* @param finding - Web research finding text to parse
|
|
542
|
+
* @returns FARScore with parsed or default values and parsing status
|
|
543
|
+
*/
|
|
544
|
+
export function evaluateFAR(finding) {
|
|
545
|
+
// Enforce maximum length to prevent ReDoS attacks
|
|
546
|
+
if (finding.length > MAX_INPUT_LENGTH) {
|
|
547
|
+
finding = finding.substring(0, MAX_INPUT_LENGTH);
|
|
548
|
+
}
|
|
549
|
+
try {
|
|
550
|
+
// Look for FAR score pattern
|
|
551
|
+
const scoreMatch = finding.match(/\*\*FAR Score\*\*:.*?Factuality:\s*(\d+).*?Actionability:\s*(\d+).*?Relevance:\s*(\d+)/i);
|
|
552
|
+
const justificationMatch = finding.match(/\*\*Justification\*\*:\s*(.+?)(?:\n\n|\n#|$)/is);
|
|
553
|
+
if (scoreMatch && justificationMatch) {
|
|
554
|
+
const factuality = parseInt(scoreMatch[1], 10);
|
|
555
|
+
const actionability = parseInt(scoreMatch[2], 10);
|
|
556
|
+
const relevance = parseInt(scoreMatch[3], 10);
|
|
557
|
+
const justification = justificationMatch[1].trim();
|
|
558
|
+
// Validate scores are in range 1-5
|
|
559
|
+
if ([factuality, actionability, relevance].every(s => s >= 1 && s <= 5)) {
|
|
560
|
+
return {
|
|
561
|
+
factuality,
|
|
562
|
+
actionability,
|
|
563
|
+
relevance,
|
|
564
|
+
justification,
|
|
565
|
+
parsingSucceeded: true,
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
getLogger().warn('web-research', 'FAR scores out of valid range (1-5), using defaults');
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
else if (scoreMatch && !justificationMatch) {
|
|
573
|
+
getLogger().warn('web-research', 'FAR justification missing, using defaults');
|
|
574
|
+
}
|
|
575
|
+
else if (!scoreMatch && justificationMatch) {
|
|
576
|
+
getLogger().warn('web-research', 'FAR scores not found in finding, using defaults');
|
|
577
|
+
}
|
|
578
|
+
else {
|
|
579
|
+
getLogger().warn('web-research', 'FAR scores and justification not found in finding, using defaults');
|
|
580
|
+
}
|
|
581
|
+
// If parsing failed, return default scores (2/5 indicates uncertainty)
|
|
582
|
+
return {
|
|
583
|
+
factuality: 2,
|
|
584
|
+
actionability: 2,
|
|
585
|
+
relevance: 2,
|
|
586
|
+
justification: 'FAR scores could not be parsed from finding. Default scores (2/5) applied.',
|
|
587
|
+
parsingSucceeded: false,
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
catch (error) {
|
|
591
|
+
getLogger().error('web-research', 'Error parsing FAR scores', { error });
|
|
592
|
+
return {
|
|
593
|
+
factuality: 2,
|
|
594
|
+
actionability: 2,
|
|
595
|
+
relevance: 2,
|
|
596
|
+
justification: 'Error parsing FAR evaluation',
|
|
597
|
+
parsingSucceeded: false,
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Perform web research using Context7/WebSearch/WebFetch.
|
|
603
|
+
* Returns formatted markdown with FAR evaluations, or empty string if all tools unavailable.
|
|
604
|
+
*/
|
|
605
|
+
async function performWebResearch(story, codebaseContext, workingDir, onProgress) {
|
|
606
|
+
const logger = getLogger();
|
|
607
|
+
logger.info('web-research', 'Starting web research phase', { storyId: story.frontmatter.id });
|
|
608
|
+
try {
|
|
609
|
+
const sanitizedContext = sanitizeCodebaseContext(codebaseContext.substring(0, 2000));
|
|
610
|
+
const webResearchPrompt = WEB_RESEARCH_PROMPT_TEMPLATE(story.frontmatter.title, story.content, sanitizedContext);
|
|
611
|
+
const webResearchResult = await runAgentQuery({
|
|
612
|
+
prompt: webResearchPrompt,
|
|
613
|
+
systemPrompt: 'You are a web research specialist. Use available tools to find authoritative documentation and best practices.',
|
|
614
|
+
workingDirectory: workingDir,
|
|
615
|
+
onProgress,
|
|
616
|
+
});
|
|
617
|
+
// Check if web tools were unavailable
|
|
618
|
+
if (webResearchResult.toLowerCase().includes('web research tools unavailable')) {
|
|
619
|
+
logger.info('web-research', 'Web research tools unavailable, skipping');
|
|
620
|
+
return '';
|
|
621
|
+
}
|
|
622
|
+
logger.info('web-research', 'Web research completed successfully');
|
|
623
|
+
return webResearchResult;
|
|
624
|
+
}
|
|
625
|
+
catch (error) {
|
|
626
|
+
logger.error('web-research', 'Web research failed', { error });
|
|
627
|
+
// Gracefully degrade - return empty string to continue with codebase-only research
|
|
628
|
+
return '';
|
|
629
|
+
}
|
|
630
|
+
}
|
|
141
631
|
//# sourceMappingURL=research.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"research.js","sourceRoot":"","sources":["../../src/agents/research.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAc,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAyB,MAAM,mBAAmB,CAAC;AAGzE,MAAM,sBAAsB,GAAG;;;;;;;;;kGASmE,CAAC;AASnG;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAiB,EACjB,QAAgB,EAChB,UAAwB,EAAE;IAE1B,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,IAAI,CAAC;QACH,0BAA0B;QAC1B,MAAM,eAAe,GAAG,MAAM,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAE9D,+EAA+E;QAC/E,IAAI,MAAM,GAAG;;SAER,KAAK,CAAC,WAAW,CAAC,KAAK;;;EAG9B,KAAK,CAAC,OAAO;;;EAGb,eAAe,EAAE,CAAC;QAEhB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;YAC1B,MAAM,IAAI;;;EAGd,OAAO,CAAC,aAAa;;;;;kDAK2B,CAAC;QAC/C,CAAC;QAED,MAAM,IAAI;;;;;;;;;wEAS0D,CAAC;QAErE,MAAM,eAAe,GAAG,MAAM,aAAa,CAAC;YAC1C,MAAM;YACN,YAAY,EAAE,sBAAsB;YACpC,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YACxC,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC,CAAC;QAEH,+BAA+B;QAC/B,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;QACpD,WAAW,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAE5C,4BAA4B;QAC5B,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC;QACnD,WAAW,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAEnD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,iCAAiC;YAC/D,WAAW;SACZ,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK;YACL,WAAW;YACX,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,qBAAqB,CAAC,QAAgB;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,iCAAiC;IACjC,MAAM,YAAY,GAAG;QACnB,cAAc;QACd,eAAe;QACf,gBAAgB;QAChB,YAAY;QACZ,QAAQ;KACT,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC7C,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACnD,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,SAAS,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YACjE,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,OAAO;aACjB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC;aACpF,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,KAAK,GAAG,OAAO;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;aAClD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEpB,OAAO,CAAC,IAAI,CAAC,6CAA6C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3G,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;IAED,wBAAwB;IACxB,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,2BAA2B,EAAE;YAC1D,GAAG,EAAE,UAAU;YACf,MAAM,EAAE,CAAC,iBAAiB,EAAE,SAAS,EAAE,UAAU,CAAC;SACnD,CAAC,CAAC;QAEH,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,yBAAyB,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qBAAqB;IACvB,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,gCAAgC,CAAC;AAClE,CAAC"}
|
|
1
|
+
{"version":3,"file":"research.js","sourceRoot":"","sources":["../../src/agents/research.ts"],"names":[],"mappings":"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"}
|