@sema-agent/sdk 16.3.0 → 17.1.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 (58) hide show
  1. package/README.md +138 -2
  2. package/dist/errors.d.ts +91 -14
  3. package/dist/errors.d.ts.map +1 -1
  4. package/dist/errors.js +104 -12
  5. package/dist/errors.js.map +1 -1
  6. package/dist/events.d.ts +8 -0
  7. package/dist/events.d.ts.map +1 -1
  8. package/dist/events.js.map +1 -1
  9. package/dist/health.d.ts +10 -1
  10. package/dist/health.d.ts.map +1 -1
  11. package/dist/health.js.map +1 -1
  12. package/dist/index.d.ts +16 -4
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +10 -2
  15. package/dist/index.js.map +1 -1
  16. package/dist/resources/approvals.d.ts +34 -30
  17. package/dist/resources/approvals.d.ts.map +1 -1
  18. package/dist/resources/approvals.js +30 -0
  19. package/dist/resources/approvals.js.map +1 -1
  20. package/dist/resources/memory.d.ts +4 -0
  21. package/dist/resources/memory.d.ts.map +1 -1
  22. package/dist/resources/memory.js +4 -0
  23. package/dist/resources/memory.js.map +1 -1
  24. package/dist/resources/rules.d.ts +4 -7
  25. package/dist/resources/rules.d.ts.map +1 -1
  26. package/dist/resources/rules.js.map +1 -1
  27. package/dist/resources/session-sync.d.ts.map +1 -1
  28. package/dist/resources/session-sync.js +2 -3
  29. package/dist/resources/session-sync.js.map +1 -1
  30. package/dist/resources/sessions.d.ts +12 -1
  31. package/dist/resources/sessions.d.ts.map +1 -1
  32. package/dist/resources/sessions.js +12 -1
  33. package/dist/resources/sessions.js.map +1 -1
  34. package/dist/resources/tasks.d.ts +12 -1
  35. package/dist/resources/tasks.d.ts.map +1 -1
  36. package/dist/resources/tasks.js +12 -1
  37. package/dist/resources/tasks.js.map +1 -1
  38. package/dist/resources/tool-approvals.d.ts +53 -90
  39. package/dist/resources/tool-approvals.d.ts.map +1 -1
  40. package/dist/resources/tool-approvals.js +24 -12
  41. package/dist/resources/tool-approvals.js.map +1 -1
  42. package/dist/settings.d.ts +7 -8
  43. package/dist/settings.d.ts.map +1 -1
  44. package/dist/settings.js +1 -1
  45. package/dist/sync.d.ts +7 -7
  46. package/dist/sync.d.ts.map +1 -1
  47. package/dist/sync.js +32 -17
  48. package/dist/sync.js.map +1 -1
  49. package/dist/transport.d.ts +3 -1
  50. package/dist/transport.d.ts.map +1 -1
  51. package/dist/transport.js +4 -1
  52. package/dist/transport.js.map +1 -1
  53. package/dist/types.d.ts +114 -44
  54. package/dist/types.d.ts.map +1 -1
  55. package/dist/types.js +23 -0
  56. package/dist/types.js.map +1 -1
  57. package/openapi.yaml +283 -160
  58. package/package.json +1 -1
package/dist/types.d.ts CHANGED
@@ -57,7 +57,7 @@
57
57
  * null" may be correct — check for a normalizer at the boundary before widening it to `| null`.
58
58
  */
59
59
  import type { SemaSettings } from "./settings.js";
60
- import type { AllowRuleShadow, AskOrigin, ClassifierUnavailable, DenialLimitFallback, PersistedRuleMandate, RuleOffer, RuleOffersAbsence, ToolApprovalFrame } from "./resources/tool-approvals.js";
60
+ import type { AllowRuleShadow, AskOrigin, AutoModeFallbackCause, BoundSkillGrants, ClassifierUnavailable, DenialLimitFallback, PersistedRuleMandate, RuleOffer, RuleOffersAbsence, ToolApprovalFrame } from "./resources/tool-approvals.js";
61
61
  /** Authenticated end-user identity. Opaque to the service (used as memory scope + session owner). The SDK
62
62
  * normalizes; the service does NOT validate the format. Convention: `user:` / `org:` / `ai:` / `anon:`. */
63
63
  export type Principal = string;
@@ -212,6 +212,14 @@ export interface TaskStats {
212
212
  /** 🔴 开集:引擎 `result.stats` 可携带本类型未命名的字段(如 `costBreakdown.*` 明细;live 实测),原样透传不丢。 */
213
213
  [key: string]: unknown;
214
214
  }
