@lmzhen/dsh-evolution-approval 0.23.0 → 0.25.0

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 (2) hide show
  1. package/lib/index.js +38 -38
  2. package/package.json +7 -7
package/lib/index.js CHANGED
@@ -32,11 +32,11 @@ function makeApprovalRoutes(approval) {
32
32
  /** Guard: trust fence, then method. Every refusal is a JSON body, never an empty response. */
33
33
  const guard = (req, res, method) => {
34
34
  if (!isLoopbackRequest(req)) {
35
- writeJson(res, 403, { error: "forbidden: loopback-only" });
35
+ writeJson(res, 403, { error: "禁止访问:仅限回环地址" });
36
36
  return false;
37
37
  }
38
38
  if (req.method !== method) {
39
- writeJson(res, 405, { error: "method not allowed: " + method });
39
+ writeJson(res, 405, { error: "方法不允许:" + method });
40
40
  return false;
41
41
  }
42
42
  return true;
@@ -82,7 +82,7 @@ function makeApprovalRoutes(approval) {
82
82
  writeJson(res, 400, {
83
83
  ok: false,
84
84
  code: "bad-request",
85
- message: "status must be one of " + PENDING_STATUSES.join(", ")
85
+ message: "status 必须是以下之一:" + PENDING_STATUSES.join(", ")
86
86
  });
87
87
  return;
88
88
  }
@@ -118,7 +118,7 @@ function makeApprovalRoutes(approval) {
118
118
  writeJson(res, 400, {
119
119
  ok: false,
120
120
  code: "bad-request",
121
- message: "id is required"
121
+ message: "缺少 id"
122
122
  });
123
123
  return;
124
124
  }
@@ -128,7 +128,7 @@ function makeApprovalRoutes(approval) {
128
128
  writeJson(res, 200, {
129
129
  ok: false,
130
130
  code: "not-found",
131
- message: "no staged write with id \"" + id + "\""
131
+ message: "没有 id 为「" + id + "」的待批准写入"
132
132
  });
133
133
  return;
134
134
  }
@@ -138,7 +138,7 @@ function makeApprovalRoutes(approval) {
138
138
  ok: true,
139
139
  data: {
140
140
  available: false,
141
- reason: "a \"" + record.kind + "\" write has no preview"
141
+ reason: "类型 \"" + record.kind + "\" 的写入没有可预览内容"
142
142
  }
143
143
  });
144
144
  return;
@@ -182,7 +182,7 @@ function makeApprovalRoutes(approval) {
182
182
  writeJson(res, 400, {
183
183
  ok: false,
184
184
  code: "bad-request",
185
- message: "id is required"
185
+ message: "缺少 id"
186
186
  });
187
187
  return;
188
188
  }
@@ -199,7 +199,7 @@ function makeApprovalRoutes(approval) {
199
199
  writeJson(res, 400, {
200
200
  ok: false,
201
201
  code: "bad-request",
202
- message: "id is required"
202
+ message: "缺少 id"
203
203
  });
204
204
  return;
205
205
  }
@@ -349,12 +349,12 @@ var EvolutionApproval = class extends Service {
349
349
  async run(kind, args, intent) {
350
350
  if (intent?.interface !== "background_review") return {
351
351
  ok: false,
352
- message: "approval.run is the background-review replay channel; direct execution must use the tool path (staging is the only gate bypass for foreground)."
352
+ message: "approval.run 是后台复核的回放通道;直接执行必须走工具路径(对前台而言,暂存是唯一的门禁旁路)。"
353
353
  };
354
354
  const runner = this.runners.get(kind);
355
355
  if (!runner) return {
356
356
  ok: false,
357
- message: `No replay runner registered for kind "${kind}".`
357
+ message: `没有为类型「${kind}」注册回放运行器。`
358
358
  };
359
359
  return await runner(args);
360
360
  }
@@ -363,11 +363,11 @@ var EvolutionApproval = class extends Service {
363
363
  const summary = normalizeSummary(input);
364
364
  if (!this.enabled) return {
365
365
  action: "allow",
366
- message: "Approval disabled."
366
+ message: "批准已禁用。"
367
367
  };
368
368
  if ((this.deriveSessionPolicy(input.sessionId, input.session) ?? (this.ctx.get("approval") ? void 0 : input.sessionPolicy)) === "never") return {
369
369
  action: "allow",
370
- message: "Session approval policy is \"never\"; write allowed without staging."
370
+ message: "会话批准策略是「never」:写入无需暂存,直接放行。"
371
371
  };
372
372
  if (input.origin === "background_review" || this.stageForeground) {
373
373
  if (input.kind !== "capability" && !this.runners.has(input.kind)) this.ctx.logger.warn(`evolution-approval: staging "${input.kind}" write with no replay runner registered - it will not be approvable`);
@@ -385,12 +385,12 @@ var EvolutionApproval = class extends Service {
385
385
  return {
386
386
  action: "staged",
387
387
  pendingId: record.id,
388
- message: `Write staged for approval. Review with /evolution pending and approve ${record.id}.`
388
+ message: `写入已暂存待批准。用 /evolution pending 查看,并批准 ${record.id}。`
389
389
  };
390
390
  }
391
391
  return {
392
392
  action: "allow",
393
- message: "Foreground write allowed."
393
+ message: "前台写入已放行。"
394
394
  };
395
395
  }
396
396
  /** T4-09/A51: the effective expiry of the staged window, 0 = never. Read by the command surface
@@ -474,26 +474,26 @@ var EvolutionApproval = class extends Service {
474
474
  if (!executing) {
475
475
  if ((await this.state().listPending("pending")).find((item) => item.id === id)) return {
476
476
  ok: false,
477
- message: `Pending write "${id}" is already in the pending window — approve or reject it.`
477
+ message: `待批准写入「${id}」已经在待批准窗口里:直接批准或拒绝它。`
478
478
  };
479
479
  return {
480
480
  ok: false,
481
- message: `Pending write "${id}" is not in the executing window — nothing to release.`
481
+ message: `待批准写入「${id}」不在执行窗口中:没有可释放的。`
482
482
  };
483
483
  }
484
484
  if (this.inFlight.has(`approve:${id}`) || this.inFlight.has(`reject:${id}`)) return {
485
485
  ok: false,
486
- message: `Pending write "${id}" has an approve/reject RUNNING in this process — do not release it. Verify the effect instead; a completed approve resolves its own record.`
486
+ message: `待批准写入「${id}」在本进程里有正在运行的批准或拒绝:不要释放它。改为核验效果;已完成的批准会自行了结该记录。`
487
487
  };
488
488
  const claimId = typeof executing.claimedBy === "string" ? executing.claimedBy : "";
489
489
  if (claimId === "") return {
490
490
  ok: false,
491
- message: `Pending write "${id}" carries no claim to release (unexpected record shape) — reject it instead.`
491
+ message: `待批准写入「${id}」没有可释放的占用声明(记录形状异常):请改为拒绝它。`
492
492
  };
493
493
  const holderPid = claimHolderPid(claimId);
494
494
  if (holderPid !== null && holderPid > 0 && holderPid !== process.pid && isProcessAlive(holderPid)) return {
495
495
  ok: false,
496
- message: `Pending write "${id}" is claimed by pid ${holderPid}, which is ALIVE — another process may be running this approve. Do not release it: verify the write effect instead and let that run finish (a completed approve resolves its own record).`
496
+ message: `待批准写入「${id}」被 pid ${holderPid} 占用且该进程仍存活:可能有另一个进程正在执行这次批准。不要释放它:改为核验写入效果,并让那次运行跑完(已完成的批准会自行了结该记录)。`
497
497
  };
498
498
  let released = false;
499
499
  let failure = "";
@@ -506,11 +506,11 @@ var EvolutionApproval = class extends Service {
506
506
  }
507
507
  if (!released) return {
508
508
  ok: false,
509
- message: `Release of "${id}" did not take effect (${failure === "" ? "the claim no longer matches the record — a concurrent writer moved it" : failure}) — it stays EXECUTING with its claim unless it resolved, and the write effect is still unverified. Retry, or reject it to close the record without replaying.`
509
+ message: `释放「${id}」没有生效(${failure === "" ? "the claim no longer matches the record — a concurrent writer moved it" : failure}):除非它已了结,否则仍处于 EXECUTING 且保留占用声明,写入效果也仍未核验。请重试,或拒绝它以在不重放的情况下关闭记录。`
510
510
  };
511
511
  return {
512
512
  ok: true,
513
- message: `Released "${id}" back to the pending window.${holderPid === null ? " Its claim carries no pid, so liveness could NOT be verified: another process may still be running this approve." : ""} VERIFY the effect before approving: approve re-runs the write, and a non-idempotent replay duplicates an effect that already landed; reject closes the record instead.`
513
+ message: `已把「${id}」放回待批准窗口。${holderPid === null ? " Its claim carries no pid, so liveness could NOT be verified: another process may still be running this approve." : ""} 批准前请先核验效果:批准会重跑该写入,非幂等的重放会造成效果重复;改为拒绝则可关闭该记录。`
514
514
  };
515
515
  }
516
516
  async reject(id) {
@@ -519,14 +519,14 @@ var EvolutionApproval = class extends Service {
519
519
  if (!await this.state().claimPending(id, claimId)) {
520
520
  if ((await this.state().listPending("executing")).find((item) => item.id === id)) return (await this.state().tryResolvePending(id, "rejected")).applied ? {
521
521
  ok: true,
522
- message: `Rejected executing write "${id}" (no claim held — this may race an in-flight approve runner; if the write already landed its effect stands as-is. Verify the write state manually).`
522
+ message: `已拒绝执行中的写入「${id}」(未持有占用声明:这可能与在途的批准运行器抢跑;如果写入已落地,其效果按现状保留。请手动核验写入状态)。`
523
523
  } : {
524
524
  ok: false,
525
- message: `Pending write "${id}" could not be rejected: it resolved concurrently.`
525
+ message: `待批准写入「${id}」无法拒绝:它并发地了结了。`
526
526
  };
527
527
  return {
528
528
  ok: false,
529
- message: `Pending write "${id}" is not in the pending window (rotated or resolved).`
529
+ message: `待批准写入「${id}」不在待批准窗口里(已轮转或已了结)。`
530
530
  };
531
531
  }
532
532
  const resolution = await this.state().tryResolvePending(id, "rejected", claimId);
@@ -534,12 +534,12 @@ var EvolutionApproval = class extends Service {
534
534
  await this.state().releasePendingClaim(id, claimId);
535
535
  return {
536
536
  ok: false,
537
- message: `Pending write "${id}" is not pending (already resolved or missing).`
537
+ message: `待批准写入「${id}」已不在待批准状态(已了结或不存在)。`
538
538
  };
539
539
  }
540
540
  return {
541
541
  ok: true,
542
- message: `Rejected ${resolution.record.kind} write "${id}".`
542
+ message: `已拒绝 ${resolution.record.kind} 写入「${id}」。`
543
543
  };
544
544
  });
545
545
  }
@@ -583,11 +583,11 @@ var EvolutionApproval = class extends Service {
583
583
  if (!record) {
584
584
  if ((await this.state().listPending("executing")).find((item) => item.id === id)) return {
585
585
  ok: false,
586
- message: `Pending write "${id}" is executing — either another writer is resolving it right now, or a previous approve ran then crashed. If you did not start this approve, do not reject it (the in-flight run completes on its own); verify the effect instead. A genuinely stuck record (no runner activity) can still be rejected — /evolution pending shows it as EXECUTING.`
586
+ message: `待批准写入「${id}」正在执行:可能有另一个写入方正在了结它,或此前一次批准跑过之后崩了。如果不是你发起的这次批准,就不要拒绝它(在途的运行会自行完成);改为核验效果。确实卡住的记录(运行器没有任何动静)仍然可以拒绝 —— /evolution pending 会把它显示为 EXECUTING。`
587
587
  };
588
588
  return {
589
589
  ok: false,
590
- message: `Pending write "${id}" is not in the pending window (rotated or resolved).`
590
+ message: `待批准写入「${id}」不在待批准窗口里(已轮转或已了结)。`
591
591
  };
592
592
  }
593
593
  const runner = this.runners.get(record.kind);
@@ -596,22 +596,22 @@ var EvolutionApproval = class extends Service {
596
596
  if (!(await this.state().tryResolvePending(id, "approved", claimId)).applied) {
597
597
  if ((await this.state().listPending("rejected")).find((item) => item.id === id)) return {
598
598
  ok: false,
599
- message: `Capability "${id}" was approved, but the record was resolved to "rejected" concurrently — no code ran and nothing needs replaying; verify before re-submitting.`
599
+ message: `能力「${id}」已获批准,但记录被并发地了结为「rejected」:没有代码运行,也无需重放;重新提交前请先核验。`
600
600
  };
601
601
  return {
602
602
  ok: false,
603
- message: `Pending write "${id}" was already resolved by another writer.`
603
+ message: `待批准写入「${id}」已被另一个写入方了结。`
604
604
  };
605
605
  }
606
606
  return {
607
607
  ok: true,
608
- message: "Capability approved for manual activation in Creator mode (no code was executed)."
608
+ message: "能力已批准,可在 Creator 模式下手动激活(未执行任何代码)。"
609
609
  };
610
610
  }
611
611
  await this.state().releasePendingClaim(id, claimId);
612
612
  return {
613
613
  ok: false,
614
- message: `No replay runner registered for kind "${record.kind}".`
614
+ message: `没有为类型「${record.kind}」注册回放运行器。`
615
615
  };
616
616
  }
617
617
  try {
@@ -620,7 +620,7 @@ var EvolutionApproval = class extends Service {
620
620
  await this.state().releasePendingClaim(id, claimId);
621
621
  return {
622
622
  ok: false,
623
- message: /changed since this plan|no entry matching|not found|no longer exists|path traversal/i.test(result.message) ? `${result.message} — a sibling write from the same plan may have already changed this target, so repeated approves will keep failing. Reject this record unless the target changed again.` : result.message
623
+ message: (/* @__PURE__ */ new RegExp("changed since this plan|no entry matching|not found|no longer exists|path traversal|在图渲染之后被改动过|匹配到多条不同条目|已不存在|不存在|路径穿越|不在技能|找不到|被改动过|已改动|不匹配|已过期|changed since it was read", "i")).test(result.message) ? `${result.message} 同一计划里的兄弟写入可能已改动该目标,反复批准会一直失败;除非目标再次变更,请驳回该记录。` : result.message
624
624
  };
625
625
  }
