@yottameta/yotta-skills-plugin 0.5.1 → 0.6.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.
|
|
15
|
+
"version": "0.6.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.
|
|
15
|
+
"version": "0.6.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
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.
|
|
4
|
+
"version": "0.6.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,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yotta-skills
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.6.0
|
|
4
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 污染全局、不自动安装缺失技能;装前摘要仅供参考,安装决策由用户确认。
|
|
5
5
|
license: MIT
|
|
6
6
|
metadata:
|
|
@@ -179,6 +179,7 @@ npx -y @yottameta/yotta-skills --route "检查代码质量,别糊弄" --json
|
|
|
179
179
|
### MCP:按需加载(可选)
|
|
180
180
|
|
|
181
181
|
本技能自带一个 MCP server:`yotta-skills`(`scripts/yotta-skills-mcp.py`,零依赖、数据不出本机),
|
|
182
|
+
基于 MCP 最新协议 2026-07-28(无状态时代;向后兼容 2025-11-25 及更早握手客户端)。
|
|
182
183
|
提供 `list_installed_skills`(盘点)/ `describe_skill`(单技能详情)/ `reindex`(强制重扫)/ `route_request`(静态编排路由)四个工具。
|
|
183
184
|
|
|
184
185
|
**按需加载,不走常驻**:本技能与 MCP 均为按需触发。默认以 CLI 为主
|
|
@@ -24,10 +24,12 @@ import subprocess
|
|
|
24
24
|
import sys
|
|
25
25
|
from pathlib import Path
|
|
26
26
|
|
|
27
|
-
VERSION = "0.
|
|
27
|
+
VERSION = "0.6.0"
|
|
28
28
|
TOOL_NAME = "yotta-skills"
|
|
29
29
|
CN_NAME = "元阁"
|
|
30
|
-
|
|
30
|
+
MCP_PROTOCOL_MODERN = "2026-07-28"
|
|
31
|
+
MCP_PROTOCOL_LEGACY = "2025-11-25"
|
|
32
|
+
SERVER_INFO = {"name": TOOL_NAME, "version": VERSION}
|
|
31
33
|
SERVERS = {TOOL_NAME: {"name": TOOL_NAME, "cn": CN_NAME, "version": VERSION}}
|
|
32
34
|
|
|
33
35
|
_HERE = Path(__file__).resolve().parent
|
|
@@ -193,8 +195,41 @@ def mcp_tools():
|
|
|
193
195
|
]
|
|
194
196
|
|
|
195
197
|
|
|
198
|
+
def _req_version(params):
|
|
199
|
+
"""取请求声明的最新协议版本(modern _meta 字段);无 = legacy。"""
|
|
200
|
+
meta = (params or {}).get("_meta") or {}
|
|
201
|
+
return meta.get("io.modelcontextprotocol/protocolVersion")
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def _modern_ok(payload, cache=None):
|
|
205
|
+
"""modern 结果包装:resultType + _meta.serverInfo(list/discover 加 ttlMs/cacheScope)。"""
|
|
206
|
+
out = {"resultType": "complete"}
|
|
207
|
+
out.update(payload)
|
|
208
|
+
out["_meta"] = {"io.modelcontextprotocol/serverInfo": dict(SERVER_INFO)}
|
|
209
|
+
if cache:
|
|
210
|
+
out["ttlMs"] = cache[0]
|
|
211
|
+
out["cacheScope"] = cache[1]
|
|
212
|
+
return out
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def _unsupported_version(rid, pv):
|
|
216
|
+
return {
|
|
217
|
+
"jsonrpc": "2.0", "id": rid,
|
|
218
|
+
"error": {
|
|
219
|
+
"code": -32022,
|
|
220
|
+
"message": "Unsupported protocol version",
|
|
221
|
+
"data": {"supported": [MCP_PROTOCOL_MODERN], "requested": pv},
|
|
222
|
+
},
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
|
|
196
226
|
def handle_message(msg):
|
|
197
|
-
"""处理一行 JSON-RPC 消息,返回响应 dict;通知返回 None。
|
|
227
|
+
"""处理一行 JSON-RPC 消息,返回响应 dict;通知返回 None。
|
|
228
|
+
|
|
229
|
+
双时代(dual-era):请求 _meta 带 io.modelcontextprotocol/protocolVersion =
|
|
230
|
+
modern(2026-07-28 无状态,server/discover 取代握手);无该字段 = legacy
|
|
231
|
+
(2025-11-25 及更早,initialize 握手),响应保持旧形状。
|
|
232
|
+
"""
|
|
198
233
|
if not isinstance(msg, dict) or msg.get("jsonrpc") != "2.0":
|
|
199
234
|
rid = msg.get("id") if isinstance(msg, dict) else None
|
|
200
235
|
return {"jsonrpc": "2.0", "id": rid, "error": {"code": -32600, "message": "invalid request"}}
|
|
@@ -205,14 +240,60 @@ def handle_message(msg):
|
|
|
205
240
|
if method is None:
|
|
206
241
|
return None
|
|
207
242
|
params = msg.get("params") or {}
|
|
243
|
+
pv = _req_version(params)
|
|
244
|
+
|
|
245
|
+
if pv is not None:
|
|
246
|
+
# ---- modern(2026-07-28 无状态)----
|
|
247
|
+
if pv != MCP_PROTOCOL_MODERN:
|
|
248
|
+
return _unsupported_version(rid, pv)
|
|
249
|
+
if method == "server/discover":
|
|
250
|
+
return {
|
|
251
|
+
"jsonrpc": "2.0", "id": rid,
|
|
252
|
+
"result": _modern_ok({
|
|
253
|
+
"supportedVersions": [MCP_PROTOCOL_MODERN],
|
|
254
|
+
"capabilities": {"tools": {}},
|
|
255
|
+
"instructions": "元阁 MCP(基于 MCP 最新协议 2026-07-28,向后兼容 2025-11-25 及更早握手):本机技能盘点与静态编排路由 list_installed_skills/describe_skill/reindex/route_request;数据不出本机。",
|
|
256
|
+
}, (3600000, "public")),
|
|
257
|
+
}
|
|
258
|
+
if method == "tools/list":
|
|
259
|
+
return {
|
|
260
|
+
"jsonrpc": "2.0", "id": rid,
|
|
261
|
+
"result": _modern_ok({"tools": mcp_tools()}, (300000, "public")),
|
|
262
|
+
}
|
|
263
|
+
if method == "tools/call":
|
|
264
|
+
name = params.get("name")
|
|
265
|
+
arguments = params.get("arguments") or {}
|
|
266
|
+
handler = TOOL_HANDLERS.get(name)
|
|
267
|
+
if not handler:
|
|
268
|
+
return {
|
|
269
|
+
"jsonrpc": "2.0", "id": rid,
|
|
270
|
+
"result": _modern_ok({"content": [{"type": "text", "text": "未知工具: %s" % name}], "isError": True}),
|
|
271
|
+
}
|
|
272
|
+
try:
|
|
273
|
+
return {"jsonrpc": "2.0", "id": rid, "result": _modern_ok(handler(arguments))}
|
|
274
|
+
except Exception as e: # noqa: BLE001
|
|
275
|
+
return {
|
|
276
|
+
"jsonrpc": "2.0", "id": rid,
|
|
277
|
+
"result": _modern_ok({"content": [{"type": "text", "text": "工具执行异常:%s" % e}], "isError": True}),
|
|
278
|
+
}
|
|
279
|
+
if method == "initialize":
|
|
280
|
+
return {
|
|
281
|
+
"jsonrpc": "2.0", "id": rid,
|
|
282
|
+
"error": {
|
|
283
|
+
"code": -32601,
|
|
284
|
+
"message": "initialize removed in MCP 2026-07-28; use server/discover. supported: ['2026-07-28']",
|
|
285
|
+
},
|
|
286
|
+
}
|
|
287
|
+
return {"jsonrpc": "2.0", "id": rid, "error": {"code": -32601, "message": "Method not found: " + str(method)}}
|
|
208
288
|
|
|
289
|
+
# ---- legacy(<=2025-11-25,initialize 握手;响应保持旧形状)----
|
|
209
290
|
if method == "initialize":
|
|
210
291
|
return {
|
|
211
292
|
"jsonrpc": "2.0", "id": rid,
|
|
212
293
|
"result": {
|
|
213
|
-
"protocolVersion":
|
|
294
|
+
"protocolVersion": MCP_PROTOCOL_LEGACY,
|
|
214
295
|
"capabilities": {"tools": {}},
|
|
215
|
-
"serverInfo":
|
|
296
|
+
"serverInfo": SERVER_INFO,
|
|
216
297
|
},
|
|
217
298
|
}
|
|
218
299
|
if method == "ping":
|
|
@@ -229,7 +310,10 @@ def handle_message(msg):
|
|
|
229
310
|
"result": {"content": [{"type": "text", "text": "未知工具: %s" % name}], "isError": True},
|
|
230
311
|
}
|
|
231
312
|
try:
|
|
232
|
-
return {
|
|
313
|
+
return {
|
|
314
|
+
"jsonrpc": "2.0", "id": rid,
|
|
315
|
+
"result": handler(arguments),
|
|
316
|
+
}
|
|
233
317
|
except Exception as e: # noqa: BLE001
|
|
234
318
|
return {
|
|
235
319
|
"jsonrpc": "2.0", "id": rid,
|
|
@@ -237,7 +321,6 @@ def handle_message(msg):
|
|
|
237
321
|
}
|
|
238
322
|
return {"jsonrpc": "2.0", "id": rid, "error": {"code": -32601, "message": "Method not found: " + str(method)}}
|
|
239
323
|
|
|
240
|
-
|
|
241
324
|
def main():
|
|
242
325
|
"""stdio 主循环:读行 -> JSON-RPC -> 响应行。"""
|
|
243
326
|
try:
|