@yottameta/yotta-skills-plugin 0.25.1 → 0.27.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/plugins/marketplace.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/skills/yotta-skills/SKILL.md +19 -8
- package/skills/yotta-skills/assets/view.html +738 -0
- package/skills/yotta-skills/bin/yotta-skills.js +143 -55
- package/skills/yotta-skills/lib/agent-dirs.js +1 -1
- package/skills/yotta-skills/lib/hub-adopt.js +16 -0
- package/skills/yotta-skills/lib/hub-scan.js +97 -0
- package/skills/yotta-skills/lib/hub-view-server.js +680 -0
- package/skills/yotta-skills/lib/hub.js +454 -9
- package/skills/yotta-skills/lib/install-snapshot.js +20 -6
- package/skills/yotta-skills/lib/registry-fetch.js +7 -0
- package/skills/yotta-skills/lib/skills-scan.js +42 -1
- package/skills/yotta-skills/references/hub.md +40 -1
- package/skills/yotta-skills/scripts/yotta-skills-mcp.py +1 -1
|
@@ -125,6 +125,44 @@ function selectRepresentativeVariant(variants) {
|
|
|
125
125
|
return selected || variants.find((variant) => variant.version) || variants[0] || null;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* 严格 YAML frontmatter 只读启发式告警(不解析、不修改源文件)。
|
|
130
|
+
*
|
|
131
|
+
* 命中常见「宽松解析可用、严格解析器拒绝」的写法:
|
|
132
|
+
* - 未加引号的单行值以逗号开头(如 `tags: ,development`)→ Plain value cannot start with flow indicator;
|
|
133
|
+
* - 未加引号的单行值包含 `: `(如折叠后的 description)→ mapping values are not allowed here。
|
|
134
|
+
* 仅供展示与记录;不影响使用则不处理(非元技能规则)。
|
|
135
|
+
*/
|
|
136
|
+
function strictFrontmatterWarnings(text) {
|
|
137
|
+
const m = String(text || '').match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
138
|
+
if (!m) return [];
|
|
139
|
+
const warnings = [];
|
|
140
|
+
let blockKey = null;
|
|
141
|
+
for (const raw of m[1].split(/\r?\n/)) {
|
|
142
|
+
if (blockKey) {
|
|
143
|
+
if (!raw.trim() || /^\s/.test(raw)) continue;
|
|
144
|
+
blockKey = null;
|
|
145
|
+
}
|
|
146
|
+
const t = raw.trim();
|
|
147
|
+
if (!t || t.startsWith('#') || t.startsWith('-')) continue;
|
|
148
|
+
const idx = t.indexOf(':');
|
|
149
|
+
if (idx <= 0) continue;
|
|
150
|
+
const key = t.slice(0, idx).trim();
|
|
151
|
+
const val = t.slice(idx + 1).trim();
|
|
152
|
+
if (!val) continue;
|
|
153
|
+
if (/^[>|][-+]?$/.test(val)) { blockKey = key; continue; }
|
|
154
|
+
if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) continue;
|
|
155
|
+
if (val.startsWith(',')) {
|
|
156
|
+
warnings.push(key + ' 值以逗号开头,严格 YAML 解析器会拒绝(Plain value cannot start with flow indicator character ,)');
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (!val.startsWith('{') && !val.startsWith('[') && val.includes(': ')) {
|
|
160
|
+
warnings.push(key + ' 值包含「: 」且未加引号,严格 YAML 解析器会拒绝(mapping values are not allowed here)');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return warnings;
|
|
164
|
+
}
|
|
165
|
+
|
|
128
166
|
/** 扫描单个技能目录:子目录含 SKILL.md 且 frontmatter 有 name 即视为技能。 */
|
|
129
167
|
function scanSkillDir(dir) {
|
|
130
168
|
const results = [];
|
|
@@ -170,7 +208,7 @@ function opencodeUserDir() {
|
|
|
170
208
|
return agentDirs.resolveUserDir('.config/opencode/skills', { homeDir: os.homedir(), env: process.env });
|
|
171
209
|
}
|
|
172
210
|
|
|
173
|
-
/** OpenClaw
|
|
211
|
+
/** OpenClaw 用户级技能目录:$OPENCLAW_STATE_DIR/skills(默认 ~/.openclaw/skills)。 */
|
|
174
212
|
function openclawUserDir() {
|
|
175
213
|
return agentDirs.resolveUserDir('.openclaw/skills', { homeDir: os.homedir(), env: process.env });
|
|
176
214
|
}
|
|
@@ -396,6 +434,9 @@ function formatInventory(registry, filePath) {
|
|
|
396
434
|
module.exports = {
|
|
397
435
|
AGENT_DIRS,
|
|
398
436
|
parseFrontmatter,
|
|
437
|
+
parseSemver,
|
|
438
|
+
compareSemver,
|
|
439
|
+
strictFrontmatterWarnings,
|
|
399
440
|
scanSkillDir,
|
|
400
441
|
defaultRoots,
|
|
401
442
|
scanRoots,
|
|
@@ -11,8 +11,24 @@ symlink),升级只改真源,已链接宿主即时生效。
|
|
|
11
11
|
- Hub 真源:`~/.yottaskills/hub`
|
|
12
12
|
- 技能台账:`<hub>/.yotta-hub.json`
|
|
13
13
|
- 链接台账:`<hub>/.yotta-links.json`
|
|
14
|
+
- 收敛回收站:`~/.yottaskills/trash/<时间戳>/<宿主>/<技能>/`(保留 7 天,可用 `YOTTA_SKILLS_TRASH` 覆盖)
|
|
14
15
|
- 覆盖方式:`--hub <dir>` 或 `YOTTA_SKILLS_HUB`
|
|
15
16
|
|
|
17
|
+
## 元技能唯一性收敛(`hub link` 执行时)
|
|
18
|
+
|
|
19
|
+
元技能(清单 27 + 特殊家族 5:元开 / 元伴 / 元呈 / 元阁本体 / 元信MCP)在
|
|
20
|
+
`hub link`(含面板链接动作)执行时收敛唯一性,不做事后全机扫描:
|
|
21
|
+
|
|
22
|
+
1. 收集宿主目录中的同名真目录与 `yotta-X__*` 重命名副本(frontmatter `name` 相同);
|
|
23
|
+
2. 版本闸门:Hub 版本 ≥ 宿主副本版本才收敛;宿主更高 → 跳过并提示先 `hub update`;
|
|
24
|
+
版本无法解析 → 跳过提示(fail-safe);
|
|
25
|
+
3. 旧副本移入回收站(保留 7 天、输出恢复路径)→ 建立指向 Hub 的链接;
|
|
26
|
+
4. 先移后链;建链失败自动尝试恢复已移动副本,恢复失败时报出回收站路径;
|
|
27
|
+
5. 外部技能保持原行为:同名冲突默认跳过,不自动删、不自动更新。
|
|
28
|
+
|
|
29
|
+
落地后跑一次 `hub link --all` 即可完成现存收敛。`hub doctor` 的
|
|
30
|
+
`single_source:*` 检查只读报告宿主中的多份副本与版本参差,不自动修改。
|
|
31
|
+
|
|
16
32
|
## 命令
|
|
17
33
|
|
|
18
34
|
```bash
|
|
@@ -20,17 +36,22 @@ symlink),升级只改真源,已链接宿主即时生效。
|
|
|
20
36
|
npx -y @yottameta/yotta-skills hub hosts
|
|
21
37
|
|
|
22
38
|
# 安装 / 更新 Hub 真源
|
|
39
|
+
# 范围 = 全家清单 27 + 特殊家族 5;特殊家族跟随各自 npm latest
|
|
40
|
+
# 非元技能不参与更新(来源无统一安装源,用户自行处理)
|
|
23
41
|
npx -y @yottameta/yotta-skills hub install
|
|
24
42
|
npx -y @yottameta/yotta-skills hub update
|
|
25
43
|
|
|
26
44
|
# 接管各宿主现有技能:先只读预演,再复制收编(原目录保留)
|
|
45
|
+
# --apply 输出明示范围与目标 Hub;--skip-scan 会显式提示跳过装前扫描
|
|
46
|
+
# 非元技能 frontmatter 的严格 YAML 风险只读告警,不影响使用则不处理
|
|
27
47
|
npx -y @yottameta/yotta-skills hub adopt --scan
|
|
28
48
|
npx -y @yottameta/yotta-skills hub adopt --apply
|
|
29
49
|
|
|
30
50
|
# 非元阁来源技能没有统一更新源:手动从指定目录刷新
|
|
31
51
|
npx -y @yottameta/yotta-skills hub refresh my-skill --from <技能目录>
|
|
32
52
|
|
|
33
|
-
#
|
|
53
|
+
# 分发到全部已发现宿主:元技能链接时收敛旧副本(回收站 7 天);
|
|
54
|
+
# 外部技能同名真目录默认跳过(--force 才备份并替换)
|
|
34
55
|
npx -y @yottameta/yotta-skills hub link --all
|
|
35
56
|
|
|
36
57
|
# 只删除链接,不动 Hub 真源
|
|
@@ -59,8 +80,26 @@ npx -y @yottameta/yotta-skills hub doctor
|
|
|
59
80
|
- 官方锁文件:只读兼容 Vercel Labs `skills` CLI 的 `.skill-lock.json` v3
|
|
60
81
|
(`$XDG_STATE_HOME/skills/` 或 `~/.agents/`)。
|
|
61
82
|
|
|
83
|
+
## 本地面板(yotta-skills view)
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx -y @yottameta/yotta-skills view
|
|
87
|
+
npx -y @yottameta/yotta-skills view --port 8790
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
面板只在 `127.0.0.1`(默认 8789)监听,零远程资源、零遥测,只读写 Hub
|
|
91
|
+
目录与台账 / 证据文件,不读元忆、不改宿主全局配置。六个视图:概览、宿主矩阵、
|
|
92
|
+
收编向导、链接与体检、记录与回滚、路由与编排,另附高级 CLI 页。
|
|
93
|
+
|
|
94
|
+
动作边界:收编 / 链接 / 解除 / 回滚可执行(预览 → 确认 → 执行 → 证据);
|
|
95
|
+
install / update / refresh 只在高级 CLI 页给出可复制命令,不在网页执行。
|
|
96
|
+
写操作需要页面会话令牌,解除与回滚需要破坏性确认串;收编始终逐项运行元信
|
|
97
|
+
扫描,high / critical 阻断。
|
|
98
|
+
|
|
62
99
|
## 安全边界
|
|
63
100
|
|
|
64
101
|
- `unlink` 只删除 lstat 确认为链接、且 readlink 目标位于 Hub 内的路径。
|
|
65
102
|
- 真目录 / 非 Hub 链接一律拒绝删除;`--force` 对真目录先备份再替换。
|
|
103
|
+
- 收敛只动元技能在宿主目录中的旧副本:移入回收站(7 天)而非直删;
|
|
104
|
+
不碰插件与宿主 MCP 配置;外部技能源文件绝不修改。
|
|
66
105
|
- Hub 仅本机使用,不对外分发技能内容。
|