siluzan-tso-cli 1.1.29-beta.7 → 1.1.29-beta.9
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/README.md +1 -1
- package/dist/index.js +122 -3
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/accounts/accounts.md +20 -0
- package/dist/skill/references/accounts/open-account-by-media.md +4 -2
- package/dist/skill/references/core/agent-conventions.md +8 -0
- package/dist/skill/scripts/install.ps1 +1 -1
- package/dist/skill/scripts/install.sh +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
|
|
|
51
51
|
siluzan-tso init --force # 强制覆盖已存在文件
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
> **注意**:当前为测试版(1.1.29-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.29-beta.9),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -2601,6 +2601,9 @@ function pickStr(obj, key) {
|
|
|
2601
2601
|
const v = obj[key];
|
|
2602
2602
|
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
2603
2603
|
}
|
|
2604
|
+
function pickPhone(data) {
|
|
2605
|
+
return pickStr(data, "phone") ?? pickStr(data, "mobile") ?? pickStr(data, "phoneNumber") ?? pickStr(data, "mobilePhone");
|
|
2606
|
+
}
|
|
2604
2607
|
function pickCompanyId(data) {
|
|
2605
2608
|
const direct = pickStr(data, "companyId") ?? pickStr(data, "companyID") ?? pickStr(data, "CompanyId");
|
|
2606
2609
|
if (direct) return direct;
|
|
@@ -2617,10 +2620,11 @@ function parseMeResponse(text) {
|
|
|
2617
2620
|
const data = json?.data && typeof json.data === "object" ? json.data : json;
|
|
2618
2621
|
const id = pickStr(data, "entityId") ?? pickStr(data, "id") ?? pickStr(data, "userId") ?? pickStr(data, "accountId");
|
|
2619
2622
|
const email = pickStr(data, "email");
|
|
2620
|
-
const
|
|
2623
|
+
const phone = pickPhone(data);
|
|
2624
|
+
const username = pickStr(data, "userName") ?? pickStr(data, "username") ?? pickStr(data, "name") ?? phone;
|
|
2621
2625
|
const companyId = pickCompanyId(data);
|
|
2622
|
-
if (!id && !email && !username && !companyId) return null;
|
|
2623
|
-
return { id, email, username, companyId };
|
|
2626
|
+
if (!id && !email && !username && !phone && !companyId) return null;
|
|
2627
|
+
return { id, email, username, phone, companyId };
|
|
2624
2628
|
} catch {
|
|
2625
2629
|
return null;
|
|
2626
2630
|
}
|
|
@@ -2645,6 +2649,7 @@ async function fetchSiluzanCurrentUser(apiBase, config) {
|
|
|
2645
2649
|
entityId: parsed.id,
|
|
2646
2650
|
email: parsed.email,
|
|
2647
2651
|
username: parsed.username,
|
|
2652
|
+
phone: parsed.phone,
|
|
2648
2653
|
companyId: parsed.companyId
|
|
2649
2654
|
};
|
|
2650
2655
|
} catch {
|
|
@@ -3099,6 +3104,18 @@ function normalizeChinaPhone(input) {
|
|
|
3099
3104
|
function isValidChinaPhone(input) {
|
|
3100
3105
|
return /^\+861\d{10}$/.test(normalizeChinaPhone(input));
|
|
3101
3106
|
}
|
|
3107
|
+
function chinaPhonesEqual(a, b) {
|
|
3108
|
+
const na = normalizeChinaPhone(a.trim());
|
|
3109
|
+
const nb = normalizeChinaPhone(b.trim());
|
|
3110
|
+
if (isValidChinaPhone(na) && isValidChinaPhone(nb)) {
|
|
3111
|
+
return na === nb;
|
|
3112
|
+
}
|
|
3113
|
+
const da = a.replace(/\D/g, "");
|
|
3114
|
+
const db = b.replace(/\D/g, "");
|
|
3115
|
+
const ca = da.length >= 11 ? da.slice(-11) : da;
|
|
3116
|
+
const cb = db.length >= 11 ? db.slice(-11) : db;
|
|
3117
|
+
return ca.length === 11 && cb.length === 11 && ca === cb;
|
|
3118
|
+
}
|
|
3102
3119
|
async function sendPhoneLoginCode(opts) {
|
|
3103
3120
|
const phone = normalizeChinaPhone(opts.phone);
|
|
3104
3121
|
const url = `${opts.ssoBaseUrl}/Account/SendVaildCode?Phone=${encodeURIComponent(
|
|
@@ -119379,6 +119396,89 @@ function register22(program2) {
|
|
|
119379
119396
|
);
|
|
119380
119397
|
}
|
|
119381
119398
|
|
|
119399
|
+
// src/commands/account-manage/me.ts
|
|
119400
|
+
init_dist();
|
|
119401
|
+
init_auth();
|
|
119402
|
+
init_cli_json_snapshot();
|
|
119403
|
+
function maskPhone(phone) {
|
|
119404
|
+
if (!phone) return "\u2014";
|
|
119405
|
+
const digits = phone.replace(/\D/g, "");
|
|
119406
|
+
if (digits.length < 7) return phone;
|
|
119407
|
+
const tail = digits.slice(-4);
|
|
119408
|
+
return `${digits.slice(0, 3)}****${tail}`;
|
|
119409
|
+
}
|
|
119410
|
+
async function runAccountMe(opts) {
|
|
119411
|
+
const config = loadConfig(opts.token);
|
|
119412
|
+
const me = await fetchSiluzanCurrentUser(config.apiBaseUrl, config);
|
|
119413
|
+
if (!me) {
|
|
119414
|
+
console.error(
|
|
119415
|
+
"\n\u274C \u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u8D26\u53F7\u4FE1\u606F\uFF08GET /query/account/me\uFF09\u3002\u8BF7\u68C0\u67E5\u51ED\u636E\u662F\u5426\u6709\u6548\uFF1Asiluzan-tso config show\n"
|
|
119416
|
+
);
|
|
119417
|
+
process.exit(1);
|
|
119418
|
+
}
|
|
119419
|
+
const phoneNormalized = me.phone ? normalizeChinaPhone(me.phone) : void 0;
|
|
119420
|
+
const payload = {
|
|
119421
|
+
entityId: me.entityId,
|
|
119422
|
+
email: me.email,
|
|
119423
|
+
username: me.username,
|
|
119424
|
+
phone: me.phone,
|
|
119425
|
+
phoneNormalized,
|
|
119426
|
+
companyId: me.companyId
|
|
119427
|
+
};
|
|
119428
|
+
if (opts.checkPhone?.trim()) {
|
|
119429
|
+
const requested = opts.checkPhone.trim();
|
|
119430
|
+
payload.requestedPhone = requested;
|
|
119431
|
+
if (!me.phone) {
|
|
119432
|
+
payload.matched = false;
|
|
119433
|
+
payload.message = "\u5F53\u524D\u767B\u5F55\u51ED\u636E\u672A\u8FD4\u56DE\u624B\u673A\u53F7\uFF0C\u65E0\u6CD5\u6821\u9A8C\u662F\u5426\u4E0E\u6307\u5B9A\u4F01\u4E1A\u7BA1\u5BB6\u8D26\u53F7\u4E00\u81F4\uFF1B\u8BF7\u4F7F\u7528\u8BE5\u624B\u673A\u53F7\u91CD\u65B0\u767B\u5F55\u540E\u518D\u67E5\u8BE2\u3002";
|
|
119434
|
+
} else {
|
|
119435
|
+
payload.matched = chinaPhonesEqual(me.phone, requested);
|
|
119436
|
+
if (!payload.matched) {
|
|
119437
|
+
payload.message = "\u6307\u5B9A\u624B\u673A\u53F7\u4E0E\u5F53\u524D\u767B\u5F55\u8D26\u53F7\u4E0D\u4E00\u81F4\uFF1B\u6682\u65F6\u4E0D\u652F\u6301\u67E5\u8BE2\u5176\u4ED6\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u4E0B\u7684\u6570\u636E\uFF0C\u8BF7\u4F7F\u7528\u8BE5\u624B\u673A\u53F7\u91CD\u65B0\u767B\u5F55\u3002";
|
|
119438
|
+
}
|
|
119439
|
+
}
|
|
119440
|
+
}
|
|
119441
|
+
if (await emitCliJsonOrSnapshot(opts, {
|
|
119442
|
+
section: "account-me",
|
|
119443
|
+
commandLabel: "account me",
|
|
119444
|
+
payload
|
|
119445
|
+
})) {
|
|
119446
|
+
if (opts.checkPhone?.trim() && payload.matched === false) {
|
|
119447
|
+
process.exit(1);
|
|
119448
|
+
}
|
|
119449
|
+
return;
|
|
119450
|
+
}
|
|
119451
|
+
console.log("\n\u5F53\u524D\u767B\u5F55\u4E1D\u8DEF\u8D5E\u8D26\u53F7\uFF1A");
|
|
119452
|
+
console.log(` entityId : ${me.entityId ?? "\u2014"}`);
|
|
119453
|
+
console.log(` \u7528\u6237\u540D : ${me.username ?? "\u2014"}`);
|
|
119454
|
+
console.log(` \u624B\u673A\u53F7 : ${me.phone ?? "\u2014"}`);
|
|
119455
|
+
console.log(` \u90AE\u7BB1 : ${me.email ?? "\u2014"}`);
|
|
119456
|
+
console.log(` companyId : ${me.companyId ?? "\u2014"}`);
|
|
119457
|
+
console.log();
|
|
119458
|
+
if (opts.checkPhone?.trim()) {
|
|
119459
|
+
const requested = opts.checkPhone.trim();
|
|
119460
|
+
if (payload.matched) {
|
|
119461
|
+
console.log(`\u2705 \u624B\u673A\u53F7\u6821\u9A8C\u901A\u8FC7\uFF1A\u4E0E\u5F53\u524D\u767B\u5F55\u8D26\u53F7\u4E00\u81F4\uFF08${maskPhone(me.phone)}\uFF09
|
|
119462
|
+
`);
|
|
119463
|
+
return;
|
|
119464
|
+
}
|
|
119465
|
+
console.error(
|
|
119466
|
+
`
|
|
119467
|
+
\u274C \u6682\u65F6\u4E0D\u652F\u6301\u67E5\u8BE2\u5176\u4ED6\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u4E0B\u7684\u6570\u636E\u3002
|
|
119468
|
+
\u60A8\u6307\u5B9A\u7684\u662F\uFF1A${requested}
|
|
119469
|
+
\u5F53\u524D\u767B\u5F55\u8D26\u53F7\uFF1A${me.phone ?? "\uFF08\u672A\u80FD\u8BC6\u522B\u624B\u673A\u53F7\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\uFF09"}
|
|
119470
|
+
|
|
119471
|
+
\u5982\u9700\u67E5\u8BE2\u8BE5\u8D26\u53F7\u6570\u636E\uFF0C\u8BF7\u4F7F\u7528\u8BE5\u624B\u673A\u53F7\u91CD\u65B0\u767B\u5F55\uFF1A
|
|
119472
|
+
1) siluzan-tso send-login-code --phone ${requested}
|
|
119473
|
+
2) siluzan-tso login --phone ${requested} --code <\u9A8C\u8BC1\u7801>
|
|
119474
|
+
|
|
119475
|
+
\u9700\u8981\u6211\u5E2E\u60A8\u5207\u6362\u767B\u5F55\u5417\uFF1F
|
|
119476
|
+
`
|
|
119477
|
+
);
|
|
119478
|
+
process.exit(1);
|
|
119479
|
+
}
|
|
119480
|
+
}
|
|
119481
|
+
|
|
119382
119482
|
// src/commands/account-manage/share.ts
|
|
119383
119483
|
init_auth();
|
|
119384
119484
|
init_cli_json_snapshot();
|
|
@@ -120506,6 +120606,25 @@ async function runAccountBmBind(opts) {
|
|
|
120506
120606
|
// src/commands/account-manage-register.ts
|
|
120507
120607
|
function register23(program2) {
|
|
120508
120608
|
const accountCmd = program2.command("account").description("\u5E7F\u544A\u8D26\u6237\u7BA1\u7406\uFF1AOAuth \u6DFB\u52A0\u6388\u6743\u3001\u89E3\u9664\u5173\u8054\uFF08\u89E3\u7ED1\uFF09\u3001Google MCC \u7ED1\u5B9A/\u89E3\u7ED1\u3001\u8D26\u53F7\u5206\u4EAB");
|
|
120609
|
+
accountCmd.command("me").description(
|
|
120610
|
+
"\u67E5\u8BE2\u5F53\u524D\u767B\u5F55\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u4FE1\u606F\uFF08GET /query/account/me\uFF09\uFF1B--check-phone \u7528\u4E8E\u6821\u9A8C\u7528\u6237\u6307\u5B9A\u7684\u4F01\u4E1A\u7BA1\u5BB6\u624B\u673A\u53F7"
|
|
120611
|
+
).option("-t, --token <token>", "Auth Token").option(
|
|
120612
|
+
"--check-phone <phone>",
|
|
120613
|
+
"\u4E0E\u7528\u6237\u6D88\u606F\u4E2D\u7684\u624B\u673A\u53F7\u6BD4\u5BF9\uFF1B\u4E0D\u4E00\u81F4\u65F6\u9000\u51FA\u5E76\u63D0\u793A\u5207\u6362\u767B\u5F55\uFF08\u6682\u65F6\u4E0D\u652F\u6301\u67E5\u4ED6\u6237\u6570\u636E\uFF09"
|
|
120614
|
+
).option(
|
|
120615
|
+
"--json-out <path>",
|
|
120616
|
+
"\u843D\u76D8 JSON\uFF1Bstdout \u4E00\u884C\u6458\u8981\uFF1B\u914D\u5408 --check-phone \u65F6 matched=false \u5219 exit 1",
|
|
120617
|
+
void 0
|
|
120618
|
+
).option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
|
|
120619
|
+
async (opts) => {
|
|
120620
|
+
await runAccountMe({
|
|
120621
|
+
token: opts.token,
|
|
120622
|
+
checkPhone: opts.checkPhone,
|
|
120623
|
+
jsonOut: opts.jsonOut,
|
|
120624
|
+
verbose: opts.verbose
|
|
120625
|
+
});
|
|
120626
|
+
}
|
|
120627
|
+
);
|
|
120509
120628
|
accountCmd.command("delink").description(
|
|
120510
120629
|
"\u89E3\u9664\u6388\u6743\uFF1A\u65AD\u5F00\u5E7F\u544A\u8D26\u6237\u4E0E\u5F53\u524D\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u7684\u5173\u8054\uFF08\u7F51\u9875 manageAccounts\u300C\u89E3\u9664\u6388\u6743\u300D\uFF1B--id \u6216 --ids\uFF09"
|
|
120511
120630
|
).option("--id <entityId>", "\u5355\u4E2A\u8D26\u6237 entityId\uFF08\u6765\u81EA list-accounts \u7684 ma.entityId \u5B57\u6BB5\uFF09").option("--ids <entityIds>", "\u6279\u91CF entityId\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u4E0E --id \u4E8C\u9009\u4E00\uFF0C\u53EF\u540C\u65F6\u4F20\uFF09").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
|
package/dist/skill/_meta.json
CHANGED
|
@@ -285,6 +285,26 @@ siluzan-tso account-history --start 2026-03-01 --end 2026-03-31 --json-out ./sna
|
|
|
285
285
|
|
|
286
286
|
## account — 账号管理(OAuth 授权 / 解除关联 / Google MCC / 分享)
|
|
287
287
|
|
|
288
|
+
### account me — 当前登录丝路赞账号
|
|
289
|
+
|
|
290
|
+
查询当前凭据对应的丝路赞用户(`GET /query/account/me`)。**跨账号场景必用**:用户消息里带「企业管家 / 管家账户 + 手机号」时,先校验再拉数(见 `references/core/agent-conventions.md` §跨账号)。
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# 查看当前登录账号
|
|
294
|
+
siluzan-tso account me
|
|
295
|
+
|
|
296
|
+
# Agent:校验用户指定的企业管家手机号是否与当前登录一致
|
|
297
|
+
siluzan-tso account me --check-phone 15130150466 --json-out ./snap-me
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
| 场景 | 行为 |
|
|
301
|
+
| ---- | ---- |
|
|
302
|
+
| 未传 `--check-phone` | 输出 entityId / 手机号 / 邮箱 / companyId |
|
|
303
|
+
| `--check-phone` 与当前一致 | exit 0,JSON 含 `matched: true` |
|
|
304
|
+
| `--check-phone` 不一致 | exit 1,提示暂不支持查他户数据,引导 `send-login-code` + `login` |
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
288
308
|
### auth — 添加媒体平台 OAuth 授权
|
|
289
309
|
|
|
290
310
|
在浏览器中打开对应媒体的 OAuth 授权页面,授权后账户自动绑定到丝路赞。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 各媒体开户
|
|
2
2
|
|
|
3
|
-
> 网页链接:`
|
|
3
|
+
> 网页链接:`https://www-ci.siluzan.com/v3/foreign_trade/tso/accountOpeningHistory?tso=%2Fv3umijs%2Ftso%2FaccountOpeningHistory`
|
|
4
4
|
> 多命令串联见 `references/core/workflows.md` § 流程一。
|
|
5
5
|
|
|
6
6
|
## 首次响应硬规范(必读)
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
|
|
16
16
|
清单须写清:**业务含义**、**CLI 选项名**、**格式/枚举**、**是否需本地文件路径**。用户补齐后再确认并提交;写入前仍须用户确认(见 `references/core/agent-conventions.md`)。
|
|
17
17
|
|
|
18
|
+
只有Google开户时需要询问用户账户币种(USD|CNY),其他广告平台禁止询问用户币种仅支持USD一种
|
|
19
|
+
|
|
18
20
|
不确定字段时:先 `siluzan-tso open-account <subcommand> -h`,再以本文件与 CLI 为准,勿猜。
|
|
19
21
|
|
|
20
22
|
---
|
|
@@ -61,8 +63,8 @@
|
|
|
61
63
|
| 法人身份证 | `--representative-id` | CLI 必填 |
|
|
62
64
|
| 法人银联账号 | `--unionpay-account` | CLI 必填 |
|
|
63
65
|
| 法人手机 | `--representative-phone` | CLI 必填 |
|
|
66
|
+
|币种|只支持USD, 无需 `--currency`|
|
|
64
67
|
|
|
65
|
-
> 币种由 CLI 固定为 USD,无需 `--currency`。
|
|
66
68
|
|
|
67
69
|
### Yandex(`open-account yandex`,无需图片)
|
|
68
70
|
|
|
@@ -80,6 +80,14 @@
|
|
|
80
80
|
- **CLI 输出忠实**:数值与 ID 须与本次落盘 JSON / stdout 一致,不编造示例 ID;`data` 为空时只说「当前返回无记录」并附 JSON 路径。
|
|
81
81
|
- **破坏性操作必须确认 + `--commit`**:账户解绑/关闭/取消分享、BC/MCC 解绑、删除预警/报告/广告/关键词、发票申请、广告发布等。
|
|
82
82
|
- **不确定时读文档**:先读对应 references 或用 `-h`,不要猜参数。
|
|
83
|
+
- **跨账号 / 企业管家手机号**:用户消息中出现**中国大陆 11 位手机号**(常见语境:「企业管家」「管家账户」「账号 xxx」)且意图是查**该手机号名下**的账户数据时,**必须先**执行 `siluzan-tso account me --check-phone <手机号> --json-out ./snap-me`。**禁止**在未校验通过前用当前凭据拉他户数据。
|
|
84
|
+
- `matched: true`(或 CLI exit 0)→ 按原工作流继续(如 P3 `accounts-digest` 查 TOP 消耗)。
|
|
85
|
+
- `matched: false`(CLI exit 1)→ **停止拉数**,告知用户并询问是否切换登录,话术示例:
|
|
86
|
+
> 暂时不支持查询其他丝路赞账号下的数据。您指定的是 **{phone}**,当前登录的是 **{currentPhone}**。
|
|
87
|
+
> 如需查询该账号,请使用该手机号重新登录:`send-login-code --phone {phone}` → `login --phone {phone} --code <验证码>`。
|
|
88
|
+
> 需要我帮您切换登录吗?
|
|
89
|
+
- 用户**未指定手机号** → 不校验,按当前凭据正常执行。
|
|
90
|
+
- 当前凭据未返回手机号且用户指定了手机号 → 视同未校验通过,引导重新用手机号登录。
|
|
83
91
|
- **Google 新建搜索系列**:流程仅在 `references/google-ads/google-ads-campaign-plan.md` 维护。
|
|
84
92
|
- **开户首次响应**:对话内首次进入开户话题时,**必须先**按 `references/accounts/open-account-by-media.md` §「首次响应硬规范」输出**完整必填清单**(未指明媒体则列全平台六表),再收集资料;**禁止**未列清单就执行 `open-account` 或零散追问。
|
|
85
93
|
- **Google 开户**:`open-account google-wizard` 仅限真实 TTY;Agent/自动化用非交互 `open-account google ...`,审核进度用 `account-history`。
|
|
@@ -9,7 +9,7 @@ $ErrorActionPreference = 'Stop'
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
$PKG_NAME = 'siluzan-tso-cli'
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
$PKG_VERSION = '1.1.29-beta.
|
|
12
|
+
$PKG_VERSION = '1.1.29-beta.9'
|
|
13
13
|
$CLI_BIN = 'siluzan-tso'
|
|
14
14
|
$SKILL_LABEL = 'Siluzan TSO'
|
|
15
15
|
$INSTALL_CMD = 'npm install -g siluzan-tso-cli@beta'
|
|
@@ -9,7 +9,7 @@ set -euo pipefail
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
readonly PKG_NAME="siluzan-tso-cli"
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
readonly PKG_VERSION="1.1.29-beta.
|
|
12
|
+
readonly PKG_VERSION="1.1.29-beta.9"
|
|
13
13
|
readonly CLI_BIN="siluzan-tso"
|
|
14
14
|
readonly SKILL_LABEL="Siluzan TSO"
|
|
15
15
|
readonly INSTALL_CMD="npm install -g siluzan-tso-cli@beta"
|