@sema-agent/sdk 0.0.74 → 0.0.76

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 (171) hide show
  1. package/dist/client.d.ts +48 -0
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +55 -2
  4. package/dist/client.js.map +1 -1
  5. package/dist/control-client.d.ts +21 -0
  6. package/dist/control-client.d.ts.map +1 -1
  7. package/dist/control-client.js +42 -1
  8. package/dist/control-client.js.map +1 -1
  9. package/dist/control-types.d.ts +108 -0
  10. package/dist/control-types.d.ts.map +1 -1
  11. package/dist/control-types.js +15 -0
  12. package/dist/control-types.js.map +1 -1
  13. package/dist/errors.d.ts +88 -2
  14. package/dist/errors.d.ts.map +1 -1
  15. package/dist/errors.js +105 -8
  16. package/dist/errors.js.map +1 -1
  17. package/dist/events.d.ts +154 -16
  18. package/dist/events.d.ts.map +1 -1
  19. package/dist/events.js +1 -0
  20. package/dist/events.js.map +1 -1
  21. package/dist/health.d.ts +44 -0
  22. package/dist/health.d.ts.map +1 -1
  23. package/dist/health.js +32 -0
  24. package/dist/health.js.map +1 -1
  25. package/dist/idempotency.d.ts +8 -0
  26. package/dist/idempotency.d.ts.map +1 -1
  27. package/dist/idempotency.js +8 -0
  28. package/dist/idempotency.js.map +1 -1
  29. package/dist/index.d.ts +19 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +13 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/resources/approvals.d.ts +43 -0
  34. package/dist/resources/approvals.d.ts.map +1 -1
  35. package/dist/resources/approvals.js +23 -3
  36. package/dist/resources/approvals.js.map +1 -1
  37. package/dist/resources/assistant.d.ts +23 -0
  38. package/dist/resources/assistant.d.ts.map +1 -1
  39. package/dist/resources/assistant.js +22 -0
  40. package/dist/resources/assistant.js.map +1 -1
  41. package/dist/resources/control/auth-providers.d.ts +17 -0
  42. package/dist/resources/control/auth-providers.d.ts.map +1 -1
  43. package/dist/resources/control/auth-providers.js +6 -0
  44. package/dist/resources/control/auth-providers.js.map +1 -1
  45. package/dist/resources/control/config.d.ts +22 -0
  46. package/dist/resources/control/config.d.ts.map +1 -1
  47. package/dist/resources/control/config.js +12 -0
  48. package/dist/resources/control/config.js.map +1 -1
  49. package/dist/resources/control/fleet.d.ts +15 -0
  50. package/dist/resources/control/fleet.d.ts.map +1 -1
  51. package/dist/resources/control/fleet.js +8 -0
  52. package/dist/resources/control/fleet.js.map +1 -1
  53. package/dist/resources/control/images.d.ts +20 -0
  54. package/dist/resources/control/images.d.ts.map +1 -1
  55. package/dist/resources/control/images.js +10 -0
  56. package/dist/resources/control/images.js.map +1 -1
  57. package/dist/resources/control/lifecycle.d.ts +8 -0
  58. package/dist/resources/control/lifecycle.d.ts.map +1 -1
  59. package/dist/resources/control/lifecycle.js +3 -0
  60. package/dist/resources/control/lifecycle.js.map +1 -1
  61. package/dist/resources/control/publish.d.ts +12 -0
  62. package/dist/resources/control/publish.d.ts.map +1 -1
  63. package/dist/resources/control/publish.js +6 -0
  64. package/dist/resources/control/publish.js.map +1 -1
  65. package/dist/resources/control/secrets.d.ts +28 -0
  66. package/dist/resources/control/secrets.d.ts.map +1 -1
  67. package/dist/resources/control/secrets.js +16 -0
  68. package/dist/resources/control/secrets.js.map +1 -1
  69. package/dist/resources/control/users.d.ts +22 -0
  70. package/dist/resources/control/users.d.ts.map +1 -1
  71. package/dist/resources/control/users.js +12 -0
  72. package/dist/resources/control/users.js.map +1 -1
  73. package/dist/resources/control/versioning.d.ts +12 -0
  74. package/dist/resources/control/versioning.d.ts.map +1 -1
  75. package/dist/resources/control/versioning.js +6 -0
  76. package/dist/resources/control/versioning.js.map +1 -1
  77. package/dist/resources/control/workers.d.ts +14 -0
  78. package/dist/resources/control/workers.d.ts.map +1 -1
  79. package/dist/resources/control/workers.js +7 -0
  80. package/dist/resources/control/workers.js.map +1 -1
  81. package/dist/resources/elicitations.d.ts +43 -0
  82. package/dist/resources/elicitations.d.ts.map +1 -1
  83. package/dist/resources/elicitations.js +8 -0
  84. package/dist/resources/elicitations.js.map +1 -1
  85. package/dist/resources/fleet.d.ts +90 -0
  86. package/dist/resources/fleet.d.ts.map +1 -1
  87. package/dist/resources/fleet.js +27 -4
  88. package/dist/resources/fleet.js.map +1 -1
  89. package/dist/resources/images.d.ts +34 -0
  90. package/dist/resources/images.d.ts.map +1 -1
  91. package/dist/resources/images.js +29 -3
  92. package/dist/resources/images.js.map +1 -1
  93. package/dist/resources/leader.d.ts +10 -0
  94. package/dist/resources/leader.d.ts.map +1 -1
  95. package/dist/resources/leader.js +4 -0
  96. package/dist/resources/leader.js.map +1 -1
  97. package/dist/resources/memory.d.ts +37 -0
  98. package/dist/resources/memory.d.ts.map +1 -1
  99. package/dist/resources/memory.js +28 -0
  100. package/dist/resources/memory.js.map +1 -1
  101. package/dist/resources/models.d.ts +12 -0
  102. package/dist/resources/models.d.ts.map +1 -1
  103. package/dist/resources/models.js +4 -0
  104. package/dist/resources/models.js.map +1 -1
  105. package/dist/resources/ops.d.ts +16 -0
  106. package/dist/resources/ops.d.ts.map +1 -1
  107. package/dist/resources/ops.js +6 -0
  108. package/dist/resources/ops.js.map +1 -1
  109. package/dist/resources/policy.d.ts +8 -0
  110. package/dist/resources/policy.d.ts.map +1 -1
  111. package/dist/resources/policy.js +1 -0
  112. package/dist/resources/policy.js.map +1 -1
  113. package/dist/resources/questions.d.ts +57 -0
  114. package/dist/resources/questions.d.ts.map +1 -1
  115. package/dist/resources/questions.js +9 -0
  116. package/dist/resources/questions.js.map +1 -1
  117. package/dist/resources/runs.d.ts +143 -0
  118. package/dist/resources/runs.d.ts.map +1 -1
  119. package/dist/resources/runs.js +129 -2
  120. package/dist/resources/runs.js.map +1 -1
  121. package/dist/resources/session-sync.d.ts +61 -0
  122. package/dist/resources/session-sync.d.ts.map +1 -1
  123. package/dist/resources/session-sync.js +54 -1
  124. package/dist/resources/session-sync.js.map +1 -1
  125. package/dist/resources/sessions.d.ts +74 -0
  126. package/dist/resources/sessions.d.ts.map +1 -1
  127. package/dist/resources/sessions.js +64 -2
  128. package/dist/resources/sessions.js.map +1 -1
  129. package/dist/resources/side-query.d.ts +18 -0
  130. package/dist/resources/side-query.d.ts.map +1 -1
  131. package/dist/resources/side-query.js +1 -0
  132. package/dist/resources/side-query.js.map +1 -1
  133. package/dist/resources/tasks.d.ts +19 -0
  134. package/dist/resources/tasks.d.ts.map +1 -1
  135. package/dist/resources/tasks.js +21 -2
  136. package/dist/resources/tasks.js.map +1 -1
  137. package/dist/resources/tool-approvals.d.ts +53 -0
  138. package/dist/resources/tool-approvals.d.ts.map +1 -1
  139. package/dist/resources/tool-approvals.js +10 -0
  140. package/dist/resources/tool-approvals.js.map +1 -1
  141. package/dist/resources/trace.d.ts +23 -0
  142. package/dist/resources/trace.d.ts.map +1 -1
  143. package/dist/resources/trace.js +27 -2
  144. package/dist/resources/trace.js.map +1 -1
  145. package/dist/resources/usage.d.ts +21 -0
  146. package/dist/resources/usage.d.ts.map +1 -1
  147. package/dist/resources/usage.js +8 -0
  148. package/dist/resources/usage.js.map +1 -1
  149. package/dist/resources/workflows.d.ts +48 -0
  150. package/dist/resources/workflows.d.ts.map +1 -1
  151. package/dist/resources/workflows.js +40 -3
  152. package/dist/resources/workflows.js.map +1 -1
  153. package/dist/settings.d.ts +90 -0
  154. package/dist/settings.d.ts.map +1 -1
  155. package/dist/settings.js +24 -0
  156. package/dist/settings.js.map +1 -1
  157. package/dist/sse.d.ts +36 -0
  158. package/dist/sse.d.ts.map +1 -1
  159. package/dist/sse.js +53 -8
  160. package/dist/sse.js.map +1 -1
  161. package/dist/sync.d.ts +56 -0
  162. package/dist/sync.d.ts.map +1 -1
  163. package/dist/sync.js +48 -4
  164. package/dist/sync.js.map +1 -1
  165. package/dist/transport.d.ts +32 -0
  166. package/dist/transport.d.ts.map +1 -1
  167. package/dist/transport.js +40 -8
  168. package/dist/transport.js.map +1 -1
  169. package/dist/types.d.ts +691 -1
  170. package/dist/types.d.ts.map +1 -1
  171. package/package.json +1 -1
package/dist/types.d.ts CHANGED
@@ -1,7 +1,25 @@
1
+ /**
2
+ * Wire types — authoritative shapes from the service maintainer (see ../../../docs/SERVICE-CORE-CONTEXT.md).
3
+ * These are NOT guesses; they mirror the live service. They MUST be kept in sync with spec/openapi.yaml (M0):
4
+ * the contract test (producer side = service, consumer side = here) anchors both to the spec.
5
+ *
6
+ * 🔴 The SHARED WORK-VIEW MODEL (Task/Run/Artifact) is the anti-fragmentation substrate (DIRECTION.md §2):
7
+ * ALL doors — CC/Codex via the MCP façade, and web-native — produce the SAME Task/Run/Artifact. A dev's
8
+ * run and an ordinary user's run look identical in the workspace. Do NOT fork this per door.
9
+ */
1
10
  import type { SemaSettings } from "./settings.js";
11
+ /** Authenticated end-user identity. Opaque to the service (used as memory scope + session owner). The SDK
12
+ * normalizes; the service does NOT validate the format. Convention: `user:` / `org:` / `ai:` / `anon:`. */
2
13
  export type Principal = string;
14
+ /** Service scenario = the primary routing axis (one image serves many). Open string (unknown → "default"). */
3
15
  export type Scenario = "default" | "oa" | "code-review" | "team" | (string & {});
16
+ /** Terminal + in-flight run states. `suspended` = HITL: a policy gate (F4) or AskUserQuestion is waiting on a
17
+ * human — NOT an error (see resources/approvals.ts). */
18
+ /** design/80 D-0: `needs_review` is a durable TERMINAL (dry-run/shadow review) distinct from `suspended`
19
+ * (mid-run HITL pause). Closed set on purpose — a new status is minted only with a proven need (D-0 r2:
20
+ * don't pre-mint `plan_review`); core→wire contract test guards parity. */
4
21
  export type RunStatus = "running" | "completed" | "failed" | "suspended" | "needs_review";
