@compilr-dev/agents-coding-ts 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 +34 -0
- package/dist/index.js +66 -0
- package/dist/parser/index.d.ts +7 -0
- package/dist/parser/index.js +6 -0
- package/dist/parser/typescript-parser.d.ts +22 -0
- package/dist/parser/typescript-parser.js +423 -0
- package/dist/skills/code-health.d.ts +9 -0
- package/dist/skills/code-health.js +167 -0
- package/dist/skills/code-structure.d.ts +9 -0
- package/dist/skills/code-structure.js +97 -0
- package/dist/skills/dependency-audit.d.ts +9 -0
- package/dist/skills/dependency-audit.js +110 -0
- package/dist/skills/index.d.ts +16 -0
- package/dist/skills/index.js +27 -0
- package/dist/skills/refactor-impact.d.ts +9 -0
- package/dist/skills/refactor-impact.js +135 -0
- package/dist/skills/type-analysis.d.ts +9 -0
- package/dist/skills/type-analysis.js +150 -0
- package/dist/tools/find-dead-code.d.ts +20 -0
- package/dist/tools/find-dead-code.js +375 -0
- package/dist/tools/find-duplicates.d.ts +21 -0
- package/dist/tools/find-duplicates.js +274 -0
- package/dist/tools/find-implementations.d.ts +21 -0
- package/dist/tools/find-implementations.js +436 -0
- package/dist/tools/find-patterns.d.ts +21 -0
- package/dist/tools/find-patterns.js +457 -0
- package/dist/tools/find-references.d.ts +23 -0
- package/dist/tools/find-references.js +488 -0
- package/dist/tools/find-symbol.d.ts +21 -0
- package/dist/tools/find-symbol.js +458 -0
- package/dist/tools/get-call-graph.d.ts +23 -0
- package/dist/tools/get-call-graph.js +469 -0
- package/dist/tools/get-complexity.d.ts +21 -0
- package/dist/tools/get-complexity.js +394 -0
- package/dist/tools/get-dependency-graph.d.ts +23 -0
- package/dist/tools/get-dependency-graph.js +482 -0
- package/dist/tools/get-documentation.d.ts +21 -0
- package/dist/tools/get-documentation.js +613 -0
- package/dist/tools/get-exports.d.ts +21 -0
- package/dist/tools/get-exports.js +427 -0
- package/dist/tools/get-file-structure.d.ts +27 -0
- package/dist/tools/get-file-structure.js +120 -0
- package/dist/tools/get-imports.d.ts +23 -0
- package/dist/tools/get-imports.js +350 -0
- package/dist/tools/get-signature.d.ts +20 -0
- package/dist/tools/get-signature.js +758 -0
- package/dist/tools/get-type-hierarchy.d.ts +22 -0
- package/dist/tools/get-type-hierarchy.js +485 -0
- package/dist/tools/index.d.ts +23 -0
- package/dist/tools/index.js +25 -0
- package/dist/tools/types.d.ts +1302 -0
- package/dist/tools/types.js +7 -0
- package/package.json +84 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 scozzola
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @compilr-dev/agents-coding-ts
|
|
3
|
+
*
|
|
4
|
+
* TypeScript/JavaScript analysis tools for AI coding agents.
|
|
5
|
+
* Provides AST-based code analysis, complexity metrics, and type hierarchy tools.
|
|
6
|
+
*/
|
|
7
|
+
export { parseTypeScript, detectLanguage, isLanguageSupported, } from './parser/index.js';
|
|
8
|
+
export { getFileStructureTool, createGetFileStructureTool, findSymbolTool, createFindSymbolTool, findReferencesTool, createFindReferencesTool, getImportsTool, createGetImportsTool, getExportsTool, createGetExportsTool, getCallGraphTool, createGetCallGraphTool, getDependencyGraphTool, createGetDependencyGraphTool, findImplementationsTool, createFindImplementationsTool, getTypeHierarchyTool, createGetTypeHierarchyTool, getComplexityTool, createGetComplexityTool, findDeadCodeTool, createFindDeadCodeTool, findDuplicatesTool, createFindDuplicatesTool, findPatternsTool, createFindPatternsTool, getSignatureTool, createGetSignatureTool, getDocumentationTool, createGetDocumentationTool, } from './tools/index.js';
|
|
9
|
+
export type { SupportedLanguage, ParameterInfo, GetFileStructureInput, FileStructure, ImportInfo, ExportInfo, ClassInfo, FunctionInfo, MethodInfo, PropertyInfo, VariableInfo, TypeDefinitionInfo, FileStats, SymbolKind, SymbolKindFilter, FindSymbolInput, FindSymbolResult, SymbolDefinition, SearchStats, ReferenceType, FindReferencesInput, FindReferencesResult, Reference, FileReferences, GetImportsInput, GetImportsResult, DetailedImport, ImportedSymbol, TransitiveImport, ImportStats, GetExportsInput, GetExportsResult, ExportedSymbol, ExportKind, ReExport, ExportStats, CallGraphDirection, CallType, GetCallGraphInput, GetCallGraphResult, FunctionNode, CallInfo, CallGraphNode, CallGraphStats, GetDependencyGraphInput, GetDependencyGraphResult, ModuleNode, DependencyEdge, CircularDependency, DependencyGraphStats, FindImplementationsInput, FindImplementationsResult, ImplementationInfo, HierarchyDirection, GetTypeHierarchyInput, GetTypeHierarchyResult, TypeHierarchyNode, GetComplexityInput, GetComplexityResult, FileComplexity, FunctionComplexity, ComplexityContributor, ComplexityContributorType, FindDeadCodeInput, FindDeadCodeResult, DeadCodeItem, FindDuplicatesInput, FindDuplicatesResult, DuplicateGroup, CodeLocation, FindPatternsInput, FindPatternsResult, PatternMatch, CodePattern, GetSignatureInput, GetSignatureResult, ParameterDetail, TypeDetail, GenericDetail, Documentation, MemberSignature, SignatureSymbolKind, GetDocumentationInput, GetDocumentationResult, FileDocumentation, DocumentedSymbol, DocumentationSymbolKind, ExtractorOptions, } from './tools/index.js';
|
|
10
|
+
export { codeStructureSkill, dependencyAuditSkill, refactorImpactSkill, typeAnalysisSkill, codeHealthSkill, tsSkills, defineSkill, type Skill, } from './skills/index.js';
|
|
11
|
+
/**
|
|
12
|
+
* All TypeScript/JavaScript analysis tools for easy registration
|
|
13
|
+
*/
|
|
14
|
+
export declare const tsTools: {
|
|
15
|
+
readonly getFileStructure: import("@compilr-dev/agents").Tool<import("./tools/types.js").GetFileStructureInput>;
|
|
16
|
+
readonly findSymbol: import("@compilr-dev/agents").Tool<import("./tools/types.js").FindSymbolInput>;
|
|
17
|
+
readonly findReferences: import("@compilr-dev/agents").Tool<import("./tools/types.js").FindReferencesInput>;
|
|
18
|
+
readonly getImports: import("@compilr-dev/agents").Tool<import("./tools/types.js").GetImportsInput>;
|
|
19
|
+
readonly getExports: import("@compilr-dev/agents").Tool<import("./tools/types.js").GetExportsInput>;
|
|
20
|
+
readonly getCallGraph: import("@compilr-dev/agents").Tool<import("./tools/types.js").GetCallGraphInput>;
|
|
21
|
+
readonly getDependencyGraph: import("@compilr-dev/agents").Tool<import("./tools/types.js").GetDependencyGraphInput>;
|
|
22
|
+
readonly findImplementations: import("@compilr-dev/agents").Tool<import("./tools/types.js").FindImplementationsInput>;
|
|
23
|
+
readonly getTypeHierarchy: import("@compilr-dev/agents").Tool<import("./tools/types.js").GetTypeHierarchyInput>;
|
|
24
|
+
readonly getComplexity: import("@compilr-dev/agents").Tool<import("./tools/types.js").GetComplexityInput>;
|
|
25
|
+
readonly findDeadCode: import("@compilr-dev/agents").Tool<import("./tools/types.js").FindDeadCodeInput>;
|
|
26
|
+
readonly findDuplicates: import("@compilr-dev/agents").Tool<import("./tools/types.js").FindDuplicatesInput>;
|
|
27
|
+
readonly findPatterns: import("@compilr-dev/agents").Tool<import("./tools/types.js").FindPatternsInput>;
|
|
28
|
+
readonly getSignature: import("@compilr-dev/agents").Tool<import("./tools/types.js").GetSignatureInput>;
|
|
29
|
+
readonly getDocumentation: import("@compilr-dev/agents").Tool<import("./tools/types.js").GetDocumentationInput>;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Array of all TypeScript/JavaScript analysis tools
|
|
33
|
+
*/
|
|
34
|
+
export declare const allTsTools: readonly [import("@compilr-dev/agents").Tool<import("./tools/types.js").GetFileStructureInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").FindSymbolInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").FindReferencesInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").GetImportsInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").GetExportsInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").GetCallGraphInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").GetDependencyGraphInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").FindImplementationsInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").GetTypeHierarchyInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").GetComplexityInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").FindDeadCodeInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").FindDuplicatesInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").FindPatternsInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").GetSignatureInput>, import("@compilr-dev/agents").Tool<import("./tools/types.js").GetDocumentationInput>];
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @compilr-dev/agents-coding-ts
|
|
3
|
+
*
|
|
4
|
+
* TypeScript/JavaScript analysis tools for AI coding agents.
|
|
5
|
+
* Provides AST-based code analysis, complexity metrics, and type hierarchy tools.
|
|
6
|
+
*/
|
|
7
|
+
// Parser exports
|
|
8
|
+
export { parseTypeScript, detectLanguage, isLanguageSupported, } from './parser/index.js';
|
|
9
|
+
// Tool exports
|
|
10
|
+
export {
|
|
11
|
+
// Tier 1 & 2 Tools
|
|
12
|
+
getFileStructureTool, createGetFileStructureTool, findSymbolTool, createFindSymbolTool, findReferencesTool, createFindReferencesTool, getImportsTool, createGetImportsTool, getExportsTool, createGetExportsTool, getCallGraphTool, createGetCallGraphTool, getDependencyGraphTool, createGetDependencyGraphTool, findImplementationsTool, createFindImplementationsTool, getTypeHierarchyTool, createGetTypeHierarchyTool,
|
|
13
|
+
// Tier 3 Tools
|
|
14
|
+
getComplexityTool, createGetComplexityTool, findDeadCodeTool, createFindDeadCodeTool, findDuplicatesTool, createFindDuplicatesTool, findPatternsTool, createFindPatternsTool,
|
|
15
|
+
// Tier 4 Utility Tools
|
|
16
|
+
getSignatureTool, createGetSignatureTool, getDocumentationTool, createGetDocumentationTool, } from './tools/index.js';
|
|
17
|
+
// Skill exports
|
|
18
|
+
export { codeStructureSkill, dependencyAuditSkill, refactorImpactSkill, typeAnalysisSkill, codeHealthSkill, tsSkills, defineSkill, } from './skills/index.js';
|
|
19
|
+
// Tool imports for collections
|
|
20
|
+
import { getFileStructureTool, findSymbolTool, findReferencesTool, getImportsTool, getExportsTool, getCallGraphTool, getDependencyGraphTool, findImplementationsTool, getTypeHierarchyTool, getComplexityTool, findDeadCodeTool, findDuplicatesTool, findPatternsTool, getSignatureTool, getDocumentationTool, } from './tools/index.js';
|
|
21
|
+
/**
|
|
22
|
+
* All TypeScript/JavaScript analysis tools for easy registration
|
|
23
|
+
*/
|
|
24
|
+
export const tsTools = {
|
|
25
|
+
// Tier 1 & 2
|
|
26
|
+
getFileStructure: getFileStructureTool,
|
|
27
|
+
findSymbol: findSymbolTool,
|
|
28
|
+
findReferences: findReferencesTool,
|
|
29
|
+
getImports: getImportsTool,
|
|
30
|
+
getExports: getExportsTool,
|
|
31
|
+
getCallGraph: getCallGraphTool,
|
|
32
|
+
getDependencyGraph: getDependencyGraphTool,
|
|
33
|
+
findImplementations: findImplementationsTool,
|
|
34
|
+
getTypeHierarchy: getTypeHierarchyTool,
|
|
35
|
+
// Tier 3
|
|
36
|
+
getComplexity: getComplexityTool,
|
|
37
|
+
findDeadCode: findDeadCodeTool,
|
|
38
|
+
findDuplicates: findDuplicatesTool,
|
|
39
|
+
findPatterns: findPatternsTool,
|
|
40
|
+
// Tier 4
|
|
41
|
+
getSignature: getSignatureTool,
|
|
42
|
+
getDocumentation: getDocumentationTool,
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Array of all TypeScript/JavaScript analysis tools
|
|
46
|
+
*/
|
|
47
|
+
export const allTsTools = [
|
|
48
|
+
// Tier 1 & 2
|
|
49
|
+
getFileStructureTool,
|
|
50
|
+
findSymbolTool,
|
|
51
|
+
findReferencesTool,
|
|
52
|
+
getImportsTool,
|
|
53
|
+
getExportsTool,
|
|
54
|
+
getCallGraphTool,
|
|
55
|
+
getDependencyGraphTool,
|
|
56
|
+
findImplementationsTool,
|
|
57
|
+
getTypeHierarchyTool,
|
|
58
|
+
// Tier 3
|
|
59
|
+
getComplexityTool,
|
|
60
|
+
findDeadCodeTool,
|
|
61
|
+
findDuplicatesTool,
|
|
62
|
+
findPatternsTool,
|
|
63
|
+
// Tier 4
|
|
64
|
+
getSignatureTool,
|
|
65
|
+
getDocumentationTool,
|
|
66
|
+
];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript/JavaScript Parser
|
|
3
|
+
*
|
|
4
|
+
* Provides AST parsing capabilities using the TypeScript Compiler API.
|
|
5
|
+
*/
|
|
6
|
+
export { parseTypeScript, detectLanguage, isLanguageSupported, } from './typescript-parser.js';
|
|
7
|
+
export type { SupportedLanguage } from '../tools/types.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript/JavaScript Parser using TypeScript Compiler API
|
|
3
|
+
*
|
|
4
|
+
* Uses TypeScript's built-in parser for accurate AST analysis.
|
|
5
|
+
* Works for both TypeScript and JavaScript files.
|
|
6
|
+
*/
|
|
7
|
+
import type { FileStructure, ExtractorOptions, SupportedLanguage } from '../tools/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Parse a TypeScript/JavaScript file and extract its structure
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseTypeScript(sourceCode: string, filePath: string, options?: ExtractorOptions): Omit<FileStructure, 'path' | 'language' | 'languageConfidence'>;
|
|
12
|
+
/**
|
|
13
|
+
* Detect language from file path
|
|
14
|
+
*/
|
|
15
|
+
export declare function detectLanguage(filePath: string): {
|
|
16
|
+
language: SupportedLanguage | null;
|
|
17
|
+
confidence: number;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Check if a language is supported by this parser
|
|
21
|
+
*/
|
|
22
|
+
export declare function isLanguageSupported(language: string): boolean;
|
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript/JavaScript Parser using TypeScript Compiler API
|
|
3
|
+
*
|
|
4
|
+
* Uses TypeScript's built-in parser for accurate AST analysis.
|
|
5
|
+
* Works for both TypeScript and JavaScript files.
|
|
6
|
+
*/
|
|
7
|
+
import * as ts from 'typescript';
|
|
8
|
+
// Helper to check for a specific modifier kind
|
|
9
|
+
function hasModifierKind(modifiers, kind) {
|
|
10
|
+
return modifiers?.some((m) => m.kind === kind) ?? false;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Parse a TypeScript/JavaScript file and extract its structure
|
|
14
|
+
*/
|
|
15
|
+
export function parseTypeScript(sourceCode, filePath, options = {}) {
|
|
16
|
+
const { maxDepth = 2, includePrivate = true } = options;
|
|
17
|
+
// Determine script kind based on file extension
|
|
18
|
+
const scriptKind = getScriptKind(filePath);
|
|
19
|
+
// Parse the source code
|
|
20
|
+
const sourceFile = ts.createSourceFile(filePath, sourceCode, ts.ScriptTarget.Latest, true, scriptKind);
|
|
21
|
+
// Extract all structural information
|
|
22
|
+
const imports = extractImports(sourceFile);
|
|
23
|
+
const exports = extractExports(sourceFile);
|
|
24
|
+
const classes = extractClasses(sourceFile, includePrivate, maxDepth);
|
|
25
|
+
const functions = extractFunctions(sourceFile);
|
|
26
|
+
const variables = extractVariables(sourceFile);
|
|
27
|
+
const types = extractTypes(sourceFile);
|
|
28
|
+
// Calculate stats
|
|
29
|
+
const stats = {
|
|
30
|
+
lineCount: sourceCode.split('\n').length,
|
|
31
|
+
importCount: imports.length,
|
|
32
|
+
exportCount: exports.length,
|
|
33
|
+
classCount: classes.length,
|
|
34
|
+
functionCount: functions.length,
|
|
35
|
+
typeCount: types.length,
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
imports,
|
|
39
|
+
exports,
|
|
40
|
+
classes,
|
|
41
|
+
functions,
|
|
42
|
+
variables,
|
|
43
|
+
types,
|
|
44
|
+
stats,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get TypeScript script kind from file extension
|
|
49
|
+
*/
|
|
50
|
+
function getScriptKind(filePath) {
|
|
51
|
+
const ext = filePath.toLowerCase().split('.').pop();
|
|
52
|
+
switch (ext) {
|
|
53
|
+
case 'ts':
|
|
54
|
+
return ts.ScriptKind.TS;
|
|
55
|
+
case 'tsx':
|
|
56
|
+
return ts.ScriptKind.TSX;
|
|
57
|
+
case 'js':
|
|
58
|
+
return ts.ScriptKind.JS;
|
|
59
|
+
case 'jsx':
|
|
60
|
+
return ts.ScriptKind.JSX;
|
|
61
|
+
case 'mts':
|
|
62
|
+
case 'cts':
|
|
63
|
+
return ts.ScriptKind.TS;
|
|
64
|
+
case 'mjs':
|
|
65
|
+
case 'cjs':
|
|
66
|
+
return ts.ScriptKind.JS;
|
|
67
|
+
default:
|
|
68
|
+
return ts.ScriptKind.TS;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Extract import statements
|
|
73
|
+
*/
|
|
74
|
+
function extractImports(sourceFile) {
|
|
75
|
+
const imports = [];
|
|
76
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
77
|
+
if (ts.isImportDeclaration(node)) {
|
|
78
|
+
const moduleSpecifier = node.moduleSpecifier;
|
|
79
|
+
if (!ts.isStringLiteral(moduleSpecifier))
|
|
80
|
+
return;
|
|
81
|
+
const source = moduleSpecifier.text;
|
|
82
|
+
// Check for type-only import using modifiers
|
|
83
|
+
const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
|
|
84
|
+
const hasTypeKeyword = hasModifierKind(modifiers, ts.SyntaxKind.TypeKeyword);
|
|
85
|
+
const importInfo = {
|
|
86
|
+
source,
|
|
87
|
+
names: [],
|
|
88
|
+
isTypeOnly: hasTypeKeyword,
|
|
89
|
+
};
|
|
90
|
+
const importClause = node.importClause;
|
|
91
|
+
if (importClause) {
|
|
92
|
+
// Default import
|
|
93
|
+
if (importClause.name) {
|
|
94
|
+
importInfo.defaultImport = importClause.name.text;
|
|
95
|
+
}
|
|
96
|
+
// Named imports
|
|
97
|
+
if (importClause.namedBindings) {
|
|
98
|
+
if (ts.isNamedImports(importClause.namedBindings)) {
|
|
99
|
+
for (const element of importClause.namedBindings.elements) {
|
|
100
|
+
importInfo.names.push(element.name.text);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else if (ts.isNamespaceImport(importClause.namedBindings)) {
|
|
104
|
+
// import * as foo
|
|
105
|
+
importInfo.namespaceImport = importClause.namedBindings.name.text;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
imports.push(importInfo);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
return imports;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Extract export statements
|
|
116
|
+
*/
|
|
117
|
+
function extractExports(sourceFile) {
|
|
118
|
+
const exports = [];
|
|
119
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
120
|
+
// export default ...
|
|
121
|
+
if (ts.isExportAssignment(node)) {
|
|
122
|
+
exports.push({
|
|
123
|
+
name: 'default',
|
|
124
|
+
isDefault: true,
|
|
125
|
+
isTypeOnly: false,
|
|
126
|
+
});
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
// export { ... }
|
|
130
|
+
if (ts.isExportDeclaration(node)) {
|
|
131
|
+
// Check for type-only export using modifiers
|
|
132
|
+
const exportMods = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
|
|
133
|
+
const isTypeOnlyExport = hasModifierKind(exportMods, ts.SyntaxKind.TypeKeyword);
|
|
134
|
+
if (node.exportClause && ts.isNamedExports(node.exportClause)) {
|
|
135
|
+
for (const element of node.exportClause.elements) {
|
|
136
|
+
exports.push({
|
|
137
|
+
name: element.name.text,
|
|
138
|
+
isDefault: false,
|
|
139
|
+
isTypeOnly: isTypeOnlyExport,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
// Check for export modifier on declarations
|
|
146
|
+
const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
|
|
147
|
+
const hasExport = hasModifierKind(modifiers, ts.SyntaxKind.ExportKeyword);
|
|
148
|
+
const hasDefault = hasModifierKind(modifiers, ts.SyntaxKind.DefaultKeyword);
|
|
149
|
+
if (hasExport) {
|
|
150
|
+
let name = 'unknown';
|
|
151
|
+
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
152
|
+
name = node.name.text;
|
|
153
|
+
}
|
|
154
|
+
else if (ts.isClassDeclaration(node) && node.name) {
|
|
155
|
+
name = node.name.text;
|
|
156
|
+
}
|
|
157
|
+
else if (ts.isVariableStatement(node)) {
|
|
158
|
+
for (const decl of node.declarationList.declarations) {
|
|
159
|
+
if (ts.isIdentifier(decl.name)) {
|
|
160
|
+
exports.push({
|
|
161
|
+
name: decl.name.text,
|
|
162
|
+
isDefault: hasDefault,
|
|
163
|
+
isTypeOnly: false,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
else if (ts.isInterfaceDeclaration(node)) {
|
|
170
|
+
name = node.name.text;
|
|
171
|
+
}
|
|
172
|
+
else if (ts.isTypeAliasDeclaration(node)) {
|
|
173
|
+
name = node.name.text;
|
|
174
|
+
}
|
|
175
|
+
else if (ts.isEnumDeclaration(node)) {
|
|
176
|
+
name = node.name.text;
|
|
177
|
+
}
|
|
178
|
+
if (name !== 'unknown' || hasDefault) {
|
|
179
|
+
exports.push({
|
|
180
|
+
name: hasDefault ? 'default' : name,
|
|
181
|
+
isDefault: hasDefault,
|
|
182
|
+
isTypeOnly: ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
return exports;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Extract class declarations
|
|
191
|
+
*/
|
|
192
|
+
function extractClasses(sourceFile, includePrivate, maxDepth) {
|
|
193
|
+
const classes = [];
|
|
194
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
195
|
+
if (ts.isClassDeclaration(node)) {
|
|
196
|
+
const classInfo = extractClassInfo(node, includePrivate, maxDepth);
|
|
197
|
+
if (classInfo) {
|
|
198
|
+
classes.push(classInfo);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
return classes;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Extract information from a class declaration
|
|
206
|
+
*/
|
|
207
|
+
function extractClassInfo(node, includePrivate, _maxDepth) {
|
|
208
|
+
const name = node.name?.text ?? 'anonymous';
|
|
209
|
+
const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
|
|
210
|
+
const isExported = hasModifierKind(modifiers, ts.SyntaxKind.ExportKeyword);
|
|
211
|
+
const isAbstract = hasModifierKind(modifiers, ts.SyntaxKind.AbstractKeyword);
|
|
212
|
+
const methods = [];
|
|
213
|
+
const properties = [];
|
|
214
|
+
for (const member of node.members) {
|
|
215
|
+
const memberModifiers = ts.canHaveModifiers(member) ? ts.getModifiers(member) : undefined;
|
|
216
|
+
const visibility = getVisibility(memberModifiers);
|
|
217
|
+
// Skip private members if not included
|
|
218
|
+
if (!includePrivate && visibility === 'private') {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (ts.isConstructorDeclaration(member)) {
|
|
222
|
+
const isAsync = hasModifierKind(memberModifiers, ts.SyntaxKind.AsyncKeyword);
|
|
223
|
+
const isStatic = hasModifierKind(memberModifiers, ts.SyntaxKind.StaticKeyword);
|
|
224
|
+
methods.push({
|
|
225
|
+
name: 'constructor',
|
|
226
|
+
visibility,
|
|
227
|
+
async: isAsync,
|
|
228
|
+
static: isStatic,
|
|
229
|
+
parameters: extractParameters(member.parameters),
|
|
230
|
+
returnType: member.type ? member.type.getText() : undefined,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
else if (ts.isMethodDeclaration(member)) {
|
|
234
|
+
const methodName = ts.isIdentifier(member.name) ? member.name.text : 'computed';
|
|
235
|
+
const isAsync = hasModifierKind(memberModifiers, ts.SyntaxKind.AsyncKeyword);
|
|
236
|
+
const isStatic = hasModifierKind(memberModifiers, ts.SyntaxKind.StaticKeyword);
|
|
237
|
+
methods.push({
|
|
238
|
+
name: methodName,
|
|
239
|
+
visibility,
|
|
240
|
+
async: isAsync,
|
|
241
|
+
static: isStatic,
|
|
242
|
+
parameters: extractParameters(member.parameters),
|
|
243
|
+
returnType: member.type ? member.type.getText() : undefined,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
else if (ts.isPropertyDeclaration(member)) {
|
|
247
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- member.name can be undefined for computed properties
|
|
248
|
+
const propName = member.name && ts.isIdentifier(member.name) ? member.name.text : null;
|
|
249
|
+
if (propName) {
|
|
250
|
+
const isStatic = hasModifierKind(memberModifiers, ts.SyntaxKind.StaticKeyword);
|
|
251
|
+
const isReadonly = hasModifierKind(memberModifiers, ts.SyntaxKind.ReadonlyKeyword);
|
|
252
|
+
properties.push({
|
|
253
|
+
name: propName,
|
|
254
|
+
visibility,
|
|
255
|
+
static: isStatic,
|
|
256
|
+
readonly: isReadonly,
|
|
257
|
+
type: member.type ? member.type.getText() : undefined,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
name,
|
|
264
|
+
exported: isExported,
|
|
265
|
+
abstract: isAbstract,
|
|
266
|
+
methods,
|
|
267
|
+
properties,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Get visibility modifier
|
|
272
|
+
*/
|
|
273
|
+
function getVisibility(modifiers) {
|
|
274
|
+
if (!modifiers)
|
|
275
|
+
return 'public';
|
|
276
|
+
for (const mod of modifiers) {
|
|
277
|
+
if (mod.kind === ts.SyntaxKind.PrivateKeyword)
|
|
278
|
+
return 'private';
|
|
279
|
+
if (mod.kind === ts.SyntaxKind.ProtectedKeyword)
|
|
280
|
+
return 'protected';
|
|
281
|
+
}
|
|
282
|
+
return 'public';
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Extract parameter information
|
|
286
|
+
*/
|
|
287
|
+
function extractParameters(params) {
|
|
288
|
+
return params.map((param) => ({
|
|
289
|
+
name: ts.isIdentifier(param.name) ? param.name.text : 'param',
|
|
290
|
+
type: param.type ? param.type.getText() : undefined,
|
|
291
|
+
}));
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Extract function declarations
|
|
295
|
+
*/
|
|
296
|
+
function extractFunctions(sourceFile) {
|
|
297
|
+
const functions = [];
|
|
298
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
299
|
+
// Function declarations
|
|
300
|
+
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
301
|
+
const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
|
|
302
|
+
const isExported = hasModifierKind(modifiers, ts.SyntaxKind.ExportKeyword);
|
|
303
|
+
const isAsync = hasModifierKind(modifiers, ts.SyntaxKind.AsyncKeyword);
|
|
304
|
+
functions.push({
|
|
305
|
+
name: node.name.text,
|
|
306
|
+
exported: isExported,
|
|
307
|
+
async: isAsync,
|
|
308
|
+
parameters: extractParameters(node.parameters),
|
|
309
|
+
returnType: node.type ? node.type.getText() : undefined,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
// Variable declarations that are arrow functions
|
|
313
|
+
if (ts.isVariableStatement(node)) {
|
|
314
|
+
const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
|
|
315
|
+
const isExported = hasModifierKind(modifiers, ts.SyntaxKind.ExportKeyword);
|
|
316
|
+
for (const decl of node.declarationList.declarations) {
|
|
317
|
+
if (ts.isIdentifier(decl.name) && decl.initializer) {
|
|
318
|
+
if (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer)) {
|
|
319
|
+
const funcModifiers = decl.initializer.modifiers;
|
|
320
|
+
const isAsync = funcModifiers
|
|
321
|
+
? funcModifiers.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword)
|
|
322
|
+
: false;
|
|
323
|
+
functions.push({
|
|
324
|
+
name: decl.name.text,
|
|
325
|
+
exported: isExported,
|
|
326
|
+
async: isAsync,
|
|
327
|
+
parameters: extractParameters(decl.initializer.parameters),
|
|
328
|
+
returnType: decl.initializer.type ? decl.initializer.type.getText() : undefined,
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
return functions;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Extract variable declarations (excluding functions)
|
|
339
|
+
*/
|
|
340
|
+
function extractVariables(sourceFile) {
|
|
341
|
+
const variables = [];
|
|
342
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
343
|
+
if (ts.isVariableStatement(node)) {
|
|
344
|
+
const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
|
|
345
|
+
const isExported = hasModifierKind(modifiers, ts.SyntaxKind.ExportKeyword);
|
|
346
|
+
const kind = node.declarationList.flags & ts.NodeFlags.Const ? 'const' : 'let';
|
|
347
|
+
for (const decl of node.declarationList.declarations) {
|
|
348
|
+
if (ts.isIdentifier(decl.name)) {
|
|
349
|
+
// Skip if this is a function (arrow function or function expression)
|
|
350
|
+
if (decl.initializer &&
|
|
351
|
+
(ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer))) {
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
variables.push({
|
|
355
|
+
name: decl.name.text,
|
|
356
|
+
kind: kind,
|
|
357
|
+
exported: isExported,
|
|
358
|
+
type: decl.type ? decl.type.getText() : undefined,
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
return variables;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Extract type definitions (interfaces, type aliases, enums)
|
|
368
|
+
*/
|
|
369
|
+
function extractTypes(sourceFile) {
|
|
370
|
+
const types = [];
|
|
371
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
372
|
+
const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
|
|
373
|
+
const isExported = hasModifierKind(modifiers, ts.SyntaxKind.ExportKeyword);
|
|
374
|
+
if (ts.isInterfaceDeclaration(node)) {
|
|
375
|
+
types.push({
|
|
376
|
+
name: node.name.text,
|
|
377
|
+
kind: 'interface',
|
|
378
|
+
exported: isExported,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
else if (ts.isTypeAliasDeclaration(node)) {
|
|
382
|
+
types.push({
|
|
383
|
+
name: node.name.text,
|
|
384
|
+
kind: 'type',
|
|
385
|
+
exported: isExported,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
else if (ts.isEnumDeclaration(node)) {
|
|
389
|
+
types.push({
|
|
390
|
+
name: node.name.text,
|
|
391
|
+
kind: 'enum',
|
|
392
|
+
exported: isExported,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
return types;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Detect language from file path
|
|
400
|
+
*/
|
|
401
|
+
export function detectLanguage(filePath) {
|
|
402
|
+
const ext = filePath.toLowerCase().split('.').pop();
|
|
403
|
+
switch (ext) {
|
|
404
|
+
case 'ts':
|
|
405
|
+
case 'tsx':
|
|
406
|
+
case 'mts':
|
|
407
|
+
case 'cts':
|
|
408
|
+
return { language: 'typescript', confidence: 1.0 };
|
|
409
|
+
case 'js':
|
|
410
|
+
case 'jsx':
|
|
411
|
+
case 'mjs':
|
|
412
|
+
case 'cjs':
|
|
413
|
+
return { language: 'javascript', confidence: 1.0 };
|
|
414
|
+
default:
|
|
415
|
+
return { language: null, confidence: 0 };
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Check if a language is supported by this parser
|
|
420
|
+
*/
|
|
421
|
+
export function isLanguageSupported(language) {
|
|
422
|
+
return language === 'typescript' || language === 'javascript';
|
|
423
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Health Skill
|
|
3
|
+
*
|
|
4
|
+
* Analyze codebase health: complexity, dead code, duplicates, and anti-patterns.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Code health skill - Analyze codebase health using Tier 3 tools
|
|
8
|
+
*/
|
|
9
|
+
export declare const codeHealthSkill: import("@compilr-dev/agents").Skill;
|