@xqyz/xq-cli 0.3.20 → 0.3.21

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/CHANGELOG.md CHANGED
@@ -10,6 +10,16 @@
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [xq-cli 0.3.21 / WorkBuddy Plugin 0.10.40 / SkillHub 1.0.20] - 2026-09-02(npm 发布准备,SkillHub 不变)
14
+
15
+ ### WorkBuddy 供应方式原任务恢复
16
+
17
+ - 新增只读 `outline wait`:只轮询既有 `cid/uuid`,不会再次调用 `preSet` 或 `multiBiddingChoice`,使 WorkBuddy 在供应方式提交后与 Web 端一样继续原解析任务。
18
+ - WorkBuddy 在 `/proxy/savebidderRole` 返回成功后直接进入原任务等待,不再把短暂滞后的 `bidderIdentity_judgement` 镜像当作提交失败,也不会再次提交供应方式。
19
+ - 当评分正文已经存在时,本地忽略矛盾的 `score_judgement=0` 镜像,避免相同招标文件在 WorkBuddy 中误弹“补充评分细则”。
20
+ - 新增旧镜像持续不变、无第二次触发型 outline、已有评分正文三类回归测试。
21
+ - SkillHub 指令与交互协议未改变,继续使用 `1.0.20`,不生成或自动上传新版本。
22
+
13
23
  ## [xq-cli 0.3.20 / WorkBuddy Plugin 0.10.39 / SkillHub 1.0.20] - 2026-09-02(npm 发布准备,SkillHub 不变)
14
24
 
15
25
  ### 供应方式并发回写根因修复
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xqyz/xq-cli",
3
- "version": "0.3.20",
3
+ "version": "0.3.21",
4
4
  "description": "CLI for xique bid-book task workflows",
5
5
  "type": "module",
6
6
  "scripts": {
package/src/cli.mjs CHANGED
@@ -429,6 +429,8 @@ async function main() {
429
429
  await handleOutlineView(parsed, state);
430
430
  } else if (isOutlineAction(parsed, ['update', 'edit'])) {
431
431
  await handleOutlineUpdate(parsed, state);
432
+ } else if (isOutlineAction(parsed, ['wait', 'resume'])) {
433
+ await handleOutlineWait(parsed, state);
432
434
  } else {
433
435
  await handleOutline(parsed, state);
434
436
  }
@@ -502,6 +504,7 @@ Commands
502
504
  basis-select Save the parsing-stage outline basis for the current task
503
505
  supplement Submit missing requirement / bill / score / directory content and continue the same task
504
506
  outline Pre-set task params and trigger outline generation
507
+ outline wait Wait for the current outline without triggering parsing again
505
508
  outline view View the current outline without triggering generation
506
509
  outline update Update the current outline from an edited JSON file
507
510
  directory view View the complete generated directory tree without triggering generation
@@ -551,6 +554,7 @@ Examples
551
554
  xq-cli outline --cid <cid> --wait --ignore-missing-bill
552
555
  xq-cli outline --cid <cid> --wait --reference-type 0
553
556
  xq-cli outline --cid <cid> --page-scope 3 --writing-quality flagship --theme-style 4 --table-quantity rich --plan-mode quick --wait
557
+ xq-cli outline wait --cid <cid> --uuid <uuid> --bidder-role 2 --wait
554
558
  xq-cli outline view --cid <cid>
555
559
  xq-cli outline view --cid <cid> --out D:\\output\\outline.json
556
560
  xq-cli outline update --cid <cid> --file D:\\output\\outline.json --dry-run --json
@@ -2045,6 +2049,37 @@ async function handleOutline(args, state) {
2045
2049
  return withGenerationLock(cid, 'generation', () => handleOutlineUnlocked(args, state));
2046
2050
  }
2047
2051
 
2052
+ async function handleOutlineWait(args, state) {
2053
+ const cid = resolveCid(args, state);
2054
+ return withGenerationLock(cid, 'generation', () => handleOutlineWaitUnlocked(args, state));
2055
+ }
2056
+
2057
+ async function handleOutlineWaitUnlocked(args, state) {
2058
+ validateOutlineReferenceTypeOption(args);
2059
+ const client = createAuthorizedClient(args, state);
2060
+ const cid = resolveCid(args, state);
2061
+ const snapshot = await hydrateTaskSnapshot(client, state, cid);
2062
+ const uuid = stringOption(args, 'uuid', snapshot.uuid);
2063
+ const planMode = enumOption(args, 'planMode', PLAN_MODE_OPTIONS, snapshot.planMode ?? 0);
2064
+ const waitResult = Number(planMode) === 1
2065
+ ? await waitForPlanningAnalysisReady(client, state, cid, uuid, args)
2066
+ : await waitForOutlineReady(client, state, cid, uuid, args);
2067
+ const resultPayload = {
2068
+ command: 'outline-wait',
2069
+ cid,
2070
+ uuid,
2071
+ planMode,
2072
+ triggerMode: 'existing-task',
2073
+ waitResult,
2074
+ };
2075
+ outputResult(args, resultPayload, [
2076
+ `outline wait completed: cid=${cid}`,
2077
+ 'triggerMode: existing-task (preSet and multiBiddingChoice were not called)',
2078
+ `phase: ${waitResult?.phase || 'unknown'}`,
2079
+ ]);
2080
+ return resultPayload;
2081
+ }
2082
+
2048
2083
  async function handleOutlineUnlocked(args, state) {
2049
2084
  validateOutlineReferenceTypeOption(args);
2050
2085
  const client = createAuthorizedClient(args, state);
@@ -4231,12 +4266,35 @@ function collectParseIssues(result) {
4231
4266
  ];
4232
4267
 
4233
4268
  return issueKeys.filter(key => {
4269
+ if (key === 'score_judgement' && hasMeaningfulScoringContent(result)) {
4270
+ return false;
4271
+ }
4234
4272
  const directValue = result[key];
4235
4273
  const nestedValue = result.judgement_status?.[key.replace('_judgement', '')];
4236
4274
  return isFalsyStatus(directValue ?? nestedValue ?? '1');
4237
4275
  });
4238
4276
  }
4239
4277
 
4278
+ function hasMeaningfulScoringContent(result = {}) {
4279
+ return [
4280
+ result.rating,
4281
+ result.ratingContent,
4282
+ result.rating_content,
4283
+ result.scoreContent,
4284
+ result.score_content,
4285
+ ].some(value => meaningfulTextLength(value) >= 20);
4286
+ }
4287
+
4288
+ function meaningfulTextLength(value) {
4289
+ if (typeof value !== 'string') return 0;
4290
+ return value
4291
+ .replace(/<[^>]*>/g, ' ')
4292
+ .replace(/&(?:nbsp|ensp|emsp|#160);/gi, ' ')
4293
+ .replace(/\s+/g, '')
4294
+ .trim()
4295
+ .length;
4296
+ }
4297
+
4240
4298
  function collectContinuationParseIssues(result, args = {}) {
4241
4299
  const issues = collectParseIssues(result);
4242
4300
  const bidderRole = Number(args.bidderRole);