215
+ /**
216
+ * 请求键 {@link TaskRequest.approvalReach} 的闭集 —— 引擎 `APPROVAL_REACH`(core 7.43.0 #1354)逐字:今天只有 `"none"`(这条 run 上没有人能被问审批)。
217
+ * 没有正向词:「有人可问」是 `interactionPosture:"interactive"` 那一门的承诺。**闭集**(server 用引擎谓词 `isApprovalReach` 判,集外 400):加词 = 引擎下一版 +
218
+ * 本常量与 spec `ApprovalReach` enum 同批加。
219
+ */
220
+ export declare const APPROVAL_REACH: readonly ["none"];
221
+ /** {@link APPROVAL_REACH} 的成员型。 */
222
+ export type ApprovalReach = (typeof APPROVAL_REACH)[number];
215
223
  /** Common request body. `objective` is required; everything else is optional and server-capped where noted.
216
224
  * 🔴 `jobId` is the work-view correlation key (DIRECTION §2): set it so the workspace groups the runs of one
217
225
  * logical job into one Task — across BOTH doors.
@@ -590,14 +598,17 @@ export interface TaskRequest {
590
598
  * 判不出保护目标的写仍拒(`deniedBy:"mode"`)。
591
599
  * · `auto` 武装 ⟺ `permissionMode === "auto"` ∧ 部署挂了分类器席 ∧ `caps.autoMode !== false`(单极;答旧极性的那一位 server 7.107.0 起删,
592
600
  * 读 `capabilities.permissionModeAuto.armed` / `reason`)。请求的模式没生效 ⇒ 流上一帧 `engine_notice` `config.permission_mode_unavailable`(`effective` 恒 `default`)。
593
- * · 词表:请求面**五词**(本型 = {@link PermissionMode} 去掉 `dontAsk`);`dontAsk` fresh 提交 400 `request.field_invalid`(S-902,票 7.107.0)。
601
+ * · 词表:请求面**六词** = {@link PermissionMode}(server ≥7.119.0 起 `dontAsk` 受理、原样过境引擎:引擎按模式拒要问的调用 —— 零卡、`tool_end.gate.disposition`
602
+ * `{ kind: "denied", deniedBy: "mode", mode: "dontAsk" }`,run 照常收束;它不比 `default` 放得更宽。**例外**:一只 PreToolUse hook 自己的问、且这只问的类集里没有别的类托底时,引擎仍把它交给人
603
+ * 〔引擎 `arbitrateByMode`:`hook` 类且该行没有 `hookAskFloor`〕—— 「拒要问的调用」不含这一条)。**见位才发**:先读 {@link Capabilities.permissionModes}(位缺席 = 老 server,
604
+ * 请求面只收五词,`dontAsk` fresh 提交 400 `request.field_invalid`;≤7.118.x 的续跑重放把存下的 `dontAsk` 折成 `default`)。顶层键、`settings.permissions.defaultMode`、
605
+ * `GET /v1/capabilities?permissionMode=` 三处读同一只闭集。词表外的值照旧 400 `request.field_invalid`,句里的词表按**这台 server 自己的**列出(比对码,别比对整句)。
594
606
  * ⚠️ 下文「omit ⇒ NO mode-derived gate」「`auto` 与请求词无关、按 principal 授权武装」「bypass adds NO mode-derived ask gate」三句只对 ≤7.105.0 成立。
595
607
  *
596
- * 🔴 PERMISSION MODE INTENT — the TOB-fleet server's five accepted wire values: `default` | `plan` |
597
- * `acceptEdits` | `bypassPermissions` | `auto` (post-[816]/[820]/[822] current state; server task-settings.ts
598
- * `SettingsPermissionMode` is the same closed set, same-batch aligned 2026-08-05 via server.ts submit-gate
599
- * commits 0c39959/ff62de6). NOT a claim that these are CC's/sema-cli's complete mode vocabulary — that
600
- * internal set is wider (e.g. `dontAsk`); this is specifically what THIS wire's closed submit-gate accepts.
608
+ * 🔴 PERMISSION MODE INTENT — the TOB-fleet server's accepted wire values: `default` | `plan` |
609
+ * `acceptEdits` | `bypassPermissions` | `auto` | `dontAsk` (server >= 7.119.0; the engine's whole mode vocabulary, published as
610
+ * {@link Capabilities.permissionModes}). A server <= 7.118.x accepts the first five only — `dontAsk` there is a 400 on a fresh submit.
611
+ * This is what THIS wire's closed submit-gate accepts.
601
612
  * The shell/web frontend carries
602
613
  * the RAW mode; the SERVICE INTERPRETS it (axis-aware, tighten-only vs the deployment/operator baseline):
603
614
  * `plan` ⇒ mount the first-party `present_plan` tool (core `TaskSpec.enablePlanMode`, CC ExitPlanMode parity) +
@@ -610,7 +621,7 @@ export interface TaskRequest {
610
621
  * gate-policy for `auto` as for `default` (identical branch, server task-settings.ts) — sending `auto` is NOT
611
622
  * itself what arms core's separate auto-mode classifier; that classifier is armed purely by the PRINCIPAL's
612
623
  * entitlement (`runtimeCaps.autoMode === true` AND a deployment `deps.autoMode` wiring), independent of which
613
- * of these five words the request sends — an entitled principal's `default` request is screened too, and a
624
+ * of these words the request sends — an entitled principal's `default` request is screened too, and a
614
625
  * non-entitled principal's `auto` request behaves as plain `default`; `bypassPermissions`
615
626
  * is HONORED as a gate-shape choice that adds NO mode-derived ask gate — it is **not** a loosen: the
616
627
  * deployment/operator baseline (deny/ask rules) still folds in deny-wins on top (`tightenTaskSpec`), so bypass
@@ -625,7 +636,7 @@ export interface TaskRequest {
625
636
  * gate at all" (the SAME posture as `bypassPermissions`) is true only when NEITHER carrier supplies a mode. A
626
637
  * caller that wants the manual-ask posture must send `"default"` on at least one carrier — omitting both is
627
638
  * NOT equivalent to sending an explicit `"default"` on either. */
628
- permissionMode?: Exclude<PermissionMode, "dontAsk">;
639
+ permissionMode?: PermissionMode;
629
640
  /** 🔴 **READ 容纳面(`readFace` / READ deny 表)不在这条请求面上** —— 2026-08-16 亲读 server 7.25.0
630
641
  * 实况定界(不是「SDK 还没跟上」,别照着 core 的 `TaskSpec.readFace` 在这里手拼一个键):
631
642
  * · **接收面 = 部署席,单腿 env**:`READ_FACE`(`open`|`roots`,坏词启动期响亮拒)/ `READ_DENY_PATTERNS`
@@ -686,6 +697,15 @@ export interface TaskRequest {
686
697
  * deployment supports them). Probe `capabilities.interactiveTools` (server hardcodes true — the `interactiveTools` bit in `routes/capabilities.ts`)
687
698
  * before sending to OLDER servers — an unknown-field deployment on the strict lane would 400. */
688
699
  interactiveTools?: boolean;
700
+ /**
701
+ * server ≥7.118.0(core 7.43.0 #1354)—— **声明这条 run 上没有人能答审批**。唯一一词 `"none"`({@link APPROVAL_REACH});原样投引擎 `TaskSpec.approvalReach`。
702
+ *
703
+ * 给 `-p` 这类握着流、却没有人能答审批的壳:不声明时部署的审批席照发活卡、wiring 清单报 `ask.effective:"human_reachable"`。声明之后活的回调不再是
704
+ * 这条 run 的审批人(wiring 清单 `ask.form:"declared_none"`);**有停驻设施的部署上第一次门控调用就停驻**(run `paused`)—— 要「拒了接着跑」用
705
+ * `permissionMode:"dontAsk"`。它**不**放行、**不**释放任何东西。引擎不把它写进检查点,续跑腿由 server 从持久化体重供。
706
+ * 读不出的值(集外词 / 非串)⇒ `400 request.field_invalid`。先探 {@link Capabilities.approvalReach}(缺席 = 老 server)。不发 = 零变化。
707
+ */
708
+ approvalReach?: ApprovalReach;
689
709
  /**
690
710
  * 🔴 ONE-SHOT SUBMISSION declaration (core ≥5.23.0 `TaskSpec.oneShot`, server ≥7.12.0 —
691
711
  * `src/http/wire-types.ts` 的请求形;非 boolean = fail-loud 400 `request.field_invalid`
@@ -919,17 +939,12 @@ export interface TaskAgentDefinition {
919
939
  /** Denylist of tool names (subtractive; applied after `allowTools`). */
