@yixinkj/cli 1.0.5 → 1.0.7

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.
Files changed (3) hide show
  1. package/README.md +10 -10
  2. package/index.js +61 -34
  3. 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
- YIXIN_KEY=你的key
19
- YIXIN_AUTH_URL=https://你的授权服务域名/v1/token
18
+ YIXIN_PHONE=你的手机号
19
+ YIXIN_AUTH_URL=http://47.237.81.135:3000/v1/token
20
20
  ```
21
21
 
22
- 也可以通过 MCP tool `configure_auth` 写入本机配置;环境变量优先于本机配置。
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
- "key": "客户授权 key",
33
- "authUrl": "https://你的授权服务域名/v1/token",
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. 使用传入的 `key`、`authUrl` 向授权服务换取一次短期 token。
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` 读取授权 key 和授权服务地址。
60
- 4. 向授权服务提交 `{ key, skill, version }`。
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` 读取授权 key 和授权服务地址。
76
- 2. 向授权服务提交 `{ key, skill: "ads", version }`。
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 envKey = String(process.env.YIXIN_KEY || '').trim();
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 localKey = String(localConfig.yixinKey || '').trim();
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
- key: envKey || localKey,
125
- authUrl: envAuthUrl || localAuthUrl,
126
- keySource: envKey ? 'env:YIXIN_KEY' : (localKey ? CONFIG_FILE : 'missing'),
127
- authUrlSource: envAuthUrl ? 'env:YIXIN_AUTH_URL' : (localAuthUrl ? CONFIG_FILE : 'missing')
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
 
@@ -226,8 +234,21 @@ function chmodExecutables(target) {
226
234
  }
227
235
  }
228
236
 
237
+ function clearMacQuarantine() {
238
+ if (process.platform !== 'darwin' || !fs.existsSync(BIN_DIR)) {
239
+ return;
240
+ }
241
+ const result = spawnSync('xattr', ['-dr', 'com.apple.quarantine', BIN_DIR], {
242
+ encoding: 'utf8'
243
+ });
244
+ if (result.error && result.error.code !== 'ENOENT') {
245
+ console.error(`[yixin] macOS 安全隔离标记清理失败:${result.error.message}`);
246
+ }
247
+ }
248
+
229
249
  async function ensureInstalled(target) {
230
250
  if (isInstalled(target)) {
251
+ clearMacQuarantine();
231
252
  chmodExecutables(target);
232
253
  return;
233
254
  }
@@ -241,6 +262,7 @@ async function ensureInstalled(target) {
241
262
  console.error(`[yixin] 正在下载 ${url}`);
242
263
  await downloadFile(url, archivePath);
243
264
  extractArchive(archivePath, target);
265
+ clearMacQuarantine();
244
266
  chmodExecutables(target);
245
267
 
246
268
  for (const name of target.binaries) {
@@ -256,14 +278,14 @@ async function ensureInstalled(target) {
256
278
  }
257
279
  }
258
280
 
259
- async function requestToken({ key, skill, version, authUrl }) {
281
+ async function requestToken({ phone, skill, version, authUrl }) {
260
282
  const normalizedAuthUrl = String(authUrl || '').trim();
261
283
  if (!normalizedAuthUrl) {
262
284
  throw new Error('未配置授权服务器地址,请添加 YIXIN_AUTH_URL');
263
285
  }
264
286
 
265
287
  const url = new URL(normalizedAuthUrl);
266
- const body = JSON.stringify({ key, skill, version });
288
+ const body = JSON.stringify({ phone, skill, version });
267
289
  const client = url.protocol === 'https:' ? https : http;
268
290
 
269
291
  return new Promise((resolve, reject) => {
@@ -308,15 +330,12 @@ async function requestToken({ key, skill, version, authUrl }) {
308
330
 
309
331
  async function authorize(skill) {
310
332
  const settings = getAuthSettings();
311
- const key = settings.key;
312
- if (!key) {
313
- throw new Error('未配置授权 key,请在 MCP 客户端环境变量里添加 YIXIN_KEY=你的key,或调用 configure_auth 写入本机配置');
314
- }
315
- if (!settings.authUrl) {
316
- throw new Error('未配置授权服务器地址,请在 MCP 客户端环境变量里添加 YIXIN_AUTH_URL,或调用 configure_auth 写入本机配置');
333
+ const phone = settings.phone;
334
+ if (!phone) {
335
+ throw new Error('未配置授权手机号,请在 MCP 客户端环境变量里添加 YIXIN_PHONE=手机号,或调用 configure_auth 写入本机配置');
317
336
  }
318
337
 
319
- const auth = await requestToken({ key, skill, version: VERSION, authUrl: settings.authUrl });
338
+ const auth = await requestToken({ phone, skill, version: VERSION, authUrl: settings.authUrl });
320
339
  if (!auth || auth.valid !== true || !auth.token) {
321
340
  throw new Error(auth && auth.reason ? auth.reason : '授权失败');
322
341
  }
@@ -373,19 +392,20 @@ async function checkAuth({ skill }) {
373
392
  `skill: ${normalizedSkill}`,
374
393
  `platform: ${target.id}`,
375
394
  `binary: ${binaryPath(target)}`,
376
- `key_source: ${settings.keySource}`,
395
+ `phone_source: ${settings.phoneSource}`,
377
396
  `auth_url_source: ${settings.authUrlSource}`,
378
397
  `config_file: ${CONFIG_FILE}`
379
398
  ].join('\n');
380
399
  }
381
400
 
382
- async function configureAuth({ key, authUrl, skill }) {
383
- const normalizedKey = String(key || '').trim();
384
- const normalizedAuthUrl = String(authUrl || '').trim();
401
+ async function configureAuth({ phone, authUrl, skill }) {
402
+ const normalizedPhone = String(phone || '').trim();
403
+ const hasCustomAuthUrl = authUrl !== undefined && authUrl !== null && String(authUrl).trim() !== '';
404
+ const normalizedAuthUrl = hasCustomAuthUrl ? String(authUrl).trim() : DEFAULT_AUTH_URL;
385
405
  const normalizedSkill = String(skill || 'ads').trim() || 'ads';
386
406
 
387
- if (!normalizedKey) {
388
- throw new Error('key 不能为空');
407
+ if (!normalizedPhone) {
408
+ throw new Error('phone 不能为空');
389
409
  }
390
410
  if (!normalizedAuthUrl) {
391
411
  throw new Error('authUrl 不能为空');
@@ -397,7 +417,7 @@ async function configureAuth({ key, authUrl, skill }) {
397
417
  }
398
418
 
399
419
  const auth = await requestToken({
400
- key: normalizedKey,
420
+ phone: normalizedPhone,
401
421
  skill: normalizedSkill,
402
422
  version: VERSION,
403
423
  authUrl: normalizedAuthUrl
@@ -407,16 +427,23 @@ async function configureAuth({ key, authUrl, skill }) {
407
427
  }
408
428
 
409
429
  const existingConfig = readLocalConfig();
410
- writeLocalConfig({
430
+ const nextConfig = {
411
431
  ...existingConfig,
412
- yixinKey: normalizedKey,
413
- yixinAuthUrl: normalizedAuthUrl,
432
+ yixinPhone: normalizedPhone,
414
433
  updatedAt: new Date().toISOString()
415
- });
434
+ };
435
+ delete nextConfig.yixinKey;
436
+ if (hasCustomAuthUrl) {
437
+ nextConfig.yixinAuthUrl = normalizedAuthUrl;
438
+ } else {
439
+ delete nextConfig.yixinAuthUrl;
440
+ }
441
+ writeLocalConfig(nextConfig);
416
442
 
417
443
  return [
418
444
  'Yixin 授权配置已写入本机',
419
445
  `skill: ${normalizedSkill}`,
446
+ `auth_url: ${hasCustomAuthUrl ? normalizedAuthUrl : `${DEFAULT_AUTH_URL} (default)`}`,
420
447
  `config_file: ${CONFIG_FILE}`,
421
448
  '后续 check_auth/run_ads_report 会优先使用环境变量;环境变量缺失时使用本机配置'
422
449
  ].join('\n');
@@ -432,24 +459,24 @@ function registerTools(server) {
432
459
  'configure_auth',
433
460
  {
434
461
  title: 'Configure Auth',
435
- description: '验证并保存译心授权 key 和授权服务地址到本机配置;环境变量仍优先于本机配置。',
462
+ description: '验证并保存译心授权手机号到本机配置;授权服务地址默认内置,也可用 authUrl 或 YIXIN_AUTH_URL 覆盖。',
436
463
  inputSchema: {
437
- key: z
464
+ phone: z
438
465
  .string()
439
466
  .min(1)
440
- .describe('客户授权 key。'),
467
+ .describe('客户授权手机号。'),
441
468
  authUrl: z
442
469
  .string()
443
- .min(1)
444
- .describe('授权服务地址,例如 https://example.com/v1/token。'),
470
+ .optional()
471
+ .describe(`授权服务地址,默认 ${DEFAULT_AUTH_URL}。`),
445
472
  skill: z
446
473
  .string()
447
474
  .optional()
448
475
  .describe('授权能力名,默认 ads。')
449
476
  }
450
477
  },
451
- async ({ key, authUrl, skill }) => {
452
- const stdout = await configureAuth({ key, authUrl, skill });
478
+ async ({ phone, authUrl, skill }) => {
479
+ const stdout = await configureAuth({ phone, authUrl, skill });
453
480
  return {
454
481
  content: [{ type: 'text', text: stdout }]
455
482
  };
@@ -460,7 +487,7 @@ function registerTools(server) {
460
487
  'check_auth',
461
488
  {
462
489
  title: 'Check Auth',
463
- description: '检查译心 MCP 环境、二进制安装和授权 key 是否可用;不生成广告报告。',
490
+ description: '检查译心 MCP 环境、二进制安装和授权手机号是否可用;不生成广告报告。',
464
491
  inputSchema: {
465
492
  skill: z
466
493
  .string()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yixinkj/cli",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Yixin local MCP server and CLI launcher for MCP clients.",
5
5
  "type": "module",
6
6
  "bin": {