@yizhuan-cli/cli 0.1.16-beta.2 → 0.1.16
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/package.json +1 -1
- package/resources/yizhuan-cli/manifest.json +3 -3
- package/src/doctor.js +1 -1
- package/src/index.js +72 -7
- package/src/skill.js +8 -6
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"name": "yizhuan-cli",
|
|
4
|
-
"version": "0.1.16
|
|
5
|
-
"compatibleCliVersion": "0.1.16
|
|
6
|
-
"source": "npm:@yizhuan-cli/cli@0.1.16
|
|
4
|
+
"version": "0.1.16",
|
|
5
|
+
"compatibleCliVersion": "0.1.16",
|
|
6
|
+
"source": "npm:@yizhuan-cli/cli@0.1.16",
|
|
7
7
|
"digestAlgorithm": "sha256",
|
|
8
8
|
"files": [
|
|
9
9
|
{
|
package/src/doctor.js
CHANGED
|
@@ -210,7 +210,7 @@ export function inspectSkill(
|
|
|
210
210
|
}
|
|
211
211
|
return check('pass', 'skill', `正式 Skill ${metadata.version} 来源和摘要有效:${resolved.target}`)
|
|
212
212
|
} catch (error) {
|
|
213
|
-
return check('fail', 'skill', `正式 Skill 校验失败:${error.message}`, '
|
|
213
|
+
return check('fail', 'skill', `正式 Skill 校验失败:${error.message}`, '人工确认后运行 yizhuan skill sync --repair,或移走冲突内容后重新同步。')
|
|
214
214
|
}
|
|
215
215
|
}
|
|
216
216
|
|
package/src/index.js
CHANGED
|
@@ -59,7 +59,7 @@ Usage:
|
|
|
59
59
|
yizhuan config init [--api-key-stdin] [--api-base-url <url>] [--force]
|
|
60
60
|
yizhuan config path
|
|
61
61
|
yizhuan config show
|
|
62
|
-
yizhuan skill sync [--global]
|
|
62
|
+
yizhuan skill sync [--global] [--host <name>] [--repair]
|
|
63
63
|
yizhuan doctor [--json]
|
|
64
64
|
|
|
65
65
|
Examples:
|
|
@@ -323,6 +323,65 @@ function assignFlagParams(params, args) {
|
|
|
323
323
|
return params
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
+
const AUTHOR_RANKING_METRICS = [
|
|
327
|
+
{
|
|
328
|
+
key: 'friendsCount',
|
|
329
|
+
label: '关注数',
|
|
330
|
+
patterns: [/关注/, /friends(?:Count|_count)?/i]
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
key: 'followerCount',
|
|
334
|
+
label: '粉丝数',
|
|
335
|
+
patterns: [/粉丝/, /follower(?:Count|_count)?/i]
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
key: 'totalViews',
|
|
339
|
+
label: '阅读数',
|
|
340
|
+
patterns: [/阅读|播放/, /(?:total)?views?/i]
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
key: 'totalLikes',
|
|
344
|
+
label: '点赞数',
|
|
345
|
+
patterns: [/点赞/, /(?:total)?likes?/i]
|
|
346
|
+
}
|
|
347
|
+
]
|
|
348
|
+
|
|
349
|
+
function rankingMetric(query, params) {
|
|
350
|
+
const text = [
|
|
351
|
+
query,
|
|
352
|
+
params?.metric,
|
|
353
|
+
params?.sortBy,
|
|
354
|
+
params?.sort_by,
|
|
355
|
+
params?.order
|
|
356
|
+
].filter(Boolean).join(' ')
|
|
357
|
+
if (!/(最高|最多|最大|第一|排行|排名|top)/i.test(text)) return undefined
|
|
358
|
+
return AUTHOR_RANKING_METRICS.find((metric) => metric.patterns.some((pattern) => pattern.test(text)))
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export function annotateUnavailableAuthorRanking(result, { query, params } = {}) {
|
|
362
|
+
const metric = rankingMetric(query, params)
|
|
363
|
+
const items = result?.data?.items
|
|
364
|
+
if (!metric || !Array.isArray(items) || items.length === 0) return result
|
|
365
|
+
|
|
366
|
+
const allValuesAreZero = items.every((item) => Number(item?.[metric.key]) === 0)
|
|
367
|
+
if (!allValuesAreZero) return result
|
|
368
|
+
|
|
369
|
+
const message = `查询到的作者${metric.label}均为 0,无法据此排序或判断最高作者`
|
|
370
|
+
return {
|
|
371
|
+
...result,
|
|
372
|
+
message: result.message || message,
|
|
373
|
+
data: {
|
|
374
|
+
...result.data,
|
|
375
|
+
ranking: {
|
|
376
|
+
metric: metric.key,
|
|
377
|
+
status: 'unavailable',
|
|
378
|
+
reason: 'all_returned_values_zero',
|
|
379
|
+
message
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
326
385
|
export function buildExecuteParams(args) {
|
|
327
386
|
if (args.jsonFile) {
|
|
328
387
|
const conflictingKeys = ['params', 'query', ...PARAM_FLAG_KEYS].filter(
|
|
@@ -372,6 +431,7 @@ async function execute(args) {
|
|
|
372
431
|
throw new Error(`未知 ability:${ability || ''},请执行 yizhuan --help 查看可用能力`)
|
|
373
432
|
}
|
|
374
433
|
|
|
434
|
+
const requestParams = buildExecuteParams(args)
|
|
375
435
|
const config = readConfig()
|
|
376
436
|
const response = await fetch(`${config.apiBaseUrl}/api/cli.execute`, {
|
|
377
437
|
method: 'POST',
|
|
@@ -384,7 +444,7 @@ async function execute(args) {
|
|
|
384
444
|
json: {
|
|
385
445
|
ability,
|
|
386
446
|
query: typeof args.query === 'string' ? args.query : undefined,
|
|
387
|
-
params:
|
|
447
|
+
params: requestParams
|
|
388
448
|
}
|
|
389
449
|
})
|
|
390
450
|
})
|
|
@@ -395,7 +455,6 @@ async function execute(args) {
|
|
|
395
455
|
}
|
|
396
456
|
|
|
397
457
|
let result = payloadResult(JSON.parse(text))
|
|
398
|
-
const requestParams = buildExecuteParams(args)
|
|
399
458
|
if (
|
|
400
459
|
ability === 'detection' &&
|
|
401
460
|
requestParams?.wait === true &&
|
|
@@ -426,6 +485,10 @@ async function execute(args) {
|
|
|
426
485
|
result = payloadResult(JSON.parse(pollText))
|
|
427
486
|
}
|
|
428
487
|
}
|
|
488
|
+
result = annotateUnavailableAuthorRanking(result, {
|
|
489
|
+
query: typeof args.query === 'string' ? args.query : undefined,
|
|
490
|
+
params: requestParams
|
|
491
|
+
})
|
|
429
492
|
console.log(JSON.stringify(result, null, 2))
|
|
430
493
|
}
|
|
431
494
|
|
|
@@ -468,9 +531,11 @@ async function query(args) {
|
|
|
468
531
|
})
|
|
469
532
|
const text = await response.text()
|
|
470
533
|
if (!response.ok) throw new Error(`请求失败 HTTP ${response.status}:${text}`)
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
534
|
+
const result = annotateUnavailableAuthorRanking(payloadResult(JSON.parse(text)), {
|
|
535
|
+
query: request.query || request.keyword,
|
|
536
|
+
params: request
|
|
537
|
+
})
|
|
538
|
+
console.log(renderQuery(result, args.format || 'json'))
|
|
474
539
|
}
|
|
475
540
|
|
|
476
541
|
async function main() {
|
|
@@ -510,7 +575,7 @@ async function main() {
|
|
|
510
575
|
}
|
|
511
576
|
|
|
512
577
|
if (command === 'skill' && args._[1] === 'sync') {
|
|
513
|
-
assertCommandArgs(args, 'skill sync', new Set(['global', 'host', 'help']), 2)
|
|
578
|
+
assertCommandArgs(args, 'skill sync', new Set(['global', 'host', 'repair', 'help']), 2)
|
|
514
579
|
await runSkillSync(args)
|
|
515
580
|
return
|
|
516
581
|
}
|
package/src/skill.js
CHANGED
|
@@ -90,7 +90,7 @@ export function loadOfficialSkill(resourceDir = DEFAULT_RESOURCE_DIR) {
|
|
|
90
90
|
return { manifest, resourceDir }
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
export function readSkillMetadata(target) {
|
|
93
|
+
export function readSkillMetadata(target, { allowModified = false } = {}) {
|
|
94
94
|
const metadataPath = path.join(target, SKILL_METADATA_FILE)
|
|
95
95
|
if (!fs.existsSync(metadataPath)) {
|
|
96
96
|
throw new Error(`目标存在未受易撰管理的同名内容,已停止同步:${target}`)
|
|
@@ -111,7 +111,7 @@ export function readSkillMetadata(target) {
|
|
|
111
111
|
}
|
|
112
112
|
for (const file of metadata.files) {
|
|
113
113
|
const installedPath = safeResourcePath(target, file.path)
|
|
114
|
-
if (!fs.existsSync(installedPath) || sha256File(installedPath) !== file.sha256) {
|
|
114
|
+
if (!allowModified && (!fs.existsSync(installedPath) || sha256File(installedPath) !== file.sha256)) {
|
|
115
115
|
throw new Error(`已安装 Skill 包含未知修改,已停止覆盖:${file.path}`)
|
|
116
116
|
}
|
|
117
117
|
}
|
|
@@ -182,14 +182,15 @@ export function syncOfficialSkill(
|
|
|
182
182
|
{
|
|
183
183
|
loadBundle = loadOfficialSkill,
|
|
184
184
|
installBundle = installStagedSkill,
|
|
185
|
-
now = () => new Date()
|
|
185
|
+
now = () => new Date(),
|
|
186
|
+
repair = false
|
|
186
187
|
} = {}
|
|
187
188
|
) {
|
|
188
189
|
const bundle = loadBundle()
|
|
189
190
|
const { manifest } = bundle
|
|
190
191
|
let installed
|
|
191
192
|
if (fs.existsSync(resolved.target)) {
|
|
192
|
-
installed = readSkillMetadata(resolved.target)
|
|
193
|
+
installed = readSkillMetadata(resolved.target, { allowModified: repair })
|
|
193
194
|
const comparison = compareVersions(installed.version, manifest.version)
|
|
194
195
|
if (comparison > 0) {
|
|
195
196
|
return { action: 'newer', metadata: installed, target: resolved.target }
|
|
@@ -257,11 +258,12 @@ export function resolveSkillTarget(
|
|
|
257
258
|
|
|
258
259
|
export function printSkillSyncHelp() {
|
|
259
260
|
console.log(`Usage:
|
|
260
|
-
yizhuan skill sync [--global] [--host <name>]
|
|
261
|
+
yizhuan skill sync [--global] [--host <name>] [--repair]
|
|
261
262
|
|
|
262
263
|
Options:
|
|
263
264
|
--global 安装到当前受支持宿主的用户级 Skill 目录
|
|
264
265
|
--host 明确指定 codex、agents、trae、claude 或 cursor
|
|
266
|
+
--repair 仅覆盖带官方托管元数据但内容校验失败的 Skill
|
|
265
267
|
--help 显示本帮助`)
|
|
266
268
|
}
|
|
267
269
|
|
|
@@ -272,7 +274,7 @@ export async function runSkillSync(args) {
|
|
|
272
274
|
}
|
|
273
275
|
|
|
274
276
|
const resolved = resolveSkillTarget({ global: Boolean(args.global), host: args.host })
|
|
275
|
-
const result = syncOfficialSkill(resolved)
|
|
277
|
+
const result = syncOfficialSkill(resolved, { repair: Boolean(args.repair) })
|
|
276
278
|
const actionText = {
|
|
277
279
|
installed: '已安装',
|
|
278
280
|
updated: '已更新',
|