@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,179 @@
1
+ /**
2
+ * Shared utilities for Smart Runner Tools
3
+ */
4
+ import { spawn } from 'node:child_process';
5
+ import { readFile, readdir, stat } from 'node:fs/promises';
6
+ import { join } from 'node:path';
7
+ /**
8
+ * Default timeout for runner commands (5 minutes)
9
+ */
10
+ export const DEFAULT_TIMEOUT = 300000;
11
+ /**
12
+ * Maximum output size (50KB)
13
+ */
14
+ export const MAX_OUTPUT_SIZE = 50 * 1024;
15
+ /**
16
+ * Check if directory exists
17
+ */
18
+ export async function isDirectory(path) {
19
+ try {
20
+ const stats = await stat(path);
21
+ return stats.isDirectory();
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ /**
28
+ * Read package.json from a directory
29
+ */
30
+ export async function readPackageJson(dirPath) {
31
+ try {
32
+ const content = await readFile(join(dirPath, 'package.json'), 'utf-8');
33
+ return JSON.parse(content);
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ /**
40
+ * List directory entries
41
+ */
42
+ export async function listDirectory(dirPath) {
43
+ try {
44
+ return await readdir(dirPath);
45
+ }
46
+ catch {
47
+ return [];
48
+ }
49
+ }
50
+ /**
51
+ * Check if a file exists in directory
52
+ */
53
+ export function hasFile(entries, pattern) {
54
+ if (pattern.includes('*')) {
55
+ const regex = new RegExp('^' + pattern.replace(/\./g, '\\.').replace(/\*/g, '.*') + '$');
56
+ return entries.some((e) => regex.test(e));
57
+ }
58
+ return entries.includes(pattern);
59
+ }
60
+ /**
61
+ * Check if a dependency exists in package.json
62
+ */
63
+ export function hasDependency(packageJson, dep) {
64
+ if (!packageJson)
65
+ return false;
66
+ return !!(packageJson.dependencies?.[dep] || packageJson.devDependencies?.[dep]);
67
+ }
68
+ /**
69
+ * Check if a script exists in package.json
70
+ */
71
+ export function hasScript(packageJson, script) {
72
+ if (!packageJson)
73
+ return false;
74
+ return !!packageJson.scripts?.[script];
75
+ }
76
+ /**
77
+ * Run a command and capture output
78
+ */
79
+ export async function runCommand(command, args, options) {
80
+ return new Promise((resolve) => {
81
+ const startTime = Date.now();
82
+ let stdout = '';
83
+ let stderr = '';
84
+ let timedOut = false;
85
+ const proc = spawn(command, args, {
86
+ cwd: options.cwd,
87
+ shell: true,
88
+ env: { ...process.env, ...options.env },
89
+ });
90
+ const timeout = setTimeout(() => {
91
+ timedOut = true;
92
+ proc.kill('SIGTERM');
93
+ setTimeout(() => {
94
+ if (!proc.killed) {
95
+ proc.kill('SIGKILL');
96
+ }
97
+ }, 5000);
98
+ }, options.timeout);
99
+ proc.stdout.on('data', (data) => {
100
+ const chunk = data.toString();
101
+ if (stdout.length + chunk.length <= MAX_OUTPUT_SIZE) {
102
+ stdout += chunk;
103
+ }
104
+ else if (stdout.length < MAX_OUTPUT_SIZE) {
105
+ stdout += chunk.slice(0, MAX_OUTPUT_SIZE - stdout.length);
106
+ stdout += '\n... (output truncated)';
107
+ }
108
+ });
109
+ proc.stderr.on('data', (data) => {
110
+ const chunk = data.toString();
111
+ if (stderr.length + chunk.length <= MAX_OUTPUT_SIZE) {
112
+ stderr += chunk;
113
+ }
114
+ else if (stderr.length < MAX_OUTPUT_SIZE) {
115
+ stderr += chunk.slice(0, MAX_OUTPUT_SIZE - stderr.length);
116
+ stderr += '\n... (output truncated)';
117
+ }
118
+ });
119
+ proc.on('close', (code) => {
120
+ clearTimeout(timeout);
121
+ const duration = Date.now() - startTime;
122
+ if (timedOut) {
123
+ stderr += `\n(Process killed: timeout after ${String(options.timeout)}ms)`;
124
+ }
125
+ resolve({
126
+ stdout,
127
+ stderr,
128
+ exitCode: code ?? (timedOut ? 124 : 1),
129
+ duration,
130
+ });
131
+ });
132
+ proc.on('error', (error) => {
133
+ clearTimeout(timeout);
134
+ const duration = Date.now() - startTime;
135
+ resolve({
136
+ stdout,
137
+ stderr: error.message,
138
+ exitCode: 1,
139
+ duration,
140
+ });
141
+ });
142
+ });
143
+ }
144
+ /**
145
+ * Build command from template
146
+ */
147
+ export function buildCommand(template) {
148
+ if (template.useScript && template.scriptName) {
149
+ // Use npm run script
150
+ return {
151
+ command: 'npm',
152
+ args: ['run', template.scriptName, ...template.args],
153
+ };
154
+ }
155
+ if (template.useNpx) {
156
+ // Use npx to run the command
157
+ return {
158
+ command: 'npx',
159
+ args: [template.command, ...template.args],
160
+ };
161
+ }
162
+ // Direct command
163
+ return {
164
+ command: template.command,
165
+ args: template.args,
166
+ };
167
+ }
168
+ /**
169
+ * Format command for display
170
+ */
171
+ export function formatCommand(command, args) {
172
+ const escapedArgs = args.map((arg) => {
173
+ if (arg.includes(' ') || arg.includes('"')) {
174
+ return `"${arg.replace(/"/g, '\\"')}"`;
175
+ }
176
+ return arg;
177
+ });
178
+ return `${command} ${escapedArgs.join(' ')}`.trim();
179
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Find Definition Tool
3
+ * Find where a symbol is defined using regex patterns
4
+ */
5
+ import type { Tool } from '@compilr-dev/agents';
6
+ import type { FindDefinitionInput } from './types.js';
7
+ /**
8
+ * Find Definition Tool
9
+ */
10
+ export declare const findDefinitionTool: Tool<FindDefinitionInput>;
11
+ /**
12
+ * Factory function to create find definition tool with custom options
13
+ */
14
+ export declare function createFindDefinitionTool(options?: {
15
+ /** Base directory for relative paths */
16
+ baseDir?: string;
17
+ /** Default limit */
18
+ defaultLimit?: number;
19
+ }): Tool<FindDefinitionInput>;
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Find Definition Tool
3
+ * Find where a symbol is defined using regex patterns
4
+ */
5
+ import { defineTool, createSuccessResult, createErrorResult } from '@compilr-dev/agents';
6
+ import { escapeRegex, isDirectory, runGrep } from './utils.js';
7
+ const DEFINITION_PATTERNS = [
8
+ // TypeScript/JavaScript - Functions
9
+ {
10
+ pattern: '(export\\s+)?(async\\s+)?function\\s+{symbol}\\s*[(<]',
11
+ type: 'function',
12
+ extensions: ['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs'],
13
+ checkExport: true,
14
+ },
15
+ {
16
+ pattern: '(export\\s+)?(const|let|var)\\s+{symbol}\\s*=\\s*(async\\s+)?\\([^)]*\\)\\s*=>',
17
+ type: 'function',
18
+ extensions: ['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs'],
19
+ checkExport: true,
20
+ },
21
+ {
22
+ pattern: '(export\\s+)?(const|let|var)\\s+{symbol}\\s*=\\s*(async\\s+)?function',
23
+ type: 'function',
24
+ extensions: ['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs'],
25
+ checkExport: true,
26
+ },
27
+ // TypeScript/JavaScript - Classes
28
+ {
29
+ pattern: '(export\\s+)?(abstract\\s+)?class\\s+{symbol}\\s*[{<]',
30
+ type: 'class',
31
+ extensions: ['ts', 'tsx', 'js', 'jsx'],
32
+ checkExport: true,
33
+ },
34
+ // TypeScript - Interfaces and Types
35
+ {
36
+ pattern: '(export\\s+)?interface\\s+{symbol}\\s*[{<]',
37
+ type: 'interface',
38
+ extensions: ['ts', 'tsx'],
39
+ checkExport: true,
40
+ },
41
+ {
42
+ pattern: '(export\\s+)?type\\s+{symbol}\\s*[=<]',
43
+ type: 'type',
44
+ extensions: ['ts', 'tsx'],
45
+ checkExport: true,
46
+ },
47
+ // TypeScript/JavaScript - Constants and Variables
48
+ {
49
+ pattern: '(export\\s+)?const\\s+{symbol}\\s*[=:]',
50
+ type: 'const',
51
+ extensions: ['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs'],
52
+ checkExport: true,
53
+ },
54
+ {
55
+ pattern: '(export\\s+)?let\\s+{symbol}\\s*[=:]',
56
+ type: 'let',
57
+ extensions: ['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs'],
58
+ checkExport: true,
59
+ },
60
+ // TypeScript - Enums
61
+ {
62
+ pattern: '(export\\s+)?(const\\s+)?enum\\s+{symbol}\\s*\\{',
63
+ type: 'enum',
64
+ extensions: ['ts', 'tsx'],
65
+ checkExport: true,
66
+ },
67
+ // Python - Functions
68
+ {
69
+ pattern: '(async\\s+)?def\\s+{symbol}\\s*\\(',
70
+ type: 'function',
71
+ extensions: ['py'],
72
+ },
73
+ // Python - Classes
74
+ {
75
+ pattern: 'class\\s+{symbol}\\s*[:(]',
76
+ type: 'class',
77
+ extensions: ['py'],
78
+ },
79
+ // Rust - Functions
80
+ {
81
+ pattern: '(pub\\s+)?(async\\s+)?fn\\s+{symbol}\\s*[(<]',
82
+ type: 'function',
83
+ extensions: ['rs'],
84
+ },
85
+ // Rust - Structs
86
+ {
87
+ pattern: '(pub\\s+)?struct\\s+{symbol}\\s*[{<(;]',
88
+ type: 'class',
89
+ extensions: ['rs'],
90
+ },
91
+ // Rust - Enums
92
+ {
93
+ pattern: '(pub\\s+)?enum\\s+{symbol}\\s*[{<]',
94
+ type: 'enum',
95
+ extensions: ['rs'],
96
+ },
97
+ // Rust - Traits
98
+ {
99
+ pattern: '(pub\\s+)?trait\\s+{symbol}\\s*[{<:]',
100
+ type: 'interface',
101
+ extensions: ['rs'],
102
+ },
103
+ // Rust - Type aliases
104
+ {
105
+ pattern: '(pub\\s+)?type\\s+{symbol}\\s*[=<]',
106
+ type: 'type',
107
+ extensions: ['rs'],
108
+ },
109
+ // Go - Functions
110
+ {
111
+ pattern: 'func\\s+{symbol}\\s*\\(',
112
+ type: 'function',
113
+ extensions: ['go'],
114
+ },
115
+ // Go - Methods (with receiver)
116
+ {
117
+ pattern: 'func\\s+\\([^)]+\\)\\s+{symbol}\\s*\\(',
118
+ type: 'method',
119
+ extensions: ['go'],
120
+ },
121
+ // Go - Types
122
+ {
123
+ pattern: 'type\\s+{symbol}\\s+(struct|interface|func|map|\\[)',
124
+ type: 'type',
125
+ extensions: ['go'],
126
+ },
127
+ // Go - Const/Var
128
+ {
129
+ pattern: '(const|var)\\s+{symbol}\\s*[=:]',
130
+ type: 'variable',
131
+ extensions: ['go'],
132
+ },
133
+ // Java/Kotlin - Classes
134
+ {
135
+ pattern: '(public\\s+|private\\s+|protected\\s+)?(abstract\\s+|final\\s+)?class\\s+{symbol}\\s*[{<]',
136
+ type: 'class',
137
+ extensions: ['java', 'kt'],
138
+ },
139
+ // Java/Kotlin - Interfaces
140
+ {
141
+ pattern: '(public\\s+|private\\s+)?interface\\s+{symbol}\\s*[{<]',
142
+ type: 'interface',
143
+ extensions: ['java', 'kt'],
144
+ },
145
+ // Java - Methods
146
+ {
147
+ pattern: '(public|private|protected)\\s+[\\w<>\\[\\]]+\\s+{symbol}\\s*\\(',
148
+ type: 'method',
149
+ extensions: ['java'],
150
+ },
151
+ ];
152
+ /**
153
+ * Run grep/ripgrep to find definitions
154
+ */
155
+ async function searchDefinitions(symbol, cwd, fileType, limit = 20) {
156
+ const escapedSymbol = escapeRegex(symbol);
157
+ const definitions = [];
158
+ // Filter patterns by file type if specified
159
+ const patterns = fileType
160
+ ? DEFINITION_PATTERNS.filter((p) => p.extensions.includes(fileType))
161
+ : DEFINITION_PATTERNS;
162
+ // Build glob pattern for file types
163
+ const extensions = fileType
164
+ ? [fileType]
165
+ : [...new Set(DEFINITION_PATTERNS.flatMap((p) => p.extensions))];
166
+ const globPattern = extensions.length === 1 ? `**/*.${extensions[0]}` : `**/*.{${extensions.join(',')}}`;
167
+ for (const pattern of patterns) {
168
+ if (definitions.length >= limit)
169
+ break;
170
+ const regexPattern = pattern.pattern.replace('{symbol}', escapedSymbol);
171
+ try {
172
+ const args = ['-n', '--column', '--glob', globPattern, '-e', regexPattern, '.'];
173
+ const results = await runGrep(args, cwd, limit - definitions.length, true);
174
+ for (const result of results) {
175
+ // Check if file extension matches this pattern
176
+ const ext = result.file.split('.').pop() ?? '';
177
+ if (!pattern.extensions.includes(ext))
178
+ continue;
179
+ // Check if already found this location
180
+ const exists = definitions.some((d) => d.file === result.file && d.line === result.line);
181
+ if (exists)
182
+ continue;
183
+ // Determine export status
184
+ const isExported = pattern.checkExport
185
+ ? /^(export\s+|pub\s+)/.test(result.context.trim())
186
+ : undefined;
187
+ definitions.push({
188
+ file: result.file,
189
+ line: result.line,
190
+ column: result.column ?? 1,
191
+ context: result.context.trim(),
192
+ type: pattern.type,
193
+ isExported,
194
+ });
195
+ if (definitions.length >= limit)
196
+ break;
197
+ }
198
+ }
199
+ catch {
200
+ // Ignore grep errors, continue with other patterns
201
+ }
202
+ }
203
+ return definitions;
204
+ }
205
+ /**
206
+ * Execute find definition
207
+ */
208
+ async function executeFindDefinition(input) {
209
+ const targetPath = input.path ?? process.cwd();
210
+ const limit = input.limit ?? 20;
211
+ if (!input.symbol || input.symbol.trim().length === 0) {
212
+ return createErrorResult('Symbol is required');
213
+ }
214
+ if (!(await isDirectory(targetPath))) {
215
+ return createErrorResult(`Directory not found: ${targetPath}`);
216
+ }
217
+ try {
218
+ const definitions = await searchDefinitions(input.symbol.trim(), targetPath, input.fileType, limit);
219
+ const result = {
220
+ definitions,
221
+ totalFound: definitions.length,
222
+ symbol: input.symbol.trim(),
223
+ };
224
+ return createSuccessResult(result);
225
+ }
226
+ catch (error) {
227
+ return createErrorResult(error instanceof Error ? error.message : String(error));
228
+ }
229
+ }
230
+ /**
231
+ * Find Definition Tool
232
+ */
233
+ export const findDefinitionTool = defineTool({
234
+ name: 'find_definition',
235
+ description: 'Find where a symbol is defined in the codebase. ' +
236
+ 'Searches for function, class, interface, type, const, enum definitions. ' +
237
+ 'Supports TypeScript, JavaScript, Python, Rust, Go, Java, Kotlin.',
238
+ inputSchema: {
239
+ type: 'object',
240
+ properties: {
241
+ symbol: {
242
+ type: 'string',
243
+ description: 'Symbol name to find (e.g., function name, class name)',
244
+ },
245
+ path: {
246
+ type: 'string',
247
+ description: 'Working directory (default: current directory)',
248
+ },
249
+ fileType: {
250
+ type: 'string',
251
+ description: 'File type filter (e.g., ts, py, rs, go)',
252
+ },
253
+ limit: {
254
+ type: 'number',
255
+ description: 'Max results (default: 20)',
256
+ },
257
+ },
258
+ required: ['symbol'],
259
+ },
260
+ execute: executeFindDefinition,
261
+ });
262
+ /**
263
+ * Factory function to create find definition tool with custom options
264
+ */
265
+ export function createFindDefinitionTool(options) {
266
+ return defineTool({
267
+ name: 'find_definition',
268
+ description: 'Find where a symbol is defined in the codebase. ' +
269
+ 'Supports TypeScript, JavaScript, Python, Rust, Go, Java, Kotlin.',
270
+ inputSchema: {
271
+ type: 'object',
272
+ properties: {
273
+ symbol: {
274
+ type: 'string',
275
+ description: 'Symbol name to find',
276
+ },
277
+ path: {
278
+ type: 'string',
279
+ description: 'Working directory',
280
+ },
281
+ fileType: {
282
+ type: 'string',
283
+ description: 'File type filter',
284
+ },
285
+ limit: {
286
+ type: 'number',
287
+ description: 'Max results',
288
+ },
289
+ },
290
+ required: ['symbol'],
291
+ },
292
+ execute: async (input) => {
293
+ let targetPath = input.path ?? '.';
294
+ if (options?.baseDir && !targetPath.startsWith('/')) {
295
+ const nodePath = await import('node:path');
296
+ targetPath = nodePath.join(options.baseDir, targetPath);
297
+ }
298
+ return executeFindDefinition({
299
+ ...input,
300
+ path: targetPath,
301
+ limit: input.limit ?? options?.defaultLimit,
302
+ });
303
+ },
304
+ });
305
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Code Search Tools
3
+ * Find definitions, references, and TODO comments
4
+ */
5
+ export { findDefinitionTool, createFindDefinitionTool } from './definition.js';
6
+ export { findReferencesTool, createFindReferencesTool } from './references.js';
7
+ export { findTodosTool, createFindTodosTool } from './todos.js';
8
+ export type { DefinitionType, Definition, FindDefinitionInput, FindDefinitionResult, Reference, FindReferencesInput, FindReferencesResult, TodoType, TodoComment, FindTodosInput, FindTodosResult, } from './types.js';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Code Search Tools
3
+ * Find definitions, references, and TODO comments
4
+ */
5
+ // Tools
6
+ export { findDefinitionTool, createFindDefinitionTool } from './definition.js';
7
+ export { findReferencesTool, createFindReferencesTool } from './references.js';
8
+ export { findTodosTool, createFindTodosTool } from './todos.js';
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Find References Tool
3
+ * Find usages of a symbol using grep with word boundary matching
4
+ */
5
+ import type { Tool } from '@compilr-dev/agents';
6
+ import type { FindReferencesInput } from './types.js';
7
+ /**
8
+ * Find References Tool
9
+ */
10
+ export declare const findReferencesTool: Tool<FindReferencesInput>;
11
+ /**
12
+ * Factory function to create find references tool with custom options
13
+ */
14
+ export declare function createFindReferencesTool(options?: {
15
+ /** Base directory for relative paths */
16
+ baseDir?: string;
17
+ /** Default limit */
18
+ defaultLimit?: number;
19
+ }): Tool<FindReferencesInput>;