sieveai 0.1.0
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/LICENSE +21 -0
- package/README.md +164 -0
- package/dist/agents/base-agent.d.ts +14 -0
- package/dist/agents/base-agent.d.ts.map +1 -0
- package/dist/agents/base-agent.js +114 -0
- package/dist/agents/base-agent.js.map +1 -0
- package/dist/agents/bug-agent.d.ts +6 -0
- package/dist/agents/bug-agent.d.ts.map +1 -0
- package/dist/agents/bug-agent.js +6 -0
- package/dist/agents/bug-agent.js.map +1 -0
- package/dist/agents/security-agent.d.ts +6 -0
- package/dist/agents/security-agent.d.ts.map +1 -0
- package/dist/agents/security-agent.js +6 -0
- package/dist/agents/security-agent.js.map +1 -0
- package/dist/agents/style-agent.d.ts +6 -0
- package/dist/agents/style-agent.d.ts.map +1 -0
- package/dist/agents/style-agent.js +6 -0
- package/dist/agents/style-agent.js.map +1 -0
- package/dist/cache/database.d.ts +26 -0
- package/dist/cache/database.d.ts.map +1 -0
- package/dist/cache/database.js +199 -0
- package/dist/cache/database.js.map +1 -0
- package/dist/cache/manager.d.ts +27 -0
- package/dist/cache/manager.d.ts.map +1 -0
- package/dist/cache/manager.js +105 -0
- package/dist/cache/manager.js.map +1 -0
- package/dist/cli/commands/check.d.ts +14 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +73 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +23 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/defaults.d.ts +3 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +18 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/loader.d.ts +11 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +78 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +67 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +34 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/git/diff-parser.d.ts +22 -0
- package/dist/git/diff-parser.d.ts.map +1 -0
- package/dist/git/diff-parser.js +151 -0
- package/dist/git/diff-parser.js.map +1 -0
- package/dist/git/repository.d.ts +28 -0
- package/dist/git/repository.d.ts.map +1 -0
- package/dist/git/repository.js +155 -0
- package/dist/git/repository.js.map +1 -0
- package/dist/llm/client.d.ts +27 -0
- package/dist/llm/client.d.ts.map +1 -0
- package/dist/llm/client.js +90 -0
- package/dist/llm/client.js.map +1 -0
- package/dist/llm/prompts.d.ts +14 -0
- package/dist/llm/prompts.d.ts.map +1 -0
- package/dist/llm/prompts.js +110 -0
- package/dist/llm/prompts.js.map +1 -0
- package/dist/llm/providers/ollama.d.ts +17 -0
- package/dist/llm/providers/ollama.d.ts.map +1 -0
- package/dist/llm/providers/ollama.js +165 -0
- package/dist/llm/providers/ollama.js.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts +20 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator.js +164 -0
- package/dist/orchestrator/orchestrator.js.map +1 -0
- package/dist/reporters/json-reporter.d.ts +3 -0
- package/dist/reporters/json-reporter.d.ts.map +1 -0
- package/dist/reporters/json-reporter.js +4 -0
- package/dist/reporters/json-reporter.js.map +1 -0
- package/dist/reporters/text-reporter.d.ts +6 -0
- package/dist/reporters/text-reporter.d.ts.map +1 -0
- package/dist/reporters/text-reporter.js +129 -0
- package/dist/reporters/text-reporter.js.map +1 -0
- package/dist/static/secrets.d.ts +3 -0
- package/dist/static/secrets.d.ts.map +1 -0
- package/dist/static/secrets.js +106 -0
- package/dist/static/secrets.js.map +1 -0
- package/dist/types/index.d.ts +155 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +36 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/errors.d.ts +13 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +61 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/hash.d.ts +5 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +18 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/index.d.ts +11 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +64 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +21 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +53 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SieveAi Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# SieveAi
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
**Local-first AI code review CLI/TUI with hybrid static+AI analysis**
|
|
12
|
+
|
|
13
|
+
SieveAi is an open-source code review tool that combines static analysis with local LLM-powered insights. Review your code privately without sending it to external servers.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- 🔒 **Local-first**: Code never leaves your machine (uses Ollama by default)
|
|
18
|
+
- 🤖 **Hybrid Analysis**: Combines static patterns with AI reasoning
|
|
19
|
+
- ⚡ **Fast & Incremental**: SQLite-based caching for speed
|
|
20
|
+
- 🎯 **Confidence Filtering**: Only show high-confidence findings (default ≥78%)
|
|
21
|
+
- 🔍 **Multiple Agents**: Bug detection, security analysis, style/maintainability
|
|
22
|
+
- 📊 **Rich Output**: Text, JSON, or TUI formats
|
|
23
|
+
- 🧠 **Learning System**: Reduce false positives over time
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### Prerequisites
|
|
28
|
+
|
|
29
|
+
1. **Node.js 20+**
|
|
30
|
+
2. **Ollama** (for local LLM)
|
|
31
|
+
```bash
|
|
32
|
+
# Install Ollama: https://ollama.ai
|
|
33
|
+
# Pull default model
|
|
34
|
+
ollama pull glm-4.7
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install -g sieveai
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Usage
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Review current changes
|
|
47
|
+
sieveai check
|
|
48
|
+
|
|
49
|
+
# Review staged changes only
|
|
50
|
+
git add .
|
|
51
|
+
sieveai check
|
|
52
|
+
|
|
53
|
+
# Compare branches
|
|
54
|
+
sieveai check --base main --target feature-branch
|
|
55
|
+
|
|
56
|
+
# Output as JSON
|
|
57
|
+
sieveai check --format json
|
|
58
|
+
|
|
59
|
+
# Use different model
|
|
60
|
+
sieveai check --model ollama:llama3.3
|
|
61
|
+
|
|
62
|
+
# Adjust confidence threshold
|
|
63
|
+
sieveai check --min-confidence 85
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Configuration
|
|
67
|
+
|
|
68
|
+
Create `.sieveai.config.json` in your project root:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"model": "ollama:glm-4.7",
|
|
73
|
+
"minConfidence": 78,
|
|
74
|
+
"enableCache": true,
|
|
75
|
+
"enableSecretScanning": true,
|
|
76
|
+
"parallel": true,
|
|
77
|
+
"format": "text",
|
|
78
|
+
"verbose": false,
|
|
79
|
+
"showRationale": true
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Architecture
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
CLI → Git Diff → Static Analysis → AI Agents (parallel) → Filter → Cache → Report
|
|
87
|
+
↓ ↓
|
|
88
|
+
Secret Scanner Bug/Security/Style
|
|
89
|
+
(Ollama/Local LLM)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Development
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Clone repository
|
|
96
|
+
git clone https://github.com/yourusername/sieveai
|
|
97
|
+
cd sieveai
|
|
98
|
+
|
|
99
|
+
# Install dependencies
|
|
100
|
+
npm install
|
|
101
|
+
|
|
102
|
+
# Build
|
|
103
|
+
npm run build
|
|
104
|
+
|
|
105
|
+
# Run locally
|
|
106
|
+
./dist/cli/index.js check
|
|
107
|
+
|
|
108
|
+
# Run tests
|
|
109
|
+
npm test
|
|
110
|
+
|
|
111
|
+
# Lint/format
|
|
112
|
+
npm run lint:fix
|
|
113
|
+
npm run format
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
For a complete step-by-step guide (clone → build → test → publish), see [docs/SETUP_BUILD.md](docs/SETUP_BUILD.md).
|
|
117
|
+
|
|
118
|
+
## Project Structure
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
src/
|
|
122
|
+
├── agents/ # AI review agents (bug, security, style)
|
|
123
|
+
├── cache/ # SQLite caching layer
|
|
124
|
+
├── cli/ # Command-line interface
|
|
125
|
+
├── config/ # Configuration loading
|
|
126
|
+
├── git/ # Git operations & diff parsing
|
|
127
|
+
├── llm/ # LLM client abstraction
|
|
128
|
+
├── orchestrator/ # Agent coordination
|
|
129
|
+
├── reporters/ # Output formatters
|
|
130
|
+
├── static/ # Static analysis (secrets)
|
|
131
|
+
├── types/ # TypeScript type definitions
|
|
132
|
+
└── utils/ # Utility functions
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Roadmap
|
|
136
|
+
|
|
137
|
+
**Phase 1 (Current)**: MVP with text output, Ollama support, basic caching
|
|
138
|
+
**Phase 2**: TUI interface (Ink), GitHub PR integration
|
|
139
|
+
**Phase 3**: Memory/learning system, more agents (performance, architecture)
|
|
140
|
+
**Phase 4**: VS Code extension, custom agent plugins
|
|
141
|
+
|
|
142
|
+
See [docs/ROADMAP.md](docs/ROADMAP.md) for details.
|
|
143
|
+
|
|
144
|
+
## Contributing
|
|
145
|
+
|
|
146
|
+
See [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) for development guidelines.
|
|
147
|
+
|
|
148
|
+
## Security
|
|
149
|
+
|
|
150
|
+
See [docs/SECURITY.md](docs/SECURITY.md) for threat model and security practices.
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
155
|
+
|
|
156
|
+
## Acknowledgments
|
|
157
|
+
|
|
158
|
+
- Inspired by Anthropic's code review patterns
|
|
159
|
+
- Uses Ollama for local LLM inference
|
|
160
|
+
- Built with TypeScript, Commander.js, Ink, and better-sqlite3
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
**Made with ❤️ for developers who value privacy and code quality**
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AgentContext, AgentResult, ReviewFinding, FileDiff, Category } from '../types/index.js';
|
|
2
|
+
import { LLMClient } from '../llm/client.js';
|
|
3
|
+
export declare abstract class BaseAgent {
|
|
4
|
+
protected abstract name: string;
|
|
5
|
+
protected abstract category: Category;
|
|
6
|
+
protected client: LLMClient;
|
|
7
|
+
constructor(client: LLMClient);
|
|
8
|
+
review(context: AgentContext): Promise<AgentResult>;
|
|
9
|
+
protected reviewFile(file: FileDiff, _context: AgentContext): Promise<ReviewFinding[]>;
|
|
10
|
+
protected buildDiffText(file: FileDiff): string;
|
|
11
|
+
protected parseResponse(response: string, file: FileDiff): ReviewFinding[];
|
|
12
|
+
protected parseSeverity(severity?: string): 'critical' | 'high' | 'medium' | 'low' | 'info';
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=base-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-agent.d.ts","sourceRoot":"","sources":["../../src/agents/base-agent.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,aAAa,EACb,QAAQ,EACR,QAAQ,EACT,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAO7C,8BAAsB,SAAS;IAC7B,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAChC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IACtC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC;gBAEhB,MAAM,EAAE,SAAS;IAOvB,MAAM,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;cAiCzC,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,aAAa,EAAE,CAAC;IAsC3B,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM;IAY/C,SAAS,CAAC,aAAa,CACrB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,QAAQ,GACb,aAAa,EAAE;IAmDlB,SAAS,CAAC,aAAa,CACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM;CAanD"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { LLMError } from '../types/index.js';
|
|
2
|
+
import { getSystemPrompt, buildUserPrompt } from '../llm/prompts.js';
|
|
3
|
+
import { createLogger } from '../utils/logger.js';
|
|
4
|
+
import { hashFinding } from '../utils/hash.js';
|
|
5
|
+
const logger = createLogger('agent:base');
|
|
6
|
+
export class BaseAgent {
|
|
7
|
+
client;
|
|
8
|
+
constructor(client) {
|
|
9
|
+
this.client = client;
|
|
10
|
+
}
|
|
11
|
+
async review(context) {
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
logger.debug(`${this.name} starting review`);
|
|
14
|
+
const findings = [];
|
|
15
|
+
try {
|
|
16
|
+
for (const file of context.diff) {
|
|
17
|
+
const fileFindings = await this.reviewFile(file, context);
|
|
18
|
+
findings.push(...fileFindings);
|
|
19
|
+
}
|
|
20
|
+
const duration = Date.now() - startTime;
|
|
21
|
+
logger.debug(`${this.name} completed in ${duration}ms, found ${findings.length} issues`);
|
|
22
|
+
return {
|
|
23
|
+
findings,
|
|
24
|
+
metadata: {
|
|
25
|
+
agentName: this.name,
|
|
26
|
+
duration,
|
|
27
|
+
model: context.config.model,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
logger.error(`${this.name} failed:`, error);
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async reviewFile(file, _context) {
|
|
37
|
+
try {
|
|
38
|
+
const diffText = this.buildDiffText(file);
|
|
39
|
+
if (!diffText.trim()) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
const systemPrompt = getSystemPrompt(this.category);
|
|
43
|
+
const userPrompt = buildUserPrompt({
|
|
44
|
+
file: file.path,
|
|
45
|
+
diff: diffText,
|
|
46
|
+
category: this.category,
|
|
47
|
+
});
|
|
48
|
+
const response = await this.client.complete(systemPrompt, userPrompt);
|
|
49
|
+
const findings = this.parseResponse(response, file);
|
|
50
|
+
return findings;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (error instanceof LLMError) {
|
|
54
|
+
logger.error(`LLM error in ${this.name}:`, error.message);
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
buildDiffText(file) {
|
|
61
|
+
return file.hunks
|
|
62
|
+
.map((hunk) => {
|
|
63
|
+
const header = `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@ ${hunk.header}`;
|
|
64
|
+
return `${header}\n${hunk.content}`;
|
|
65
|
+
})
|
|
66
|
+
.join('\n\n');
|
|
67
|
+
}
|
|
68
|
+
parseResponse(response, file) {
|
|
69
|
+
try {
|
|
70
|
+
const jsonMatch = response.match(/```json\s*([\s\S]*?)\s*```/);
|
|
71
|
+
const jsonStr = jsonMatch ? jsonMatch[1] ?? '{}' : response;
|
|
72
|
+
const parsed = JSON.parse(jsonStr);
|
|
73
|
+
if (!parsed.findings || !Array.isArray(parsed.findings)) {
|
|
74
|
+
logger.warn(`Invalid response format from ${this.name}`);
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
return parsed.findings.map((finding) => {
|
|
78
|
+
const id = hashFinding(file.path, finding.line, finding.message);
|
|
79
|
+
return {
|
|
80
|
+
id,
|
|
81
|
+
message: finding.message,
|
|
82
|
+
location: {
|
|
83
|
+
file: file.path,
|
|
84
|
+
line: finding.line,
|
|
85
|
+
},
|
|
86
|
+
severity: this.parseSeverity(finding.severity),
|
|
87
|
+
category: this.category,
|
|
88
|
+
confidence: finding.confidence ?? 70,
|
|
89
|
+
rationale: finding.rationale ?? '',
|
|
90
|
+
suggestion: finding.suggestion,
|
|
91
|
+
source: 'ai',
|
|
92
|
+
agentName: this.name,
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
logger.error(`Failed to parse ${this.name} response:`, error);
|
|
98
|
+
logger.debug('Response:', response);
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
parseSeverity(severity) {
|
|
103
|
+
const normalized = severity?.toLowerCase();
|
|
104
|
+
if (normalized === 'critical' ||
|
|
105
|
+
normalized === 'high' ||
|
|
106
|
+
normalized === 'medium' ||
|
|
107
|
+
normalized === 'low' ||
|
|
108
|
+
normalized === 'info') {
|
|
109
|
+
return normalized;
|
|
110
|
+
}
|
|
111
|
+
return 'medium';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=base-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-agent.js","sourceRoot":"","sources":["../../src/agents/base-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bug-agent.d.ts","sourceRoot":"","sources":["../../src/agents/bug-agent.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,qBAAa,QAAS,SAAQ,SAAS;IACrC,SAAS,CAAC,IAAI,SAAc;IAC5B,SAAS,CAAC,QAAQ,EAAG,KAAK,CAAU;CACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bug-agent.js","sourceRoot":"","sources":["../../src/agents/bug-agent.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,OAAO,QAAS,SAAQ,SAAS;IAC3B,IAAI,GAAG,UAAU,CAAC;IAClB,QAAQ,GAAG,KAAc,CAAC;CACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-agent.d.ts","sourceRoot":"","sources":["../../src/agents/security-agent.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,qBAAa,aAAc,SAAQ,SAAS;IAC1C,SAAS,CAAC,IAAI,SAAmB;IACjC,SAAS,CAAC,QAAQ,EAAG,UAAU,CAAU;CAC1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-agent.js","sourceRoot":"","sources":["../../src/agents/security-agent.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,OAAO,aAAc,SAAQ,SAAS;IAChC,IAAI,GAAG,eAAe,CAAC;IACvB,QAAQ,GAAG,UAAmB,CAAC;CAC1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style-agent.d.ts","sourceRoot":"","sources":["../../src/agents/style-agent.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,qBAAa,UAAW,SAAQ,SAAS;IACvC,SAAS,CAAC,IAAI,SAAgB;IAC9B,SAAS,CAAC,QAAQ,EAAG,OAAO,CAAU;CACvC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style-agent.js","sourceRoot":"","sources":["../../src/agents/style-agent.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,OAAO,UAAW,SAAQ,SAAS;IAC7B,IAAI,GAAG,YAAY,CAAC;IACpB,QAAQ,GAAG,OAAgB,CAAC;CACvC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CacheEntry, CacheKey } from '../types/index.js';
|
|
2
|
+
export interface CacheDatabaseOptions {
|
|
3
|
+
path: string;
|
|
4
|
+
readonly?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare class CacheDatabase {
|
|
7
|
+
private db;
|
|
8
|
+
constructor(options: CacheDatabaseOptions);
|
|
9
|
+
private initSchema;
|
|
10
|
+
get(key: CacheKey): CacheEntry | null;
|
|
11
|
+
set(entry: CacheEntry): void;
|
|
12
|
+
delete(key: CacheKey): boolean;
|
|
13
|
+
clear(): number;
|
|
14
|
+
getStats(): {
|
|
15
|
+
totalEntries: number;
|
|
16
|
+
oldestEntry: number | null;
|
|
17
|
+
newestEntry: number | null;
|
|
18
|
+
totalSize: number;
|
|
19
|
+
};
|
|
20
|
+
deleteOlderThan(ageMs: number): number;
|
|
21
|
+
getMetadata(key: string): string | null;
|
|
22
|
+
setMetadata(key: string, value: string): void;
|
|
23
|
+
close(): void;
|
|
24
|
+
vacuum(): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/cache/database.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAiB,MAAM,mBAAmB,CAAC;AA2B7E,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAKD,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAoB;gBAElB,OAAO,EAAE,oBAAoB;IAmCzC,OAAO,CAAC,UAAU;IAYlB,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,UAAU,GAAG,IAAI;IA2CrC,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAiC5B,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO;IAiB9B,KAAK,IAAI,MAAM;IAcf,QAAQ,IAAI;QACV,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,SAAS,EAAE,MAAM,CAAC;KACnB;IAgCD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAetC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAWvC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAc7C,KAAK,IAAI,IAAI;IAYb,MAAM,IAAI,IAAI;CAQf"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { CacheError } from '../types/index.js';
|
|
3
|
+
import { createLogger } from '../utils/logger.js';
|
|
4
|
+
import { hashCacheKey } from '../utils/hash.js';
|
|
5
|
+
import { mkdirSync } from 'node:fs';
|
|
6
|
+
import { dirname } from 'node:path';
|
|
7
|
+
const logger = createLogger('cache:db');
|
|
8
|
+
const SCHEMA = `
|
|
9
|
+
CREATE TABLE IF NOT EXISTS cache_entries (
|
|
10
|
+
id TEXT PRIMARY KEY,
|
|
11
|
+
commit_sha TEXT NOT NULL,
|
|
12
|
+
file_path TEXT NOT NULL,
|
|
13
|
+
content_hash TEXT NOT NULL,
|
|
14
|
+
findings TEXT NOT NULL,
|
|
15
|
+
agent_version TEXT NOT NULL,
|
|
16
|
+
created_at INTEGER NOT NULL,
|
|
17
|
+
INDEX idx_commit_file ON cache_entries(commit_sha, file_path)
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
CREATE TABLE IF NOT EXISTS metadata (
|
|
21
|
+
key TEXT PRIMARY KEY,
|
|
22
|
+
value TEXT NOT NULL
|
|
23
|
+
);
|
|
24
|
+
`;
|
|
25
|
+
export class CacheDatabase {
|
|
26
|
+
db;
|
|
27
|
+
constructor(options) {
|
|
28
|
+
try {
|
|
29
|
+
const dir = dirname(options.path);
|
|
30
|
+
try {
|
|
31
|
+
mkdirSync(dir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
}
|
|
35
|
+
this.db = new Database(options.path, {
|
|
36
|
+
readonly: options.readonly ?? false,
|
|
37
|
+
fileMustExist: false,
|
|
38
|
+
});
|
|
39
|
+
this.db.pragma('journal_mode = WAL');
|
|
40
|
+
this.db.pragma('synchronous = NORMAL');
|
|
41
|
+
this.db.pragma('cache_size = -64000');
|
|
42
|
+
if (!options.readonly) {
|
|
43
|
+
this.initSchema();
|
|
44
|
+
}
|
|
45
|
+
logger.debug('Cache database initialized:', options.path);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
throw new CacheError('Failed to initialize cache database', { error });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
initSchema() {
|
|
52
|
+
try {
|
|
53
|
+
this.db.exec(SCHEMA);
|
|
54
|
+
this.setMetadata('schema_version', '1');
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw new CacheError('Failed to initialize schema', { error });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
get(key) {
|
|
61
|
+
try {
|
|
62
|
+
const id = hashCacheKey(key.commitSha, key.filePath, key.contentHash);
|
|
63
|
+
const stmt = this.db.prepare(`
|
|
64
|
+
SELECT * FROM cache_entries WHERE id = ?
|
|
65
|
+
`);
|
|
66
|
+
const row = stmt.get(id);
|
|
67
|
+
if (!row) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
key: {
|
|
72
|
+
commitSha: row.commit_sha,
|
|
73
|
+
filePath: row.file_path,
|
|
74
|
+
contentHash: row.content_hash,
|
|
75
|
+
},
|
|
76
|
+
findings: JSON.parse(row.findings),
|
|
77
|
+
createdAt: row.created_at,
|
|
78
|
+
agentVersion: row.agent_version,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
logger.error('Failed to get cache entry:', error);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
set(entry) {
|
|
87
|
+
try {
|
|
88
|
+
const id = hashCacheKey(entry.key.commitSha, entry.key.filePath, entry.key.contentHash);
|
|
89
|
+
const stmt = this.db.prepare(`
|
|
90
|
+
INSERT OR REPLACE INTO cache_entries
|
|
91
|
+
(id, commit_sha, file_path, content_hash, findings, agent_version, created_at)
|
|
92
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
93
|
+
`);
|
|
94
|
+
stmt.run(id, entry.key.commitSha, entry.key.filePath, entry.key.contentHash, JSON.stringify(entry.findings), entry.agentVersion, entry.createdAt);
|
|
95
|
+
logger.debug('Cache entry saved:', id);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
throw new CacheError('Failed to set cache entry', { error });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
delete(key) {
|
|
102
|
+
try {
|
|
103
|
+
const id = hashCacheKey(key.commitSha, key.filePath, key.contentHash);
|
|
104
|
+
const stmt = this.db.prepare('DELETE FROM cache_entries WHERE id = ?');
|
|
105
|
+
const result = stmt.run(id);
|
|
106
|
+
return result.changes > 0;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
logger.error('Failed to delete cache entry:', error);
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
clear() {
|
|
114
|
+
try {
|
|
115
|
+
const stmt = this.db.prepare('DELETE FROM cache_entries');
|
|
116
|
+
const result = stmt.run();
|
|
117
|
+
logger.info('Cache cleared:', result.changes, 'entries');
|
|
118
|
+
return result.changes;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
throw new CacheError('Failed to clear cache', { error });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
getStats() {
|
|
125
|
+
try {
|
|
126
|
+
const countStmt = this.db.prepare('SELECT COUNT(*) as count FROM cache_entries');
|
|
127
|
+
const countResult = countStmt.get();
|
|
128
|
+
const rangeStmt = this.db.prepare(`
|
|
129
|
+
SELECT MIN(created_at) as oldest, MAX(created_at) as newest
|
|
130
|
+
FROM cache_entries
|
|
131
|
+
`);
|
|
132
|
+
const rangeResult = rangeStmt.get();
|
|
133
|
+
const sizeStmt = this.db.prepare("SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size()");
|
|
134
|
+
const sizeResult = sizeStmt.get();
|
|
135
|
+
return {
|
|
136
|
+
totalEntries: countResult.count,
|
|
137
|
+
oldestEntry: rangeResult.oldest,
|
|
138
|
+
newestEntry: rangeResult.newest,
|
|
139
|
+
totalSize: sizeResult.size,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
throw new CacheError('Failed to get cache stats', { error });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
deleteOlderThan(ageMs) {
|
|
147
|
+
try {
|
|
148
|
+
const cutoffTime = Date.now() - ageMs;
|
|
149
|
+
const stmt = this.db.prepare('DELETE FROM cache_entries WHERE created_at < ?');
|
|
150
|
+
const result = stmt.run(cutoffTime);
|
|
151
|
+
logger.info('Deleted old cache entries:', result.changes);
|
|
152
|
+
return result.changes;
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
throw new CacheError('Failed to delete old entries', { error });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
getMetadata(key) {
|
|
159
|
+
try {
|
|
160
|
+
const stmt = this.db.prepare('SELECT value FROM metadata WHERE key = ?');
|
|
161
|
+
const result = stmt.get(key);
|
|
162
|
+
return result?.value ?? null;
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
logger.error('Failed to get metadata:', error);
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
setMetadata(key, value) {
|
|
170
|
+
try {
|
|
171
|
+
const stmt = this.db.prepare(`
|
|
172
|
+
INSERT OR REPLACE INTO metadata (key, value) VALUES (?, ?)
|
|
173
|
+
`);
|
|
174
|
+
stmt.run(key, value);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
throw new CacheError('Failed to set metadata', { error });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
close() {
|
|
181
|
+
try {
|
|
182
|
+
this.db.close();
|
|
183
|
+
logger.debug('Cache database closed');
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
logger.error('Failed to close database:', error);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
vacuum() {
|
|
190
|
+
try {
|
|
191
|
+
this.db.exec('VACUUM');
|
|
192
|
+
logger.info('Database vacuumed');
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
throw new CacheError('Failed to vacuum database', { error });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/cache/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { FileDiff, ReviewFinding } from '../types/index.js';
|
|
2
|
+
export interface CacheManagerOptions {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
dbPath: string;
|
|
5
|
+
maxAgeMs?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class CacheManager {
|
|
8
|
+
private db;
|
|
9
|
+
private enabled;
|
|
10
|
+
private maxAgeMs;
|
|
11
|
+
constructor(options: CacheManagerOptions);
|
|
12
|
+
get(commitSha: string, file: FileDiff): Promise<ReviewFinding[] | null>;
|
|
13
|
+
set(commitSha: string, file: FileDiff, findings: ReviewFinding[]): Promise<void>;
|
|
14
|
+
clear(): Promise<number>;
|
|
15
|
+
cleanup(): Promise<number>;
|
|
16
|
+
getStats(): Promise<{
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
totalEntries: number;
|
|
19
|
+
oldestEntry: number | null;
|
|
20
|
+
newestEntry: number | null;
|
|
21
|
+
totalSize: number;
|
|
22
|
+
}>;
|
|
23
|
+
close(): void;
|
|
24
|
+
optimize(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export declare function createCacheManager(options: CacheManagerOptions): CacheManager;
|
|
27
|
+
//# sourceMappingURL=manager.d.ts.map
|