TypeScript重构工具

基于ts-morph的AST操作工具,提供TypeScript/JavaScript代码库的符号重命名、文件/文件夹重命名、引用查找等重构功能,保持项目整体一致性。

  • by SiroSuzume
  • TypeScript
  • 本地部署
  • 16 星标
  • 更新于
在 GitHub 查看 sirosuzume/mcp-ts-morph

使用说明

MCP变形重构工具

ts变形 类型的多个类型参数的着色器的编译器中可能发生的故障。您可以更改符号名称、更改文件/文件夹名称和浏览搜索,同时保持整个项目的完整性。

目次

快速启动

MCP客户端配置文件(mcp.json 等)中追加以下内容。npx 将条目添加到文档注册表。

{
  "mcpServers": {
    "mcp-tsmorph-refactor": {
      "command": "npx",
      "args": ["-y", "@sirosuzume/mcp-tsmorph-refactor"],
      "env": {}
    }
  }
}

自定义日志记录 记录设置 来修改标记元素的显示属性。从本地源启动 开発 来修改标记元素的显示属性。

提供的工具

每个工具 ts-morph 中描述的场景,使用以下步骤创建明细表,以便在概念设计中分析体量的体积。所有工具 tsconfig.json 需要路径。

工具概述 | --- | --- | | rename_symbol_by_tsmorph 在整个项目中成批更改符号名称 | rename_filesystem_entry_by_tsmorph 更改文件/文件夹名称,更新import路径 | find_references_by_tsmorph |列出符号的定义、参照位置| | remove_path_alias_by_tsmorph 将路径别名替换为相对路径 | move_symbol_to_file_by_tsmorph 将符号移动到其他文件并更新参照 | change_signature_by_tsmorph |添加/删除/排序函数参数,更新所有调用位置| | get_type_at_position_by_tsmorph 获取指定位置的推理类型信息 | find_unused_exports_by_tsmorph 枚举未使用的导出候选项

rename_symbol_by_tsmorph

在整个项目中统一重命名指定文件中位于特定位置的符号(例如,函数变量类接口)。

  • 用例:如果引用的地方很多,手动更改很困难。
  • 所需信息:目标文件路径、符号位置(行/列)、当前符号名称和新符号名称。

rename_filesystem_entry_by_tsmorph

