@compilr-dev/agents-coding-go 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.
- package/LICENSE +21 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/parser/go-parser.d.ts +104 -0
- package/dist/parser/go-parser.d.ts.map +1 -0
- package/dist/parser/go-parser.js +492 -0
- package/dist/parser/index.d.ts +6 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +5 -0
- package/dist/parser/node-types.d.ts +130 -0
- package/dist/parser/node-types.d.ts.map +1 -0
- package/dist/parser/node-types.js +4 -0
- package/dist/skills/go-best-practices.d.ts +7 -0
- package/dist/skills/go-best-practices.d.ts.map +1 -0
- package/dist/skills/go-best-practices.js +78 -0
- package/dist/skills/go-code-health.d.ts +7 -0
- package/dist/skills/go-code-health.d.ts.map +1 -0
- package/dist/skills/go-code-health.js +209 -0
- package/dist/skills/go-code-structure.d.ts +7 -0
- package/dist/skills/go-code-structure.d.ts.map +1 -0
- package/dist/skills/go-code-structure.js +155 -0
- package/dist/skills/go-dependency-audit.d.ts +7 -0
- package/dist/skills/go-dependency-audit.d.ts.map +1 -0
- package/dist/skills/go-dependency-audit.js +246 -0
- package/dist/skills/go-refactor-impact.d.ts +7 -0
- package/dist/skills/go-refactor-impact.d.ts.map +1 -0
- package/dist/skills/go-refactor-impact.js +232 -0
- package/dist/skills/index.d.ts +26 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +36 -0
- package/dist/tools/extract-docstrings.d.ts +51 -0
- package/dist/tools/extract-docstrings.d.ts.map +1 -0
- package/dist/tools/extract-docstrings.js +292 -0
- package/dist/tools/find-dead-code.d.ts +62 -0
- package/dist/tools/find-dead-code.d.ts.map +1 -0
- package/dist/tools/find-dead-code.js +422 -0
- package/dist/tools/find-duplicates.d.ts +65 -0
- package/dist/tools/find-duplicates.d.ts.map +1 -0
- package/dist/tools/find-duplicates.js +289 -0
- package/dist/tools/find-implementations.d.ts +71 -0
- package/dist/tools/find-implementations.d.ts.map +1 -0
- package/dist/tools/find-implementations.js +342 -0
- package/dist/tools/find-patterns.d.ts +71 -0
- package/dist/tools/find-patterns.d.ts.map +1 -0
- package/dist/tools/find-patterns.js +477 -0
- package/dist/tools/find-references.d.ts +66 -0
- package/dist/tools/find-references.d.ts.map +1 -0
- package/dist/tools/find-references.js +306 -0
- package/dist/tools/find-symbol.d.ts +86 -0
- package/dist/tools/find-symbol.d.ts.map +1 -0
- package/dist/tools/find-symbol.js +380 -0
- package/dist/tools/get-call-graph.d.ts +89 -0
- package/dist/tools/get-call-graph.d.ts.map +1 -0
- package/dist/tools/get-call-graph.js +431 -0
- package/dist/tools/get-class-hierarchy.d.ts +34 -0
- package/dist/tools/get-class-hierarchy.d.ts.map +1 -0
- package/dist/tools/get-class-hierarchy.js +250 -0
- package/dist/tools/get-complexity.d.ts +53 -0
- package/dist/tools/get-complexity.d.ts.map +1 -0
- package/dist/tools/get-complexity.js +357 -0
- package/dist/tools/get-dependency-graph.d.ts +85 -0
- package/dist/tools/get-dependency-graph.d.ts.map +1 -0
- package/dist/tools/get-dependency-graph.js +389 -0
- package/dist/tools/get-exports.d.ts +78 -0
- package/dist/tools/get-exports.d.ts.map +1 -0
- package/dist/tools/get-exports.js +437 -0
- package/dist/tools/get-file-structure.d.ts +28 -0
- package/dist/tools/get-file-structure.d.ts.map +1 -0
- package/dist/tools/get-file-structure.js +172 -0
- package/dist/tools/get-imports.d.ts +30 -0
- package/dist/tools/get-imports.d.ts.map +1 -0
- package/dist/tools/get-imports.js +420 -0
- package/dist/tools/get-signature.d.ts +100 -0
- package/dist/tools/get-signature.d.ts.map +1 -0
- package/dist/tools/get-signature.js +800 -0
- package/dist/tools/index.d.ts +55 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +75 -0
- package/dist/tools/types.d.ts +408 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +4 -0
- package/package.json +86 -0
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* getExports Tool
|
|
3
|
+
*
|
|
4
|
+
* Get all exports from a Go package.
|
|
5
|
+
* Analyzes __all__ declarations and identifies public API.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from "node:fs/promises";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import { defineTool, createSuccessResult, createErrorResult, } from "@compilr-dev/agents";
|
|
10
|
+
import { parseFile, parseFunction, parseClass } from "../parser/go-parser.js";
|
|
11
|
+
// Tool description
|
|
12
|
+
const TOOL_DESCRIPTION = `Get all exports from a Go package.
|
|
13
|
+
Analyzes __all__ declarations and identifies public API surface.
|
|
14
|
+
Use this to understand what a module exposes to other modules.`;
|
|
15
|
+
// Tool input schema
|
|
16
|
+
const TOOL_INPUT_SCHEMA = {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
path: {
|
|
20
|
+
type: "string",
|
|
21
|
+
description: "File to analyze",
|
|
22
|
+
},
|
|
23
|
+
includeReExports: {
|
|
24
|
+
type: "boolean",
|
|
25
|
+
description: "Include re-exports from imports (default: true)",
|
|
26
|
+
default: true,
|
|
27
|
+
},
|
|
28
|
+
includePrivate: {
|
|
29
|
+
type: "boolean",
|
|
30
|
+
description: "Include private symbols with _ prefix (default: false)",
|
|
31
|
+
default: false,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
required: ["path"],
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* getExports tool
|
|
38
|
+
*/
|
|
39
|
+
export const getExportsTool = defineTool({
|
|
40
|
+
name: "get_exports_go",
|
|
41
|
+
description: TOOL_DESCRIPTION,
|
|
42
|
+
inputSchema: TOOL_INPUT_SCHEMA,
|
|
43
|
+
execute: executeGetExports,
|
|
44
|
+
});
|
|
45
|
+
/**
|
|
46
|
+
* Execute the getExports tool
|
|
47
|
+
*/
|
|
48
|
+
async function executeGetExports(input) {
|
|
49
|
+
const { path: inputPath, includeReExports = true, includePrivate = false, } = input;
|
|
50
|
+
// Validate input
|
|
51
|
+
if (!inputPath || inputPath.trim().length === 0) {
|
|
52
|
+
return createErrorResult("Path is required");
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const resolvedPath = path.resolve(inputPath);
|
|
56
|
+
// Check if file exists
|
|
57
|
+
try {
|
|
58
|
+
await fs.access(resolvedPath);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return createErrorResult(`File not found: ${resolvedPath}`);
|
|
62
|
+
}
|
|
63
|
+
const stats = await fs.stat(resolvedPath);
|
|
64
|
+
if (!stats.isFile()) {
|
|
65
|
+
return createErrorResult(`Path must be a file: ${resolvedPath}`);
|
|
66
|
+
}
|
|
67
|
+
if (!resolvedPath.endsWith(".go")) {
|
|
68
|
+
return createErrorResult("File must be a Go file (.go)");
|
|
69
|
+
}
|
|
70
|
+
// Analyze the file
|
|
71
|
+
const result = await analyzeExports(resolvedPath, includeReExports, includePrivate);
|
|
72
|
+
return createSuccessResult({
|
|
73
|
+
...result,
|
|
74
|
+
path: resolvedPath,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
79
|
+
return createErrorResult(`Failed to analyze exports: ${message}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Analyze exports in a Go file
|
|
84
|
+
*/
|
|
85
|
+
async function analyzeExports(filePath, includeReExports, includePrivate) {
|
|
86
|
+
const parseResult = await parseFile(filePath);
|
|
87
|
+
const { tree, source } = parseResult;
|
|
88
|
+
const allDeclaration = [];
|
|
89
|
+
const publicExports = [];
|
|
90
|
+
const privateSymbols = [];
|
|
91
|
+
const reExports = [];
|
|
92
|
+
// Track names in __all__
|
|
93
|
+
const allNames = new Set();
|
|
94
|
+
// First pass: find __all__ declaration
|
|
95
|
+
for (const child of tree.rootNode.children) {
|
|
96
|
+
if (child.type === "expression_statement") {
|
|
97
|
+
const expr = child.children[0];
|
|
98
|
+
if (expr?.type === "assignment") {
|
|
99
|
+
const left = expr.childForFieldName("left");
|
|
100
|
+
if (left?.text === "__all__") {
|
|
101
|
+
const right = expr.childForFieldName("right");
|
|
102
|
+
if (right) {
|
|
103
|
+
const names = extractAllNames(right);
|
|
104
|
+
names.forEach((n) => {
|
|
105
|
+
allDeclaration.push(n);
|
|
106
|
+
allNames.add(n);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Second pass: extract all module-level definitions
|
|
114
|
+
for (const child of tree.rootNode.children) {
|
|
115
|
+
// Function definitions
|
|
116
|
+
if (child.type === "function_definition") {
|
|
117
|
+
const funcInfo = parseFunction(child, source);
|
|
118
|
+
const isPrivate = funcInfo.name.startsWith("_");
|
|
119
|
+
const inAll = allNames.has(funcInfo.name);
|
|
120
|
+
const symbol = {
|
|
121
|
+
name: funcInfo.name,
|
|
122
|
+
kind: "function",
|
|
123
|
+
line: funcInfo.line,
|
|
124
|
+
signature: buildFunctionSignature(child, source),
|
|
125
|
+
docstring: extractDocstring(child),
|
|
126
|
+
isPrivate,
|
|
127
|
+
inAll,
|
|
128
|
+
};
|
|
129
|
+
if (isPrivate && !inAll) {
|
|
130
|
+
if (includePrivate)
|
|
131
|
+
privateSymbols.push(symbol);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
publicExports.push(symbol);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Async function definitions
|
|
138
|
+
else if (child.type === "async_function_definition") {
|
|
139
|
+
const funcDef = child.children.find((c) => c.type === "function_definition");
|
|
140
|
+
if (funcDef) {
|
|
141
|
+
const funcInfo = parseFunction(funcDef, source);
|
|
142
|
+
const isPrivate = funcInfo.name.startsWith("_");
|
|
143
|
+
const inAll = allNames.has(funcInfo.name);
|
|
144
|
+
const symbol = {
|
|
145
|
+
name: funcInfo.name,
|
|
146
|
+
kind: "async_function",
|
|
147
|
+
line: funcInfo.line,
|
|
148
|
+
signature: `async ${buildFunctionSignature(funcDef, source)}`,
|
|
149
|
+
docstring: extractDocstring(funcDef),
|
|
150
|
+
isPrivate,
|
|
151
|
+
inAll,
|
|
152
|
+
};
|
|
153
|
+
if (isPrivate && !inAll) {
|
|
154
|
+
if (includePrivate)
|
|
155
|
+
privateSymbols.push(symbol);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
publicExports.push(symbol);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Class definitions
|
|
163
|
+
else if (child.type === "class_definition") {
|
|
164
|
+
const classInfo = parseClass(child, source);
|
|
165
|
+
const isPrivate = classInfo.name.startsWith("_");
|
|
166
|
+
const inAll = allNames.has(classInfo.name);
|
|
167
|
+
const symbol = {
|
|
168
|
+
name: classInfo.name,
|
|
169
|
+
kind: "class",
|
|
170
|
+
line: classInfo.line,
|
|
171
|
+
signature: buildClassSignature(child, source),
|
|
172
|
+
docstring: extractDocstring(child),
|
|
173
|
+
isPrivate,
|
|
174
|
+
inAll,
|
|
175
|
+
};
|
|
176
|
+
if (isPrivate && !inAll) {
|
|
177
|
+
if (includePrivate)
|
|
178
|
+
privateSymbols.push(symbol);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
publicExports.push(symbol);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Decorated definitions
|
|
185
|
+
else if (child.type === "decorated_definition") {
|
|
186
|
+
const definition = child.children.find((c) => c.type === "function_definition" ||
|
|
187
|
+
c.type === "async_function_definition" ||
|
|
188
|
+
c.type === "class_definition");
|
|
189
|
+
if (definition) {
|
|
190
|
+
if (definition.type === "class_definition") {
|
|
191
|
+
const classInfo = parseClass(definition, source);
|
|
192
|
+
const isPrivate = classInfo.name.startsWith("_");
|
|
193
|
+
const inAll = allNames.has(classInfo.name);
|
|
194
|
+
const symbol = {
|
|
195
|
+
name: classInfo.name,
|
|
196
|
+
kind: "class",
|
|
197
|
+
line: classInfo.line,
|
|
198
|
+
signature: buildClassSignature(definition, source),
|
|
199
|
+
docstring: extractDocstring(definition),
|
|
200
|
+
isPrivate,
|
|
201
|
+
inAll,
|
|
202
|
+
};
|
|
203
|
+
if (isPrivate && !inAll) {
|
|
204
|
+
if (includePrivate)
|
|
205
|
+
privateSymbols.push(symbol);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
publicExports.push(symbol);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
const funcDef = definition.type === "async_function_definition"
|
|
213
|
+
? definition.children.find((c) => c.type === "function_definition")
|
|
214
|
+
: definition;
|
|
215
|
+
if (funcDef) {
|
|
216
|
+
const funcInfo = parseFunction(funcDef, source);
|
|
217
|
+
const isPrivate = funcInfo.name.startsWith("_");
|
|
218
|
+
const inAll = allNames.has(funcInfo.name);
|
|
219
|
+
const isAsync = definition.type === "async_function_definition";
|
|
220
|
+
const symbol = {
|
|
221
|
+
name: funcInfo.name,
|
|
222
|
+
kind: isAsync ? "async_function" : "function",
|
|
223
|
+
line: funcInfo.line,
|
|
224
|
+
signature: isAsync
|
|
225
|
+
? `async ${buildFunctionSignature(funcDef, source)}`
|
|
226
|
+
: buildFunctionSignature(funcDef, source),
|
|
227
|
+
docstring: extractDocstring(funcDef),
|
|
228
|
+
isPrivate,
|
|
229
|
+
inAll,
|
|
230
|
+
};
|
|
231
|
+
if (isPrivate && !inAll) {
|
|
232
|
+
if (includePrivate)
|
|
233
|
+
privateSymbols.push(symbol);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
publicExports.push(symbol);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// Variable assignments (module-level constants/variables)
|
|
243
|
+
else if (child.type === "expression_statement") {
|
|
244
|
+
const expr = child.children[0];
|
|
245
|
+
if (expr?.type === "assignment") {
|
|
246
|
+
const left = expr.childForFieldName("left");
|
|
247
|
+
if (left?.type === "identifier" && left.text !== "__all__") {
|
|
248
|
+
const name = left.text;
|
|
249
|
+
const isPrivate = name.startsWith("_");
|
|
250
|
+
const inAll = allNames.has(name);
|
|
251
|
+
const isConstant = name === name.toUpperCase();
|
|
252
|
+
const symbol = {
|
|
253
|
+
name,
|
|
254
|
+
kind: isConstant ? "constant" : "variable",
|
|
255
|
+
line: child.startPosition.row + 1,
|
|
256
|
+
isPrivate,
|
|
257
|
+
inAll,
|
|
258
|
+
};
|
|
259
|
+
if (isPrivate && !inAll) {
|
|
260
|
+
if (includePrivate)
|
|
261
|
+
privateSymbols.push(symbol);
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
publicExports.push(symbol);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// Import statements (for re-exports)
|
|
270
|
+
else if (includeReExports && child.type === "import_from_statement") {
|
|
271
|
+
const reExport = extractReExport(child, source);
|
|
272
|
+
if (reExport) {
|
|
273
|
+
reExports.push(reExport);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// Calculate statistics
|
|
278
|
+
const exportStats = {
|
|
279
|
+
totalExports: publicExports.length,
|
|
280
|
+
functions: publicExports.filter((e) => e.kind === "function" || e.kind === "async_function").length,
|
|
281
|
+
classes: publicExports.filter((e) => e.kind === "class").length,
|
|
282
|
+
variables: publicExports.filter((e) => e.kind === "variable" || e.kind === "constant").length,
|
|
283
|
+
reExports: reExports.length,
|
|
284
|
+
hasAll: allDeclaration.length > 0,
|
|
285
|
+
allCount: allDeclaration.length > 0 ? allDeclaration.length : undefined,
|
|
286
|
+
};
|
|
287
|
+
return {
|
|
288
|
+
allDeclaration: allDeclaration.length > 0 ? allDeclaration : undefined,
|
|
289
|
+
publicExports,
|
|
290
|
+
privateSymbols: includePrivate && privateSymbols.length > 0 ? privateSymbols : undefined,
|
|
291
|
+
reExports: includeReExports && reExports.length > 0 ? reExports : undefined,
|
|
292
|
+
stats: exportStats,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Extract names from __all__ list
|
|
297
|
+
*/
|
|
298
|
+
function extractAllNames(node) {
|
|
299
|
+
const names = [];
|
|
300
|
+
if (node.type === "list") {
|
|
301
|
+
for (const child of node.children) {
|
|
302
|
+
if (child.type === "string") {
|
|
303
|
+
// Remove quotes
|
|
304
|
+
const text = child.text;
|
|
305
|
+
const name = text.slice(1, -1);
|
|
306
|
+
if (name)
|
|
307
|
+
names.push(name);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else if (node.type === "tuple") {
|
|
312
|
+
for (const child of node.children) {
|
|
313
|
+
if (child.type === "string") {
|
|
314
|
+
const text = child.text;
|
|
315
|
+
const name = text.slice(1, -1);
|
|
316
|
+
if (name)
|
|
317
|
+
names.push(name);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return names;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Build function signature string
|
|
325
|
+
*/
|
|
326
|
+
function buildFunctionSignature(funcNode, _source) {
|
|
327
|
+
const nameNode = funcNode.childForFieldName("name");
|
|
328
|
+
const paramsNode = funcNode.childForFieldName("parameters");
|
|
329
|
+
const returnNode = funcNode.childForFieldName("return_type");
|
|
330
|
+
const name = nameNode?.text ?? "unknown";
|
|
331
|
+
const params = paramsNode?.text ?? "()";
|
|
332
|
+
const returnType = returnNode ? ` -> ${returnNode.text}` : "";
|
|
333
|
+
return `def ${name}${params}${returnType}`;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Build class signature string
|
|
337
|
+
*/
|
|
338
|
+
function buildClassSignature(classNode, _source) {
|
|
339
|
+
const nameNode = classNode.childForFieldName("name");
|
|
340
|
+
const superclassNode = classNode.childForFieldName("superclasses");
|
|
341
|
+
const name = nameNode?.text ?? "unknown";
|
|
342
|
+
const bases = superclassNode?.text ?? "";
|
|
343
|
+
return bases ? `class ${name}${bases}` : `class ${name}`;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Extract docstring from a definition
|
|
347
|
+
*/
|
|
348
|
+
function extractDocstring(node) {
|
|
349
|
+
const body = node.childForFieldName("body");
|
|
350
|
+
if (!body)
|
|
351
|
+
return undefined;
|
|
352
|
+
for (const child of body.children) {
|
|
353
|
+
if (child.type === "expression_statement") {
|
|
354
|
+
const string = child.children.find((c) => c.type === "string" || c.type === "concatenated_string");
|
|
355
|
+
if (string) {
|
|
356
|
+
// Extract first line of docstring
|
|
357
|
+
let content = string.text;
|
|
358
|
+
if (content.startsWith('"""') || content.startsWith("'''")) {
|
|
359
|
+
content = content.slice(3, -3);
|
|
360
|
+
}
|
|
361
|
+
else if (content.startsWith('"') || content.startsWith("'")) {
|
|
362
|
+
content = content.slice(1, -1);
|
|
363
|
+
}
|
|
364
|
+
const firstLine = content.trim().split("\n")[0];
|
|
365
|
+
return firstLine.length > 100
|
|
366
|
+
? firstLine.slice(0, 100) + "..."
|
|
367
|
+
: firstLine;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// Stop after first non-docstring statement
|
|
371
|
+
if (child.type !== "expression_statement" && child.type !== "comment") {
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return undefined;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Extract re-export info from import statement
|
|
379
|
+
*/
|
|
380
|
+
function extractReExport(node, _source) {
|
|
381
|
+
// from module import name, name2
|
|
382
|
+
// from module import *
|
|
383
|
+
const moduleNode = node.childForFieldName("module_name");
|
|
384
|
+
if (!moduleNode)
|
|
385
|
+
return null;
|
|
386
|
+
const moduleName = moduleNode.text;
|
|
387
|
+
const isRelative = moduleName.startsWith(".");
|
|
388
|
+
const line = node.startPosition.row + 1;
|
|
389
|
+
// Check for star import
|
|
390
|
+
const hasWildcard = node.children.some((c) => c.type === "wildcard_import" || c.text === "*");
|
|
391
|
+
if (hasWildcard) {
|
|
392
|
+
return {
|
|
393
|
+
symbols: "*",
|
|
394
|
+
from: moduleName,
|
|
395
|
+
line,
|
|
396
|
+
isRelative,
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
// Named imports
|
|
400
|
+
const symbols = [];
|
|
401
|
+
for (const child of node.children) {
|
|
402
|
+
if (child.type === "dotted_name" && child !== moduleNode) {
|
|
403
|
+
symbols.push(child.text);
|
|
404
|
+
}
|
|
405
|
+
else if (child.type === "aliased_import") {
|
|
406
|
+
const nameNode = child.childForFieldName("name");
|
|
407
|
+
if (nameNode) {
|
|
408
|
+
symbols.push(nameNode.text);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (symbols.length === 0)
|
|
413
|
+
return null;
|
|
414
|
+
return {
|
|
415
|
+
symbols,
|
|
416
|
+
from: moduleName,
|
|
417
|
+
line,
|
|
418
|
+
isRelative,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Factory function to create a customized getExports tool
|
|
423
|
+
*/
|
|
424
|
+
export function createGetExportsTool(options) {
|
|
425
|
+
return defineTool({
|
|
426
|
+
name: "get_exports_go",
|
|
427
|
+
description: TOOL_DESCRIPTION,
|
|
428
|
+
inputSchema: TOOL_INPUT_SCHEMA,
|
|
429
|
+
execute: async (input) => {
|
|
430
|
+
return executeGetExports({
|
|
431
|
+
...input,
|
|
432
|
+
includeReExports: input.includeReExports ?? options?.defaultIncludeReExports ?? true,
|
|
433
|
+
includePrivate: input.includePrivate ?? options?.defaultIncludePrivate ?? false,
|
|
434
|
+
});
|
|
435
|
+
},
|
|
436
|
+
});
|
|
437
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get File Structure Tool
|
|
3
|
+
*
|
|
4
|
+
* Analyzes a Go file and returns its structural overview including
|
|
5
|
+
* types (structs/interfaces), functions, variables, and imports.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Input for getFileStructure tool
|
|
9
|
+
*/
|
|
10
|
+
export interface GetFileStructureInput {
|
|
11
|
+
/** Path to Go file */
|
|
12
|
+
path: string;
|
|
13
|
+
/** Include unexported members (lowercase names) */
|
|
14
|
+
includePrivate?: boolean;
|
|
15
|
+
/** Maximum nesting depth */
|
|
16
|
+
maxDepth?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get file structure tool
|
|
20
|
+
*/
|
|
21
|
+
export declare const getFileStructureTool: import("@compilr-dev/agents").Tool<GetFileStructureInput>;
|
|
22
|
+
/**
|
|
23
|
+
* Factory function to create getFileStructure tool with custom options
|
|
24
|
+
*/
|
|
25
|
+
export declare function createGetFileStructureTool(options?: {
|
|
26
|
+
baseDir?: string;
|
|
27
|
+
}): import("@compilr-dev/agents").Tool<GetFileStructureInput>;
|
|
28
|
+
//# sourceMappingURL=get-file-structure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-file-structure.d.ts","sourceRoot":"","sources":["../../src/tools/get-file-structure.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsBH;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,2DAwB/B,CAAC;AAwHH;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,6DAmCxE"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get File Structure Tool
|
|
3
|
+
*
|
|
4
|
+
* Analyzes a Go file and returns its structural overview including
|
|
5
|
+
* types (structs/interfaces), functions, variables, and imports.
|
|
6
|
+
*/
|
|
7
|
+
import { defineTool, createSuccessResult, createErrorResult, } from "@compilr-dev/agents";
|
|
8
|
+
import { stat } from "node:fs/promises";
|
|
9
|
+
import { resolve } from "node:path";
|
|
10
|
+
import { parseFile, parseClass, parseFunction, parseMethod, parseImport, parseVariable, getPackageName, isExported, } from "../parser/go-parser.js";
|
|
11
|
+
/**
|
|
12
|
+
* Get file structure tool
|
|
13
|
+
*/
|
|
14
|
+
export const getFileStructureTool = defineTool({
|
|
15
|
+
name: "get_file_structure_go",
|
|
16
|
+
description: "Get structural overview of a Go file including types (structs/interfaces), functions, variables, and imports. " +
|
|
17
|
+
"Useful for understanding file organization and API surface.",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
path: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Path to Go file (.go)",
|
|
24
|
+
},
|
|
25
|
+
includePrivate: {
|
|
26
|
+
type: "boolean",
|
|
27
|
+
description: "Include unexported members (lowercase names)",
|
|
28
|
+
},
|
|
29
|
+
maxDepth: {
|
|
30
|
+
type: "number",
|
|
31
|
+
description: "Maximum nesting depth to analyze",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
required: ["path"],
|
|
35
|
+
},
|
|
36
|
+
execute: executeGetFileStructure,
|
|
37
|
+
});
|
|
38
|
+
async function executeGetFileStructure(input) {
|
|
39
|
+
const filePath = resolve(input.path);
|
|
40
|
+
const includePrivate = input.includePrivate ?? false;
|
|
41
|
+
// Validate file exists and is a Go file
|
|
42
|
+
try {
|
|
43
|
+
const stats = await stat(filePath);
|
|
44
|
+
if (!stats.isFile()) {
|
|
45
|
+
return createErrorResult(`Not a file: ${filePath}`);
|
|
46
|
+
}
|
|
47
|
+
if (!filePath.endsWith(".go")) {
|
|
48
|
+
return createErrorResult(`Not a Go file: ${filePath}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return createErrorResult(`File not found: ${filePath}`);
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const parseResult = await parseFile(filePath);
|
|
56
|
+
const { tree, source } = parseResult;
|
|
57
|
+
const rootNode = tree.rootNode;
|
|
58
|
+
const result = {
|
|
59
|
+
path: filePath,
|
|
60
|
+
package: getPackageName(tree, source),
|
|
61
|
+
classes: [], // structs and interfaces
|
|
62
|
+
functions: [],
|
|
63
|
+
variables: [],
|
|
64
|
+
imports: [],
|
|
65
|
+
stats: {
|
|
66
|
+
totalClasses: 0,
|
|
67
|
+
totalFunctions: 0,
|
|
68
|
+
totalVariables: 0,
|
|
69
|
+
totalImports: 0,
|
|
70
|
+
totalLines: source.split("\n").length,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
// Process top-level nodes
|
|
74
|
+
for (const child of rootNode.children) {
|
|
75
|
+
// Imports
|
|
76
|
+
if (child.type === "import_declaration") {
|
|
77
|
+
const importInfos = parseImport(child, source);
|
|
78
|
+
for (const importInfo of importInfos) {
|
|
79
|
+
result.imports.push(importInfo);
|
|
80
|
+
result.stats.totalImports++;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Type declarations (struct, interface)
|
|
84
|
+
if (child.type === "type_declaration") {
|
|
85
|
+
const classInfo = parseClass(child, source);
|
|
86
|
+
if (classInfo.name && (includePrivate || isExported(classInfo.name))) {
|
|
87
|
+
// Filter unexported fields if needed
|
|
88
|
+
if (!includePrivate) {
|
|
89
|
+
classInfo.attributes = classInfo.attributes.filter((a) => isExported(a.name));
|
|
90
|
+
classInfo.methods = classInfo.methods.filter((m) => isExported(m.name));
|
|
91
|
+
}
|
|
92
|
+
result.classes.push(classInfo);
|
|
93
|
+
result.stats.totalClasses++;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Function declarations
|
|
97
|
+
if (child.type === "function_declaration") {
|
|
98
|
+
const funcInfo = parseFunction(child, source);
|
|
99
|
+
if (includePrivate || isExported(funcInfo.name)) {
|
|
100
|
+
result.functions.push(funcInfo);
|
|
101
|
+
result.stats.totalFunctions++;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Method declarations (functions with receivers)
|
|
105
|
+
if (child.type === "method_declaration") {
|
|
106
|
+
const methodInfo = parseMethod(child, source);
|
|
107
|
+
if (includePrivate || isExported(methodInfo.name)) {
|
|
108
|
+
result.functions.push(methodInfo);
|
|
109
|
+
result.stats.totalFunctions++;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Variable declarations
|
|
113
|
+
if (child.type === "var_declaration") {
|
|
114
|
+
const varInfos = parseVariable(child, source);
|
|
115
|
+
for (const varInfo of varInfos) {
|
|
116
|
+
if (includePrivate || isExported(varInfo.name)) {
|
|
117
|
+
result.variables.push(varInfo);
|
|
118
|
+
result.stats.totalVariables++;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Constant declarations
|
|
123
|
+
if (child.type === "const_declaration") {
|
|
124
|
+
const constInfos = parseVariable(child, source);
|
|
125
|
+
for (const constInfo of constInfos) {
|
|
126
|
+
if (includePrivate || isExported(constInfo.name)) {
|
|
127
|
+
result.variables.push(constInfo);
|
|
128
|
+
result.stats.totalVariables++;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return createSuccessResult(result);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
return createErrorResult(error instanceof Error ? error.message : String(error));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Factory function to create getFileStructure tool with custom options
|
|
141
|
+
*/
|
|
142
|
+
export function createGetFileStructureTool(options) {
|
|
143
|
+
return defineTool({
|
|
144
|
+
name: "get_file_structure_go",
|
|
145
|
+
description: "Get structural overview of a Go file including types, functions, variables, and imports.",
|
|
146
|
+
inputSchema: {
|
|
147
|
+
type: "object",
|
|
148
|
+
properties: {
|
|
149
|
+
path: {
|
|
150
|
+
type: "string",
|
|
151
|
+
description: "Path to Go file (.go)",
|
|
152
|
+
},
|
|
153
|
+
includePrivate: {
|
|
154
|
+
type: "boolean",
|
|
155
|
+
description: "Include unexported members (lowercase names)",
|
|
156
|
+
},
|
|
157
|
+
maxDepth: {
|
|
158
|
+
type: "number",
|
|
159
|
+
description: "Maximum nesting depth to analyze",
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
required: ["path"],
|
|
163
|
+
},
|
|
164
|
+
execute: async (input) => {
|
|
165
|
+
let targetPath = input.path;
|
|
166
|
+
if (options?.baseDir && !targetPath.startsWith("/")) {
|
|
167
|
+
targetPath = resolve(options.baseDir, targetPath);
|
|
168
|
+
}
|
|
169
|
+
return executeGetFileStructure({ ...input, path: targetPath });
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* getImports Tool
|
|
3
|
+
*
|
|
4
|
+
* Analyzes imports in Go files.
|
|
5
|
+
* Categorizes imports into stdlib, third-party, and local.
|
|
6
|
+
*/
|
|
7
|
+
import type { Tool } from "@compilr-dev/agents";
|
|
8
|
+
/**
|
|
9
|
+
* Input for getImports tool
|
|
10
|
+
*/
|
|
11
|
+
export interface GetImportsInput {
|
|
12
|
+
/** Path to file or directory */
|
|
13
|
+
path: string;
|
|
14
|
+
/** Filter to specific module prefix */
|
|
15
|
+
filterModule?: string;
|
|
16
|
+
/** Include recursive directory scan */
|
|
17
|
+
recursive?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* getImports tool - Analyze Go imports
|
|
21
|
+
*/
|
|
22
|
+
export declare const getImportsTool: Tool<GetImportsInput>;
|
|
23
|
+
/**
|
|
24
|
+
* Factory function to create a customized getImports tool
|
|
25
|
+
*/
|
|
26
|
+
export declare function createGetImportsTool(options?: {
|
|
27
|
+
/** Default recursive setting */
|
|
28
|
+
defaultRecursive?: boolean;
|
|
29
|
+
}): Tool<GetImportsInput>;
|
|
30
|
+
//# sourceMappingURL=get-imports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-imports.d.ts","sourceRoot":"","sources":["../../src/tools/get-imports.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,IAAI,EAAuB,MAAM,qBAAqB,CAAC;AAkLrE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA4BD;;GAEG;AACH,eAAO,MAAM,cAAc,uBAKzB,CAAC;AAyOH;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAC7C,gCAAgC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,IAAI,CAAC,eAAe,CAAC,CAcxB"}
|