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/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 "$@"