@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,376 @@
1
+ /**
2
+ * Run Format Tool
3
+ * Auto-detect and run formatter 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 FORMATTERS = [
8
+ // Prettier (Node.js)
9
+ {
10
+ name: 'prettier',
11
+ detect: (entries, pkg) => hasFile(entries, '.prettierrc') ||
12
+ hasFile(entries, '.prettierrc.js') ||
13
+ hasFile(entries, '.prettierrc.json') ||
14
+ hasFile(entries, '.prettierrc.yaml') ||
15
+ hasFile(entries, '.prettierrc.yml') ||
16
+ hasFile(entries, 'prettier.config.js') ||
17
+ hasFile(entries, 'prettier.config.mjs') ||
18
+ hasDependency(pkg, 'prettier'),
19
+ getCommand: (input) => {
20
+ const args = ['prettier'];
21
+ if (input.check) {
22
+ args.push('--check');
23
+ }
24
+ else {
25
+ args.push('--write');
26
+ }
27
+ if (input.files && input.files.length > 0) {
28
+ args.push(...input.files);
29
+ }
30
+ else {
31
+ args.push('.');
32
+ }
33
+ return { command: 'npx', args, useNpx: false };
34
+ },
35
+ },
36
+ // Biome (Node.js)
37
+ {
38
+ name: 'biome',
39
+ detect: (entries, pkg) => hasFile(entries, 'biome.json') ||
40
+ hasFile(entries, 'biome.jsonc') ||
41
+ hasDependency(pkg, '@biomejs/biome'),
42
+ getCommand: (input) => {
43
+ const args = ['biome', 'format'];
44
+ if (!input.check) {
45
+ args.push('--write');
46
+ }
47
+ if (input.files && input.files.length > 0) {
48
+ args.push(...input.files);
49
+ }
50
+ else {
51
+ args.push('.');
52
+ }
53
+ return { command: 'npx', args, useNpx: false };
54
+ },
55
+ },
56
+ // dprint (Node.js)
57
+ {
58
+ name: 'dprint',
59
+ detect: (entries, pkg) => hasFile(entries, 'dprint.json') ||
60
+ hasFile(entries, '.dprint.json') ||
61
+ hasDependency(pkg, 'dprint'),
62
+ getCommand: (input) => {
63
+ const args = ['dprint'];
64
+ if (input.check) {
65
+ args.push('check');
66
+ }
67
+ else {
68
+ args.push('fmt');
69
+ }
70
+ if (input.files && input.files.length > 0) {
71
+ args.push(...input.files);
72
+ }
73
+ return { command: 'npx', args, useNpx: false };
74
+ },
75
+ },
76
+ // npm format script fallback (Node.js)
77
+ {
78
+ name: 'npm format',
79
+ detect: (_entries, pkg) => hasScript(pkg, 'format'),
80
+ getCommand: (input) => {
81
+ if (input.check && hasScript(null, 'format:check')) {
82
+ return {
83
+ command: 'npm',
84
+ args: ['run', 'format:check'],
85
+ useScript: true,
86
+ scriptName: 'format:check',
87
+ };
88
+ }
89
+ return { command: 'npm', args: ['run', 'format'], useScript: true, scriptName: 'format' };
90
+ },
91
+ },
92
+ // Black (Python)
93
+ {
94
+ name: 'black',
95
+ detect: (entries) => hasFile(entries, 'pyproject.toml') || hasFile(entries, '.black'),
96
+ getCommand: (input) => {
97
+ const args = [];
98
+ if (input.check)
99
+ args.push('--check');
100
+ if (input.files && input.files.length > 0) {
101
+ args.push(...input.files);
102
+ }
103
+ else {
104
+ args.push('.');
105
+ }
106
+ return { command: 'black', args };
107
+ },
108
+ },
109
+ // Ruff format (Python)
110
+ {
111
+ name: 'ruff format',
112
+ detect: (entries) => hasFile(entries, 'ruff.toml') || hasFile(entries, '.ruff.toml'),
113
+ getCommand: (input) => {
114
+ const args = ['format'];
115
+ if (input.check)
116
+ args.push('--check');
117
+ if (input.files && input.files.length > 0) {
118
+ args.push(...input.files);
119
+ }
120
+ else {
121
+ args.push('.');
122
+ }
123
+ return { command: 'ruff', args };
124
+ },
125
+ },
126
+ // autopep8 (Python)
127
+ {
128
+ name: 'autopep8',
129
+ detect: (entries) => hasFile(entries, '.pep8') || hasFile(entries, 'setup.cfg'),
130
+ getCommand: (input) => {
131
+ const args = [];
132
+ if (input.check) {
133
+ args.push('--diff');
134
+ }
135
+ else {
136
+ args.push('--in-place');
137
+ }
138
+ args.push('--recursive');
139
+ if (input.files && input.files.length > 0) {
140
+ args.push(...input.files);
141
+ }
142
+ else {
143
+ args.push('.');
144
+ }
145
+ return { command: 'autopep8', args };
146
+ },
147
+ },
148
+ // rustfmt (Rust)
149
+ {
150
+ name: 'rustfmt',
151
+ detect: (entries) => hasFile(entries, 'Cargo.toml'),
152
+ getCommand: (input) => {
153
+ const args = ['fmt'];
154
+ if (input.check)
155
+ args.push('--check');
156
+ return { command: 'cargo', args };
157
+ },
158
+ },
159
+ // gofmt (Go)
160
+ {
161
+ name: 'gofmt',
162
+ detect: (entries) => hasFile(entries, 'go.mod'),
163
+ getCommand: (input) => {
164
+ const args = [];
165
+ if (input.check) {
166
+ args.push('-l');
167
+ }
168
+ else {
169
+ args.push('-w');
170
+ }
171
+ if (input.files && input.files.length > 0) {
172
+ args.push(...input.files);
173
+ }
174
+ else {
175
+ args.push('.');
176
+ }
177
+ return { command: 'gofmt', args };
178
+ },
179
+ },
180
+ // goimports (Go) - preferred over gofmt
181
+ {
182
+ name: 'goimports',
183
+ detect: (entries) => hasFile(entries, 'go.mod'),
184
+ getCommand: (input) => {
185
+ const args = [];
186
+ if (input.check) {
187
+ args.push('-l');
188
+ }
189
+ else {
190
+ args.push('-w');
191
+ }
192
+ if (input.files && input.files.length > 0) {
193
+ args.push(...input.files);
194
+ }
195
+ else {
196
+ args.push('.');
197
+ }
198
+ return { command: 'goimports', args };
199
+ },
200
+ },
201
+ ];
202
+ /**
203
+ * Run Format Tool
204
+ */
205
+ export const runFormatTool = defineTool({
206
+ name: 'run_format',
207
+ description: 'Run formatter using the auto-detected formatting tool. ' +
208
+ 'Supports Prettier, Biome, dprint, Black, Ruff, rustfmt, gofmt, and npm format scripts. ' +
209
+ "Options: files (specific files), check (check only, don't write).",
210
+ inputSchema: {
211
+ type: 'object',
212
+ properties: {
213
+ path: {
214
+ type: 'string',
215
+ description: 'Working directory (default: current directory)',
216
+ },
217
+ files: {
218
+ type: 'array',
219
+ items: { type: 'string' },
220
+ description: 'Specific files to format',
221
+ },
222
+ check: {
223
+ type: 'boolean',
224
+ description: "Check only, don't write changes",
225
+ },
226
+ timeout: {
227
+ type: 'number',
228
+ description: 'Timeout in milliseconds (default: 300000)',
229
+ },
230
+ dryRun: {
231
+ type: 'boolean',
232
+ description: 'Detect formatter and return command without executing (default: false)',
233
+ },
234
+ },
235
+ required: [],
236
+ },
237
+ execute: executeRunFormat,
238
+ });
239
+ /**
240
+ * Execute run format
241
+ */
242
+ async function executeRunFormat(input) {
243
+ const targetPath = input.path ?? process.cwd();
244
+ const timeout = input.timeout ?? DEFAULT_TIMEOUT;
245
+ // Check if directory exists
246
+ if (!(await isDirectory(targetPath))) {
247
+ return createErrorResult(`Directory not found: ${targetPath}`);
248
+ }
249
+ try {
250
+ // Read directory and package.json
251
+ const entries = await listDirectory(targetPath);
252
+ const packageJson = await readPackageJson(targetPath);
253
+ // Detect formatter
254
+ let formatter;
255
+ for (const f of FORMATTERS) {
256
+ if (f.detect(entries, packageJson)) {
257
+ formatter = f;
258
+ break;
259
+ }
260
+ }
261
+ if (!formatter) {
262
+ return createErrorResult('No formatter detected. Supported: Prettier, Biome, dprint, Black, Ruff, rustfmt, gofmt, npm format script.');
263
+ }
264
+ // Build command
265
+ const template = formatter.getCommand(input);
266
+ const { command, args } = buildCommand(template);
267
+ const commandString = formatCommand(command, args);
268
+ // Dry run - return detected info without executing
269
+ if (input.dryRun) {
270
+ const formatResult = {
271
+ command: commandString,
272
+ output: '(dry run - command not executed)',
273
+ exitCode: 0,
274
+ duration: 0,
275
+ success: true,
276
+ formatter: formatter.name,
277
+ };
278
+ return createSuccessResult(formatResult);
279
+ }
280
+ // Run formatter
281
+ const result = await runCommand(command, args, {
282
+ cwd: targetPath,
283
+ timeout,
284
+ });
285
+ // Combine output
286
+ const output = [result.stdout, result.stderr].filter(Boolean).join('\n');
287
+ // Parse file count from output (best effort)
288
+ const filesProcessed = parseFormatFileCount(output, formatter.name);
289
+ const formatResult = {
290
+ command: commandString,
291
+ output,
292
+ exitCode: result.exitCode,
293
+ duration: result.duration,
294
+ success: result.exitCode === 0,
295
+ formatter: formatter.name,
296
+ filesProcessed,
297
+ };
298
+ return createSuccessResult(formatResult);
299
+ }
300
+ catch (error) {
301
+ return createErrorResult(error instanceof Error ? error.message : String(error));
302
+ }
303
+ }
304
+ /**
305
+ * Parse file count from format output (best effort)
306
+ */
307
+ function parseFormatFileCount(output, _formatter) {
308
+ // Prettier pattern: "N files changed" or lists files
309
+ const prettierMatch = output.match(/(\d+)\s+files?\s+(changed|formatted)/i);
310
+ if (prettierMatch) {
311
+ return parseInt(prettierMatch[1], 10);
312
+ }
313
+ // Count lines that look like file paths
314
+ const fileLines = output.split('\n').filter((line) => {
315
+ // Skip empty lines and common noise
316
+ const trimmed = line.trim();
317
+ if (!trimmed)
318
+ return false;
319
+ if (trimmed.startsWith('['))
320
+ return false; // Log prefixes
321
+ if (trimmed.startsWith('Checking') || trimmed.startsWith('Formatting'))
322
+ return false;
323
+ // Check if line looks like a file path
324
+ return /\.(ts|tsx|js|jsx|py|rs|go|java|json|md|css|scss|html)$/i.test(trimmed);
325
+ });
326
+ if (fileLines.length > 0) {
327
+ return fileLines.length;
328
+ }
329
+ return undefined;
330
+ }
331
+ /**
332
+ * Factory function to create run format tool with custom options
333
+ */
334
+ export function createRunFormatTool(options) {
335
+ return defineTool({
336
+ name: 'run_format',
337
+ description: 'Run formatter using the auto-detected formatting tool. ' +
338
+ 'Supports Prettier, Biome, dprint, Black, Ruff, rustfmt, gofmt.',
339
+ inputSchema: {
340
+ type: 'object',
341
+ properties: {
342
+ path: {
343
+ type: 'string',
344
+ description: 'Working directory (default: current directory)',
345
+ },
346
+ files: {
347
+ type: 'array',
348
+ items: { type: 'string' },
349
+ description: 'Specific files to format',
350
+ },
351
+ check: {
352
+ type: 'boolean',
353
+ description: "Check only, don't write changes",
354
+ },
355
+ timeout: {
356
+ type: 'number',
357
+ description: 'Timeout in milliseconds',
358
+ },
359
+ },
360
+ required: [],
361
+ },
362
+ execute: async (input) => {
363
+ let targetPath = input.path ?? '.';
364
+ // Resolve relative paths
365
+ if (options?.baseDir && !targetPath.startsWith('/')) {
366
+ const nodePath = await import('node:path');
367
+ targetPath = nodePath.join(options.baseDir, targetPath);
368
+ }
369
+ return executeRunFormat({
370
+ ...input,
371
+ path: targetPath,
372
+ timeout: input.timeout ?? options?.defaultTimeout,
373
+ });
374
+ },
375
+ });
376
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Smart Runner Tools
3
+ * Auto-detect and run tests, lint, build, and format
4
+ */
5
+ export { runTestsTool, createRunTestsTool } from './test.js';
6
+ export { runLintTool, createRunLintTool } from './lint.js';
7
+ export { runBuildTool, createRunBuildTool } from './build.js';
8
+ export { runFormatTool, createRunFormatTool } from './format.js';
9
+ export type { BaseRunnerInput, BaseRunnerResult, RunTestsInput, RunTestsResult, RunLintInput, RunLintResult, RunBuildInput, RunBuildResult, RunFormatInput, RunFormatResult, } from './types.js';
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Smart Runner Tools
3
+ * Auto-detect and run tests, lint, build, and format
4
+ */
5
+ // Tools
6
+ export { runTestsTool, createRunTestsTool } from './test.js';
7
+ export { runLintTool, createRunLintTool } from './lint.js';
8
+ export { runBuildTool, createRunBuildTool } from './build.js';
9
+ export { runFormatTool, createRunFormatTool } from './format.js';
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Run Lint Tool
3
+ * Auto-detect and run linter using the appropriate tool
4
+ */
5
+ import type { Tool } from '@compilr-dev/agents';
6
+ import type { RunLintInput } from './types.js';
7
+ /**
8
+ * Run Lint Tool
9
+ */
10
+ export declare const runLintTool: Tool<RunLintInput>;
11
+ /**
12
+ * Factory function to create run lint tool with custom options
13
+ */
14
+ export declare function createRunLintTool(options?: {
15
+ /** Base directory for relative paths */
16
+ baseDir?: string;
17
+ /** Default timeout */
18
+ defaultTimeout?: number;
19
+ }): Tool<RunLintInput>;