prinfer 0.3.0 → 0.4.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/README.md CHANGED
@@ -1,77 +1,87 @@
1
1
  # prinfer
2
2
 
3
- TypeScript type inference inspection tool. Inspect the inferred types of functions and variables in your TypeScript code.
3
+ **Typehints for your AI agent.**
4
4
 
5
- ## Installation
5
+ prinfer gives AI coding assistants the ability to inspect TypeScript's inferred types — so they can write cleaner code without redundant type annotations.
6
6
 
7
- ```bash
8
- npm install prinfer
9
- ```
7
+ ## Why?
10
8
 
11
- ## CLI Usage
9
+ AI agents write TypeScript, but they can't see what the compiler infers. This leads to:
10
+ - Unnecessary explicit type annotations everywhere
11
+ - Verbose code that fights against TypeScript's design
12
+ - Missed opportunities to leverage type inference
12
13
 
13
- ```bash
14
- # Basic usage
15
- prinfer src/utils.ts myFunction
14
+ prinfer solves this by exposing TypeScript's type inference to your agent via MCP.
16
15
 
17
- # With custom tsconfig
18
- prinfer src/utils.ts myFunction --project ./tsconfig.json
16
+ ## Quick Start
19
17
 
20
- # Show help
21
- prinfer --help
18
+ ```bash
19
+ npm i -g prinfer
22
20
  ```
23
21
 
24
- ### Output
22
+ That's it. On install, prinfer automatically:
23
+ 1. Adds itself as an MCP tool for Claude
24
+ 2. Installs a skill that teaches Claude to prefer type inference
25
+
26
+ ## What Gets Installed
27
+
28
+ ### MCP Server (`prinfer-mcp`)
29
+
30
+ Your agent gets an `infer_type` tool to check what TypeScript infers:
25
31
 
26
32
  ```
27
- (x: number, y: string) => boolean
28
- returns: boolean
33
+ infer_type(file: "src/utils.ts", name: "myFunction")
34
+ infer_type(file: "src/utils.ts", name: "commandResult", line: 75)
29
35
  ```
30
36
 
31
- ## Programmatic API
37
+ ### Claude Skill (`~/.claude/skills/prinfer.md`)
32
38
 
33
- ```typescript
34
- import { inferType } from "prinfer";
39
+ A coding guideline that encourages your agent to:
40
+ - Rely on type inference instead of explicit annotations
41
+ - Use prinfer to verify types before adding redundant hints
42
+ - Write idiomatic TypeScript
35
43
 
36
- // Basic usage
37
- const result = inferType("./src/utils.ts", "myFunction");
38
- console.log(result.signature);
39
- // => "(x: number, y: string) => boolean"
40
- console.log(result.returnType);
41
- // => "boolean"
44
+ Plus a `/check-type` command for quick lookups.
42
45
 
43
- // With custom tsconfig
44
- const result2 = inferType("./src/utils.ts", "myFunction", "./tsconfig.json");
45
- ```
46
+ ## MCP Setup
46
47
 
47
- ### API Reference
48
+ If the auto-setup didn't work, add to `~/.claude/claude_desktop_config.json`:
48
49
 
49
- #### `inferType(file, name, project?)`
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "prinfer": {
54
+ "command": "prinfer-mcp"
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ ## CLI Usage
50
61
 
51
- Infer the type of a function or variable in a TypeScript file.
62
+ prinfer also works as a standalone CLI:
52
63
 
53
- **Parameters:**
54
- - `file` - Path to the TypeScript file
55
- - `name` - Name of the function/variable to inspect
56
- - `project` - Optional path to tsconfig.json
64
+ ```bash
65
+ prinfer src/utils.ts myFunction
66
+ prinfer src/utils.ts:75 commandResult
67
+ ```
57
68
 
58
- **Returns:** `InferredTypeResult`
59
- - `signature` - The inferred type signature
60
- - `returnType` - The return type (for functions)
69
+ Output:
70
+ ```
71
+ (x: number, y: string) => boolean
72
+ returns: boolean
73
+ ```
61
74
 
62
- #### Types
75
+ ## Programmatic API
63
76
 
64
77
  ```typescript
65
- interface Options {
66
- file: string;
67
- name: string;
68
- project?: string;
69
- }
78
+ import { inferType } from "prinfer";
70
79
 
