@social-data/social-neuron-subscription 1.0.0-beta.2 → 1.0.0-beta.20
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/bin/cli.js +72 -8
- package/bin/install-skills.js +1 -1
- package/manifest.json +734 -59
- package/package.json +1 -1
- package/skills/social-neuron-subscription/SKILL.md +314 -31
package/bin/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
|
-
// ⚠️ 本文件由
|
|
4
|
+
// ⚠️ 本文件由 core/cli/gen.py 生成,请勿手改;要改改 gen.py 的 _CLI_JS 后重跑 gen。
|
|
5
5
|
//
|
|
6
6
|
// 能力 CLI —— 通用薄运行时(纯 JS,零依赖):一能力一命令、一包、一配置文件,互不影响。
|
|
7
7
|
// <cmd> <action> [--flags] 调用一条命令
|
|
@@ -40,7 +40,11 @@ function resolveConfig() {
|
|
|
40
40
|
|
|
41
41
|
function emit(env) {
|
|
42
42
|
process.stdout.write(JSON.stringify(env) + "\n");
|
|
43
|
-
|
|
43
|
+
const dataExit = env.ok && env.data && env.data.meta && env.data.meta.exit_code;
|
|
44
|
+
const status = env.ok
|
|
45
|
+
? ([0, 1, 2].includes(dataExit) ? dataExit : 0)
|
|
46
|
+
: (EXIT[env.error && env.error.type] ?? 1);
|
|
47
|
+
process.exit(status);
|
|
44
48
|
}
|
|
45
49
|
function fail(type, code, message, extra) {
|
|
46
50
|
emit({ ok: false, error: { type, code, message, ...(extra || {}) } });
|
|
@@ -61,7 +65,9 @@ function normalize(body) {
|
|
|
61
65
|
const type = forgeType(body.code);
|
|
62
66
|
let message = body.msg || "";
|
|
63
67
|
if (type === "outdated") message += "(升级后请重新加载 SKILL.md 与 manifest 再调用)";
|
|
64
|
-
|
|
68
|
+
// 网关在 data 里带审计 trace_id 的业务错误(如查询失败):透出供 get-query 回查。
|
|
69
|
+
const extra = body.data && body.data.trace_id ? { trace_id: body.data.trace_id } : {};
|
|
70
|
+
return { ok: false, error: { type, code: body.code, message, ...extra } };
|
|
65
71
|
}
|
|
66
72
|
return { ok: false, error: { type: "api_error", code: "UNKNOWN", message: JSON.stringify(body).slice(0, 200) } };
|
|
67
73
|
}
|
|
@@ -109,15 +115,63 @@ function printWelcome() {
|
|
|
109
115
|
w("──────────────────────────────────────────────");
|
|
110
116
|
}
|
|
111
117
|
|
|
118
|
+
// ── 嵌套对象形状:object(json) / list[object](json) 这类 flag 光看类型名没法拼 JSON,
|
|
119
|
+
// 这里把 input_schema.$defs 里**被引用到的**对象摊开印出来(与 SKILL.md 同源同内容)。
|
|
120
|
+
// 没有这段时,调用方只能靠 422 报错反推字段名。
|
|
121
|
+
function typeStr(node) {
|
|
122
|
+
if (!node || typeof node !== "object") return "any";
|
|
123
|
+
if (typeof node.$ref === "string") return node.$ref.split("/").pop();
|
|
124
|
+
const union = node.anyOf || node.oneOf;
|
|
125
|
+
if (union) {
|
|
126
|
+
const parts = union.filter((n) => n && n.type !== "null").map(typeStr);
|
|
127
|
+
return parts.length ? parts.join("|") : "any";
|
|
128
|
+
}
|
|
129
|
+
if (Array.isArray(node.enum)) return "enum(" + node.enum.join("|") + ")";
|
|
130
|
+
if (node.type === "array") return "list[" + typeStr(node.items) + "]";
|
|
131
|
+
return node.type || "any";
|
|
132
|
+
}
|
|
133
|
+
function refsOf(node, acc) {
|
|
134
|
+
if (!node || typeof node !== "object") return acc;
|
|
135
|
+
if (Array.isArray(node)) { for (const n of node) refsOf(n, acc); return acc; }
|
|
136
|
+
if (typeof node.$ref === "string") acc.add(node.$ref.split("/").pop());
|
|
137
|
+
for (const k of Object.keys(node)) if (k !== "$defs") refsOf(node[k], acc);
|
|
138
|
+
return acc;
|
|
139
|
+
}
|
|
140
|
+
function objectBlocks(schema) {
|
|
141
|
+
const defs = (schema && schema.$defs) || {};
|
|
142
|
+
const queue = [...refsOf((schema && schema.properties) || {}, new Set())], seen = new Set();
|
|
143
|
+
while (queue.length) { // 递归:GroupLevel 会引用自己、Leaf 会被 AndNode 引用
|
|
144
|
+
const name = queue.shift();
|
|
145
|
+
if (seen.has(name) || !defs[name]) continue;
|
|
146
|
+
seen.add(name);
|
|
147
|
+
for (const r of refsOf(defs[name], new Set())) queue.push(r);
|
|
148
|
+
}
|
|
149
|
+
const out = [];
|
|
150
|
+
for (const name of [...seen].sort()) {
|
|
151
|
+
const d = defs[name], props = d.properties;
|
|
152
|
+
if (!props) continue;
|
|
153
|
+
const required = new Set(d.required || []);
|
|
154
|
+
const rows = Object.keys(props).map((k) => [k, typeStr(props[k]), required.has(k) ? "required" : "optional",
|
|
155
|
+
props[k].description || ""]);
|
|
156
|
+
const w0 = Math.max(...rows.map((r) => r[0].length)), w1 = Math.max(...rows.map((r) => r[1].length));
|
|
157
|
+
out.push("对象 " + name + ":" + (d.description ? " " + d.description.split("\n")[0] : ""));
|
|
158
|
+
for (const r of rows) out.push(" " + r[0].padEnd(w0) + " " + r[1].padEnd(w1) + " " + r[2].padEnd(8) + " " + r[3]);
|
|
159
|
+
}
|
|
160
|
+
return out;
|
|
161
|
+
}
|
|
162
|
+
|
|
112
163
|
function usageOf(cmd) {
|
|
113
164
|
const line = (f) => " " + f.flag + " " + f.type + (f.required ? " required" : " optional") + " " + (f.desc || "");
|
|
114
165
|
const req = cmd.flags.filter((f) => f.required), opt = cmd.flags.filter((f) => !f.required);
|
|
166
|
+
const blocks = objectBlocks(cmd.input_schema);
|
|
115
167
|
return {
|
|
116
168
|
command: COMMAND + " " + cmd.action,
|
|
117
169
|
required: req.map((f) => ({ flag: f.flag, type: f.type, desc: f.desc })),
|
|
118
170
|
optional: opt.map((f) => ({ flag: f.flag, type: f.type, desc: f.desc })),
|
|
171
|
+
objects: blocks, // 同样带进 INVALID_ARGS 报错里,拼错时直接能看到形状
|
|
119
172
|
example: (COMMAND + " " + cmd.action + " " + req.map((f) => f.flag + " <v>").join(" ")).trim(),
|
|
120
|
-
_text: [COMMAND + " " + cmd.action + " — " + cmd.summary, "Inputs:", ...cmd.flags.map(line)
|
|
173
|
+
_text: [COMMAND + " " + cmd.action + " — " + cmd.summary, "Inputs:", ...cmd.flags.map(line),
|
|
174
|
+
...(blocks.length ? ["", ...blocks] : [])].join("\n"),
|
|
121
175
|
};
|
|
122
176
|
}
|
|
123
177
|
function printHelp(action) {
|
|
@@ -130,7 +184,7 @@ function printHelp(action) {
|
|
|
130
184
|
w(COMMAND + " v" + VERSION + " — Social Neuron 能力 CLI(能力:" + CAPABILITY + ";供 AI agent 调用)");
|
|
131
185
|
w("");
|
|
132
186
|
w("用法:" + COMMAND + " <action> [--flags]");
|
|
133
|
-
w(" 标量 --flag v
|
|
187
|
+
w(" 标量 --flag v;数组/对象一律 JSON:--flag '[\"a\",\"b\"]' / --flag '{\"k\":\"v\"}';写/删/触发加 -y");
|
|
134
188
|
w("");
|
|
135
189
|
w("命令:");
|
|
136
190
|
for (const c of MANIFEST.tools) w(" " + COMMAND + " " + c.action + " — " + c.summary);
|
|
@@ -158,8 +212,17 @@ function parseArgs(cmd, argv) {
|
|
|
158
212
|
const raw = argv[++i];
|
|
159
213
|
if (raw === undefined) return { err: fail("validation", "MISSING_VALUE", a + " 缺少取值") };
|
|
160
214
|
let val = raw;
|
|
161
|
-
if (f.type.
|
|
162
|
-
|
|
215
|
+
if (f.type.indexOf("(json)") >= 0) {
|
|
216
|
+
// 数组/对象一律按 JSON 解析(与 MCP 入参同形)。不做「逗号分隔」这类特例:
|
|
217
|
+
// 同一份文档要能同时用于两个出口,取值写法就只能有一种。
|
|
218
|
+
try { val = JSON.parse(raw); } catch {
|
|
219
|
+
const hint = f.type.startsWith("list") ? "JSON 数组,如 '[\"a\",\"b\"]'" : "JSON 对象,如 '{\"k\":\"v\"}'";
|
|
220
|
+
return { err: fail("validation", "BAD_JSON", a + " 需为 " + hint + "(当前取值:" + raw + ")") };
|
|
221
|
+
}
|
|
222
|
+
if (f.type.startsWith("list") && !Array.isArray(val)) {
|
|
223
|
+
return { err: fail("validation", "BAD_JSON", a + " 需为 JSON 数组,如 '[\"a\",\"b\"]';单个取值也要写成数组") };
|
|
224
|
+
}
|
|
225
|
+
}
|
|
163
226
|
else if (f.type === "integer") val = Number(raw);
|
|
164
227
|
args[f.field] = val;
|
|
165
228
|
}
|
|
@@ -167,7 +230,8 @@ function parseArgs(cmd, argv) {
|
|
|
167
230
|
}
|
|
168
231
|
|
|
169
232
|
async function main() {
|
|
170
|
-
|
|
233
|
+
let argv = process.argv.slice(2);
|
|
234
|
+
if (argv.length === 0 && MANIFEST.default_action) argv = [MANIFEST.default_action];
|
|
171
235
|
if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") return printHelp();
|
|
172
236
|
if (argv[0] === "--version" || argv[0] === "-V") { process.stdout.write(VERSION + "\n"); return; }
|
|
173
237
|
if (argv[0] === "bind") return doBind(argv.slice(1));
|
package/bin/install-skills.js
CHANGED