psmgr 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/rules/changelog-rules.md +38 -0
- package/.agents/rules/code-standards-rules.md +74 -0
- package/.agents/rules/project-rules.md +126 -0
- package/.agents/rules/skill-lifecycle-rules.md +34 -0
- package/.agents/rules/skill-scheduling-rules.md +119 -0
- package/.agents/rules/templates/code-standards-go.md +14 -0
- package/.agents/rules/templates/code-standards-node.md +14 -0
- package/.agents/rules/templates/code-standards-python.md +15 -0
- package/.agents/rules/templates/code-standards-rust.md +14 -0
- package/.agents/rules/templates/project-rules-base.md +119 -0
- package/.agents/rules/version-management-rules.md +85 -0
- package/.agents/skills/INDEX.md +160 -0
- package/.agents/skills/generating-changelogs/SKILL.md +87 -0
- package/.agents/skills/installing-project-skills/SKILL.md +274 -0
- package/.agents/skills/managing-project-skills/SKILL.md +97 -0
- package/.agents/skills/scheduling-project-skills/SKILL.md +70 -0
- package/.agents/skills-config.template.json +21 -0
- package/.agents/skills-registry.json +172 -0
- package/.agents/tools.json +70 -0
- package/LICENSE +21 -0
- package/README.md +133 -0
- package/bin/psm.js +2004 -0
- package/package.json +50 -0
- package/scripts/bootstrap.js +145 -0
- package/scripts/bootstrap.sh +157 -0
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "psmgr",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "PSMgr (Project Skills Manager) — one command to install AI agent skills & rules into any project",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"psmgr",
|
|
8
|
+
"psm",
|
|
9
|
+
"project-skills-manager",
|
|
10
|
+
"ai-skills",
|
|
11
|
+
"project-skills",
|
|
12
|
+
"agent-skills",
|
|
13
|
+
"claude-skills",
|
|
14
|
+
"cursor-skills",
|
|
15
|
+
"windsurf-skills",
|
|
16
|
+
"skills-manager",
|
|
17
|
+
"bootstrap",
|
|
18
|
+
"agent-rules"
|
|
19
|
+
],
|
|
20
|
+
"homepage": "https://github.com/JiunianTV/Le-Skills",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/JiunianTV/Le-Skills/issues"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"author": "JiunianTV",
|
|
26
|
+
"bin": {
|
|
27
|
+
"psm": "bin/psm.js"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"bin/",
|
|
31
|
+
".agents/",
|
|
32
|
+
"scripts/",
|
|
33
|
+
"LICENSE",
|
|
34
|
+
"README.md"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"bootstrap": "node scripts/bootstrap.js",
|
|
38
|
+
"bootstrap:check": "node scripts/bootstrap.js --check"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=18"
|
|
42
|
+
},
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/JiunianTV/Le-Skills.git"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ============================================================
|
|
3
|
+
// bootstrap.js — Cross-platform project detection & guidance
|
|
4
|
+
// ============================================================
|
|
5
|
+
// node scripts/bootstrap.js Detection + guidance
|
|
6
|
+
// node scripts/bootstrap.js --check Just check status, exit 0/1
|
|
7
|
+
// ============================================================
|
|
8
|
+
|
|
9
|
+
import fs from 'node:fs';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const ROOT_DIR = path.resolve(__filename, '../..');
|
|
15
|
+
|
|
16
|
+
// ---- Colour helpers ----
|
|
17
|
+
|
|
18
|
+
function colour(code, text) {
|
|
19
|
+
return process.stdout.isTTY ? `\x1b[${code}m${text}\x1b[0m` : text;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const info = (s) => console.log(colour('0;36', `ℹ ${s}`));
|
|
23
|
+
const ok = (s) => console.log(colour('0;32', `✔ ${s}`));
|
|
24
|
+
const warn = (s) => console.log(colour('1;33', `⚡ ${s}`));
|
|
25
|
+
const err = (s) => console.log(colour('0;31', `✘ ${s}`));
|
|
26
|
+
|
|
27
|
+
// ---- Detection ----
|
|
28
|
+
|
|
29
|
+
function detectProjectType() {
|
|
30
|
+
if (fs.existsSync(path.join(ROOT_DIR, 'package.json'))) return 'node';
|
|
31
|
+
if (fs.existsSync(path.join(ROOT_DIR, 'pyproject.toml'))) return 'python';
|
|
32
|
+
if (fs.existsSync(path.join(ROOT_DIR, 'requirements.txt'))) return 'python';
|
|
33
|
+
if (fs.existsSync(path.join(ROOT_DIR, 'Cargo.toml'))) return 'rust';
|
|
34
|
+
if (fs.existsSync(path.join(ROOT_DIR, 'go.mod'))) return 'go';
|
|
35
|
+
return 'unknown';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function checkSkillsStatus() {
|
|
39
|
+
const skillsDir = path.join(ROOT_DIR, '.agents', 'skills');
|
|
40
|
+
const rulesDir = path.join(ROOT_DIR, '.agents', 'rules');
|
|
41
|
+
|
|
42
|
+
if (!fs.existsSync(skillsDir)) return 'no-skills-dir';
|
|
43
|
+
if (!fs.existsSync(path.join(skillsDir, 'INDEX.md'))) return 'no-index';
|
|
44
|
+
|
|
45
|
+
const count = fs.readdirSync(skillsDir).filter((e) => {
|
|
46
|
+
const skillMd = path.join(skillsDir, e, 'SKILL.md');
|
|
47
|
+
return fs.statSync(path.join(skillsDir, e)).isDirectory() && fs.existsSync(skillMd);
|
|
48
|
+
}).length;
|
|
49
|
+
|
|
50
|
+
if (count === 0) return 'empty';
|
|
51
|
+
|
|
52
|
+
// Check rules
|
|
53
|
+
const rulesCount = fs.existsSync(rulesDir)
|
|
54
|
+
? fs.readdirSync(rulesDir).filter((f) => f.endsWith('.md')).length
|
|
55
|
+
: 0;
|
|
56
|
+
|
|
57
|
+
return { count, rulesCount };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const PROJECT_LABELS = {
|
|
61
|
+
node: 'Node.js / Frontend',
|
|
62
|
+
python: 'Python',
|
|
63
|
+
rust: 'Rust',
|
|
64
|
+
go: 'Go',
|
|
65
|
+
unknown: '未能自动识别',
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// ---- Print guidance ----
|
|
69
|
+
|
|
70
|
+
function printGuidance(projectType, skillsStatus) {
|
|
71
|
+
console.log();
|
|
72
|
+
console.log('============================================');
|
|
73
|
+
console.log(' Project Skills — Bootstrap Report');
|
|
74
|
+
console.log('============================================');
|
|
75
|
+
console.log();
|
|
76
|
+
|
|
77
|
+
// Project type
|
|
78
|
+
const label = PROJECT_LABELS[projectType] || projectType;
|
|
79
|
+
if (projectType === 'unknown') {
|
|
80
|
+
warn(`项目类型: ${label}(未找到 package.json/pyproject.toml/Cargo.toml/go.mod)`);
|
|
81
|
+
} else {
|
|
82
|
+
ok(`项目类型: ${label}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log();
|
|
86
|
+
|
|
87
|
+
// Skills status
|
|
88
|
+
if (typeof skillsStatus === 'string') {
|
|
89
|
+
switch (skillsStatus) {
|
|
90
|
+
case 'no-skills-dir':
|
|
91
|
+
warn('技能尚未安装');
|
|
92
|
+
info('解决方案: 在 IDE 中打开项目,输入「安装技能和规则」即可自动配置');
|
|
93
|
+
break;
|
|
94
|
+
case 'no-index':
|
|
95
|
+
case 'empty':
|
|
96
|
+
warn('技能目录存在但尚未完成安装');
|
|
97
|
+
info('解决方案: 在 IDE 中打开项目,输入「安装技能和规则」即可自动安装');
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
ok(`已安装 ${skillsStatus.count} 个技能`);
|
|
102
|
+
ok(`${skillsStatus.rulesCount} 个规则文件`);
|
|
103
|
+
info('运行以下命令查看技能清单:');
|
|
104
|
+
console.log(` dir ${ROOT_DIR}\\.agents\\skills\\`);
|
|
105
|
+
console.log();
|
|
106
|
+
info('如需更新技能,运行:');
|
|
107
|
+
console.log(' npx psmgr install --yes');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// IDE hints
|
|
111
|
+
console.log();
|
|
112
|
+
console.log('━━━ IDE 使用提示 ━━━');
|
|
113
|
+
console.log();
|
|
114
|
+
console.log(' 支持的 IDE 命令:');
|
|
115
|
+
console.log(' 「安装技能和规则」 — 首次安装/配置');
|
|
116
|
+
console.log(' 「更新技能和规则」 — 升级已有技能');
|
|
117
|
+
console.log(' 「卸载技能 xxx」 — 移除指定技能');
|
|
118
|
+
console.log(' 「查看技能」 — 查看技能状态');
|
|
119
|
+
console.log(' 「更新更新日志为 vx.x.x」 — 生成 CHANGELOG');
|
|
120
|
+
console.log();
|
|
121
|
+
console.log('━━━━━━━━━━━━━━━━━━');
|
|
122
|
+
console.log();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ---- Main ----
|
|
126
|
+
|
|
127
|
+
function main() {
|
|
128
|
+
const args = process.argv.slice(2);
|
|
129
|
+
const checkMode = args.includes('--check');
|
|
130
|
+
|
|
131
|
+
const projectType = detectProjectType();
|
|
132
|
+
const skillsStatus = checkSkillsStatus();
|
|
133
|
+
|
|
134
|
+
// --check mode: just exit with code
|
|
135
|
+
if (checkMode) {
|
|
136
|
+
if (typeof skillsStatus === 'string') {
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
process.exit(0);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
printGuidance(projectType, skillsStatus);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
main();
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ============================================================
|
|
3
|
+
# Project Skills Bootstrap Script
|
|
4
|
+
# ============================================================
|
|
5
|
+
# Detects project type, checks skill installation status,
|
|
6
|
+
# and guides the user to set up skills.
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# bash scripts/bootstrap.sh # Detection + guidance
|
|
10
|
+
# bash scripts/bootstrap.sh --check # Just check status, exit 0/1
|
|
11
|
+
# ============================================================
|
|
12
|
+
# NOTE: A cross-platform Node.js version is also available:
|
|
13
|
+
# node scripts/bootstrap.js
|
|
14
|
+
# ============================================================
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
18
|
+
|
|
19
|
+
# ---- Windows detection ----
|
|
20
|
+
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" || -n "$WINDIR" ]]; then
|
|
21
|
+
echo ""
|
|
22
|
+
echo "============================================"
|
|
23
|
+
echo " Windows detected"
|
|
24
|
+
echo "============================================"
|
|
25
|
+
echo ""
|
|
26
|
+
echo " For better Windows support, use the Node.js version:"
|
|
27
|
+
echo " node scripts/bootstrap.js"
|
|
28
|
+
echo ""
|
|
29
|
+
echo " Or run this script with Git Bash / WSL."
|
|
30
|
+
echo ""
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# ---- Colour helpers ----
|
|
34
|
+
RED='\033[0;31m'
|
|
35
|
+
GREEN='\033[0;32m'
|
|
36
|
+
YELLOW='\033[1;33m'
|
|
37
|
+
CYAN='\033[0;36m'
|
|
38
|
+
NC='\033[0m' # No Color
|
|
39
|
+
|
|
40
|
+
info() { echo -e "${CYAN}ℹ${NC} $1"; }
|
|
41
|
+
ok() { echo -e "${GREEN}✔${NC} $1"; }
|
|
42
|
+
warn() { echo -e "${YELLOW}⚡${NC} $1"; }
|
|
43
|
+
err() { echo -e "${RED}✘${NC} $1"; }
|
|
44
|
+
|
|
45
|
+
# ---- Detect project type ----
|
|
46
|
+
detect_project_type() {
|
|
47
|
+
if [[ -f "$ROOT_DIR/package.json" ]]; then
|
|
48
|
+
echo "node"
|
|
49
|
+
elif [[ -f "$ROOT_DIR/pyproject.toml" ]]; then
|
|
50
|
+
echo "python"
|
|
51
|
+
elif [[ -f "$ROOT_DIR/requirements.txt" ]]; then
|
|
52
|
+
echo "python"
|
|
53
|
+
elif [[ -f "$ROOT_DIR/Cargo.toml" ]]; then
|
|
54
|
+
echo "rust"
|
|
55
|
+
elif [[ -f "$ROOT_DIR/go.mod" ]]; then
|
|
56
|
+
echo "go"
|
|
57
|
+
else
|
|
58
|
+
echo "unknown"
|
|
59
|
+
fi
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# ---- Skill installation status ----
|
|
63
|
+
check_skills_status() {
|
|
64
|
+
local skills_dir="$ROOT_DIR/.agents/skills"
|
|
65
|
+
local rules_dir="$ROOT_DIR/.agents/rules"
|
|
66
|
+
|
|
67
|
+
if [[ ! -d "$skills_dir" ]]; then
|
|
68
|
+
echo "no-skills-dir"
|
|
69
|
+
elif [[ ! -f "$skills_dir/INDEX.md" ]]; then
|
|
70
|
+
echo "no-index"
|
|
71
|
+
else
|
|
72
|
+
local count
|
|
73
|
+
count=$(find "$skills_dir" -maxdepth 2 -name "SKILL.md" 2>/dev/null | wc -l)
|
|
74
|
+
if [[ "$count" -eq 0 ]]; then
|
|
75
|
+
echo "empty"
|
|
76
|
+
else
|
|
77
|
+
echo "installed:$count"
|
|
78
|
+
fi
|
|
79
|
+
fi
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# ---- Print guidance ----
|
|
83
|
+
print_guidance() {
|
|
84
|
+
local project_type="$1"
|
|
85
|
+
local skills_status="$2"
|
|
86
|
+
|
|
87
|
+
echo ""
|
|
88
|
+
echo "============================================"
|
|
89
|
+
echo " Project Skills — Bootstrap Report"
|
|
90
|
+
echo "============================================"
|
|
91
|
+
echo ""
|
|
92
|
+
|
|
93
|
+
# Project type
|
|
94
|
+
case "$project_type" in
|
|
95
|
+
node) ok "项目类型: Node.js / Frontend" ;;
|
|
96
|
+
python) ok "项目类型: Python" ;;
|
|
97
|
+
rust) ok "项目类型: Rust" ;;
|
|
98
|
+
go) ok "项目类型: Go" ;;
|
|
99
|
+
*) warn "项目类型: 未能自动识别(未找到 package.json/pyproject.toml/Cargo.toml/go.mod)" ;;
|
|
100
|
+
esac
|
|
101
|
+
|
|
102
|
+
# Skills status
|
|
103
|
+
echo ""
|
|
104
|
+
case "$skills_status" in
|
|
105
|
+
no-skills-dir)
|
|
106
|
+
warn "技能尚未安装"
|
|
107
|
+
info "解决方案: 在 IDE 中打开项目,输入「安装技能和规则」即可自动配置"
|
|
108
|
+
;;
|
|
109
|
+
no-index|empty)
|
|
110
|
+
warn "技能目录存在但尚未完成安装"
|
|
111
|
+
info "解决方案: 在 IDE 中打开项目,输入「安装技能和规则」即可自动安装"
|
|
112
|
+
;;
|
|
113
|
+
installed:*)
|
|
114
|
+
local count="${skills_status#installed:}"
|
|
115
|
+
ok "已安装 ${count} 个技能"
|
|
116
|
+
info "查看技能清单:"
|
|
117
|
+
echo " ls ${ROOT_DIR}/.agents/skills/"
|
|
118
|
+
info "如需更新技能,在 IDE 中输入「更新技能和规则」或运行:"
|
|
119
|
+
echo " npx psmgr install --yes"
|
|
120
|
+
;;
|
|
121
|
+
esac
|
|
122
|
+
|
|
123
|
+
# IDE hints
|
|
124
|
+
echo ""
|
|
125
|
+
echo "━━━ IDE 使用提示 ━━━"
|
|
126
|
+
echo ""
|
|
127
|
+
echo " 支持的 IDE 命令:"
|
|
128
|
+
echo " 「安装技能和规则」 — 首次安装/配置"
|
|
129
|
+
echo " 「更新技能和规则」 — 升级已有技能"
|
|
130
|
+
echo " 「卸载技能 xxx」 — 移除指定技能"
|
|
131
|
+
echo " 「查看技能」 — 查看技能状态"
|
|
132
|
+
echo " 「更新更新日志为 vx.x.x」 — 生成 CHANGELOG"
|
|
133
|
+
echo ""
|
|
134
|
+
echo "━━━━━━━━━━━━━━━━━━"
|
|
135
|
+
echo ""
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# ---- Main ----
|
|
139
|
+
main() {
|
|
140
|
+
local project_type
|
|
141
|
+
project_type=$(detect_project_type)
|
|
142
|
+
|
|
143
|
+
local skills_status
|
|
144
|
+
skills_status=$(check_skills_status)
|
|
145
|
+
|
|
146
|
+
# --check mode: just exit with status
|
|
147
|
+
if [[ "${1:-}" == "--check" ]]; then
|
|
148
|
+
case "$skills_status" in
|
|
149
|
+
no-skills-dir|no-index|empty) exit 1 ;;
|
|
150
|
+
*) exit 0 ;;
|
|
151
|
+
esac
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
print_guidance "$project_type" "$skills_status"
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
main "$@"
|