coder-agent 2.0.1 → 2.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/dist/memory.js CHANGED
@@ -11,6 +11,7 @@ PRINCIPLES & SYSTEM PROTOCOLS FOR ERROR-FREE EXECUTION:
11
11
  3. Precise Target Editing: Prefer patching files (using patch_file) over complete overwriting. Ensure targeted matches are unique and match exactly, leaving existing unrelated functions/comments intact.
12
12
  4. Auto-Verification Loop: After any code or file edit, you MUST run the appropriate compiler, type-check, build script, or test tool (e.g. npm run build, npx tsc, pytest, cargo build, etc.) to verify your changes are syntactically and logically correct. If compilation fails, diagnose the error and patch it immediately.
13
13
  5. Autonomous Troubleshooting: If a command fails or times out, inspect the codebase or script to see why it hangs or fails. Do not blindly edit package scripts or configs.
14
+ 6. Automated Diagnostic Parsing: When the user pastes IDE problem diagnostics (e.g., JSON blocks containing "resource", "message", "startLineNumber"), stack traces, or compiler errors, parse the diagnostic payload autonomously. Extract the file path and line number, locate the file inside the workspace (resolving drive formats like '/c:/...' to standard local paths, or searching for the filename if needed), read the target lines, and formulate a fix. Do not ask the user for clarifying questions (such as "where is this error?") if the path and error message are already present in the diagnostic block.
14
15
 
15
16
  Guidelines:
16
17
  - Be concise in your explanations; let code and command output speak for itself.
package/dist/tools.js CHANGED
@@ -3,7 +3,15 @@ import { promisify } from "util";
3
3
  import * as fs from "fs/promises";
4
4
  import * as path from "path";
5
5
  const execAsync = promisify(exec);
6
- // ─── Tool Definitions (sent to Groq) ────────────────────────────────────────
6
+ // Helper to normalize file paths, especially handling leading slashes on Windows drive letters (e.g. /c:/... -> c:/...)
7
+ function normalizeFilePath(p) {
8
+ let normalized = p;
9
+ if (process.platform === "win32" && /^\/[a-zA-Z]:/.test(normalized)) {
10
+ normalized = normalized.slice(1);
11
+ }
12
+ return path.normalize(normalized);
13
+ }
14
+ // ─── Tool Definitions (sent to Gemini) ───────────────────────────────────────
7
15
  export const TOOL_DEFINITIONS = [
8
16
  {
9
17
  type: "function",
@@ -90,7 +98,7 @@ export const TOOL_DEFINITIONS = [
90
98
  },
91
99
  required: ["query"]
92
100
  }
93
- }
101
+ },
94
102
  },
95
103
  {
96
104
  type: "function",
@@ -106,7 +114,7 @@ export const TOOL_DEFINITIONS = [
106
114
  },
107
115
  required: ["file_path", "start_line", "end_line"]
108
116
  }
109
- }
117
+ },
110
118
  },
111
119
  {
112
120
  type: "function",
@@ -121,7 +129,7 @@ export const TOOL_DEFINITIONS = [
121
129
  },
122
130
  required: ["query"]
123
131
  }
124
- }
132
+ },
125
133
  },
126
134
  {
127
135
  type: "function",
@@ -137,13 +145,14 @@ export const TOOL_DEFINITIONS = [
137
145
  },
138
146
  required: ["file_path", "target_code", "replacement_code"]
139
147
  }
140
- }
148
+ },
141
149
  }
142
150
  ];
143
151
  // ─── Tool Implementations ────────────────────────────────────────────────────
