@yottameta/yotta-guardian 0.1.1 → 0.1.3
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/CHANGELOG.md +19 -3
- package/LICENSE +20 -20
- package/README.md +151 -163
- package/README.zh-CN.md +39 -51
- package/SKILL.md +5 -3
- package/bin/install.js +162 -162
- package/install.sh +131 -131
- package/package.json +6 -2
- package/scripts/yotta_guardian.py +1 -1
- package/skill-manifest.json +33 -0
- package/scripts/test_yotta_guardian.py +0 -454
package/bin/install.js
CHANGED
|
@@ -1,163 +1,163 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* yotta-guardian 跨平台安装器(YottaSkills)
|
|
4
|
-
* 用法:
|
|
5
|
-
* npx -y @yottameta/yotta-guardian --agent <name> # 按智能体默认用户级目录安装(推荐)
|
|
6
|
-
* npx -y @yottameta/yotta-guardian --dir PATH # 装到指定目录(用户改了目录的智能体)
|
|
7
|
-
* npx -y @yottameta/yotta-guardian -g # 安装到全部已知智能体用户级目录
|
|
8
|
-
* npx -y @yottameta/yotta-guardian # 安装到检测到的项目级目录
|
|
9
|
-
* npx -y @yottameta/yotta-guardian --list # 列出智能体 -> 默认目录
|
|
10
|
-
*/
|
|
11
|
-
'use strict';
|
|
12
|
-
const fs = require('fs');
|
|
13
|
-
const path = require('path');
|
|
14
|
-
const os = require('os');
|
|
15
|
-
|
|
16
|
-
const SKILL_NAME = 'yotta-guardian';
|
|
17
|
-
const PKG_ROOT = path.join(__dirname, '..');
|
|
18
|
-
|
|
19
|
-
// 智能体 -> 用户级默认技能目录(dirs 按优先级排列;--agent 装到第一个)
|
|
20
|
-
// 依据官方文档:.agents/skills 并非通用目录,被 OpenCode / Cursor / Cline / Amp /
|
|
21
|
-
// Kimi / Gemini CLI / GitHub Copilot 等读取;Claude Code 与 Codex 默认不读 .agents。
|
|
22
|
-
const AGENT_DIRS = {
|
|
23
|
-
claude: { label: 'Claude Code', dirs: ['.claude/skills'] },
|
|
24
|
-
cursor: { label: 'Cursor', dirs: ['.cursor/skills', '.agents/skills'] },
|
|
25
|
-
codex: { label: 'Codex', dirs: ['.codex/skills'] }, // 特判:$CODEX_HOME/skills
|
|
26
|
-
gemini: { label: 'Gemini CLI', dirs: ['.gemini/skills', '.agents/skills'] },
|
|
27
|
-
goose: { label: 'Goose', dirs: ['.config/goose/skills', '.agents/skills'] },
|
|
28
|
-
amp: { label: 'Amp', dirs: ['.config/agents/skills', '.agents/skills'] },
|
|
29
|
-
opencode: { label: 'OpenCode', dirs: ['.config/opencode/skills'] }, // 特判:$XDG_CONFIG_HOME
|
|
30
|
-
windsurf: { label: 'Windsurf', dirs: ['.codeium/windsurf/skills'] },
|
|
31
|
-
workbuddy: { label: 'WorkBuddy', dirs: ['.workbuddy/skills'] },
|
|
32
|
-
kiro: { label: 'Kiro', dirs: ['.kiro/skills'] },
|
|
33
|
-
trae: { label: 'Trae Code CLI', dirs: ['.traecli/skills'] },
|
|
34
|
-
'trae-cn': { label: 'Trae IDE(国内)', dirs: ['.trae-cn/skills'] },
|
|
35
|
-
qwen: { label: 'Qwen Code', dirs: ['.qwen/skills'] },
|
|
36
|
-
comate: { label: 'Comate 文心快码', dirs: ['.comate/skills'] },
|
|
37
|
-
codebuddy: { label: 'CodeBuddy Code', dirs: ['.codebuddy/skills'] },
|
|
38
|
-
kimi: { label: 'Kimi Code CLI', dirs: ['.kimi/skills'] },
|
|
39
|
-
agents: { label: '通用 AGENTS.md', dirs: ['.agents/skills'] },
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
// Codex 用户级目录特判:优先 $CODEX_HOME/skills,否则 ~/.codex/skills
|
|
43
|
-
function codexUserDir() {
|
|
44
|
-
const base = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
45
|
-
return path.join(base, 'skills');
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// OpenCode 用户级目录特判:优先 $XDG_CONFIG_HOME/opencode/skills,否则 ~/.config/opencode/skills
|
|
49
|
-
function opencodeUserDir() {
|
|
50
|
-
const base = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
|
|
51
|
-
return path.join(base, 'opencode', 'skills');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function resolveUserDir(rel) {
|
|
55
|
-
if (rel === '.codex/skills') return codexUserDir();
|
|
56
|
-
if (rel === '.config/opencode/skills') return opencodeUserDir();
|
|
57
|
-
return path.join(os.homedir(), rel);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function installTo(dest) {
|
|
61
|
-
const target = path.join(dest, SKILL_NAME);
|
|
62
|
-
fs.mkdirSync(target, { recursive: true });
|
|
63
|
-
copyDir(PKG_ROOT, target, new Set(['package.json', 'bin', 'node_modules', '.git']));
|
|
64
|
-
console.log('installed -> ' + target);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function copyDir(src, dst, skip) {
|
|
68
|
-
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
69
|
-
if (skip.has(entry.name)) continue;
|
|
70
|
-
const s = path.join(src, entry.name);
|
|
71
|
-
const d = path.join(dst, entry.name);
|
|
72
|
-
if (entry.isDirectory()) {
|
|
73
|
-
fs.mkdirSync(d, { recursive: true });
|
|
74
|
-
copyDir(s, d, skip);
|
|
75
|
-
} else if (entry.isFile()) {
|
|
76
|
-
fs.copyFileSync(s, d);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function displayDir(rel) {
|
|
82
|
-
if (process.platform === 'win32') return '%USERPROFILE%\\' + rel.replace(/\//g, '\\');
|
|
83
|
-
return '~/' + rel;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function main() {
|
|
87
|
-
const args = process.argv.slice(2);
|
|
88
|
-
const isGlobal = args.includes('-g') || args.includes('--global');
|
|
89
|
-
const list = args.includes('--list') || args.includes('-l');
|
|
90
|
-
let explicitDir = null;
|
|
91
|
-
const di = args.indexOf('--dir');
|
|
92
|
-
if (di !== -1 && args[di + 1]) explicitDir = args[di + 1];
|
|
93
|
-
let agent = null;
|
|
94
|
-
const ai = args.indexOf('--agent');
|
|
95
|
-
if (ai !== -1 && args[ai + 1]) agent = String(args[ai + 1]).toLowerCase();
|
|
96
|
-
|
|
97
|
-
if (list) {
|
|
98
|
-
console.log('智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):');
|
|
99
|
-
for (const [key, v] of Object.entries(AGENT_DIRS)) {
|
|
100
|
-
const resolved = v.dirs.map(displayDir);
|
|
101
|
-
console.log(' ' + key.padEnd(10) + v.label.padEnd(18) + resolved.join('、'));
|
|
102
|
-
}
|
|
103
|
-
console.log('\n说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。');
|
|
104
|
-
console.log('改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。');
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (explicitDir) { installTo(explicitDir); return; }
|
|
109
|
-
|
|
110
|
-
if (agent) {
|
|
111
|
-
const info = AGENT_DIRS[agent];
|
|
112
|
-
if (!info) {
|
|
113
|
-
console.log('未收录智能体: ' + agent + '。请用 --dir <路径> 指定技能目录。');
|
|
114
|
-
console.log('可用: ' + Object.keys(AGENT_DIRS).join(', '));
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
installTo(resolveUserDir(info.dirs[0]));
|
|
118
|
-
console.log('完成。');
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (isGlobal) {
|
|
123
|
-
const seen = new Set();
|
|
124
|
-
for (const v of Object.values(AGENT_DIRS)) {
|
|
125
|
-
for (const d of v.dirs) {
|
|
126
|
-
if (seen.has(d)) continue;
|
|
127
|
-
seen.add(d);
|
|
128
|
-
installTo(resolveUserDir(d));
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
console.log('完成。');
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const PROJECT_DIRS = [
|
|
136
|
-
'.claude/skills',
|
|
137
|
-
'.cursor/skills',
|
|
138
|
-
'.codex/skills',
|
|
139
|
-
'.config/goose/skills',
|
|
140
|
-
'.config/agents/skills',
|
|
141
|
-
'.opencode/skills',
|
|
142
|
-
'.codeium/windsurf/skills',
|
|
143
|
-
'.workbuddy/skills',
|
|
144
|
-
'.kiro/skills',
|
|
145
|
-
'.traecli/skills',
|
|
146
|
-
'.gemini/skills',
|
|
147
|
-
'.trae-cn/skills',
|
|
148
|
-
'.qwen/skills',
|
|
149
|
-
'.comate/skills',
|
|
150
|
-
'.codebuddy/skills',
|
|
151
|
-
'.kimi/skills',
|
|
152
|
-
'.agents/skills',
|
|
153
|
-
];
|
|
154
|
-
let installedAny = false;
|
|
155
|
-
for (const d of PROJECT_DIRS) {
|
|
156
|
-
if (fs.existsSync(d)) { installTo(d); installedAny = true; }
|
|
157
|
-
}
|
|
158
|
-
if (!installedAny) {
|
|
159
|
-
console.log('未检测到项目级智能体目录。可手动复制,或用 --agent <name> / -g 装到用户级。');
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* yotta-guardian 跨平台安装器(YottaSkills)
|
|
4
|
+
* 用法:
|
|
5
|
+
* npx -y @yottameta/yotta-guardian --agent <name> # 按智能体默认用户级目录安装(推荐)
|
|
6
|
+
* npx -y @yottameta/yotta-guardian --dir PATH # 装到指定目录(用户改了目录的智能体)
|
|
7
|
+
* npx -y @yottameta/yotta-guardian -g # 安装到全部已知智能体用户级目录
|
|
8
|
+
* npx -y @yottameta/yotta-guardian # 安装到检测到的项目级目录
|
|
9
|
+
* npx -y @yottameta/yotta-guardian --list # 列出智能体 -> 默认目录
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const os = require('os');
|
|
15
|
+
|
|
16
|
+
const SKILL_NAME = 'yotta-guardian';
|
|
17
|
+
const PKG_ROOT = path.join(__dirname, '..');
|
|
18
|
+
|
|
19
|
+
// 智能体 -> 用户级默认技能目录(dirs 按优先级排列;--agent 装到第一个)
|
|
20
|
+
// 依据官方文档:.agents/skills 并非通用目录,被 OpenCode / Cursor / Cline / Amp /
|
|
21
|
+
// Kimi / Gemini CLI / GitHub Copilot 等读取;Claude Code 与 Codex 默认不读 .agents。
|
|
22
|
+
const AGENT_DIRS = {
|
|
23
|
+
claude: { label: 'Claude Code', dirs: ['.claude/skills'] },
|
|
24
|
+
cursor: { label: 'Cursor', dirs: ['.cursor/skills', '.agents/skills'] },
|
|
25
|
+
codex: { label: 'Codex', dirs: ['.codex/skills'] }, // 特判:$CODEX_HOME/skills
|
|
26
|
+
gemini: { label: 'Gemini CLI', dirs: ['.gemini/skills', '.agents/skills'] },
|
|
27
|
+
goose: { label: 'Goose', dirs: ['.config/goose/skills', '.agents/skills'] },
|
|
28
|
+
amp: { label: 'Amp', dirs: ['.config/agents/skills', '.agents/skills'] },
|
|
29
|
+
opencode: { label: 'OpenCode', dirs: ['.config/opencode/skills'] }, // 特判:$XDG_CONFIG_HOME
|
|
30
|
+
windsurf: { label: 'Windsurf', dirs: ['.codeium/windsurf/skills'] },
|
|
31
|
+
workbuddy: { label: 'WorkBuddy', dirs: ['.workbuddy/skills'] },
|
|
32
|
+
kiro: { label: 'Kiro', dirs: ['.kiro/skills'] },
|
|
33
|
+
trae: { label: 'Trae Code CLI', dirs: ['.traecli/skills'] },
|
|
34
|
+
'trae-cn': { label: 'Trae IDE(国内)', dirs: ['.trae-cn/skills'] },
|
|
35
|
+
qwen: { label: 'Qwen Code', dirs: ['.qwen/skills'] },
|
|
36
|
+
comate: { label: 'Comate 文心快码', dirs: ['.comate/skills'] },
|
|
37
|
+
codebuddy: { label: 'CodeBuddy Code', dirs: ['.codebuddy/skills'] },
|
|
38
|
+
kimi: { label: 'Kimi Code CLI', dirs: ['.kimi/skills'] },
|
|
39
|
+
agents: { label: '通用 AGENTS.md', dirs: ['.agents/skills'] },
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Codex 用户级目录特判:优先 $CODEX_HOME/skills,否则 ~/.codex/skills
|
|
43
|
+
function codexUserDir() {
|
|
44
|
+
const base = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
45
|
+
return path.join(base, 'skills');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// OpenCode 用户级目录特判:优先 $XDG_CONFIG_HOME/opencode/skills,否则 ~/.config/opencode/skills
|
|
49
|
+
function opencodeUserDir() {
|
|
50
|
+
const base = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
|
|
51
|
+
return path.join(base, 'opencode', 'skills');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function resolveUserDir(rel) {
|
|
55
|
+
if (rel === '.codex/skills') return codexUserDir();
|
|
56
|
+
if (rel === '.config/opencode/skills') return opencodeUserDir();
|
|
57
|
+
return path.join(os.homedir(), rel);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function installTo(dest) {
|
|
61
|
+
const target = path.join(dest, SKILL_NAME);
|
|
62
|
+
fs.mkdirSync(target, { recursive: true });
|
|
63
|
+
copyDir(PKG_ROOT, target, new Set(['package.json', 'bin', 'node_modules', '.git']));
|
|
64
|
+
console.log('installed -> ' + target);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function copyDir(src, dst, skip) {
|
|
68
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
69
|
+
if (skip.has(entry.name)) continue;
|
|
70
|
+
const s = path.join(src, entry.name);
|
|
71
|
+
const d = path.join(dst, entry.name);
|
|
72
|
+
if (entry.isDirectory()) {
|
|
73
|
+
fs.mkdirSync(d, { recursive: true });
|
|
74
|
+
copyDir(s, d, skip);
|
|
75
|
+
} else if (entry.isFile()) {
|
|
76
|
+
fs.copyFileSync(s, d);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function displayDir(rel) {
|
|
82
|
+
if (process.platform === 'win32') return '%USERPROFILE%\\' + rel.replace(/\//g, '\\');
|
|
83
|
+
return '~/' + rel;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function main() {
|
|
87
|
+
const args = process.argv.slice(2);
|
|
88
|
+
const isGlobal = args.includes('-g') || args.includes('--global');
|
|
89
|
+
const list = args.includes('--list') || args.includes('-l');
|
|
90
|
+
let explicitDir = null;
|
|
91
|
+
const di = args.indexOf('--dir');
|
|
92
|
+
if (di !== -1 && args[di + 1]) explicitDir = args[di + 1];
|
|
93
|
+
let agent = null;
|
|
94
|
+
const ai = args.indexOf('--agent');
|
|
95
|
+
if (ai !== -1 && args[ai + 1]) agent = String(args[ai + 1]).toLowerCase();
|
|
96
|
+
|
|
97
|
+
if (list) {
|
|
98
|
+
console.log('智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):');
|
|
99
|
+
for (const [key, v] of Object.entries(AGENT_DIRS)) {
|
|
100
|
+
const resolved = v.dirs.map(displayDir);
|
|
101
|
+
console.log(' ' + key.padEnd(10) + v.label.padEnd(18) + resolved.join('、'));
|
|
102
|
+
}
|
|
103
|
+
console.log('\n说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。');
|
|
104
|
+
console.log('改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (explicitDir) { installTo(explicitDir); return; }
|
|
109
|
+
|
|
110
|
+
if (agent) {
|
|
111
|
+
const info = AGENT_DIRS[agent];
|
|
112
|
+
if (!info) {
|
|
113
|
+
console.log('未收录智能体: ' + agent + '。请用 --dir <路径> 指定技能目录。');
|
|
114
|
+
console.log('可用: ' + Object.keys(AGENT_DIRS).join(', '));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
installTo(resolveUserDir(info.dirs[0]));
|
|
118
|
+
console.log('完成。');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (isGlobal) {
|
|
123
|
+
const seen = new Set();
|
|
124
|
+
for (const v of Object.values(AGENT_DIRS)) {
|
|
125
|
+
for (const d of v.dirs) {
|
|
126
|
+
if (seen.has(d)) continue;
|
|
127
|
+
seen.add(d);
|
|
128
|
+
installTo(resolveUserDir(d));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
console.log('完成。');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const PROJECT_DIRS = [
|
|
136
|
+
'.claude/skills',
|
|
137
|
+
'.cursor/skills',
|
|
138
|
+
'.codex/skills',
|
|
139
|
+
'.config/goose/skills',
|
|
140
|
+
'.config/agents/skills',
|
|
141
|
+
'.opencode/skills',
|
|
142
|
+
'.codeium/windsurf/skills',
|
|
143
|
+
'.workbuddy/skills',
|
|
144
|
+
'.kiro/skills',
|
|
145
|
+
'.traecli/skills',
|
|
146
|
+
'.gemini/skills',
|
|
147
|
+
'.trae-cn/skills',
|
|
148
|
+
'.qwen/skills',
|
|
149
|
+
'.comate/skills',
|
|
150
|
+
'.codebuddy/skills',
|
|
151
|
+
'.kimi/skills',
|
|
152
|
+
'.agents/skills',
|
|
153
|
+
];
|
|
154
|
+
let installedAny = false;
|
|
155
|
+
for (const d of PROJECT_DIRS) {
|
|
156
|
+
if (fs.existsSync(d)) { installTo(d); installedAny = true; }
|
|
157
|
+
}
|
|
158
|
+
if (!installedAny) {
|
|
159
|
+
console.log('未检测到项目级智能体目录。可手动复制,或用 --agent <name> / -g 装到用户级。');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
163
|
main();
|
package/install.sh
CHANGED
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# yotta-guardian 多智能体安装脚本(YottaSkills 模板)
|
|
3
|
-
# 用法:
|
|
4
|
-
# bash install.sh --agent <name> # 按智能体默认用户级目录安装
|
|
5
|
-
# bash install.sh --dir <path> # 装到指定目录(用户改过目录的智能体)
|
|
6
|
-
# bash install.sh -g # 装到全部已知智能体用户级目录
|
|
7
|
-
# bash install.sh # 检测并安装到已存在的项目级目录
|
|
8
|
-
# bash install.sh --list # 列出智能体 -> 默认目录
|
|
9
|
-
set -euo pipefail
|
|
10
|
-
|
|
11
|
-
SKILL_NAME="yotta-guardian"
|
|
12
|
-
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
-
case "$(uname -s)" in
|
|
14
|
-
MINGW*|MSYS*)
|
|
15
|
-
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -W)"
|
|
16
|
-
;;
|
|
17
|
-
esac
|
|
18
|
-
|
|
19
|
-
# 智能体 -> 用户级默认目录(--agent 装到第一个)
|
|
20
|
-
# .agents/skills 并非通用目录:OpenCode / Cursor / Cline / Amp / Kimi / Gemini CLI / GitHub Copilot 读取。
|
|
21
|
-
# 判断当前环境:Windows Git Bash 用 %USERPROFILE%,Unix 用 ~
|
|
22
|
-
_IS_WINDOWS=0
|
|
23
|
-
case "$(uname -s)" in
|
|
24
|
-
MINGW*|MSYS*|CYGWIN*) _IS_WINDOWS=1 ;;
|
|
25
|
-
esac
|
|
26
|
-
dirs_for() {
|
|
27
|
-
case "$1" in
|
|
28
|
-
claude) echo ".claude/skills" ;;
|
|
29
|
-
cursor) echo ".cursor/skills .agents/skills" ;;
|
|
30
|
-
codex) echo "__CODEX__" ;;
|
|
31
|
-
gemini) echo ".gemini/skills .agents/skills" ;;
|
|
32
|
-
goose) echo ".config/goose/skills .agents/skills" ;;
|
|
33
|
-
amp) echo ".config/agents/skills .agents/skills" ;;
|
|
34
|
-
opencode) echo "__OPENCODE__" ;;
|
|
35
|
-
windsurf) echo ".codeium/windsurf/skills" ;;
|
|
36
|
-
workbuddy) echo ".workbuddy/skills" ;;
|
|
37
|
-
kiro) echo ".kiro/skills" ;;
|
|
38
|
-
trae) echo ".traecli/skills" ;;
|
|
39
|
-
trae-cn) echo ".trae-cn/skills" ;;
|
|
40
|
-
qwen) echo ".qwen/skills" ;;
|
|
41
|
-
comate) echo ".comate/skills" ;;
|
|
42
|
-
codebuddy) echo ".codebuddy/skills" ;;
|
|
43
|
-
kimi) echo ".kimi/skills" ;;
|
|
44
|
-
agents) echo ".agents/skills" ;;
|
|
45
|
-
*) return 1 ;;
|
|
46
|
-
esac
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
codex_dir() {
|
|
50
|
-
if [ -n "${CODEX_HOME:-}" ]; then printf '%s' "$CODEX_HOME/skills"; else printf '%s' "$HOME/.codex/skills"; fi
|
|
51
|
-
}
|
|
52
|
-
opencode_dir() {
|
|
53
|
-
if [ -n "${XDG_CONFIG_HOME:-}" ]; then printf '%s' "$XDG_CONFIG_HOME/opencode/skills"; else printf '%s' "$HOME/.config/opencode/skills"; fi
|
|
54
|
-
}
|
|
55
|
-
resolve_user() {
|
|
56
|
-
case "$1" in
|
|
57
|
-
__CODEX__) codex_dir ;;
|
|
58
|
-
__OPENCODE__) opencode_dir ;;
|
|
59
|
-
*) printf '%s' "$HOME/$1" ;;
|
|
60
|
-
esac
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
install_to() {
|
|
64
|
-
mkdir -p "$1/$SKILL_NAME"
|
|
65
|
-
cp -r "$SOURCE_DIR/." "$1/$SKILL_NAME/"
|
|
66
|
-
rm -rf "$1/$SKILL_NAME/.git"
|
|
67
|
-
echo "installed -> $1/$SKILL_NAME"
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
list() {
|
|
71
|
-
echo "智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):"
|
|
72
|
-
for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
|
|
73
|
-
local dirs first
|
|
74
|
-
dirs="$(dirs_for "$a")"
|
|
75
|
-
first="${dirs%% *}"
|
|
76
|
-
case "$first" in
|
|
77
|
-
__CODEX__) first=".codex/skills" ;;
|
|
78
|
-
__OPENCODE__) first=".config/opencode/skills" ;;
|
|
79
|
-
esac
|
|
80
|
-
if [ "$_IS_WINDOWS" = "1" ]; then
|
|
81
|
-
first="%USERPROFILE%\\${first//\//\\}"
|
|
82
|
-
else
|
|
83
|
-
first="~/$first"
|
|
84
|
-
fi
|
|
85
|
-
printf ' %-10s %s\n' "$a" "$first"
|
|
86
|
-
done
|
|
87
|
-
echo '说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。'
|
|
88
|
-
echo '改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。'
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
main() {
|
|
92
|
-
local agent="" dir="" global=0 show_list=0
|
|
93
|
-
while [ $# -gt 0 ]; do
|
|
94
|
-
case "$1" in
|
|
95
|
-
--agent) shift; agent="${1:-}" ;;
|
|
96
|
-
--dir) shift; dir="${1:-}" ;;
|
|
97
|
-
-g|--global) global=1 ;;
|
|
98
|
-
--list|-l) show_list=1 ;;
|
|
99
|
-
*) echo "未知参数: $1" >&2; exit 2 ;;
|
|
100
|
-
esac
|
|
101
|
-
shift
|
|
102
|
-
done
|
|
103
|
-
|
|
104
|
-
if [ "$show_list" = "1" ]; then list; return; fi
|
|
105
|
-
if [ -n "$dir" ]; then install_to "$dir"; echo "完成。"; return; fi
|
|
106
|
-
if [ -n "$agent" ]; then
|
|
107
|
-
local dirs first
|
|
108
|
-
if ! dirs="$(dirs_for "$agent")"; then
|
|
109
|
-
echo "未收录智能体: $agent。请用 --dir <路径> 指定技能目录。" >&2; exit 2
|
|
110
|
-
fi
|
|
111
|
-
first="${dirs%% *}"
|
|
112
|
-
install_to "$(resolve_user "$first")"; echo "完成。"; return
|
|
113
|
-
fi
|
|
114
|
-
if [ "$global" = "1" ]; then
|
|
115
|
-
echo "安装到全部已知智能体用户级目录..."
|
|
116
|
-
local dirs rel
|
|
117
|
-
for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
|
|
118
|
-
dirs="$(dirs_for "$a")"
|
|
119
|
-
for rel in $dirs; do install_to "$(resolve_user "$rel")"; done
|
|
120
|
-
done
|
|
121
|
-
echo "完成。"; return
|
|
122
|
-
fi
|
|
123
|
-
local installed=0 d
|
|
124
|
-
for d in .claude/skills .cursor/skills .codex/skills .config/goose/skills .config/agents/skills .opencode/skills .codeium/windsurf/skills .workbuddy/skills .kiro/skills .traecli/skills .gemini/skills .trae-cn/skills .qwen/skills .comate/skills .codebuddy/skills .kimi/skills .agents/skills; do
|
|
125
|
-
if [ -d "$d" ]; then install_to "$d"; installed=1; fi
|
|
126
|
-
done
|
|
127
|
-
if [ "$installed" = "0" ]; then
|
|
128
|
-
echo "未检测到项目级智能体目录。可用 --agent <name> / -g 装到用户级,或 --dir 指定。"
|
|
129
|
-
fi
|
|
130
|
-
}
|
|
131
|
-
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# yotta-guardian 多智能体安装脚本(YottaSkills 模板)
|
|
3
|
+
# 用法:
|
|
4
|
+
# bash install.sh --agent <name> # 按智能体默认用户级目录安装
|
|
5
|
+
# bash install.sh --dir <path> # 装到指定目录(用户改过目录的智能体)
|
|
6
|
+
# bash install.sh -g # 装到全部已知智能体用户级目录
|
|
7
|
+
# bash install.sh # 检测并安装到已存在的项目级目录
|
|
8
|
+
# bash install.sh --list # 列出智能体 -> 默认目录
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
SKILL_NAME="yotta-guardian"
|
|
12
|
+
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
case "$(uname -s)" in
|
|
14
|
+
MINGW*|MSYS*)
|
|
15
|
+
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -W)"
|
|
16
|
+
;;
|
|
17
|
+
esac
|
|
18
|
+
|
|
19
|
+
# 智能体 -> 用户级默认目录(--agent 装到第一个)
|
|
20
|
+
# .agents/skills 并非通用目录:OpenCode / Cursor / Cline / Amp / Kimi / Gemini CLI / GitHub Copilot 读取。
|
|
21
|
+
# 判断当前环境:Windows Git Bash 用 %USERPROFILE%,Unix 用 ~
|
|
22
|
+
_IS_WINDOWS=0
|
|
23
|
+
case "$(uname -s)" in
|
|
24
|
+
MINGW*|MSYS*|CYGWIN*) _IS_WINDOWS=1 ;;
|
|
25
|
+
esac
|
|
26
|
+
dirs_for() {
|
|
27
|
+
case "$1" in
|
|
28
|
+
claude) echo ".claude/skills" ;;
|
|
29
|
+
cursor) echo ".cursor/skills .agents/skills" ;;
|
|
30
|
+
codex) echo "__CODEX__" ;;
|
|
31
|
+
gemini) echo ".gemini/skills .agents/skills" ;;
|
|
32
|
+
goose) echo ".config/goose/skills .agents/skills" ;;
|
|
33
|
+
amp) echo ".config/agents/skills .agents/skills" ;;
|
|
34
|
+
opencode) echo "__OPENCODE__" ;;
|
|
35
|
+
windsurf) echo ".codeium/windsurf/skills" ;;
|
|
36
|
+
workbuddy) echo ".workbuddy/skills" ;;
|
|
37
|
+
kiro) echo ".kiro/skills" ;;
|
|
38
|
+
trae) echo ".traecli/skills" ;;
|
|
39
|
+
trae-cn) echo ".trae-cn/skills" ;;
|
|
40
|
+
qwen) echo ".qwen/skills" ;;
|
|
41
|
+
comate) echo ".comate/skills" ;;
|
|
42
|
+
codebuddy) echo ".codebuddy/skills" ;;
|
|
43
|
+
kimi) echo ".kimi/skills" ;;
|
|
44
|
+
agents) echo ".agents/skills" ;;
|
|
45
|
+
*) return 1 ;;
|
|
46
|
+
esac
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
codex_dir() {
|
|
50
|
+
if [ -n "${CODEX_HOME:-}" ]; then printf '%s' "$CODEX_HOME/skills"; else printf '%s' "$HOME/.codex/skills"; fi
|
|
51
|
+
}
|
|
52
|
+
opencode_dir() {
|
|
53
|
+
if [ -n "${XDG_CONFIG_HOME:-}" ]; then printf '%s' "$XDG_CONFIG_HOME/opencode/skills"; else printf '%s' "$HOME/.config/opencode/skills"; fi
|
|
54
|
+
}
|
|
55
|
+
resolve_user() {
|
|
56
|
+
case "$1" in
|
|
57
|
+
__CODEX__) codex_dir ;;
|
|
58
|
+
__OPENCODE__) opencode_dir ;;
|
|
59
|
+
*) printf '%s' "$HOME/$1" ;;
|
|
60
|
+
esac
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
install_to() {
|
|
64
|
+
mkdir -p "$1/$SKILL_NAME"
|
|
65
|
+
cp -r "$SOURCE_DIR/." "$1/$SKILL_NAME/"
|
|
66
|
+
rm -rf "$1/$SKILL_NAME/.git"
|
|
67
|
+
echo "installed -> $1/$SKILL_NAME"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
list() {
|
|
71
|
+
echo "智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):"
|
|
72
|
+
for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
|
|
73
|
+
local dirs first
|
|
74
|
+
dirs="$(dirs_for "$a")"
|
|
75
|
+
first="${dirs%% *}"
|
|
76
|
+
case "$first" in
|
|
77
|
+
__CODEX__) first=".codex/skills" ;;
|
|
78
|
+
__OPENCODE__) first=".config/opencode/skills" ;;
|
|
79
|
+
esac
|
|
80
|
+
if [ "$_IS_WINDOWS" = "1" ]; then
|
|
81
|
+
first="%USERPROFILE%\\${first//\//\\}"
|
|
82
|
+
else
|
|
83
|
+
first="~/$first"
|
|
84
|
+
fi
|
|
85
|
+
printf ' %-10s %s\n' "$a" "$first"
|
|
86
|
+
done
|
|
87
|
+
echo '说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。'
|
|
88
|
+
echo '改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。'
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
main() {
|
|
92
|
+
local agent="" dir="" global=0 show_list=0
|
|
93
|
+
while [ $# -gt 0 ]; do
|
|
94
|
+
case "$1" in
|
|
95
|
+
--agent) shift; agent="${1:-}" ;;
|
|
96
|
+
--dir) shift; dir="${1:-}" ;;
|
|
97
|
+
-g|--global) global=1 ;;
|
|
98
|
+
--list|-l) show_list=1 ;;
|
|
99
|
+
*) echo "未知参数: $1" >&2; exit 2 ;;
|
|
100
|
+
esac
|
|
101
|
+
shift
|
|
102
|
+
done
|
|
103
|
+
|
|
104
|
+
if [ "$show_list" = "1" ]; then list; return; fi
|
|
105
|
+
if [ -n "$dir" ]; then install_to "$dir"; echo "完成。"; return; fi
|
|
106
|
+
if [ -n "$agent" ]; then
|
|
107
|
+
local dirs first
|
|
108
|
+
if ! dirs="$(dirs_for "$agent")"; then
|
|
109
|
+
echo "未收录智能体: $agent。请用 --dir <路径> 指定技能目录。" >&2; exit 2
|
|
110
|
+
fi
|
|
111
|
+
first="${dirs%% *}"
|
|
112
|
+
install_to "$(resolve_user "$first")"; echo "完成。"; return
|
|
113
|
+
fi
|
|
114
|
+
if [ "$global" = "1" ]; then
|
|
115
|
+
echo "安装到全部已知智能体用户级目录..."
|
|
116
|
+
local dirs rel
|
|
117
|
+
for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
|
|
118
|
+
dirs="$(dirs_for "$a")"
|
|
119
|
+
for rel in $dirs; do install_to "$(resolve_user "$rel")"; done
|
|
120
|
+
done
|
|
121
|
+
echo "完成。"; return
|
|
122
|
+
fi
|
|
123
|
+
local installed=0 d
|
|
124
|
+
for d in .claude/skills .cursor/skills .codex/skills .config/goose/skills .config/agents/skills .opencode/skills .codeium/windsurf/skills .workbuddy/skills .kiro/skills .traecli/skills .gemini/skills .trae-cn/skills .qwen/skills .comate/skills .codebuddy/skills .kimi/skills .agents/skills; do
|
|
125
|
+
if [ -d "$d" ]; then install_to "$d"; installed=1; fi
|
|
126
|
+
done
|
|
127
|
+
if [ "$installed" = "0" ]; then
|
|
128
|
+
echo "未检测到项目级智能体目录。可用 --agent <name> / -g 装到用户级,或 --dir 指定。"
|
|
129
|
+
fi
|
|
130
|
+
}
|
|
131
|
+
|
|
132
132
|
main "$@"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yottameta/yotta-guardian",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Yuandun (元盾) — cross-agent dangerous tool-call guardrail: a deterministic rule engine + pluggable intent verifier (model-agnostic) that evaluates exec/write/edit/read/run/shell calls and provides audit logs. Triggers when an agent is about to run a high-risk command, write sensitive paths, or change system config. Boundaries: read-only evaluation by default, configurable allowances.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
],
|
|
11
11
|
"files": [
|
|
12
12
|
"SKILL.md",
|
|
13
|
+
"skill-manifest.json",
|
|
13
14
|
"LICENSE",
|
|
14
15
|
"README.md",
|
|
15
16
|
"install.sh",
|
|
@@ -19,7 +20,10 @@
|
|
|
19
20
|
"bin",
|
|
20
21
|
"NOTICE",
|
|
21
22
|
"CHANGELOG.md",
|
|
22
|
-
"README.zh-CN.md"
|
|
23
|
+
"README.zh-CN.md",
|
|
24
|
+
"!**/__pycache__",
|
|
25
|
+
"!**/*.pyc",
|
|
26
|
+
"!scripts/test_*.py"
|
|
23
27
|
],
|
|
24
28
|
"repository": {
|
|
25
29
|
"type": "git",
|