重命名多个文件和/或文件夹,然后单击 import / export 自动更新语句路径。

  • 用例:随文件配置更改修改import路径。想一次重命名/移动多个文件/文件夹时。
  • 所需信息:重命名操作数组 renames: { oldPath: string, newPath: string }[]。
  • 举动:
    • 参照解析主要使用符号解析。
    • 路径别名(@/ 中所述修改相应参数的值转换为相对路径来修改标记元素的显示属性。
    • 浏览目录索引的导入(例如: ../components),则显式文件路径(例: ../components/index.tsx),模板名称将采用不同的格式。
    • 操作前检查路径冲突(现有路径操作中的冲突)。
  • 注意:对于许多文件/文件夹或非常大的项目,分析和更新可能需要很长时间。export default Identifier; 格式的默认导出引用可能无法正确更新(已知限制)。

find_references_by_tsmorph

查找并列出指定文件中特定位置的符号定义和整个项目中的所有引用。

  • 用例:了解某个函数或变量的使用位置。重构影响范围的调查。
  • 所需信息:目标文件的路径、符号的位置(行、列)。

remove_path_alias_by_tsmorph

在动态输入提示中单击 import / export 语句中包含的路径别名(@/components 的双曲正切值../../components 中所述修改相应参数的值。

  • 用例:要提高项目的可移植性,必须符合特定的编码约定。
  • 所需信息:要处理的文件或目录的路径。

move_symbol_to_file_by_tsmorph

将指定的符号(函数变量类接口别名Enum)移动到其他文件,并自动更新整个项目的引用(包括import/export路径)。

  • 用例:想将特定的功能剪切到其他文件来变更代码构成的情况。
  • 所需信息:源位置文件路径,要移动的符号的名称。如果有同名符号,则为种类(declarationKindString)来删除它。
  • 举动:同时移动仅在该符号中使用的内部从属关系。从移动源的其他符号引用的从属关系仍保留在移动源中,如有必要 export 将条目添加到文档注册表。
  • 注意:默认导出(export default)的符号不能移动。

change_signature_by_tsmorph

添加、删除和排序函数方法箭头函数的参数,并更新项目中所有调用位置的参数。

  • 用例:要向调用方较多的函数添加必需参数,要删除和排序通过import/重新导出/方法链引用的函数的参数。通过类型检查器可靠地反映LLM的单次编辑容易发生遗漏的更新。
  • 所需信息:对象文件的路径、函数名标识符的位置(行、列)、函数名、适用操作的排列 operations。
  • 操作(operations):
    • add: index(省略时为末尾)插入参数。argumentForCallers 时,在各调用处的相同位置插入该文本。省略时不更改调用方(仅限末尾的optional/默认参数)。
    • remove: index 的参数。从传递该数以上参数的调用中删除对应部分。
    • reorder: newOrder 中描述的场景,使用以下步骤创建明细表,以便在概念设计中分析体量的体积。如果调用的参数数不匹配,则会失败。
    • 操作按顺序应用,后续操作参考应用前置操作后的参数列表。
  • 注意:扩散参数(fn(...args))的调用在更改参数的操作中失败。调用方多的情况下 dryRun: true 中所述修改相应参数的值。参数的重命名是 rename_symbol_by_tsmorph、函数的移动 move_symbol_to_file_by_tsmorph 来修改标记元素的显示属性。

get_type_at_position_by_tsmorph

返回TypeScript/JavaScript文件指定位置上TypeChecker推导的类型符号声明位置。

  • 用例: tsc 而需要与环境混合的每条反射光线,进行环境采样。单击功能区上 Read 更便宜地获得型号签名时。想在重构前确认值的实际形状时。
  • 所需信息:对象文件的路径、要检查的位置(行、列)。
  • 注意:文件级推理类型(例如: typeof import("...")),通常不是预期的结果。响应 nodeKind 查看项目中可用的所有族。如果你想集中分析多个位置 tsc 来定义自定义外观。

find_unused_exports_by_tsmorph

扫描整个项目,未从声明文件外部引用 export 列表框中,此格式对应于条目“无”。

  • 検出対象:内联 export(export function/class/const/let/var/enum/interface/type)、export default(标识符函数类)、export = <Identifier>。
  • 判定方法: findReferencesAsNodes() 查看项目中可用的所有族ExportDeclaration 下标引用(export { x } from "./y" 等纯粹的再导出)・node_modules 中描述的场景,使用下列步骤创建明细表,以便在概念设计中分析体量的周长。
  • 用例:死线清理,模块公开面盘点。删除前必须 find_references_by_tsmorph 请在中双击。
  • sameFileRefs(删除vs unexport的判断):为每个候选项添加同一文件中的引用数(声明本身和重新导出站点除外)。报告的候选项在定义上为“声明文件的外缺少支持的问题。
    • sameFileRefs=0:在同一文件中未使用→ 真正的死。删除所有声明以确保安全(textHits=0 一起更可靠)。
    • sameFileRefs=1+:在同一文件中使用 export 只需要关键字。声明应保留(删除后会破坏同一文件内的引用)。删除所有报告的声明会损坏构建。
  • textOccurrences(textHits):声明文件以外在源文件中 \b<name>\b 出现的次数。0 只是“其他文件没有名字”,同一文件内有无使用另外 sameFileRefs (该字段单独无法判断“删除后安全”)。1+ 如果是这样的话,有字符串文字/JSX/动态参照的可能性 find_references_by_tsmorph 中所述方法的备选方法。
  • default export假阳性: [default] 标记候选项(export default <Identifier> / export = <Identifier>),则findReferencesAsNodes 的 import Foo from "./mod" 的default import不结合容易成为假阳性。textHits 的规格化距离的幂函数。低信赖 find_references_by_tsmorph 中所述修改相应参数的值。
  • responseFormat: "list"(默认值,1个候选1行)/ "summary"(项目整体的合计=总数、删除安全性的细目、按kind、按目录)。在大规模报告中,所有列举都容易超过响应大小上限,所以首先 "summary" 中把握死码的偏差entryPoints / excludeFilePatterns 缩小 "list" 的正确位置的运用是安全的(summary 是 maxResults 进行动态观察时的轴心点。
  • 选项: entryPoints(绝对路径数组。始终作为公开API使用)、excludeFilePatterns(部分一致,不属于扫描对象)、maxResults(list模式的上限。默认值100)expandNamespaceImports(默认ON)。
  • 已知极限:动的 require / import()、根据文件系统规约的路由(Next.js的 page.tsx 等),无法检测出隔着字符串反射的参照。entryPoints / excludeFilePatterns 中选择新的扶手类型,来修改默认的扶手。
  • monorepo的built dist包系假阳性:workspace包是package.json的 exports(或 main / module / types中描述的场景,使用以下步骤创建明细表,以便在概念设计中分析体量的体积 ./dist/index.js)时,来自其他软件包的import将在构建输出(或node_modules)侧解析,不会与扫描对象的src侧符号关联。因此实际使用的导出仅限于该包未使用。该形状在结构上检测,在结果的开头⚠ 以包为单位发出警告(超出包名称扫描的入口点影响候选计数)。具有警告的软件包候选者被视为不信任,并且在删除之前 textHits 和 find_references_by_tsmorph 中所述修改相应参数的值。解决方法:分析时 exports 源(./src/index.ts 等)或个别验证候选人。

记录设置

服务器的行为日志由环境变量控制。mcp.json 的,之 env 在块中设置。

|环境变量|说明|默认| | --- | --- | --- | | LOG_LEVEL 日志详细程度。fatal / error / warn / info / debug / trace / silent | info | | LOG_OUTPUT | 出力先。console 或 file | console | | LOG_FILE_PATH | LOG_OUTPUT=file 时日志文件的绝对路径 [プロジェクトルート]/app.log |

LOG_OUTPUT=console 且开发环境(NODE_ENV !== 'production'),模板名称将采用不同的格式 pino-pretty 中描述的场景,使用下列步骤创建明细表,以便在概念设计中分析体量的周长。想要避免标准输出对MCP客户端的影响时 file 中所述修改相应参数的值。

设定例:

{
  "mcpServers": {
    "mcp-tsmorph-refactor": {
      "command": "npx",
      "args": ["-y", "@sirosuzume/mcp-tsmorph-refactor"],
      "env": {
        "LOG_LEVEL": "debug",
        "LOG_OUTPUT": "file",
        "LOG_FILE_PATH": "/Users/yourname/logs/mcp-tsmorph.log"
      }
    }
  }
}

开発

前提条件

  • Node.js(版本为 package.json 的,之 volta 字段)
  • pnpm(版本为 package.json 的,之 packageManager 字段)

设置和构建

git clone https://github.com/sirosuzume/mcp-tsmorph-refactor.git
cd mcp-tsmorph-refactor
pnpm install
pnpm build      # dist/ に出力

主要命令

pnpm test       # テスト実行
pnpm test:watch # ウォッチモードでテスト
pnpm check-types # 型チェック(コンパイルなし)
pnpm lint       # Lint チェック
pnpm lint:fix   # Lint 修正
pnpm format     # フォーマット
pnpm inspector  # MCP Inspector でデバッグ

从MCP客户端使用本地构建

构建后node 的 dist/index.js 中所述修改相应参数的值。

{
  "mcpServers": {
    "mcp-tsmorph-refactor-dev": {
      "command": "node",
      "args": ["/path/to/your/local/repo/dist/index.js"],
      "env": {
        "LOG_LEVEL": "debug"
      }
    }
  }
}

调试用启动器

在动态输入提示中单击scripts/mcp_launcher.js 的双曲正切值。将原始服务器进程作为子进程启动,将启动信息和输出 .logs/mcp_launcher.log 中所述修改相应参数的值。

mcp.json 的,之 command 的 "node"、args 的 scripts/mcp_launcher.js 在动态输入提示中单击.logs/mcp_launcher.log(以及服务器自身的日志)。

{
  "mcpServers": {
    "mcp-tsmorph-refactor": {
      "command": "node",
      "args": ["scripts/mcp_launcher.js"],
      "env": {
        "LOG_OUTPUT": "file",
        "LOG_FILE_PATH": ".logs/mcp-ts-morph.log"
      }
    }
  }
}

发布

此软件包包含GitHub Actions工作流(.github/workflows/release.yml),模板名称将采用不同的格式。

Git标记是版本的单个真实source。 package.json 的,之 version 和 src/version.ts 的,之 VERSION 无论哪一个 0.0.0-development 中所述修改相应参数的值。不需要手动bump。

公开手顺

git checkout main && git pull --ff-only
git tag v1.2.0
git push origin v1.2.0

在标记push中触发工作流,按以下顺序执行:。

  1. 标签(v1.2.0)到VERSION(1.2.0)(仅限strict SemVer。未支持预发布)
  2. 保持placeholder版本 pnpm test
  3. node scripts/release-version.mjs --bake 1.2.0 的 src/version.ts 和 package.json 的,之 version 改写
  4. pnpm build
  5. dist/version.js 的 exports.VERSION = "1.2.0"; 包括 grep -F 确认
  6. _version_note 从package.json中删除
  7. pnpm publish --provenance 发布到npm

完了后、npm view @sirosuzume/mcp-tsmorph-refactor version 查看项目中可用的所有族。

前提是npm Trusted Publishing。NPM_TOKEN 已取消,将通过GitHub Actions的OIDC发布(release.yml 的,之 id-token: write 参照)。

为什么把tag作为真实的source

在以前的操作中package.json 的版本src/mcp/config.ts 的,之 serverInfo.version 忘记「bump」「打标签」的3顺序的其中之一的话不匹配被发表了(实际有偏离了的履历)。新运用在开发中一直 0.0.0-development 就这样,发行时CI会看tag更新所有地方bump遗忘没有结构性地发生。

CI(.github/workflows/ci.yml)是每次PR/main push node scripts/release-version.mjs --check 中描述的场景,使用以下步骤创建明细表,以便在概念设计中分析体量的体积。用手bump了的PR在这里失败。

失败时的恢复

  • 如果工作流中途失败 不删除tag、将修改合并到主标记中,然后单击vX.Y.(Z+1))(fix-forward)。
  • 由于npm的immutability不允许在同一标记上重新publish,所以tag的覆盖是无意义的。

许可证

该项目在MIT许可证下发布。了解更多信息 许可证 请看文件。