@yottameta/yotta-skills-plugin 0.6.1 → 0.7.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.
@@ -12,7 +12,7 @@
12
12
  "authentication": "ON_INSTALL"
13
13
  },
14
14
  "category": "Developer Tools",
15
- "version": "0.6.1",
15
+ "version": "0.7.0",
16
16
  "description": "YuanGe (元阁) - orchestration routing, inventory, and one-command installer for the YottaMeta skill family (zero dependencies, Node.js only).",
17
17
  "interface": {
18
18
  "displayName": "元阁 yotta-skills",
@@ -12,7 +12,7 @@
12
12
  "authentication": "ON_INSTALL"
13
13
  },
14
14
  "category": "Developer Tools",
15
- "version": "0.6.1",
15
+ "version": "0.7.0",
16
16
  "description": "YuanGe (元阁) - orchestration routing, inventory, and one-command installer for the YottaMeta skill family (zero dependencies, Node.js only).",
17
17
  "interface": {
18
18
  "displayName": "元阁 yotta-skills",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yottameta/yotta-skills-plugin",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "YuanGe (元阁) — orchestration and routing for the YottaMeta skill family, packaged as a YottaMeta Agent Plugin.",
5
5
  "license": "MIT",
6
6
  "keywords": [
package/plugin.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
3
  "name": "yotta-skills",
4
- "version": "0.6.1",
4
+ "version": "0.7.0",
5
5
  "description": "YuanGe (元阁) - orchestration routing, inventory, and one-command installer for the YottaMeta skill family (zero dependencies, Node.js only).",
6
6
  "author": {
7
7
  "name": "YottaMeta",
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: yotta-skills
3
- version: 0.6.1
4
- description: 元阁 -- 元阁全家技能的总编排策划 + 编排路由 + 一键安装器 + 技能盘点。路由层:--route / route_request 按需求摘要给出候选组合、调用顺序、角色、置信度、依据、已装/缺失状态与安装命令,只建议不自动安装;非元阁家族已装技能按 frontmatter description 机械匹配作并列候选(标注来源与未扫描状态,只读不自动调用);策划层:按场景给出「该组合哪几个元技能、组合强在哪、怎么自动装+自动用」;安装层:一条命令把 YottaMeta 已发布的全部 yotta-* 技能装进指定智能体或目录;盘点层:--inventory / --reindex 扫描本机已装技能生成/更新注册表,新装技能自动被发现(install/update 后自动 re-index,会话开工可先跑 --reindex;自包含零依赖,不依赖任何元技能);MCP 按需加载(可选:list_installed_skills/describe_skill/reindex/route_request,不常驻,未加载降级 CLI)。支持 --list 清单 / --route 路由 / install / update / --inventory / --reindex / --dry-run 预览 / --pin 锁版本。触发:需要批量安装或更新元阁全家技能、按场景组合多个元技能、路由或判断该用哪些技能、盘点或查看本机已装技能、重扫技能注册表、给某个智能体或目录一次性铺齐 yotta-* 技能、预览安装清单、锁版本安装、或用户说 元阁/装全家/一次装齐/yotta-skills/install-all/更新全家/该用哪个技能/路由技能/盘点技能/查看已装技能 等。边界(Do NOT trigger):只做「组合策划 + 静态路由建议 + 清单 + 下载 + 落位 + 汇总 + 盘点 + re-index」,不含技能本体、不做技能内容开发、不 -g 污染全局、不自动安装缺失技能;装前摘要仅供参考,安装决策由用户确认。
3
+ version: 0.7.0
4
+ description: 元阁 -- 元阁全家技能的总编排策划 + 编排路由 + 一键安装器 + 技能盘点。路由层:--route / route_request 按需求摘要给出候选组合、调用顺序、角色、置信度、依据、已装/缺失状态与安装命令,只建议不自动安装;非元阁家族已装技能按 frontmatter description 机械匹配作并列候选(标注来源与未扫描状态,只读不自动调用);策划层:按场景给出「该组合哪几个元技能、组合强在哪、怎么自动装+自动用」;安装层:一条命令把 YottaMeta 已发布的全部 yotta-* 技能装进指定智能体或目录;盘点层:--inventory / --reindex 扫描本机已装技能生成/更新注册表,新装技能自动被发现(install/update 后自动 re-index,会话开工可先跑 --reindex 与 update --check(联网只读检查更新);自包含零依赖,不依赖任何元技能);MCP 按需加载(可选:list_installed_skills/describe_skill/reindex/route_request,不常驻,未加载降级 CLI)。支持 --list 清单 / --route 路由 / install / update / update --check(只读检查)/ update --auto(家族自动更新)/ --inventory / --reindex / --dry-run 预览 / --pin 锁版本。触发:需要批量安装或更新元阁全家技能、按场景组合多个元技能、路由或判断该用哪些技能、盘点或查看本机已装技能、重扫技能注册表、给某个智能体或目录一次性铺齐 yotta-* 技能、预览安装清单、锁版本安装、或用户说 元阁/装全家/一次装齐/yotta-skills/install-all/更新全家/检查更新/自动更新/该用哪个技能/路由技能/盘点技能/查看已装技能 等。边界(Do NOT trigger):只做「组合策划 + 静态路由建议 + 清单 + 下载 + 落位 + 汇总 + 盘点 + re-index」,不含技能本体、不做技能内容开发、不 -g 污染全局、不自动安装缺失技能;装前摘要仅供参考,安装决策由用户确认。
5
5
  license: MIT
6
6
  metadata:
7
7
  zh_name: 元阁
@@ -16,7 +16,8 @@ metadata:
16
16
  **写入内容(逐字)**:
17
17
 
18
18
  > **元阁编排**:单技能是零件,组合才是系统。会话开工先跑一次 `yotta-skills --reindex`
19
- > (重扫本机技能注册表,新装技能自动被看见)。接到需求,先查「元阁编排策划」命中哪个组合
19
+ > (重扫本机技能注册表,新装技能自动被看见);会话开工再跑一次 `yotta-skills update --check`
20
+ > (联网只读检查本地已装技能是否有更新;有更新列清单,确认后 `update`,或 `update --auto` 仅自动更新自家 yotta-* 家族)。接到需求,先查「元阁编排策划」命中哪个组合
20
21
  > (输出呈现标准 / 长生命周期 / 交付质量门 / 装前安全门 / 造技能发版 / 安全事件响应 / 入口安装),
21
22
  > 再按需自动安装并应用。完整决策表见技能 `yotta-skills/references/orchestration.md`。
22
23
 
@@ -31,7 +32,7 @@ metadata:
31
32
 
32
33
  - **路由层(该用哪几个)**:`--route "<需求摘要>"` / MCP `route_request` 查本地注册表与静态编排 playbook,输出候选组合、调用顺序、每个技能角色、置信度、依据、已装/缺失状态与安装命令;非元阁家族已装技能按 frontmatter description 机械匹配作并列候选(标注来源与未扫描状态,只读不自动调用);只建议安装,不自动安装。
33
34
  - **策划层(怎么用)**:接到需求,先按「编排策划」定位命中哪个组合——哪些元技能搭配起来最强、适合什么场景、AI 该怎么自动装并自动用起来。
34
- - **安装层(怎么装)**:一条 `npx -y @yottameta/yotta-skills` 把组合/全家装进指定智能体或目录——`--list` 看清单、`install` 装、`update` 增量更新、`--dry-run` 预览、`--pin` 锁版本。
35
+ - **安装层(怎么装)**:一条 `npx -y @yottameta/yotta-skills` 把组合/全家装进指定智能体或目录——`--list` 看清单、`install` 装、`update` 增量更新、`update --check` 只读检查更新、`update --auto` 家族自动更新、`--dry-run` 预览、`--pin` 锁版本。
35
36
  - **盘点层(已装了什么)**:`--inventory` / `--reindex` 扫描本机各智能体技能目录,生成/更新本地注册表;装技能后自动 re-index,新装技能自动被发现——自包含扫描,不依赖任何元技能。
36
37
 
37
38
  每个技能仍走各自独立的 npm 包(版本源唯一);本包只做「清单 + 下载 + 落位 + 汇总」,**不内置任何技能本体**。
@@ -97,6 +98,12 @@ npx -y @yottameta/yotta-skills install yotta-memory yotta-verify --dir ~/my-skil
97
98
  # 增量更新已装技能(补齐缺失 / 版本不一致)
98
99
  npx -y @yottameta/yotta-skills update --agent codex
99
100
 
101
+ # 只读检查有没有更新(联网对 npm 最新,不改动;0=全部最新 / 3=有更新 / 1=查失败)
102
+ npx -y @yottameta/yotta-skills update --check --agent codex
103
+
104
+ # 检查到家族更新后自动更新(仅 yotta-* 自家家族,含装前安全扫描)
105
+ npx -y @yottameta/yotta-skills update --auto --agent codex
106
+
100
107
  # 预览将安装清单(不联网、不改动)
101
108
  npx -y @yottameta/yotta-skills --dry-run
102
109
 
@@ -116,6 +123,8 @@ npx -y @yottameta/yotta-skills --reindex
116
123
  | `install --dir <path>` | 装全家到指定目录,每个技能落在 `<path>/<slug>` |
117
124
  | `install <skill>... [--agent <name> \| --dir <path>]` | 只装指定的一个或多个技能 |
118
125
  | `update [--agent <name> \| --dir <path>]` | 增量更新:补齐缺失技能、升级版本不一致的技能 |
126
+ | `update --check [--agent <name> \| --dir <path>]` | 只读检查更新:联网对 npm 最新,不改动;退出码 0=全部最新 / 3=有更新 / 1=查失败 |
127
+ | `update --auto [--agent <name> \| --dir <path>]` | 检查到家族更新后自动更新(仅 yotta-* 自家家族,含装前安全扫描) |
119
128
  | `--inventory` | 盘点本机已装技能:扫描技能目录生成/更新注册表(自包含,不依赖元技能);`--json` 输出 JSON、`--project` 附扫项目级目录 |
120
129
  | `--reindex` | 重扫注册表:扫描技能目录并增量合并变化(会话开工 / 装技能后自动调用);`--json` 输出 JSON、`--project` 附扫项目级目录;`--rescan` 同义 |
121
130
  | `--route <需求摘要>` | 静态编排路由:输出组合、调用顺序、技能角色、置信度、依据、已装/缺失状态与安装建议;`--json` 输出 JSON、`--project` 附扫项目级目录 |
@@ -158,6 +167,22 @@ npx -y @yottameta/yotta-skills --inventory --dir ~/my-skills --project
158
167
  让新装 / 更新的技能自动进入注册表。
159
168
  - **手动**:`yotta-skills --reindex`(`--rescan` 同义);`--json` 机器可读、`--project` 附扫项目级目录。
160
169
 
170
+ ### update 增量更新与检查(--check / --auto)
171
+
172
+ 增量更新遍历清单,补齐缺失、升级版本不一致,默认跳过已最新。`--check` 只读联网
173
+ (对 npm `dist-tags.latest`),按本地 `SKILL.md` 版本对比——无论技能源自哪个安装渠道
174
+ (npm / git clone / 本地拷贝等)都兼容;`--auto` 检测到家族(`yotta-*` / 清单内)可更新时,走安装管线
175
+ (含元信装前安全扫描)自动更新。**非元阁家族(非 yotta-*)技能绝不自动更新**(默认保守:`--check` 列清单,
176
+ 用户确认后再 `update`)。
177
+
178
+ ```bash
179
+ # 只读检查(0=全部最新 / 3=有更新 / 1=查失败)
180
+ npx -y @yottameta/yotta-skills update --check --agent codex
181
+
182
+ # 检查到家族更新后自动更新(仅自家家族)
183
+ npx -y @yottameta/yotta-skills update --auto --agent codex
184
+ ```
185
+
161
186
  ## 编排路由(--route)
162
187
 
163
188
  把需求摘要交给静态编排 playbook 和本地注册表,得到一组可执行建议:
@@ -247,3 +272,5 @@ npx -y @yottameta/yotta-skills --route "检查代码质量,别糊弄" --json
247
272
  - 全家技能清单(人工可读版):`references/skill-list.md`(机器权威源为 `skills.json`)。
248
273
  - 内部机制:`references/install-flow.md`。
249
274
  - 新手中文教程:`references/tutorial.md`。
275
+ - 常见问题:`references/faq.md`。
276
+ - 复杂场景走查:`references/walkthroughs.md`。
@@ -8,6 +8,8 @@
8
8
  * npx -y @yottameta/yotta-skills install --dir <path> # 装全家到指定目录
9
9
  * npx -y @yottameta/yotta-skills install <skill> --dir <path> # 装单个技能
10
10
  * npx -y @yottameta/yotta-skills update --agent <name> # 增量更新已装技能(补齐缺失/版本不一致)
11
+ * npx -y @yottameta/yotta-skills update --check # 只读检查更新(联网对 npm 最新,不改动;退出码 0/3/1)
12
+ * npx -y @yottameta/yotta-skills update --auto # 检查到家族更新后自动更新(仅 yotta-* 家族,含装前扫描)
11
13
  * npx -y @yottameta/yotta-skills --dry-run # 预览将安装清单(不联网、不改动)
12
14
  *
13
15
  * 版本策略:清单锁定 `major.x`(不锁死 patch,维护性更新随最新);--pin 锁死精确版本。
@@ -20,6 +22,8 @@ const fs = require('fs');
20
22
  const path = require('path');
21
23
  const os = require('os');
22
24
  const { spawnSync } = require('child_process');
25
+ const http = require('http');
26
+ const https = require('https');
23
27
 
24
28
  const PKG_ROOT = path.join(__dirname, '..');
25
29
  let VERSION = '0.2.1';
@@ -31,7 +35,7 @@ function loadManifest() {
31
35
  try {
32
36
  data = JSON.parse(fs.readFileSync(file, 'utf8'));
33
37
  } catch (e) {
34
- die('无法读取技能清单: ' + file + '(' + e.message + ')');
38
+ die('无法读取技能清单: ' + file + '(' + e.message + ')', 2, '检查 YOTTA_SKILLS_MANIFEST 或 skills.json 是否存在且为合法 JSON。');
35
39
  }
36
40
  const list = Array.isArray(data) ? data : data.skills;
37
41
  if (!Array.isArray(list) || list.length === 0) die('技能清单为空: ' + file);
@@ -81,8 +85,9 @@ function resolveUserDir(rel) {
81
85
  }
82
86
 
83
87
  // ── 工具函数 ───────────────────────────────────────────────────────────────
84
- function die(msg, code) {
88
+ function die(msg, code, hint) {
85
89
  process.stderr.write('错误:' + msg + '\n');
90
+ if (hint) process.stderr.write('修复建议:' + hint + '\n');
86
91
  process.exit(code === undefined ? 2 : code);
87
92
  }
88
93
  function out(s) { process.stdout.write(s + '\n'); }
@@ -132,11 +137,12 @@ function parseArgs(argv) {
132
137
  help: false, version: false, agent: null, dir: null, npm: null,
133
138
  python: null, verify: null, command: null, skill: null, rest: [],
134
139
  inventory: false, reindex: false, noReindex: false, json: false, project: false, route: null,
140
+ check: false, auto: false, registry: null,
135
141
  };
136
142
  const positionals = [];
137
143
  for (let i = 0; i < argv.length; i++) {
138
144
  const a = argv[i];
139
- const take = (name) => { const v = argv[i + 1]; if (v === undefined || v.startsWith('--')) die(name + ' 缺少参数值'); i++; return v; };
145
+ const take = (name) => { const v = argv[i + 1]; if (v === undefined || v.startsWith('--')) die(name + ' 缺少参数值', 2, '请为该选项提供一个非空值;可用 --help 查看用法。'); i++; return v; };
140
146
  if (a === '--list' || a === '-l') opts.list = true;
141
147
  else if (a === '--dry-run') opts.dryRun = true;
142
148
  else if (a === '--pin') opts.pin = true;
@@ -147,7 +153,7 @@ function parseArgs(argv) {
147
153
  else if (a === '--inventory' || a === '--inv') opts.inventory = true;
148
154
  else if (a === '--route') {
149
155
  const value = argv[i + 1];
150
- if (value === undefined || value.startsWith('--')) die('--route 缺少需求摘要');
156
+ if (value === undefined || value.startsWith('--')) die('--route 缺少需求摘要', 2, '请提供一句需求描述,例如 --route "帮我做发布前质量检查"。');
151
157
  opts.route = value;
152
158
  i++;
153
159
  }
@@ -160,7 +166,10 @@ function parseArgs(argv) {
160
166
  else if (a === '--npm') opts.npm = take('--npm');
161
167
  else if (a === '--python') opts.python = take('--python');
162
168
  else if (a === '--verify') opts.verify = take('--verify');
163
- else if (a.startsWith('-')) die('未知参数: ' + a);
169
+ else if (a === '--check') opts.check = true;
170
+ else if (a === '--auto') opts.auto = true;
171
+ else if (a === '--registry') opts.registry = take('--registry');
172
+ else if (a.startsWith('-')) die('未知参数: ' + a, 2, '可用 --help 查看支持的选项。');
164
173
  else positionals.push(a);
165
174
  }
166
175
  // 命令解析:install / update,其余位置参数 = 技能 slug(可多个)
@@ -193,7 +202,7 @@ function selectSkills(opts) {
193
202
  const picked = [];
194
203
  for (const slug of opts.skills) {
195
204
  const s = findSkill(slug);
196
- if (!s) die('未知技能: ' + slug + '(可用: yotta-skills --list)');
205
+ if (!s) die('未知技能: ' + slug + '(可用: yotta-skills --list)', 2, '请先运行 --list 查看技能名,或检查拼写。');
197
206
  picked.push(s);
198
207
  }
199
208
  return picked;
@@ -208,6 +217,147 @@ function readInstalledVersion(dir) {
208
217
  } catch (_) { return null; }
209
218
  }
210
219
 
220
+
221
+ // ── 更新检查(只读)与自动更新 ─────────────────────────────────────────────
222
+ function registryUrl(pkg, registry) {
223
+ var base = (registry || process.env.YOTTA_SKILLS_REGISTRY || 'https://registry.npmjs.org/').replace(/\/$/, '');
224
+ return base + '/' + pkg.replace(/\//g, '%2f');
225
+ }
226
+
227
+ function fetchRegistryLatest(pkg, opts) {
228
+ return new Promise(function (resolve) {
229
+ var url = registryUrl(pkg, opts.registry);
230
+ var client = url.startsWith('https:') ? https : http;
231
+ var req = client.get(url, { timeout: 15000, headers: { 'accept': 'application/json', 'user-agent': 'yotta-skills-check' } }, function (res) {
232
+ var data = '';
233
+ res.setEncoding('utf8');
234
+ res.on('data', function (c) { data += c; });
235
+ res.on('end', function () {
236
+ try {
237
+ var j = JSON.parse(data);
238
+ var latest = j && j['dist-tags'] && j['dist-tags'].latest;
239
+ if (!latest) { resolve({ ok: false, error: '响应缺少 dist-tags.latest(' + pkg + ')' }); return; }
240
+ resolve({ ok: true, version: latest });
241
+ } catch (e) {
242
+ resolve({ ok: false, error: '解析 registry 响应失败: ' + e.message });
243
+ }
244
+ });
245
+ });
246
+ req.on('error', function (e) { resolve({ ok: false, error: '网络错误: ' + (e && e.message ? e.message : e) }); });
247
+ req.on('timeout', function () { req.destroy(); resolve({ ok: false, error: '网络超时(15s)' }); });
248
+ });
249
+ }
250
+
251
+ function readInstalledMeta(dir) {
252
+ var f = path.join(dir, 'SKILL.md');
253
+ try {
254
+ var text = fs.readFileSync(f, 'utf8');
255
+ var name = (text.match(/^name:\s*(.+)$/m) || [])[1];
256
+ var version = (text.match(/^version:\s*([0-9]+\.[0-9]+\.[0-9]+)/m) || [])[1];
257
+ return { name: name ? name.trim() : null, version: version || null };
258
+ } catch (e) { return { name: null, version: null }; }
259
+ }
260
+
261
+ function familySkillFor(slug) {
262
+ var m = findSkill(slug);
263
+ if (m) return m;
264
+ if (/^yotta-/.test(slug)) {
265
+ return { slug: slug, name: slug.replace(/^yotta-/, ''), pkg: '@yottameta/' + slug, version: null, desc: '推断的家族技能(不在 skills.json 清单)' };
266
+ }
267
+ return null;
268
+ }
269
+
270
+ function scanInstalledSlugs(dest) {
271
+ var list = [];
272
+ var entries;
273
+ try { entries = fs.readdirSync(dest, { withFileTypes: true }); } catch (e) { return list; }
274
+ for (var i = 0; i < entries.length; i++) {
275
+ var e = entries[i];
276
+ if (!e.isDirectory()) continue;
277
+ var meta = readInstalledMeta(path.join(dest, e.name));
278
+ if (meta.name) list.push({ slug: e.name, name: meta.name, version: meta.version });
279
+ }
280
+ return list;
281
+ }
282
+
283
+ async function runUpdateCheck(opts, dest) {
284
+ var lines = [];
285
+ var quiet = !!opts.json;
286
+ function say(s) { if (!quiet) lines.push(s); }
287
+ say('yotta-skills(元阁)v' + VERSION + ' —— 检查更新(只读,不改动) -> ' + dest);
288
+ say('版本源: ' + (opts.registry || process.env.YOTTA_SKILLS_REGISTRY || 'https://registry.npmjs.org/'));
289
+ say('');
290
+ var installed = scanInstalledSlugs(dest);
291
+ if (installed.length === 0) {
292
+ say('(' + dest + ' 下未发现已装技能目录)');
293
+ return { code: 0, rows: [], updates: 0, latest: 0, failed: 0, nonFamily: 0 };
294
+ }
295
+ var rows = [];
296
+ var updates = 0, latest = 0, failed = 0, nonFamily = 0;
297
+ for (var i = 0; i < installed.length; i++) {
298
+ var it = installed[i];
299
+ var fam = familySkillFor(it.slug);
300
+ if (!fam) {
301
+ nonFamily++;
302
+ say(' - ' + it.slug.padEnd(22) + '非元阁家族,跳过');
303
+ continue;
304
+ }
305
+ var res = await fetchRegistryLatest(fam.pkg, opts);
306
+ if (!res.ok) {
307
+ failed++;
308
+ say(' ✘ ' + it.slug.padEnd(22) + '检查失败: ' + res.error);
309
+ continue;
310
+ }
311
+ var current = res.version;
312
+ var cur = it.version || null;
313
+ var isUp = (cur === current);
314
+ if (isUp) {
315
+ latest++;
316
+ say(' ✔ ' + it.slug.padEnd(22) + '已最新(本地 v' + cur + ')');
317
+ } else {
318
+ updates++;
319
+ say(' ➤ ' + it.slug.padEnd(22) + '有更新:本地 v' + (cur || '未知') + ' -> 最新 v' + current);
320
+ if (fam.version && fam.version !== current) {
321
+ say(' ⚠ 清单 skills.json 记为 v' + fam.version + ',与 npm 最新 v' + current + ' 不一致(需同步清单)');
322
+ }
323
+ }
324
+ rows.push({ slug: it.slug, installed: cur, latest: current, pkg: fam.pkg, hasUpdate: !isUp, family: fam });
325
+ }
326
+ say('');
327
+ say('汇总: 有更新 ' + updates + ' / 已最新 ' + latest + ' / 检查失败 ' + failed + ' / 非家族跳过 ' + nonFamily);
328
+ for (var j = 0; j < lines.length; j++) out(lines[j]);
329
+ var code = (failed > 0) ? 1 : (updates > 0 ? 3 : 0);
330
+ return { code: code, rows: rows, updates: updates, latest: latest, failed: failed, nonFamily: nonFamily };
331
+ }
332
+
333
+ async function runUpdateAuto(opts, dest) {
334
+ out('yotta-skills(元阁)v' + VERSION + ' —— 检查并自动更新(仅 yotta-* 家族) -> ' + dest);
335
+ var r = await runUpdateCheck(Object.assign({}, opts, { json: false }), dest);
336
+ if (r.failed > 0) {
337
+ out('检查未完成(' + r.failed + ' 个失败),未自动更新;可先排查网络后重试。');
338
+ return { code: 1 };
339
+ }
340
+ if (r.updates === 0) {
341
+ out('全部已最新,无需更新。');
342
+ return { code: 0 };
343
+ }
344
+ out('');
345
+ out('检测到 ' + r.updates + ' 个家族技能可更新,开始自动更新(安装管线,含装前安全扫描):');
346
+ var ok = 0, failed2 = 0;
347
+ for (var i = 0; i < r.rows.length; i++) {
348
+ var row = r.rows[i];
349
+ if (!row.hasUpdate) continue;
350
+ var res = installOne(Object.assign({}, row.family, { version: row.latest }), dest, Object.assign({}, opts, { force: true, pin: true }));
351
+ if (res.status === 'ok') ok++;
352
+ else if (res.status === 'skip') ok++;
353
+ else failed2++;
354
+ }
355
+ out('');
356
+ out('自动更新汇总: 成功 ' + ok + ' / 失败 ' + failed2);
357
+ maybeAutoReindex(opts, dest);
358
+ return { code: failed2 > 0 ? 1 : 0 };
359
+ }
360
+
211
361
  function shouldSkip(name, isFile) {
212
362
  if (name === '__pycache__' || name === '.pytest_cache' || name === '.mypy_cache') return true;
213
363
  if (isFile && (name.endsWith('.pyc') || name.endsWith('.pyo'))) return true;
@@ -458,6 +608,9 @@ function printHelp() {
458
608
  out(' --verify <path> 指定 yotta_verify.py 路径(默认找目标目录已装的元信)');
459
609
  out(' --json inventory / reindex / route 时输出 JSON');
460
610
  out(' --route <需求> 静态编排路由(输出组合 / 顺序 / 依据 / 缺失技能建议)');
611
+ out(' --check update 时仅只读检查更新(联网对 npm 最新版本,不改动;退出码 0/3/1)');
612
+ out(' --auto update 时检查到家族更新后自动更新(仅 yotta-* 家族,含装前扫描)');
613
+ out(' --registry <url> npm registry 地址(默认 https://registry.npmjs.org/;YOTTA_SKILLS_REGISTRY 覆盖)');
461
614
  out(' --project inventory / reindex 时附加扫描当前项目 .agents/skills / .codex/skills');
462
615
  out(' --no-reindex 安装 / 更新后不自动重扫注册表');
463
616
  out(' -h, --help 帮助');
@@ -596,7 +749,7 @@ function main() {
596
749
  let dest = resolveTargetDir(opts);
597
750
  if (!dest && !opts.dryRun) dest = detectProjectDir();
598
751
  if (!dest && command === 'install' && !opts.dryRun) {
599
- die('未指定目标:请用 --agent <name> 或 --dir <path>(当前目录未检测到项目级技能目录)。', 4);
752
+ die('未指定目标:请用 --agent <name> 或 --dir <path>(当前目录未检测到项目级技能目录)。', 4, '未收录智能体也可用 --dir 指定其技能目录。');
600
753
  }
601
754
 
602
755
  if (opts.dryRun) {
@@ -614,9 +767,29 @@ function main() {
614
767
  return;
615
768
  }
616
769
 
617
- if (command === 'update') runUpdate(opts, dest);
618
- else runInstall(opts, dest);
619
- maybeAutoReindex(opts, dest);
770
+ if (command === 'update') {
771
+ if (opts.check || opts.auto) {
772
+ var runFn = opts.auto ? runUpdateAuto : runUpdateCheck;
773
+ runFn(opts, dest).then(function (r) {
774
+ if (opts.json && !opts.auto) {
775
+ out(JSON.stringify({ dest: dest, updatable: r.rows.filter(function (x) { return x.hasUpdate; }), updates: r.updates, latest: r.latest, failed: r.failed, nonFamily: r.nonFamily }, null, 2));
776
+ }
777
+ process.exitCode = r.code;
778
+ });
779
+ } else {
780
+ runUpdate(opts, dest);
781
+ maybeAutoReindex(opts, dest);
782
+ }
783
+ } else {
784
+ runInstall(opts, dest);
785
+ maybeAutoReindex(opts, dest);
786
+ }
620
787
  }
621
788
 
622
- main();
789
+ try {
790
+ main();
791
+ } catch (err) {
792
+ process.stderr.write('错误:' + (err && err.message ? err.message : String(err)) + '\n');
793
+ process.stderr.write('修复建议:检查目标目录权限、npm 可用性与网络;可用 --help 查看用法。\n');
794
+ process.exitCode = 1;
795
+ }
@@ -0,0 +1,84 @@
1
+ # 元阁常见问题
2
+
3
+ ## 速查索引
4
+
5
+ - **安装目标**:未指定目标怎么办 · 支持哪些智能体 · 装完为什么看不到
6
+ - **网络与源**:国内访问慢 · 镜像延迟 · 网络失败
7
+ - **更新**:`update --check` 退出码 · 自动更新边界 · 幂等
8
+ - **版本**:`--pin` 与默认策略 · 清单漂移 · 单技能安装
9
+ - **安全**:装前扫描 · 目标目录校验 · 失败恢复
10
+
11
+ ---
12
+
13
+ ## 1. 安装时提示「未指定目标」怎么办?
14
+
15
+ 这表示当前目录没有检测到项目级技能目录。两种解决方式:
16
+
17
+ ```bash
18
+ npx -y @yottameta/yotta-skills --agent codex
19
+ npx -y @yottameta/yotta-skills --dir /path/to/skills
20
+ ```
21
+
22
+ `--agent` 使用内置智能体默认目录;`--dir` 适合自定义目录或未收录智能体。
23
+
24
+ ## 2. 支持哪些智能体?
25
+
26
+ 内置 17 个键名:`claude`、`cursor`、`codex`、`gemini`、`goose`、`amp`、`opencode`、`windsurf`、`workbuddy`、`kiro`、`trae`、`trae-cn`、`qwen`、`comate`、`codebuddy`、`kimi`、`agents`。未收录的智能体用 `--dir` 指定目录。
27
+
28
+ ## 3. 国内访问 npm 慢或失败怎么办?
29
+
30
+ 可用 `YOTTA_SKILLS_NPM_FLAGS` 追加 registry 参数:
31
+
32
+ ```bash
33
+ YOTTA_SKILLS_NPM_FLAGS="--registry=https://registry.npmmirror.com" npx -y @yottameta/yotta-skills --agent codex
34
+ ```
35
+
36
+ 新版本发布后镜像可能有延迟;如需立即获取,可临时改回 npm 官方源并配置代理。
37
+
38
+ ## 4. `update --check` 的退出码是什么意思?
39
+
40
+ - `0`:全部最新
41
+ - `3`:存在可更新技能
42
+ - `1`:检查失败(网络或 registry 异常)
43
+
44
+ 该命令只读,不修改文件。
45
+
46
+ ## 5. `update --auto` 会更新所有技能吗?
47
+
48
+ 只自动更新元阁家族内技能(`yotta-*` 且在清单中)。其他已装技能只提示,不自动改动。
49
+
50
+ ## 6. 重复安装会重复占空间吗?
51
+
52
+ 不会。默认按清单版本判断,已一致的技能跳过;需要强制覆盖时加 `--force`。
53
+
54
+ ## 7. `--pin` 和默认版本策略怎么选?
55
+
56
+ 默认策略是同 major 跟随最新 patch,适合日常使用;`--pin` 锁定清单精确版本,适合可复现部署。
57
+
58
+ ## 8. 为什么清单和文档版本会不一致?
59
+
60
+ 人工文档可能滞后。机器权威源是 `skills.json`,人工可读副本是 `references/skill-list.md`;当前版本已加入自动测试,两者不一致会导致测试失败。
61
+
62
+ ## 9. 如何只安装部分技能?
63
+
64
+ ```bash
65
+ npx -y @yottameta/yotta-skills install yotta-memory yotta-workflow --agent codex
66
+ ```
67
+
68
+ 也可以先用 `--route` 查看建议组合,再按需安装。
69
+
70
+ ## 10. 安装前安全扫描怎么用?
71
+
72
+ 默认会查找可用的元信引擎并输出摘要;可用 `--verify <path>` 指定引擎,或 `--skip-scan` 关闭。扫描结果仅提示,不替代人工判断。
73
+
74
+ ## 11. 安装失败后如何恢复?
75
+
76
+ 查看汇总中的失败原因,先修复目录权限或网络,再单独安装失败技能:
77
+
78
+ ```bash
79
+ npx -y @yottameta/yotta-skills install <slug> --dir /path/to/skills
80
+ ```
81
+
82
+ ## 12. 装完为什么智能体里看不到?
83
+
84
+ 确认安装目录与智能体实际读取目录一致;安装后通常需要重启会话或重新加载技能列表。
@@ -1,32 +1,32 @@
1
1
  # 全家技能清单(22 个)
2
2
 
3
3
  > 机器权威源:`skills.json`(随包分发);本文件为人工可读副本,新技能发布后须同步更新
4
- > `skills.json`(登记表为内部台账,不随包分发)。清单更新日期:2026-08-29。
4
+ > `skills.json`(登记表为内部台账,不随包分发)。清单更新日期:2026-09-08。
5
5
 
6
6
  | slug | 中文名 | npm 包 | 清单版本 | 说明 |
7
7
  |---|---|---|---|---|
8
- | `yotta-anti-shallow` | 元谨 | `@yottameta/yotta-anti-shallow` | 1.3.4 | 防 AI 敷衍规则引擎(深入分析/根因追溯时激活) |
9
- | `yotta-code-quality` | 元质 | `@yottameta/yotta-code-quality` | 0.3.4 | 结对式代码质量评审(十二类腐化风险 + 0-100 健康分) |
10
- | `yotta-workflow` | 元序 | `@yottameta/yotta-workflow` | 0.2.6 | 跨会话/跨项目通用工作流协议(状态就近存) |
11
- | `yotta-memory` | 元忆 | `@yottameta/yotta-memory` | 0.8.4 | 有权限边界的文件式智能体记忆(FACT/PREF/BOUND/COMMIT) |
8
+ | `yotta-anti-shallow` | 元谨 | `@yottameta/yotta-anti-shallow` | 1.4.0 | 防 AI 敷衍规则引擎(深入分析/根因追溯时激活) |
9
+ | `yotta-code-quality` | 元质 | `@yottameta/yotta-code-quality` | 0.4.0 | 结对式代码质量评审(十二类腐化风险 + 0-100 健康分) |
10
+ | `yotta-workflow` | 元序 | `@yottameta/yotta-workflow` | 0.3.0 | 跨会话/跨项目通用工作流协议(状态就近存) |
11
+ | `yotta-memory` | 元忆 | `@yottameta/yotta-memory` | 0.11.0 | 有权限边界的文件式智能体记忆(FACT/PREF/BOUND/COMMIT) |
12
12
  | `yotta-learn` | 元习 | `@yottameta/yotta-learn` | 0.1.4 | 学习沉淀 CLI:错误/纠正/洞见沉淀为 .learnings/ 条目 |
13
- | `yotta-security-audit` | 元安 | `@yottameta/yotta-security-audit` | 0.1.7 | 安全扫描引擎:13 类检测器 + 系统安全基线 |
14
- | `yotta-vetter` | 元审 | `@yottameta/yotta-vetter` | 0.1.5 | 安全审查协议:四阶段 review + SAFE TO INSTALL 判定 |
13
+ | `yotta-security-audit` | 元安 | `@yottameta/yotta-security-audit` | 0.2.2 | 安全扫描引擎:13 类检测器 + 系统安全基线 |
14
+ | `yotta-vetter` | 元审 | `@yottameta/yotta-vetter` | 0.2.3 | 安全审查协议:四阶段 review + SAFE TO INSTALL 判定 |
15
15
  | `yotta-recon` | 元析 | `@yottameta/yotta-recon` | 0.1.5 | 跨智能体网络侦察:零依赖端口/服务/版本指纹探测 |
16
16
  | `yotta-guardian` | 元盾 | `@yottameta/yotta-guardian` | 0.1.2 | 跨智能体危险调用拦截护栏:确定性规则 + 可插拔意图验证 |
17
- | `yotta-humanize` | 元真 | `@yottameta/yotta-humanize` | 0.1.2 | 去 AI 味中文写作编辑:检测器引擎 |
18
- | `yotta-logs` | 元史 | `@yottameta/yotta-logs` | 0.2.2 | 跨智能体历史会话 / 记忆日志检索 |
19
- | `yotta-security-testing` | 元测 | `@yottameta/yotta-security-testing` | 0.1.0 | 有纪律的 AI 安全测试方法论 + Scope Guard 五道防线 |
20
- | `yotta-agent-hardening` | 元安全 | `@yottameta/yotta-agent-hardening` | 0.1.0 | 防御向 AI 智能体自身安全加固(配置面静态扫描三域) |
17
+ | `yotta-humanize` | 元真 | `@yottameta/yotta-humanize` | 0.1.3 | 去 AI 味中文写作编辑:检测器引擎 |
18
+ | `yotta-logs` | 元史 | `@yottameta/yotta-logs` | 0.3.0 | 跨智能体历史会话 / 记忆日志检索 |
19
+ | `yotta-security-testing` | 元测 | `@yottameta/yotta-security-testing` | 0.2.4 | 有纪律的 AI 安全测试方法论 + Scope Guard 五道防线 |
20
+ | `yotta-agent-hardening` | 元安全 | `@yottameta/yotta-agent-hardening` | 0.2.4 | 防御向 AI 智能体自身安全加固(配置面静态扫描三域) |
21
21
  | `yotta-skill-creator` | 元造 | `@yottameta/yotta-skill-creator` | 0.1.0 | 工坊「造」:端到端造技能脚手架 |
22
- | `yotta-publish-guard` | 元守 | `@yottameta/yotta-publish-guard` | 0.1.1 | 工坊「守」:发布前守门(版本四件对齐 + 三通道查重) |
22
+ | `yotta-publish-guard` | 元守 | `@yottameta/yotta-publish-guard` | 0.2.1 | 工坊「守」:发布前守门(版本四件对齐 + 三通道查重) |
23
23
  | `yotta-logwatch` | 元察 | `@yottameta/yotta-logwatch` | 0.2.7 | 安全日志分析检测引擎(攻击链识别/告警聚合) |
24
24
  | `yotta-intel` | 元情 | `@yottameta/yotta-intel` | 0.1.1 | 威胁情报 IOC 提取与规范化引擎(STIX-lite) |
25
25
  | `yotta-secret` | 元钥 | `@yottameta/yotta-secret` | 0.1.2 | 密钥 / 凭据泄露源头扫描引擎 |
26
26
  | `yotta-chain` | 元链 | `@yottameta/yotta-chain` | 0.1.2 | 供应链依赖校验引擎 |
27
27
  | `yotta-triage` | 元鉴 | `@yottameta/yotta-triage` | 0.1.1 | 恶意样本静态初筛引擎(哈希/熵/字符串/PE-ELF) |
28
- | `yotta-prompt` | 元引 | `@yottameta/yotta-prompt` | 0.1.1 | 意图澄清 + 生态入口(常驻注入,map 串联元阁全家) |
29
- | `yotta-verify` | 元信 | `@yottameta/yotta-verify` | 0.1.1 | 装前安全扫描器 + audited 徽章(prompt injection + 危险模式) |
28
+ | `yotta-prompt` | 元引 | `@yottameta/yotta-prompt` | 0.2.0 | 意图澄清 + 生态入口(常驻注入,map 串联元阁全家) |
29
+ | `yotta-verify` | 元信 | `@yottameta/yotta-verify` | 0.2.2 | 装前安全扫描器 + audited 徽章(prompt injection + 危险模式) |
30
30
 
31
31
  ## 家族分布
32
32
 
@@ -0,0 +1,61 @@
1
+ # 元阁复杂场景走查
2
+
3
+ ## 走查 1:新智能体初始化
4
+
5
+ 目标:在一台新机器上为 Codex 安装元阁家族。
6
+
7
+ 1. 查看清单:
8
+
9
+ ```bash
10
+ npx -y @yottameta/yotta-skills --list
11
+ ```
12
+
13
+ 2. 安装到默认目录:
14
+
15
+ ```bash
16
+ npx -y @yottameta/yotta-skills --agent codex
17
+ ```
18
+
19
+ 3. 核对结果:输出应包含安装路径与成功 / 跳过 / 失败汇总。
20
+
21
+ 4. 重启会话后输入“列出已装技能”,确认注册表能读取到新技能。
22
+
23
+ ## 走查 2:版本漂移更新
24
+
25
+ 背景:本机已装 22 个技能,其中 5 个版本落后。
26
+
27
+ 1. 只读检查:
28
+
29
+ ```bash
30
+ npx -y @yottameta/yotta-skills update --check --agent codex
31
+ ```
32
+
33
+ 2. 根据输出确认可更新清单。
34
+
35
+ 3. 执行增量更新:
36
+
37
+ ```bash
38
+ npx -y @yottameta/yotta-skills update --agent codex
39
+ ```
40
+
41
+ 4. 复核:已最新的技能应显示跳过,落后的技能显示更新;失败项单独重装。
42
+
43
+ ## 走查 3:按路由安装单个技能
44
+
45
+ 用户需求:“帮我做发布前质量检查。”
46
+
47
+ 1. 路由:
48
+
49
+ ```bash
50
+ npx -y @yottameta/yotta-skills --route "发布前质量检查"
51
+ ```
52
+
53
+ 2. 输出建议组合与缺失技能。
54
+
55
+ 3. 只安装缺失技能:
56
+
57
+ ```bash
58
+ npx -y @yottameta/yotta-skills install yotta-code-quality yotta-anti-shallow --agent codex
59
+ ```
60
+
61
+ 4. 重新执行路由,确认缺失技能已补齐。
@@ -24,7 +24,7 @@ import subprocess
24
24
  import sys
25
25
  from pathlib import Path
26
26
 
27
- VERSION = "0.6.1"
27
+ VERSION = "0.7.0"
28
28
  TOOL_NAME = "yotta-skills"
29
29
  CN_NAME = "元阁"
30
30
  MCP_PROTOCOL_MODERN = "2026-07-28"