626
626
  } catch (error) {
@@ -628,7 +628,7 @@ var EvolutionApproval = class extends Service {
628
628
  this.ctx.logger.warn(error);
629
629
  return {
630
630
  ok: false,
631
- message: "Replay runner failed; the pending write remains pending."
631
+ message: "回放运行器失败:该待批准写入仍处于待批准状态。"
632
632
  };
633
633
  }
634
634
  const resolution = await this.state().tryResolvePending(id, "approved", claimId).catch((error) => {
@@ -637,21 +637,21 @@ var EvolutionApproval = class extends Service {
637
637
  });
638
638
  if (typeof resolution === "string") return {
639
639
  ok: false,
640
- message: `Approved write "${id}" was replayed, but resolving the record failed (${resolution.slice(8)}) — the effect has LANDED while the audit row stays "executing". Verify the write manually; approve will not re-run it.`
640
+ message: `已批准写入「${id}」已重放,但了结记录失败(${resolution.slice(8)}):效果已经落地,而审计行仍停在「executing」。请手动核验该写入;批准不会再次重跑它。`
641
641
  };
642
642
  if (!resolution.applied) {
643
643
  if ((await this.state().listPending("rejected")).find((item) => item.id === id)) return {
644
644
  ok: false,
645
- message: `Approved write "${id}" was replayed, but the record was resolved to "rejected" concurrently — the effect has landed while the audit reads rejected. Verify the write and do NOT replay it.`
645
+ message: `已批准写入「${id}」已重放,但记录被并发地了结为「rejected」:效果已落地,而审计显示为 rejected。请核验该写入,且不要重放它。`
646
646
  };
647
647
  return {
648
648
  ok: false,
649
- message: `Pending write "${id}" was already resolved by another writer.`
649
+ message: `待批准写入「${id}」已被另一个写入方了结。`
650
650
  };
651
651
  }
652
652
  return {
653
653
  ok: true,
654
- message: `Approved ${record.kind} write "${id}" (${record.summary}).`
654
+ message: `已批准 ${record.kind} 写入「${id}」(${record.summary})。`
655
655
  };
656
656
  }
657
657
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-approval",
3
3
  "description": "Stage/pending approval service for Hermes-style self-evolution writes (community build)",
4
- "version": "0.23.0",
4
+ "version": "0.25.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,18 +27,18 @@
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
29
  "@deepseek-ai/schemastery": "^3.18.4",
30
- "@lmzhen/dsh-evolution-core": "^0.23.0"
30
+ "@lmzhen/dsh-evolution-core": "^0.25.0"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "@deepseek-ai/cordis": "^4.0.1",
34
34
  "@deepseek-ai/dsh-host-webserver": "^0.2.0-rc.1",
35
- "@lmzhen/dsh-evolution-state-storage": "^0.23.0",
36
- "@lmzhen/dsh-evolution-state": "^0.23.0"
35
+ "@lmzhen/dsh-evolution-state-storage": "^0.25.0",
36
+ "@lmzhen/dsh-evolution-state": "^0.25.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@deepseek-ai/dsh-host-webserver": "^0.2.0-rc.1",
40
- "@lmzhen/dsh-evolution-core": "^0.23.0",
41
- "@lmzhen/dsh-evolution-state-storage": "^0.23.0",
42
- "@lmzhen/dsh-evolution-state": "^0.23.0"
40
+ "@lmzhen/dsh-evolution-core": "^0.25.0",
41
+ "@lmzhen/dsh-evolution-state-storage": "^0.25.0",
42
+ "@lmzhen/dsh-evolution-state": "^0.25.0"
43
43
  }
44
44
  }