skills/path-locator-checker-yashu/SKILL.md
扫描技能 scripts/ 目录下 JS 脚本中依赖当前文件位置(__dirname、import.meta.url)定位资源的写法,报告问题并按需修复。激活条件:用户消息须包含以下关键词之一:`检查路径定位`、`扫描 __dirname`、`检测路径定位写法`、`修复路径定位问题`。
npx skillsauth add steelan9199/wechat-publisher-skill path-locator-checker-yashuInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
在开发 wechat-publisher-yashu 技能时遇到了一个真实 bug:源码运行正常,但经过 js-obfuscator-yashu 打包混淆后报错"主题 blue 不存在"。
根因:theme.js 里用 path.join(__dirname, "..", "..", "themes") 定位主题目录。
__dirname 是 scripts-backup/tools,上两级正好到 wechat-publisher-yashu/themes,正常。scripts/index.js 单文件,__dirname 变成了 scripts,上两级跳到 skills/themes,这个目录不存在。更糟的是,loadTheme("blue") 找不到文件时递归调用自己,导致栈溢出。
这类问题的本质:代码用"当前文件位置"(__dirname / import.meta.url / process.cwd())作为基准定位运行时资源(主题、配置、模板等静态文件)。当打包工具把多个文件合并成单文件、或改变输出目录结构时,"当前文件位置"会变化,导致资源路径失效。
大公司的通用做法:以"项目根目录"为基准定位资源(通过向上查找 package.json 或项目标志文件),而不是以"当前文件"为基准。因为项目根目录是稳定的,bundle 文件放到任何位置都不影响资源定位。
本技能就是用来发现这类问题,并提供以技能根目录(SKILL.md 所在目录)为基准的修复方案。
对指定技能的 scripts/ 目录及其子目录下的 JavaScript 文件(仅 .js,ES6 语法)递归扫描,发现"依赖当前文件位置定位资源"的代码模式。
核心原则:
SKILL.md 所在目录为技能根目录,向上查找定位为了让 AI 准确识别并触发本技能,用户应尽量在请求中包含以下两点:
scripts/ 目录、JS 脚本、路径定位、__dirname、资源路径)| 用户说法 | AI 应执行的操作 |
| -------------------------------------------------- | ------------------------------------------ |
| "检查 wechat-publisher 技能的路径定位问题" | 运行 check.js 扫描该技能 JS 脚本 |
| "扫描 feishu-docx 技能 scripts 里的 __dirname" | 运行 check.js 扫描该技能 JS 脚本 |
| "检测 coze-caller 技能的资源路径是否会混淆失效" | 运行 check.js 扫描该技能 JS 脚本 |
| "帮我修复 wechat-publisher 技能的路径定位问题" | 先扫描报告,询问确认后由 AI 读取源码并修复 |
| 用户说法 | 真实意图 | 本技能是否处理 |
| ----------------------------- | ----------------- | ------------------------------------------------- |
| "检查这段代码的逻辑错误" | 代码逻辑审查 | 否 |
| "修复文件路径错误的 bug" | 具体某个 bug 修复 | 否 |
| "扫描 scripts 目录有没有混淆" | 混淆检测 | 否(用 js-obfuscator 的 check-obfuscated.js) |
反向提问提示:如果用户只说"检查路径问题"而没有说明是"检查路径定位(
__dirname/import.meta.url)是否会混淆失效",AI 应当反问用户"是要检查路径定位写法是否会混淆失效,还是检查其他路径问题?",确认后再执行。
$SKILL_DIR:本技能所在的绝对目录,即 SKILL.md 所在文件夹SearchReplace 精准修复(无修复脚本)scripts/ 目录存放待检查的 .js 文件本技能采用深度模式扫描,覆盖以下三类问题模式:
检测 __dirname、import.meta.url、process.cwd() 与 path.join / path.resolve 的组合使用。
典型问题代码:
// ❌ 问题:依赖 __dirname 定位资源,打包后 __dirname 变化
function getThemesDir() {
return path.join(__dirname, "..", "..", "themes");
}
// ❌ 问题:依赖 import.meta.url 定位资源
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const configPath = path.join(__dirname, "..", "config.json");
// ❌ 问题:依赖 process.cwd() 定位资源
const dataPath = path.resolve(process.cwd(), "data", "templates");
检测 __dirname、import.meta.url、process.cwd() 的所有使用(即使不与 path 模块组合)。
典型问题代码:
// ❌ 问题:直接用 __dirname 拼接路径
const tokenFile = path.join(__dirname, "../wechat-token.json");
// ❌ 问题:import.meta.url 用于定位资源
const templateUrl = new URL("./template.html", import.meta.url);
检测 fs.readFile、fs.readFileSync、fs.existsSync、fs.readdirSync、fs.writeFile 等文件系统操作中使用相对路径字符串(如 "./config.json"、"../themes")的情况。
典型问题代码:
// ⚠️ 可能有问题:相对路径字符串,依赖 cwd
const config = JSON.parse(fs.readFileSync("./config.json", "utf-8"));
// ⚠️ 可能有问题:相对路径字符串
if (fs.existsSync("../themes/blue.json")) {
// ...
}
注意:模式 3 可能存在误报(例如
fs.readFile("./README.md")如果是读取随 bundle 移动的文件则没问题)。报告时会标注"⚠️ 可能误报",需用户自行甄别。
修复时采用以 SKILL.md 所在目录为技能根目录的策略:
SKILL.md 文件即认定其所在目录为技能根目录path.join(skillRoot, "themes"))// 修复后的代码示例
import fs from "node:fs";
import path from "node:path";
function findSkillRootDir(startDir) {
let dir = startDir;
while (dir !== path.dirname(dir)) {
if (fs.existsSync(path.join(dir, "SKILL.md"))) {
return dir;
}
dir = path.dirname(dir);
}
return null;
}
function getThemesDir() {
const skillRoot = findSkillRootDir(__dirname);
if (!skillRoot) {
throw new Error("无法定位技能根目录,找不到 SKILL.md");
}
return path.join(skillRoot, "themes");
}
为什么选择 SKILL.md 而不是 package.json:
SKILL.md,是技能体系的标志文件package.json 在你的技能里位于 scripts/ 下,会定位到错误的层级SKILL.md 始终位于技能根目录,稳定可靠process.cwd() 作为默认基准process.cwd() 表示 Node.js 进程启动时的工作目录,它不是稳定的资源定位基准。
原因:
d:\project\)d:\skill\private-skills\.trae\skills\xxx-yashu\scripts\)正确做法:
SKILL_ROOT 定位SKILL_ROOT 通过向上查找 SKILL.md 确定,只要 bundle 和 SKILL.md 保持在一起,路径就稳定SKILL_ROOT 解析,而不是 process.cwd()禁止写法:
// ❌ 不要依赖 process.cwd() 定位资源
const dataPath = path.resolve(process.cwd(), "data", "templates");
推荐写法:
// ✅ 基于 SKILL_ROOT 定位资源
const dataPath = path.join(SKILL_ROOT, "data", "templates");
当用户要求检查某个技能的路径定位问题时,按以下步骤执行:
LS 检查目标技能目录,确认 scripts/ 目录存在node $SKILL_DIR/scripts/check.js --target <目标技能绝对路径> 执行扫描check.js 会输出完整的问题报告,直接信任其输出Read 读取命中的 JS 文件源码,用 SearchReplace 精准修复上下文节约原则:扫描阶段不得用
Read读取目标技能的 JS 文件源码,直接信任check.js输出。仅当用户确认修复后,AI 才读取需要修改的文件。修复前必须确认:修复会修改源码,运行前必须获得用户明确确认。严禁未经确认直接修复。
避免重复注入:同一文件若有多处路径定位问题,
findSkillRootDir辅助函数只注入一次,后续问题复用该函数。这正是采用 AI 修复而非脚本修复的原因--脚本能机械替换但会重复注入,AI 可统筹整文件去重。
| 场景 | 判断条件 | 执行操作 |
| ------------------------ | -------------------------------------- | ------------------------------------ |
| 目标无 scripts/ 目录 | LS 返回目录不存在 | 报错,提示用户确认目标技能路径 |
| scripts/ 目录无 .js 文件 | check.js 输出"未找到 JS 文件" | 提示用户无可检查的文件 |
| 未发现问题 | check.js 输出"✅ 未发现路径定位问题" | 告知用户代码安全,无需修复 |
| 发现问题,用户未确认修复 | 用户说"先不修复"或未回应 | 仅输出报告,不修复 |
| 发现问题,用户确认修复 | 用户说"修复"、"处理"、"确认" | AI 读取源码并用 SearchReplace 修复 |
🔍 路径定位问题扫描报告
目标技能:d:\skill\private-skills\.trae\skills\wechat-publisher-yashu
扫描文件:5 个
发现问题:3 处
──────────────────────────────────────
📄 文件:scripts-backup/tools/theme.js
──────────────────────────────────────
[模式1] 第 18 行:__dirname + path.join 组合
代码: return path.join(__dirname, "..", "..", "themes");
风险: 打包后 __dirname 变化,路径失效
建议: 改为基于技能根目录(SKILL.md)定位
[模式2] 第 46 行:__dirname 直接使用
代码: const themePath = path.join(themesDir, `${themeName}.json`);
风险: 依赖 themesDir 的定位,间接依赖 __dirname
建议: 确认 themesDir 已修复为基于技能根目录
──────────────────────────────────────
📄 文件:scripts-backup/index.js
──────────────────────────────────────
[模式3] 第 121 行:fs 操作中的相对路径
代码: TOKEN_FILE_PATH: path.join(__dirname, "../", "wechat-token.json"),
风险: 依赖 __dirname 定位 token 文件
建议: 改为基于技能根目录定位
⚠️ 可能误报:如果 token 文件随 bundle 移动则无问题
──────────────────────────────────────
是否需要修复这些问题?(回复"修复"或"是"以确认)
运行 check.js 时支持以下选项:
| 选项 | 说明 | 默认值 |
| ---------------------- | --------------------------------------------------------------- | --------- |
| --target <path> | 目标技能目录路径(必须) | - |
| --scripts-dir <name> | 脚本目录名 | scripts |
| --mode <mode> | 检测模式:precise(精准)/ extended(扩展)/ deep(深度) | deep |
SearchReplace 完成,不再依赖 fix.js 脚本。AI 可统筹整文件,避免辅助函数重复注入.js 文件,不处理 .ts、.mjs、.cjsnode_modules、scripts-backup、scripts-backup-path-fix、.gitSKILL.md 定位技能根目录"的策略,不提供其他策略选项process.cwd() 作为默认基准:process.cwd() 在加密混淆前后可能变化,资源定位应统一基于 SKILL_ROOT(见上文"为什么不要使用 process.cwd() 作为默认基准")content-media
自动启停视频课程录制所需的辅助程序。激活条件:用户消息须包含以下关键词之一:`我要录制视频课程`、`开始录制视频课程`、`准备录课`、`视频课程录完了`、`录课结束`、`停止录制`。
content-media
生成扁平的 SVG 图(架构图、中心辐射图、流程图、简易时序图、思维导图、组织架构图、2×2对比矩阵、时间线、循环图、鱼骨图),也支持把已有 SVG 文件转成 PNG 图片。激活条件(满足任一即可):生成类关键词 `画架构图`、`画中心辐射图`、`画流程图`、`画时序图`、`画思维导图`、`画脑图`、`画组织架构图`、`画树形图`、`画对比矩阵`、`画四象限`、`画时间线`、`画循环图`、`画鱼骨图`、`画因果分析图`;转换类关键词`SVG 转图片`、`把 SVG 转成图片`、`把 SVG 转成 PNG`。
testing
检查指定技能文档中的废话文字并输出诊断报告。激活条件:用户消息须包含以下关键词之一:`检查技能废话`、`这个技能文档有没有多余内容`、`清理技能文档废话`、`审查技能文档废话`、`清理技能文档历史说明`。
testing
评审一个技能是否「自包含」——即其知识、经验、规范是否全部内置在技能文件内(SKILL.md + references/),不依赖特定 AI 客户端专有的知识接口命令(如 read_me / modules: / show_widget / Visualizer)去外部拉取,也不硬编码某个 AI 软件的私有路径(如 .workbuddy)。同时检查工具依赖(node、浏览器、命令行)是否仅作为用户自备工具声明、未写死私有路径。当用户要求「评审这个技能是否自包含 / 独立」「检查技能知识是否内置」「审查技能的独立性 / 可移植性」「audit / review a skill for self-containment」时触发。产出评审报告:结论(自包含 / 不独立)+ 问题清单(文件:行号 + 引用的外部依赖 + 为何影响独立性)+ 整改建议。