prinfer 0.5.2 → 0.6.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/README.md +26 -21
- package/dist/cli.cjs +279 -130
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +278 -130
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +298 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -1
- package/dist/index.d.ts +66 -1
- package/dist/index.js +294 -12
- package/dist/index.js.map +1 -1
- package/dist/mcp.cjs +233 -85
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.js +233 -85
- package/dist/mcp.js.map +1 -1
- package/dist/postinstall.cjs +2 -25
- package/dist/postinstall.cjs.map +1 -1
- package/dist/postinstall.js +2 -25
- package/dist/postinstall.js.map +1 -1
- package/package.json +1 -1
package/dist/mcp.cjs
CHANGED
|
@@ -71,66 +71,203 @@ function loadProgram(entryFileAbs, project) {
|
|
|
71
71
|
function isArrowOrFnExpr(n) {
|
|
72
72
|
return !!n && (import_typescript.default.isArrowFunction(n) || import_typescript.default.isFunctionExpression(n));
|
|
73
73
|
}
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if ((import_typescript.default.isMethodDeclaration(node) || import_typescript.default.isMethodSignature(node)) && nodeNameText(node.name) === name) {
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
if (import_typescript.default.isPropertyAssignment(node) && nodeNameText(node.name) === name) {
|
|
90
|
-
return isArrowOrFnExpr(node.initializer);
|
|
74
|
+
function findSmallestNodeAtPosition(sourceFile, position) {
|
|
75
|
+
let result;
|
|
76
|
+
function visit(node) {
|
|
77
|
+
const start = node.getStart(sourceFile);
|
|
78
|
+
const end = node.getEnd();
|
|
79
|
+
if (position < start || position >= end) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (!result || node.getWidth(sourceFile) <= result.getWidth(sourceFile)) {
|
|
83
|
+
result = node;
|
|
84
|
+
}
|
|
85
|
+
import_typescript.default.forEachChild(node, visit);
|
|
91
86
|
}
|
|
92
|
-
|
|
87
|
+
visit(sourceFile);
|
|
88
|
+
return result;
|
|
93
89
|
}
|
|
94
|
-
function
|
|
95
|
-
|
|
90
|
+
function findHoverableAncestor(sourceFile, position) {
|
|
91
|
+
const smallestNode = findSmallestNodeAtPosition(sourceFile, position);
|
|
92
|
+
if (!smallestNode) return void 0;
|
|
93
|
+
let bestMatch = smallestNode;
|
|
94
|
+
function visit(n) {
|
|
95
|
+
const start = n.getStart(sourceFile);
|
|
96
|
+
const end = n.getEnd();
|
|
97
|
+
if (position < start || position >= end) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
if (import_typescript.default.isCallExpression(n)) {
|
|
101
|
+
const expr = n.expression;
|
|
102
|
+
if (import_typescript.default.isIdentifier(expr)) {
|
|
103
|
+
if (position >= expr.getStart(sourceFile) && position < expr.getEnd()) {
|
|
104
|
+
bestMatch = n;
|
|
105
|
+
}
|
|
106
|
+
} else if (import_typescript.default.isPropertyAccessExpression(expr)) {
|
|
107
|
+
if (position >= expr.name.getStart(sourceFile) && position < expr.name.getEnd()) {
|
|
108
|
+
bestMatch = n;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (import_typescript.default.isFunctionDeclaration(n) && n.name) {
|
|
113
|
+
if (position >= n.name.getStart(sourceFile) && position < n.name.getEnd()) {
|
|
114
|
+
bestMatch = n;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (import_typescript.default.isVariableDeclaration(n) && import_typescript.default.isIdentifier(n.name)) {
|
|
118
|
+
if (position >= n.name.getStart(sourceFile) && position < n.name.getEnd()) {
|
|
119
|
+
bestMatch = n;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if ((import_typescript.default.isMethodDeclaration(n) || import_typescript.default.isMethodSignature(n)) && import_typescript.default.isIdentifier(n.name)) {
|
|
123
|
+
if (position >= n.name.getStart(sourceFile) && position < n.name.getEnd()) {
|
|
124
|
+
bestMatch = n;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (import_typescript.default.isClassDeclaration(n) && n.name) {
|
|
128
|
+
if (position >= n.name.getStart(sourceFile) && position < n.name.getEnd()) {
|
|
129
|
+
bestMatch = n;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (import_typescript.default.isInterfaceDeclaration(n) && n.name) {
|
|
133
|
+
if (position >= n.name.getStart(sourceFile) && position < n.name.getEnd()) {
|
|
134
|
+
bestMatch = n;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
import_typescript.default.forEachChild(n, visit);
|
|
96
138
|
return true;
|
|
97
139
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
function isNamedNode(node, name) {
|
|
101
|
-
return isFunctionLikeNamed(node, name) || isVariableNamed(node, name);
|
|
140
|
+
visit(sourceFile);
|
|
141
|
+
return bestMatch;
|
|
102
142
|
}
|
|
103
|
-
function
|
|
104
|
-
const
|
|
105
|
-
|
|
143
|
+
function findNodeAtPosition(sourceFile, line, column) {
|
|
144
|
+
const lineCount = sourceFile.getLineStarts().length;
|
|
145
|
+
if (line < 1 || line > lineCount) {
|
|
146
|
+
return void 0;
|
|
147
|
+
}
|
|
148
|
+
const lineStart = sourceFile.getLineStarts()[line - 1];
|
|
149
|
+
const lineEnd = line < lineCount ? sourceFile.getLineStarts()[line] : sourceFile.getEnd();
|
|
150
|
+
const lineLength = lineEnd - lineStart;
|
|
151
|
+
if (column < 1 || column > lineLength + 1) {
|
|
152
|
+
return void 0;
|
|
153
|
+
}
|
|
154
|
+
const position = sourceFile.getPositionOfLineAndCharacter(
|
|
155
|
+
line - 1,
|
|
156
|
+
column - 1
|
|
106
157
|
);
|
|
107
|
-
return
|
|
158
|
+
return findHoverableAncestor(sourceFile, position);
|
|
108
159
|
}
|
|
109
|
-
function
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
} else {
|
|
121
|
-
found = node;
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
160
|
+
function getSymbolKind(node) {
|
|
161
|
+
if (import_typescript.default.isFunctionDeclaration(node)) return "function";
|
|
162
|
+
if (import_typescript.default.isArrowFunction(node)) return "function";
|
|
163
|
+
if (import_typescript.default.isFunctionExpression(node)) return "function";
|
|
164
|
+
if (import_typescript.default.isMethodDeclaration(node)) return "method";
|
|
165
|
+
if (import_typescript.default.isMethodSignature(node)) return "method";
|
|
166
|
+
if (import_typescript.default.isVariableDeclaration(node)) {
|
|
167
|
+
const init = node.initializer;
|
|
168
|
+
if (init && (import_typescript.default.isArrowFunction(init) || import_typescript.default.isFunctionExpression(init))) {
|
|
169
|
+
return "function";
|
|
124
170
|
}
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return
|
|
171
|
+
return "variable";
|
|
172
|
+
}
|
|
173
|
+
if (import_typescript.default.isParameter(node)) return "parameter";
|
|
174
|
+
if (import_typescript.default.isPropertyDeclaration(node)) return "property";
|
|
175
|
+
if (import_typescript.default.isPropertySignature(node)) return "property";
|
|
176
|
+
if (import_typescript.default.isPropertyAccessExpression(node)) return "property";
|
|
177
|
+
if (import_typescript.default.isCallExpression(node)) return "call";
|
|
178
|
+
if (import_typescript.default.isTypeAliasDeclaration(node)) return "type";
|
|
179
|
+
if (import_typescript.default.isInterfaceDeclaration(node)) return "interface";
|
|
180
|
+
if (import_typescript.default.isClassDeclaration(node)) return "class";
|
|
181
|
+
if (import_typescript.default.isIdentifier(node)) return "identifier";
|
|
182
|
+
return "unknown";
|
|
129
183
|
}
|
|
130
|
-
function
|
|
184
|
+
function getNodeName(node) {
|
|
185
|
+
if (import_typescript.default.isFunctionDeclaration(node) && node.name) {
|
|
186
|
+
return node.name.text;
|
|
187
|
+
}
|
|
188
|
+
if (import_typescript.default.isVariableDeclaration(node) && import_typescript.default.isIdentifier(node.name)) {
|
|
189
|
+
return node.name.text;
|
|
190
|
+
}
|
|
191
|
+
if ((import_typescript.default.isMethodDeclaration(node) || import_typescript.default.isMethodSignature(node)) && import_typescript.default.isIdentifier(node.name)) {
|
|
192
|
+
return node.name.text;
|
|
193
|
+
}
|
|
194
|
+
if (import_typescript.default.isPropertyAccessExpression(node)) {
|
|
195
|
+
return node.name.text;
|
|
196
|
+
}
|
|
197
|
+
if (import_typescript.default.isCallExpression(node)) {
|
|
198
|
+
const expr = node.expression;
|
|
199
|
+
if (import_typescript.default.isIdentifier(expr)) return expr.text;
|
|
200
|
+
if (import_typescript.default.isPropertyAccessExpression(expr)) return expr.name.text;
|
|
201
|
+
}
|
|
202
|
+
if (import_typescript.default.isParameter(node) && import_typescript.default.isIdentifier(node.name)) {
|
|
203
|
+
return node.name.text;
|
|
204
|
+
}
|
|
205
|
+
if (import_typescript.default.isIdentifier(node)) {
|
|
206
|
+
return node.text;
|
|
207
|
+
}
|
|
208
|
+
if (import_typescript.default.isTypeAliasDeclaration(node) || import_typescript.default.isInterfaceDeclaration(node) || import_typescript.default.isClassDeclaration(node)) {
|
|
209
|
+
return node.name?.text;
|
|
210
|
+
}
|
|
211
|
+
return void 0;
|
|
212
|
+
}
|
|
213
|
+
function getDocumentation(checker, symbol) {
|
|
214
|
+
if (!symbol) return void 0;
|
|
215
|
+
const docs = symbol.getDocumentationComment(checker);
|
|
216
|
+
if (docs.length === 0) return void 0;
|
|
217
|
+
return import_typescript.default.displayPartsToString(docs);
|
|
218
|
+
}
|
|
219
|
+
function getHoverInfo(program, node, sourceFile, includeDocs) {
|
|
131
220
|
const checker = program.getTypeChecker();
|
|
132
|
-
const sf = sourceFile
|
|
133
|
-
const line =
|
|
221
|
+
const sf = sourceFile;
|
|
222
|
+
const { line, character } = sf.getLineAndCharacterOfPosition(
|
|
223
|
+
node.getStart(sf)
|
|
224
|
+
);
|
|
225
|
+
const flags = import_typescript.default.TypeFormatFlags.NoTruncation;
|
|
226
|
+
const kind = getSymbolKind(node);
|
|
227
|
+
const name = getNodeName(node);
|
|
228
|
+
let symbol;
|
|
229
|
+
if (import_typescript.default.isCallExpression(node)) {
|
|
230
|
+
const expr = node.expression;
|
|
231
|
+
if (import_typescript.default.isPropertyAccessExpression(expr)) {
|
|
232
|
+
symbol = checker.getSymbolAtLocation(expr.name);
|
|
233
|
+
} else {
|
|
234
|
+
symbol = checker.getSymbolAtLocation(expr);
|
|
235
|
+
}
|
|
236
|
+
} else {
|
|
237
|
+
const nodeWithName2 = node;
|
|
238
|
+
if (nodeWithName2.name) {
|
|
239
|
+
symbol = checker.getSymbolAtLocation(nodeWithName2.name);
|
|
240
|
+
} else {
|
|
241
|
+
symbol = checker.getSymbolAtLocation(node);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const documentation = includeDocs ? getDocumentation(checker, symbol) : void 0;
|
|
245
|
+
if (import_typescript.default.isCallExpression(node)) {
|
|
246
|
+
const sig2 = checker.getResolvedSignature(node);
|
|
247
|
+
if (sig2) {
|
|
248
|
+
const signature = checker.signatureToString(sig2, void 0, flags);
|
|
249
|
+
const ret = checker.getReturnTypeOfSignature(sig2);
|
|
250
|
+
const returnType = checker.typeToString(ret, void 0, flags);
|
|
251
|
+
return {
|
|
252
|
+
signature,
|
|
253
|
+
returnType,
|
|
254
|
+
line: line + 1,
|
|
255
|
+
column: character + 1,
|
|
256
|
+
documentation,
|
|
257
|
+
kind,
|
|
258
|
+
name
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
const t2 = checker.getTypeAtLocation(node);
|
|
262
|
+
return {
|
|
263
|
+
signature: checker.typeToString(t2, void 0, flags),
|
|
264
|
+
line: line + 1,
|
|
265
|
+
column: character + 1,
|
|
266
|
+
documentation,
|
|
267
|
+
kind,
|
|
268
|
+
name
|
|
269
|
+
};
|
|
270
|
+
}
|
|
134
271
|
let sig;
|
|
135
272
|
if (import_typescript.default.isFunctionDeclaration(node) || import_typescript.default.isMethodDeclaration(node)) {
|
|
136
273
|
sig = checker.getSignatureFromDeclaration(node) ?? void 0;
|
|
@@ -145,26 +282,39 @@ function getTypeInfo(program, node, sourceFile) {
|
|
|
145
282
|
} else if (import_typescript.default.isMethodSignature(node)) {
|
|
146
283
|
sig = checker.getSignatureFromDeclaration(node) ?? void 0;
|
|
147
284
|
}
|
|
148
|
-
const flags = import_typescript.default.TypeFormatFlags.NoTruncation;
|
|
149
285
|
if (sig) {
|
|
150
286
|
const signature = checker.signatureToString(sig, void 0, flags);
|
|
151
287
|
const ret = checker.getReturnTypeOfSignature(sig);
|
|
152
288
|
const returnType = checker.typeToString(ret, void 0, flags);
|
|
153
|
-
return {
|
|
289
|
+
return {
|
|
290
|
+
signature,
|
|
291
|
+
returnType,
|
|
292
|
+
line: line + 1,
|
|
293
|
+
column: character + 1,
|
|
294
|
+
documentation,
|
|
295
|
+
kind,
|
|
296
|
+
name
|
|
297
|
+
};
|
|
154
298
|
}
|
|
155
299
|
const nodeWithName = node;
|
|
156
|
-
let
|
|
300
|
+
let targetNode = node;
|
|
157
301
|
if (nodeWithName.name && import_typescript.default.isIdentifier(nodeWithName.name)) {
|
|
158
|
-
|
|
302
|
+
targetNode = nodeWithName.name;
|
|
159
303
|
}
|
|
160
|
-
const t = checker.getTypeAtLocation(
|
|
161
|
-
return {
|
|
304
|
+
const t = checker.getTypeAtLocation(targetNode);
|
|
305
|
+
return {
|
|
306
|
+
signature: checker.typeToString(t, void 0, flags),
|
|
307
|
+
line: line + 1,
|
|
308
|
+
column: character + 1,
|
|
309
|
+
documentation,
|
|
310
|
+
kind,
|
|
311
|
+
name
|
|
312
|
+
};
|
|
162
313
|
}
|
|
163
314
|
|
|
164
315
|
// src/index.ts
|
|
165
|
-
function
|
|
166
|
-
const
|
|
167
|
-
const { line, project } = opts;
|
|
316
|
+
function hover(file, line, column, options) {
|
|
317
|
+
const { project, include_docs = false } = options ?? {};
|
|
168
318
|
const entryFileAbs = import_node_path2.default.resolve(process.cwd(), file);
|
|
169
319
|
if (!import_node_fs.default.existsSync(entryFileAbs)) {
|
|
170
320
|
throw new Error(`File not found: ${entryFileAbs}`);
|
|
@@ -176,14 +326,11 @@ function inferType(file, name, options) {
|
|
|
176
326
|
`Could not load source file into the program (check tsconfig include/exclude): ${entryFileAbs}`
|
|
177
327
|
);
|
|
178
328
|
}
|
|
179
|
-
const node =
|
|
329
|
+
const node = findNodeAtPosition(sourceFile, line, column);
|
|
180
330
|
if (!node) {
|
|
181
|
-
|
|
182
|
-
throw new Error(
|
|
183
|
-
`No symbol named "${name}"${lineInfo} found in ${entryFileAbs}`
|
|
184
|
-
);
|
|
331
|
+
throw new Error(`No symbol found at ${entryFileAbs}:${line}:${column}`);
|
|
185
332
|
}
|
|
186
|
-
return
|
|
333
|
+
return getHoverInfo(program, node, sourceFile, include_docs);
|
|
187
334
|
}
|
|
188
335
|
|
|
189
336
|
// src/mcp.ts
|
|
@@ -197,19 +344,11 @@ Setup:
|
|
|
197
344
|
Run 'prinfer setup' to configure Claude Code automatically.
|
|
198
345
|
|
|
199
346
|
Manual setup:
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
{
|
|
203
|
-
"mcpServers": {
|
|
204
|
-
"prinfer": {
|
|
205
|
-
"command": "prinfer-mcp"
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
347
|
+
Run: claude mcp add prinfer node /path/to/prinfer-mcp
|
|
209
348
|
|
|
210
349
|
Provided tools:
|
|
211
|
-
|
|
212
|
-
|
|
350
|
+
hover(file, line, column, include_docs?, project?)
|
|
351
|
+
Get TypeScript type information at a specific position.
|
|
213
352
|
|
|
214
353
|
See also:
|
|
215
354
|
prinfer --help CLI for direct type inspection
|
|
@@ -220,28 +359,37 @@ if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
|
220
359
|
}
|
|
221
360
|
var server = new import_mcp.McpServer({
|
|
222
361
|
name: "prinfer",
|
|
223
|
-
version: "0.
|
|
362
|
+
version: "0.3.0"
|
|
224
363
|
});
|
|
225
364
|
server.tool(
|
|
226
|
-
"
|
|
227
|
-
"
|
|
365
|
+
"hover",
|
|
366
|
+
"Get TypeScript type information at a specific position in a file. Returns the type signature, return type, documentation, and symbol kind.",
|
|
228
367
|
{
|
|
229
368
|
file: import_zod.z.string().describe("Path to the TypeScript file"),
|
|
230
|
-
|
|
231
|
-
|
|
369
|
+
line: import_zod.z.number().describe("1-based line number"),
|
|
370
|
+
column: import_zod.z.number().describe("1-based column (character position)"),
|
|
371
|
+
include_docs: import_zod.z.boolean().optional().describe("Include JSDoc/TSDoc documentation"),
|
|
232
372
|
project: import_zod.z.string().optional().describe("Optional path to tsconfig.json")
|
|
233
373
|
},
|
|
234
|
-
async ({ file,
|
|
374
|
+
async ({ file, line, column, include_docs, project }) => {
|
|
235
375
|
try {
|
|
236
|
-
const result =
|
|
376
|
+
const result = hover(file, line, column, { include_docs, project });
|
|
237
377
|
let text = `Type: ${result.signature}`;
|
|
238
378
|
if (result.returnType) {
|
|
239
379
|
text += `
|
|
240
380
|
Returns: ${result.returnType}`;
|
|
241
381
|
}
|
|
242
|
-
if (result.
|
|
382
|
+
if (result.name) {
|
|
383
|
+
text += `
|
|
384
|
+
Name: ${result.name}`;
|
|
385
|
+
}
|
|
386
|
+
text += `
|
|
387
|
+
Kind: ${result.kind}`;
|
|
388
|
+
text += `
|
|
389
|
+
Position: ${result.line}:${result.column}`;
|
|
390
|
+
if (result.documentation) {
|
|
243
391
|
text += `
|
|
244
|
-
|
|
392
|
+
Documentation: ${result.documentation}`;
|
|
245
393
|
}
|
|
246
394
|
return { content: [{ type: "text", text }] };
|
|
247
395
|
} catch (error) {
|
package/dist/mcp.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mcp.ts","../src/index.ts","../src/core.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { inferType } from \"./index.js\";\n\nconst HELP = `\nprinfer-mcp - MCP server for TypeScript type inference\n\nThis is an MCP (Model Context Protocol) server. It's designed to be run\nby Claude Code, not directly from the command line.\n\nSetup:\n Run 'prinfer setup' to configure Claude Code automatically.\n\nManual setup:\n Add to ~/.claude/settings.json:\n\n {\n \"mcpServers\": {\n \"prinfer\": {\n \"command\": \"prinfer-mcp\"\n }\n }\n }\n\nProvided tools:\n infer_type(file, name, line?, project?)\n Infer the TypeScript type of a function or variable.\n\nSee also:\n prinfer --help CLI for direct type inspection\n`.trim();\n\nif (process.argv.includes(\"--help\") || process.argv.includes(\"-h\")) {\n\tconsole.log(HELP);\n\tprocess.exit(0);\n}\n\nconst server = new McpServer({\n\tname: \"prinfer\",\n\tversion: \"0.2.1\",\n});\n\nserver.tool(\n\t\"infer_type\",\n\t\"Infer the TypeScript type of a function or variable in a file. Returns the type signature and optionally the return type for functions.\",\n\t{\n\t\tfile: z.string().describe(\"Path to the TypeScript file\"),\n\t\tname: z\n\t\t\t.string()\n\t\t\t.describe(\"Name of the function or variable to inspect\"),\n\t\tline: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\"Optional line number to narrow search (1-based)\"),\n\t\tproject: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\"Optional path to tsconfig.json\"),\n\t},\n\tasync ({ file, name, line, project }) => {\n\t\ttry {\n\t\t\tconst result = inferType(file, name, { line, project });\n\t\t\tlet text = `Type: ${result.signature}`;\n\t\t\tif (result.returnType) {\n\t\t\t\ttext += `\\nReturns: ${result.returnType}`;\n\t\t\t}\n\t\t\tif (result.line) {\n\t\t\t\ttext += `\\nLine: ${result.line}`;\n\t\t\t}\n\t\t\treturn { content: [{ type: \"text\", text }] };\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: `Error: ${(error as Error).message}`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tisError: true,\n\t\t\t};\n\t\t}\n\t},\n);\n\nasync function main() {\n\tconst transport = new StdioServerTransport();\n\tawait server.connect(transport);\n}\n\nmain().catch(console.error);\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { findNodeByNameAndLine, getTypeInfo, loadProgram } from \"./core.js\";\nimport type { InferredTypeResult, Options } from \"./types.js\";\n\n// Re-export types\nexport type { Options, InferredTypeResult };\n\n// Re-export core utilities\nexport {\n\tfindFirstMatch,\n\tfindNearestTsconfig,\n\tfindNodeByNameAndLine,\n\tgetLineNumber,\n\tgetTypeInfo,\n\tloadProgram,\n} from \"./core.js\";\n\n/**\n * Infer the type of a function or variable in a TypeScript file\n *\n * @param file - Path to the TypeScript file\n * @param name - Name of the function/variable to inspect\n * @param options - Optional: project path (string) or options object with line and project\n * @returns The inferred type information\n * @throws Error if file not found or symbol not found\n *\n * @example\n * ```ts\n * import { inferType } from \"prinfer\";\n *\n * // By name only\n * const result = inferType(\"./src/utils.ts\", \"myFunction\");\n * console.log(result.signature);\n * // => \"(x: number, y: string) => boolean\"\n *\n * // By name and line number\n * const result2 = inferType(\"./src/utils.ts\", \"commandResult\", { line: 75 });\n * console.log(result2.signature);\n * // => \"Result<VaultAction[], CommandError>\"\n * ```\n */\nexport function inferType(\n\tfile: string,\n\tname: string,\n\toptions?: string | { line?: number; project?: string },\n): InferredTypeResult {\n\t// Normalize options for backward compatibility\n\tconst opts =\n\t\ttypeof options === \"string\" ? { project: options } : (options ?? {});\n\tconst { line, project } = opts;\n\n\tconst entryFileAbs = path.resolve(process.cwd(), file);\n\n\tif (!fs.existsSync(entryFileAbs)) {\n\t\tthrow new Error(`File not found: ${entryFileAbs}`);\n\t}\n\n\tconst program = loadProgram(entryFileAbs, project);\n\tconst sourceFile = program.getSourceFile(entryFileAbs);\n\n\tif (!sourceFile) {\n\t\tthrow new Error(\n\t\t\t`Could not load source file into the program (check tsconfig include/exclude): ${entryFileAbs}`,\n\t\t);\n\t}\n\n\tconst node = findNodeByNameAndLine(sourceFile, name, line);\n\tif (!node) {\n\t\tconst lineInfo = line !== undefined ? ` at line ${line}` : \"\";\n\t\tthrow new Error(\n\t\t\t`No symbol named \"${name}\"${lineInfo} found in ${entryFileAbs}`,\n\t\t);\n\t}\n\n\treturn getTypeInfo(program, node, sourceFile);\n}\n\n/**\n * Infer the type using an options object\n *\n * @param options - Options for type inference\n * @returns The inferred type information\n */\nexport function inferTypeFromOptions(options: Options): InferredTypeResult {\n\treturn inferType(options.file, options.name, {\n\t\tline: options.line,\n\t\tproject: options.project,\n\t});\n}\n","import path from \"node:path\";\nimport ts from \"typescript\";\nimport type { InferredTypeResult } from \"./types.js\";\n\n/**\n * Find the nearest tsconfig.json from a starting directory\n */\nexport function findNearestTsconfig(startDir: string): string | undefined {\n\treturn (\n\t\tts.findConfigFile(startDir, ts.sys.fileExists, \"tsconfig.json\") ??\n\t\tundefined\n\t);\n}\n\n/**\n * Load a TypeScript program from an entry file\n */\nexport function loadProgram(\n\tentryFileAbs: string,\n\tproject?: string,\n): ts.Program {\n\tconst fileDir = path.dirname(entryFileAbs);\n\tconst tsconfigPath = project\n\t\t? path.resolve(process.cwd(), project)\n\t\t: findNearestTsconfig(fileDir);\n\n\tif (!tsconfigPath) {\n\t\t// Fallback: single-file program\n\t\treturn ts.createProgram([entryFileAbs], {\n\t\t\ttarget: ts.ScriptTarget.ES2022,\n\t\t\tmodule: ts.ModuleKind.ESNext,\n\t\t\tstrict: true,\n\t\t\tallowJs: true,\n\t\t\tcheckJs: false,\n\t\t\tmoduleResolution: ts.ModuleResolutionKind.Bundler,\n\t\t\tskipLibCheck: true,\n\t\t});\n\t}\n\n\tconst cfg = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n\tif (cfg.error) {\n\t\tthrow new Error(\n\t\t\tts.flattenDiagnosticMessageText(cfg.error.messageText, \"\\n\"),\n\t\t);\n\t}\n\n\tconst parsed = ts.parseJsonConfigFileContent(\n\t\tcfg.config,\n\t\tts.sys,\n\t\tpath.dirname(tsconfigPath),\n\t);\n\treturn ts.createProgram({\n\t\trootNames: parsed.fileNames,\n\t\toptions: parsed.options,\n\t});\n}\n\nfunction isArrowOrFnExpr(\n\tn: ts.Node | undefined,\n): n is ts.ArrowFunction | ts.FunctionExpression {\n\treturn !!n && (ts.isArrowFunction(n) || ts.isFunctionExpression(n));\n}\n\nfunction nodeNameText(\n\tn: ts.PropertyName | ts.BindingName | undefined,\n): string | undefined {\n\tif (!n) return undefined;\n\tif (ts.isIdentifier(n)) return n.text;\n\tif (ts.isStringLiteral(n)) return n.text;\n\tif (ts.isNumericLiteral(n)) return n.text;\n\treturn undefined; // ignore computed names etc.\n}\n\nfunction isFunctionLikeNamed(node: ts.Node, name: string): boolean {\n\t// function foo() {}\n\tif (ts.isFunctionDeclaration(node) && node.name?.text === name) return true;\n\n\t// const foo = () => {} / function() {}\n\tif (\n\t\tts.isVariableDeclaration(node) &&\n\t\tts.isIdentifier(node.name) &&\n\t\tnode.name.text === name\n\t) {\n\t\treturn isArrowOrFnExpr(node.initializer);\n\t}\n\n\t// class C { foo() {} } / interface signatures\n\tif (\n\t\t(ts.isMethodDeclaration(node) || ts.isMethodSignature(node)) &&\n\t\tnodeNameText(node.name) === name\n\t) {\n\t\treturn true;\n\t}\n\n\t// object literal { foo() {} } via MethodDeclaration inside object literal is also MethodDeclaration\n\t// property assignment: { foo: () => {} }\n\tif (ts.isPropertyAssignment(node) && nodeNameText(node.name) === name) {\n\t\treturn isArrowOrFnExpr(node.initializer);\n\t}\n\n\treturn false;\n}\n\n/**\n * Check if a node is any variable declaration with the given name\n */\nfunction isVariableNamed(node: ts.Node, name: string): boolean {\n\tif (\n\t\tts.isVariableDeclaration(node) &&\n\t\tts.isIdentifier(node.name) &&\n\t\tnode.name.text === name\n\t) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * Check if a node matches the given name (function-like or variable)\n */\nfunction isNamedNode(node: ts.Node, name: string): boolean {\n\treturn isFunctionLikeNamed(node, name) || isVariableNamed(node, name);\n}\n\n/**\n * Get the 1-based line number for a node\n */\nexport function getLineNumber(\n\tsourceFile: ts.SourceFile,\n\tnode: ts.Node,\n): number {\n\tconst { line } = sourceFile.getLineAndCharacterOfPosition(\n\t\tnode.getStart(sourceFile),\n\t);\n\treturn line + 1;\n}\n\n/**\n * Find the first function-like node with the given name in a source file\n */\nexport function findFirstMatch(\n\tsourceFile: ts.SourceFile,\n\tname: string,\n): ts.Node | undefined {\n\tlet found: ts.Node | undefined;\n\n\tconst visit = (node: ts.Node) => {\n\t\tif (found) return;\n\t\tif (isFunctionLikeNamed(node, name)) {\n\t\t\tfound = node;\n\t\t\treturn;\n\t\t}\n\t\tts.forEachChild(node, visit);\n\t};\n\n\tvisit(sourceFile);\n\treturn found;\n}\n\n/**\n * Find a node by name and optionally by line number\n */\nexport function findNodeByNameAndLine(\n\tsourceFile: ts.SourceFile,\n\tname: string,\n\tline?: number,\n): ts.Node | undefined {\n\tlet found: ts.Node | undefined;\n\n\tconst visit = (node: ts.Node) => {\n\t\tif (found) return;\n\t\tif (isNamedNode(node, name)) {\n\t\t\tif (line !== undefined) {\n\t\t\t\tconst nodeLine = getLineNumber(sourceFile, node);\n\t\t\t\tif (nodeLine === line) {\n\t\t\t\t\tfound = node;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfound = node;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tts.forEachChild(node, visit);\n\t};\n\n\tvisit(sourceFile);\n\treturn found;\n}\n\n/**\n * Get type information for a node\n */\nexport function getTypeInfo(\n\tprogram: ts.Program,\n\tnode: ts.Node,\n\tsourceFile?: ts.SourceFile,\n): InferredTypeResult {\n\tconst checker = program.getTypeChecker();\n\tconst sf = sourceFile ?? node.getSourceFile();\n\tconst line = getLineNumber(sf, node);\n\n\tlet sig: ts.Signature | undefined;\n\n\t// Prefer getting the signature from a declaration/expression directly\n\tif (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {\n\t\tsig = checker.getSignatureFromDeclaration(node) ?? undefined;\n\t} else if (ts.isVariableDeclaration(node)) {\n\t\tconst init = node.initializer;\n\t\tif (isArrowOrFnExpr(init))\n\t\t\tsig = checker.getSignatureFromDeclaration(init) ?? undefined;\n\t} else if (ts.isPropertyAssignment(node)) {\n\t\tconst init = node.initializer;\n\t\tif (isArrowOrFnExpr(init))\n\t\t\tsig = checker.getSignatureFromDeclaration(init) ?? undefined;\n\t} else if (ts.isMethodSignature(node)) {\n\t\t// interfaces/types\n\t\tsig = checker.getSignatureFromDeclaration(node) ?? undefined;\n\t}\n\n\tconst flags = ts.TypeFormatFlags.NoTruncation;\n\n\tif (sig) {\n\t\tconst signature = checker.signatureToString(sig, undefined, flags);\n\t\tconst ret = checker.getReturnTypeOfSignature(sig);\n\t\tconst returnType = checker.typeToString(ret, undefined, flags);\n\t\treturn { signature, returnType, line };\n\t}\n\n\t// Fallback: type at the name location\n\tconst nodeWithName = node as unknown as { name?: ts.Node };\n\tlet nameNode: ts.Node = node;\n\tif (nodeWithName.name && ts.isIdentifier(nodeWithName.name)) {\n\t\tnameNode = nodeWithName.name;\n\t}\n\n\tconst t = checker.getTypeAtLocation(nameNode);\n\treturn { signature: checker.typeToString(t, undefined, flags), line };\n}\n"],"mappings":"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","names":["import_node_path","ts","path","ts","path","fs"]}
|
|
1
|
+
{"version":3,"sources":["../src/mcp.ts","../src/index.ts","../src/core.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { hover } from \"./index.js\";\n\nconst HELP = `\nprinfer-mcp - MCP server for TypeScript type inference\n\nThis is an MCP (Model Context Protocol) server. It's designed to be run\nby Claude Code, not directly from the command line.\n\nSetup:\n Run 'prinfer setup' to configure Claude Code automatically.\n\nManual setup:\n Run: claude mcp add prinfer node /path/to/prinfer-mcp\n\nProvided tools:\n hover(file, line, column, include_docs?, project?)\n Get TypeScript type information at a specific position.\n\nSee also:\n prinfer --help CLI for direct type inspection\n`.trim();\n\nif (process.argv.includes(\"--help\") || process.argv.includes(\"-h\")) {\n\tconsole.log(HELP);\n\tprocess.exit(0);\n}\n\nconst server = new McpServer({\n\tname: \"prinfer\",\n\tversion: \"0.3.0\",\n});\n\nserver.tool(\n\t\"hover\",\n\t\"Get TypeScript type information at a specific position in a file. Returns the type signature, return type, documentation, and symbol kind.\",\n\t{\n\t\tfile: z.string().describe(\"Path to the TypeScript file\"),\n\t\tline: z.number().describe(\"1-based line number\"),\n\t\tcolumn: z.number().describe(\"1-based column (character position)\"),\n\t\tinclude_docs: z\n\t\t\t.boolean()\n\t\t\t.optional()\n\t\t\t.describe(\"Include JSDoc/TSDoc documentation\"),\n\t\tproject: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\"Optional path to tsconfig.json\"),\n\t},\n\tasync ({ file, line, column, include_docs, project }) => {\n\t\ttry {\n\t\t\tconst result = hover(file, line, column, { include_docs, project });\n\t\t\tlet text = `Type: ${result.signature}`;\n\t\t\tif (result.returnType) {\n\t\t\t\ttext += `\\nReturns: ${result.returnType}`;\n\t\t\t}\n\t\t\tif (result.name) {\n\t\t\t\ttext += `\\nName: ${result.name}`;\n\t\t\t}\n\t\t\ttext += `\\nKind: ${result.kind}`;\n\t\t\ttext += `\\nPosition: ${result.line}:${result.column}`;\n\t\t\tif (result.documentation) {\n\t\t\t\ttext += `\\nDocumentation: ${result.documentation}`;\n\t\t\t}\n\t\t\treturn { content: [{ type: \"text\", text }] };\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: `Error: ${(error as Error).message}`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tisError: true,\n\t\t\t};\n\t\t}\n\t},\n);\n\nasync function main() {\n\tconst transport = new StdioServerTransport();\n\tawait server.connect(transport);\n}\n\nmain().catch(console.error);\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport {\n\tfindNodeAtPosition,\n\tfindNodeByNameAndLine,\n\tgetHoverInfo,\n\tgetTypeInfo,\n\tloadProgram,\n} from \"./core.js\";\nimport type {\n\tHoverOptions,\n\tHoverResult,\n\tInferredTypeResult,\n\tOptions,\n} from \"./types.js\";\n\n// Re-export types\nexport type { HoverOptions, HoverResult, InferredTypeResult, Options };\n\n// Re-export core utilities\nexport {\n\tfindFirstMatch,\n\tfindNearestTsconfig,\n\tfindNodeAtPosition,\n\tfindNodeByNameAndLine,\n\tgetDocumentation,\n\tgetHoverInfo,\n\tgetLineNumber,\n\tgetTypeInfo,\n\tloadProgram,\n} from \"./core.js\";\n\n/**\n * Infer the type of a function or variable in a TypeScript file\n *\n * @param file - Path to the TypeScript file\n * @param name - Name of the function/variable to inspect\n * @param options - Optional: project path (string) or options object with line and project\n * @returns The inferred type information\n * @throws Error if file not found or symbol not found\n *\n * @example\n * ```ts\n * import { inferType } from \"prinfer\";\n *\n * // By name only\n * const result = inferType(\"./src/utils.ts\", \"myFunction\");\n * console.log(result.signature);\n * // => \"(x: number, y: string) => boolean\"\n *\n * // By name and line number\n * const result2 = inferType(\"./src/utils.ts\", \"commandResult\", { line: 75 });\n * console.log(result2.signature);\n * // => \"Result<VaultAction[], CommandError>\"\n * ```\n */\nexport function inferType(\n\tfile: string,\n\tname: string,\n\toptions?: string | { line?: number; project?: string },\n): InferredTypeResult {\n\t// Normalize options for backward compatibility\n\tconst opts =\n\t\ttypeof options === \"string\" ? { project: options } : (options ?? {});\n\tconst { line, project } = opts;\n\n\tconst entryFileAbs = path.resolve(process.cwd(), file);\n\n\tif (!fs.existsSync(entryFileAbs)) {\n\t\tthrow new Error(`File not found: ${entryFileAbs}`);\n\t}\n\n\tconst program = loadProgram(entryFileAbs, project);\n\tconst sourceFile = program.getSourceFile(entryFileAbs);\n\n\tif (!sourceFile) {\n\t\tthrow new Error(\n\t\t\t`Could not load source file into the program (check tsconfig include/exclude): ${entryFileAbs}`,\n\t\t);\n\t}\n\n\tconst node = findNodeByNameAndLine(sourceFile, name, line);\n\tif (!node) {\n\t\tconst lineInfo = line !== undefined ? ` at line ${line}` : \"\";\n\t\tthrow new Error(\n\t\t\t`No symbol named \"${name}\"${lineInfo} found in ${entryFileAbs}`,\n\t\t);\n\t}\n\n\treturn getTypeInfo(program, node, sourceFile);\n}\n\n/**\n * Infer the type using an options object\n *\n * @param options - Options for type inference\n * @returns The inferred type information\n */\nexport function inferTypeFromOptions(options: Options): InferredTypeResult {\n\treturn inferType(options.file, options.name, {\n\t\tline: options.line,\n\t\tproject: options.project,\n\t});\n}\n\n/**\n * Get type information at a specific position in a TypeScript file\n *\n * @param file - Path to the TypeScript file\n * @param line - 1-based line number\n * @param column - 1-based column number\n * @param options - Optional hover options (project path, include_docs)\n * @returns The hover information at the position\n * @throws Error if file not found or no symbol at position\n *\n * @example\n * ```ts\n * import { hover } from \"prinfer\";\n *\n * const result = hover(\"./src/utils.ts\", 75, 10);\n * console.log(result.signature);\n * // => \"(x: number) => string\"\n *\n * // With documentation\n * const result2 = hover(\"./src/utils.ts\", 75, 10, { include_docs: true });\n * console.log(result2.documentation);\n * // => \"Formats a number as a string\"\n * ```\n */\nexport function hover(\n\tfile: string,\n\tline: number,\n\tcolumn: number,\n\toptions?: HoverOptions,\n): HoverResult {\n\tconst { project, include_docs = false } = options ?? {};\n\n\tconst entryFileAbs = path.resolve(process.cwd(), file);\n\n\tif (!fs.existsSync(entryFileAbs)) {\n\t\tthrow new Error(`File not found: ${entryFileAbs}`);\n\t}\n\n\tconst program = loadProgram(entryFileAbs, project);\n\tconst sourceFile = program.getSourceFile(entryFileAbs);\n\n\tif (!sourceFile) {\n\t\tthrow new Error(\n\t\t\t`Could not load source file into the program (check tsconfig include/exclude): ${entryFileAbs}`,\n\t\t);\n\t}\n\n\tconst node = findNodeAtPosition(sourceFile, line, column);\n\tif (!node) {\n\t\tthrow new Error(`No symbol found at ${entryFileAbs}:${line}:${column}`);\n\t}\n\n\treturn getHoverInfo(program, node, sourceFile, include_docs);\n}\n","import path from \"node:path\";\nimport ts from \"typescript\";\nimport type { HoverResult, InferredTypeResult } from \"./types.js\";\n\n/**\n * Find the nearest tsconfig.json from a starting directory\n */\nexport function findNearestTsconfig(startDir: string): string | undefined {\n\treturn (\n\t\tts.findConfigFile(startDir, ts.sys.fileExists, \"tsconfig.json\") ??\n\t\tundefined\n\t);\n}\n\n/**\n * Load a TypeScript program from an entry file\n */\nexport function loadProgram(\n\tentryFileAbs: string,\n\tproject?: string,\n): ts.Program {\n\tconst fileDir = path.dirname(entryFileAbs);\n\tconst tsconfigPath = project\n\t\t? path.resolve(process.cwd(), project)\n\t\t: findNearestTsconfig(fileDir);\n\n\tif (!tsconfigPath) {\n\t\t// Fallback: single-file program\n\t\treturn ts.createProgram([entryFileAbs], {\n\t\t\ttarget: ts.ScriptTarget.ES2022,\n\t\t\tmodule: ts.ModuleKind.ESNext,\n\t\t\tstrict: true,\n\t\t\tallowJs: true,\n\t\t\tcheckJs: false,\n\t\t\tmoduleResolution: ts.ModuleResolutionKind.Bundler,\n\t\t\tskipLibCheck: true,\n\t\t});\n\t}\n\n\tconst cfg = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n\tif (cfg.error) {\n\t\tthrow new Error(\n\t\t\tts.flattenDiagnosticMessageText(cfg.error.messageText, \"\\n\"),\n\t\t);\n\t}\n\n\tconst parsed = ts.parseJsonConfigFileContent(\n\t\tcfg.config,\n\t\tts.sys,\n\t\tpath.dirname(tsconfigPath),\n\t);\n\treturn ts.createProgram({\n\t\trootNames: parsed.fileNames,\n\t\toptions: parsed.options,\n\t});\n}\n\nfunction isArrowOrFnExpr(\n\tn: ts.Node | undefined,\n): n is ts.ArrowFunction | ts.FunctionExpression {\n\treturn !!n && (ts.isArrowFunction(n) || ts.isFunctionExpression(n));\n}\n\nfunction nodeNameText(\n\tn: ts.PropertyName | ts.BindingName | undefined,\n): string | undefined {\n\tif (!n) return undefined;\n\tif (ts.isIdentifier(n)) return n.text;\n\tif (ts.isStringLiteral(n)) return n.text;\n\tif (ts.isNumericLiteral(n)) return n.text;\n\treturn undefined; // ignore computed names etc.\n}\n\nfunction isFunctionLikeNamed(node: ts.Node, name: string): boolean {\n\t// function foo() {}\n\tif (ts.isFunctionDeclaration(node) && node.name?.text === name) return true;\n\n\t// const foo = () => {} / function() {}\n\tif (\n\t\tts.isVariableDeclaration(node) &&\n\t\tts.isIdentifier(node.name) &&\n\t\tnode.name.text === name\n\t) {\n\t\treturn isArrowOrFnExpr(node.initializer);\n\t}\n\n\t// class C { foo() {} } / interface signatures\n\tif (\n\t\t(ts.isMethodDeclaration(node) || ts.isMethodSignature(node)) &&\n\t\tnodeNameText(node.name) === name\n\t) {\n\t\treturn true;\n\t}\n\n\t// object literal { foo() {} } via MethodDeclaration inside object literal is also MethodDeclaration\n\t// property assignment: { foo: () => {} }\n\tif (ts.isPropertyAssignment(node) && nodeNameText(node.name) === name) {\n\t\treturn isArrowOrFnExpr(node.initializer);\n\t}\n\n\treturn false;\n}\n\n/**\n * Check if a node is any variable declaration with the given name\n */\nfunction isVariableNamed(node: ts.Node, name: string): boolean {\n\tif (\n\t\tts.isVariableDeclaration(node) &&\n\t\tts.isIdentifier(node.name) &&\n\t\tnode.name.text === name\n\t) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * Check if a node matches the given name (function-like or variable)\n */\nfunction isNamedNode(node: ts.Node, name: string): boolean {\n\treturn isFunctionLikeNamed(node, name) || isVariableNamed(node, name);\n}\n\n/**\n * Check if a node is a call expression with the given name\n */\nfunction isCallExpressionNamed(node: ts.Node, name: string): boolean {\n\tif (!ts.isCallExpression(node)) return false;\n\tconst expr = node.expression;\n\n\t// Direct call: foo()\n\tif (ts.isIdentifier(expr) && expr.text === name) return true;\n\n\t// Property access: this.foo() or obj.foo()\n\tif (ts.isPropertyAccessExpression(expr) && expr.name.text === name)\n\t\treturn true;\n\n\treturn false;\n}\n\n/**\n * Get the 1-based line number for a node\n */\nexport function getLineNumber(\n\tsourceFile: ts.SourceFile,\n\tnode: ts.Node,\n): number {\n\tconst { line } = sourceFile.getLineAndCharacterOfPosition(\n\t\tnode.getStart(sourceFile),\n\t);\n\treturn line + 1;\n}\n\n/**\n * Find the first function-like node with the given name in a source file\n */\nexport function findFirstMatch(\n\tsourceFile: ts.SourceFile,\n\tname: string,\n): ts.Node | undefined {\n\tlet found: ts.Node | undefined;\n\n\tconst visit = (node: ts.Node) => {\n\t\tif (found) return;\n\t\tif (isFunctionLikeNamed(node, name)) {\n\t\t\tfound = node;\n\t\t\treturn;\n\t\t}\n\t\tts.forEachChild(node, visit);\n\t};\n\n\tvisit(sourceFile);\n\treturn found;\n}\n\n/**\n * Find a node by name and optionally by line number\n */\nexport function findNodeByNameAndLine(\n\tsourceFile: ts.SourceFile,\n\tname: string,\n\tline?: number,\n): ts.Node | undefined {\n\tlet found: ts.Node | undefined;\n\n\tconst matchesLine = (node: ts.Node): boolean => {\n\t\tif (line === undefined) return true;\n\t\treturn getLineNumber(sourceFile, node) === line;\n\t};\n\n\tconst visit = (node: ts.Node) => {\n\t\tif (found) return;\n\n\t\t// Check declarations (existing logic)\n\t\tif (isNamedNode(node, name) && matchesLine(node)) {\n\t\t\tfound = node;\n\t\t\treturn;\n\t\t}\n\n\t\t// Check call expressions (new)\n\t\tif (isCallExpressionNamed(node, name) && matchesLine(node)) {\n\t\t\tfound = node;\n\t\t\treturn;\n\t\t}\n\n\t\tts.forEachChild(node, visit);\n\t};\n\n\tvisit(sourceFile);\n\treturn found;\n}\n\n/**\n * Get type information for a node\n */\nexport function getTypeInfo(\n\tprogram: ts.Program,\n\tnode: ts.Node,\n\tsourceFile?: ts.SourceFile,\n): InferredTypeResult {\n\tconst checker = program.getTypeChecker();\n\tconst sf = sourceFile ?? node.getSourceFile();\n\tconst line = getLineNumber(sf, node);\n\tconst flags = ts.TypeFormatFlags.NoTruncation;\n\n\t// Handle call expressions - get instantiated signature\n\tif (ts.isCallExpression(node)) {\n\t\tconst sig = checker.getResolvedSignature(node);\n\t\tif (sig) {\n\t\t\tconst signature = checker.signatureToString(sig, undefined, flags);\n\t\t\tconst ret = checker.getReturnTypeOfSignature(sig);\n\t\t\tconst returnType = checker.typeToString(ret, undefined, flags);\n\t\t\treturn { signature, returnType, line };\n\t\t}\n\t\t// Fallback: get type of the call result\n\t\tconst t = checker.getTypeAtLocation(node);\n\t\treturn { signature: checker.typeToString(t, undefined, flags), line };\n\t}\n\n\tlet sig: ts.Signature | undefined;\n\n\t// Prefer getting the signature from a declaration/expression directly\n\tif (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {\n\t\tsig = checker.getSignatureFromDeclaration(node) ?? undefined;\n\t} else if (ts.isVariableDeclaration(node)) {\n\t\tconst init = node.initializer;\n\t\tif (isArrowOrFnExpr(init))\n\t\t\tsig = checker.getSignatureFromDeclaration(init) ?? undefined;\n\t} else if (ts.isPropertyAssignment(node)) {\n\t\tconst init = node.initializer;\n\t\tif (isArrowOrFnExpr(init))\n\t\t\tsig = checker.getSignatureFromDeclaration(init) ?? undefined;\n\t} else if (ts.isMethodSignature(node)) {\n\t\t// interfaces/types\n\t\tsig = checker.getSignatureFromDeclaration(node) ?? undefined;\n\t}\n\n\tif (sig) {\n\t\tconst signature = checker.signatureToString(sig, undefined, flags);\n\t\tconst ret = checker.getReturnTypeOfSignature(sig);\n\t\tconst returnType = checker.typeToString(ret, undefined, flags);\n\t\treturn { signature, returnType, line };\n\t}\n\n\t// Fallback: type at the name location\n\tconst nodeWithName = node as unknown as { name?: ts.Node };\n\tlet nameNode: ts.Node = node;\n\tif (nodeWithName.name && ts.isIdentifier(nodeWithName.name)) {\n\t\tnameNode = nodeWithName.name;\n\t}\n\n\tconst t = checker.getTypeAtLocation(nameNode);\n\treturn { signature: checker.typeToString(t, undefined, flags), line };\n}\n\n/**\n * Find the most specific node containing a position by walking the AST\n */\nfunction findSmallestNodeAtPosition(\n\tsourceFile: ts.SourceFile,\n\tposition: number,\n): ts.Node | undefined {\n\tlet result: ts.Node | undefined;\n\n\tfunction visit(node: ts.Node): void {\n\t\tconst start = node.getStart(sourceFile);\n\t\tconst end = node.getEnd();\n\n\t\t// Position must be within this node's range\n\t\tif (position < start || position >= end) {\n\t\t\treturn;\n\t\t}\n\n\t\t// This node contains the position - check if it's more specific than current result\n\t\tif (\n\t\t\t!result ||\n\t\t\tnode.getWidth(sourceFile) <= result.getWidth(sourceFile)\n\t\t) {\n\t\t\tresult = node;\n\t\t}\n\n\t\t// Continue to check children for more specific nodes\n\t\tts.forEachChild(node, visit);\n\t}\n\n\tvisit(sourceFile);\n\treturn result;\n}\n\n/**\n * Walk up from a token to find the most useful node for hover info\n */\nfunction findHoverableAncestor(\n\tsourceFile: ts.SourceFile,\n\tposition: number,\n): ts.Node | undefined {\n\tconst smallestNode = findSmallestNodeAtPosition(sourceFile, position);\n\tif (!smallestNode) return undefined;\n\n\t// Walk up the tree to find the most useful hoverable node\n\tlet bestMatch: ts.Node | undefined = smallestNode;\n\n\t// Visit ancestors\n\tfunction visit(n: ts.Node): boolean {\n\t\tconst start = n.getStart(sourceFile);\n\t\tconst end = n.getEnd();\n\n\t\tif (position < start || position >= end) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if this is a call expression with our node as the callee\n\t\tif (ts.isCallExpression(n)) {\n\t\t\tconst expr = n.expression;\n\t\t\t// Check if position is on the function name part\n\t\t\tif (ts.isIdentifier(expr)) {\n\t\t\t\tif (\n\t\t\t\t\tposition >= expr.getStart(sourceFile) &&\n\t\t\t\t\tposition < expr.getEnd()\n\t\t\t\t) {\n\t\t\t\t\tbestMatch = n;\n\t\t\t\t}\n\t\t\t} else if (ts.isPropertyAccessExpression(expr)) {\n\t\t\t\tif (\n\t\t\t\t\tposition >= expr.name.getStart(sourceFile) &&\n\t\t\t\t\tposition < expr.name.getEnd()\n\t\t\t\t) {\n\t\t\t\t\tbestMatch = n;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If this is a declaration and the position is on its name, use this declaration\n\t\tif (ts.isFunctionDeclaration(n) && n.name) {\n\t\t\tif (\n\t\t\t\tposition >= n.name.getStart(sourceFile) &&\n\t\t\t\tposition < n.name.getEnd()\n\t\t\t) {\n\t\t\t\tbestMatch = n;\n\t\t\t}\n\t\t}\n\t\tif (ts.isVariableDeclaration(n) && ts.isIdentifier(n.name)) {\n\t\t\tif (\n\t\t\t\tposition >= n.name.getStart(sourceFile) &&\n\t\t\t\tposition < n.name.getEnd()\n\t\t\t) {\n\t\t\t\tbestMatch = n;\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\t(ts.isMethodDeclaration(n) || ts.isMethodSignature(n)) &&\n\t\t\tts.isIdentifier(n.name)\n\t\t) {\n\t\t\tif (\n\t\t\t\tposition >= n.name.getStart(sourceFile) &&\n\t\t\t\tposition < n.name.getEnd()\n\t\t\t) {\n\t\t\t\tbestMatch = n;\n\t\t\t}\n\t\t}\n\t\tif (ts.isClassDeclaration(n) && n.name) {\n\t\t\tif (\n\t\t\t\tposition >= n.name.getStart(sourceFile) &&\n\t\t\t\tposition < n.name.getEnd()\n\t\t\t) {\n\t\t\t\tbestMatch = n;\n\t\t\t}\n\t\t}\n\t\tif (ts.isInterfaceDeclaration(n) && n.name) {\n\t\t\tif (\n\t\t\t\tposition >= n.name.getStart(sourceFile) &&\n\t\t\t\tposition < n.name.getEnd()\n\t\t\t) {\n\t\t\t\tbestMatch = n;\n\t\t\t}\n\t\t}\n\n\t\tts.forEachChild(n, visit);\n\t\treturn true;\n\t}\n\n\tvisit(sourceFile);\n\treturn bestMatch;\n}\n\n/**\n * Find the node at a specific position (1-based line and column)\n */\nexport function findNodeAtPosition(\n\tsourceFile: ts.SourceFile,\n\tline: number,\n\tcolumn: number,\n): ts.Node | undefined {\n\t// Validate line/column bounds\n\tconst lineCount = sourceFile.getLineStarts().length;\n\tif (line < 1 || line > lineCount) {\n\t\treturn undefined;\n\t}\n\n\tconst lineStart = sourceFile.getLineStarts()[line - 1];\n\tconst lineEnd =\n\t\tline < lineCount\n\t\t\t? sourceFile.getLineStarts()[line]\n\t\t\t: sourceFile.getEnd();\n\tconst lineLength = lineEnd - lineStart;\n\n\tif (column < 1 || column > lineLength + 1) {\n\t\treturn undefined;\n\t}\n\n\t// Convert 1-based line/column to 0-based position\n\tconst position = sourceFile.getPositionOfLineAndCharacter(\n\t\tline - 1,\n\t\tcolumn - 1,\n\t);\n\n\treturn findHoverableAncestor(sourceFile, position);\n}\n\n/**\n * Get the symbol kind as a string\n */\nfunction getSymbolKind(node: ts.Node): string {\n\tif (ts.isFunctionDeclaration(node)) return \"function\";\n\tif (ts.isArrowFunction(node)) return \"function\";\n\tif (ts.isFunctionExpression(node)) return \"function\";\n\tif (ts.isMethodDeclaration(node)) return \"method\";\n\tif (ts.isMethodSignature(node)) return \"method\";\n\tif (ts.isVariableDeclaration(node)) {\n\t\tconst init = node.initializer;\n\t\tif (\n\t\t\tinit &&\n\t\t\t(ts.isArrowFunction(init) || ts.isFunctionExpression(init))\n\t\t) {\n\t\t\treturn \"function\";\n\t\t}\n\t\treturn \"variable\";\n\t}\n\tif (ts.isParameter(node)) return \"parameter\";\n\tif (ts.isPropertyDeclaration(node)) return \"property\";\n\tif (ts.isPropertySignature(node)) return \"property\";\n\tif (ts.isPropertyAccessExpression(node)) return \"property\";\n\tif (ts.isCallExpression(node)) return \"call\";\n\tif (ts.isTypeAliasDeclaration(node)) return \"type\";\n\tif (ts.isInterfaceDeclaration(node)) return \"interface\";\n\tif (ts.isClassDeclaration(node)) return \"class\";\n\tif (ts.isIdentifier(node)) return \"identifier\";\n\treturn \"unknown\";\n}\n\n/**\n * Get the name of a node if it has one\n */\nfunction getNodeName(node: ts.Node): string | undefined {\n\tif (ts.isFunctionDeclaration(node) && node.name) {\n\t\treturn node.name.text;\n\t}\n\tif (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)) {\n\t\treturn node.name.text;\n\t}\n\tif (\n\t\t(ts.isMethodDeclaration(node) || ts.isMethodSignature(node)) &&\n\t\tts.isIdentifier(node.name)\n\t) {\n\t\treturn node.name.text;\n\t}\n\tif (ts.isPropertyAccessExpression(node)) {\n\t\treturn node.name.text;\n\t}\n\tif (ts.isCallExpression(node)) {\n\t\tconst expr = node.expression;\n\t\tif (ts.isIdentifier(expr)) return expr.text;\n\t\tif (ts.isPropertyAccessExpression(expr)) return expr.name.text;\n\t}\n\tif (ts.isParameter(node) && ts.isIdentifier(node.name)) {\n\t\treturn node.name.text;\n\t}\n\tif (ts.isIdentifier(node)) {\n\t\treturn node.text;\n\t}\n\tif (\n\t\tts.isTypeAliasDeclaration(node) ||\n\t\tts.isInterfaceDeclaration(node) ||\n\t\tts.isClassDeclaration(node)\n\t) {\n\t\treturn node.name?.text;\n\t}\n\treturn undefined;\n}\n\n/**\n * Get documentation from a symbol\n */\nexport function getDocumentation(\n\tchecker: ts.TypeChecker,\n\tsymbol: ts.Symbol | undefined,\n): string | undefined {\n\tif (!symbol) return undefined;\n\n\tconst docs = symbol.getDocumentationComment(checker);\n\tif (docs.length === 0) return undefined;\n\n\treturn ts.displayPartsToString(docs);\n}\n\n/**\n * Get hover information at a specific position\n */\nexport function getHoverInfo(\n\tprogram: ts.Program,\n\tnode: ts.Node,\n\tsourceFile: ts.SourceFile,\n\tincludeDocs: boolean,\n): HoverResult {\n\tconst checker = program.getTypeChecker();\n\tconst sf = sourceFile;\n\tconst { line, character } = sf.getLineAndCharacterOfPosition(\n\t\tnode.getStart(sf),\n\t);\n\tconst flags = ts.TypeFormatFlags.NoTruncation;\n\n\tconst kind = getSymbolKind(node);\n\tconst name = getNodeName(node);\n\n\t// Get symbol for documentation\n\tlet symbol: ts.Symbol | undefined;\n\tif (ts.isCallExpression(node)) {\n\t\t// For calls, get symbol from the expression\n\t\tconst expr = node.expression;\n\t\tif (ts.isPropertyAccessExpression(expr)) {\n\t\t\tsymbol = checker.getSymbolAtLocation(expr.name);\n\t\t} else {\n\t\t\tsymbol = checker.getSymbolAtLocation(expr);\n\t\t}\n\t} else {\n\t\tconst nodeWithName = node as unknown as { name?: ts.Node };\n\t\tif (nodeWithName.name) {\n\t\t\tsymbol = checker.getSymbolAtLocation(nodeWithName.name);\n\t\t} else {\n\t\t\tsymbol = checker.getSymbolAtLocation(node);\n\t\t}\n\t}\n\n\tconst documentation = includeDocs\n\t\t? getDocumentation(checker, symbol)\n\t\t: undefined;\n\n\t// Handle call expressions - get instantiated signature\n\tif (ts.isCallExpression(node)) {\n\t\tconst sig = checker.getResolvedSignature(node);\n\t\tif (sig) {\n\t\t\tconst signature = checker.signatureToString(sig, undefined, flags);\n\t\t\tconst ret = checker.getReturnTypeOfSignature(sig);\n\t\t\tconst returnType = checker.typeToString(ret, undefined, flags);\n\t\t\treturn {\n\t\t\t\tsignature,\n\t\t\t\treturnType,\n\t\t\t\tline: line + 1,\n\t\t\t\tcolumn: character + 1,\n\t\t\t\tdocumentation,\n\t\t\t\tkind,\n\t\t\t\tname,\n\t\t\t};\n\t\t}\n\t\t// Fallback: get type of the call result\n\t\tconst t = checker.getTypeAtLocation(node);\n\t\treturn {\n\t\t\tsignature: checker.typeToString(t, undefined, flags),\n\t\t\tline: line + 1,\n\t\t\tcolumn: character + 1,\n\t\t\tdocumentation,\n\t\t\tkind,\n\t\t\tname,\n\t\t};\n\t}\n\n\tlet sig: ts.Signature | undefined;\n\n\t// Prefer getting the signature from a declaration/expression directly\n\tif (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {\n\t\tsig = checker.getSignatureFromDeclaration(node) ?? undefined;\n\t} else if (ts.isVariableDeclaration(node)) {\n\t\tconst init = node.initializer;\n\t\tif (isArrowOrFnExpr(init))\n\t\t\tsig = checker.getSignatureFromDeclaration(init) ?? undefined;\n\t} else if (ts.isPropertyAssignment(node)) {\n\t\tconst init = node.initializer;\n\t\tif (isArrowOrFnExpr(init))\n\t\t\tsig = checker.getSignatureFromDeclaration(init) ?? undefined;\n\t} else if (ts.isMethodSignature(node)) {\n\t\tsig = checker.getSignatureFromDeclaration(node) ?? undefined;\n\t}\n\n\tif (sig) {\n\t\tconst signature = checker.signatureToString(sig, undefined, flags);\n\t\tconst ret = checker.getReturnTypeOfSignature(sig);\n\t\tconst returnType = checker.typeToString(ret, undefined, flags);\n\t\treturn {\n\t\t\tsignature,\n\t\t\treturnType,\n\t\t\tline: line + 1,\n\t\t\tcolumn: character + 1,\n\t\t\tdocumentation,\n\t\t\tkind,\n\t\t\tname,\n\t\t};\n\t}\n\n\t// Fallback: type at the node location\n\tconst nodeWithName = node as unknown as { name?: ts.Node };\n\tlet targetNode: ts.Node = node;\n\tif (nodeWithName.name && ts.isIdentifier(nodeWithName.name)) {\n\t\ttargetNode = nodeWithName.name;\n\t}\n\n\tconst t = checker.getTypeAtLocation(targetNode);\n\treturn {\n\t\tsignature: checker.typeToString(t, undefined, flags),\n\t\tline: line + 1,\n\t\tcolumn: character + 1,\n\t\tdocumentation,\n\t\tkind,\n\t\tname,\n\t};\n}\n"],"mappings":"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","names":["import_node_path","ts","path","ts","nodeWithName","sig","t","path","fs"]}
|