Community编程与开发github.com

sublime-mcp 包审计

如何运行 Sublime 包审计,以暴露 sublime-mcp 的弱点。在通过便携式 Sublime 实例安装、测试或卸载 Sublime 包时使用:不使用脚本、eval_python、HTTP 桥接;像用户一样安装;说明每一步要使用哪些 sublime-mcp 工具,以及什么算作发现。

sublime-mcp 包审计 是什么?

该技能定义了一套严格的审计流程,用于识别和记录 sublime-mcp 工具本身的缺陷。它强调通过真正的用户操作(如命令面板安装包)来测试包,同时严格禁止任何绕过 sublime-mcp 功能的变通方法,例如使用脚本、`eval_python` 或 HTTP 调用。任何无法通过 sublime-mcp 执行的用户操作都会被标记为弱点。审计过程通过截图、原生窗口检测和 Python 控制台日志,强制对对话框、选择器和错误进行系统检查。发现的缺陷被整理为完整的 GitHub 问题,并包含回滚说明,但仅在获得明确许可后才会发布。该技能包含详细的规则,涉及工作流程协调、窗口聚焦注意事项、工具文档审计以及文件命名等方面的具体约束。

兼容平台✓Claude Code~Codex CLI✓Cursor
Part ofMobile
npx skills add https://github.com/dpc00/sublime-package-audit/tree/HEAD/.claude/skills/sublime-mcp-audit

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

sublime-mcp 包审计 是做什么的?

面向其他人的公开通用版本方法:https://github.com/dpc00/sublime-package-audit (.claude/skills/sublime-package-audit/SKILL.md 和 PROCEDURE.md)。本文件是 Donald 的本地规则和路径的私人工作副本;当某个经验具有通用性时,也应放入公开技能中。

来源:Donald 于 2026-10-07 的指示以及当天使用 discover_tools 进行的工具调查。

文件位置(更新于 2026-10-17)

所有内容均在审计仓库中,位于 C:\Users\donal\projects\sublime-package-audit:data\ (.tested_packages.tsv, .package_skill_test_log.md, .package_skill_baton.md, campaign_tools\),notes\(带日期的笔记和交接记录,索引 notes\MEMORY.md),tools\ (rec.ps1 记录单个包;它不会提交或推送,Donald 2026-10-20:在批量任务结束时运行 tools\commit_day.ps1:午夜后的第一次运行会创建当天的提交,当天的其他每次运行都会修订它;历史记录保持每天一个提交)。下面和笔记中提到的较旧的“仓库根目录”或 .claude\memory 指的是这些文件夹。包列表仍在 C:\Users\donal\data\st_packages。

目的

审计是我们发现 sublime-mcp 自身弱点的方式。沿途发现的包错误是附带结果。任何掩盖 MCP 漏洞的东西都会破坏审计。

硬性规则

  1. 不允许任何类型的脚本(Python、PowerShell、Shell、充当脚本的单行命令)。
  2. 不允许使用 eval_python,用于任何事情。
  3. 不允许对 MCP 桥接端口(9510、9520、9532...)进行 HTTP 调用。如果便携版 Sublime 的 MCP 服务器崩溃或挂起,停止并报告;不要绕过它。
  4. 像用户一样安装是目标,但不总是现实。对于 Package Control 发布版本,使用命令面板:“Package Control: Install Package”,输入名称,按 Enter。仓库主分支(最新代码)无法从选择器中获取,因此需要复制进去(见下面的“允许”)。测试两者,并说明每个结果是哪个版本展示的。
  5. 如果 sublime-mcp 无法完成用户可以完成的步骤,则不要绕过它。将其记录为 sublime-mcp 弱点并告知 Donald。
  6. 安装(他的顺序,2026-10-24;取代了旧的“安装免费先决条件并测试”笔记): 不要安装任何体积庞大或无法卸载的软件(他的措辞,2026-10-31;旧的“仅限选择器,无 winget,pip,npm -g,gem,go,cargo,apt,安装程序,无需管理员权限”的列表已失效且从未被遵循)。小型可移除的安装可以。(旧的“任何需要管理员权限的”条款于 2026-10-31 被 Donald 移除:它已失效且从未被遵循。)如果一个包的先决条件缺失,则在 finish.ps1 中记录为“先决条件未安装”并跳过。如果他在一轮中允许安装一个包,首先将其行写入 data\installs_ledger.md。每次测试后,移除已安装的内容并验证其已消失(使用 Test-Path、控制台“Removed package”、注册表),然后再记录该包。详情请见:notes\feedback_install_policy_2026_10_24.md。

