feat: 更新 postinstall 脚本以支持技能链接和文件链接

This commit is contained in:
Hooray
2026-04-01 13:51:39 +08:00
parent 7cf493a6f8
commit 528044ac85
2 changed files with 96 additions and 1 deletions
+1 -1
View File
@@ -16,7 +16,7 @@
"lint:eslint": "eslint . --cache --fix",
"lint:stylelint": "stylelint \"{apps,packages}/**/*.{css,scss,vue}\" --cache --fix",
"preinstall": "npx only-allow pnpm",
"postinstall": "simple-git-hooks",
"postinstall": "simple-git-hooks && tsx scripts/postinstall.ts",
"taze": "taze minor -wIr",
"commit": "git cz",
"release": "bumpp"
+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/env node
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const rootDir = path.resolve(__dirname, '..')
const isWindows = process.platform === 'win32'
const sourceDir = path.resolve(rootDir, '.agents/skills')
const targetDirs = [
'.claude/skills',
// '.other-agent/skills',
]
// 根目录文件链接:[source, link]
const fileLinks = [
['AGENTS.md', 'CLAUDE.md'],
]
function syncSkillLinks() {
if (!fs.existsSync(sourceDir)) {
return
}
const skills = fs.readdirSync(sourceDir, { withFileTypes: true })
.filter(entry => entry.isDirectory())
.map(entry => entry.name)
for (const targetDir of targetDirs) {
const absTargetDir = path.resolve(rootDir, targetDir)
fs.mkdirSync(absTargetDir, { recursive: true })
let created = 0
for (const skill of skills) {
const linkPath = path.join(absTargetDir, skill)
const skillSourcePath = path.join(sourceDir, skill)
// 已存在则先删除(兼容 symlink / junction / 普通目录)
try {
fs.lstatSync(linkPath)
fs.rmSync(linkPath, { recursive: true, force: true })
}
catch {
// 不存在,正常继续创建
}
if (isWindows) {
// Windows 使用 junction(目录联接),无需管理员权限
fs.symlinkSync(skillSourcePath, linkPath, 'junction')
}
else {
// Mac/Linux 使用相对路径软链接
const relativePath = path.relative(absTargetDir, skillSourcePath)
fs.symlinkSync(relativePath, linkPath)
}
created++
}
if (created > 0) {
console.log(`[postinstall] Linked ${created} skill(s) to ${targetDir}/`)
}
}
}
function syncFileLinks() {
for (const [source, link] of fileLinks) {
const sourcePath = path.resolve(rootDir, source)
const linkPath = path.resolve(rootDir, link)
if (!fs.existsSync(sourcePath)) {
console.warn(`[postinstall] Source file not found, skipping: ${source}`)
continue
}
// 已存在则先删除
try {
fs.lstatSync(linkPath)
fs.rmSync(linkPath, { force: true })
}
catch {
// 不存在,正常继续创建
}
const relativePath = isWindows ? sourcePath : path.relative(rootDir, sourcePath)
fs.symlinkSync(relativePath, linkPath, 'file')
console.log(`[postinstall] Linked file: ${link} -> ${source}`)
}
}
syncSkillLinks()
syncFileLinks()