@compilr-dev/agents-coding 0.0.1

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 (60) hide show
  1. package/README.md +788 -0
  2. package/dist/index.d.ts +39 -0
  3. package/dist/index.js +75 -0
  4. package/dist/skills/index.d.ts +39 -0
  5. package/dist/skills/index.js +322 -0
  6. package/dist/tools/git/branch.d.ts +17 -0
  7. package/dist/tools/git/branch.js +264 -0
  8. package/dist/tools/git/commit.d.ts +23 -0
  9. package/dist/tools/git/commit.js +280 -0
  10. package/dist/tools/git/diff.d.ts +19 -0
  11. package/dist/tools/git/diff.js +221 -0
  12. package/dist/tools/git/index.d.ts +10 -0
  13. package/dist/tools/git/index.js +11 -0
  14. package/dist/tools/git/log.d.ts +19 -0
  15. package/dist/tools/git/log.js +235 -0
  16. package/dist/tools/git/stash.d.ts +17 -0
  17. package/dist/tools/git/stash.js +294 -0
  18. package/dist/tools/git/status.d.ts +19 -0
  19. package/dist/tools/git/status.js +160 -0
  20. package/dist/tools/git/types.d.ts +293 -0
  21. package/dist/tools/git/types.js +4 -0
  22. package/dist/tools/git/utils.d.ts +58 -0
  23. package/dist/tools/git/utils.js +197 -0
  24. package/dist/tools/index.d.ts +5 -0
  25. package/dist/tools/index.js +5 -0
  26. package/dist/tools/project/detect.d.ts +19 -0
  27. package/dist/tools/project/detect.js +341 -0
  28. package/dist/tools/project/find-root.d.ts +21 -0
  29. package/dist/tools/project/find-root.js +239 -0
  30. package/dist/tools/project/index.d.ts +6 -0
  31. package/dist/tools/project/index.js +5 -0
  32. package/dist/tools/project/types.d.ts +83 -0
  33. package/dist/tools/project/types.js +4 -0
  34. package/dist/tools/runners/build.d.ts +19 -0
  35. package/dist/tools/runners/build.js +306 -0
  36. package/dist/tools/runners/format.d.ts +19 -0
  37. package/dist/tools/runners/format.js +376 -0
  38. package/dist/tools/runners/index.d.ts +9 -0
  39. package/dist/tools/runners/index.js +9 -0
  40. package/dist/tools/runners/lint.d.ts +19 -0
  41. package/dist/tools/runners/lint.js +356 -0
  42. package/dist/tools/runners/test.d.ts +19 -0
  43. package/dist/tools/runners/test.js +386 -0
  44. package/dist/tools/runners/types.d.ts +97 -0
  45. package/dist/tools/runners/types.js +4 -0
  46. package/dist/tools/runners/utils.d.ts +69 -0
  47. package/dist/tools/runners/utils.js +179 -0
  48. package/dist/tools/search/definition.d.ts +19 -0
  49. package/dist/tools/search/definition.js +305 -0
  50. package/dist/tools/search/index.d.ts +8 -0
  51. package/dist/tools/search/index.js +8 -0
  52. package/dist/tools/search/references.d.ts +19 -0
  53. package/dist/tools/search/references.js +179 -0
  54. package/dist/tools/search/todos.d.ts +19 -0
  55. package/dist/tools/search/todos.js +269 -0
  56. package/dist/tools/search/types.d.ts +132 -0
  57. package/dist/tools/search/types.js +4 -0
  58. package/dist/tools/search/utils.d.ts +45 -0
  59. package/dist/tools/search/utils.js +152 -0
  60. package/package.json +88 -0