允许的操作,Donald 已确认:将包副本(例如仓库主分支代码)复制到 Packages 文件夹中进行测试;sublime-mcp 的 run_command 工具,它可以模拟用户的菜单点击。不允许从 eval_python 内部运行命令。

仅限主 Sublime,他在同一键盘上(Donald,2026-10-20;取代了下面的所有便携版步骤)

便携版已不复存在。审计在他的主 Sublime 实例的一个窗口中进行,他正在打字、点击标签页和关闭对话框,而我则在工作。MCP 代码保持不变;这些规则是修复措施(他的决定:修复措施应属于技能)。

  1. 取代 00 和分支/PR 禁令(Donald,2026-10-21,在我写下修复措施并停止之后:“如果你认为这能帮助别人,那就去做吧。开了又关,别再浪费时间”): 对于真正可重现的缺陷,完成工作:编写修复方案,在他的 Sublime 上测试它,然后将证据加上经过测试的修复方案作为评论发布在包的 issue 上(或者一个新的简短 issue),以“Claude 报告:”开头,并进行记录。无需为每个缺陷再次请求许可。跳过已归档的仓库(他的规则,同日:GitHub 拒绝那里的评论)。将 findings\ 作为记录(将其状态行设置为 POSTED 并附带链接)。仅当评论无法承载修复方案时才创建拉取请求;他于 2026-10-14 暂停 PR 以及禁止分支的规定,需要由他本人再次解除,因此未经询问,不要开启 PR 或分支。
  2. (较旧,已被 000 取代)未经他的同意,不得向外部发布任何内容(他的担忧,2026-10-20:错误的公开报告会在他软件工程师同行面前让他难堪;当天已经发出了三个错误的报告)。 不得发送任何形式的 GitHub issue、评论、PR 或电子邮件。每个发现都应写成一个完整的 issue(标题、内容、证据、文档说明),放在其自己的文件中,位于仓库根目录的 findings\ 中(<package>-<short-topic>.md,第一行 Status: not filed),格式与将要提交的完全一致。他的话:“把完整的 issues 放进去,不要提交它们”;该仓库是公开的,因此作者可以在这里查找自己的包,并且内容会被跟踪和备份(notes\ 被 .gitignore 忽略)。清理本地路径和名称。在 RESULTS.tsv 中记录为“已在 findings\ 中记录(未提交)”。仅在他稍后要求针对特定发现发布时才发布,并且需要先回读文本给他听。这条规则取代了本技能和笔记中所有旧的“提交它”的指示,直到他解除限制。
  3. 首次使用前请阅读(他的规则,2026-10-20:像那样的错误意味着文档没有被阅读)。 在会话中首次使用任何会关闭、删除、键入、发送或更改内容的工具之前,使用 discover_tools(query = 工具名称)阅读其自身的描述,并说出关键的那一行内容(“不带名称的 close_file 会关闭活动标签页”)。在任何向外发送(电子邮件、GitHub 帖子)之前,重新阅读他笔记中的匹配规则,并展示或检查它所引用的原始内容;如果找不到原始内容,则不要发送任何内容。
  4. 为每个标签页命名。 close_file 始终带有 name 参数(未保存标签页的名称是其第一行文本;错误的名称会返回 open_views)。绝不要在没有 name 的情况下使用 close_file:它会关闭活动标签页,而哪个标签页是活动的由他决定,而不是我(2026-10-20 它在我输入 /rc 时关闭了我自己的 Claude 标签页)。 1b. 破坏性调用需先询问 Donald(2026-10-27,sublime-mcp 提交 1a71fa6)。 close_file(带 discard)、delete_file、delete_folder、revert_file、revert、close_window、close_workspace、remove_folder、exit、eval_python 和 run_command 的这些命令(即使在批处理中)会在他的 Claude Code 终端中显示一个接受/拒绝提示。在执行此类调用之前,说一句话(例如“正在关闭测试标签页 'x' 并放弃更改,将出现一个提示”),指明确切的标签页名称,并且不要重复执行他拒绝的调用(“已拒绝,未作任何更改”是最终答案;不要用另一个工具绕过它)。便携版(C:\Users\donal\tools\st_portable)运行相同的插件,但在其 User\MCP Commander.sublime-settings 中设置了 "require_consent_for_destructive": false,因为其连接是旧式连接,无法被询问;没有这行,这些调用在便携版中会被拒绝。仅在那里将其设为 false,绝不在他的主 Sublime 中设置。一个名称匹配多个标签页的情况现在会被 close_file 和 revert_file 拒绝:请使用 get_sheets 返回的 index。
  5. 永远不要依赖几轮调用前处于活动状态的标签页。 在调用作用于“活动标签页”的操作之前(insert、作用域为文本的 run_command、get_active_file、ui_press_key、ui_type_text),在同一个批处理中,立即查看窗口标题或 get_open_files。如果活动标签页不是我意图操作的标签页,则不执行任何操作,并用一句话说明原因。
  6. 更少、更短的爆发式操作。 先进行读取、gh 和文件操作;将触及窗口的步骤放在一起;中间不要有任何等待,以免留下未完成的选择器或打开的脏标签页。 3b. 屏幕上留下的选择器或对话框意味着测试未运行(Donald,2026-11-05,此前因屏幕上留有 CP New 选择器而对我大喊:“如果有东西弹出了对话框或选择器,你必须必须必须检测并处理它。否则你就是把它留在那里,把它留在那里意味着插件正在等待一个答案**。如果你甚至没有注意到选择器,你就没有正确地测试这个包。”)。** 仍然存在的提示是一个未回答的问题:包尚未完成,编辑器不可用,并且窗口属于该包,而不是我。因此:
  • 在每次命令分发后,以及在写入任何行之前:对测试窗口进行 ui_screenshot(图片是唯一能检测到 ST4 输入处理程序选择器的方法——当包在 3.14 主机中加载时,get_quick_panel 无法看到它们,辅助功能树也无法显示它们)加上 list_native_windows(后者可以找到原生模态对话框)。
  • 回答它,或者故意取消它,并在行中说明。绝不要让它留在那里,也绝不要从仍然有提示的窗口中写入行。
  • 发布的文本 + 返回键,按此顺序:ui_type_text → 截图(文本确实已输入) → ui_press_key Return → 截图(步骤确实已推进)。当窗口不在前台时,发布的返回键无效,并且通常需要按下第二次。ui_press_key/ui_type_text 接受 hwnd 参数;便携版编辑器的 hwnd 来自 list_native_windows。
  • 原生模态对话框(ok_cancel_dialog、error_message)会阻塞 Sublime 的主线程:所有其他路由都会返回“主线程超时 5 秒... 一个原生窗口阻塞了 Sublime 的主线程”。list_native_windows 和 dismiss_native_window {"hwnd":…, "action":"button", "button":"Yes"} 在阻塞时仍能应答并关闭对话框而不影响焦点——使用它们,不要使用 AX 点击(对对话框按钮的 AX 按下可能会无声地失败)。
  • 将测试窗口置于前台会占用 Donald 的键盘:在同一轮中宣布“请放手便携版约 60 秒”,将前置+按键+截图作为一次爆发操作执行,并在最后将他自己的窗口再次置于前台(front.ps1 -Hwnd <他的 hwnd>)。2026-11-05 时,他用于批准提示的 Enter 键落在了便携版的选择器中,替我回答了测试。

