patchpilots 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.
Files changed (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +230 -0
  3. package/dist/bin/demo.d.ts +2 -0
  4. package/dist/bin/demo.js +5 -0
  5. package/dist/bin/demo.js.map +1 -0
  6. package/dist/bin/patchpilots.d.ts +2 -0
  7. package/dist/bin/patchpilots.js +5 -0
  8. package/dist/bin/patchpilots.js.map +1 -0
  9. package/dist/src/agents/base-agent.d.ts +13 -0
  10. package/dist/src/agents/base-agent.js +23 -0
  11. package/dist/src/agents/base-agent.js.map +1 -0
  12. package/dist/src/agents/coder.d.ts +63 -0
  13. package/dist/src/agents/coder.js +59 -0
  14. package/dist/src/agents/coder.js.map +1 -0
  15. package/dist/src/agents/docs.d.ts +40 -0
  16. package/dist/src/agents/docs.js +45 -0
  17. package/dist/src/agents/docs.js.map +1 -0
  18. package/dist/src/agents/index.d.ts +6 -0
  19. package/dist/src/agents/index.js +7 -0
  20. package/dist/src/agents/index.js.map +1 -0
  21. package/dist/src/agents/planner.d.ts +63 -0
  22. package/dist/src/agents/planner.js +59 -0
  23. package/dist/src/agents/planner.js.map +1 -0
  24. package/dist/src/agents/reviewer.d.ts +60 -0
  25. package/dist/src/agents/reviewer.js +46 -0
  26. package/dist/src/agents/reviewer.js.map +1 -0
  27. package/dist/src/agents/tester.d.ts +47 -0
  28. package/dist/src/agents/tester.js +51 -0
  29. package/dist/src/agents/tester.js.map +1 -0
  30. package/dist/src/cli/commands/docs.d.ts +2 -0
  31. package/dist/src/cli/commands/docs.js +40 -0
  32. package/dist/src/cli/commands/docs.js.map +1 -0
  33. package/dist/src/cli/commands/improve.d.ts +2 -0
  34. package/dist/src/cli/commands/improve.js +42 -0
  35. package/dist/src/cli/commands/improve.js.map +1 -0
  36. package/dist/src/cli/commands/plan.d.ts +2 -0
  37. package/dist/src/cli/commands/plan.js +38 -0
  38. package/dist/src/cli/commands/plan.js.map +1 -0
  39. package/dist/src/cli/commands/review.d.ts +2 -0
  40. package/dist/src/cli/commands/review.js +38 -0
  41. package/dist/src/cli/commands/review.js.map +1 -0
  42. package/dist/src/cli/commands/test.d.ts +2 -0
  43. package/dist/src/cli/commands/test.js +40 -0
  44. package/dist/src/cli/commands/test.js.map +1 -0
  45. package/dist/src/cli/index.d.ts +1 -0
  46. package/dist/src/cli/index.js +2 -0
  47. package/dist/src/cli/index.js.map +1 -0
  48. package/dist/src/cli/program.d.ts +2 -0
  49. package/dist/src/cli/program.js +20 -0
  50. package/dist/src/cli/program.js.map +1 -0
  51. package/dist/src/core/config.d.ts +6 -0
  52. package/dist/src/core/config.js +72 -0
  53. package/dist/src/core/config.js.map +1 -0
  54. package/dist/src/core/llm-client.d.ts +19 -0
  55. package/dist/src/core/llm-client.js +70 -0
  56. package/dist/src/core/llm-client.js.map +1 -0
  57. package/dist/src/core/orchestrator.d.ts +27 -0
  58. package/dist/src/core/orchestrator.js +262 -0
  59. package/dist/src/core/orchestrator.js.map +1 -0
  60. package/dist/src/index.d.ts +5 -0
  61. package/dist/src/index.js +6 -0
  62. package/dist/src/index.js.map +1 -0
  63. package/dist/src/types/agent.d.ts +21 -0
  64. package/dist/src/types/agent.js +2 -0
  65. package/dist/src/types/agent.js.map +1 -0
  66. package/dist/src/types/config.d.ts +11 -0
  67. package/dist/src/types/config.js +10 -0
  68. package/dist/src/types/config.js.map +1 -0
  69. package/dist/src/types/index.d.ts +3 -0
  70. package/dist/src/types/index.js +4 -0
  71. package/dist/src/types/index.js.map +1 -0
  72. package/dist/src/types/review.d.ts +61 -0
  73. package/dist/src/types/review.js +2 -0
  74. package/dist/src/types/review.js.map +1 -0
  75. package/dist/src/utils/banner.d.ts +2 -0
  76. package/dist/src/utils/banner.js +65 -0
  77. package/dist/src/utils/banner.js.map +1 -0
  78. package/dist/src/utils/cost.d.ts +15 -0
  79. package/dist/src/utils/cost.js +46 -0
  80. package/dist/src/utils/cost.js.map +1 -0
  81. package/dist/src/utils/files.d.ts +2 -0
  82. package/dist/src/utils/files.js +65 -0
  83. package/dist/src/utils/files.js.map +1 -0
  84. package/dist/src/utils/formatter.d.ts +7 -0
  85. package/dist/src/utils/formatter.js +190 -0
  86. package/dist/src/utils/formatter.js.map +1 -0
  87. package/dist/src/utils/logger.d.ts +9 -0
  88. package/dist/src/utils/logger.js +28 -0
  89. package/dist/src/utils/logger.js.map +1 -0
  90. package/package.json +57 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Piia Alavesa
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 OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,230 @@
1
+ # PatchPilots
2
+
3
+ A team of AI agents that reviews and improves your code automatically.
4
+
5
+ ```
6
+ ○ ○ ○ ○ ○ ○
7
+ /|\ /|\ /|\ /|\ /|\ /|\
8
+ / \ / \ / \ / \ / \ / \
9
+ 🧠 🔍 ✨ 🧪 📝 🎯
10
+ Planner Reviewer Coder Tester Docs Orchestrator
11
+
12
+ ____ __ __ ____ _ __ __
13
+ / __ \____ _/ /______/ /_ / __ \(_) /___ / /______
14
+ / /_/ / __ `/ __/ ___/ __ \/ /_/ / / / __ \/ __/ ___/
15
+ / ____/ /_/ / /_/ /__/ / / / ____/ / / /_/ / /_(__ )
16
+ /_/ \__,_/\__/\___/_/ /_/_/ /_/_/\____/\__/____/
17
+
18
+ ○ ○ ○ ○ ○ ○
19
+ /|\ /|\ /|\ /|\ /|\ /|\
20
+ / \ / \ / \ / \ / \ / \
21
+
22
+ Your code crew is ready. One dev. Six agents. Zero bugs.
23
+ ```
24
+
25
+ **One dev. Six AI agents. Zero excuses.**
26
+
27
+ Built for solo developers and hobby projects — when you don't have a team to review your PRs, PatchPilots is your crew.
28
+
29
+ ## The Crew
30
+
31
+ | Agent | Command | What it does |
32
+ |-------|---------|--------------|
33
+ | 🧠 Planner | `patchpilots plan` | Analyzes codebase and breaks down work into tasks |
34
+ | 🔍 Reviewer | `patchpilots review` | Finds bugs, security issues, and code smells |
35
+ | ✨ Coder | `patchpilots improve` | Rewrites and fixes code based on review findings |
36
+ | 🧪 Tester | `patchpilots test` | Generates unit tests for your source files |
37
+ | 📝 Docs | `patchpilots docs` | Generates JSDoc/TSDoc documentation |
38
+ | 🎯 Orchestrator | (coordinates) | Manages the pipeline between agents |
39
+
40
+ ## Quick start
41
+
42
+ ```bash
43
+ # Install dependencies
44
+ npm install
45
+
46
+ # Set your API key
47
+ export ANTHROPIC_API_KEY=your-key-here
48
+
49
+ # Review code
50
+ npx tsx bin/patchpilots.ts review ./src
51
+
52
+ # Generate an implementation plan
53
+ npx tsx bin/patchpilots.ts plan ./src --task "add authentication"
54
+
55
+ # Review and improve code
56
+ npx tsx bin/patchpilots.ts improve ./src
57
+
58
+ # Generate unit tests
59
+ npx tsx bin/patchpilots.ts test ./src
60
+
61
+ # Generate documentation
62
+ npx tsx bin/patchpilots.ts docs ./src
63
+
64
+ # Apply any changes to disk
65
+ npx tsx bin/patchpilots.ts improve ./src --write
66
+ npx tsx bin/patchpilots.ts test ./src --write
67
+ npx tsx bin/patchpilots.ts docs ./src --write
68
+ ```
69
+
70
+ ## CLI commands
71
+
72
+ ### `patchpilots review <path>`
73
+
74
+ Analyzes your code and reports findings grouped by file, color-coded by severity.
75
+
76
+ | Option | Description |
77
+ |--------|-------------|
78
+ | `-m, --model <model>` | Claude model to use |
79
+ | `-c, --config <path>` | Path to config file |
80
+ | `--severity <level>` | Minimum severity: `critical`, `warning`, `info` |
81
+ | `--json` | Output raw JSON |
82
+ | `--verbose` | Show token usage and thinking progress |
83
+
84
+ ### `patchpilots improve <path>`
85
+
86
+ Reviews code and then generates improved versions with fixes applied.
87
+
88
+ All `review` options plus:
89
+
90
+ | Option | Description |
91
+ |--------|-------------|
92
+ | `--write` | Write improved files to disk (default: dry-run) |
93
+ | `--backup` | Create `.bak` files before overwriting |
94
+
95
+ ### `patchpilots test <path>`
96
+
97
+ Generates unit tests for source files.
98
+
99
+ | Option | Description |
100
+ |--------|-------------|
101
+ | `--write` | Write test files to disk |
102
+ | `--framework <name>` | Test framework to use (default: `vitest`) |
103
+
104
+ ### `patchpilots plan <path>`
105
+
106
+ Analyzes codebase and creates a structured implementation plan.
107
+
108
+ | Option | Description |
109
+ |--------|-------------|
110
+ | `-t, --task <description>` | Specific task to plan for |
111
+
112
+ ### `patchpilots docs <path>`
113
+
114
+ Generates documentation for source files.
115
+
116
+ | Option | Description |
117
+ |--------|-------------|
118
+ | `--write` | Write documented files to disk |
119
+ | `--backup` | Create `.bak` files before overwriting |
120
+
121
+ ## Configuration
122
+
123
+ Create a `.patchpilots.json` in your project root:
124
+
125
+ ```json
126
+ {
127
+ "model": "claude-sonnet-4-6",
128
+ "maxTokens": 16000,
129
+ "temperature": 0.3,
130
+ "include": ["**/*.ts", "**/*.js"],
131
+ "exclude": ["node_modules/**", "dist/**"],
132
+ "maxFileSize": 100000,
133
+ "maxFiles": 20
134
+ }
135
+ ```
136
+
137
+ Or set your API key **once globally** so it works for every project:
138
+
139
+ ```bash
140
+ echo '{"apiKey": "sk-ant-..."}' > ~/.patchpilots.json
141
+ ```
142
+
143
+ Or per-project via `.patchpilots.json` in your project root, or via environment variable:
144
+
145
+ ```bash
146
+ export ANTHROPIC_API_KEY=your-key-here
147
+ ```
148
+
149
+ Config resolution order: CLI flags > project `.patchpilots.json` > global `~/.patchpilots.json` > `ANTHROPIC_API_KEY` env var.
150
+
151
+ ## Powered by Claude API
152
+
153
+ PatchPilots uses three key features of the Claude API:
154
+
155
+ ### Structured outputs
156
+ Every agent response is **guaranteed** to match its Zod schema via `zodOutputFormat`. No regex JSON extraction, no prayer-based parsing — the API enforces the schema.
157
+
158
+ ### Adaptive thinking
159
+ Agents use Claude's adaptive thinking mode for deeper reasoning. The Reviewer agent thinks through code logic before flagging issues, catching bugs that a surface-level scan would miss.
160
+
161
+ ### Streaming
162
+ Responses are streamed in real-time. No hanging on long requests, no timeouts. Use `--verbose` to see thinking progress as it happens.
163
+
164
+ ### Prompt caching
165
+ System prompts are cached via Claude's `cache_control` — repeat runs against the same project cost ~90% less on the cached portion.
166
+
167
+ ### Cost tracking
168
+ Every run shows a cost summary with per-agent token usage and estimated USD cost.
169
+
170
+ ## Architecture
171
+
172
+ PatchPilots uses a clean agent abstraction. Every agent extends `BaseAgent<T>` and implements three methods:
173
+
174
+ ```typescript
175
+ class MyAgent extends BaseAgent<MyOutputType> {
176
+ getSystemPrompt() // What the agent's role is
177
+ buildUserMessage(context) // How to format the input
178
+ getOutputSchema() // Zod schema — guarantees output shape
179
+ }
180
+ ```
181
+
182
+ Adding a new agent is one file + three methods. The orchestrator handles coordination, streaming, error handling, and output formatting.
183
+
184
+ ### Error handling
185
+
186
+ The LLM client uses typed Anthropic SDK exceptions:
187
+ - `RateLimitError` — automatic retry with backoff
188
+ - `AuthenticationError` — clear message about API key
189
+ - `APIError` — surfaced with status code and details
190
+
191
+ ## Tech stack
192
+
193
+ - TypeScript + Node.js
194
+ - Claude API (`@anthropic-ai/sdk` v0.79.0)
195
+ - Structured outputs (`zodOutputFormat`) — guaranteed schema compliance
196
+ - Adaptive thinking — deeper code analysis
197
+ - Streaming — real-time response delivery
198
+ - Commander (CLI)
199
+ - Chalk (terminal formatting)
200
+ - Zod (schema definition + validation)
201
+
202
+ ## Status
203
+
204
+ This is an MVP — actively being built in public. Follow along for updates.
205
+
206
+ ## Roadmap
207
+
208
+ ### Done
209
+ - [x] 6 AI agents: Planner, Reviewer, Coder, Tester, Docs, Orchestrator
210
+ - [x] Structured outputs with Zod schemas — guaranteed valid responses
211
+ - [x] Adaptive thinking for deeper code analysis
212
+ - [x] Streaming — real-time response delivery
213
+ - [x] Prompt caching — ~90% cost savings on repeat runs
214
+ - [x] Cost tracking — per-agent token usage and USD estimate after every run
215
+ - [x] Global config (`~/.patchpilots.json`) — set API key once for all projects
216
+
217
+ ### Next up
218
+ - [x] **Diff-based Coder output** — return patches instead of full files (fixes token limit on large files)
219
+ - [ ] **npm publish** — `npx patchpilots review ./src` from anywhere
220
+ - [ ] **Parallel file review** — review files in batches instead of one giant prompt
221
+ - [ ] **GitHub Action** — auto-review PRs and post findings as comments
222
+ - [ ] **`patchpilots audit`** — full pipeline: plan → review → improve → test → docs in one command
223
+ - [ ] **Smart model routing** — Haiku for Docs/Tester, Sonnet for Reviewer/Coder
224
+ - [ ] **HTML/CSS support** — review static sites and stylesheets
225
+ - [ ] **Security agent** — dedicated OWASP Top 10, secrets detection, input validation, and auth pattern analysis
226
+ - [ ] **Designer agent** — generate CSS, design tokens, and component markup
227
+
228
+ ## License
229
+
230
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env npx tsx
2
+ export {};
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env npx tsx
2
+ import { playBanner } from "../src/utils/banner.js";
3
+ await playBanner();
4
+ console.log("\n Ready to review your code. Run: patchpilots review <path>\n");
5
+ //# sourceMappingURL=demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.js","sourceRoot":"","sources":["../../bin/demo.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,MAAM,UAAU,EAAE,CAAC;AACnB,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { createProgram } from "../src/cli/index.js";
3
+ const program = createProgram();
4
+ program.parse();
5
+ //# sourceMappingURL=patchpilots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patchpilots.js","sourceRoot":"","sources":["../../bin/patchpilots.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;AAChC,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { z } from "zod";
2
+ import type { LLMClient } from "../core/llm-client.js";
3
+ import type { AgentContext, AgentResult } from "../types/index.js";
4
+ export declare abstract class BaseAgent<T = unknown> {
5
+ protected llmClient: LLMClient;
6
+ abstract readonly name: string;
7
+ abstract readonly description: string;
8
+ constructor(llmClient: LLMClient);
9
+ protected abstract getSystemPrompt(): string;
10
+ protected abstract buildUserMessage(context: AgentContext): string;
11
+ protected abstract getOutputSchema(): z.ZodType<T>;
12
+ execute(context: AgentContext, onToken?: (text: string) => void): Promise<AgentResult>;
13
+ }
@@ -0,0 +1,23 @@
1
+ export class BaseAgent {
2
+ llmClient;
3
+ constructor(llmClient) {
4
+ this.llmClient = llmClient;
5
+ }
6
+ async execute(context, onToken) {
7
+ const systemPrompt = this.getSystemPrompt();
8
+ const userMessage = this.buildUserMessage(context);
9
+ const schema = this.getOutputSchema();
10
+ const response = await this.llmClient.chatStructured(systemPrompt, userMessage, schema, {
11
+ maxTokens: context.config.maxTokens,
12
+ temperature: context.config.temperature,
13
+ }, onToken);
14
+ return {
15
+ agentName: this.name,
16
+ success: true,
17
+ data: response.data,
18
+ rawResponse: JSON.stringify(response.data),
19
+ tokensUsed: response.usage,
20
+ };
21
+ }
22
+ }
23
+ //# sourceMappingURL=base-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-agent.js","sourceRoot":"","sources":["../../../src/agents/base-agent.ts"],"names":[],"mappings":"AAIA,MAAM,OAAgB,SAAS;IAIP;IAAtB,YAAsB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAM9C,KAAK,CAAC,OAAO,CACX,OAAqB,EACrB,OAAgC;QAEhC,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAEtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,cAAc,CAClD,YAAY,EACZ,WAAW,EACX,MAAM,EACN;YACE,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS;YACnC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW;SACxC,EACD,OAAO,CACR,CAAC;QAEF,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,IAAI;YACpB,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;YAC1C,UAAU,EAAE,QAAQ,CAAC,KAAK;SAC3B,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,63 @@
1
+ import { z } from "zod";
2
+ import { BaseAgent } from "./base-agent.js";
3
+ import type { AgentContext } from "../types/index.js";
4
+ import type { CoderResult } from "../types/review.js";
5
+ export declare class CoderAgent extends BaseAgent<CoderResult> {
6
+ readonly name = "Coder";
7
+ readonly description = "Rewrites and improves code based on review findings";
8
+ protected getOutputSchema(): z.ZodObject<{
9
+ improvedFiles: z.ZodArray<z.ZodObject<{
10
+ path: z.ZodString;
11
+ patches: z.ZodArray<z.ZodObject<{
12
+ find: z.ZodString;
13
+ replace: z.ZodString;
14
+ description: z.ZodString;
15
+ }, "strip", z.ZodTypeAny, {
16
+ replace: string;
17
+ find: string;
18
+ description: string;
19
+ }, {
20
+ replace: string;
21
+ find: string;
22
+ description: string;
23
+ }>, "many">;
24
+ }, "strip", z.ZodTypeAny, {
25
+ path: string;
26
+ patches: {
27
+ replace: string;
28
+ find: string;
29
+ description: string;
30
+ }[];
31
+ }, {
32
+ path: string;
33
+ patches: {
34
+ replace: string;
35
+ find: string;
36
+ description: string;
37
+ }[];
38
+ }>, "many">;
39
+ summary: z.ZodString;
40
+ }, "strip", z.ZodTypeAny, {
41
+ summary: string;
42
+ improvedFiles: {
43
+ path: string;
44
+ patches: {
45
+ replace: string;
46
+ find: string;
47
+ description: string;
48
+ }[];
49
+ }[];
50
+ }, {
51
+ summary: string;
52
+ improvedFiles: {
53
+ path: string;
54
+ patches: {
55
+ replace: string;
56
+ find: string;
57
+ description: string;
58
+ }[];
59
+ }[];
60
+ }>;
61
+ protected getSystemPrompt(): string;
62
+ protected buildUserMessage(context: AgentContext): string;
63
+ }
@@ -0,0 +1,59 @@
1
+ import { z } from "zod";
2
+ import { BaseAgent } from "./base-agent.js";
3
+ const coderResultSchema = z.object({
4
+ improvedFiles: z.array(z.object({
5
+ path: z.string(),
6
+ patches: z.array(z.object({
7
+ find: z.string(),
8
+ replace: z.string(),
9
+ description: z.string(),
10
+ })),
11
+ })),
12
+ summary: z.string(),
13
+ });
14
+ export class CoderAgent extends BaseAgent {
15
+ name = "Coder";
16
+ description = "Rewrites and improves code based on review findings";
17
+ getOutputSchema() {
18
+ return coderResultSchema;
19
+ }
20
+ getSystemPrompt() {
21
+ return `You are a senior software developer. You receive code files along with review findings, and your job is to fix the identified issues.
22
+
23
+ Rules:
24
+ - Only change what the review identified — do not refactor unrelated code
25
+ - Preserve the original code style (indentation, naming conventions, etc.)
26
+ - Make minimal, targeted changes
27
+
28
+ Output format: For each file, return an array of search-and-replace patches.
29
+ Each patch has:
30
+ - "find": the EXACT string to find in the original file (must match uniquely, include enough context)
31
+ - "replace": the replacement string
32
+ - "description": brief explanation of what the patch does
33
+
34
+ IMPORTANT:
35
+ - The "find" string must be an EXACT match of the original source code including whitespace and indentation
36
+ - Include enough surrounding context in "find" to ensure a unique match (at least 2-3 lines)
37
+ - Do NOT include the entire file — only the specific lines that need changing with minimal surrounding context
38
+ - Each patch should be small and focused on one change
39
+
40
+ Only include files that actually need changes. If no changes are needed, return an empty improvedFiles array.`;
41
+ }
42
+ buildUserMessage(context) {
43
+ const review = context.previousResults?.data;
44
+ const parts = ["Here are the code files and the review findings. Please fix the identified issues.\n"];
45
+ parts.push("## Review Findings");
46
+ parts.push("```json");
47
+ parts.push(JSON.stringify(review, null, 2));
48
+ parts.push("```\n");
49
+ parts.push("## Source Files\n");
50
+ for (const file of context.files) {
51
+ parts.push(`### ${file.path} (${file.language})`);
52
+ parts.push("```" + file.language);
53
+ parts.push(file.content);
54
+ parts.push("```\n");
55
+ }
56
+ return parts.join("\n");
57
+ }
58
+ }
59
+ //# sourceMappingURL=coder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coder.js","sourceRoot":"","sources":["../../../src/agents/coder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,aAAa,EAAE,CAAC,CAAC,KAAK,CACpB,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,OAAO,EAAE,CAAC,CAAC,KAAK,CACd,CAAC,CAAC,MAAM,CAAC;YACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;YACnB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;SACxB,CAAC,CACH;KACF,CAAC,CACH;IACD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;CACpB,CAAC,CAAC;AAEH,MAAM,OAAO,UAAW,SAAQ,SAAsB;IAC3C,IAAI,GAAG,OAAO,CAAC;IACf,WAAW,GAAG,qDAAqD,CAAC;IAEnE,eAAe;QACvB,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAES,eAAe;QACvB,OAAO;;;;;;;;;;;;;;;;;;;8GAmBmG,CAAC;IAC7G,CAAC;IAES,gBAAgB,CAAC,OAAqB;QAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,IAAoB,CAAC;QAC7D,MAAM,KAAK,GAAG,CAAC,sFAAsF,CAAC,CAAC;QAEvG,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpB,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,40 @@
1
+ import { z } from "zod";
2
+ import { BaseAgent } from "./base-agent.js";
3
+ import type { AgentContext } from "../types/index.js";
4
+ import type { DocsResult } from "../types/review.js";
5
+ export declare class DocsAgent extends BaseAgent<DocsResult> {
6
+ readonly name = "Docs";
7
+ readonly description = "Generates and improves documentation for source files";
8
+ protected getOutputSchema(): z.ZodObject<{
9
+ docs: z.ZodArray<z.ZodObject<{
10
+ file: z.ZodString;
11
+ content: z.ZodString;
12
+ type: z.ZodEnum<["jsdoc", "readme", "inline"]>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ type: "jsdoc" | "readme" | "inline";
15
+ file: string;
16
+ content: string;
17
+ }, {
18
+ type: "jsdoc" | "readme" | "inline";
19
+ file: string;
20
+ content: string;
21
+ }>, "many">;
22
+ summary: z.ZodString;
23
+ }, "strip", z.ZodTypeAny, {
24
+ summary: string;
25
+ docs: {
26
+ type: "jsdoc" | "readme" | "inline";
27
+ file: string;
28
+ content: string;
29
+ }[];
30
+ }, {
31
+ summary: string;
32
+ docs: {
33
+ type: "jsdoc" | "readme" | "inline";
34
+ file: string;
35
+ content: string;
36
+ }[];
37
+ }>;
38
+ protected getSystemPrompt(): string;
39
+ protected buildUserMessage(context: AgentContext): string;
40
+ }
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ import { BaseAgent } from "./base-agent.js";
3
+ const docsResultSchema = z.object({
4
+ docs: z.array(z.object({
5
+ file: z.string(),
6
+ content: z.string(),
7
+ type: z.enum(["jsdoc", "readme", "inline"]),
8
+ })),
9
+ summary: z.string(),
10
+ });
11
+ export class DocsAgent extends BaseAgent {
12
+ name = "Docs";
13
+ description = "Generates and improves documentation for source files";
14
+ getOutputSchema() {
15
+ return docsResultSchema;
16
+ }
17
+ getSystemPrompt() {
18
+ return `You are a senior technical writer and documentation specialist. Your job is to generate clear, useful documentation for source code.
19
+
20
+ Rules:
21
+ - Generate JSDoc/TSDoc comments for exported functions, classes, and interfaces
22
+ - Write concise descriptions that explain WHAT something does and WHY, not just restating the code
23
+ - Include @param, @returns, and @example tags where helpful
24
+ - For complex modules, generate a module-level doc comment explaining the overall purpose
25
+ - Keep inline comments short and only where logic isn't self-evident
26
+ - Use the "jsdoc" type for function/class documentation
27
+ - Use the "inline" type for important inline comments
28
+ - Use the "readme" type if you generate a module README section
29
+
30
+ For each file, return the full file content with documentation added. Do not change any functional code — only add or improve documentation.
31
+
32
+ Skip files that are already well-documented or are simple re-exports.`;
33
+ }
34
+ buildUserMessage(context) {
35
+ const parts = ["Please add documentation to the following source files:\n"];
36
+ for (const file of context.files) {
37
+ parts.push(`## File: ${file.path} (${file.language})`);
38
+ parts.push("```" + file.language);
39
+ parts.push(file.content);
40
+ parts.push("```\n");
41
+ }
42
+ return parts.join("\n");
43
+ }
44
+ }
45
+ //# sourceMappingURL=docs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs.js","sourceRoot":"","sources":["../../../src/agents/docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,IAAI,EAAE,CAAC,CAAC,KAAK,CACX,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;KAC5C,CAAC,CACH;IACD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;CACpB,CAAC,CAAC;AAEH,MAAM,OAAO,SAAU,SAAQ,SAAqB;IACzC,IAAI,GAAG,MAAM,CAAC;IACd,WAAW,GAAG,uDAAuD,CAAC;IAErE,eAAe;QACvB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAES,eAAe;QACvB,OAAO;;;;;;;;;;;;;;sEAc2D,CAAC;IACrE,CAAC;IAES,gBAAgB,CAAC,OAAqB;QAC9C,MAAM,KAAK,GAAG,CAAC,2DAA2D,CAAC,CAAC;QAE5E,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ export { BaseAgent } from "./base-agent.js";
2
+ export { ReviewerAgent } from "./reviewer.js";
3
+ export { CoderAgent } from "./coder.js";
4
+ export { TesterAgent } from "./tester.js";
5
+ export { PlannerAgent } from "./planner.js";
6
+ export { DocsAgent } from "./docs.js";
@@ -0,0 +1,7 @@
1
+ export { BaseAgent } from "./base-agent.js";
2
+ export { ReviewerAgent } from "./reviewer.js";
3
+ export { CoderAgent } from "./coder.js";
4
+ export { TesterAgent } from "./tester.js";
5
+ export { PlannerAgent } from "./planner.js";
6
+ export { DocsAgent } from "./docs.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agents/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { z } from "zod";
2
+ import { BaseAgent } from "./base-agent.js";
3
+ import type { AgentContext } from "../types/index.js";
4
+ import type { PlanResult } from "../types/review.js";
5
+ export declare class PlannerAgent extends BaseAgent<PlanResult> {
6
+ readonly name = "Planner";
7
+ readonly description = "Breaks down tasks and creates implementation plans";
8
+ private taskDescription;
9
+ constructor(llmClient: ConstructorParameters<typeof BaseAgent>[0], taskDescription?: string);
10
+ protected getOutputSchema(): z.ZodObject<{
11
+ goal: z.ZodString;
12
+ tasks: z.ZodArray<z.ZodObject<{
13
+ id: z.ZodNumber;
14
+ title: z.ZodString;
15
+ description: z.ZodString;
16
+ files: z.ZodArray<z.ZodString, "many">;
17
+ priority: z.ZodEnum<["high", "medium", "low"]>;
18
+ estimatedComplexity: z.ZodEnum<["simple", "moderate", "complex"]>;
19
+ }, "strip", z.ZodTypeAny, {
20
+ title: string;
21
+ description: string;
22
+ id: number;
23
+ files: string[];
24
+ priority: "high" | "medium" | "low";
25
+ estimatedComplexity: "simple" | "moderate" | "complex";
26
+ }, {
27
+ title: string;
28
+ description: string;
29
+ id: number;
30
+ files: string[];
31
+ priority: "high" | "medium" | "low";
32
+ estimatedComplexity: "simple" | "moderate" | "complex";
33
+ }>, "many">;
34
+ risks: z.ZodArray<z.ZodString, "many">;
35
+ summary: z.ZodString;
36
+ }, "strip", z.ZodTypeAny, {
37
+ summary: string;
38
+ goal: string;
39
+ tasks: {
40
+ title: string;
41
+ description: string;
42
+ id: number;
43
+ files: string[];
44
+ priority: "high" | "medium" | "low";
45
+ estimatedComplexity: "simple" | "moderate" | "complex";
46
+ }[];
47
+ risks: string[];
48
+ }, {
49
+ summary: string;
50
+ goal: string;
51
+ tasks: {
52
+ title: string;
53
+ description: string;
54
+ id: number;
55
+ files: string[];
56
+ priority: "high" | "medium" | "low";
57
+ estimatedComplexity: "simple" | "moderate" | "complex";
58
+ }[];
59
+ risks: string[];
60
+ }>;
61
+ protected getSystemPrompt(): string;
62
+ protected buildUserMessage(context: AgentContext): string;
63
+ }