@@ -0,0 +1,356 @@
1
+ /**
2
+ * Run Lint Tool
3
+ * Auto-detect and run linter using the appropriate tool
4
+ */
5
+ import { defineTool, createSuccessResult, createErrorResult } from '@compilr-dev/agents';
6
+ import { isDirectory, readPackageJson, listDirectory, hasFile, hasDependency, hasScript, runCommand, buildCommand, formatCommand, DEFAULT_TIMEOUT, } from './utils.js';
7
+ const LINTERS = [
8
+ // ESLint (Node.js)
9
+ {
10
+ name: 'eslint',
11
+ detect: (entries, pkg) => hasFile(entries, 'eslint.config.js') ||
12
+ hasFile(entries, 'eslint.config.mjs') ||
13
+ hasFile(entries, 'eslint.config.cjs') ||
14
+ hasFile(entries, '.eslintrc.js') ||
15
+ hasFile(entries, '.eslintrc.json') ||
16
+ hasFile(entries, '.eslintrc.yaml') ||
17
+ hasFile(entries, '.eslintrc.yml') ||
18
+ hasFile(entries, '.eslintrc') ||
19
+ hasDependency(pkg, 'eslint'),
20
+ getCommand: (input) => {
21
+ const args = ['eslint'];
22
+ if (input.files && input.files.length > 0) {
23
+ args.push(...input.files);
24
+ }
25
+ else {
26
+ args.push('.');
27
+ }
28
+ if (input.fix)
29
+ args.push('--fix');
30
+ if (input.format)
31
+ args.push('--format', input.format);
32
+ return { command: 'npx', args, useNpx: false };
33
+ },
34
+ },
35
+ // Biome (Node.js)
36
+ {
37
+ name: 'biome',
38
+ detect: (entries, pkg) => hasFile(entries, 'biome.json') ||
39
+ hasFile(entries, 'biome.jsonc') ||
40
+ hasDependency(pkg, '@biomejs/biome'),
41
+ getCommand: (input) => {
42
+ const args = ['biome', 'lint'];
43
+ if (input.files && input.files.length > 0) {
44
+ args.push(...input.files);
45
+ }
46
+ else {
47
+ args.push('.');
48
+ }
49
+ if (input.fix)
50
+ args.push('--apply');
51
+ return { command: 'npx', args, useNpx: false };
52
+ },
53
+ },
54
+ // npm lint script fallback (Node.js)
55
+ {
56
+ name: 'npm lint',
57
+ detect: (_entries, pkg) => hasScript(pkg, 'lint'),
58
+ getCommand: (input) => {
59
+ const args = ['run', 'lint'];
60
+ if (input.fix && hasScript(null, 'lint:fix')) {
61
+ return {
62
+ command: 'npm',
63
+ args: ['run', 'lint:fix'],
64
+ useScript: true,
65
+ scriptName: 'lint:fix',
66
+ };
67
+ }
68
+ return { command: 'npm', args, useScript: true, scriptName: 'lint' };
69
+ },
70
+ },
71
+ // Ruff (Python)
72
+ {
73
+ name: 'ruff',
74
+ detect: (entries) => hasFile(entries, 'ruff.toml') || hasFile(entries, '.ruff.toml'),
75
+ getCommand: (input) => {
76
+ const args = ['check'];
77
+ if (input.files && input.files.length > 0) {
78
+ args.push(...input.files);
79
+ }
80
+ else {
81
+ args.push('.');
82
+ }
83
+ if (input.fix)
84
+ args.push('--fix');
85
+ if (input.format === 'json')
86
+ args.push('--output-format', 'json');
87
+ return { command: 'ruff', args };
88
+ },
89
+ },
90
+ // Pylint (Python)
91
+ {
92
+ name: 'pylint',
93
+ detect: (entries) => hasFile(entries, '.pylintrc') || hasFile(entries, 'pylintrc'),
94
+ getCommand: (input) => {
95
+ const args = [];
96
+ if (input.files && input.files.length > 0) {
97
+ args.push(...input.files);
98
+ }
99
+ else {
100
+ args.push('.');
101
+ }
102
+ if (input.format === 'json')
103
+ args.push('--output-format=json');
104
+ return { command: 'pylint', args };
105
+ },
106
+ },
107
+ // Flake8 (Python)
108
+ {
109
+ name: 'flake8',
110
+ detect: (entries) => hasFile(entries, '.flake8') || hasFile(entries, 'setup.cfg'),
111
+ getCommand: (input) => {
112
+ const args = [];
113
+ if (input.files && input.files.length > 0) {
114
+ args.push(...input.files);
115
+ }
116
+ else {
117
+ args.push('.');
118
+ }
119
+ if (input.format === 'json')
120
+ args.push('--format=json');
121
+ return { command: 'flake8', args };
122
+ },
123
+ },
124
+ // Clippy (Rust)
125
+ {
126
+ name: 'clippy',
127
+ detect: (entries) => hasFile(entries, 'Cargo.toml'),
128
+ getCommand: (input) => {
129
+ const args = ['clippy'];
130
+ if (input.fix)
131
+ args.push('--fix', '--allow-dirty');
132
+ args.push('--', '-D', 'warnings');
133
+ return { command: 'cargo', args };
134
+ },
135
+ },
136
+ // golangci-lint (Go)
137
+ {
138
+ name: 'golangci-lint',
139
+ detect: (entries) => hasFile(entries, '.golangci.yml') ||
140
+ hasFile(entries, '.golangci.yaml') ||
141
+ hasFile(entries, '.golangci.json') ||
142
+ hasFile(entries, 'go.mod'),
143
+ getCommand: (input) => {
144
+ const args = ['run'];
145
+ if (input.files && input.files.length > 0) {
146
+ args.push(...input.files);
147
+ }
148
+ if (input.fix)
149
+ args.push('--fix');
150
+ if (input.format === 'json')
151
+ args.push('--out-format', 'json');
152
+ return { command: 'golangci-lint', args };
153
+ },
154
+ },
155
+ ];
156
+ /**
157
+ * Run Lint Tool
158
+ */
159
+ export const runLintTool = defineTool({
160
+ name: 'run_lint',
161
+ description: 'Run linter using the auto-detected linting tool. ' +
162
+ 'Supports ESLint, Biome, Ruff, Pylint, Flake8, Clippy, golangci-lint, and npm lint scripts. ' +
163
+ 'Options: files (specific files), fix (auto-fix), format (output format).',
164
+ inputSchema: {
165
+ type: 'object',
166
+ properties: {
167
+ path: {
168
+ type: 'string',
169
+ description: 'Working directory (default: current directory)',
170
+ },
171
+ files: {
172
+ type: 'array',
173
+ items: { type: 'string' },
174
+ description: 'Specific files to lint',
175
+ },
176
+ fix: {
177
+ type: 'boolean',
178
+ description: 'Auto-fix issues (if supported)',
179
+ },
180
+ format: {
181
+ type: 'string',
182
+ description: 'Output format (json, stylish, etc.)',
183
+ },
184
+ timeout: {
185
+ type: 'number',
186
+ description: 'Timeout in milliseconds (default: 300000)',
187
+ },
188
+ dryRun: {
189
+ type: 'boolean',
190
+ description: 'Detect linter and return command without executing (default: false)',
191
+ },
192
+ },
193
+ required: [],
194
+ },
195
+ execute: executeRunLint,
196
+ });
197
+ /**
198
+ * Execute run lint
199
+ */
200
+ async function executeRunLint(input) {
201
+ const targetPath = input.path ?? process.cwd();
202
+ const timeout = input.timeout ?? DEFAULT_TIMEOUT;
203
+ // Check if directory exists
204
+ if (!(await isDirectory(targetPath))) {
205
+ return createErrorResult(`Directory not found: ${targetPath}`);
206
+ }
207
+ try {
208
+ // Read directory and package.json
209
+ const entries = await listDirectory(targetPath);
210
+ const packageJson = await readPackageJson(targetPath);
211
+ // Detect linter
212
+ let linter;
213
+ for (const l of LINTERS) {
214
+ if (l.detect(entries, packageJson)) {
215
+ linter = l;
216
+ break;
217
+ }
218
+ }
219
+ if (!linter) {
220
+ return createErrorResult('No linter detected. Supported: ESLint, Biome, Ruff, Pylint, Flake8, Clippy, golangci-lint, npm lint script.');
221
+ }
222
+ // Build command
223
+ const template = linter.getCommand(input);
224
+ const { command, args } = buildCommand(template);
225
+ const commandString = formatCommand(command, args);
226
+ // Dry run - return detected info without executing
227
+ if (input.dryRun) {
228
+ const lintResult = {
229
+ command: commandString,
230
+ output: '(dry run - command not executed)',
231
+ exitCode: 0,
232
+ duration: 0,
233
+ success: true,
234
+ linter: linter.name,
235
+ };
236
+ return createSuccessResult(lintResult);
237
+ }
238
+ // Run linter
239
+ const result = await runCommand(command, args, {
240
+ cwd: targetPath,
241
+ timeout,
242
+ env: {
243
+ FORCE_COLOR: '1',
244
+ },
245
+ });
246
+ // Combine output
247
+ const output = [result.stdout, result.stderr].filter(Boolean).join('\n');
248
+ // Parse error/warning counts from output (best effort)
249
+ const counts = parseLintCounts(output, linter.name);
250
+ const lintResult = {
251
+ command: commandString,
252
+ output,
253
+ exitCode: result.exitCode,
254
+ duration: result.duration,
255
+ success: result.exitCode === 0,
256
+ linter: linter.name,
257
+ ...counts,
258
+ };
259
+ return createSuccessResult(lintResult);
260
+ }
261
+ catch (error) {
262
+ return createErrorResult(error instanceof Error ? error.message : String(error));
263
+ }
264
+ }
265
+ /**
266
+ * Parse lint error/warning counts from output (best effort)
267
+ */
268
+ function parseLintCounts(output, _linter) {
269
+ const counts = {};
270
+ // ESLint pattern: "✖ 5 problems (3 errors, 2 warnings)"
271
+ const eslintMatch = output.match(/(\d+)\s+errors?,\s+(\d+)\s+warnings?/i);
272
+ if (eslintMatch) {
273
+ counts.errors = parseInt(eslintMatch[1], 10);
274
+ counts.warnings = parseInt(eslintMatch[2], 10);
275
+ }
276
+ // Ruff pattern: "Found 10 errors."
277
+ const ruffMatch = output.match(/Found\s+(\d+)\s+errors?/i);
278
+ if (ruffMatch) {
279
+ counts.errors = parseInt(ruffMatch[1], 10);
280
+ }
281
+ // Pylint pattern: "Your code has been rated at 8.5/10"
282
+ // Pylint doesn't give direct counts easily, but we can try
283
+ const pylintErrorMatch = output.match(/E\d{4}:/g);
284
+ if (pylintErrorMatch) {
285
+ counts.errors = pylintErrorMatch.length;
286
+ }
287
+ const pylintWarnMatch = output.match(/W\d{4}:/g);
288
+ if (pylintWarnMatch) {
289
+ counts.warnings = pylintWarnMatch.length;
290
+ }
291
+ // Clippy pattern: "error:" and "warning:"
292
+ const clippyErrorMatch = output.match(/^error(\[E\d+\])?:/gm);
293
+ if (clippyErrorMatch) {
294
+ counts.errors = clippyErrorMatch.length;
295
+ }
296
+ const clippyWarnMatch = output.match(/^warning(\[.+\])?:/gm);
297
+ if (clippyWarnMatch) {
298
+ counts.warnings = clippyWarnMatch.length;
299
+ }
300
+ // golangci-lint pattern counts errors by lines with issues
301
+ const goLintMatch = output.match(/^[^:]+:\d+:\d+:/gm);
302
+ if (goLintMatch) {
303
+ counts.errors = goLintMatch.length;
304
+ }
305
+ return counts;
306
+ }
307
+ /**
308
+ * Factory function to create run lint tool with custom options
309
+ */
310
+ export function createRunLintTool(options) {
311
+ return defineTool({
312
+ name: 'run_lint',
313
+ description: 'Run linter using the auto-detected linting tool. ' +
314
+ 'Supports ESLint, Biome, Ruff, Pylint, Flake8, Clippy, golangci-lint.',
315
+ inputSchema: {
316
+ type: 'object',
317
+ properties: {
318
+ path: {
319
+ type: 'string',
320
+ description: 'Working directory (default: current directory)',
321
+ },
322
+ files: {
323
+ type: 'array',
324
+ items: { type: 'string' },
325
+ description: 'Specific files to lint',
326
+ },
327
+ fix: {
328
+ type: 'boolean',
329
+ description: 'Auto-fix issues',
330
+ },
331
+ format: {
332
+ type: 'string',
333
+ description: 'Output format',
334
+ },
335
+ timeout: {
336
+ type: 'number',
337
+ description: 'Timeout in milliseconds',
338
+ },
339
+ },
340
+ required: [],
341
+ },
342
+ execute: async (input) => {
343
+ let targetPath = input.path ?? '.';
344
+ // Resolve relative paths
345
+ if (options?.baseDir && !targetPath.startsWith('/')) {
346
+ const nodePath = await import('node:path');
347
+ targetPath = nodePath.join(options.baseDir, targetPath);
348
+ }
349
+ return executeRunLint({
350
+ ...input,
351
+ path: targetPath,
352
+ timeout: input.timeout ?? options?.defaultTimeout,
353
+ });
354
+ },
355
+ });
356
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Run Tests Tool
3
+ * Auto-detect and run tests using the appropriate framework
4
+ */
5
+ import type { Tool } from '@compilr-dev/agents';
6
+ import type { RunTestsInput } from './types.js';
7
+ /**
8
+ * Run Tests Tool
9
+ */
10
+ export declare const runTestsTool: Tool<RunTestsInput>;
11
+ /**
12
+ * Factory function to create run tests tool with custom options
13
+ */
14
+ export declare function createRunTestsTool(options?: {
15
+ /** Base directory for relative paths */
16
+ baseDir?: string;
17
+ /** Default timeout */
18
+ defaultTimeout?: number;
19
+ }): Tool<RunTestsInput>;