144
152
  export async function read_file({ file_path }) {
145
153
  try {
146
- const content = await fs.readFile(file_path, "utf-8");
154
+ const targetPath = normalizeFilePath(file_path);
155
+ const content = await fs.readFile(targetPath, "utf-8");
147
156
  return content;
148
157
  }
149
158
  catch (e) {
@@ -152,9 +161,10 @@ export async function read_file({ file_path }) {
152
161
  }
153
162
  export async function write_file({ file_path, content }) {
154
163
  try {
155
- await fs.mkdir(path.dirname(file_path), { recursive: true });
156
- await fs.writeFile(file_path, content, "utf-8");
157
- return `✓ Written ${content.length} chars to ${file_path}`;
164
+ const targetPath = normalizeFilePath(file_path);
165
+ await fs.mkdir(path.dirname(targetPath), { recursive: true });
166
+ await fs.writeFile(targetPath, content, "utf-8");
167
+ return `✓ Written ${content.length} chars to ${targetPath}`;
158
168
  }
159
169
  catch (e) {
160
170
  return `ERROR: ${e.message}`;
@@ -162,7 +172,8 @@ export async function write_file({ file_path, content }) {
162
172
  }
163
173
  export async function list_directory({ dir_path = "." }) {
164
174
  try {
165
- const entries = await fs.readdir(dir_path, { withFileTypes: true });
175
+ const targetPath = normalizeFilePath(dir_path);
176
+ const entries = await fs.readdir(targetPath, { withFileTypes: true });
166
177
  const lines = entries.map((e) => `${e.isDirectory() ? "📁" : "📄"} ${e.name}`);
167
178
  return lines.join("\n") || "(empty)";
168
179
  }
@@ -174,12 +185,13 @@ export async function run_shell({ command, cwd }) {
174
185
  try {
175
186
  let targetCwd = process.cwd();
176
187
  if (cwd) {
188
+ const targetCwdPath = normalizeFilePath(cwd);
177
189
  try {
178
- const stats = await fs.stat(cwd);
190
+ const stats = await fs.stat(targetCwdPath);
179
191
  if (!stats.isDirectory()) {
180
192
  return `ERROR: The specified working directory (cwd) "${cwd}" is a file, not a directory.`;
181
193
  }
182
- targetCwd = path.resolve(cwd);
194
+ targetCwd = path.resolve(targetCwdPath);
183
195
  }
184
196
  catch (err) {
185
197
  return `ERROR: The specified working directory (cwd) "${cwd}" does not exist. Please specify a valid, existing directory path or omit 'cwd'.`;
@@ -225,7 +237,7 @@ async function walkDir(dir, fileList = []) {
225
237
  const entries = await fs.readdir(dir, { withFileTypes: true });
226
238
  for (const entry of entries) {
227
239
  const fullPath = path.join(dir, entry.name);
228
- if (["node_modules", ".git", "dist", "build", "__pycache__", ".next", "out"].includes(entry.name)) {
240
+ if (["node_modules", ".git", "dist", "build", "__pycache__", ".next", "out", ".coder", ".gemini-agent", ".groq-agent"].includes(entry.name)) {
229
241
  continue;
230
242
  }
231
243
  if (entry.isDirectory()) {
@@ -241,10 +253,11 @@ async function walkDir(dir, fileList = []) {
241
253
  }
242
254
  export async function find_files({ query, dir_path = "." }) {
243
255
  try {
244
- const allFiles = await walkDir(dir_path);
256
+ const targetPath = normalizeFilePath(dir_path);
257
+ const allFiles = await walkDir(targetPath);
245
258
  const lowercaseQuery = query.toLowerCase();
246
259
  const matches = allFiles
247
- .map(f => path.relative(dir_path, f))
260
+ .map(f => path.relative(targetPath, f))
248
261
  .filter(f => f.toLowerCase().includes(lowercaseQuery));
249
262
  if (matches.length === 0) {
250
263
  return `No files found matching: "${query}"`;
@@ -257,7 +270,8 @@ export async function find_files({ query, dir_path = "." }) {
257
270
  }
258
271
  export async function read_file_lines({ file_path, start_line, end_line }) {
259
272
  try {
260
- const content = await fs.readFile(file_path, "utf-8");
273
+ const targetPath = normalizeFilePath(file_path);
274
+ const content = await fs.readFile(targetPath, "utf-8");
261
275
  const lines = content.split(/\r?\n/);
262
276
  const totalLines = lines.length;
263
277
  const start = Math.max(1, start_line);
@@ -309,7 +323,8 @@ export async function search_grep({ query, is_regex = false }) {
309
323
  }
310
324
  export async function patch_file({ file_path, target_code, replacement_code }) {
311
325
  try {
312
- const content = await fs.readFile(file_path, "utf-8");
326
+ const targetPath = normalizeFilePath(file_path);
327
+ const content = await fs.readFile(targetPath, "utf-8");
313
328
  if (!content.includes(target_code)) {
314
329
  return `ERROR: Target code not found in file ${file_path}. Please verify target content.`;
315
330
  }
@@ -318,7 +333,7 @@ export async function patch_file({ file_path, target_code, replacement_code }) {
318
333
  return `ERROR: Target code matches ${occurrences} times in file ${file_path}. Please provide more unique context to target the exact edit.`;
319
334
  }
320
335
  const newContent = content.replace(target_code, replacement_code);
321
- await fs.writeFile(file_path, newContent, "utf-8");
336
+ await fs.writeFile(targetPath, newContent, "utf-8");
322
337
  return `✓ Patched file ${file_path} successfully.`;
323
338
  }
324
339
  catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coder-agent",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "CLI coding agent powered by Google Gemini",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",