Community生产力与协作github.com

Moksa1123/wporg-plugin-submit

便携的 Claude 智能体技能,助你轻松通过 WordPress.org 的自动扫描和人工审核——包含参考资料、构建/预检脚本和代码→修复对照表。

wporg-plugin-submit 是什么?

该技能旨在帮助开发者将 WordPress 插件顺利提交至 WordPress.org 目录,顺利通过自动扫描(Plugin Check)和人工审核。它汇总了实际审核周期中的常见问题及解决方案,涵盖隐藏文件、前缀冲突、数据清理、安全实践等核心痛点。技能提供了详细的参考文件、构建脚本(build-zip.sh)和预检脚本(preflight.sh),以及一个快速上传前的核对清单,能有效减少因重复上传导致的失败。支持 Claude Code 等 AI 代理平台,通过读取参考文档、执行构建和修复步骤,实现自动化或半自动化的插件提交流程。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add Moksa1123/wporg-plugin-submit

Installed? Explore more 生产力与协作 skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

在你喜欢的 AI 中提问

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

文档

WordPress.org 插件提交技能

帮助你的插件顺利通过 wp.org 的 自动扫描 和 人工审核,无需反复上传五次。基于真实审核周期提炼而成(那种因为一个不起眼的 .gitkeep 就导致整个扫描失败的教训)。

维护者: moksa · moksaweb.com · 许可证:MIT

何时使用

当用户要求以下操作时触发此技能:

  • 打包/构建一个干净的安装 zip 文件用于 wordpress.org
  • 提交或重新提交插件到 wp.org 目录
  • 修复 wp.org 审核团队的反馈(4 个经典类别)
  • 诊断自动扫描拒绝原因(隐藏文件、前缀、数据库调用等)
  • 一致地增加插件版本号(文件头 + readme + 常量)
  • 上传前预检插件

不要用于:

  • 非 WordPress 项目
  • 不会提交到 wp.org 的私有/内部插件(审核规则不适用,但安全实践仍然有益)

两大关卡

  1. 自动扫描(上传时运行的 Plugin Check)—— 硬性阻止。必须通过才能接触人工审核。参见 references/automated-scan.md。
  2. 人工审核(自动扫描通过后由人类执行)—— 通过邮件发送问题,你修复后回复。几乎总是属于 4 个代码类别之一(references/review-categories.md)以及 没有 linter 能捕捉的策略指南——许可、远程代码、跟踪、管理通知、商标、外部服务披露(references/guidelines.md)。

参考资料对照表

主题文件
Plugin Check (PCP) 操作手册——UI/CLI,全部 31 项检查 → 修复对照,错误与警告references/plugin-check.md
自动扫描硬性阻止(隐藏文件、数据库、禁止调用)references/automated-scan.md
4 个人工审核类别 + 回复措辞references/review-categories.md
真实审核教训(样例→全局搜索,3 种情况的 nonce,phpcs:ignore ≠ 转义,类型转换 ≠ 清理,路径,分支前缀)references/real-review-lessons.md
前缀化所有全局变量(函数/选项/钩子/句柄/自定义文章类型/元数据等)references/prefixing.md
清理/验证/转义 + $wpdb->prepare + Webhook 签名references/sanitization-escaping.md
加载 JS/CSS(依赖/版本、内联、条件控制、块编辑器、无原始标签)references/enqueue.md
国际化(textdomain == 插件别名,文本参数为字面量,翻译器注释,JS)references/i18n.md
权限与权限回调(授权、REST、priv/nopriv)references/capabilities.md
策略指南(许可、远程代码、跟踪、管理通知、商标、披露)references/guidelines.md
readme.txt 格式规范(文件头、标签≤5、简短描述≤150、截图、外部服务)references/readme-txt.md
能力 API/AI 客户端/MCP(每项能力的授权、数据边界、破坏性操作确认、提供商披露)references/abilities-ai-mcp.md
安全附加(文件/WP_Filesystem、上传、SSRF、禁止/混淆调用)references/security-extras.md
卸载与生命周期(数据清理、不删除用户内容、多站点)references/uninstall.md
打包 zip + 版本/文件头/readme 一致性 + .mo 文件references/packaging.md
扫描/PHPCS 代码 → 修复查找data/plugin-check-errors.csv

快速上传前核对清单(复制粘贴验证)

自动扫描(硬性阻止)
[ ] zip 中没有隐藏文件:`find . -name '.*' -not -name '.' -not -name '..'` 结果为空
    (.gitkeep / .gitignore / .DS_Store / .editorconfig 都会导致 "hidden_files" 错误)
[ ] zip 中没有 node_modules/、.git/、tests/、scripts/、phpcs.xml、webpack.config.js
[ ] 所有插件拥有的全局变量使用唯一且 >=4 个字符的前缀(不能使用 wp_ / __ / 单个 _)
[ ] 没有未使用 prepare() 的直接 $wpdb 查询;没有远程代码执行;没有回传信息

人工审核(4 个类别)
[ ] 加载:没有原始的 echo '<script>'/'<style>';使用 wp_enqueue_* + wp_add_inline_*
[ ] 每个更改状态的 AJAX/admin_post 都使用 nonce + current_user_can;Webhook 在
    使用前用 hash_equals 验证提供商签名(无法使用 WP nonce)
[ ] 每个 $_POST/$_GET 都经过清理(wp_unslash + sanitize_*);json_decode -> map_deep;
    输出延迟转义(esc_html/esc_attr/esc_url/wp_kses)
[ ] textdomain == 插件别名;__() 参数为字面量字符串;%s 前有 /* translators: */ 注释