3c. 每次分发后的三项检查——对话框、选择器、控制台(Donald,2026-11-05:“对对话框和选择器要更加警惕... 如果你不注意这些类型的东西,测试很可能会不准确。还有 Python 控制台,错误会在那里出现。”)。 每次分发意味着每次 run_command、每次执行的 eval_python、每次安装、每次构建、每次 run_syntax_tests。四次调用,按此顺序,四个答案放入行中:

  1. list_native_windows——一个 kind:"dialog" 条目是一个已冻结 Sublime 的模态框。读取其 messages 和 buttons,使用 dismiss_native_window 应答它(无需焦点,无需 AX 点击),然后再次列出以证明它已消失。一个没有人回答的对话框正是为什么一个“崩溃的”编辑器实际上是一个在等待的编辑器。

  2. get_quick_panel——非空的 items 表示面板已打开(也可能是已关闭面板的过时答案,因此使用步骤 4 确认)。使用 pick_quick_panel {index} 驱动它;输入面板(show_input_panel,ST4 输入处理程序)永远不在此出现,因此图片是它们唯一的检测器。

  3. get_console——在分发之前获取 total 条目计数,然后仅读取之后的新条目(tail = 之后计数 − 之前计数)。扫描该切片以查找 Traceback、Error、error:、ImportError、ModuleNotFoundError、SyntaxWarning,以及包自身的状态行。一个导入失败的插件什么也不会输出(Uxntal,2026-11-05),因此在安装带有插件代码的包后,一个空的切片本身就是一个需要追究的发现:使用 importlib.import_module('<Pkg>.<module>') 来暴露真实的异常。

  4. 测试窗口的 ui_screenshot——这是唯一能显示输入面板、自动完成弹出窗口或遗留覆盖层的方式,也是区分活动选择器和过时记录的方法。在分发后执行一次,在写入行之前再执行一次。 任何残留状态(面板、弹出窗口、文件夹、脏标签页)在写入行之前都会被清除:run_command hide_overlay,对于 output.exec 使用 hide_panel,set_project_data {"folders": []},以及在文件可丢弃时,在 set_scratch(True) 之后按名称关闭视图。

  5. 他的消息或中断会立即停止我的工作。 如果某个工具结果被拒绝或者他在一轮工作中间写字,请停止发出窗口调用,回答他,并且只有在他要求时才恢复。不要完成“就这一步”。

  6. 不要读取我自己的标签页。 对一个大型标签页使用 get_active_file 会转储多达 28 KB 的内容;不带参数的 get_sheets 会转储 7 KB 的设置。使用带 settings=false 的 get_sheets 获取标签页列表和焦点,使用 get_open_files 获取名称,使用带 name 参数的 get_view_size / get_view_chars 进行有限制的读取,使用截图查看外观。 5b. 始终按名称定位。 run_command(作用域为文本,带 name)、send_to_view、get_view_content、get_view_chars、get_view_size 和 close_file 接受标签页名称或索引。只要工具提供名称参数,就使用它们,而不是“活动标签页”形式(insert、get_active_file、ui_press_key 进入编辑器)。

  7. 保持窗口原样: 按名称关闭测试标签页,关闭选择器,不留对话框,设置哈希值与备份文件(临时文件 *.backup)一致。 6a. 在提交一种新型发现之前(在本审计中以前从未提交过的类型),阅读 Sublime 自身文档(sublimetext.com/docs,discover_tools/get_help for sublime-mcp)中关于该功能的说明,并在 issue 中引用它。一个仅基于一次观察而无文档支持的发现是猜测。 6b. 在构建 4215 上,重复的 tabTriggers并不是缺陷(已于 2026-10-20 用 Haml 的 doctype 验证):按 Tab 键会显示一个弹出窗口,列出具有该触发器的每个代码片段,用户从中选择一个。绝不要在未打开该弹出窗口的情况下提交“两个代码片段共享一个触发器”的问题(输入触发器,按 Tab,截图)。2026-10-20 的 React ES6 Snippets rcc 发现(“没有选择”)是在没有寻找弹出窗口的情况下做出的,很可能是错误的。 6c. tabTrigger 中的空格(已于 2026-10-21 在构建 4215 上验证): Sublime 的文档...

相关技能