@yixinkj/cli 1.0.5 → 1.0.6
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 +10 -10
- package/index.js +47 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,11 +15,11 @@ npx -y @yixinkj/cli@latest
|
|
|
15
15
|
推荐环境变量:
|
|
16
16
|
|
|
17
17
|
```text
|
|
18
|
-
|
|
19
|
-
YIXIN_AUTH_URL=
|
|
18
|
+
YIXIN_PHONE=你的手机号
|
|
19
|
+
YIXIN_AUTH_URL=http://47.237.81.135:3000/v1/token
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
`YIXIN_AUTH_URL` 已内置默认值,普通用户只需要填写 `YIXIN_PHONE`。也可以通过 MCP tool `configure_auth` 写入本机配置;环境变量优先于本机配置。
|
|
23
23
|
|
|
24
24
|
## 工具
|
|
25
25
|
|
|
@@ -29,15 +29,15 @@ YIXIN_AUTH_URL=https://你的授权服务域名/v1/token
|
|
|
29
29
|
|
|
30
30
|
```json
|
|
31
31
|
{
|
|
32
|
-
"
|
|
33
|
-
"authUrl": "
|
|
32
|
+
"phone": "客户授权手机号",
|
|
33
|
+
"authUrl": "http://47.237.81.135:3000/v1/token",
|
|
34
34
|
"skill": "ads"
|
|
35
35
|
}
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
执行流程:
|
|
39
39
|
|
|
40
|
-
1. 使用传入的 `
|
|
40
|
+
1. 使用传入的 `phone`、`authUrl` 向授权服务换取一次短期 token。
|
|
41
41
|
2. 验证成功后写入 `~/.yixin/config.json`。
|
|
42
42
|
3. 文件权限尽量设置为 `0600`。
|
|
43
43
|
4. 环境变量仍然优先;环境变量缺失时才读取本机配置。
|
|
@@ -56,8 +56,8 @@ YIXIN_AUTH_URL=https://你的授权服务域名/v1/token
|
|
|
56
56
|
|
|
57
57
|
1. 检查当前平台是否支持。
|
|
58
58
|
2. 如当前版本二进制尚未安装,则从公开 GitHub Release 下载对应平台包并解压到 `~/.yixin/bin`。
|
|
59
|
-
3. 从环境变量或 `~/.yixin/config.json`
|
|
60
|
-
4. 向授权服务提交 `{
|
|
59
|
+
3. 从环境变量或 `~/.yixin/config.json` 读取授权手机号;授权服务地址默认使用 `http://47.237.81.135:3000/v1/token`,也可由配置覆盖。
|
|
60
|
+
4. 向授权服务提交 `{ phone, skill, version }`。
|
|
61
61
|
5. 返回自检结果;不会生成广告报告。
|
|
62
62
|
|
|
63
63
|
### run_ads_report
|
|
@@ -72,8 +72,8 @@ YIXIN_AUTH_URL=https://你的授权服务域名/v1/token
|
|
|
72
72
|
|
|
73
73
|
执行流程:
|
|
74
74
|
|
|
75
|
-
1. 从环境变量或 `~/.yixin/config.json`
|
|
76
|
-
2. 向授权服务提交 `{
|
|
75
|
+
1. 从环境变量或 `~/.yixin/config.json` 读取授权手机号;授权服务地址默认使用 `http://47.237.81.135:3000/v1/token`,也可由配置覆盖。
|
|
76
|
+
2. 向授权服务提交 `{ phone, skill: "ads", version }`。
|
|
77
77
|
3. 获取短期授权 token。
|
|
78
78
|
4. 如当前版本二进制尚未安装,则从公开 GitHub Release 下载对应平台包并解压到 `~/.yixin/bin`。
|
|
79
79
|
5. 使用以下参数运行 `~/.yixin/bin/alibaba-cli-{platform}`:
|
package/index.js
CHANGED
|
@@ -21,6 +21,7 @@ const CACHE_ROOT = path.join(os.homedir(), '.yixin');
|
|
|
21
21
|
const BIN_DIR = path.join(os.homedir(), '.yixin', 'bin');
|
|
22
22
|
const VERSION_FILE = path.join(CACHE_ROOT, 'version');
|
|
23
23
|
const CONFIG_FILE = path.join(CACHE_ROOT, 'config.json');
|
|
24
|
+
const DEFAULT_AUTH_URL = process.env.YIXIN_DEFAULT_AUTH_URL || 'http://47.237.81.135:3000/v1/token';
|
|
24
25
|
|
|
25
26
|
const PLATFORM_TARGETS = {
|
|
26
27
|
'darwin-arm64': {
|
|
@@ -115,16 +116,23 @@ function writeLocalConfig(config) {
|
|
|
115
116
|
|
|
116
117
|
function getAuthSettings() {
|
|
117
118
|
const localConfig = readLocalConfig();
|
|
118
|
-
const
|
|
119
|
+
const envPhone = String(process.env.YIXIN_PHONE || '').trim();
|
|
120
|
+
const envLegacyKey = String(process.env.YIXIN_KEY || '').trim();
|
|
119
121
|
const envAuthUrl = String(process.env.YIXIN_AUTH_URL || '').trim();
|
|
120
|
-
const
|
|
122
|
+
const localPhone = String(localConfig.yixinPhone || localConfig.yixinKey || '').trim();
|
|
121
123
|
const localAuthUrl = String(localConfig.yixinAuthUrl || '').trim();
|
|
124
|
+
const phone = envPhone || envLegacyKey || localPhone;
|
|
125
|
+
const authUrl = envAuthUrl || localAuthUrl || DEFAULT_AUTH_URL;
|
|
122
126
|
|
|
123
127
|
return {
|
|
124
|
-
|
|
125
|
-
authUrl
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
phone,
|
|
129
|
+
authUrl,
|
|
130
|
+
phoneSource: envPhone
|
|
131
|
+
? 'env:YIXIN_PHONE'
|
|
132
|
+
: (envLegacyKey ? 'env:YIXIN_KEY' : (localPhone ? CONFIG_FILE : 'missing')),
|
|
133
|
+
authUrlSource: envAuthUrl
|
|
134
|
+
? 'env:YIXIN_AUTH_URL'
|
|
135
|
+
: (localAuthUrl ? CONFIG_FILE : 'default')
|
|
128
136
|
};
|
|
129
137
|
}
|
|
130
138
|
|
|
@@ -256,14 +264,14 @@ async function ensureInstalled(target) {
|
|
|
256
264
|
}
|
|
257
265
|
}
|
|
258
266
|
|
|
259
|
-
async function requestToken({
|
|
267
|
+
async function requestToken({ phone, skill, version, authUrl }) {
|
|
260
268
|
const normalizedAuthUrl = String(authUrl || '').trim();
|
|
261
269
|
if (!normalizedAuthUrl) {
|
|
262
270
|
throw new Error('未配置授权服务器地址,请添加 YIXIN_AUTH_URL');
|
|
263
271
|
}
|
|
264
272
|
|
|
265
273
|
const url = new URL(normalizedAuthUrl);
|
|
266
|
-
const body = JSON.stringify({
|
|
274
|
+
const body = JSON.stringify({ phone, skill, version });
|
|
267
275
|
const client = url.protocol === 'https:' ? https : http;
|
|
268
276
|
|
|
269
277
|
return new Promise((resolve, reject) => {
|
|
@@ -308,15 +316,12 @@ async function requestToken({ key, skill, version, authUrl }) {
|
|
|
308
316
|
|
|
309
317
|
async function authorize(skill) {
|
|
310
318
|
const settings = getAuthSettings();
|
|
311
|
-
const
|
|
312
|
-
if (!
|
|
313
|
-
throw new Error('
|
|
314
|
-
}
|
|
315
|
-
if (!settings.authUrl) {
|
|
316
|
-
throw new Error('未配置授权服务器地址,请在 MCP 客户端环境变量里添加 YIXIN_AUTH_URL,或调用 configure_auth 写入本机配置');
|
|
319
|
+
const phone = settings.phone;
|
|
320
|
+
if (!phone) {
|
|
321
|
+
throw new Error('未配置授权手机号,请在 MCP 客户端环境变量里添加 YIXIN_PHONE=手机号,或调用 configure_auth 写入本机配置');
|
|
317
322
|
}
|
|
318
323
|
|
|
319
|
-
const auth = await requestToken({
|
|
324
|
+
const auth = await requestToken({ phone, skill, version: VERSION, authUrl: settings.authUrl });
|
|
320
325
|
if (!auth || auth.valid !== true || !auth.token) {
|
|
321
326
|
throw new Error(auth && auth.reason ? auth.reason : '授权失败');
|
|
322
327
|
}
|
|
@@ -373,19 +378,20 @@ async function checkAuth({ skill }) {
|
|
|
373
378
|
`skill: ${normalizedSkill}`,
|
|
374
379
|
`platform: ${target.id}`,
|
|
375
380
|
`binary: ${binaryPath(target)}`,
|
|
376
|
-
`
|
|
381
|
+
`phone_source: ${settings.phoneSource}`,
|
|
377
382
|
`auth_url_source: ${settings.authUrlSource}`,
|
|
378
383
|
`config_file: ${CONFIG_FILE}`
|
|
379
384
|
].join('\n');
|
|
380
385
|
}
|
|
381
386
|
|
|
382
|
-
async function configureAuth({
|
|
383
|
-
const
|
|
384
|
-
const
|
|
387
|
+
async function configureAuth({ phone, authUrl, skill }) {
|
|
388
|
+
const normalizedPhone = String(phone || '').trim();
|
|
389
|
+
const hasCustomAuthUrl = authUrl !== undefined && authUrl !== null && String(authUrl).trim() !== '';
|
|
390
|
+
const normalizedAuthUrl = hasCustomAuthUrl ? String(authUrl).trim() : DEFAULT_AUTH_URL;
|
|
385
391
|
const normalizedSkill = String(skill || 'ads').trim() || 'ads';
|
|
386
392
|
|
|
387
|
-
if (!
|
|
388
|
-
throw new Error('
|
|
393
|
+
if (!normalizedPhone) {
|
|
394
|
+
throw new Error('phone 不能为空');
|
|
389
395
|
}
|
|
390
396
|
if (!normalizedAuthUrl) {
|
|
391
397
|
throw new Error('authUrl 不能为空');
|
|
@@ -397,7 +403,7 @@ async function configureAuth({ key, authUrl, skill }) {
|
|
|
397
403
|
}
|
|
398
404
|
|
|
399
405
|
const auth = await requestToken({
|
|
400
|
-
|
|
406
|
+
phone: normalizedPhone,
|
|
401
407
|
skill: normalizedSkill,
|
|
402
408
|
version: VERSION,
|
|
403
409
|
authUrl: normalizedAuthUrl
|
|
@@ -407,16 +413,23 @@ async function configureAuth({ key, authUrl, skill }) {
|
|
|
407
413
|
}
|
|
408
414
|
|
|
409
415
|
const existingConfig = readLocalConfig();
|
|
410
|
-
|
|
416
|
+
const nextConfig = {
|
|
411
417
|
...existingConfig,
|
|
412
|
-
|
|
413
|
-
yixinAuthUrl: normalizedAuthUrl,
|
|
418
|
+
yixinPhone: normalizedPhone,
|
|
414
419
|
updatedAt: new Date().toISOString()
|
|
415
|
-
}
|
|
420
|
+
};
|
|
421
|
+
delete nextConfig.yixinKey;
|
|
422
|
+
if (hasCustomAuthUrl) {
|
|
423
|
+
nextConfig.yixinAuthUrl = normalizedAuthUrl;
|
|
424
|
+
} else {
|
|
425
|
+
delete nextConfig.yixinAuthUrl;
|
|
426
|
+
}
|
|
427
|
+
writeLocalConfig(nextConfig);
|
|
416
428
|
|
|
417
429
|
return [
|
|
418
430
|
'Yixin 授权配置已写入本机',
|
|
419
431
|
`skill: ${normalizedSkill}`,
|
|
432
|
+
`auth_url: ${hasCustomAuthUrl ? normalizedAuthUrl : `${DEFAULT_AUTH_URL} (default)`}`,
|
|
420
433
|
`config_file: ${CONFIG_FILE}`,
|
|
421
434
|
'后续 check_auth/run_ads_report 会优先使用环境变量;环境变量缺失时使用本机配置'
|
|
422
435
|
].join('\n');
|
|
@@ -432,24 +445,24 @@ function registerTools(server) {
|
|
|
432
445
|
'configure_auth',
|
|
433
446
|
{
|
|
434
447
|
title: 'Configure Auth',
|
|
435
|
-
description: '
|
|
448
|
+
description: '验证并保存译心授权手机号到本机配置;授权服务地址默认内置,也可用 authUrl 或 YIXIN_AUTH_URL 覆盖。',
|
|
436
449
|
inputSchema: {
|
|
437
|
-
|
|
450
|
+
phone: z
|
|
438
451
|
.string()
|
|
439
452
|
.min(1)
|
|
440
|
-
.describe('
|
|
453
|
+
.describe('客户授权手机号。'),
|
|
441
454
|
authUrl: z
|
|
442
455
|
.string()
|
|
443
|
-
.
|
|
444
|
-
.describe(
|
|
456
|
+
.optional()
|
|
457
|
+
.describe(`授权服务地址,默认 ${DEFAULT_AUTH_URL}。`),
|
|
445
458
|
skill: z
|
|
446
459
|
.string()
|
|
447
460
|
.optional()
|
|
448
461
|
.describe('授权能力名,默认 ads。')
|
|
449
462
|
}
|
|
450
463
|
},
|
|
451
|
-
async ({
|
|
452
|
-
const stdout = await configureAuth({
|
|
464
|
+
async ({ phone, authUrl, skill }) => {
|
|
465
|
+
const stdout = await configureAuth({ phone, authUrl, skill });
|
|
453
466
|
return {
|
|
454
467
|
content: [{ type: 'text', text: stdout }]
|
|
455
468
|
};
|
|
@@ -460,7 +473,7 @@ function registerTools(server) {
|
|
|
460
473
|
'check_auth',
|
|
461
474
|
{
|
|
462
475
|
title: 'Check Auth',
|
|
463
|
-
description: '检查译心 MCP
|
|
476
|
+
description: '检查译心 MCP 环境、二进制安装和授权手机号是否可用;不生成广告报告。',
|
|
464
477
|
inputSchema: {
|
|
465
478
|
skill: z
|
|
466
479
|
.string()
|