71
- interface InferredTypeResult {
72
- signature: string;
73
- returnType?: string;
74
- }
80
+ const result = inferType("./src/utils.ts", "myFunction");
81
+ // => { signature: "(x: number, y: string) => boolean", returnType: "boolean", line: 4 }
82
+
83
+ // With line number for disambiguation
84
+ const result2 = inferType("./src/utils.ts", "commandResult", { line: 75 });
75
85
  ```
76
86
 
77
87
  ## Requirements
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/postinstall.ts
27
+ var import_node_fs = __toESM(require("fs"), 1);
28
+ var import_node_os = __toESM(require("os"), 1);
29
+ var import_node_path = __toESM(require("path"), 1);
30
+ var SKILL_CONTENT = `# TypeScript Type Inference (prinfer)
31
+
32
+ ## Coding Guideline
33
+
34
+ When writing TypeScript code, prefer relying on type inference over explicit type annotations:
35
+
36
+ - Let TypeScript infer return types for functions when the implementation makes them obvious
37
+ - Let TypeScript infer variable types from their initializers
38
+ - Only add explicit types when:
39
+ - The inferred type is too wide (e.g., \`string\` instead of a literal type)
40
+ - The type serves as documentation for complex structures
41
+ - You're defining a public API contract
42
+
43
+ Use the \`prinfer\` MCP tool (\`infer_type\`) to verify what TypeScript infers before adding explicit types.
44
+
45
+ ## Commands
46
+
47
+ ### /check-type
48
+
49
+ Check the inferred type of a TypeScript symbol.
50
+
51
+ Usage: \`/check-type <file>:<line> <name>\` or \`/check-type <file> <name>\`
52
+
53
+ Examples:
54
+ - \`/check-type src/utils.ts:75 commandResult\`
55
+ - \`/check-type src/utils.ts myFunction\`
56
+
57
+ <command-name>check-type</command-name>
58
+
59
+ Use the \`infer_type\` MCP tool to check the type:
60
+ 1. Parse the arguments to extract file, optional line number, and symbol name
61
+ 2. Call \`infer_type(file, name, line?)\`
62
+ 3. Report the inferred signature and return type
63
+ `;
64
+ function main() {
65
+ const homeDir = import_node_os.default.homedir();
66
+ const skillsDir = import_node_path.default.join(homeDir, ".claude", "skills");
67
+ const skillFile = import_node_path.default.join(skillsDir, "prinfer.md");
68
+ const claudeDir = import_node_path.default.join(homeDir, ".claude");
69
+ if (!import_node_fs.default.existsSync(claudeDir)) {
70
+ console.log(
71
+ "~/.claude directory not found. Skipping skill installation."
72
+ );
73
+ console.log("To manually install, create ~/.claude/skills/prinfer.md");
74
+ return;
75
+ }
76
+ if (!import_node_fs.default.existsSync(skillsDir)) {
77
+ import_node_fs.default.mkdirSync(skillsDir, { recursive: true });
78
+ }
79
+ if (import_node_fs.default.existsSync(skillFile)) {
80
+ console.log(
81
+ "prinfer skill already installed at ~/.claude/skills/prinfer.md"
82
+ );
83
+ return;
84
+ }
85
+ import_node_fs.default.writeFileSync(skillFile, SKILL_CONTENT);
86
+ console.log("Installed prinfer skill to ~/.claude/skills/prinfer.md");
87
+ console.log("You can now use /check-type to verify TypeScript types!");
88
+ }
89
+ main();
90
+ //# sourceMappingURL=postinstall.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/postinstall.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nconst SKILL_CONTENT = `# TypeScript Type Inference (prinfer)\n\n## Coding Guideline\n\nWhen writing TypeScript code, prefer relying on type inference over explicit type annotations:\n\n- Let TypeScript infer return types for functions when the implementation makes them obvious\n- Let TypeScript infer variable types from their initializers\n- Only add explicit types when:\n - The inferred type is too wide (e.g., \\`string\\` instead of a literal type)\n - The type serves as documentation for complex structures\n - You're defining a public API contract\n\nUse the \\`prinfer\\` MCP tool (\\`infer_type\\`) to verify what TypeScript infers before adding explicit types.\n\n## Commands\n\n### /check-type\n\nCheck the inferred type of a TypeScript symbol.\n\nUsage: \\`/check-type <file>:<line> <name>\\` or \\`/check-type <file> <name>\\`\n\nExamples:\n- \\`/check-type src/utils.ts:75 commandResult\\`\n- \\`/check-type src/utils.ts myFunction\\`\n\n<command-name>check-type</command-name>\n\nUse the \\`infer_type\\` MCP tool to check the type:\n1. Parse the arguments to extract file, optional line number, and symbol name\n2. Call \\`infer_type(file, name, line?)\\`\n3. Report the inferred signature and return type\n`;\n\nfunction main() {\n\tconst homeDir = os.homedir();\n\tconst skillsDir = path.join(homeDir, \".claude\", \"skills\");\n\tconst skillFile = path.join(skillsDir, \"prinfer.md\");\n\n\t// Check if ~/.claude exists\n\tconst claudeDir = path.join(homeDir, \".claude\");\n\tif (!fs.existsSync(claudeDir)) {\n\t\tconsole.log(\n\t\t\t\"~/.claude directory not found. Skipping skill installation.\",\n\t\t);\n\t\tconsole.log(\"To manually install, create ~/.claude/skills/prinfer.md\");\n\t\treturn;\n\t}\n\n\t// Create skills directory if it doesn't exist\n\tif (!fs.existsSync(skillsDir)) {\n\t\tfs.mkdirSync(skillsDir, { recursive: true });\n\t}\n\n\t// Check if skill already exists\n\tif (fs.existsSync(skillFile)) {\n\t\tconsole.log(\n\t\t\t\"prinfer skill already installed at ~/.claude/skills/prinfer.md\",\n\t\t);\n\t\treturn;\n\t}\n\n\t// Write the skill file\n\tfs.writeFileSync(skillFile, SKILL_CONTENT);\n\tconsole.log(\"Installed prinfer skill to ~/.claude/skills/prinfer.md\");\n\tconsole.log(\"You can now use /check-type to verify TypeScript types!\");\n}\n\nmain();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,qBAAe;AACf,qBAAe;AACf,uBAAiB;AAEjB,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmCtB,SAAS,OAAO;AACf,QAAM,UAAU,eAAAA,QAAG,QAAQ;AAC3B,QAAM,YAAY,iBAAAC,QAAK,KAAK,SAAS,WAAW,QAAQ;AACxD,QAAM,YAAY,iBAAAA,QAAK,KAAK,WAAW,YAAY;AAGnD,QAAM,YAAY,iBAAAA,QAAK,KAAK,SAAS,SAAS;AAC9C,MAAI,CAAC,eAAAC,QAAG,WAAW,SAAS,GAAG;AAC9B,YAAQ;AAAA,MACP;AAAA,IACD;AACA,YAAQ,IAAI,yDAAyD;AACrE;AAAA,EACD;AAGA,MAAI,CAAC,eAAAA,QAAG,WAAW,SAAS,GAAG;AAC9B,mBAAAA,QAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5C;AAGA,MAAI,eAAAA,QAAG,WAAW,SAAS,GAAG;AAC7B,YAAQ;AAAA,MACP;AAAA,IACD;AACA;AAAA,EACD;AAGA,iBAAAA,QAAG,cAAc,WAAW,aAAa;AACzC,UAAQ,IAAI,wDAAwD;AACpE,UAAQ,IAAI,yDAAyD;AACtE;AAEA,KAAK;","names":["os","path","fs"]}
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/postinstall.ts
4
+ import fs from "fs";
5
+ import os from "os";
6
+ import path from "path";
7
+ var SKILL_CONTENT = `# TypeScript Type Inference (prinfer)
8
+
9
+ ## Coding Guideline
10
+
11
+ When writing TypeScript code, prefer relying on type inference over explicit type annotations:
12
+
13
+ - Let TypeScript infer return types for functions when the implementation makes them obvious
14
+ - Let TypeScript infer variable types from their initializers
15
+ - Only add explicit types when:
16
+ - The inferred type is too wide (e.g., \`string\` instead of a literal type)
17
+ - The type serves as documentation for complex structures
18
+ - You're defining a public API contract
19
+
20
+ Use the \`prinfer\` MCP tool (\`infer_type\`) to verify what TypeScript infers before adding explicit types.
21
+
22
+ ## Commands
23
+
24
+ ### /check-type
25
+
26
+ Check the inferred type of a TypeScript symbol.
27
+
28
+ Usage: \`/check-type <file>:<line> <name>\` or \`/check-type <file> <name>\`
29
+
30
+ Examples:
31
+ - \`/check-type src/utils.ts:75 commandResult\`
32
+ - \`/check-type src/utils.ts myFunction\`
33
+
34
+ <command-name>check-type</command-name>
35
+
36
+ Use the \`infer_type\` MCP tool to check the type:
37
+ 1. Parse the arguments to extract file, optional line number, and symbol name
38
+ 2. Call \`infer_type(file, name, line?)\`
39
+ 3. Report the inferred signature and return type
40
+ `;
41
+ function main() {
42
+ const homeDir = os.homedir();
43
+ const skillsDir = path.join(homeDir, ".claude", "skills");
44
+ const skillFile = path.join(skillsDir, "prinfer.md");
45
+ const claudeDir = path.join(homeDir, ".claude");
46
+ if (!fs.existsSync(claudeDir)) {
47
+ console.log(
48
+ "~/.claude directory not found. Skipping skill installation."
49
+ );
50
+ console.log("To manually install, create ~/.claude/skills/prinfer.md");
51
+ return;
52
+ }
53
+ if (!fs.existsSync(skillsDir)) {
54
+ fs.mkdirSync(skillsDir, { recursive: true });
55
+ }
56
+ if (fs.existsSync(skillFile)) {
57
+ console.log(
58
+ "prinfer skill already installed at ~/.claude/skills/prinfer.md"
59
+ );
60
+ return;
61
+ }
62
+ fs.writeFileSync(skillFile, SKILL_CONTENT);
63
+ console.log("Installed prinfer skill to ~/.claude/skills/prinfer.md");
64
+ console.log("You can now use /check-type to verify TypeScript types!");
65
+ }
66
+ main();
67
+ //# sourceMappingURL=postinstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/postinstall.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nconst SKILL_CONTENT = `# TypeScript Type Inference (prinfer)\n\n## Coding Guideline\n\nWhen writing TypeScript code, prefer relying on type inference over explicit type annotations:\n\n- Let TypeScript infer return types for functions when the implementation makes them obvious\n- Let TypeScript infer variable types from their initializers\n- Only add explicit types when:\n - The inferred type is too wide (e.g., \\`string\\` instead of a literal type)\n - The type serves as documentation for complex structures\n - You're defining a public API contract\n\nUse the \\`prinfer\\` MCP tool (\\`infer_type\\`) to verify what TypeScript infers before adding explicit types.\n\n## Commands\n\n### /check-type\n\nCheck the inferred type of a TypeScript symbol.\n\nUsage: \\`/check-type <file>:<line> <name>\\` or \\`/check-type <file> <name>\\`\n\nExamples:\n- \\`/check-type src/utils.ts:75 commandResult\\`\n- \\`/check-type src/utils.ts myFunction\\`\n\n<command-name>check-type</command-name>\n\nUse the \\`infer_type\\` MCP tool to check the type:\n1. Parse the arguments to extract file, optional line number, and symbol name\n2. Call \\`infer_type(file, name, line?)\\`\n3. Report the inferred signature and return type\n`;\n\nfunction main() {\n\tconst homeDir = os.homedir();\n\tconst skillsDir = path.join(homeDir, \".claude\", \"skills\");\n\tconst skillFile = path.join(skillsDir, \"prinfer.md\");\n\n\t// Check if ~/.claude exists\n\tconst claudeDir = path.join(homeDir, \".claude\");\n\tif (!fs.existsSync(claudeDir)) {\n\t\tconsole.log(\n\t\t\t\"~/.claude directory not found. Skipping skill installation.\",\n\t\t);\n\t\tconsole.log(\"To manually install, create ~/.claude/skills/prinfer.md\");\n\t\treturn;\n\t}\n\n\t// Create skills directory if it doesn't exist\n\tif (!fs.existsSync(skillsDir)) {\n\t\tfs.mkdirSync(skillsDir, { recursive: true });\n\t}\n\n\t// Check if skill already exists\n\tif (fs.existsSync(skillFile)) {\n\t\tconsole.log(\n\t\t\t\"prinfer skill already installed at ~/.claude/skills/prinfer.md\",\n\t\t);\n\t\treturn;\n\t}\n\n\t// Write the skill file\n\tfs.writeFileSync(skillFile, SKILL_CONTENT);\n\tconsole.log(\"Installed prinfer skill to ~/.claude/skills/prinfer.md\");\n\tconsole.log(\"You can now use /check-type to verify TypeScript types!\");\n}\n\nmain();\n"],"mappings":";;;AACA,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmCtB,SAAS,OAAO;AACf,QAAM,UAAU,GAAG,QAAQ;AAC3B,QAAM,YAAY,KAAK,KAAK,SAAS,WAAW,QAAQ;AACxD,QAAM,YAAY,KAAK,KAAK,WAAW,YAAY;AAGnD,QAAM,YAAY,KAAK,KAAK,SAAS,SAAS;AAC9C,MAAI,CAAC,GAAG,WAAW,SAAS,GAAG;AAC9B,YAAQ;AAAA,MACP;AAAA,IACD;AACA,YAAQ,IAAI,yDAAyD;AACrE;AAAA,EACD;AAGA,MAAI,CAAC,GAAG,WAAW,SAAS,GAAG;AAC9B,OAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5C;AAGA,MAAI,GAAG,WAAW,SAAS,GAAG;AAC7B,YAAQ;AAAA,MACP;AAAA,IACD;AACA;AAAA,EACD;AAGA,KAAG,cAAc,WAAW,aAAa;AACzC,UAAQ,IAAI,wDAAwD;AACpE,UAAQ,IAAI,yDAAyD;AACtE;AAEA,KAAK;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prinfer",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "TypeScript type inference inspection tool",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -33,7 +33,8 @@
33
33
  "version": "changeset version",
34
34
  "release": "bun run build && changeset publish",
35
35
  "prepublishOnly": "bun run ci",
36
- "prepare": "simple-git-hooks"
36
+ "prepare": "simple-git-hooks",
37
+ "postinstall": "node ./dist/postinstall.js || true"
37
38
  },
38
39
  "simple-git-hooks": {
39
40
  "pre-commit": "bunx biome check ."