策略(人工审核,没有 linter 能捕捉这些——参见 references/guidelines.md)
[ ] 声明 GPL 兼容许可证 + 包含 LICENSE 文件;所有捆绑的库/资源均为 GPL 兼容
[ ] 无远程代码执行 / 不从 CDN 加载可执行 JS;资源本地打包
[ ] 任何第三方 API 调用在 readme "== External services ==" 中披露(什么数据、何时、URL)
[ ] 无未经明确选择加入的数据收集/跟踪(默认关闭);无前端信用
    链接除非选择加入;管理通知可关闭 + 限定于特定页面(不滥用通知)
[ ] 插件别名/名称不以你未拥有商标的词开头(woocommerce-… / google-…)

README.TXT(参见 references/readme-txt.md——在 wp.org readme 验证器中验证)
[ ] 文件头解析:Contributors=wp.org 用户名,Tags≤5 个,Stable tag = 实际发布的版本
[ ] 简短描述 <=150 个字符,纯文本;变更日志有 Stable tag 对应的条目
[ ] 截图/横幅/图标放在 SVN /assets/ 目录中,不在 zip 内

AI / 能力 / MCP(如果插件注册了能力、调用了 LLM 或暴露了 MCP)
[ ] 每个 wp_register_ability 都有真实的 permission_callback(对象级权限),不是 __return_true
[ ] 数据边界:能力/MCP 工具只返回当前用户权限允许的数据
[ ] 模型/代理输入视为不可信;破坏性能力需确认后才执行
[ ] 捆绑了 LLM/AI SDK(GPL);在 == External services == 中披露提供商;密钥永不记录
[ ] MCP 端点需要认证(App Password/OAuth)并且执行每个能力的 permission_callback

额外安全与生命周期
[ ] 无 eval/shell/obfuscation/extract;无遗留的 var_dump/print_r/error_log
[ ] 仅通过 WP_Filesystem 将文件放到 uploads 目录;上传使用 wp_handle_upload + MIME 白名单
[ ] 通过 wp_safe_remote_* 进行远程调用(SSRF:阻止内部网络范围)+ 超时 + 响应检查
[ ] uninstall.php 受 WP_UNINSTALL_PLUGIN 保护;仅删除你前缀的数据;永不删除用户内容

打包与元数据
[ ] 版本同步:主文件头 Version、版本常量、readme Stable tag、变更日志
[ ] Requires 文件头在主文件 AND readme.txt 中保持一致(WP / PHP / WC)——以及任何
    运行时在激活时检查的 MIN_* 常量
[ ] vendor/ 通过 `composer install --no-dev` 生成(不含 squizlabs/phpunit/phpcompatibility)
[ ] zip 根文件夹名称 == 插件别名

工作流程

  1. 阅读规则 了解任务(参见上方的参考资料对照表)——从 references/automated-scan.md + references/review-categories.md 开始,然后深入与发现的问题对应的参考文件(prefixing.md / sanitization-escaping.md / enqueue.md / i18n.md),以及用于构建的 references/packaging.md。
  2. 构建干净的 zip —— 运行 scripts/build-zip.sh(处理 git archive,移除开发文件 + 所有点文件,安装 vendor/ 时使用 --no-dev,以插件别名作为根目录压缩)。永远不要手动打包工作目录,否则开发垃圾和点文件会泄露进去。
  3. 预检 —— 运行 scripts/preflight.sh <path-to-zip-or-dir>:扫描隐藏文件,检查版本同步 + 文件头/readme 一致性,如果配置了 PHPCS 则运行。修复直到干净为止。
  4. 运行 Plugin Check (PCP) —— 这是官方工具,可以在本地运行目录的自动检查。wp plugin check <slug> --require=./wp-content/plugins/plugin-check/cli.php(或工具 → Plugin Check)。修复每个 ERROR,检查每个 WARNING。参见 references/plugin-check.md 了解全部 31 项检查、标志以及每个技能章节对应修复什么问题。
  5. 上传。 如果自动扫描拒绝 → 读取准确的错误代码,通过 data/plugin-check-errors.csv 映射,修复,重新构建,重新上传。
  6. 人工审核回复 —— 当审核者通过邮件发送问题时,在整个代码中逐一修复(示例只是样本——用 grep 搜索整个树,对整个插件运行 Plugin Check + PHPCS;相同类别重复出现 = 立即重新拒绝)。然后逐点回复,说明修改了什么。参见 references/review-categories.md 了解标准修复 + 回复措辞,以及 references/real-review-lessons.md 了解每个类别的全局搜索命令和那些第一次修复时可能漏掉的陷阱。

来之不易的经验教训(代价高昂的那些)

  • .gitkeep 会导致自动扫描失败。 它是隐藏文件。从包中去除所有点文件;从 git 中移除 .gitkeep,这样 git archive 永远不会重新添加它。
  • 版本要求漂移。 wp.org 同时读取主文件文件头 AND readme.txt;运行时的 MIN_WC/MIN_PHP 常量可以单独控制激活。三者必须一致,否则低版本用户安装成功后会遇到功能异常。
  • Webhook 无法使用 WP nonce。 审核者会在 IPN 处理器上标记“无 nonce”——这是误报;正确的做法是通过 hash_equals() 验证提供商签名。加上逐行的 phpcs:ignore 注释并说明原因。
  • json_decode 不是清理操作。 始终对结果应用 map_deep(sanitize_text_field)。
  • composer install(不加 --no-dev) 会将 phpcs/phpunit 泄露到 vendor/ 中 → 包体积增大,被标记。始终对发布包使用 --no-dev。

相关技能