22
+ /** Per-task budget/usage the service reports back. */
5
23
  export interface TaskStats {
6
24
  turns: number;
7
25
  tokens: number;
@@ -10,16 +28,28 @@ export interface TaskStats {
10
28
  outputTokens?: number;
11
29
  costUsd?: number;
12
30
  cacheHitRate?: number;
31
+ /** 🔴 Live-verified(@sema-agent/server@1.3.0 `done.result.stats` 真回传;原 TaskStats 漏声明 → 严格消费方读不到,
32
+ * 尤其 `costMicroUsd`/`totalInputTokens` 是成本/总览面板要的。live full-scenario 测逮到,round-6 补)。 */
13
33
  toolCalls?: number;
14
34
  cacheWriteTokens?: number;
15
35
  cacheWriteTokensLong?: number;
16
36
  totalInputTokens?: number;
17
37
  costMicroUsd?: number;
38
+ /** ASSISTANT-WIRE-CONTRACT §5(service main 6cd0164 / core 1.110.0)— cost + 人工耗时透传, 运行时已经过
39
+ * `GET /v1/runs/:id → result.stats` 原样回传, 这里只补类型层让 N4 总览/成本 UI 能类型安全读取(不另起 wire)。
40
+ * 这些字段是封闭 TaskStats 之外的可选投影, 缺则 OMIT。 */
41
+ /** core LLM 成本明细(开放结构, 透传不解析)。 */
18
42
  costBreakdown?: unknown;
43
+ /** 便利字段: LLM + service infra 轴的合计, 仅在 infra 定价已配置且 run 终态时出现。 */
19
44
  supervisorCost?: number;
45
+ /** design/89 §2.4 C2 人工复核负担轴(core 1.110.0)—— budget-EXCLUDED(永不折进成本/预算门, 同 stats.memory)。 */
20
46
  humanReview?: {
21
47
  count: number;
22
48
  totalWaitMs: number;
49
+ /** MF-24 denial ledger。🔴 **LIVE 钉死(canary 1.6.1 在线验形 2026-06-27,deny 后 result.stats.humanReview)**:
50
+ * gate **恰好 4 键** `{kind, decision, toolName, waitMs}`,逐键命中、零未声明字段。**`tool_input`/`toolInput` 不在
51
+ * 1.6.1 gate ledger 上**(此前推测 core 1.148 会经开集带被拒入参 —— 本部署证伪;留开集 `[k]` 待更新部署再验,不加为
52
+ * typed 字段)。`toolName` 实采为被拒工具名(Q6/core 1.161 起 = CC 名,如 "Bash")。 */
23
53
  gates: Array<{
24
54
  kind: string;
25
55
  waitMs: number;
@@ -28,23 +58,67 @@ export interface TaskStats {
28
58
  [k: string]: unknown;
29
59
  }>;
30
60
  };
61
+ /** 🔴 开集:引擎 `result.stats` 可携带本类型未命名的字段(如 `costBreakdown.*` 明细;live 实测),原样透传不丢。 */
31
62
  [key: string]: unknown;
32
63
  }
64
+ /** Common request body. `objective` is required; everything else is optional and server-capped where noted.
65
+ * `[k: string]: unknown` mirrors the service's passthrough (scenario-specific fields like code-review's
66
+ * `repo`/`council`/`debate`/`rounds` ride here). 🔴 `jobId` is the work-view correlation key (DIRECTION §2):
67
+ * set it so the workspace groups the runs of one logical job into one Task — across BOTH doors. */
33
68
  export interface TaskRequest {
69
+ /** 🔴 secret discipline: NEVER put tokens/secrets in `objective` or `systemPrompt` — commands/prompts land
70
+ * in the durable event stream (tool_start.args) and the L1 session history. Secrets reach the sandbox
71
+ * OUT-OF-BAND via the worker's `E2B_SANDBOX_ENV` (see service CONSUMER-SANDBOX-SKILLS.md). */
34
72
  objective: string;
35
73
  scenario?: Scenario;
74
+ /** Continue a conversation: pass the same sessionId across turns. Omit on first turn → service mints one. */
36
75
  sessionId?: string;
76
+ /** 🔴 Per-turn MODEL (CC /model picker parity). A model alias ('sonnet'/'opus') or full id. The service
77
+ * resolveTaskModel (main.ts:1217) CATALOG-GATES it (body.model wins over @mention wins over the deployment
78
+ * default; an out-of-roster pick falls back). Maps to core TaskSpec.model. Omit ⇒ deployment/role default. */
37
79
  model?: string;
80
+ /** Cheap-model gear for within-task compaction/summarize (server ≥1.243, core design/145). A catalog intent
81
+ * like `model` (name/tier word/id), gated against the SAME allow-list — an unknown value is a 400 on fresh
82
+ * submit. core clamps window-unsafe picks back to the main model (`modelFallback` on the `compacted` event).
83
+ * Probe `capabilities.compactionModel`; older servers drop the field. Omit ⇒ summarize role / main model. */
38
84
  compactionModel?: string;
85
+ /** Work-view correlation (the anti-fragmentation substrate). A CC dispatch loop or a web job sets one
86
+ * jobId across its sub-runs so they group into one Task. SDK auto-generates if absent. */
39
87
  jobId?: string;
88
+ /** Business/UX system prompt the CLIENT owns (decoupling seam) — STABLE per integrator version (cacheable
89
+ * prefix); put per-request context in `objective`. Server cap: >16384 chars → 400. */
40
90
  systemPrompt?: string;
91
+ /** Append-only system prompt rider (server ≥1.243, ≈ CC `--append-system-prompt`): a STABLE block composed
92
+ * after the scenario base + `systemPrompt`, before the volatile tail. First-class lane for the shell's
93
+ * product-knowledge block — `settings.outputStyle` composes AFTER it (byte-stable order), so a style block
94
+ * and this rider coexist. Probe `capabilities.appendSystemPrompt`; on false/absent fall back to the
95
+ * `settings.outputStyle` ride-along. Same cap as `systemPrompt`: >16384 chars → 400. */
41
96
  appendSystemPrompt?: string;
97
+ /** Per-request user skills (live, service 170c384): progressive disclosure, same mechanism
98
+ * as scenario skills. Server caps: ≤10 items, name ≤64, description ≤1024, content ≤32768 — violations 400.
99
+ * Merge: scenario WINS on name collision (user's dropped + warn-logged) — the safety baseline can't be
100
+ * overridden. Injected by the trusted BFF, never raw user input. */
42
101
  skills?: SkillSpec[];
102
+ /** Per-turn reasoning strength (CC `/effort` parity). One of the core ThinkingLevel tiers:
103
+ * `off`|`minimal`|`low`|`medium`|`high`|`xhigh`|`max`. Service maps it → `TaskSpec.thinking`
104
+ * (server.ts reasoningEffort → main.ts:1270); an UNKNOWN value is a 400 (fail-loud). Omit ⇒ engine
105
+ * default (the model/role default). The shell stamps the user's `/effort` pick here per turn. */
43
106
  reasoningEffort?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
107
+ /** User context for env-block localization (core 1.181, design/112). The shell/client knows the user's TZ +
108
+ * identity; the worker container runs UTC and knows neither. Threaded → service `body.clientContext` →
109
+ * `TaskSpec.clientContext` → core localizes the `# Environment` block's "today" to the user's zone (+ names
110
+ * who the agent acts for); absent ⇒ UTC date, no user line. Auto-inherited by subagent/Fork children. Shape =
111
+ * core `TaskSpec.clientContext`. The shell stamps `timeZone` from `Intl.DateTimeFormat().resolvedOptions()`. */
44
112
  clientContext?: {
45
113
  timeZone?: string;
46
114
  userEmail?: string;
47
115
  };
116
+ /** Per-request MCP servers (CC `.mcp.json` / `claude mcp add` parity). The trusted BFF/shell projects the
117
+ * user's local `.mcp.json` here so the engine mounts those servers' tools. Field shape = core `McpServerSpec`.
118
+ * HONORED only on a SINGLE-USER deployment (service `task-mcp.ts mcpInjectionHonored = requirePrincipal!==true`):
119
+ * there the caller is their own worker's superadmin (= CC). Multi-tenant: ignored (fail-closed, no RCE/SSRF);
120
+ * the fleet gets MCP via center config refs. Merge: deployment/center baseline wins on name collision (caller
121
+ * can ADD, never SHADOW), like `skills`. Gate whether to project via `capabilities.mcpInjection`. */
48
122
  mcpServers?: McpServerSpec[];
49
123
  images?: Array<{
50
124
  data: string;
@@ -52,32 +126,137 @@ export interface TaskRequest {
52
126
  } | {
53
127
  url: string;
54
128
  }>;
129
+ /** Caller-requested ceilings; server caps to the operator max (a caller may ask for less, never more). */
55
130
  maxCostUsd?: number;
56
131
  maxTokens?: number;
132
+ /** Developer-mode adversarial verify gate (impl → independent read-only verify → fix loop). Not on `stream`. */
57
133
  verify?: boolean;
58
134
  verifyRounds?: number;
135
+ /** Quality-gate cascade (cheap→strong). Mutually exclusive with verify. Not on `stream`. */
59
136
  cascade?: boolean;
137
+ /** §sandbox-image-select(P0.5):送**镜像 profile 意图**(≤128 chars),service 内部按 trusted
138
+ * principal 用 `latestPublished(profile, viewer)` **fail-closed** 解析 digest + 再准入 → per-pod 起像(复用 select 同 visibility)。
139
+ * 🔴 caller **永远只送 profile,绝不送 digest/ref**(信 caller digest = fail-OPEN,对抗审逮 4 越权);解析/准入 100% 在 service 信任边界。
140
+ * v1 约束(违反 → 400):仅 k8s 后端;**不与 `verify`/`cascade` 同用**(镜像绑定按 sessionId,子运行换 session 会静默回退默认像,宁可 fail-loud)。 */
60
141
  sandboxImageProfile?: string;
142
+ /** 约束选中像须具备的 bool 能力(`browser`/`db`/`nestedBuild`);**单独给(无 `sandboxImageProfile`)→ 400**。 */
61
143
  capabilitiesNeeded?: string[];
144
+ /** E12(shell-host;service `normalizeSuggestNextPrompts` spec-fields.ts:9 / runs.ts:392 + server.ts:3276,SHIPPED)
145
+ * —— opt-in:run 跑完(`status:"completed"`)后 core 跑一次 LLM pass 生成「下一步可问什么」建议,service 持久成一个
146
+ * `suggestions` event(见 {@link AgentEvent} 的 suggestions arm)on the durable run-events tail。`true` = 用 core
147
+ * 默认;`{count?, role?}` = 调条数 / 指定生成用的 model role。🔴 与 `verify`/`cascade` **互斥**(那两个返 result 非
148
+ * streamed run → 400)。只在 `/v1/runs` durable leg 有意义(`POST /v1/tasks` 同步返 result,无 events tail)。
149
+ * UNTRUSTED 模型文本(service 已 redact)→ 仅 UI 展示,**绝不回喂模型**。 */
62
150
  suggestNextPrompts?: boolean | {
63
151
  count?: number;
64
152
  role?: string;
65
153
  };
154
+ /** MF-30 PAUSE toggle(per-request,@sema-agent/server 1.4.0 `84ff944` option B,2026-06-27 拍板)——
155
+ * `memoryWrite:false` → 本 run 对 memory **只读**(`writeScope:null`:无 remember 工具、无 consolidation 写;recall 仍可)。
156
+ * 缺省 = 写开启。引擎 main.ts:1183 / security.ts:194 读它。pause 是 per-RUN(非 per-session stored-flag)。 */
66
157
  memoryWrite?: boolean;
158
+ /** 🔴 TOB-fleet 透传(core/search AI 2026-06-27,research/toc-settings-adapter/01-design.md §5②)—— fleet/远端模式
159
+ * 把用户 `settings.json`(CC-parity {@link SemaSettings})带给 service;**service** 把它 wire 进引擎同款 seam
160
+ * (SessionPolicyStore / NodeExecutionEnv / RunnerDeps.hooks),同它做 MF-* 数据契约那层。TOC-local 模式**不走这**
161
+ * (shell 适配器直接 wire 本地 `new Runner(deps)`)。⚠️ **service-side wire pending** —— 契约先立、service 接后即 live。
162
+ * SDK 只搬契约、不解释、不跑 shell-hook(那是 shell/profile 层的活)。 */
67
163
  settings?: SemaSettings;
164
+ /** 🔴 LOCAL workspace 目录(FATAL 修,service root-cause A)—— 持久 HTTP 引擎(常驻 8788)的 agent
165
+ * bash/file 工具默认跑在**引擎启动时的固定 workspaceDir**,而非每次 `sema` 启动的目录;持久进程无从知 client 的
166
+ * cwd → client 在 launch 时传 `process.cwd()`,service 在 **LOCAL host-adapter 模式** honor 它(executionEnv
167
+ * workspaceDir = cwd)。🔒 安全:cwd 是宿主路径,**只在 local 单用户(REQUIRE_PRINCIPAL=false / host adapter)
168
+ * honor;云/多租户 MUST ignore**(否则租户可把共享 worker 指到任意宿主路径 = 路径穿越,同 env-defer 信任边界)。 */
68
169
  cwd?: string;
170
+ /** 🔴 E18 resume-at / REWIND(core 答 §J=方案A "fork-from-entry";core prepare-task.ts:529 `spec.resumeAt`,
171
+ * service main.ts:1150-1166)—— 从会话历史里**某条已发生的消息**分叉一条新支线(不是 mutate 旧 run)。值 = 该消息的
172
+ * **E2 message eventId**(`AgentEvent.eventId`,client 在流里见过的那个),**非** core 内部 entryId —— service 持有
173
+ * eventId→entryId 映射、`resumeAnchorStore.resolve` 折算。**必须配 `sessionId`**(要分叉的会话;session 由 auth 派生,
174
+ * body 不带);**不能与 durable resume 同用**(resume 路径会先剥掉 resumeAt 再 re-resolve)。anchor 未知 → 4xx;已知但
175
+ * 被 compact 掉 → 同步 4xx / 异步 run-result `resume_at.not_found`。worker 无 anchor store(`resumeAnchorStore`+
176
+ * `getLeafId`)→ 501,与 `capabilities.resumeAt` 同对一对(能力说 yes ⟺ 路由 resolve)。 */
69
177
  resumeAt?: string;
178
+ /** 🔴 与 {@link resumeAt} 配套(core runtask.ts:1834 `spec.rewindFiles`,service main.ts:1198 `body.rewindFiles===true`)
179
+ * —— 分叉时**同时把工作树恢复**到 resumeAt 那一回合完成时的快照(否则只回退对话、文件留在最新态)。core 自动按
180
+ * completed-turn 快照 capture/restore(任何 ExecutionEnv,当 fileSnapshotStore wired);worker 缺快照存储则 `rewindFiles`
181
+ * 能力位 false。缺省 = 不动文件。 */
70
182
  rewindFiles?: boolean;
183
+ /** 🔴 E18 code-only rewind(core 1.166.0 `TaskSpec.rewindFilesTo`,commit 0bf1aeb)—— 把工作树还原到该 message
184
+ * entryId 的快照、**不** fork 对话(无 setLeafId)。= CC Rewind "code"-only 模式(`resumeAt`+`rewindFiles`=both、
185
+ * `resumeAt` 单独=conversation、本字段=code)。收的是 user-message 的 `SessionTreeEntry.id`(server anchor user
186
+ * message 边界后即可端到端)。与 `resumeAt` 互斥使用(code-only 不 fork 对话)。 */
71
187
  rewindFilesTo?: string;
188
+ /** 🔴 PERMISSION MODE INTENT (CC permission mode: `default` | `plan` | `acceptEdits` | `bypassPermissions`).
189
+ * The shell/web frontend carries the RAW mode; the SERVICE INTERPRETS it (axis-aware, tighten-only): `plan` ⇒
190
+ * mount the first-party `present_plan` tool (core `TaskSpec.enablePlanMode`, CC ExitPlanMode parity) + read-only
191
+ * hands (`handsReadOnly`) = CC EnterPlanMode read-only research; `acceptEdits`/`bypassPermissions` are LOOSENING
192
+ * → not honorable remotely (tighten-only), coerced to `default` engine-side + enforced client-side. Carrying the
193
+ * INTENT (not the client's pre-interpreted core fields) keeps one interpretation across TUI+web frontends and
194
+ * lets the service govern per deployment axis (single-user vs multi-tenant). Omit/`default` ⇒ no stamp. */
72
195
  permissionMode?: "default" | "plan" | "acceptEdits" | "bypassPermissions" | "auto";
196
+ /** 🔴 Workflow super-set (sema-cc-parity) — per-task activation of the LLM-authored workflow engine (core
197
+ * `run_workflow`: the agent/parallel/pipeline/phase/nested orchestrator). The SERVICE reads `body.selfOrchestration`
198
+ * STRICTLY (`=== true`) → `TaskSpec.selfOrchestration`, the gate that MOUNTS run_workflow (the service
199
+ * task-workflow.ts `selfOrchestrationFromBody` / main.ts:1343; server.ts:282 SubmitTaskRequest `selfOrchestration?`).
200
+ * Gated downstream: (1) DEPLOYMENT — the worker's `SELF_ORCHESTRATION_ENABLED` must be on (else a harmless no-op,
201
+ * dropped); (2) MULTI-TENANT — honored only when a per-principal entitlement RESOLVER is wired (fail-closed:
202
+ * no resolver ⇒ dropped); single-user honors directly. Absent/false ⇒ no workflow tool this run (default behaviour
203
+ * unchanged). Three-gate: engine-can ∧ center-may(allowWorkflows) ∧ shell-show. */
73
204
  selfOrchestration?: boolean;
205
+ /** 🔴 Fork super-set (sema-cc-parity, CC `subagent_type:fork`) — per-task activation of core's first-party Fork
206
+ * tool: the model can fork itself into a subagent that INHERITS the parent context + shares the prompt cache
207
+ * (vs Task's clean-context subagent). The SERVICE reads `body.enableFork` STRICTLY (`=== true`) → `TaskSpec.enableFork`,
208
+ * the gate that MOUNTS the Fork tool (core prepare-task.ts: `enableFork===true` AND a durable session store with
209
+ * `hasSessionFork` — TOC's file backend qualifies). OPT-IN (default OFF): fork can recurse / burn tokens, so unlike
210
+ * `selfOrchestration` it is NOT default-on — the USER enables it (shell `SEMA_ENABLE_FORK`), the model never gets it
211
+ * by default (2026-07-01 拍板: 用户来开,默认对 LLM 不开). Absent/false ⇒ no fork tool this run (default unchanged).
212
+ * ⚠️ SERVICE must add the `body.enableFork → spec.enableFork` mapping (awaiting per CHANGELOG 1.38; client path
213
+ * now chosen = opt-in model tool). */
74
214
  enableFork?: boolean;
215
+ /** 🔴 [876]③ Per-task custom SUBAGENTS — the shell/client projects the user's subagent definitions
216
+ * (`.sema/agents/*.md` or programmatic) here so the ENGINE can mount them as Task-tool agent types for THIS
217
+ * run. 0.0.50 BREAKING vs 0.0.49: the 0.0.49 shape (Record keyed by name, description/prompt/tools keys —
218
+ * a CC-SDK-style guess) never matched the live wire and was rejected 400 by every deployment; this array
219
+ * shape mirrors the server contract verbatim (server 1.205 `spec-fields.js` `validateTaskAgents` /
220
+ * `TASK_AGENT_FIELD_SHAPES` = core 1.295 `AgentDefinition`), so no consumer can have depended on the old
221
+ * type at runtime. Rules enforced server-side: non-empty array, ≤32 items, unique `name`s, unknown keys
222
+ * fail-loud 400 on the strict lane (`permissionMode` is DELIBERATELY excluded from this contract — send it
223
+ * and the request is rejected), body→spec lane drops invalid items with a `task_agent_dropped` warn.
224
+ * `model` = the SHELL-RESOLVED real model name/id (壳侧已解析,引擎零词表负担 — the server does no alias
225
+ * translation; resolve 'sonnet'→id before sending). Multi-tenant deployments ignore this field entirely
226
+ * (fail-closed, `task_agents_ignored`). Probe `capabilities.taskAgents` before sending to older servers. */
75
227
  agents?: TaskAgentDefinition[];
228
+ /** 🔴 INTERACTIVE-TOOLS toggle (server 1.214 server.js:4021 — STRICT boolean, anything else 400s).
229
+ * `false` = the CC `-p`/headless UNATTENDED semantic: the engine does NOT mount the interactive HITL tool
230
+ * family (AskUserQuestion etc.) so the run never parks on a live human — it takes the headless default and
231
+ * keeps moving (CI / cron / fire-and-forget). `true`/omit = attended (interactive tools mount where the
232
+ * deployment supports them). Probe `capabilities.interactiveTools` (server hardcodes true at server.js:600)
233
+ * before sending to OLDER servers — an unknown-field deployment on the strict lane would 400. */
76
234
  interactiveTools?: boolean;
235
+ /** 🔴 Retain background processes past the turn (server 1.214 server.js:4025 — STRICT boolean, else 400).
236
+ * `true` = backgrounded Bash tasks (b*) survive the run's turn end instead of being reaped (long dev servers,
237
+ * watch builds). HONORED only on a single-user deployment (`capabilities.retainBackgroundProcesses` =
238
+ * `requirePrincipal !== true`, server.js:599) — multi-tenant ignores it (a tenant must not pin processes on
239
+ * a shared worker). */
77
240
  retainBackgroundProcesses?: boolean;
241
+ /** server ≥1.221 (core 1.314 工具面控制批,[1052]②): roster TRUE-UNMOUNT list — the named wire tools'
242
+ * schemas never reach the model (the deny gate saves no tokens; this does), and the assembly manifest
243
+ * narrows honestly. Tighten-only: core's inheritance invariant unions it into EVERY child spawn path.
244
+ * Malformed (non-array / empty-string items) → 400 fail-loud at submit. */
78
245
  excludeTools?: string[];
246
+ /** server ≥1.221 (core 1.314): DEFERRED DISCLOSURE list — the named MOUNTED tools (built-ins included)
247
+ * ride the wire as a placeholder (schema bytes out of the cache prefix) and materialize via ToolSearch
248
+ * on demand. The carrier for the shell's "Workflow on by default but not exposed" posture. Same
249
+ * validation/inheritance posture as {@link excludeTools}. */
79
250
  deferTools?: string[];
251
+ /** server ≥1.227 (core 1.328 R2, [1144]/[1146]): prompt PRESENTATION profile — `"simple"` (CC 212
252
+ * short form; the engine default when omitted) or `"classic"` (the long pre-R2 form; switchable per
253
+ * task/model for A/B). Pure presentation axis (no policy change); inherits through the whole
254
+ * delegation tree. Any other value → 400 fail-loud at submit; omit to stay on the engine default. */
80
255
  promptProfile?: "simple" | "classic";
256
+ /** server ≥1.254 — context attachments family (core design/133):literal-true opt-ins
257
+ * (todoReminder/planModeReminder/budgetUsd/backgroundTasks/toolsDelta/mcpInstructions;false=省键),
258
+ * `changedFiles` 可带 {maxFiles};`agentListing`/`skillsListing` 是 core DEFAULT-ON——**explicit false
259
+ * 才关**(1.254 起 false 真透传;更老 server 静默丢);`todoReminderMode` "baseline"|"off"。 */
81
260
  attachments?: {
82
261
  todoReminder?: true;
83
262
  todoReminderMode?: "baseline" | "off";
@@ -92,6 +271,8 @@ export interface TaskRequest {
92
271
  skillsListing?: boolean;
93
272
  mcpInstructions?: true;
94
273
  };
274
+ /** server ≥1.254 — per-task limits(数值三键早有;deadline 族三 **opt-out** 只认 literal false:
275
+ * timeoutSec 在场即默认 ON 的 nudge/call-cap/graceful-finalize 可关)。 */
95
276
  limits?: {
96
277
  timeoutSec?: number;
97
278
  maxOutputTokens?: number;
@@ -100,18 +281,29 @@ export interface TaskRequest {
100
281
  callCapByDeadline?: false;
101
282
  gracefulFinalize?: false;
102
283
  };
284
+ /** server ≥1.254 — retry-on-invalid rounds for `outputSchema`(成对旋钮;1..10,无 schema 时 core 忽略)。 */
103
285
  outputRetries?: number;
286
+ /** server ≥1.254 — within-task compaction 的容差旋钮(design/145,与 compactionModel 配套;0..1)。
287
+ * 其余 compaction 键是操作方轴,wire 不开。 */
104
288
  compaction?: {
105
289
  clampTolerance?: number;
106
290
  };
107
291
  [k: string]: unknown;
108
292
  }
293
+ /** One per-task subagent definition (`TaskRequest.agents[]` item) — mirrors core `AgentDefinition` verbatim
294
+ * (the server whitelists exactly these keys; anything else is a 400 on the strict lane). */
109
295
  export interface TaskAgentDefinition {
296
+ /** Agent name = the `subagent_type` the model passes to Task. Non-empty, ≤64 chars, unique per request. */
110
297
  name: string;
298
+ /** When the model should delegate to this agent (shown in the Task tool's agent list). ≤4096 chars. */
111
299
  whenToUse?: string;
300
+ /** Compact variant of `whenToUse` for lean tool listings. ≤4096 chars. */
112
301
  whenToUseLean?: string;
302
+ /** Allowlist of tool names the agent may use. Omit ⇒ inherit all tools. */
113
303
  allowTools?: string[];
304
+ /** Denylist of tool names (subtractive; applied after `allowTools`). */
114
305
  denyTools?: string[];
306
+ /** Skills preloaded into the agent: `{ name, description, content }` (+ optional manifest/files). */
115
307
  skills?: Array<{
116
308
  name: string;
117
309
  description: string;
@@ -122,19 +314,30 @@ export interface TaskAgentDefinition {
122
314
  content: string;
123
315
  }>;
124
316
  }>;
317
+ /** Run the agent in the background (parent turn continues). */
125
318
  background?: boolean;
319
+ /** `"worktree"` = run the agent in an isolated git worktree. */
126
320
  isolation?: 'worktree';
321
+ /** Shell-resolved real model name/id — or a Model object with a string `id`. NOT an alias (the server does
322
+ * no translation). Omit ⇒ inherit the parent model. */
127
323
  model?: string | {
128
324
  id: string;
129
325
  [k: string]: unknown;
130
326
  };
327
+ /** Thinking level: off | minimal | low | medium | high | xhigh | max. */
131
328
  thinking?: string;
329
+ /** The agent's system prompt. ≤65536 chars. */
132
330
  systemPrompt?: string;
331
+ /** Max agent turns before the subagent is stopped. Positive integer. */
133
332
  maxTurns?: number;
333
+ /** Memory spec (`{ scope?, scopes?, writeScope?, enabled?, scopeContract? }`). */
134
334
  memory?: Record<string, unknown>;
335
+ /** Observer prompt (agent-observes-agent lane). ≤4096 chars. */
135
336
  observer?: string;
337
+ /** Message template the observer sends. ≤4096 chars. */
136
338
  observerMessage?: string;
137
339
  }
340
+ /** Synchronous task result (`POST /v1/tasks`). */
138
341
  export interface TaskResult {
139
342
  taskId: string;
140
343
  sessionId: string;
@@ -143,51 +346,91 @@ export interface TaskResult {
143
346
  errorCode?: string;
144
347
  errorMessage?: string;
145
348
  stats: TaskStats;
349
+ /** MF-25 — effective model id that ran the task(`done.result.model`,engine main.ts:1339 `model: config.model.id`)。
350
+ * 成本/总览面板据此知"哪个模型跑的"。live 实测引擎真回传(@sema-agent/server 1.3.0+)。 */
146
351
  model?: string;
352
+ /** Present when the task was run behind the verify gate. */
147
353
  verification?: {
148
354
  verdict: "PASS" | "FAIL" | "PARTIAL" | "unverified";
149
355
  rounds: number;
150
356
  findings: string[];
151
357
  };
152
358
  }
359
+ /** Async run receipt (`POST /v1/runs` → 202). The capability token is NEVER on the wire (server-internal). */
153
360
  export interface RunReceipt {
154
361
  taskId: string;
155
362
  sessionId: string;
156
363
  status: RunStatus;
157
364
  }
365
+ /** §sandbox-image catalog(service IMAGE-API §7)— `GET /v1/images` 的目录行(visibility 按 principal scoped)。
366
+ * 门B「选沙箱模板」UI 据此渲染(profile 卡 + 能力徽章 + toolchain)。开集容多余字段;字段源自 worker → 渲染前 sanitize。 */
367
+ /** `GET /v1/models` 的非密钥模型目录条目(core 1.116 `@model` mention 线;service server.ts:535)。
368
+ * `name` = `@handle`(用户在正文打 `@<name>` per-task 选它)。🔴 **只名/能力,无 baseUrl/apiKey/headers**(service 已剥)。 */
158
369
  export interface ModelInfo {
370
+ /** `@mention` 句柄 = 用户可选的模型名。 */
159
371
  name: string;
372
+ /** 底层 model id(展示用,如 deepseek-v4-pro)。 */
160
373
  id?: string;
161
374
  provider?: string;
375
+ /** 该模型是否 reasoning 档(picker 可标徽章)。 */
162
376
  reasoning?: boolean;
377
+ /** 是否支持图片输入。 */
163
378
  vision?: boolean;
379
+ /** E4(shell-host;service server.ts:868-874,SHIPPED)— 上下文窗口 token 总额 = 「% 上下文已用 / 距 compact N
380
+ * token / 低上下文告警」仪表的**分母**。soft-degrade:未知(0)则 service 省略 → 壳渲染裸 token 数无 %。
381
+ * (分子 `turn_end.usage.contextTokens` 仍 core-blocked;分母此处已可独立用。) */
164
382
  contextWindow?: number;
383
+ /** E4(service server.ts:874,SHIPPED)— 该模型单次输出的 max token(`maxTokens`)。未知则省略。 */
165
384
  maxOutputTokens?: number;
385
+ /** E7(shell-host;service server.ts:875-879,SHIPPED)— `/effort` picker 的选项 = core 权威默认档集
386
+ * (minimal/low/medium/high)。**仅 reasoning 模型**有(非 reasoning 省略,effort 不适用)。这是 picker 默认展示集,
387
+ * 非硬白名单(请求侧 accept-set 更宽 = 任意 core ThinkingLevel)。 */
166
388
  supportedEffortLevels?: string[];
167
389
  [k: string]: unknown;
168
390
  }
391
+ /** §cost/usage 面板(service `GET /v1/usage`,实测形态已按源审计)—— per-principal 成本配额 + 单任务上限。
392
+ * CLI `/cost` `/usage` 面板 + 门B 用量条据此渲染真数据(取代静态占位)。🔴 owner-scoped:worker 据 request principal 自算。
393
+ * 无配额时 `enabled:false` + 仅 `windowSec`/`maxTask*`(金额/limit 字段缺)→ 渲染须容缺。permissive 开集容未来字段。 */
169
394
  export interface UsageInfo {
395
+ /** 是否配置了成本配额窗口(false ⇒ 仅有单任务上限,无窗口用量账本)。 */
170
396
  enabled: boolean;
397
+ /** 配额滚动窗口秒数(如 86400=日窗)。 */
171
398
  windowSec?: number;
399
+ /** 当前窗口已用(micro-USD,1e-6 美元)。 */
172
400
  usedMicroUsd?: number;
401
+ /** 当前窗口已用(USD,便利投影)。 */
173
402
  usedUsd?: number;
403
+ /** 窗口配额上限(micro-USD)。 */
174
404
  limitMicroUsd?: number;
405
+ /** 窗口配额上限(USD)。 */
175
406
  limitUsd?: number;
407
+ /** 窗口剩余额度(micro-USD;limit - used)。 */
176
408
  remainingMicroUsd?: number;
409
+ /** 是否已超出窗口配额(超则新任务被拦,等 retryAfterSec)。 */
177
410
  overLimit?: boolean;
411
+ /** 超限时建议的重试等待秒数。 */
178
412
  retryAfterSec?: number;
413
+ /** 单任务成本硬上限(USD;与窗口配额独立,总在)。 */
179
414
  maxTaskCostUsd?: number;
415
+ /** 单任务 token 硬上限(与窗口配额独立,总在)。 */
180
416
  maxTaskTokens?: number;
181
417
  [k: string]: unknown;
182
418
  }
419
+ /** §permissions 面板(service `GET /v1/policy`,实测形态已按源审计)—— 当前生效的自治档 + 命令策略 + 上限。
420
+ * CLI `/permissions` 面板渲它显「现在能自动做什么、哪些要审批、上限多少」(取代静态占位,真实反映 worker 侧策略)。
421
+ * 🔴 只读快照:client 不重算/不据此放行(放行 100% 在 worker;面板仅 inspect)。permissive 开集 + 内部嵌套形态容演进。 */
183
422
  export interface PolicyInfo {
423
+ /** 自治档(如 "auto"/"supervised"/...;null = 未设/默认)。开放串,渲染读已知值、容未知。 */
184
424
  autonomy?: string | null;
425
+ /** 命令 → 决策(allow/deny/ask 等)的策略表。内部形态 permissive,渲染读 command/decision。 */
185
426
  commandPolicy?: Array<{
186
427
  command?: string;
187
428
  decision?: string;
188
429
  [k: string]: unknown;
189
430
  }>;
431
+ /** 触发人工审批的条件列表(开放结构,透传不解析)。 */
190
432
  approvalRequire?: unknown[];
433
+ /** 生效上限(单任务 + principal 级 + 配额窗口)。缺字段容缺。 */
191
434
  limits?: {
192
435
  maxTaskCostUsd?: number;
193
436
  maxTaskTokens?: number;
@@ -197,51 +440,98 @@ export interface PolicyInfo {
197
440
  };
198
441
  [k: string]: unknown;
199
442
  }
443
+ /** §workflows 可观测(core 1.116 design/97;service `GET /v1/workflows*`)。
444
+ * 生命周期状态;开放联合容未来新态。源=core `WorkflowRunStatus`(running/completed/failed,workflow-run-store.ts)。 */
200
445
  export type WorkflowRunStatus = "queued" | "running" | "completed" | "failed" | (string & {});
446
+ /** `GET /v1/workflows` 列表行 = core `summarizeWorkflowRun` 投影(workflow-run-store.ts:34,跨 InMem/File/PG byte-identical)。
447
+ * owner-scoped(service 只返调用方 principal 自己的 run,scope=创建者 principal)。时间均 epoch ms。 */
201
448
  export interface WorkflowRunSummary {
449
+ /** run id(= `WorkflowRun.id`)。 */
202
450
  id: string;
451
+ /** 租户/分组 scope(= 创建 run 的 principal)。 */
203
452
  scope: string;
453
+ /** 🔴 K-2(core SHIPPED 1.155.0)—— `/workflows` 列表渲染:工作流名/描述/当前 phase 标题。core
454
+ * `summarizeWorkflowRun` 投影发(additive/tolerate-absent)。 */
204
455
  name?: string;
205
456
  description?: string;
206
457
  currentPhase?: string;
207
458
  status: WorkflowRunStatus;
459
+ /** 已记录的 phase 数。 */
208
460
  phaseCount: number;
461
+ /** 已记录的 agent-run 数。 */
209
462
  agentCount: number;
463
+ /** 总 token = own + nested(summary 已折叠;triage 排序键)。 */
210
464
  tokens: number;
465
+ /** 起始 epoch ms。🔴 MF-W:**queued 态还没起跑 → optional**(1.6.0 / core 1.150,startedAt now optional)。 */
211
466
  startedAt?: number;
467
+ /** 结束 epoch ms(running 时缺)。 */
212
468
  endedAt?: number;
469
+ /** 记录创建 epoch ms(listByScope 排序键)。 */
213
470
  createdAt: number;
214
471
  [k: string]: unknown;
215
472
  }
473
+ /** MF-W (workflow monitor "Activity · last N of M tool calls") — one tool-call beat on a workflow agent's bounded
474
+ * activity tail. Source = core `ToolActivity` (types.ts:1023-1035), projected verbatim by the service detail
475
+ * handler (`summarizeWorkflowDetail` → `activity: a.activity`, server.ts). Maps to the shell `WorkflowToolCall
476
+ * { name, arg? }` (MF-W-workflow-monitor.md): `toolName`→`name`, `arg`→`arg`.
477
+ * 🔴 `arg` is a SHORT primary-arg summary (command→name, path→basename, url→origin+path), SECRET-SCRUBBED +
478
+ * truncated (~80 code points) by core — it is for the monitor's `Read(path)` / `Bash(grep …)` display, NOT the
479
+ * full args; render it, NEVER re-feed it to a model. Open shape (index sig) — tolerate future fields. */
216
480
  export interface WorkflowActivityBeat {
217
481
  phase?: "start" | "end";
218
482
  toolCallId?: string;
483
+ /** The tool name (shell renders `${toolName}(${arg})`). */
219
484
  toolName?: string;
485
+ /** SHORT, secret-scrubbed, ~80-code-point primary-arg summary (set on `phase:"start"`). UNTRUSTED display text. */
220
486
  arg?: string;
487
+ /** Set on `phase:"end"` — whether the tool call errored. */
221
488
  isError?: boolean;
222
489
  [k: string]: unknown;
223
490
  }
491
+ /** MF-W — one agent-run row in a workflow's detail (`summarizeWorkflowDetail` agents projection, server.ts). The
492
+ * shape is PERMISSIVE (index sig) — read the known render fields, tolerate the rest as the projection evolves.
493
+ * The typed fields are the ones the monitor keys on; `activity[].arg` is the load-bearing addition (round-3 ③). */
224
494
  export interface WorkflowAgentRow {
495
+ /** Display label ("port:/mcp"). */
225
496
  label?: string;
497
+ /** Lifecycle status (the input vocab the display derivation reads). */
226
498
  status?: string;
499
+ /** The phase title this agent ran under (groups it into a phase bucket). */
227
500
  phase?: string;
501
+ /** Per-agent model display label ("Opus 4.8 (1M context)") — SVC-4 / CORE-8 ①. */
228
502
  model?: string;
229
503
  tokens?: number;
230
504
  turns?: number;
505
+ /** Total tool calls ("M" in "last N of M tool calls") — CORE-8 ②. */
231
506
  toolCalls?: number;
507
+ /** MF-W "Activity" tail — the LAST-N tool-call beats (bounded; `arg` is the per-beat display summary). CORE-8 ③. */
232
508
  activity?: WorkflowActivityBeat[];
509
+ /** What the worker was ASKED (core-redacted + bounded). UNTRUSTED display text. */
233
510
  prompt?: string;
511
+ /** The worker's final OUTPUT (core-redacted + bounded). UNTRUSTED display text. */
234
512
  output?: string;
235
513
  [k: string]: unknown;
236
514
  }
515
+ /** `GET /v1/workflows/:id` 完整 run(core `WorkflowRun`,orchestration/workflow.ts;service `summarizeWorkflowDetail`
516
+ * 投影)。非 owner → 404(无 existence oracle)。
517
+ * 🔴 phases/groups/stats 内部嵌套形态可能演进 → 标 permissive(unknown[]/index sig);消费方按需读、容缺。
518
+ * 🔴 round-3 ③: `agents[]` 收紧为 {@link WorkflowAgentRow}(暴露 `activity[].arg`,MF-W 监视器渲染键),仍 index-sig 容缺。
519
+ * 🔴 工作流级 `name`/`description`(core `WorkflowRun.name?/description?` 确有,MF-W 头部要)截至 service `1bf7a5c`
520
+ * **未被 `summarizeWorkflowDetail`/`summarizeWorkflowRun` 投到 wire** → SDK 暂不声明(不造没发的形;service 补投后再加)。 */
237
521
  export interface WorkflowRun {
238
522
  id: string;
239
523
  scope: string;
240
524
  status: WorkflowRunStatus;
525
+ /** 🔴 K-2c detail 侧(service `summarizeWorkflowDetail` server.ts:5171-5172,redacted/omit-when-absent)—— 工作流头部
526
+ * 名/副标题(来自脚本 `export const meta={name,description}`)。detail **不带 `currentPhase`**(那是 summary 行字段;
527
+ * detail 有完整 `phases[]` 含 per-phase `title`,当前 phase 自这里取)。老 run 二者皆缺。 */
241
528
  name?: string;
242
529
  description?: string;
530
+ /** 阶段记录(内部形态 permissive;渲染读 length/已知字段即可。detail 投结构化 `{title,status,startedAt,endedAt,durationMs,done,total}`)。 */
243
531
  phases: unknown[];
532
+ /** agent-run 记录(收紧为 {@link WorkflowAgentRow}:暴露 MF-W `activity[].arg`;仍容缺/容演进)。 */
244
533
  agents: WorkflowAgentRow[];
534
+ /** 统计(`stats.tokens` own + `stats.nested.tokens`,R-5 own/nested 分开存)。 */
245
535
  stats: {
246
536
  tokens?: number;
247
537
  nested?: {
@@ -250,6 +540,7 @@ export interface WorkflowRun {
250
540
  };
251
541
  [k: string]: unknown;
252
542
  };
543
+ /** 起始 epoch ms。🔴 MF-W:queued 态还没起跑 → optional(1.6.0 / core 1.150)。 */
253
544
  startedAt?: number;
254
545
  endedAt?: number;
255
546
  createdAt: number;
@@ -267,9 +558,11 @@ export interface ImageIndexEntry {
267
558
  podContract?: Record<string, unknown>;
268
559
  status?: string;
269
560
  visibility?: string;
561
+ /** 不可变 digest(一个 running sandbox 由它 build)。🔴 UI **仅展示**,caller **绝不送它回去绑定**(绑定送 profile)。 */
270
562
  digest?: string;
271
563
  [k: string]: unknown;
272
564
  }
565
+ /** `POST /v1/images/select` 的 §7 resolution 结果(**仅 UI 预览"这 profile 解析到哪个 digest/能力",非绑定凭证**)。 */
273
566
  export interface ImageSelectResult {
274
567
  profile?: string;
275
568
  digest?: string;
@@ -283,6 +576,8 @@ export interface ImageSelectResult {
283
576
  manifestSha?: string;
284
577
  [k: string]: unknown;
285
578
  }
579
+ /** Run state (`GET /v1/runs/:id`) — LIVE shape (service Drift 2): `result` is the NESTED TaskResult
580
+ * (output text = result.result, stats = result.stats; no top-level stats); error text field is `error`. */
286
581
  export interface RunRecord {
287
582
  taskId: string;
288
583
  sessionId: string;
@@ -290,17 +585,30 @@ export interface RunRecord {
290
585
  result?: TaskResult;
291
586
  errorCode?: string;
292
587
  error?: string;
588
+ /** Work-view correlation. Present when the run has a jobId (omitted when null). LIVE server-side
589
+ * (service 63b8696): persisted + groupable via `GET /v1/tasks?jobId=`. */
293
590
  jobId?: string;
591
+ /** System-level attribution, DERIVED FROM the authenticating credential (unforgeable; body injection is
592
+ * ignored). e.g. "oa" | "cc-mcp" | "portal". LIVE (service cf1be73). */
294
593
  source?: string;
594
+ /** E12 prompt-suggestions(`suggestNextPrompts:true` 提交后)—— **完成后**才产(settle 前 undefined,轮询到出现);
595
+ * UNTRUSTED 模型文本、仅 UI、绝不回喂模型。🔴 **LIVE 验证(tidb 引擎 2026-06-27)**:`runs.get`
596
+ * 把 events tail 上最后一个 `suggestions` 事件读进此字段(server.ts:1371)—— 不流式消费 events 的轮询方从这读。
597
+ * 仅 durable run(async,需 TiDB run store);流式消费方读 {@link AgentEvent} 的 `suggestions` arm(两路同源)。 */
295
598
  suggestions?: string[];
296
599
  }
600
+ /** Run list item (`GET /v1/tasks` items) — the live cheap `runSummary` shape (service Drift 1).
601
+ * NOTE wire names: `id` (not taskId), `startedAt` (not createdAt), `costMicroUsd` (micro-USD); no sessionId. */
297
602
  export interface TaskSummary {
298
603
  id: string;
299
604
  status: RunStatus;
300
605
  scenario?: string;
301
606
  jobId?: string;
607
+ /** Credential-derived system attribution. */
302
608
  source?: string;
609
+ /** Objective, secret-redacted then truncated to 120 chars (the pinned wire contract; older rows null/absent). */
303
610
  objectivePreview?: string;
611
+ /** Run owner principal (boss/operator view; the pinned wire contract). */
304
612
  owner?: string;
305
613
  startedAt: string;
306
614
  endedAt?: string;
@@ -313,25 +621,59 @@ export interface TaskSummary {
313
621
  };
314
622
  [k: string]: unknown;
315
623
  }
624
+ /** A workspace artifact — deterministic projection of persisted tool events (co-signed with the service).
625
+ * `kind` is an OPEN set: render unknown kinds as a generic row, never crash. v1 emits "file" | "git-push"
626
+ * ("diff" reserved, not emitted). */
316
627
  export interface Artifact {
628
+ /** "<taskId>:<n>" — stable within the task (UI key). */
317
629
  id: string;
318
630
  taskId: string;
631
+ /** Present when the run has a job (job-level aggregation key). */
319
632
  jobId?: string;
320
633
  kind: "file" | "git-push" | "diff" | (string & {});
634
+ /** file: workspace-relative path; git-push: refspec tail or command. */
321
635
  ref: string;
322
636
  summary?: string;
637
+ /** ts of the last successful contributing call. */
323
638
  createdAt: string;
639
+ /** file kind only — HUNK-LEVEL line stats derived from logged call args (NOT a git diff; upgrades to the
640
+ * reserved `diff` kind when a real patch store lands). the pinned wire contract. */
324
641
  additions?: number;
325
642
  deletions?: number;
326
643
  [k: string]: unknown;
327
644
  }
645
+ /** The `suspended` event's gate payload (core checkpoint-store). Tool args / question text
646
+ * are NOT here — join the same task's trace tool-call block via approvals' toolCallId.
647
+ *
648
+ * OPEN DISCRIMINATED SET (design/80 D-0) — mirrors core `src/core/checkpoint-store.ts` CheckpointGate.
649
+ * Consumers MUST branch on `kind` and render an unknown `kind` generically (never crash): core can mint a
650
+ * kind this wire predates, and a contract test pins core→wire parity so a new core arm fails CI, not prod. */
328
651
  export interface CheckpointGate {
652
+ /** OPEN SET — branch on this, render an UNKNOWN kind generically (interface, not a closed union, so a new
653
+ * core kind doesn't break narrowing — same idiom as `Artifact.kind`). Known kinds:
654
+ * - `human` — plain HITL approval (budget-auto-approvable). has `reason`, `toolName`.
655
+ * - `irreversible_ask` — design/37 irreversibility / design/70 egress safety-tighten; NOT budgetable
656
+ * (load-bearing safety gate). has `reason`, `toolName`.
657
+ * - `resource_limit` — design/74 cost/token/time slice boundary; resolve `{decision:"continue"}`. has `reason`.
658
+ * - `needs_review` — design/76 dry-run/shadow → durable `needs_review` TERMINAL (POST-prediction review,
659
+ * disjoint from the approval family). has `reason`.
660
+ * - `task_done` — design/38 Path A background sub-task handle (door B never sees it). */
329
661
  kind: "human" | "irreversible_ask" | "resource_limit" | "needs_review" | "task_done" | (string & {});
662
+ /** Present on human / irreversible_ask / resource_limit / needs_review (not task_done). */
330
663
  reason?: string;
664
+ /** Present on human / irreversible_ask. */
331
665
  toolName?: string;
332
666
  [k: string]: unknown;
333
667
  }
668
+ /** The prompt-assembly manifest (server ≥1.219 — core `prompt.assembled` trace contract verbatim,
669
+ * service budget.ts `promptManifestRecordOf` 实拆): constitution ownership + per-section digests +
670
+ * the tool contract summary. Carries ONLY ids/digests/counts — NEVER prompt bodies (privacy boundary);
671
+ * hashes are process-salted (NOT comparable across worker restarts — UI must not diff them cross-process).
672
+ * v1 face = constitution/blocks/totalChars; `sections`/`tools` are the v2 additive face (absent on a
673
+ * v1-only engine). ⚠️ One task can carry MULTIPLE manifests: a cascade/verify run re-prepares under one
674
+ * taskId and every rung's manifest is persisted in emission order (server runs.ts flushPromptManifest). */
334
675
  export interface PromptManifest {
676
+ /** Who owned the constitution layer: "core" is the steady state; anything else is worth eyes. */
335
677
  constitution: "core" | "replaced" | "provider-assembled" | "legacy" | (string & {});
336
678
  blocks: Array<{
337
679
  id: string;
@@ -362,14 +704,21 @@ export interface PromptManifest {
362
704
  totalChars: number;
363
705
  [k: string]: unknown;
364
706
  }
707
+ /** A session's prompt-epoch pin (server ≥1.220 `GET /v1/sessions/:id` additive `promptEpoch`; core
708
+ * `session.getPromptEpoch()` contract verbatim, service audit.ts 实拆). Absent key = a pre-epoch
709
+ * session (never null). `activatedBy: "legacy_migration"` = the one-time re-pin after an engine
710
+ * upgrade (normal, not an anomaly). */
365
711
  export interface PromptEpoch {
366
712
  epoch: number;
713
+ /** `sha256:<64 hex>` — core's normalize gate rejects anything else (a bad pin reads as absent). */
367
714
  artifactDigest: string;
368
715
  packId: string;
369
716
  assemblyApi: number;
370
717
  activatedBy: "session_start" | "compaction" | "legacy_migration" | (string & {});
371
718
  [k: string]: unknown;
372
719
  }
720
+ /** A trace turn (GET /v1/tasks/:id/turns items — true shape). role currently only
721
+ * "assistant" (user/system/tool reserved). */
373
722
  export interface TraceTurn {
374
723
  seq: number;
375
724
  ts: string;
@@ -383,6 +732,14 @@ export interface TraceTurn {
383
732
  };
384
733
  [k: string]: unknown;
385
734
  }
735
+ /** Open set — render unknown types generically, never crash.
736
+ *
737
+ * design/99 §E1/§E2 (SHIPPED, service `TraceBlock`/`projectEvents` project.ts:69-73,160-165): the action-card
738
+ * BODY now rides the trace. `tool-result.output` (+ `truncated`) is the model-facing result content — UNTRUSTED
739
+ * RAW, but the service has already `redactDeep`'d + SIZE-bounded it at append (the old "ALWAYS absent" gap is
740
+ * CLOSED). NON-UNIFORM (string | (TextContent|ImageContent)[]; truncated ⇒ a single string); absent ⇒ no body.
741
+ * Both `tool-call` and `tool-result` also carry the §E2 identity (`eventId` = dedup/resume handle;
742
+ * `parentToolCallId` = sub-agent attribution), additive / tolerate-absent. */
386
743
  export type TraceBlock = {
387
744
  type: "thinking";
388
745
  text: string;
@@ -404,27 +761,66 @@ export type TraceBlock = {
404
761
  truncated?: boolean;
405
762
  eventId?: string;
406
763
  parentToolCallId?: string;
407
- } | ({
764
+ }
765
+ /** server ≥1.219 ([998]②/[1005]①b): the assembly manifest rendered at the TOP of the turn it prepared
766
+ * (web's "Prompt 组成" card source; service project.ts projectEvents `prompt_assembled` 实拆). */
767
+ | ({
408
768
  type: "prompt-assembled";
409
769
  } & PromptManifest) | {
410
770
  type: string;
411
771
  [k: string]: unknown;
412
772
  };
773
+ /** A trace-relay SSE event (`GET /v1/tasks/:id/stream` — the workspace LIVE timeline, `streamTaskTrace` +
774
+ * `mapTraceEvent`, server.ts). This is a DISTINCT vocabulary from `AgentEvent` (do NOT confuse with
775
+ * `runs.events`): the durable log is BLOCK-grained, so each frame is a "delta" the client appends. Resumable
776
+ * (each `id:` = the durable `task_event.seq`); on a window eviction the server returns 416 → resync via
777
+ * `trace.turns` then resume from `retainedFrom`.
778
+ *
779
+ * OPEN set — branch on `event`, render an unknown one generically (never crash). Known frames (mapTraceEvent):
780
+ * - `meta` — FIRST frame: `{ version, mode, resumeFrom }` (stream contract, NOT id-stamped).
781
+ * - `block-thinking-delta` — `{ seq, text }` collapsible thinking append.
782
+ * - `block-content-delta` — `{ seq, text }` answer text append.
783
+ * - `tool-call` — `{ seq, id, name, input, eventId?, parentToolCallId? }` an action started (§E2 identity additive).
784
+ * - `tool-result` — `{ seq, callId, isError, output?, truncated?, eventId?, parentToolCallId? }` an action closed.
785
+ * §E1 (SHIPPED, mapTraceEvent project.ts:248-250): `output`/`truncated` = the model-facing
786
+ * BODY (redacted+bounded at append; absent ⇒ no body). The old "output absent" gap is CLOSED.
787
+ * - `prompt-assembled` — `{ seq, ...PromptManifest }` (server ≥1.219): the prepare's assembly manifest
788
+ * (constitution/blocks/sections?/tools?/totalChars — mapTraceEvent passthrough,
789
+ * whitelisted at append). MULTIPLE per task on cascade/verify runs.
790
+ * - `turn` — `{ seq, tokens? }` a turn boundary (+ usage if present).
791
+ * - `done` — `{ seq, suspended? }` terminal (suspended:true = paused on HITL, NOT completed).
792
+ * - `error` — `{ code, message }` terminal failure / `WORKER_DOWN` (stalled) / `STREAM_MAX_DURATION`.
793
+ * - `heartbeat` — `{}` keep-alive (the SDK reader swallows these; not yielded). */
413
794
  export interface TraceStreamEvent {
795
+ /** SSE event name (open set; dispatch on this). */
414
796
  event: "meta" | "block-thinking-delta" | "block-content-delta" | "tool-call" | "tool-result" | "prompt-assembled" | "turn" | "done" | "error" | (string & {});
797
+ /** The durable seq (`id:` line) when the frame carries one — feed it back as Last-Event-ID to resume. `meta`
798
+ * and `heartbeat` carry none. */
415
799
  id?: string;
800
+ /** The frame's JSON `data:` payload (shape varies by `event`; permissive — read known fields, tolerate the rest). */
416
801
  data: Record<string, unknown>;
417
802
  }
803
+ /** A workflow-run SSE event (`GET /v1/workflows/:id/stream` — S8 self-orchestration LIVE progress,
804
+ * `streamWorkflowRun` + core `subscribeWorkflow`, server.ts). NOT resumable (replica-local, in-process;
805
+ * no `id:`/Last-Event-ID — a drop is a full restart, NOT a resume). FIRST frame is `meta` `{ version, runId }`;
806
+ * subsequent frames carry the core `WorkflowEvent` (its `type` becomes the SSE event name). OPEN set — branch on
807
+ * `event`, the `data` shape is core-internal and may evolve (read known fields, tolerate the rest). */
418
808
  export interface WorkflowStreamEvent {
809
+ /** SSE event name = `meta` for the opener, else the core WorkflowEvent `type` (open set). */
419
810
  event: "meta" | "error" | (string & {});
811
+ /** The frame's JSON `data:` payload (core `WorkflowEvent` shape; permissive). */
420
812
  data: Record<string, unknown>;
421
813
  }
814
+ /** A per-request skill (passed as an object, not loaded from disk) — core-native TaskSpec.skills shape. */
422
815
  export interface SkillSpec {
423
816
  name: string;
424
817
  description: string;
425
818
  content: string;
426
819
  }
820
+ /** A per-request MCP server (CC `.mcp.json` parity) — core-native `McpServerSpec` shape (core types.ts:277).
821
+ * `stdio` = a local command the worker spawns (single-user only); `http` = a remote streamable-HTTP server. */
427
822
  export interface McpServerSpec {
823
+ /** Stable name; the server's tools are namespaced `<name>__<tool>`. */
428
824
  name: string;
429
825
  transport: {
430
826
  kind: "stdio";
@@ -434,59 +830,123 @@ export interface McpServerSpec {
434
830
  } | {
435
831
  kind: "http";
436
832
  url: string;
833
+ /** Static headers sent on every request (e.g. an auth bearer for the MCP server itself). */
437
834
  headers?: Record<string, string>;
835
+ /** Header name into which the Runner-held principal is injected (model/worker can't read/set it). */
438
836
  principalHeader?: string;
439
837
  };
838
+ /** Optional allowlist of tool names to expose (others dropped). */
440
839
  allowTools?: string[];
840
+ /** Opt in to INBOUND elicitation for this server (server may ask the END USER mid-tool-call). Default OFF. */
441
841
  elicitation?: boolean;
842
+ /** Caller-side per-tool safety-axis overrides, keyed by the server's remote (un-namespaced) tool name. */
442
843
  toolAxes?: Record<string, {
443
844
  effect?: "read" | "write";
444
845
  egress?: boolean;
445
846
  irreversibility?: "always" | "never";
446
847
  }>;
447
848
  }
849
+ /** The user's `<user_memory>` (GET /v1/memory) — owner-scoped by construction (scope derived from the
850
+ * request principal; cannot address others' memory). content null = empty. the pinned wire contract. */
448
851
  export interface MemoryRecord {
449
852
  scope: string;
450
853
  content: string | null;
451
854
  }
855
+ /** MF-30 memory WRITE ack —— append/edit/remove **统一形** `{ ok, id, scope }`(service `@sema-agent/server@1.3.0`,
856
+ * 实际 handler append=2917 / patch=2926 / delete=2933 全返此形;locked 测试断言 append 含 `ok`)。
857
+ * 🔴 service 订正:旧源**摘要注释** server.ts:2880 误写 append 漏 `ok`,**实际代码一直含 `ok`** —— 代码为准,三 verb 统一。
858
+ * 🔴 **memory 是 per-PRINCIPAL,不是 per-session** —— path 的 `:id`(session)只是 shell 的**寻址上下文**(`/memory`
859
+ * 命令在某 session 里跑),**非 per-session 分区**;为某 principal append 的 note,该 principal **所有 session 都读得到**。
860
+ * note **VERBATIM 存(≤8 KiB,用户授权内容、不 redact)**;空/超长/缺字段 → 400 fail-loud。edit/remove 需 store 的
861
+ * id-addressable update/delete,后端缺 → **501**(honest degrade,绝非假 200);append 永远可用(memoryWrite=true 时)。 */
452
862
  export interface MemoryWriteAck {
453
863
  ok: boolean;
454
864
  id: string;
455
865
  scope: string;
456
866
  }
867
+ /** Worker capability map (`GET /v1/capabilities`). Open set — ignore unknown keys. Booleans
868
+ * share deps with the route gates ("says yes but 501s" is structurally impossible, producer-tested). */
457
869
  export interface Capabilities {
458
870
  asyncRuns?: boolean;
459
871
  artifacts?: boolean;
460
872
  approvals?: boolean;
461
873
  leader?: boolean;
874
+ /** 🔴 K-2(core SHIPPED 1.155.0;service `/v1/capabilities` 暴 `workflows: Boolean(deps.workflowRunStore)`,
875
+ * server.ts:930)—— worker 支持工作流编排(`/workflows` 可观测 + workflow 提交)。false/缺 ⇒ shell 隐藏 `/workflows`
876
+ * 面板,别 trial-by-501。注:per-principal `allowWorkflows`(center runtimeCaps,core 1.157.0)是更细的**授权**轴,
877
+ * 与本 worker 能力位正交。 */
462
878
  workflows?: boolean;
879
+ /** 🔴 E18 rewind gate(service server.ts:911 `Boolean(resumeAnchorStore && sessionStorage.getLeafId)`)—— `TaskRequest.resumeAt`
880
+ * 能否 resolve。false/缺 ⇒ shell 隐藏「rewind 到某条消息」入口,别 trial-by-4xx。本/云均可(anchor store 各后端都在),
881
+ * 仅 env-only/无后端 worker false。 */
463
882
  resumeAt?: boolean;
883
+ /** 🔴 E19 rewind-files gate(service server.ts:921 `Boolean(fileSnapshotStore)`)—— `TaskRequest.rewindFiles` 能否生效
884
+ * (分叉时同步回退工作树)。false/缺 ⇒ rewind 仅回退对话、文件留最新态(shell 该把「连同文件回退」选项灰掉)。 */
464
885
  rewindFiles?: boolean;
886
+ /** 🔴 K-1c 手动 compact gate(service server.ts:~932 `Boolean(runStore)`,POST /v1/runs/:id/compact → core 1.156
887
+ * `TaskStream.compact()`)—— 手动 `/compact` 命令是否可发。配 `compacted` 事件的 `trigger:"manual"`。false/缺 ⇒ 灰掉
888
+ * `/compact`(非 live run 409、无 store 501)。 */
465
889
  manualCompact?: boolean;
466
890
  version: string;
467
891
  scenarios?: string[];
892
+ /** false ⇒ stats.costMicroUsd=0 may mean "no MODEL_COST_* configured", not "free". Worker-level. */
468
893
  pricingConfigured?: boolean;
894
+ /** Memory transparency endpoints available (GET/DELETE /v1/memory). the pinned wire contract. */
469
895
  memory?: boolean;
896
+ /** MF-30 — memory WRITE available (`deps.memory?.append`;server.ts:828)。true ⇒ `memory.append/edit/remove` 可用,
897
+ * UI 显写入入口。append 永远可用(memoryWrite=true 时);edit/remove 后端缺 id-addressable 时各自 501。 */
470
898
  memoryWrite?: boolean;
899
+ /** 2c session-sync (P1d) — the `/v1/sessions/:id/sync/*` peer routes resolve (durable backend + entry-export seam
900
+ * + a file-snapshot store all wired; server.ts:850). Gate the whole `client.sessions.sync.*` surface off this —
901
+ * DON'T trial-by-501. False ⇒ the routes 501 (no durable session store). */
471
902
  sessionSync?: boolean;
903
+ /** 🔴 K-5 session-resume gates(service server.ts:894/836/+,§0.5 session 抽象)—— shell 的 `/resume` picker 据此诚实
904
+ * gate,别 trial-by-501:`sessionList` = list 可用(`Boolean(sessionStorage.listSessions ?? runStore.listSessions)`,
905
+ * 喂 picker 行);`sessions` = transcript preview 可用(`Boolean(sessionAudit)`,`GET /v1/sessions/:id`→SessionAudit)。
906
+ * `sessionFork`(E17,`sessionStorage.fork`)/`sessionDelete`(E21,`purgeSession`)是 fork/删的 producing-path gate。
907
+ * 各 false ⇒ 对应路由 501(「says yes ⟺ route works」)。 */
472
908
  sessions?: boolean;
473
909
  sessionList?: boolean;
910
+ /** K-5 session-search — same producing gate as `sessionList` (server.js:610 — the picker's search leg). */
474
911
  sessionSearch?: boolean;
475
912
  sessionFork?: boolean;
476
913
  sessionDelete?: boolean;
914
+ /** /v1/usage 成本面可用(server.js:588 `Boolean(costQuota)`)。 */
477
915
  usage?: boolean;
916
+ /** /v1/policy 面(server.js:587 硬编码 true)。 */
478
917
  policy?: boolean;
918
+ /** 会话内改 permission mode 的写面 —— server 1.214 恒 false(server.js:589,未上线;mode 走 TaskRequest.permissionMode)。 */
479
919
  permissionModeWrite?: boolean;
920
+ /** per-turn `model` 字段可用(server.js:590 硬编码 true;TaskRequest.model → CC /model parity)。 */
480
921
  modelSelection?: boolean;
922
+ /** per-turn `reasoningEffort` 可用(server.js:591 硬编码 true;CC /effort parity)。 */
481
923
  effortSelection?: boolean;
924
+ /** tool_end 带完整 toolOutput(server.js:592 硬编码 true)。 */
482
925
  toolOutput?: boolean;
926
+ /** 事件带 message identity(eventId/messageId 族;server.js:593 硬编码 true)。 */
483
927
  messageIdentity?: boolean;
928
+ /** 子代理内容事件前向转发(parentToolCallId stamped;server.js:594 硬编码 true)。 */
484
929
  forwardSubagentEvents?: boolean;
930
+ /** C2 子代理 steer 面(server.js:595 `Boolean(subagentSteerRegistry && runStore)`;POST /v1/runs/:id/subagents/:t/steer)。 */
485
931
  subagentSteer?: boolean;
932
+ /** 子代理 resume/复活面(server.js:596 同 subagentSteer 双 dep;POST …/subagents/:t/resume,还需 run 侧 retainSubagentSessions)。 */
486
933
  subagentResume?: boolean;
934
+ /** server 1.244 [1488]③(b):后台子代(a… 句柄,background_agent ONLY;wa… 观测行走 workflow journal)终报读面
935
+ * —— GET /v1/runs/:id/subagents/:handle/output(引擎 TaskRegistry 的 TaskOutput 工具投影过 HTTP;
936
+ * bg 子代永不在 run store)。副本本地,同 steer。 */
487
937
  subagentOutput?: boolean;
938
+ /** server 1.251(S2,core 1.370 bgAgentId):per-agent live tail —— GET /v1/runs/:id/subagents/:handle/stream
939
+ * (SSE:meta/forward/heartbeat;replay+tail 的 tail 半场,replay=subagentOutput 面)。live 帧
940
+ * replica-local(帧只在宿主 run 所在副本产生;meta 帧如实声明)。同门同寻址同 404 形,session-enforced。 */
488
941
  subagentStream?: boolean;
942
+ /** server 1.246 [1499]:泛后台任务句柄双 verb(CC TaskOutput/TaskStop 人侧对位)——
943
+ * GET/POST /v1/runs/:id/tasks/:handle/{output,stop}:background_bash(stdout;是否消费游标取决于句柄形态,
944
+ * spooled 全量可重读/cursor-only 增量,投影 flags 权威)/monitor(批)/background_agent(终报);workflow
945
+ * 句柄 404(读走 journal 面;wire 上无 workflow 停止面)。出生即 session-enforced(session-bound run 必带
946
+ * 匹配 ?session=)。副本本地,同 subagentOutput。 */
489
947
  taskHandles?: boolean;
948
+ /** TaskRequest.settings 各分片是否 honored(server.js:597 —— 唯一对象形能力位;`env` 恒 false,
949
+ * `hooks` 单用户部署(requirePrincipal!==true)才 true)。 */
490
950
  taskSettings?: {
491
951
  permissions?: boolean;
492
952
  permissionMode?: boolean;
@@ -496,31 +956,69 @@ export interface Capabilities {
496
956
  hooks?: boolean;
497
957
  [k: string]: unknown;
498
958
  };
959
+ /** server ≥1.243 ([1478] R2): TaskRequest.appendSystemPrompt accepted top-level → core TaskSpec.appendSystemPrompt.
960
+ * false/absent ⇒ fall back to the `settings.outputStyle` ride-along (older servers fold it into the same field). */
499
961
  appendSystemPrompt?: boolean;
962
+ /** server ≥1.243 ([1479]①): TaskRequest.compactionModel accepted (catalog-gated cheap compaction gear).
963
+ * false/absent ⇒ older server drops the field — don't offer the picker. */
500
964
  compactionModel?: boolean;
965
+ /** [876]③ TaskRequest.agents per-task 子代理定义 honored(server.js:598 `requirePrincipal !== true` —— 单用户部署才收)。 */
501
966
  taskAgents?: boolean;
967
+ /** TaskRequest.retainBackgroundProcesses honored(server.js:599 单用户部署才收)。 */
502
968
  retainBackgroundProcesses?: boolean;
969
+ /** server ≥1.221 (core 1.314 工具面控制批,[1052]②): roster TRUE-UNMOUNT list — the named wire tools'
970
+ * schemas never reach the model (the deny gate saves no tokens; this does), and the assembly manifest
971
+ * narrows honestly. Tighten-only: core's inheritance invariant unions it into EVERY child spawn path.
972
+ * Malformed (non-array / empty-string items) → 400 fail-loud at submit. */
503
973
  excludeTools?: string[];
974
+ /** server ≥1.221 (core 1.314): DEFERRED DISCLOSURE list — the named MOUNTED tools (built-ins included)
975
+ * ride the wire as a placeholder (schema bytes out of the cache prefix) and materialize via ToolSearch
976
+ * on demand. The carrier for the shell's "Workflow on by default but not exposed" posture. Same
977
+ * validation/inheritance posture as {@link excludeTools}. */
504
978
  deferTools?: string[];
979
+ /** TaskRequest.interactiveTools 认词(server.js:600 硬编码 true;-p 无人值守语义探测位 —— 见 TaskRequest 注)。 */
505
980
  interactiveTools?: boolean;
981
+ /** TaskRequest.cwd honored(server.js:601 `cwdHonored`:local 单用户 host-adapter 才 true;多租户 fail-closed)。 */
506
982
  projectContext?: boolean;
983
+ /** TaskRequest.mcpServers honored(server.js:602 `mcpInjectionHonored`:单用户才 true,多租户 ignore)。 */
507
984
  mcpInjection?: boolean;
985
+ /** GET /v1/runs/:id/model-usage 面(server.js:603 `Boolean(runStore && modelUsage)`)。 */
508
986
  modelUsage?: boolean;
987
+ /** session_init 首帧(CC parity;server.js:604 硬编码 true)。 */
509
988
  sessionInit?: boolean;
989
+ /** MCP 面总位(/v1/mcp status 等;server.js:605 硬编码 true)。 */
510
990
  mcp?: boolean;
991
+ /** §E23 inbound-MCP elicitation HITL(server.js:606 `Boolean(elicitation)` = MCP_ELICITATION_ENABLED)。 */
511
992
  mcpElicitation?: boolean;
993
+ /** §4④ live AskUserQuestion HITL(server.js:607 `Boolean(question)` = ASK_QUESTION_ENABLED)。 */
512
994
  askUserQuestion?: boolean;
995
+ /** [830]① live tool-approval HITL(server.js:608 `Boolean(toolApproval)` = TOOL_APPROVAL_ENABLED;
996
+ * gate `client.toolApprovals` 整面,别 trial-by-501)。 */
513
997
  toolApproval?: boolean;
998
+ /** E12 suggestNextPrompts 认词(server.js:614 硬编码 true)。 */
514
999
  promptSuggestions?: boolean;
1000
+ /** PUT /v1/sessions/:id/policy 面(server.js:615 `Boolean(sessionPolicyStore)`)。 */
515
1001
  sessionPolicy?: boolean;
1002
+ /** E18 code-only rewind(TaskRequest.rewindFilesTo;server.js:617 `Boolean(fileSnapshotStore && resumeAnchorStore && getLeafId)`)。 */
516
1003
  rewindFilesTo?: boolean;
1004
+ /** assistant-scheduler 面(server.js:618 `schedulerEnabled && requirePrincipal!==true && remoteExec==="host"` 三与)。 */
517
1005
  scheduler?: boolean;
1006
+ /** SendUserFile 工具面(server.js:620 `Boolean(sendUserFile && publicEndpoint)`)。 */
518
1007
  sendUserFile?: boolean;
1008
+ /** SendUserFile 的 S3 公网端点(server.js:621 —— 唯一 string|null 位;null = 未配)。 */
519
1009
  s3PublicEndpoint?: string | null;
1010
+ /** GET /v1/files/sent 台账面(server.js:622 `Boolean(sendFileLedger)`)。 */
520
1011
  sendUserFileLedger?: boolean;
1012
+ /** GET /v1/workflows 列表面(server.js:624 `Boolean(workflowRunStore)`;`workflows` 总位见上)。 */
521
1013
  workflowsList?: boolean;
522
1014
  [k: string]: unknown;
523
1015
  }
1016
+ /** One scenario's detail card (`GET /v1/capabilities/scenarios/:name` — server 1.214 server.js:567-576 handler,
1017
+ * shape = capabilities/scenarios.d.ts `ScenarioDetail` verbatim; the LIST of names rides `capabilities.scenarios`).
1018
+ * `source`/`builtin` = builtin vs center-config overlay; `toolset` names the tool bundle, `tools` the resolved
1019
+ * tool names; `promptSummary` is a human-readable prompt digest (NOT the full prompt); `enabled` = a center
1020
+ * scenario can be declared-but-disabled. UNKNOWN name → 404 `{error:{code:"scenario_not_found"}}` (note the
1021
+ * OBJECT-shaped error body — unique to this route). */
524
1022
  export interface ScenarioDetail {
525
1023
  name: string;
526
1024
  source: "builtin" | "center";
@@ -532,17 +1030,49 @@ export interface ScenarioDetail {
532
1030
  enabled: boolean;
533
1031
  [k: string]: unknown;
534
1032
  }
1033
+ /** A pending HITL checkpoint — the RICH `/v1/approvals` operator-queue row (true shape;
1034
+ * ASSISTANT-WIRE-CONTRACT §7(b), service main 1fafeec / core 1.110.0). ⚠️ createdAt/deadline are EPOCH MS.
1035
+ *
1036
+ * 🔴 §7 钉死两形状不可混 —— 本类型是 **(b) 富 /v1/approvals 行**(`GET /v1/approvals` + `/stream` 用,
1037
+ * decide-ready operator queue),**不是** (a) inbox/tasks 的标量 `CheckpointSummary`(见下文 CheckpointSummary)。
1038
+ * 与标量形状的精确差(§7b/§4a):
1039
+ * - severity 嵌在 **`riskDescriptor.severity`** 内 —— 富行**无顶层 severity 标量**;
1040
+ * - 富行**无 `gateKind`**(消费方要类别时回退 `toolName`/`riskDescriptor.toolName`);
1041
+ * - 富行**无 `token`**(§1:resume capability token 是永不上线的 secret,server 自按 sessionId 解析);
1042
+ * - **无 `checkpointToken`**(§4a:server-INTERNAL,NOT surfaced 在 /v1/approvals 记录上;合规 client 只回传
1043
+ * boundCallId+boundInputHash 两件套,可选 checkpointToken→409 approval_stale 是 deprecated legacy 路径)。
1044
+ * 这是 boundCallId/boundInputHash decide 绑定的唯一 surface 处。契约说"可选字段缺则 OMIT 不是 null"。 */
535
1045
  export interface PendingCheckpoint {
1046
+ /** The decide handle: POST /v1/approvals/:sessionId/decide. */
536
1047
  sessionId: string;
1048
+ /** Principal / 多租户 owner scope; "_" = submitted without one. */
537
1049
  scope: string;
1050
+ /** The suspended run holding the session claim — the JOIN KEY to the task's trace
1051
+ * tool-call block (block.id == toolCallId → input = full args/question payload) and the context link. */
538
1052
  taskId?: string | null;
1053
+ /** Tool awaiting approval (AskUserQuestion = the question gate)。富行无 gateKind → 类别从 toolName 推。 */
539
1054
  toolName?: string | null;
540
1055
  toolCallId?: string | null;
1056
+ /** design/80 D-1 — the TWO binding values the human implicitly approves; the consumer reads them here and
1057
+ * echoes them VERBATIM into `decide` (TOCTOU guard: "I'm approving THIS pending action, not one swapped in").
1058
+ * Absent on checkpoints minted before D-1 → omit from decide (server falls back to the legacy resolve).
1059
+ * = `toolCallId` of the action the human saw (the bound call). */
541
1060
  boundCallId?: string;
1061
+ /** SERVER-MINTED OPAQUE sha256 over the pending action's args at mint time. Echo VERBATIM; NEVER recompute
1062
+ * (no canonical-JSON on the client — a false mismatch would fail-close a legitimate approval). It binds the
1063
+ * input the human SAW, NOT any `updatedInput` (which is applied AFTER binding, design/37 last-wins). */
542
1064
  boundInputHash?: string;
1065
+ /** The pending tool call's args (post-hook), REDACTED + size-bounded by the producer:
1066
+ * for a tool gate the write payload, for an AskUserQuestion the question itself. Lets an approval card
1067
+ * render WITHOUT an N+1 `trace.turns` fetch per item. Oversized → `{ truncated, bytes }`. NEVER a
1068
+ * capability token. `null`/absent = checkpoint suspended before this field existed → fall back to the
1069
+ * trace join (block.id == toolCallId). */
543
1070
  input?: unknown;
544
1071
  createdAt: number;
1072
+ /** epoch ms; expired checkpoints are reaped. */
545
1073
  deadline?: number | null;
1074
+ /** §7(b) — 富行的**完整 RiskDescriptor 对象**;**severity 在此处**(无顶层 severity 标量)。
1075
+ * axes/toolName/summary/touchedPaths 是引擎内部投影出的风险画像。缺则 OMIT(早期 checkpoint 可能无)。 */
546
1076
  riskDescriptor?: {
547
1077
  severity?: 1 | 2 | 3 | 4 | 5;
548
1078
  axes?: Record<string, unknown>;
@@ -552,10 +1082,17 @@ export interface PendingCheckpoint {
552
1082
  };
553
1083
  [k: string]: unknown;
554
1084
  }
1085
+ /** Session audit (`GET /v1/sessions/:id`) — true shape. `messages` = CURRENT model context
1086
+ * (older history folded into a summary message); can be LARGE — lazy-expand in UIs.
1087
+ * With window params (server ≥1.162 four-face, board [611]) the response additionally carries
1088
+ * `window` — ABSENT on an old engine (<1.162 strips the query before routing and returns the
1089
+ * full record): probe "no `window` in the response" to degrade honestly, never error. */
555
1090
  export interface SessionRecord {
556
1091
  sessionId: string;
557
1092
  owner?: string | null;
1093
+ /** ISO timestamp (unlike approvals' epoch-ms). */
558
1094
  createdAt: string;
1095
+ /** Compaction window floor; null = never compacted. */
559
1096
  floorEntryId?: string | null;
560
1097
  thinkingLevel?: string;
561
1098
  model?: {
@@ -563,15 +1100,24 @@ export interface SessionRecord {
563
1100
  modelId: string;
564
1101
  } | null;
565
1102
  messages: unknown[];
1103
+ /** Present ONLY on a windowed read (`tail`/`before`) against server ≥1.162. */
566
1104
  window?: SessionWindow;
1105
+ /** server ≥1.220 ([1023]①): the session's prompt-epoch pin (additive; absent = pre-epoch session
1106
+ * OR an older engine — never null). The typed entry is NOT an LLM message, so it never appears
1107
+ * in `messages`. */
567
1108
  promptEpoch?: PromptEpoch;
568
1109
  [k: string]: unknown;
569
1110
  }
1111
+ /** The `window` companion of a windowed session read: `messages` is the slice
1112
+ * `[offset, offset+messages.length)` of `total`. `offset` is stable within one `floorEntryId`
1113
+ * generation — compaction swaps the generation (floorEntryId changes) ⇒ re-pull from scratch. */
570
1114
  export interface SessionWindow {
571
1115
  offset: number;
572
1116
  total: number;
573
1117
  [k: string]: unknown;
574
1118
  }
1119
+ /** `GET /v1/sessions/:id?message=<index>` — the single-message expand leg (server ≥1.162).
1120
+ * Out-of-range index → 404 (typed NotFoundError; wire body carries `total`). */
575
1121
  export interface SessionMessageEnvelope {
576
1122
  sessionId: string;
577
1123
  floorEntryId?: string | null;
@@ -579,31 +1125,63 @@ export interface SessionMessageEnvelope {
579
1125
  message: unknown;
580
1126
  [k: string]: unknown;
581
1127
  }
1128
+ /** E16(shell-host sessionPicker;service `SessionSummary` plugins/tidb-run-store.ts:42,SHIPPED `6cbf61e`)—
1129
+ * `GET /v1/sessions` 列表行 = keyset 聚合一个 session 的 run 账本(**不是** TaskSummary 的单 run 行)。owner-scoped
1130
+ * (service 据 principal 自算;non-owner 不出现)。门B/CLI 的「会话/对话历史」picker 据此渲染(last activity + 最近
1131
+ * objective 预览 + 最近状态)。`objectivePreview` 已 service 侧脱敏 + 截断,真回 `null`(无 run 时)故保 `| null`。
1132
+ * 所有时间 ISO 串。permissive 开集容未来字段。 */
582
1133
  export interface SessionSummary {
583
1134
  sessionId: string;
1135
+ /** 租户/owner(ownerless session = null)。 */
584
1136
  owner: string | null;
1137
+ /** 最近一个 run 的创建时间(keyset 排序键)。 */
585
1138
  lastActivityAt: string;
1139
+ /** 该 session 第一个 run 的创建时间。 */
586
1140
  firstActivityAt: string;
1141
+ /** 该 session 下的 run 数。 */
587
1142
  runCount: number;
1143
+ /** 最近 run 的 objective 预览(service 脱敏 + 截断;无 run → null)。 */
588
1144
  objectivePreview: string | null;
1145
+ /** 最近 run 的状态("completed"/"running"/... 开放串)。 */
589
1146
  lastStatus: string;
1147
+ /** 🔴 K-5c(service SHIPPED 全后端:security.ts:19 + tidb/pg/file/memory/local-session-store)—— 最近 run 的 taskId,
1148
+ * = **一跳 live-tail re-attach 锚**:picker 选中会话 → 直接 `GET /v1/runs/:lastRunId/events?from=seq` 续 live 尾,
1149
+ * 免二次查。无 run → null(空会话)。running/suspended run 也会冒出来(noteTaskRun seam),故选中即可续在跑的尾。 */
590
1150
  lastRunId: string | null;
591
1151
  [k: string]: unknown;
592
1152
  }
1153
+ /** `GET /v1/sessions` 的分页信封(service handleSessionList,keyset)。`nextCursor` 缺 = 末页。 */
593
1154
  export interface SessionListPage {
594
1155
  sessions: SessionSummary[];
1156
+ /** 不透明 keyset 游标;原样回送 `?cursor=` 取下一页(绝不 parse)。缺 = 没有更多。 */
595
1157
  nextCursor?: string;
596
1158
  }
1159
+ /** E6(shell-host permissionMode;core `SessionPermissionRules` session-policy-store.ts:23,service `GET/PUT
1160
+ * /v1/sessions/:id/policy`,SHIPPED)—— operator 收紧的 per-session 工具权限规则(core 在 prepare-time SUBTRACT-only
1161
+ * 读它)。5 个开放可选 string[] 字段;读写均经 {@link StoredSessionRules}(带 `rev` OCC 键)。🔴 **tighten-only 不变式**
1162
+ * core 强制:普通(非 operator)写只能收紧(删 deny / 不能放宽 allowlist/allowDirs)→ 放宽 403 `loosen_forbidden`;
1163
+ * CAS `expectedRev` 不符 → 409 `conflict`;ownerless session → 409;non-owner → 404(无 existence oracle)。 */
597
1164
  export interface SessionPermissionRules {
1165
+ /** 设了 = 仅这些工具名放行(白名单收紧)。 */
598
1166
  toolAllow?: string[];
1167
+ /** 总禁的工具名(deny wins)。 */
599
1168
  toolDeny?: string[];
1169
+ /** 设了 = 写工具(Q6/core 1.161 起 CC 名 `Write`/`Edit`)仅可写这些目录内;不能路径约束的写工具(如 `Bash`)在它设了时被禁。RAW 存,run 时解析。 */
600
1170
  allowDirs?: string[];
1171
+ /** 设了 = 仅这些 bash 命令名(argv[0])放行。 */
601
1172
  commandAllow?: string[];
1173
+ /** 总禁的 bash 命令名(argv[0])。 */
602
1174
  commandDeny?: string[];
603
1175
  }
1176
+ /** {@link SessionPermissionRules} + store 盖的单调 `rev`(OCC 键)。GET/PUT 的 `{rules}` 信封里就是这个。
1177
+ * PUT 回送 `rev` 作下次 `expectedRev`(CAS)。 */
604
1178
  export interface StoredSessionRules extends SessionPermissionRules {
605
1179
  rev: number;
606
1180
  }
1181
+ /** E9(shell-host mcpStatus;core `McpServerStatus` core/mcp.ts:76,service `GET /v1/sessions/:id/mcp`,SHIPPED
1182
+ * core 1.124)—— 单 MCP server 的状态。🔴 core 不持久化 MCP 连接(task-scoped)→ 无「存的 session MCP 健康」;service
1183
+ * **按需 materialize**(fresh connect→list→dispose,fail-open)→ 这是 **materialization-time** 状态,非 live session
1184
+ * 健康(壳渲「as of <asOf>」)。`status` 仅 connected/failed(core 不发 disabled)。`error` service 已脱敏 + 限 200 字符。 */
607
1185
  export interface McpServerStatus {
608
1186
  name: string;
609
1187
  status: "connected" | "failed" | (string & {});
@@ -612,50 +1190,87 @@ export interface McpServerStatus {
612
1190
  version: string;
613
1191
  };
614
1192
  toolNames?: string[];
1193
+ /** 仅 failed 时;service redact + slice(200)。 */
615
1194
  error?: string;
616
1195
  [k: string]: unknown;
617
1196
  }
1197
+ /** `GET /v1/sessions/:id/mcp` 的信封(service server.ts:2640-2672)。`asOf` = THIS materialize 时刻(ISO);
1198
+ * `degraded:true` = materialize 超时/失败 → `servers` 空但非「无 MCP」(壳显「状态暂不可得」)。无 MCP 配置 → `servers:[]`。 */
618
1199
  export interface McpStatusPanel {
619
1200
  asOf: string;
620
1201
  servers: McpServerStatus[];
1202
+ /** materialize 超时/失败的降级标记(servers 空且 degraded 时 = 取不到,非「没有」)。 */
621
1203
  degraded?: boolean;
622
1204
  [k: string]: unknown;
623
1205
  }
1206
+ /** ONE session-tree entry as it crosses the sync wire — the SDK treats it as an OPAQUE payload (verbatim,
1207
+ * cross-backend stable ids/parents). It is core's `SessionTreeEntry`; the SDK only ever reads `.id` (for the
1208
+ * §7 id-set classify) and otherwise pipes it through untouched (the cloud re-validates the whole tree). */
624
1209
  export interface SyncEntry {
1210
+ /** Stable entry id, unique within a session (verbatim across backends — the §7 divergence key). */
625
1211
  id: string;
1212
+ /** Parent entry id, or null for a root. */
626
1213
  parentId?: string | null;
1214
+ /** Entry discriminator (message / leaf / compaction / …) — opaque to the SDK. */
627
1215
  type?: string;
628
1216
  [k: string]: unknown;
629
1217
  }
1218
+ /** A (principal, rules) record — one row of a session's policy across ALL principals (E6 `listBySession`).
1219
+ * Replayed verbatim on import (the cloud applies the E6 tighten-only gate). `principal` absent = the
1220
+ * session-default rules. */
630
1221
  export interface SessionRulesRecord {
631
1222
  principal?: string;
632
1223
  rules: StoredSessionRules;
633
1224
  }
1225
+ /** One E19 file snapshot keyed by a `SessionTreeEntry.id` — `manifest` = `[relPath, blobHash]` tuples. The blob
1226
+ * BYTES are NOT inlined (a turn's working tree can be tens of MiB → OOM/413); they ride the content-addressed
1227
+ * blob routes (GET …/snapshots/:key/blobs/:hash to pull, PUT …/blobs/:hash to push). */
634
1228
  export interface SyncSnapshot {
635
1229
  key: string;
636
1230
  manifest: Array<[string, string]>;
637
1231
  }
1232
+ /** One E18 resume-at anchor (eventId→entryId + its source owner). `owner` is RE-KEYED to the importing principal
1233
+ * on a PUSH (§9) — the local peer sends what it has; the cloud overwrites it. */
638
1234
  export interface SyncAnchor {
639
1235
  eventId: string;
640
1236
  entryId: string;
641
1237
  owner: string | null;
642
1238
  }
1239
+ /** `GET …/sync/manifest` → `{ manifest: SessionManifest }`. The THIN cross-backend snapshot: entry IDS (oldest-first,
1240
+ * NOT payloads — those stream via `/sync/entries`) + per-snapshot relPath→blobHash + policy + anchors + leaf. The
1241
+ * local peer feeds `entryIds` to {@link classifySyncRelationshipByIds} to decide fast-forward/fork BEFORE pulling
1242
+ * the entry stream + only the blob hashes it lacks. Mirrors session-sync.ts SessionManifest:213. */
643
1243
  export interface SessionManifest {
644
1244
  sessionId: string;
1245
+ /** The full durable log's entry IDS, oldest-first (verbatim, cross-backend stable). NOT the payloads. */
645
1246
  entryIds: string[];
1247
+ /** `entryIds.length` — the count the paired `/sync/entries` NDJSON trailer must report. */
646
1248
  entryCount: number;
1249
+ /** The session's current leaf entry id, or null. */
647
1250
  leafId: string | null;
648
1251
  snapshots: SyncSnapshot[];
649
1252
  policy: SessionRulesRecord[];
650
1253
  anchors: SyncAnchor[];
651
1254
  }
1255
+ /** The portable state of ONE session, ready to replay into another backend (mirrors session-sync.ts SessionBundle:193).
1256
+ * Blobs are deliberately NOT inlined — each snapshot carries only its `manifest`; the bytes stream through the
1257
+ * content-addressed blob routes. The SDK assembles this from a manifest + the streamed entries for a PUSH. */
652
1258
  export interface SessionBundle {
653
1259
  sessionId: string;
1260
+ /** The FULL durable conversation log, verbatim ids/parents/payload (oldest-first). */
654
1261
  entries: SyncEntry[];
655
1262
  snapshots: SyncSnapshot[];
656
1263
  policy: SessionRulesRecord[];
657
1264
  anchors: SyncAnchor[];
658
1265
  }
1266
+ /** §7 — how a SOURCE log relates to a DESTINATION log, decided over the entry-ID SETS (mirrors session-sync.ts
1267
+ * SyncRelation:95). A discriminated union the local peer reads to decide what a PUSH/PULL would do:
1268
+ * - `fresh` — dst has no such session → an unconditional fresh import.
1269
+ * - `identical` — the id sets are equal → a no-op.
1270
+ * - `fast_forward` — dst ⊊ src (src strictly ahead = clean append) → SAFE to apply; `newEntryIds` = the tail.
1271
+ * - `stale` — src ⊊ dst (src strictly behind) → applying LOSES dst entries → a conflict (`dstAheadBy`).
1272
+ * - `fork` — each side has ≥1 exclusive entry (true divergence) → a conflict; `commonAncestor` = the
1273
+ * deepest shared id (null if none), `srcExclusive`/`dstExclusive` = each side's extra ids. */
659
1274
  export type SyncRelation = {
660
1275
  relation: "fresh";
661
1276
  } | {
@@ -672,21 +1287,40 @@ export type SyncRelation = {
672
1287
  srcExclusive: string[];
673
1288
  dstExclusive: string[];
674
1289
  };
1290
+ /** The two conflicting relations (`fork`/`stale`) the cloud refuses on a PUSH without `{resolution:"overwrite-dst"}`
1291
+ * — the payload of the 409 typed {@link import("./errors.js").SyncConflictError}. */
675
1292
  export type SyncConflictRelation = Extract<SyncRelation, {
676
1293
  relation: "fork" | "stale";
677
1294
  }>;
1295
+ /** `POST …/sync/import` Phase-A result. A `fork`/`stale` without `overwrite-dst` → 409 (typed SyncConflictError),
1296
+ * never this. `identical` → `{ relation:"identical" }` with NO `stagingId` (the dst already holds the log; Phase B
1297
+ * is skipped). Anything that needs entries → `{ stagingId, relation }` (drive Phase B with the `stagingId`).
1298
+ * `relation` is the BARE classifier tag (server sends `relA.relation`, not the full object — server.ts:3037/2986). */
678
1299
  export interface ImportStaged {
1300
+ /** Present iff Phase B is needed (absent on `identical`). Feed it to `importEntries(...)`. */
679
1301
  stagingId?: string;
1302
+ /** The §7 relation tag classified at Phase A (`fresh` | `fast_forward` | `identical`). */
680
1303
  relation: SyncRelation["relation"];
681
1304
  }
1305
+ /** `POST …/sync/import/:stagingId/entries` (Phase B) commit result — `{ relation }` (the AUTHORITATIVE in-txn
1306
+ * re-classify tag; server.ts:3138). */
682
1307
  export interface ImportCommitted {
683
1308
  relation: SyncRelation["relation"];
684
1309
  }
1310
+ /** Synchronous ack for `POST /v1/runs/:id/cancel` (LIVE, service ced3d88). `status` is
1311
+ * "cancelling" (accepted) or a terminal status (idempotent no-op). NOT a RunStatus member. The run then
1312
+ * settles to `failed` + `errorCode:"cancelled"`. */
685
1313
  export interface CancelAck {
686
1314
  taskId: string;
687
1315
  status: string;
688
1316
  note?: string;
689
1317
  }
1318
+ /** Leader run (`POST /v1/leader`) — the **v2 leader pipeline** (E2B workers + git push), gated server-side
1319
+ * (`LEADER_ENABLED` + `REMOTE_EXEC=e2b`, both default OFF). Mode is a SERVER deploy flag, NOT a client choice:
1320
+ * `LEADER_FANOUT_ENABLED=true` (default) = router decides single-vs-decompose and CAN fan out to N workers
1321
+ * (= the value-HOLD correctness path); `=false` pins it to a deterministic single worker. ⚠️ This is NOT the
1322
+ * default door-B brain — **door B uses `/v1/tasks`+`/v1/runs`+`scenario`** (strong single, live today, no
1323
+ * E2B-leader machinery). Keep this resource as a clearly-labeled v2/optional path. See DIRECTION §1. */
690
1324
  export interface LeaderReceipt {
691
1325
  leaderRunId: string;
692
1326
  status: "running" | "completed" | "failed";
@@ -697,52 +1331,108 @@ export interface LeaderRecord {
697
1331
  result?: unknown;
698
1332
  error?: string;
699
1333
  }
1334
+ /** §1 CheckpointSummary —— core 对每个 PENDING checkpoint 的轻量投影(summarizeCheckpoint, 全 store 后端一致)。
1335
+ * inbox/总览 的共享行形状。可选字段缺则 OMIT 不是 null。🔴 只投影 severity 标量, **不带 riskDescriptor 对象**。 */
700
1336
  export interface CheckpointSummary {
1337
+ /** resume capability token(opaque; echo, 绝不 parse)。 */
701
1338
  token: string;
1339
+ /** 被暂停的 task/session id。 */
702
1340
  sessionId: string;
1341
+ /** 多租户 owner scope。 */
703
1342
  scope: string;
1343
+ /** 哪种暂停(6-arm 开集)。开放联合留 `(string & {})` 容未来新 arm。 */
704
1344
  gateKind: "human" | "irreversible_ask" | "resource_limit" | "needs_review" | "plan_review" | "task_done" | (string & {});
1345
+ /** MF-14 contentKind passthrough(@sema-agent/server 1.6.0 / core 1.150 checkpoint-store.d.ts:765)—— `needs_review`/
1346
+ * `suspended` gate 上 core 透传的内容类型;`"content_ask"` = 被 gate 的工具是 AskUserQuestion(让 shell 渲染问答式 UI
1347
+ * 而非普通审批)。开放联合容未来新 kind。缺省 = 普通 gate。 */
705
1348
  contentKind?: "content_ask" | (string & {});
1349
+ /** 确定性风险层 = inbox 排序键。**仅 human/irreversible_ask 有**; 其余无 → 排序须容 undefined。 */
706
1350
  severity?: 1 | 2 | 3 | 4 | 5;
1351
+ /** suspend 链上累计花费(资源账本附着时出现)。 */
707
1352
  spentMicroUsd?: number;
1353
+ /** awaiting-human SLA deadline(epoch ms)。 */
708
1354
  deadline?: number;
1355
+ /** §assistant-scheduler 归因(core 1.114.0 source-tag 持久化 + summarizeCheckpoint 投影自动带;the pinned wire contract)。
1356
+ * echo-only triage 显示 —— **core 门控不读、跨副本持久化带着、跨后端 byte-identical**。单收件箱跨任务聚合时,
1357
+ * 消费方据此显「这条 ask 属哪个任务/用户」。缺则 OMIT(旧 worker / 未持久化场景)。 */
1358
+ /** 发起此 ask 的任务身份(= 发起 ask 的 worker session id;delegated worker-unforgeable)。 */
709
1359
  sourceTaskId?: string;
1360
+ /** 发起此 ask 的 end-user principal(per-ask 用户归因;与多租户 `scope` 不同层 —— scope=租户命名空间, principal=具体用户)。 */
710
1361
  principal?: string;
1362
+ /** §assistant-scheduler 下批(service b96b76b):ask 创建时间(epoch ms)→ 面板显「挂了多久」。
1363
+ * 非轻量 summary 字段,inbox 端点并行 get 完整 Checkpoint best-effort 取;缺/过期 cp → OMIT(容缺降级)。 */
711
1364
  createdAt?: number;
712
1365
  }
1366
+ /** §2 GET /v1/assistant/inbox 的行 = CheckpointSummary + objective(从 task ctx 富化)。
1367
+ * objective 契约明确"`null` if unavailable"故保留 `| null`(不与"缺则 OMIT"冲突, 这是真的回 null 的字段)。
1368
+ * 已由 core listPending 按 severity 排序 —— 消费方**不要再排**。 */
713
1369
  export interface InboxRow extends CheckpointSummary {
714
1370
  objective?: string | null;
1371
+ /** 🔴 LIVE 契约偏差(实测,已 flag service):部署的 worker(42c7a65,≥6cd0164)
1372
+ * 的 `/v1/assistant/inbox` 实返**富 pending**(server.ts:1414 直接 spread `listPending()`,**没走 summarizeCheckpoint**),
1373
+ * 即 `severity` 藏在 **`riskDescriptor.severity`** 里、无顶层 `severity` 标量、无 `gateKind`、无 `token`,且带 decide 三绑定。
1374
+ * 这与契约文档「只 severity 标量、不上 riskDescriptor、有 gateKind/token」矛盾(文档自述"code wins")。
1375
+ * `assistant.inbox()` 防御性归一:severity 优先顶层标量(文档/未来态),缺则回退 `riskDescriptor.severity`(当前 live 态)——
1376
+ * service 修 handler 后顶层标量自动接管,前向兼容。下列字段标 optional 容当前富形状。 */
715
1377
  riskDescriptor?: {
716
1378
  severity?: 1 | 2 | 3 | 4 | 5;
717
1379
  axes?: Record<string, unknown>;
718
1380
  toolName?: string;
719
1381
  } | null;
720
1382
  toolName?: string | null;
1383
+ /** decide 三绑定(富 inbox 行直接带 → 可不回拉 /api/approvals 决策;opaque echo)。 */
721
1384
  boundCallId?: string;
722
1385
  boundInputHash?: string;
1386
+ /** §assistant-scheduler(core 1.114.0;the pinned wire contract)approval-suspend 时的 per-call 身份 = S3 D-1 精确锚。
1387
+ * 🔴 聚合单收件箱**必保** toolCallId —— 否则 decide 仅按 taskId+sessionId 在 boundCallId 缺时退化 first-match(D-1 锚定回归)。 */
723
1388
  toolCallId?: string;
1389
+ /** §assistant-scheduler 下批(service b96b76b):挂起工具调用的 args **脱敏预览**("这条 ask 关于什么")。
1390
+ * 🔴 server 侧已 `redactDeep` scrub 密钥族 + 限长 2KB(inbox owner-scoped,仅 ask 自己 principal/operator 见);
1391
+ * 仅 `tool_approval` gate 带 args,`resource_limit`/`plan_review` 无 args → `null`(容缺渲染)。client 只展示、不重算。 */
724
1392
  input?: unknown;
725
1393
  }
1394
+ /** §3 GET /v1/assistant/tasks 行内联的 gate。wire 上 severity/spentMicroUsd/deadline 形如 `4 | null` —
1395
+ * SDK 侧规约为 `?:number`(缺/null 都容忍, OMIT 优先)。整个 gate 在 wire 上可为 null → AssistantTask.gate 是 `AssistantGate | null`。 */
726
1396
  export interface AssistantGate {
1397
+ /** 同 gateKind 开集。 */
727
1398
  kind: string;
1399
+ /** wire 可能回 null, 容忍。 */
728
1400
  severity?: number;
729
1401
  spentMicroUsd?: number;
1402
+ /** epoch ms; wire 可能回 null, 容忍。 */
730
1403
  deadline?: number;
731
1404
  }
1405
+ /** §3 N-task 调度总览行 = run-store listRuns(owner) join 核心 scheduler seam listByScope。
1406
+ * Triage 序: needs-attention 优先, 再 severity DESC, 再 spend DESC(**core 已排, 不要再排**)。
1407
+ * 需 TiDB run store 否则 `{tasks:[]}`。⚠️ createdAt/updatedAt 是 **ISO 串**(与 inbox/§1 的 epoch-ms 不同)。 */
732
1408
  export interface AssistantTask {
733
1409
  taskId: string;
734
1410
  sessionId: string;
1411
+ /** §3 状态三态(service 源审计 fix):
1412
+ * - `running` — 在跑。
1413
+ * - `suspended` — 在 HITL 门上 durable 挂起(resource_limit / 人审 tool gate 等)→ 走 §4b resume / §4a decide。
1414
+ * - `needs_review` — **first-class triage 态**:plan_review / dry-run review park 持久化成此态(**非 suspended**;
1415
+ * 旧 handler filter 漏了它)。带 needsAttention:true + gate.kind=`plan_review`/`needs_review`(severity 缺)、
1416
+ * 排最前。🔴 解析走 §4c plan_review(POST /v1/assistant/tasks/:id/plan_review),**非 §4b resume**。
1417
+ * 注:与 L23 RunStatus 的 `needs_review`(design/80 D-0 dry-run TERMINAL 终态)语义不同 —— 那是 run 终态,
1418
+ * 这是调度总览行上的 park 态;同名不同轴。 */
735
1419
  status: "running" | "suspended" | "needs_review";
1420
+ /** = 在 HITL 门上 park(suspended 或 needs_review)。 */
736
1421
  needsAttention: boolean;
737
1422
  gate: AssistantGate | null;
1423
+ /** ISO 时间串。 */
738
1424
  createdAt: string;
739
1425
  updatedAt: string;
740
1426
  }
1427
+ /** §4c plan_review 请求体(3-state)。editedPlan 仅 decision==="edit" 时必带, 其余禁带(→ 400, BFF 也会守)。 */
741
1428
  export interface PlanReviewRequest {
742
1429
  decision: "approve" | "edit" | "reject";
1430
+ /** operator 改写后的 plan; REQUIRED iff decision==="edit", 否则禁带。 */
743
1431
  editedPlan?: string;
744
1432
  reason?: string;
745
1433
  }
1434
+ /** §4b/§4c/§4d 决策端点的轻量返回(resume/plan_review→200 {status}, preempt→202 {status})。
1435
+ * status 形如 "completed"|"preempting"|… —— 开放串, 不窄化。 */
746
1436
  export interface AssistantTaskStatus {
747
1437
  status: string;
748
1438
  }