920
940
  denyTools?: string[];
921
941
  /** Skills preloaded into the agent: `{ name, description, content }` (+ optional allowedTools / disallowedTools / files).
922
- * server ≥7.116.0:子代技能受理两只清单(`allowedTools` / `disallowedTools`,读法见 {@link SkillSpec.allowedTools};≤7.115.x 是未知键整条拒)。 */
942
+ * server ≥7.116.0:子代技能受理两只清单(`allowedTools` / `disallowedTools`,读法见 {@link SkillSpec.allowedTools};≤7.115.x 是未知键整条拒)。
943
+ * ⚰️ sdk 17.0.0 删 `manifest`(core 7.41.0 退役、server ≥7.116.0 整条拒;≤7.115.x 收下也不生效)—— 改写:`manifest.allowTools` → `allowedTools`,`allowPaths` 无替身(用会话规则 `allowDirs`)。 */
923
944
  skills?: Array<{
924
945
  name: string;
925
946
  description: string;
926
947
  content: string;
927
- /** @deprecated server ≥7.116.0 **整条技能拒**(子代技能上 `manifest` 是未知键 ⇒ `agent.skills must be …` 400;顶层技能是 400 `request.field_invalid`,
928
- * 句首 `skill.manifest was retired in core 7.41.0 — `)—— core 7.41.0 退役了技能 `manifest`(硬破坏,零别名)。**改写**:`manifest.allowTools` →
929
- * 技能的 `allowedTools`(语义变了:allow 规则来源、不是围栏,见 {@link SkillSpec.allowedTools});写围栏 `allowPaths` 没有替身
930
- * (圈写路径用会话规则 `allowDirs`)。详见 server 随包 `MIGRATION.md` 7.116.0 节。
931
- * 本成员**留着**:老一代 server(≤7.115.x)仍收它,删公开成员 = major,下个 major 删;对 ≥7.116.0 的 server 别再发。 */
932
- manifest?: Record<string, unknown>;
933
948
  allowedTools?: string[];
934
949
  disallowedTools?: string[];
935
950
  files?: Array<{
@@ -1142,9 +1157,15 @@ export interface SyncSubmitResult extends TaskResult {
1142
1157
  * 先到先得:一条腿只被中止一次,先落地的那次定词(断连之后又到的取消动词、取消之后又断连,终局说的都是真正让它停下来的那一个)。
1143
1158
  * **闭集**,按 additive 规矩只会加词(加词 = server 新版本的 wire 变更〔`wire-changes` 登记〕+ 本包下一版形变,spec 具名 schema `AbortCause` 的 enum 同批):
1144
1159
  * 认不得的词读作「server 中止,成因不认识」。属主是 server `plugins/store-contracts.ts` 的 `ABORT_CAUSES`(自铸登记 `trace/self-minted-wire.ts#abortCause`);
1145
- * 测试对已装 server 的真登记做四方相等(server 常量 / 登记 / spec enum / 本型的词)。读法与在场闸见 {@link TaskResult.abortCause}。
1160
+ * 测试对已装 server 的真登记做四方相等(server 常量 / 登记 / spec enum / 本常量)。读法与在场闸见 {@link TaskResult.abortCause}。
1161
+ *
1162
+ * 🔴 **运行期常量**(sdk 17.0.0 起导出;消费方的生成表直接读它,不手抄第二份):与 server 的 `ABORT_CAUSES` **同名同序**;
1163
+ * server 包根不导出那一只(`./dist/*` 子路径也不导出),所以本包是消费方能 import 的唯一一处 —— 测试对已装 server 发布字节里的真常量逐词逐序对拍。
1164
+ * `Object.freeze` 的字面元组(公面消费者 push 一下就能改写判定的病形)。
1146
1165
  */
1147
- export type AbortCause = "client_disconnected" | "ask_park_grace_exhausted" | "cancel_verb";
1166
+ export declare const ABORT_CAUSES: readonly ["client_disconnected", "ask_park_grace_exhausted", "cancel_verb"];
1167
+ /** {@link ABORT_CAUSES} 的成员型。 */
1168
+ export type AbortCause = (typeof ABORT_CAUSES)[number];
1148
1169
  /**
1149
1170
  * 取消现场快照里的**大脑相位**(server `RunBrainStatusSnapshot`,`turn-activity.ts` `pickRunBrainStatus` 投出的五键子集;K-43,sdk 16.0.0 具名)——
1150
1171
  * 「取消那一刻引擎正在重试第几次 / 在等什么 / 什么错类」。`phase` 是这只快照的存在理由(没有它就没有快照,不铸半只)。
@@ -2403,19 +2424,20 @@ export type DeniedBy = "policy" | "hook" | "org" | "persisted_rule" | "classifie
2403
2424
  /**
2404
2425
  * 权限模式词(core 7.34.0 `PERMISSION_MODES`,六词;K-32 扩项 / server ≥7.106.0 起上 wire 的门记录位 {@link ModeRelease.mode} 用它)。
2405
2426
  * 🔴 **在门记录这一面是真闭集**:server `dist/trace/project.js` 的 `modeLedgerDefect` 按 core `isPermissionMode` 筛,出集 ⇒ 整条 `gate` 不上帧
2406
- * (与 {@link DeniedBy} 同一条纪律)。⚠️ 请求面不是六词:{@link TaskRequest.permissionMode} 在 server 7.106.0 上只收**五词**(`dontAsk` fresh
2407
- * 400 `request.field_invalid`,S-902 票 7.107.0)—— 它照样可能出现在门记录上(例:部署旋钮 `UNATTENDED_PERMISSION_MODE=dontAsk` 的无人值守腿)。
2427
+ * (与 {@link DeniedBy} 同一条纪律)。请求面({@link TaskRequest.permissionMode})从 server 7.119.0 起收**同一只六词**(先读 {@link Capabilities.permissionModes});
2428
+ * ≤7.118.x 的请求面只收五词(`dontAsk` fresh 提交 400 `request.field_invalid`)—— 但它在那些版本上照样可能出现在门记录上
2429
+ * (例:部署旋钮 `UNATTENDED_PERMISSION_MODE=dontAsk` 的无人值守腿)。
2408
2430
  */
2409
2431
  export type PermissionMode = "default" | "acceptEdits" | "plan" | "auto" | "bypassPermissions" | "dontAsk";
2410
2432
  /**
2411
- * 一只问**属于哪一类**(core `ASK_CLASSES`:7.34.0 铸二十词,core 7.39.0 起 `shell_floor` 入册 ⇒ 二十一词,core 7.40.0 起 `unstated` 入册 ⇒ 二十二词,core 7.41.0 起 `requires_user_interaction` 入册 ⇒ **二十三词**;模式 × 类仲裁表的列)。K-32 扩项 / server ≥7.106.0 起出现在
2433
+ * 一只问**属于哪一类**(core `ASK_CLASSES`:7.34.0 铸二十词,core 7.39.0 起 `shell_floor` 入册 ⇒ 二十一词,core 7.40.0 起 `unstated` 入册 ⇒ 二十二词,core 7.41.0 起 `requires_user_interaction` 入册 ⇒ 二十三词,core 7.43.0 起 `classifier_no_ruling` 入册 ⇒ 二十四词,core 7.45.0 起 `dangerous_delete` 入册 ⇒ **二十五词**;模式 × 类仲裁表的列)。K-32 扩项 / server ≥7.106.0 起出现在
2412
2434
  * {@link ModeRelease.askClass} / `.classes` 与 deny 臂的 `askClass` / `classes` 上,以及通告 `permission.ask_released_by_mode` 的 detail 里;
2413
2435
  * K-37 扩项 / server ≥7.109.0(S-934 ②)起也在审批面:活卡帧 / 卡面 / 运维队列行 / `/stream` `pending` 帧的 `askClass` / `classes`
2414
2436
  * (同样经 core `isAskClass` 筛,读不出整对不投;见 {@link import("./resources/tool-approvals.js").ToolApprovalFrame.askClass})。
2415
2437
  * 🔴 **门记录这一面是真闭集**(server 按 core `isAskClass` 筛,出集整条不上帧)。`bypassPermissions` 只放行其中**可放**的十类
2416
2438
  * (core `RELEASABLE_ASK_CLASSES`:`transcript_write` / `rule_unreadable` / `probe` / `write_protection` / `tool_marks_mcp` / `tool_marks_a2a` /
2417
2439
  * `artifact_shared_read` / `mode` / `unstated` / `ordinary`);其余(`operator_forced` 部署出身、`ask_rule` / `org_rule`、`hook`、`ancestor`、`content_question`、
2418
- * `unverifiable_delete`、`governance_unavailable`、`policy_rra`、`requires_user_interaction` …)任何模式下都照问。
2440
+ * `dangerous_delete`(core 7.45.0)、`unverifiable_delete`、`governance_unavailable`、`policy_rra`、`requires_user_interaction` …)任何模式下都照问。
2419
2441
  *
2420
2442
  * 🔴 **`requires_user_interaction`(core 7.41.0;server ≥7.116.0 提货)= 服务器声明「这只工具每次都要用户在场」**:MCP 服务器在工具申报里声明
2421
2443
  * `_meta["anthropic/requiresUserInteraction"] === true`(只认布尔 `true`)⇒ 这只工具的**每一次**调用都问人 —— **每种模式含 `bypassPermissions`** 都问(**不在**可放十类里),
@@ -2429,7 +2451,14 @@ export type PermissionMode = "default" | "acceptEdits" | "plan" | "auto" | "bypa
2429
2451
  * 先探 `capabilities.settings.permissions.allowGrant`)· 运维 env `APPROVAL_GRANT` · PreToolUse hook 显式 `permissionDecision:"allow"` · 接审批面 · `permissionMode:"bypassPermissions"`(请求腿);
2430
2452
  * `plan` 模式下只有**只读**的服务器工具出这张卡。本类说的是「**没人说**」,不是 `ask_rule` / `org_rule` 那种「有人说了问」。
2431
2453
  */
2432
- export type AskClass = "content_question" | "hook" | "ancestor" | "unverifiable_delete" | "transcript_write" | "org_rule" | "governance_unavailable" | "rule_unreadable" | "ask_rule" | "denial_limit_fallback"
2454
+ export type AskClass = "content_question" | "hook" | "ancestor"
2455
+ /** core 7.45.0 / server ≥7.119.0:**受保护位置的删除**(`rm` / `rmdir` 的目标是文件系统根、顶层目录、家目录、任务根 / 工作目录 / 附加工作目录或它们的祖先 —— 含 `rm -rf *` 在任务根、`rm -rf ~/*` ——
2456
+ * 或 shell 拿到的是运行时才拼出的脚本〔`bash -c "$CMD"` / `eval "$(…)"`〕)。**只有人的答清得掉**:任何模式(含 `bypassPermissions`)、任何 allow(请求 `settings.permissions.allow`、运维 `APPROVAL_GRANT`、
2457
+ * 存下的 allow 行、技能清单、hook 的 allow)、`auto` 的分类器都清不掉;帧上同带 `requiresRealApproval:true`;没人答就不执行(无人值守腿拒)。**免疫 bypass**(不在可放十类里)。 */
2458
+ | "dangerous_delete" | "unverifiable_delete" | "transcript_write" | "org_rule" | "governance_unavailable" | "rule_unreadable" | "ask_rule" | "denial_limit_fallback"
2459
+ /** core 7.43.0 #1353 / server ≥7.118.0:auto 模式的分类器**没判出来**(它跑不了 —— `error` / `timeout`,或答了却没有判词 —— `parse_error`),于是交给人:
2460
+ * denial-limit 回落那一行(只有人的答清得掉;**免疫 bypass**,allow 规则清不掉,分类器不再被问)。活卡帧 / 收件箱行另带成因 {@link import("./resources/tool-approvals.js").ToolApprovalFrame.classifierNoRuling}。 */
2461
+ | "classifier_no_ruling"
2433
2462
  /** core 7.41.0 / server ≥7.116.0:服务器工具申报声明「每次调用都要用户在场」(见本型顶注)—— **不在** `bypassPermissions` 可放的十类里,只有人的答清得掉。 */
2434
2463
  | "requires_user_interaction" | "operator_forced"
2435
2464
  /** core 7.39.0(#1260;server ≥7.113.0 提货):运维旋钮 `shellGate: "always"` 在**跑 shell 的席位**上的地板 —— `operator_always` 授权词所披露的那一问,
@@ -3389,7 +3418,7 @@ export interface McpToolFace {
3389
3418
  export type AutoModeUnarmedReason = "mode_not_auto" | "deployment_incapable" | "org_denied" | "local_denied" | "settings_denied" | "resolver_fault" | (string & {});
3390
3419
  /** 三代形共有的三位 —— server **≤7.56.0 只发这三位**(见 {@link PermissionModeAutoCapability})。 */
3391
3420
  interface PermissionModeAutoBase {
3392
- /** 提交面按五词闭集收 `"auto"`(server 写的是字面量,恒 `true`)。 */
3421
+ /** 提交面按闭集收 `"auto"`(server 写的是字面量,恒 `true`)。 */
3393
3422
  accepted: true;
3394
3423
  /** 分类器席位真挂上了(桩 / 一次性 CLI 不挂席位时如实 `false`)。 */
3395
3424
  classifierSeat: boolean;
@@ -3623,8 +3652,10 @@ export interface Capabilities {
3623
3652
  * 🔴 **两端都读**:同步是 src → dst 两个 peer,**任一端为 `false` ⇒ 只同步对话**:别推 `fileHistory`、别 PUT blob(把 `fileHistory` 推给没有 blob 面的对端,
3624
3653
  * commit 之后因缺 blob 422 `missing_blob`)。位为 `false` 时两口答 **501 `capability.snapshot_store_required`**(任何会话 id 同一句,先于属主判);
3625
3654
  * blob「未被会话历史图引用 / 字节不存在」仍是 404 `not_found.blob`(scope 边界,只在有 blob 面的后端上可达)。
3626
- * ⚠️ **缺席 = 老 server(≤7.115.x)**:那里 `sessionSync: true` 的 local 部署上 PUT blob 恒 501(位说「能」而口恒拒)—— 缺席时**读不出**这一面能不能用,
3627
- * 既有 verb 照旧试(`pushSessionBundle` / `pullSessionBundle` 对缺席位照旧尝试,见 {@link import("./sync.js").PushSessionResult.fileHistory})。 */
3655
+ * ⚠️ **缺席 = 老 server(≤7.115.x)= 不知道**:那里 `sessionSync: true` 的 local 部署上 PUT blob 恒 501、`GET …/sync/history/blobs` 对清单引用的 blob 恒 404(位说「能」而口恒拒)。
3656
+ * sdk 17.0.0 起编排 verb 按一条律读(`pushSessionBundle` / `pullSessionBundle` / `importSessionBundle` 同读):**信封引用了 blob 而某一端位缺席 ⇒ 不搬**(`fileHistory:"skipped"`,只同步对话);
3657
+ * 信封不引用 blob(只有回退边界)⇒ 照带 —— 16.2.0–16.3.0「缺席 ⇒ 照旧尝试」退役(那一读法在 7.52–7.115 的 local 后端上改过文件的会话整次抛),
3658
+ * 见 {@link import("./sync.js").PushSessionResult.fileHistory}。 */
3628
3659
  sessionSyncFileHistory?: boolean;
3629
3660
  /** 🔴 K-5 session-resume gates(service src/http/routes/capabilities.ts,§0.5 session 抽象)—— shell 的 `/resume` picker 据此诚实
3630
3661
  * gate,别 trial-by-501:`sessionList` = list 可用(`Boolean(sessionStorage.listSessions ?? runStore.listSessions)`,
@@ -3730,6 +3761,9 @@ export interface Capabilities {
3730
3761
  retainBackgroundProcesses?: boolean;
3731
3762
  /** TaskRequest.interactiveTools 认词(`routes/capabilities.ts` 的能力对象 硬编码 true;-p 无人值守语义探测位 —— 见 TaskRequest 注)。 */
3732
3763
  interactiveTools?: boolean;
3764
+ /** server ≥7.118.0(`routes/capabilities.ts` 的能力对象**硬编码 true**,与请求键同一个词)—— 请求键 {@link TaskRequest.approvalReach} 认词的**版本探测位**。
3765
+ * 缺席 = 老 server:别发那只键(严格体会拒)。 */
3766
+ approvalReach?: boolean;
3733
3767
  /** TaskRequest.cwd honored(`routes/capabilities.ts` 的能力对象 `cwdHonored`:local 单用户 host-adapter 才 true;多租户 fail-closed)。
3734
3768
  * 🔴 K-32 扩项(server ≥7.106.0 / S-895):本位也是请求键 {@link TaskRequest.inheritEnv} `"all"` 的**精确兑现读数** —— 谓词(host 车道 ∧
3735
3769
  * 非托管)与那个键的车道门 + 射程门逐组合相等(契约附录 B.1 该行 / §18)。`false` ⇒ 发 `"all"` 会拿 400(非 host 车道)或 422(托管)。 */
@@ -3807,6 +3841,12 @@ export interface Capabilities {
3807
3841
  * 「这个二进制认识这个键」——与 {@link permissionRulesRevoke} 的存在性信号同族,刻意不挂任何设施谓词。
3808
3842
  */
3809
3843
  approvalDecisionNote?: boolean;
3844
+ /**
3845
+ * server ≥7.118.0(`routes/capabilities.ts` 的能力对象**硬编码 true**,恒真的版本位)—— 三条审批决定口收决定体的出处位 `decidedBy`
3846
+ * ({@link import("./resources/approvals.js").ApprovalDecidedBy})。**见位才发**:位缺席 = 老 server —— 耐久两口与 `plan_review` 对它 400、
3847
+ * live `respond` 静默丢 + 200,照老形发(不带这只键)。与 {@link approvalDecisionNote} 同族:只答「这个二进制认识这个键」,不挂设施谓词。
3848
+ */
3849
+ approvalDecidedBy?: boolean;
3810
3850
  /**
3811
3851
  * #340(server ≥7.44.0,`routes/capabilities.ts` 的能力对象**硬编码 true**)—— live 回决口
3812
3852
  * `POST /v1/tool-approvals/:id/respond` 收 `persistRule.edited: true` 的**版本探测位**:
@@ -3979,11 +4019,21 @@ export interface Capabilities {
3979
4019
  * ⇒ 四口 501 `capability.memory_optout_grant_required`)。
3980
4020
  * 🔴 位为假时是 **501**(换部署形态),与 {@link memoryConsolidationDriver} 的 404(开旋钮)分家。 */
3981
4021
  memoryOptOutGrant?: boolean;
4022
+ /**
4023
+ * server ≥7.119.0(`routes/capabilities.ts` 的能力对象,值 = 引擎 `PERMISSION_MODES` **全集**,引擎序)—— 这台 worker 的请求面**收的权限模式词**:今天六词
4024
+ * `default` / `acceptEdits` / `plan` / `auto` / `bypassPermissions` / `dontAsk`。顶层 {@link TaskRequest.permissionMode}、`settings.permissions.defaultMode`、
4025
+ * `GET /v1/capabilities?permissionMode=` 三处读同一只闭集;**位 ⟺ 面**:位里的每个词读口都收、位外的词 400 `request.field_invalid` 且句里的词表与位逐字同。
4026
+ *
4027
+ * 🔴 **见位才发 `dontAsk`**:位缺席 = 老 server(≤7.118.x),请求面只收五词,`dontAsk` fresh 提交 400。位在场且含某词 ⇒ 这个词可发。
4028
+ * 🔴 **开集读**:位是**引擎词表的原样转发**,不是 SDK 判成员的闭集 —— 引擎加第七个词时位里会先出现一个本包型面还不认识的串;按位决定发不发,别拿
4029
+ * {@link PermissionMode} 去过滤它。⚠️ 它说的是「这台 server 收这个词」,**不说**这个词在这次提交上会不会生效(`auto` 还要分类器席与授权,读 {@link permissionModeAuto})。
4030
+ */
4031
+ permissionModes?: Array<PermissionMode | (string & {})>;
3982
4032
  /** `permissionMode: "auto"` 的**缺省态披露**(server `routes/capabilities.ts:463`;裁决在
3983
4033
  * `src/auto-mode-face.ts` 的 `judgeAutoModeArming`)。**各项刻意不合成一个布尔** —— 合成后
3984
4034
  * 「这份二进制不认识 auto」与「认识但本机没有 entitlement 源」会得到同一个 `false`,而壳对这两种要做的
3985
4035
  * 事不同(前者别给这一档;后者给,但别宣称在筛)。
3986
- * · `accepted` —— 提交面按五词闭集收 `"auto"`(恒 `true`,server 写的是字面量);
4036
+ * · `accepted` —— 提交面按闭集收 `"auto"`(恒 `true`,server 写的是字面量);
3987
4037
  * · `classifierSeat` —— 分类器席位真挂上了(server 读装配面递来的 `autoModeFace.seatMounted`,
3988
4038
  * 桩 / 一次性 CLI 不挂席位时如实 `false`);
3989
4039
  * · `entitlementSource` —— **center 源在不在**,绝不冒充「你被授权了」(授权是 per-principal 的,
@@ -3996,7 +4046,7 @@ export interface Capabilities {
3996
4046
  * **分词就是为了让壳指不同的路**(改本机 env vs 找组织)。按开集读:server 已经从四词长到六词。
3997
4047
  * · `model` —— 分类器**配置**的模型路由(core 的 role 回落链 `classifier → summarize → default`);
3998
4048
  * 解不出时 server **不写这个键**(把 core 的拒句当数据记进日志,读面不 500)。
3999
- * 🔴 查询串 `?permissionMode=<五词>` 把「本次意图」折进裁决(缺席 = 按 auto 意图答);五词闭集之外
4049
+ * 🔴 查询串 `?permissionMode=<模式词>` 把「本次意图」折进裁决(缺席 = 按 auto 意图答;server ≥7.119.0 收六词,`dontAsk` 答 `armed:false` / `reason:"mode_not_auto"`,≤7.118.x 只收五词);闭集之外
4000
4050
  * server 回 **400 `request.field_invalid`**(读面也不静默折词)。 */
4001
4051
  permissionModeAuto?: PermissionModeAutoCapability;
4002
4052
  /** READ 容纳面的**生效档**披露位(server `routes/capabilities.ts:484` = `deps.config.readFace ?? null`;#A4)。
@@ -4235,14 +4285,16 @@ export interface StoreCapability {
4235
4285
  /** 运维**声明**的后端 = `DB_BACKEND` 词(含缺省推导)。词表属主 = server `DB_BACKEND_WORDS`(config 枚举 / 目录 / caps 同读一只常量)。 */
4236
4286
  declared: StoreBackendWord;
4237
4287
  /** **装配出的**后端(同一词表;没装出后端 = `"memory"`)。`declared ≠ backend` 是合法形,由调用方自己读出落差:
4238
- * `DB_BACKEND=pg` + `SESSION_BACKEND=memory`(声明 pg、刻意不持久,**无** `degradedReason`)/ `auto` 降级(`degradedReason:"db_unreachable"`)/
4239
- * 缺省推导 local 起不来(`declared:"local"`、`backend:"memory"`、`"local_unwritable"`)。 */
4288
+ * `DB_BACKEND=pg` + `SESSION_BACKEND=memory`(声明 pg、刻意不持久,**无** `degradedReason`)/
4289
+ * 缺省推导 local 起不来(`declared:"local"`、`backend:"memory"`、`"local_unwritable"`)。
4290
+ * server ≥7.119.0:配了 DSN 的 SQL 库打不开 ⇒ 窗内重试、到窗**拒启**,**从不**退成内存 —— SQL 族没有降级态(≤7.118.x 的 `SESSION_BACKEND=auto` 会静默退内存并置 `degradedReason:"db_unreachable"`,
4291
+ * 那个词现在是 ⚰️ 退役词,见 {@link StoreDegradedReason})。 */
4240
4292
  backend: StoreBackendWord;
4241
- /** `backend !== "memory"`。壳据此渲「pg (durable)」/「pg declared, running in memory: db_unreachable」。 */
4293
+ /** `backend !== "memory"`。壳据此渲「pg (durable)」/「local declared, running in memory: local_unwritable」。 */
4242
4294
  durable: boolean;
4243
- /** 🔴 **present-iff 降级臂走过**(按后端族定词,不按失败发生在哪一步):`"db_unreachable"` = SQL 族(`mysql` / `pg`)在
4244
- * `SESSION_BACKEND=auto` 下打不开(连接或建表,不分);`"local_unwritable"` = **缺省推导**的 local 文件店建不出来(mkdir / 锁 /
4245
- * 权限 / 只读挂载 / 磁盘满)。词表属主 = server `STORE_DEGRADED_REASONS`;词表外的词按未知读。缺席 = 没降级(不是「不知道」)。 */
4295
+ /** 🔴 **present-iff 降级臂走过**:`"local_unwritable"` = **缺省推导**的 local 文件店建不出来(mkdir / 锁 /
4296
+ * 权限 / 只读挂载 / 磁盘满)。词表属主 = server `STORE_DEGRADED_REASONS`(server ≥7.119.0 只剩这一词);⚰️ `"db_unreachable"` 是**退役词**(≤7.118.x 的 SQL 族 auto 降级,7.119.0 随降级臂一并退役,
4297
+ * 服务端 ≥7.119.0 不再发)—— 老 server 仍会发,所以留在联合里;词表外的词按未知读。缺席 = 没降级(不是「不知道」)。 */
4246
4298
  degradedReason?: StoreDegradedReason;
4247
4299
  /** 🔴 **7.105.0 及以前的顶层 `sql` 对象原样搬入**(对象逐字同形,见 {@link SqlEngineCapability})。**present-iff** `backend` 是
4248
4300
  * `mysql` / `pg` **且**驱动此刻给得出回读复核过的事实 —— 最近一次连接初始化被拒(S-137 ④)时缺席(此前的顶层 `sql:null` 那一义);
@@ -4251,7 +4303,11 @@ export interface StoreCapability {
4251
4303
  }
4252
4304
  /** `DB_BACKEND` 词表(server `DB_BACKEND_WORDS`;`store.declared` / `store.backend` 同读)。开集尾:新词到货不形变,按未知读。 */
4253
4305
  export type StoreBackendWord = "mysql" | "pg" | "local" | "memory" | (string & {});
4254
- /** `store.degradedReason` 词表(server `STORE_DEGRADED_REASONS`,闭集两词按后端族)。开集尾:词表外的词按未知读。 */
4306
+ /** `store.degradedReason` 词表(server `STORE_DEGRADED_REASONS`:server ≥7.119.0 闭集只剩 `local_unwritable`)。开集尾:词表外的词按未知读。
4307
+ *
4308
+ * ⚰️ **`"db_unreachable"` 是退役词,服务端 ≥7.119.0 不再发,底线抬过 7.118.x 后删**:≤7.118.x 的 server(支持地板之内)在 `SESSION_BACKEND=auto` 下 SQL 库打不开时静默退内存并发它;
4309
+ * 7.119.0 起配了 DSN 的库打不开 ⇒ 窗内重试、到窗**拒启**,SQL 族没有降级态。它留在联合与随包 spec 的 enum 里,是为了让消费端对着老 server 写得出契约给它的那一臂;
4310
+ * 登记在册(`CAPABILITY_RETIRED_WORDS["store.degradedReason"]`,对账门要求「SDK 词 == server 现行词 ∪ 退役名单」,名单里的词 server 现行表里不许有)。 */
4255
4311
  export type StoreDegradedReason = "db_unreachable" | "local_unwritable" | (string & {});
4256
4312
  /**
4257
4313
  * 本部署的 **SQL 事务读语义**(S-131;7.105.0 及以前在 `Capabilities.sql`,**7.106.0 起在 {@link StoreCapability.sql}**)—— 与 server
@@ -4643,7 +4699,9 @@ export interface PendingCheckpoint {
4643
4699
  * (older history folded into a summary message); can be LARGE — lazy-expand in UIs.
4644
4700
  * With window params (server ≥1.162 four-face, board [611]) the response additionally carries
4645
4701
  * `window` — ABSENT on an old engine (<1.162 strips the query before routing and returns the
4646
- * full record): probe "no `window` in the response" to degrade honestly, never error. */
4702
+ * full record): probe "no `window` in the response" to degrade honestly, never error.
4703
+ * 🔴 Server >= 7.119.0 (wire VALUE change, shape unchanged): string leaves inside `messages` pass the same redaction as the live and ledger frames — a credential-shaped
4704
+ * span reads `«redacted:…»`; the archive itself is untouched (read-side only), and a history with no credential-shaped span is byte-identical. See {@link SessionsResource.get}. */
4647
4705
  export interface SessionRecord {
4648
4706
  sessionId: string;
4649
4707
  owner?: string | null;
@@ -4667,11 +4725,15 @@ export interface SessionRecord {
4667
4725
  * 承载它的 server 进程却在那条 run 收场前死了(**引擎在进程死前没来得及确认消费**;server ≥7.113.0 / core 7.39.0 #1273 起引擎确认消费过的受理结清成 `consumed`、
4668
4726
  * **不再**列在这里 —— 7.112.x 及以前「消费与否未知」的口径随之收窄;它**仍不**说「从未消费」,见 `engine_notice` `task.user_steer_undrained{cause:"crashed"}`)。
4669
4727
  * 只列收敛行、同 (taskId, messageId) 一行、至多最新 500 条;`announced` = 已在哪条新 run 首拍告知过。server ≥7.111.0(S-966)起行里**含同步子代的 steer**
4670
- * (记在回执上那条 run 名下,`messageId` = 那张子代 steer 回执的 `messageId`,行形与 run steer 同 —— `kind` 仍只有 `"steer"`)。**缺席 = 这一次读没有可报的条目**
4671
- * (零条,或这一次账本读不出 —— 权威告知是 run 流上的通告帧,不是本键);`?message=` 单条形不带。 */
4728
+ * (记在回执上那条 run 名下,`messageId` = 那张子代 steer 回执的 `messageId`,行形与 run steer 同)。**缺席 = 这一次读没有可报的条目**
4729
+ * (零条,或这一次账本读不出 —— 权威告知是 run 流上的通告帧,不是本键);`?message=` 单条形不带。
4730
+ * 🔴 **`kind` = 受理时它排进的引擎车道**(server ≥7.118.0 / core 7.44.0 #1362,闭两词):`"steer"`(`priority` 为 `now` / `next` 或缺省)·
4731
+ * **`"follow_up"`**(`priority:"later"`,排到 run 收场的那一道)。对应的崩溃告知码分两族:`task.user_steer_undrained` / `task.user_followup_undrained`
4732
+ * (后者 `detail: { followUp, cause:"crashed", taskId, sessionId }`)。按 `kind === "steer"` 过滤的消费方会少看见 `later` 那几行 —— 两词同读,按 `cause` 分支。
4733
+ * 升级前受理、升级后才告知的 `later` 受理按当时的族(`steer`)报。 */
4672
4734
  userInputUndrained?: Array<{
4673
4735
  messageId: string;
4674
- kind: "steer";
4736
+ kind: "steer" | "follow_up";
4675
4737
  taskId: string;
4676
4738
  acceptedAt: string;
4677
4739
  cause: "crashed";
@@ -5127,10 +5189,9 @@ export interface SessionManifest {
5127
5189
  /** The session's current leaf entry id, or null. */
5128
5190
  leafId: string | null;
5129
5191
  /** 🔴 **server ≥7.52(S-15)起不发这个键、wire 上不再有它**(E19 整树快照纪元退役;server `exportSessionManifest` 铸 `{ sessionId, entryIds, entryCount, leafId, fileHistory, policy, anchors }`,
5130
- * 7.116.0 发布字节逐键核过)。≤7.51 老 server 仍发它。**本型承诺它恒是数组**:{@link import("./resources/session-sync.js").SessionSyncResource.manifest} 在 wire 缺席时填 `[]`
5131
- * —— 所以对 ≥7.52 的 server 它恒空,真正的文件历史在 {@link fileHistory}。
5132
- * 🚧 这是为了不在 minor 里收窄公开型的**披露性过渡**(`snapshots` 本该是可选 / 随退役纪元删除):**下一个 major 把它改可选并删掉 `manifest()` 的填充**。 */
5133
- snapshots: SyncSnapshot[];
5192
+ * 7.116.0 发布字节逐键核过)。≤7.51 老 server 仍发它。**缺席 = 这台 server 不发整树快照**(真正的文件历史在 {@link fileHistory});
5193
+ * sdk 17.0.0 起本成员可选、`manifest()` 原样交回 wire(16.x 在缺席时填 `[]`,那一层过渡删了 —— 读它的代码按「缺席 = 没有」处理)。 */
5194
+ snapshots?: SyncSnapshot[];
5134
5195
  /** server ≥7.52:per-edited-file 文件历史信封({@link FileHistoryExport});`null` = 没有历史 / 源店导不出;**键缺席 = ≤7.51 老 server**(那一代走 {@link snapshots})。
5135
5196
  * 搬 blob 前先读两端的 {@link Capabilities.sessionSyncFileHistory}(server ≥7.116.0)。 */
5136
5197
  fileHistory?: FileHistoryExport | null;
@@ -5144,7 +5205,8 @@ export interface SessionBundle {
5144
5205
  sessionId: string;
5145
5206
  /** The FULL durable conversation log, verbatim ids/parents/payload (oldest-first). */
5146
5207
  entries: SyncEntry[];
5147
- snapshots: SyncSnapshot[];
5208
+ /** 同 {@link SessionManifest.snapshots}(≤7.51 老 server 的整树快照;缺席 = 源是 ≥7.52)。 */
5209
+ snapshots?: SyncSnapshot[];
5148
5210
  /** 同 {@link SessionManifest.fileHistory}(server ≥7.52 的文件历史信封;键缺席 = 源是 ≤7.51 老 server)。 */
5149
5211
  fileHistory?: FileHistoryExport | null;
5150
5212
  policy: SessionRulesRecord[];
@@ -5522,6 +5584,14 @@ export interface InboxRow {
5522
5584
  * 且长过,读法与别处逐字相同:认已知词 + 一条 default 臂,未知词读「未知出身」而**不是**「没有出身」。
5523
5585
  * 这一位出现之前铸的老行读作缺席(未上报),不是「没有权威」。 */
5524
5586
  origin?: AskOrigin;
5587
+ /** server ≥7.118.0(core 7.43.0 #1348 / #1357)—— 引擎 `Skill` 工具的停驻卡上的授予绑定摘要,与活卡帧同名位同值
5588
+ * ({@link import("./resources/tool-approvals.js").ToolApprovalFrame.boundGrantDigest});别的卡缺席。 */
5589
+ boundGrantDigest?: string;
5590
+ /** server ≥7.118.0 —— 上一位哈希的那一份值;**只在它确实哈希成 {@link boundGrantDigest} 时**出现(引擎判,server 不重算 —— 摘要绑定另一份时清单读作缺席)。
5591
+ * 🔴 部署文本:渲染按上下文转义。 */
5592
+ boundGrants?: BoundSkillGrants;
5593
+ /** server ≥7.118.0(core 7.43.0 #1353)—— 只在类 `classifier_no_ruling` 的停驻卡上:分类器为什么没判({@link AutoModeFallbackCause})。 */
5594
+ classifierNoRuling?: AutoModeFallbackCause;
5525
5595
  /** server ≥7.69.0(core 7.10.0 #616)—— **为什么这一问会到我手上**:分类器被咨询过但答不了。inbox 是
5526
5596
  * **分诊**面,`breaker_open` 在这里价值最大 —— 它预告的是一场审批风暴,而不是一次偶发询问。
5527
5597
  * 形与三条硬读法(开集 `cause` / 缺席不是断言 / switch 带 default)逐字见 {@link ClassifierUnavailable}。