skannr 0.1.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.
- package/.eslintrc.js +22 -0
- package/README.md +109 -0
- package/dist/agent-cli.d.ts +7 -0
- package/dist/agent-cli.d.ts.map +1 -0
- package/dist/agent-cli.js +364 -0
- package/dist/agent-cli.js.map +1 -0
- package/dist/agent.d.ts +115 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +340 -0
- package/dist/agent.js.map +1 -0
- package/dist/benchmark.d.ts +53 -0
- package/dist/benchmark.d.ts.map +1 -0
- package/dist/benchmark.js +307 -0
- package/dist/benchmark.js.map +1 -0
- package/dist/cache.d.ts +97 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +284 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +238 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +52 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +176 -0
- package/dist/index.js.map +1 -0
- package/dist/languages/GenericAdapter.d.ts +10 -0
- package/dist/languages/GenericAdapter.d.ts.map +1 -0
- package/dist/languages/GenericAdapter.js +41 -0
- package/dist/languages/GenericAdapter.js.map +1 -0
- package/dist/languages/LanguageAdapter.d.ts +14 -0
- package/dist/languages/LanguageAdapter.d.ts.map +1 -0
- package/dist/languages/LanguageAdapter.js +3 -0
- package/dist/languages/LanguageAdapter.js.map +1 -0
- package/dist/languages/PythonAdapter.d.ts +10 -0
- package/dist/languages/PythonAdapter.d.ts.map +1 -0
- package/dist/languages/PythonAdapter.js +98 -0
- package/dist/languages/PythonAdapter.js.map +1 -0
- package/dist/languages/TypeScriptAdapter.d.ts +17 -0
- package/dist/languages/TypeScriptAdapter.d.ts.map +1 -0
- package/dist/languages/TypeScriptAdapter.js +321 -0
- package/dist/languages/TypeScriptAdapter.js.map +1 -0
- package/dist/languages/registry.d.ts +4 -0
- package/dist/languages/registry.d.ts.map +1 -0
- package/dist/languages/registry.js +86 -0
- package/dist/languages/registry.js.map +1 -0
- package/dist/mapper.d.ts +49 -0
- package/dist/mapper.d.ts.map +1 -0
- package/dist/mapper.js +386 -0
- package/dist/mapper.js.map +1 -0
- package/dist/ranker-enhanced.d.ts +37 -0
- package/dist/ranker-enhanced.d.ts.map +1 -0
- package/dist/ranker-enhanced.js +395 -0
- package/dist/ranker-enhanced.js.map +1 -0
- package/dist/ranker.d.ts +14 -0
- package/dist/ranker.d.ts.map +1 -0
- package/dist/ranker.js +105 -0
- package/dist/ranker.js.map +1 -0
- package/dist/rocket-chat-scope.d.ts +7 -0
- package/dist/rocket-chat-scope.d.ts.map +1 -0
- package/dist/rocket-chat-scope.js +95 -0
- package/dist/rocket-chat-scope.js.map +1 -0
- package/dist/scanner.d.ts +16 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +228 -0
- package/dist/scanner.js.map +1 -0
- package/dist/skeletonizer.d.ts +5 -0
- package/dist/skeletonizer.d.ts.map +1 -0
- package/dist/skeletonizer.js +52 -0
- package/dist/skeletonizer.js.map +1 -0
- package/dist/tokenizer.d.ts +9 -0
- package/dist/tokenizer.d.ts.map +1 -0
- package/dist/tokenizer.js +21 -0
- package/dist/tokenizer.js.map +1 -0
- package/dist/types.d.ts +68 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/gemini-extension/GEMINI.md +26 -0
- package/gemini-extension/gemini-extension.json +12 -0
- package/gemini-extension/package.json +14 -0
- package/gemini-extension/src/server.ts +63 -0
- package/gemini-extension/tsconfig.json +14 -0
- package/jest.config.js +5 -0
- package/package.json +46 -0
- package/src/agent-cli.ts +383 -0
- package/src/agent.ts +344 -0
- package/src/benchmark.ts +389 -0
- package/src/cache.ts +317 -0
- package/src/cli.ts +223 -0
- package/src/config.ts +22 -0
- package/src/index.ts +215 -0
- package/src/languages/GenericAdapter.ts +44 -0
- package/src/languages/LanguageAdapter.ts +14 -0
- package/src/languages/PythonAdapter.ts +74 -0
- package/src/languages/TypeScriptAdapter.ts +338 -0
- package/src/languages/registry.ts +49 -0
- package/src/mapper.ts +448 -0
- package/src/ranker-enhanced.ts +460 -0
- package/src/ranker.ts +92 -0
- package/src/scanner.ts +201 -0
- package/src/skeletonizer.ts +16 -0
- package/src/tokenizer.ts +20 -0
- package/src/types.ts +71 -0
- package/tests/agent.tools.test.ts +81 -0
- package/tests/benchmark.test.ts +31 -0
- package/tests/fixtures/sample.py +17 -0
- package/tests/fixtures/sample.ts +13 -0
- package/tests/fixtures/src/api/routes.ts +1 -0
- package/tests/fixtures/src/auth/permission.ts +3 -0
- package/tests/ranker-enhanced.test.ts +68 -0
- package/tests/ranker.test.ts +75 -0
- package/tests/scanner.scope.test.ts +41 -0
- package/tests/setup-fixtures.js +29 -0
- package/tests/skeletonizer.test.ts +142 -0
- package/tsconfig.json +21 -0
- package/uca-landing/index.html +17 -0
- package/uca-landing/package.json +23 -0
- package/uca-landing/postcss.config.js +6 -0
- package/uca-landing/src/App.jsx +43 -0
- package/uca-landing/src/components/AgentMode.jsx +45 -0
- package/uca-landing/src/components/CliReference.jsx +49 -0
- package/uca-landing/src/components/Features.jsx +63 -0
- package/uca-landing/src/components/Footer.jsx +35 -0
- package/uca-landing/src/components/Hero.jsx +124 -0
- package/uca-landing/src/components/HowItWorks.jsx +60 -0
- package/uca-landing/src/components/Install.jsx +90 -0
- package/uca-landing/src/components/LanguageSupport.jsx +63 -0
- package/uca-landing/src/components/Navbar.jsx +86 -0
- package/uca-landing/src/components/Problem.jsx +51 -0
- package/uca-landing/src/components/Reveal.jsx +40 -0
- package/uca-landing/src/components/WorksWith.jsx +59 -0
- package/uca-landing/src/hooks/useScrollNav.js +13 -0
- package/uca-landing/src/hooks/useTypewriter.js +41 -0
- package/uca-landing/src/index.css +13 -0
- package/uca-landing/src/main.jsx +10 -0
- package/uca-landing/tailwind.config.js +68 -0
- package/uca-landing/vite.config.js +6 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File scanner for universal codebases.
|
|
3
|
+
*/
|
|
4
|
+
export declare const DEFAULT_EXCLUDES: string[];
|
|
5
|
+
export interface ScanOptions {
|
|
6
|
+
extensions?: string[];
|
|
7
|
+
exclude?: string[];
|
|
8
|
+
moduleKeys?: string[];
|
|
9
|
+
moduleDefinitions?: Record<string, string[]>;
|
|
10
|
+
}
|
|
11
|
+
export declare function discoverModules(root: string): string[];
|
|
12
|
+
export declare function scanFiles(rootDir: string, options?: ScanOptions): string[];
|
|
13
|
+
export declare function scanTypeScriptFiles(rootDir: string): string[];
|
|
14
|
+
export declare function scanRocketChatFiles(rootDir: string, moduleKeys?: string[]): string[];
|
|
15
|
+
export declare function readFileContent(filePath: string): string | null;
|
|
16
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,eAAO,MAAM,gBAAgB,UAe5B,CAAC;AAoBF,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC9C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBtD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,EAAE,CA4C9E;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAE7D;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAKpF;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM/D"}
|
package/dist/scanner.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* File scanner for universal codebases.
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.DEFAULT_EXCLUDES = void 0;
|
|
40
|
+
exports.discoverModules = discoverModules;
|
|
41
|
+
exports.scanFiles = scanFiles;
|
|
42
|
+
exports.scanTypeScriptFiles = scanTypeScriptFiles;
|
|
43
|
+
exports.scanRocketChatFiles = scanRocketChatFiles;
|
|
44
|
+
exports.readFileContent = readFileContent;
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
exports.DEFAULT_EXCLUDES = [
|
|
48
|
+
'**/node_modules/**',
|
|
49
|
+
'**/.git/**',
|
|
50
|
+
'**/dist/**',
|
|
51
|
+
'**/build/**',
|
|
52
|
+
'**/coverage/**',
|
|
53
|
+
'**/__pycache__/**',
|
|
54
|
+
'**/*.min.js',
|
|
55
|
+
'**/*.bundle.js',
|
|
56
|
+
'**/vendor/**',
|
|
57
|
+
'**/.next/**',
|
|
58
|
+
'**/.nuxt/**',
|
|
59
|
+
'**/target/**',
|
|
60
|
+
'**/*.pyc',
|
|
61
|
+
'**/.cache/**',
|
|
62
|
+
];
|
|
63
|
+
const DEFAULT_IGNORED_DIRS = new Set([
|
|
64
|
+
'node_modules',
|
|
65
|
+
'.git',
|
|
66
|
+
'dist',
|
|
67
|
+
'build',
|
|
68
|
+
'coverage',
|
|
69
|
+
'__pycache__',
|
|
70
|
+
'vendor',
|
|
71
|
+
'.next',
|
|
72
|
+
'.nuxt',
|
|
73
|
+
'target',
|
|
74
|
+
'.cache',
|
|
75
|
+
'.idea',
|
|
76
|
+
'.vscode',
|
|
77
|
+
]);
|
|
78
|
+
const SRC_CANDIDATES = ['src', 'lib', 'packages', 'apps', 'modules'];
|
|
79
|
+
function discoverModules(root) {
|
|
80
|
+
const srcCandidates = ['src', 'lib', 'packages', 'apps', 'modules'];
|
|
81
|
+
for (const candidate of srcCandidates) {
|
|
82
|
+
const candidatePath = path.join(root, candidate);
|
|
83
|
+
if (fs.existsSync(candidatePath) && fs.statSync(candidatePath).isDirectory()) {
|
|
84
|
+
const subdirs = fs.readdirSync(candidatePath)
|
|
85
|
+
.filter((name) => {
|
|
86
|
+
const fullPath = path.join(candidatePath, name);
|
|
87
|
+
return fs.statSync(fullPath).isDirectory() && !name.startsWith('.');
|
|
88
|
+
});
|
|
89
|
+
if (subdirs.length > 0)
|
|
90
|
+
return subdirs;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const ignored = new Set(['node_modules', '.git', 'dist', 'build', 'coverage', '.cache', '__pycache__', 'vendor']);
|
|
94
|
+
return fs.readdirSync(root)
|
|
95
|
+
.filter((name) => {
|
|
96
|
+
const fullPath = path.join(root, name);
|
|
97
|
+
return fs.statSync(fullPath).isDirectory() && !name.startsWith('.') && !ignored.has(name);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function scanFiles(rootDir, options = {}) {
|
|
101
|
+
const results = [];
|
|
102
|
+
const excludes = options.exclude ?? exports.DEFAULT_EXCLUDES;
|
|
103
|
+
const extensions = options.extensions?.map((ext) => ext.toLowerCase());
|
|
104
|
+
const scanRoots = resolveScanRoots(rootDir, options);
|
|
105
|
+
const scan = (dir) => {
|
|
106
|
+
let entries;
|
|
107
|
+
try {
|
|
108
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
for (const entry of entries) {
|
|
114
|
+
const fullPath = path.join(dir, entry.name);
|
|
115
|
+
if (shouldExclude(fullPath, rootDir, excludes)) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (entry.isDirectory()) {
|
|
119
|
+
if (!DEFAULT_IGNORED_DIRS.has(entry.name)) {
|
|
120
|
+
scan(fullPath);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else if (entry.isFile()) {
|
|
124
|
+
if (!extensions || extensions.length === 0) {
|
|
125
|
+
results.push(fullPath);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
129
|
+
if (extensions.includes(ext)) {
|
|
130
|
+
results.push(fullPath);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
for (const scanRoot of scanRoots) {
|
|
136
|
+
if (fs.existsSync(scanRoot) && fs.statSync(scanRoot).isDirectory()) {
|
|
137
|
+
scan(scanRoot);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return Array.from(new Set(results));
|
|
141
|
+
}
|
|
142
|
+
function scanTypeScriptFiles(rootDir) {
|
|
143
|
+
return scanFiles(rootDir, { extensions: ['.ts', '.tsx'] });
|
|
144
|
+
}
|
|
145
|
+
function scanRocketChatFiles(rootDir, moduleKeys) {
|
|
146
|
+
return scanFiles(rootDir, {
|
|
147
|
+
extensions: ['.ts', '.tsx'],
|
|
148
|
+
moduleKeys,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
function readFileContent(filePath) {
|
|
152
|
+
try {
|
|
153
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function resolveScanRoots(rootDir, options) {
|
|
160
|
+
const moduleKeys = options.moduleKeys;
|
|
161
|
+
const moduleDefinitions = options.moduleDefinitions;
|
|
162
|
+
if (!moduleKeys || moduleKeys.length === 0) {
|
|
163
|
+
return [rootDir];
|
|
164
|
+
}
|
|
165
|
+
const resolved = [];
|
|
166
|
+
for (const key of moduleKeys) {
|
|
167
|
+
if (moduleDefinitions?.[key]) {
|
|
168
|
+
for (const rel of moduleDefinitions[key]) {
|
|
169
|
+
const full = path.resolve(rootDir, rel);
|
|
170
|
+
if (fs.existsSync(full) && fs.statSync(full).isDirectory()) {
|
|
171
|
+
resolved.push(full);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const direct = path.join(rootDir, key);
|
|
177
|
+
if (fs.existsSync(direct) && fs.statSync(direct).isDirectory()) {
|
|
178
|
+
resolved.push(direct);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
for (const base of SRC_CANDIDATES) {
|
|
182
|
+
const candidate = path.join(rootDir, base, key);
|
|
183
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
|
|
184
|
+
resolved.push(candidate);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (resolved.length === 0 && moduleKeys.length > 0) {
|
|
189
|
+
throw new Error(`No matching modules found for keys: ${moduleKeys.join(', ')}`);
|
|
190
|
+
}
|
|
191
|
+
return resolved;
|
|
192
|
+
}
|
|
193
|
+
function shouldExclude(fullPath, rootDir, excludes) {
|
|
194
|
+
const rel = path.relative(rootDir, fullPath).split(path.sep).join('/');
|
|
195
|
+
const hasSegment = (segment) => rel === segment || rel.startsWith(`${segment}/`) || rel.includes(`/${segment}/`);
|
|
196
|
+
for (const pattern of excludes) {
|
|
197
|
+
if (pattern.includes('node_modules') && hasSegment('node_modules'))
|
|
198
|
+
return true;
|
|
199
|
+
if (pattern.includes('.git') && hasSegment('.git'))
|
|
200
|
+
return true;
|
|
201
|
+
if (pattern.includes('/dist/') && hasSegment('dist'))
|
|
202
|
+
return true;
|
|
203
|
+
if (pattern.includes('/build/') && hasSegment('build'))
|
|
204
|
+
return true;
|
|
205
|
+
if (pattern.includes('/coverage/') && hasSegment('coverage'))
|
|
206
|
+
return true;
|
|
207
|
+
if (pattern.includes('__pycache__') && hasSegment('__pycache__'))
|
|
208
|
+
return true;
|
|
209
|
+
if (pattern.includes('/vendor/') && hasSegment('vendor'))
|
|
210
|
+
return true;
|
|
211
|
+
if (pattern.includes('/.next/') && hasSegment('.next'))
|
|
212
|
+
return true;
|
|
213
|
+
if (pattern.includes('/.nuxt/') && hasSegment('.nuxt'))
|
|
214
|
+
return true;
|
|
215
|
+
if (pattern.includes('/target/') && hasSegment('target'))
|
|
216
|
+
return true;
|
|
217
|
+
if (pattern.includes('/.cache/') && hasSegment('.cache'))
|
|
218
|
+
return true;
|
|
219
|
+
if (pattern.endsWith('*.min.js') && rel.endsWith('.min.js'))
|
|
220
|
+
return true;
|
|
221
|
+
if (pattern.endsWith('*.bundle.js') && rel.endsWith('.bundle.js'))
|
|
222
|
+
return true;
|
|
223
|
+
if (pattern.endsWith('*.pyc') && rel.endsWith('.pyc'))
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeletonizer.d.ts","sourceRoot":"","sources":["../src/skeletonizer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ7D"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Language-aware skeleton generation.
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.buildSkeletonForFile = buildSkeletonForFile;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const registry_1 = require("./languages/registry");
|
|
42
|
+
function buildSkeletonForFile(filePath) {
|
|
43
|
+
try {
|
|
44
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
45
|
+
const adapter = (0, registry_1.getAdapter)(filePath);
|
|
46
|
+
return adapter.generateSkeleton(content, filePath);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return `/* Failed to parse file: ${error instanceof Error ? error.message : 'Unknown error'} */`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=skeletonizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeletonizer.js","sourceRoot":"","sources":["../src/skeletonizer.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKH,oDAQC;AAXD,uCAAyB;AACzB,mDAAkD;AAElD,SAAgB,oBAAoB,CAAC,QAAgB;IACnD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,IAAA,qBAAU,EAAC,QAAQ,CAAC,CAAC;QACrC,OAAO,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,KAAK,CAAC;IACnG,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple tokenizer for counting approximate tokens in code
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Count approximate tokens in a string by splitting on whitespace and punctuation
|
|
6
|
+
* This is a simple heuristic for estimating token count
|
|
7
|
+
*/
|
|
8
|
+
export declare function countTokens(text: string): number;
|
|
9
|
+
//# sourceMappingURL=tokenizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../src/tokenizer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWhD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Simple tokenizer for counting approximate tokens in code
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.countTokens = countTokens;
|
|
7
|
+
/**
|
|
8
|
+
* Count approximate tokens in a string by splitting on whitespace and punctuation
|
|
9
|
+
* This is a simple heuristic for estimating token count
|
|
10
|
+
*/
|
|
11
|
+
function countTokens(text) {
|
|
12
|
+
if (!text || text.trim().length === 0) {
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
// Split on whitespace, punctuation, and common code delimiters
|
|
16
|
+
const tokens = text
|
|
17
|
+
.split(/[\s\n\r\t.,;:!?(){}[\]<>'"/\\|`~@#$%^&*+=-]+/)
|
|
18
|
+
.filter(token => token.length > 0);
|
|
19
|
+
return tokens.length;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=tokenizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../src/tokenizer.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAMH,kCAWC;AAfD;;;GAGG;AACH,SAAgB,WAAW,CAAC,IAAY;IACtC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,+DAA+D;IAC/D,MAAM,MAAM,GAAG,IAAI;SAChB,KAAK,CAAC,8CAA8C,CAAC;SACrD,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAErC,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared type definitions for skannr
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Options for analyzing a project
|
|
6
|
+
*/
|
|
7
|
+
export interface AnalyzeOptions {
|
|
8
|
+
/** Root directory of the project */
|
|
9
|
+
root: string;
|
|
10
|
+
/** Natural language question about the codebase */
|
|
11
|
+
question: string;
|
|
12
|
+
/** Number of top files to return */
|
|
13
|
+
limit?: number;
|
|
14
|
+
/** Generate symbol mapping for on-demand retrieval */
|
|
15
|
+
generateMapping?: boolean;
|
|
16
|
+
/** Output path for mapping file (default: <root>/code-analyzer.mapping.json) */
|
|
17
|
+
mappingOutputPath?: string;
|
|
18
|
+
/** Use enhanced ranking algorithm with dependency analysis */
|
|
19
|
+
enhancedRanking?: boolean;
|
|
20
|
+
/** Optional filter for module keys (e.g. ['auth', 'api']) */
|
|
21
|
+
moduleKeys?: string[];
|
|
22
|
+
/** Optional module definitions from config (module -> directory list) */
|
|
23
|
+
moduleDefinitions?: Record<string, string[]>;
|
|
24
|
+
/** Optional exclusion globs */
|
|
25
|
+
exclude?: string[];
|
|
26
|
+
/** Optional extension allow-list */
|
|
27
|
+
extensions?: string[];
|
|
28
|
+
/** Language strategy */
|
|
29
|
+
lang?: 'typescript' | 'javascript' | 'python' | 'auto';
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Ranked file with relevance score
|
|
33
|
+
*/
|
|
34
|
+
export interface RankedFile {
|
|
35
|
+
/** Absolute path to the file */
|
|
36
|
+
path: string;
|
|
37
|
+
/** Relevance score (0-1) */
|
|
38
|
+
score: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Analysis result for a single file
|
|
42
|
+
*/
|
|
43
|
+
export interface FileAnalysis {
|
|
44
|
+
/** Relative path to the file */
|
|
45
|
+
path: string;
|
|
46
|
+
/** Relevance score (0-1) */
|
|
47
|
+
score: number;
|
|
48
|
+
/** Generated skeleton code */
|
|
49
|
+
skeleton: string;
|
|
50
|
+
/** Approximate token count of original file */
|
|
51
|
+
originalTokenCount: number;
|
|
52
|
+
/** Approximate token count of skeleton */
|
|
53
|
+
skeletonTokenCount: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Complete analysis result
|
|
57
|
+
*/
|
|
58
|
+
export interface AnalysisResult {
|
|
59
|
+
/** The original question */
|
|
60
|
+
question: string;
|
|
61
|
+
/** The project root directory */
|
|
62
|
+
root: string;
|
|
63
|
+
/** Number of files requested */
|
|
64
|
+
limit: number;
|
|
65
|
+
/** Analyzed files with skeletons */
|
|
66
|
+
files: FileAnalysis[];
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,wBAAwB;IACxB,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Universal Code Analyzer
|
|
2
|
+
|
|
3
|
+
You have a tool called `scan_codebase` that scans any repository and returns compressed **skeletons** — function signatures and types without the full implementation bodies.
|
|
4
|
+
|
|
5
|
+
## When to use it
|
|
6
|
+
|
|
7
|
+
Use `scan_codebase` before reading source files. It tells you which files are relevant and shows their structure without burning tokens on full file contents.
|
|
8
|
+
|
|
9
|
+
## Parameters
|
|
10
|
+
|
|
11
|
+
- `question` (**required**): what you want to understand, e.g. `"how are messages sent?"`
|
|
12
|
+
- `root` (**required**): absolute path to the repository, e.g. `/home/user/my-project`
|
|
13
|
+
- `limit`: how many files to return (default: 10)
|
|
14
|
+
- `modules`: narrow the search to specific modules or directories
|
|
15
|
+
|
|
16
|
+
## Example
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
scan_codebase({
|
|
20
|
+
question: "How does the authentication flow work?",
|
|
21
|
+
root: "/home/user/my-project",
|
|
22
|
+
modules: ["auth"]
|
|
23
|
+
})
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The response includes each file's path, relevance score, skeleton code, and token counts so you can decide what to read in full.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "code-analyzer",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Analyze any codebase and return token-efficient structural skeletons",
|
|
5
|
+
"mcpServers": {
|
|
6
|
+
"code-analyzer": {
|
|
7
|
+
"command": "node",
|
|
8
|
+
"args": ["${extensionPath}/dist/server.js"]
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"contextFileName": "GEMINI.md"
|
|
12
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { analyzeProject } from '../../dist/index';
|
|
5
|
+
|
|
6
|
+
const server = new Server(
|
|
7
|
+
{ name: 'code-analyzer', version: '0.1.0' },
|
|
8
|
+
{ capabilities: { tools: {} } }
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
12
|
+
tools: [
|
|
13
|
+
{
|
|
14
|
+
name: 'scan_codebase',
|
|
15
|
+
description: 'Analyzes any codebase to answer questions about its structure and architecture. Scans files, generates structural skeletons, and ranks results using hybrid retrieval. Supports TypeScript, JavaScript, and Python. Pass the root path of any repository.',
|
|
16
|
+
inputSchema: {
|
|
17
|
+
type: 'object',
|
|
18
|
+
properties: {
|
|
19
|
+
question: {
|
|
20
|
+
type: 'string',
|
|
21
|
+
description: 'What you want to understand about the codebase',
|
|
22
|
+
},
|
|
23
|
+
root: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
description: 'Absolute path to the repository root',
|
|
26
|
+
},
|
|
27
|
+
limit: {
|
|
28
|
+
type: 'number',
|
|
29
|
+
description: 'Max number of files to return (default: 10)',
|
|
30
|
+
},
|
|
31
|
+
modules: {
|
|
32
|
+
type: 'array',
|
|
33
|
+
items: { type: 'string' },
|
|
34
|
+
description: 'Optional module keys (or directory names) to narrow the search scope',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
required: ['question', 'root'],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
44
|
+
if (request.params.name !== 'scan_codebase') {
|
|
45
|
+
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const { question, root, limit = 10, modules } = request.params.arguments as {
|
|
49
|
+
question: string;
|
|
50
|
+
root: string;
|
|
51
|
+
limit?: number;
|
|
52
|
+
modules?: string[];
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const result = await analyzeProject({ question, root, limit, moduleKeys: modules });
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const transport = new StdioServerTransport();
|
|
63
|
+
server.connect(transport).catch(console.error);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"outDir": "./dist",
|
|
6
|
+
"rootDir": "./src",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"moduleResolution": "node",
|
|
11
|
+
"types": ["node"]
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*"]
|
|
14
|
+
}
|
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "skannr",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "A universal tool to analyze any codebase and generate semantic skeletons for AI agents",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"skannr": "dist/cli.js",
|
|
9
|
+
"skannr-benchmark": "dist/benchmark.js",
|
|
10
|
+
"skannr-agent": "dist/agent-cli.js"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"test": "jest",
|
|
15
|
+
"lint": "eslint src --ext .ts",
|
|
16
|
+
"start": "npm run build && node dist/cli.js",
|
|
17
|
+
"cli": "npm run build && node dist/cli.js",
|
|
18
|
+
"benchmark": "npm run build && node dist/benchmark.js",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"typescript",
|
|
23
|
+
"code-analysis",
|
|
24
|
+
"skeleton",
|
|
25
|
+
"ast"
|
|
26
|
+
],
|
|
27
|
+
"author": "",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@google/generative-ai": "^0.21.0",
|
|
31
|
+
"ts-morph": "^21.0.1"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/jest": "^29.5.11",
|
|
35
|
+
"@types/node": "^20.11.0",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
37
|
+
"@typescript-eslint/parser": "^6.19.0",
|
|
38
|
+
"eslint": "^8.56.0",
|
|
39
|
+
"jest": "^29.7.0",
|
|
40
|
+
"ts-jest": "^29.1.1",
|
|
41
|
+
"typescript": "^5.3.3"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|