@sema-agent/client-core 0.109.0 → 0.111.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/CHANGELOG.md +342 -0
  2. package/README.md +88 -32
  3. package/dist/abortableSleep.d.ts +7 -0
  4. package/dist/abortableSleep.js +37 -0
  5. package/dist/adapt/arms.js +45 -11
  6. package/dist/adapt/toolCards.d.ts +3 -1
  7. package/dist/adapt/toolCards.js +4 -2
  8. package/dist/adapter/activeRunSelfHeal.d.ts +39 -0
  9. package/dist/adapter/activeRunSelfHeal.js +171 -3
  10. package/dist/adapter/downstream/eventToSdkMessage.js +20 -15
  11. package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -0
  12. package/dist/adapter/downstream/terminalToSdkResult.js +11 -0
  13. package/dist/adapter/runStream.d.ts +5 -0
  14. package/dist/adapter/runStream.js +15 -3
  15. package/dist/attachmentRoute.d.ts +20 -0
  16. package/dist/attachmentRoute.js +39 -0
  17. package/dist/attachmentsWireCaps.js +1 -1
  18. package/dist/builtinOutputStyles.d.ts +12 -0
  19. package/dist/builtinOutputStyles.js +147 -0
  20. package/dist/compactionStatus.d.ts +9 -0
  21. package/dist/compactionStatus.js +29 -5
  22. package/dist/controlRouter.js +2 -1
  23. package/dist/coreValuePorts.d.ts +39 -1
  24. package/dist/coreValuePorts.js +10 -0
  25. package/dist/declared/supportFloorDeclared.js +1 -1
  26. package/dist/displayUntrusted.d.ts +1 -0
  27. package/dist/displayUntrusted.js +138 -14
  28. package/dist/engineErrorCodes.d.ts +3 -0
  29. package/dist/engineErrorCodes.js +3 -0
  30. package/dist/engineHealthFacts.d.ts +20 -0
  31. package/dist/engineHealthFacts.js +42 -1
  32. package/dist/engineHealthProbeVerdict.d.ts +23 -0
  33. package/dist/engineHealthProbeVerdict.js +115 -0
  34. package/dist/engineInlineTaskStats.d.ts +4 -3
  35. package/dist/engineInlineTaskStats.js +18 -2
  36. package/dist/engineNoticeCodes.d.ts +10 -0
  37. package/dist/engineNoticeCodes.js +36 -6
  38. package/dist/engineRepoint.d.ts +147 -0
  39. package/dist/engineRepoint.js +310 -0
  40. package/dist/engineRowRef.d.ts +3 -0
  41. package/dist/engineRowRef.js +13 -1
  42. package/dist/engineSessionMessages.d.ts +2 -1
  43. package/dist/engineSessionMessages.js +5 -0
  44. package/dist/engineSwapCrossing.d.ts +57 -0
  45. package/dist/engineSwapCrossing.js +297 -0
  46. package/dist/engineUnavailable.d.ts +44 -0
  47. package/dist/engineUnavailable.js +492 -0
  48. package/dist/errorSupplementRoles.js +2 -1
  49. package/dist/eventLeg.js +3 -3
  50. package/dist/fleet/fleetProjection.js +3 -2
  51. package/dist/generated/engineFactTables.d.ts +2 -0
  52. package/dist/generated/engineFactTables.js +12 -0
  53. package/dist/generated/sdkFactTables.d.ts +2 -1
  54. package/dist/generated/sdkFactTables.js +5 -0
  55. package/dist/generated/settingsSchemaTables.d.ts +4 -0
  56. package/dist/generated/settingsSchemaTables.js +1 -0
  57. package/dist/hitl/approvalAskers.d.ts +6 -0
  58. package/dist/hitl/approvalAskers.js +30 -0
  59. package/dist/hitl/approvalCardReasons.js +6 -3
  60. package/dist/hitl/approvalDelivery.d.ts +1 -0
  61. package/dist/hitl/approvalDelivery.js +1 -1
  62. package/dist/hitl/approvalRequestFrameReading.d.ts +7 -0
  63. package/dist/hitl/approvalRequestFrameReading.js +11 -0
  64. package/dist/hitl/approvalResolution.d.ts +9 -2
  65. package/dist/hitl/approvalResolution.js +6 -1
  66. package/dist/hitl/askGateWire.js +5 -8
  67. package/dist/hitl/automaticAnswerVerdict.js +2 -2
  68. package/dist/hitl/decisionConflict.js +6 -3
  69. package/dist/hitl/decisionRefusal.d.ts +2 -0
  70. package/dist/hitl/decisionRefusal.js +8 -8
  71. package/dist/hitl/decisionRefusalCarrier.d.ts +3 -0
  72. package/dist/hitl/decisionRefusalCarrier.js +348 -0
  73. package/dist/hitl/decisionSend.d.ts +10 -0
  74. package/dist/hitl/decisionSend.js +57 -17
  75. package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
  76. package/dist/hitl/editedApprovalAcceptance.js +26 -0
  77. package/dist/hitl/elicitationRefusal.d.ts +4 -0
  78. package/dist/hitl/elicitationRefusal.js +23 -0
  79. package/dist/hitl/frameRouter.d.ts +2 -2
  80. package/dist/hitl/frameRouter.js +12 -33
  81. package/dist/hitl/gateIdentity.d.ts +5 -0
  82. package/dist/hitl/gateIdentity.js +23 -0
  83. package/dist/hitl/gateLedger.d.ts +0 -4
  84. package/dist/hitl/gateLedger.js +0 -19
  85. package/dist/hitl/hitlBridge.d.ts +7 -0
  86. package/dist/hitl/hitlBridge.js +14 -8
  87. package/dist/hitl/hitlHostSurface.d.ts +3 -1
  88. package/dist/hitl/hitlHostSurface.js +14 -4
  89. package/dist/hitl/hostWithdrawal.d.ts +15 -0
  90. package/dist/hitl/hostWithdrawal.js +38 -0
  91. package/dist/hitl/localAllowRedemption.d.ts +67 -0
  92. package/dist/hitl/localAllowRedemption.js +256 -0
  93. package/dist/hitl/parkResolver.js +32 -13
  94. package/dist/hitl/persistedRulesWire.d.ts +16 -0
  95. package/dist/hitl/persistedRulesWire.js +72 -2
  96. package/dist/hitl/planReviewWire.d.ts +3 -0
  97. package/dist/hitl/planReviewWire.js +37 -10
  98. package/dist/hitl/policyDenyCause.d.ts +1 -1
  99. package/dist/hitl/policyDenyCause.js +1 -1
  100. package/dist/hitl/resumeRunningCard.d.ts +1 -0
  101. package/dist/hitl/resumeRunningCard.js +1 -0
  102. package/dist/hitl/screenCardCarriers.d.ts +15 -0
  103. package/dist/hitl/screenCardCarriers.js +41 -0
  104. package/dist/hitl/screenDecisionCards.d.ts +98 -0
  105. package/dist/hitl/screenDecisionCards.js +362 -0
  106. package/dist/hitl/sessionPolicyWire.js +6 -4
  107. package/dist/hitl/standingRows.d.ts +4 -1
  108. package/dist/hitl/standingRows.js +33 -1
  109. package/dist/hitl/toolApprovalWire.d.ts +64 -15
  110. package/dist/hitl/toolApprovalWire.js +470 -125
  111. package/dist/hooksWireCaps.js +31 -1
  112. package/dist/hostSettingNoticeArm.d.ts +3 -0
  113. package/dist/hostSettingNoticeArm.js +12 -0
  114. package/dist/hostTurnSettings.d.ts +13 -4
  115. package/dist/hostTurnSettings.js +150 -10
  116. package/dist/humanTurnRead.js +11 -1
  117. package/dist/i18n/messages.en.d.ts +212 -0
  118. package/dist/i18n/messages.en.js +217 -5
  119. package/dist/i18n/messages.zh.js +235 -5
  120. package/dist/i18n/translate.d.ts +3 -0
  121. package/dist/i18n/translate.js +78 -10
  122. package/dist/i18n/zh.d.ts +1 -0
  123. package/dist/i18n/zh.js +1 -0
  124. package/dist/index.d.ts +56 -16
  125. package/dist/index.js +40 -12
  126. package/dist/inheritEnvCapability.js +2 -0
  127. package/dist/inputAuthor.d.ts +16 -0
  128. package/dist/inputAuthor.js +44 -0
  129. package/dist/interactiveHalt.js +2 -1
  130. package/dist/interactiveInterrupt.js +20 -2
  131. package/dist/interruptRefusalNote.d.ts +2 -0
  132. package/dist/interruptRefusalNote.js +17 -0
  133. package/dist/liveModelCatalog.d.ts +2 -0
  134. package/dist/liveModelCatalog.js +23 -9
  135. package/dist/liveQuestionStore.d.ts +4 -1
  136. package/dist/liveQuestionStore.js +12 -3
  137. package/dist/localEngineSeatReading.d.ts +2 -2
  138. package/dist/localEngineSeatReading.js +5 -3
  139. package/dist/localEngineSpawn.d.ts +0 -7
  140. package/dist/localEngineSpawn.js +0 -92
  141. package/dist/localEngineStep.d.ts +2 -2
  142. package/dist/localEngineStep.js +2 -0
  143. package/dist/mcpEngineLeg.d.ts +3 -0
  144. package/dist/mcpEngineLeg.js +38 -1
  145. package/dist/mcpPanel.js +2 -0
  146. package/dist/mcpReconnect.d.ts +9 -1
  147. package/dist/mcpReconnect.js +124 -19
  148. package/dist/mcpWireCaps.js +1 -1
  149. package/dist/model/engineModelWords.d.ts +3 -0
  150. package/dist/model/engineModelWords.js +13 -0
  151. package/dist/model/subagentModelWord.d.ts +21 -2
  152. package/dist/model/subagentModelWord.js +100 -29
  153. package/dist/modelCapabilityProbe.js +7 -43
  154. package/dist/modsFace.d.ts +8 -1
  155. package/dist/modsFace.js +27 -0
  156. package/dist/notifications.d.ts +36 -6
  157. package/dist/notifications.js +170 -20
  158. package/dist/ownKey.d.ts +6 -5
  159. package/dist/ownKey.js +31 -7
  160. package/dist/peerFrames.d.ts +40 -2
  161. package/dist/peerFrames.js +158 -3
  162. package/dist/pendingUserRow.d.ts +4 -0
  163. package/dist/pendingUserRow.js +16 -0
  164. package/dist/permissionsDeclaration.d.ts +1 -0
  165. package/dist/permissionsDeclaration.js +11 -1
  166. package/dist/planReviewCardFacts.d.ts +3 -0
  167. package/dist/planReviewCardFacts.js +52 -2
  168. package/dist/pluginHooksWire.d.ts +10 -1
  169. package/dist/pluginHooksWire.js +96 -7
  170. package/dist/printToolResultFrame.js +4 -2
  171. package/dist/promptBlockedCopy.js +11 -6
  172. package/dist/promptSuggestionBatch.d.ts +7 -0
  173. package/dist/promptSuggestionBatch.js +9 -0
  174. package/dist/promptSuggestionsTail.d.ts +39 -0
  175. package/dist/promptSuggestionsTail.js +116 -0
  176. package/dist/replayBody.js +10 -2
  177. package/dist/request/taskRequest.d.ts +5 -0
  178. package/dist/request/taskRequest.js +142 -21
  179. package/dist/requestCoordinate.d.ts +1 -0
  180. package/dist/requestCoordinate.js +13 -0
  181. package/dist/resumeRefusalCopy.d.ts +1 -3
  182. package/dist/resumeRefusalCopy.js +2 -1
  183. package/dist/retryStatus.d.ts +2 -2
  184. package/dist/retryStatus.js +2 -0
  185. package/dist/rewindArchiveReading.js +4 -4
  186. package/dist/runCancelContext.d.ts +2 -1
  187. package/dist/runCancelContext.js +1 -0
  188. package/dist/runPermissionModeSwitch.js +2 -2
  189. package/dist/scenarioRefusal.js +11 -13
  190. package/dist/scenarioSkills.js +11 -6
  191. package/dist/seam.d.ts +27 -2
  192. package/dist/seam.js +17 -1
  193. package/dist/seatContract.d.ts +189 -12
  194. package/dist/seatContract.js +401 -9
  195. package/dist/sessionBackground.js +2 -1
  196. package/dist/sessionBackgroundHandoff.js +2 -1
  197. package/dist/sessionCostReading.d.ts +70 -0
  198. package/dist/sessionCostReading.js +150 -0
  199. package/dist/sessionEngine.d.ts +2 -0
  200. package/dist/sessionEngine.js +111 -0
  201. package/dist/sessionHooksRoster.d.ts +4 -0
  202. package/dist/sessionHooksRoster.js +158 -0
  203. package/dist/sessionMemoryStatus.d.ts +2 -1
  204. package/dist/sessionMemoryStatus.js +2 -2
  205. package/dist/sessionReadRedaction.d.ts +7 -0
  206. package/dist/sessionReadRedaction.js +26 -0
  207. package/dist/sessionSyncFileHistory.d.ts +4 -0
  208. package/dist/sessionSyncFileHistory.js +27 -0
  209. package/dist/settingsHooksSalvage.js +2 -1
  210. package/dist/sseIdleTriage.d.ts +13 -1
  211. package/dist/sseIdleTriage.js +25 -6
  212. package/dist/storeDurabilityWord.d.ts +15 -0
  213. package/dist/storeDurabilityWord.js +18 -0
  214. package/dist/storePostureCapability.d.ts +7 -3
  215. package/dist/storePostureCapability.js +69 -39
  216. package/dist/subagent/engineSubagentResume.js +2 -2
  217. package/dist/subagent/engineSubagentTail.js +8 -1
  218. package/dist/subagentContentStore.d.ts +11 -0
  219. package/dist/subagentContentStore.js +28 -2
  220. package/dist/terminalStatuses.d.ts +1 -0
  221. package/dist/terminalStatuses.js +4 -1
  222. package/dist/toolResult.d.ts +1 -0
  223. package/dist/toolResult.js +2 -0
  224. package/dist/turnFailurePresentation.js +9 -2
  225. package/dist/typePins.d.ts +11 -0
  226. package/dist/usageAnalytics.d.ts +17 -0
  227. package/dist/usageAnalytics.js +44 -2
  228. package/dist/userAttachmentEnvelope.d.ts +2 -1
  229. package/dist/userAttachmentEnvelope.js +10 -0
  230. package/dist/wireErrorTriage.js +2 -1
  231. package/dist/wireFailureShape.d.ts +6 -5
  232. package/dist/wireFailureShape.js +150 -38
  233. package/dist/wireRefusalCopy.d.ts +16 -5
  234. package/dist/wireRefusalCopy.js +119 -86
  235. package/docs/INTEGRATION-CLIENTS.md +4228 -21
  236. package/package.json +7 -3
@@ -62,8 +62,16 @@ export function runRowSentenceOf(carrier) {
62
62
  return undefined;
63
63
  }
64
64
  }
65
+ function isPlainObjectLike(v) {
66
+ try {
67
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
68
+ }
69
+ catch {
70
+ return false;
71
+ }
72
+ }
65
73
  export function doneResultView(result) {
66
- if (typeof result !== 'object' || result === null || Array.isArray(result))
74
+ if (!isPlainObjectLike(result))
67
75
  return { replay: false, receipt: false, body: result };
68
76
  const replay = guarded(result, 'replay') === true;
69
77
  const engine = engineResultLayerOf(result);
@@ -80,7 +88,7 @@ export function doneResultView(result) {
80
88
  return { replay, receipt: true, body: Object.freeze(view) };
81
89
  }
82
90
  export function isReplayedTerminal(frame) {
83
- if (frame === null || typeof frame !== 'object' || Array.isArray(frame))
91
+ if (!isPlainObjectLike(frame))
84
92
  return false;
85
93
  if (guarded(frame, 'type') !== 'done')
86
94
  return false;
@@ -179,5 +179,10 @@ export interface LiveDefaultsInput {
179
179
  mockScenarioKeys?: ReadonlySet<string>;
180
180
  }
181
181
  export declare function applyLiveRequestDefaults(req: TaskRequestLike, host: LiveDefaultsInput): TaskRequestLike;
182
+ export interface LiveRequestDefaultsResult {
183
+ readonly request: TaskRequestLike;
184
+ readonly notices: readonly HostSettingNotice[];
185
+ }
186
+ export declare function applyLiveRequestDefaultsWithNotices(req: TaskRequestLike, host: LiveDefaultsInput): LiveRequestDefaultsResult;
182
187
  export type BuiltTaskRequest = TaskRequest;
183
188
  export declare function unregisteredRequestKeys(req: TaskRequestLike, lane: RequestLane): string[];
@@ -8,9 +8,9 @@ import { PROJECT_MEMORY_DISABLED } from '../projectMemory.js';
8
8
  import { frameFamiliesJudgementOf } from '../approvalFrameFamilies.js';
9
9
  import { outputStyleSeatAdmitted } from '../outputStyleSeatCapability.js';
10
10
  import { refuseBadApprovalReach } from '../approvalReachWire.js';
11
- import { HOST_SUPPLIED_KEYS, UNWIRED_HOST_TURN_SETTINGS, buildHostTurnSettings, hostIntakeSnapshotOf, hostFileHistoryRestoreNotice, hostProjectionNotice, hostTurnSettingsOf, intersectHostHooks, rethrowHostResolvedDeferred, hostSettingsRefusedError, } from '../hostTurnSettings.js';
11
+ import { HOST_SUPPLIED_KEYS, UNWIRED_HOST_TURN_SETTINGS, buildHostTurnSettings, hostIntakeSnapshotOf, hostFileHistoryRestoreNotice, hostProjectionNotice, hostStyleNotAppliedNotice, hostTurnSettingsOf, hookEnvNamesOf, intersectHostHooks, rethrowHostResolvedDeferred, hostSettingsRefusedError, } from '../hostTurnSettings.js';
12
12
  import { SUBMISSION_ORIGINS, SUBMISSION_SURFACES, SUBMISSION_TOOLS, submissionAxesOf, } from './submissionIdentity.js';
13
- import { withAssemblyRefusal } from '../wireFailureShape.js';
13
+ import { slotReadOf, withAssemblyRefusal } from '../wireFailureShape.js';
14
14
  import { isPlainRecord, materializeJsonFaithful, shapeTag } from '../jsonFaithful.js';
15
15
  export const REQUEST_FIELD_MATRIX = [
16
16
  { field: 'objective', lanes: ['interactive', 'print', 'utility'], live: false, why: '本 turn 的真实输入,每条车道都必需', whyUtilityLane: '恒座:三条车道都必须带上本次提交的模型面输入' },
@@ -29,6 +29,7 @@ export const REQUEST_FIELD_MATRIX = [
29
29
  { field: 'mcpServers', lanes: ['interactive', 'print'], live: true, why: '本地 .mcp.json 投影;service 单用户门决定是否兑现', whyUtilityLane: '无座:MCP 服务挂的是工具,与零工具面矛盾' },
30
30
  { field: 'settings.webSearch', lanes: ['interactive', 'print'], live: true, why: 'SEMA_WEBSEARCH_* / settings.json;per-request 配置赢过部署 env', whyUtilityLane: '无座:联网检索是一只工具,与零工具面矛盾' },
31
31
  { field: 'settings.hooks', lanes: ['interactive', 'print'], live: true, why: '[495]① 用户 settings 文件 hooks 逐字上 wire', whyUtilityLane: '无座:hook 挂在工具门上(零工具面没有门),而且 side-channel 是壳自己的提交,不该继承用户那份 hook 表' },
32
+ { field: 'settings.env', lanes: ['interactive', 'print'], live: true, why: '交引擎执行的 http hook 头 `$NAME` 插值的那一层环境(服务端 `settings.env`:引擎 hook 环境 = 十二名基础名单 + 本键;同一份也进引擎命令 hook 与单用户宿主车道的会话 shell 环境 —— 服务端的设计)。两条用户车道都把 hooks 交给引擎执行 ⇒ 都有座,与 settings.hooks 同座。值只由宿主自供项入口按 hooks 那一行算出:名集 = 这一发请求体 hooks 里引擎点亮的事件下 http 条目 allowedEnvVars 之并 ∩ 宿主环境在场,值 = 环境原值,名集空 ⇒ 键缺席;不按凭据名预筛(凭据判官只在服务端:400 request.env_credential_refused)', whyUtilityLane: '无座:与 settings.hooks 同理由 —— side-channel 不带用户的 hook 表,就没有要插值的 http 头;带上它只会把宿主环境里的值交给一条零工具面的提交' },
32
33
  { field: 'settings.approvalFrameFamilies', lanes: ['interactive', 'print'], live: true, why: '这条运行的客户端渲得了哪些审批开卡帧族的**逐运行声明**(服务端提交体 `settings.approvalFrameFamilies`:词数组,值族闭集 tool_approval / approval_request;一条运行只在声明含服务端呈的那一族时才开审批卡,不含 ⇒ 问当场交无人值守政策口、不出卡)。两条用户车道都有审批腿(交互面出卡答人;`-p` 面交宿主的审批口),都得声明;🔴 只在能力读数 confirmed(受理位 `taskSettings.approvalFrameFamilies` 恒真 ∧ 值族位合格)时由装配口自己铸,老服务端(受理位缺席)对表外 settings 子键整条 400', whyUtilityLane: '无座:side-channel 强制零工具面(`excludeAllTools`),没有门控调用、不会问审批 ⇒ 声明没有对象;带上它只会在不认识这一键的老服务端上给这条提交多一种 400' },
33
34
  { field: 'settings.<resolved>', lanes: ['interactive', 'print'], live: true, why: 'settings resolver 的 effective 快照(hooks/env/model + 已解析权限投影)。两条车道同源:交互面 replEntry / print 面 printModeEngine 各跑一遍同一个 resolver,产物经同一个 buildWireSettingsStamp 投影。开放集(子键不可枚举)⇒ unregisteredRequestKeys 放行本车道 settings 的**表外**子键,但表内异车道子键仍点名', whyUtilityLane: '无座:这一位是**开放集 spread**(子键原样即 wire 键),摊开的是用户 settings 的已解析面(权限 / env / 模型)。side-channel 是壳自己的提交:摊上去既无用(零工具面没有工具门求值权限)又把用户的配置面带进了一条他没参与的提交。🔴 无座 ⇒ 本车道整只快照不产。🔴 **本行无座的前提由构造期校验兜住**:剥掉的是用户显式的 deny / ask,所以 `refuseUtilityWithoutToolUnload` 强制这条车道必须带字面 `excludeAllTools: true` —— 否则产出会是一条「既没卸工具、又没带用户 deny」的请求(比无人值守车道同一份输入更宽)' },
34
35
  { field: 'repo', lanes: ['interactive', 'print'], live: true, why: 'scan/code-review 场景的仓库坐标(passthrough;server 是权威校验方,本层不铸第二判官)', whyUtilityLane: '无座:场景键;side-channel 不走场景' },
@@ -217,6 +218,7 @@ const SETTINGS_KEY_ROUTES = {
217
218
  webSearch: row('settings.webSearch'),
218
219
  ultracode: row('settings.ultracode'),
219
220
  hooks: row('settings.hooks'),
221
+ env: row('settings.env'),
220
222
  approvalFrameFamilies: row('settings.approvalFrameFamilies'),
221
223
  outputStyle: { via: 'always' },
222
224
  };
@@ -520,27 +522,63 @@ export function refilterHostSettings(request, fresh, lane) {
520
522
  const base = tight.request;
521
523
  const tightened = tight.tightened;
522
524
  const settings = base.settings;
523
- if (!isPlainRecord(settings) || !Object.hasOwn(settings, 'hooks'))
525
+ if (!isPlainRecord(settings))
524
526
  return Object.freeze({ kind: 'send', request: base, hooksDropped: 0, tightened });
525
- const disposition = intake.dispositions['settings.hooks'];
526
- if (disposition === 'unwired')
527
- return Object.freeze({ kind: 'send', request: base, hooksDropped: 0, tightened });
528
- const now = intake.carried.hooks;
529
- const sentHooks = settings.hooks;
530
- if (!isPlainRecord(sentHooks))
531
- return Object.freeze({ kind: 'refuse', notice: refuseNotice() });
532
- const cut = intersectHostHooks(sentHooks, now);
533
- if (!cut.judged)
534
- return Object.freeze({ kind: 'refuse', notice: refuseNotice() });
535
- if (cut.dropped === 0)
527
+ const unjudged = () => Object.freeze({ kind: 'refuse', notice: refuseNotice() });
528
+ let nextSettings = settings;
529
+ let hooksDropped = 0;
530
+ let finalHooks;
531
+ if (Object.hasOwn(settings, 'hooks')) {
532
+ const sentHooks = settings.hooks;
533
+ if (intake.dispositions['settings.hooks'] === 'unwired')
534
+ finalHooks = sentHooks;
535
+ else {
536
+ const now = intake.carried.hooks;
537
+ if (!isPlainRecord(sentHooks))
538
+ return unjudged();
539
+ const cut = intersectHostHooks(sentHooks, now);
540
+ if (!cut.judged)
541
+ return unjudged();
542
+ finalHooks = cut.hooks;
543
+ if (cut.dropped > 0) {
544
+ const { hooks: _sentHooks, ...restSettings } = settings;
545
+ void _sentHooks;
546
+ nextSettings = cut.hooks === undefined ? restSettings : { ...restSettings, hooks: cut.hooks };
547
+ hooksDropped = cut.dropped;
548
+ }
549
+ }
550
+ }
551
+ const nowEnv = intake.carried.env;
552
+ const envUnwired = intake.dispositions['settings.env'] === 'unwired';
553
+ const envMaybeAdded = nowEnv !== undefined && !envUnwired && hostRefuseRowSeated('settings.env', lane, true);
554
+ const hasSentEnv = Object.hasOwn(nextSettings, 'env');
555
+ if (hasSentEnv || envMaybeAdded) {
556
+ const sentEnv = hasSentEnv ? nextSettings.env : {};
557
+ if (!isPlainRecord(sentEnv))
558
+ return unjudged();
559
+ let names;
560
+ try {
561
+ names = hookEnvNamesOf(finalHooks);
562
+ }
563
+ catch {
564
+ return unjudged();
565
+ }
566
+ const sentKeys = Object.keys(sentEnv);
567
+ const kept = sentKeys.filter((k) => names.includes(k) && (envUnwired || (nowEnv !== undefined && Object.hasOwn(nowEnv, k))));
568
+ const added = envMaybeAdded && nowEnv !== undefined ? names.filter((n) => !sentKeys.includes(n) && Object.hasOwn(nowEnv, n)) : [];
569
+ if (kept.length !== sentKeys.length || added.length > 0) {
570
+ const { env: _sentEnv, ...restSettings } = nextSettings;
571
+ void _sentEnv;
572
+ const rows = [...kept.map((k) => [k, sentEnv[k]]), ...added.map((n) => [n, nowEnv?.[n]])];
573
+ nextSettings = rows.length === 0 ? restSettings : { ...restSettings, env: Object.fromEntries(rows) };
574
+ }
575
+ }
576
+ if (nextSettings === settings)
536
577
  return Object.freeze({ kind: 'send', request: base, hooksDropped: 0, tightened });
537
- const { hooks: _sentHooks, ...restSettings } = settings;
538
- void _sentHooks;
539
- const nextSettings = cut.hooks === undefined ? restSettings : { ...restSettings, hooks: cut.hooks };
540
578
  const { settings: _sentSettings, ...restRequest } = base;
541
579
  void _sentSettings;
542
580
  const next = Object.keys(nextSettings).length > 0 ? { ...restRequest, settings: nextSettings } : restRequest;
543
- return Object.freeze({ kind: 'send', request: next, hooksDropped: cut.dropped, tightened });
581
+ return Object.freeze({ kind: 'send', request: next, hooksDropped, tightened });
544
582
  }
545
583
  export const MEMORY_CAPTURE_OFF = 'off';
546
584
  export function memoryCaptureDeclarationField(declared) {
@@ -924,6 +962,7 @@ export function assembleTaskRequest(input, laneOrIdentity) {
924
962
  hooks: intake.carried.hooks,
925
963
  outputStyle: intake.carried.outputStyle,
926
964
  approvalFrameFamilies: approvalFamilies,
965
+ env: intake.carried.env,
927
966
  };
928
967
  refuseBadMemoryCapture(memoryCaptureIn);
929
968
  refuseBadMaxCostUsd(maxCostUsdIn);
@@ -1080,6 +1119,7 @@ export function assembleTaskRequest(input, laneOrIdentity) {
1080
1119
  ...(onSetting('webSearch') ? { webSearch: s.webSearch } : {}),
1081
1120
  ...(onSetting('ultracode') ? { ultracode: s.ultracode } : {}),
1082
1121
  ...(onSetting('hooks') ? { hooks: s.hooks } : {}),
1122
+ ...(onSetting('env') ? { env: { ...s.env } } : {}),
1083
1123
  ...(s.outputStyle !== undefined ? { outputStyle: s.outputStyle } : {}),
1084
1124
  ...(onSetting('approvalFrameFamilies') ? { approvalFrameFamilies: [...(s.approvalFrameFamilies ?? [])] } : {}),
1085
1125
  };
@@ -1228,6 +1268,74 @@ export function thinkingTurnProjection(input) {
1228
1268
  return projectThinkingCore({ lane, latch, strength, floor, ultracodeStamped: seated && inPlay('settings.ultracode', ultracode) && ultracode === true });
1229
1269
  }
1230
1270
  export function applyLiveRequestDefaults(req, host) {
1271
+ return liveRequestDefaultsOf(req, host).request;
1272
+ }
1273
+ export function applyLiveRequestDefaultsWithNotices(req, host) {
1274
+ return liveRequestDefaultsOf(req, host);
1275
+ }
1276
+ const SELF_KNOWLEDGE_JOIN = '\n\n';
1277
+ const OUTPUT_STYLE_MAX_CHARS = 16384;
1278
+ function selfKnowledgeSeatOf(block, readBody) {
1279
+ if (typeof block !== 'string')
1280
+ return { kind: 'set', value: block };
1281
+ let body;
1282
+ const read = readBody();
1283
+ if (read !== undefined) {
1284
+ if (read.presence === 'unreadable')
1285
+ return { kind: 'set', value: block, notice: hostStyleNotAppliedNotice('unreadable', OUTPUT_STYLE_MAX_CHARS) };
1286
+ if (read.presence === 'present' && read.value !== undefined && read.value !== null) {
1287
+ if (typeof read.value !== 'string')
1288
+ return { kind: 'set', value: block, notice: hostStyleNotAppliedNotice('unreadable', OUTPUT_STYLE_MAX_CHARS) };
1289
+ if (read.value.trim() !== '')
1290
+ body = read.value;
1291
+ }
1292
+ }
1293
+ if (body === undefined)
1294
+ return { kind: 'set', value: block };
1295
+ let merged;
1296
+ let separable = false;
1297
+ if (block.trim() === '' || body === block || body.startsWith(block + SELF_KNOWLEDGE_JOIN)) {
1298
+ merged = body;
1299
+ }
1300
+ else if (block.endsWith(SELF_KNOWLEDGE_JOIN + body)) {
1301
+ merged = block;
1302
+ }
1303
+ else {
1304
+ merged = block + SELF_KNOWLEDGE_JOIN + body;
1305
+ separable = true;
1306
+ }
1307
+ if (merged.length <= OUTPUT_STYLE_MAX_CHARS)
1308
+ return { kind: 'set', value: merged };
1309
+ const notice = hostStyleNotAppliedNotice('oversize', OUTPUT_STYLE_MAX_CHARS);
1310
+ return separable && block.length <= OUTPUT_STYLE_MAX_CHARS ? { kind: 'set', value: block, notice } : { kind: 'omit', notice };
1311
+ }
1312
+ const styleBodyReadOf = (settings) => () => typeof settings === 'object' && settings !== null ? slotReadOf(settings, 'outputStyle') : undefined;
1313
+ const appendBodyReadOf = (req) => () => typeof req === 'object' && req !== null ? slotReadOf(req, 'appendSystemPrompt') : undefined;
1314
+ function settingsWithStyleSeat(settings, seat) {
1315
+ const next = {};
1316
+ const put = (key, value) => {
1317
+ Object.defineProperty(next, key, { value, writable: true, enumerable: true, configurable: true });
1318
+ };
1319
+ const src = Object(settings);
1320
+ let placed = false;
1321
+ for (const key of Reflect.ownKeys(src)) {
1322
+ const d = Object.getOwnPropertyDescriptor(src, key);
1323
+ if (d === undefined || d.enumerable !== true)
1324
+ continue;
1325
+ if (key === 'outputStyle') {
1326
+ if (seat.kind === 'set')
1327
+ put(key, seat.value);
1328
+ placed = true;
1329
+ continue;
1330
+ }
1331
+ put(key, src[key]);
1332
+ }
1333
+ if (!placed && seat.kind === 'set')
1334
+ put('outputStyle', seat.value);
1335
+ return Reflect.ownKeys(next).length > 0 ? next : undefined;
1336
+ }
1337
+ function liveRequestDefaultsOf(req, host) {
1338
+ const notices = [];
1231
1339
  const out = { ...req };
1232
1340
  if (out.cwd == null && host.cwd !== undefined)
1233
1341
  out.cwd = host.cwd;
@@ -1249,11 +1357,24 @@ export function applyLiveRequestDefaults(req, host) {
1249
1357
  }
1250
1358
  if (host.selfKnowledge !== undefined) {
1251
1359
  if (host.appendSystemPromptCapable) {
1252
- out.appendSystemPrompt = host.selfKnowledge.forAppend;
1360
+ const seat = selfKnowledgeSeatOf(host.selfKnowledge.forAppend, appendBodyReadOf(req));
1361
+ if (seat.notice !== undefined)
1362
+ appendOwnElement(notices, seat.notice);
1363
+ if (seat.kind === 'set')
1364
+ out.appendSystemPrompt = seat.value;
1365
+ else
1366
+ delete out.appendSystemPrompt;
1253
1367
  }
1254
1368
  else {
1255
1369
  const settings = (out.settings ?? {});
1256
- out.settings = { ...settings, outputStyle: host.selfKnowledge.forOutputStyle };
1370
+ const seat = selfKnowledgeSeatOf(host.selfKnowledge.forOutputStyle, styleBodyReadOf(settings));
1371
+ if (seat.notice !== undefined)
1372
+ appendOwnElement(notices, seat.notice);
1373
+ const next = settingsWithStyleSeat(settings, seat);
1374
+ if (next !== undefined)
1375
+ out.settings = next;
1376
+ else
1377
+ delete out.settings;
1257
1378
  }
1258
1379
  }
1259
1380
  if (out.outputStyle === undefined && host.outputStyleSeat !== undefined && outputStyleSeatAdmitted(host.outputStyleSeatReading)) {
@@ -1276,7 +1397,7 @@ export function applyLiveRequestDefaults(req, host) {
1276
1397
  delete out.sessionId;
1277
1398
  }
1278
1399
  refuseRequireExistingWithoutSession(out.requireExistingSession, out.sessionId, 'applyLiveRequestDefaults');
1279
- return out;
1400
+ return Object.freeze({ request: out, notices: Object.freeze(notices) });
1280
1401
  }
1281
1402
  export function unregisteredRequestKeys(req, lane) {
1282
1403
  const liveDefaults = liveDefaultKeyNames();
@@ -0,0 +1 @@
1
+ export declare function requestCoordinateText(root: string, segs: readonly (string | number)[], label?: (seg: string) => string): string;
@@ -0,0 +1,13 @@
1
+ const PLAIN_SEGMENT = /^[^.[\]"\s\p{Cc}]+$/u;
2
+ export function requestCoordinateText(root, segs, label) {
3
+ let out = root;
4
+ for (const seg of segs) {
5
+ if (typeof seg === 'number') {
6
+ out += `[${seg}]`;
7
+ continue;
8
+ }
9
+ const shown = label === undefined ? seg : label(seg);
10
+ out += PLAIN_SEGMENT.test(shown) ? `.${shown}` : `[${JSON.stringify(shown)}]`;
11
+ }
12
+ return out;
13
+ }
@@ -43,12 +43,10 @@ export interface ParkedResumeStartupDetail {
43
43
  code: string;
44
44
  cause: ParkedResumeStartupCause;
45
45
  taskId?: string;
46
- startupCause?: ResumeStartupCause | ResumeCauseCoreAhead;
46
+ startupCause?: ResumeStartupCause;
47
47
  resendable: false;
48
48
  denyStaysOpen: true;
49
49
  }
50
- declare const RESUME_CAUSE_CORE_AHEAD: readonly ["transcript_corrupt"];
51
- type ResumeCauseCoreAhead = Exclude<(typeof RESUME_CAUSE_CORE_AHEAD)[number], ResumeStartupCause>;
52
50
  export declare function parkedResumeStartupFromError(err: unknown, decision?: ParkedResumeStartupDecision): ParkedResumeStartupDetail | null;
53
51
  export declare function parkedResumeStartupContent(detail: ParkedResumeStartupDetail, lang?: UiLanguage): string;
54
52
  export interface CheckpointUnsupportedVersionDetail {
@@ -132,7 +132,6 @@ function parkedResumeStartupCauseWord(err) {
132
132
  function isResumeStartupCause(v) {
133
133
  return typeof v === 'string' && CORE_RESUME_STARTUP_CAUSES.includes(v);
134
134
  }
135
- const RESUME_CAUSE_CORE_AHEAD = Object.freeze(['transcript_corrupt']);
136
135
  const _startupCausePin = true;
137
136
  void _startupCausePin;
138
137
  export function parkedResumeStartupFromError(err, decision) {
@@ -349,3 +348,5 @@ export function refusedParkBlockedContent(taskId, lane = 'interactive', lang) {
349
348
  return renderMessage(msg('resume.refusal.park.blockedPrint', { run, cancel: `POST /v1/runs/${runId ?? '<run id>'}/cancel` }), lang);
350
349
  return renderMessage(msg('resume.refusal.park.blockedInteractive', { run }), lang);
351
350
  }
351
+ const _pinRefusedPark = [true, true, true];
352
+ void _pinRefusedPark;
@@ -1,3 +1,4 @@
1
+ import type { BrainStatusPhase } from '@sema-agent/sdk';
1
2
  import type { UiLanguage } from './env/uiLanguage.js';
2
3
  export type RetryStatus = {
3
4
  kind: 'stalled';
@@ -62,7 +63,7 @@ interface RetryStatusErrorPayload {
62
63
  } | null;
63
64
  }
64
65
  export declare const BRAIN_STATUS_PHASES: readonly ["rate_limited", "retrying", "reconnecting", "circuit_open", "recovered", "gave_up", "waiting_first_token"];
65
- export type BrainStatusPhase = (typeof BRAIN_STATUS_PHASES)[number];
66
+ export type { BrainStatusPhase };
66
67
  export type BrainRetryErrClass = 'connect_refused' | 'transport' | 'stall' | 'rate_limit' | 'server' | 'http' | 'output_cap';
67
68
  export interface BrainStatusPayload {
68
69
  phase: BrainStatusPhase | (string & {});
@@ -161,4 +162,3 @@ export interface ResultWayOut {
161
162
  }
162
163
  export declare function resultWayOutOf(frame: object | null | undefined): ResultWayOut | undefined;
163
164
  export declare function wayOutSentence(wayOut: ResultWayOut | null | undefined, lang?: UiLanguage): string | undefined;
164
- export {};
@@ -11,6 +11,8 @@ export const BRAIN_STATUS_PHASES = [
11
11
  'gave_up',
12
12
  'waiting_first_token',
13
13
  ];
14
+ const _brainStatusPhasePin = [true, true];
15
+ void _brainStatusPhasePin;
14
16
  export const BRAIN_STATUS_WAIT_SEGMENTS = Object.freeze(['response_headers', 'first_token']);
15
17
  void true;
16
18
  void true;
@@ -2,9 +2,8 @@ import { createEngineCapReader } from './engineCapReader.js';
2
2
  import { ownDataField } from './ownKey.js';
3
3
  const CAPS_KEYS = {
4
4
  conversationAnchor: 'resumeAt',
5
- forkRestore: 'rewindFiles',
5
+ restoreFiles: 'restoreFiles',
6
6
  codeOnly: 'rewindFilesTo',
7
- restoreFilesEpoch: 'restoreFiles',
8
7
  };
9
8
  const _capsKeyPin = true;
10
9
  void _capsKeyPin;
@@ -22,12 +21,13 @@ export function projectRewindArchiveCapability(caps) {
22
21
  try {
23
22
  if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
24
23
  return undefined;
24
+ const restoreFiles = bitOf(caps, CAPS_KEYS.restoreFiles);
25
25
  return {
26
26
  kind: 'present',
27
27
  conversationAnchor: bitOf(caps, CAPS_KEYS.conversationAnchor),
28
- forkRestore: bitOf(caps, CAPS_KEYS.forkRestore),
28
+ forkRestore: restoreFiles,
29
29
  codeOnly: bitOf(caps, CAPS_KEYS.codeOnly),
30
- restoreFilesEpoch: bitOf(caps, CAPS_KEYS.restoreFilesEpoch),
30
+ restoreFilesEpoch: restoreFiles,
31
31
  };
32
32
  }
33
33
  catch {
@@ -31,9 +31,10 @@ export type RunAbortCause = {
31
31
  export declare const RUN_CANCELLED_CODE: "cancelled";
32
32
  export declare function classifyRunAbortCause(record: unknown): RunAbortCause;
33
33
  export type { AbortCause };
34
+ export type AbortCauseWord = AbortCause | 'stall_verdict';
34
35
  export type AbortCauseReading = {
35
36
  readonly kind: 'known';
36
- readonly cause: AbortCause;
37
+ readonly cause: AbortCauseWord;
37
38
  } | {
38
39
  readonly kind: 'unrecognized';
39
40
  readonly word: string;
@@ -100,6 +100,7 @@ const ABORT_CAUSE_SENTENCES = Object.freeze({
100
100
  ask_park_grace_exhausted: 'Aborted: the connection dropped while a question or approval was pending, and the run could not be parked for later resumption in time ' +
101
101
  '(cause ask_park_grace_exhausted) — not an engine error.',
102
102
  cancel_verb: 'Cancelled: a cancel request to the engine stopped this run (cause cancel_verb) — not an engine error.',
103
+ stall_verdict: 'Aborted: the server had already marked this run as stalled (its heartbeat lapsed), so this leg stopped itself (cause stall_verdict) — not an engine error.',
103
104
  });
104
105
  const ABORT_CAUSE_UNRECOGNIZED_SENTENCE = 'Aborted by the engine for a reason this client does not recognize — not an engine error.';
105
106
  function secondsText(ms) {
@@ -1,6 +1,7 @@
1
1
  import { atMostOnceVerdictOf } from './atMostOnce.js';
2
2
  import { readPermissionModeReceiptSegment } from './adapter/downstream/wiringManifestView.js';
3
3
  import { displayUntrusted } from './displayUntrusted.js';
4
+ import { STEERING_NOT_RUNNING } from './engineErrorCodes.js';
4
5
  import { SDK_PERMISSION_MODE_ADMISSION_FOLDS, SDK_PERMISSION_MODE_PERSIST_MISSES } from './generated/sdkFactTables.js';
5
6
  import { msg, renderMessage } from './i18n/translate.js';
6
7
  import { ownDataField, readOwnDataValue } from './ownKey.js';
@@ -8,7 +9,6 @@ import { permissionModeWriteAvailable } from './permissionModeWriteCapability.js
8
9
  import { permissionModeTitle } from './permissionWireCaps.js';
9
10
  import { isDisplayableWireCode } from './wireFailureShape.js';
10
11
  export const PERMISSION_MODE_SWITCH_RESULT_KEYS = Object.freeze(['taskId', 'sessionId', 'status', 'permissionMode', 'admission', 'persisted', 'persistMiss']);
11
- const NOT_RUNNING_CODE = 'steering.not_running';
12
12
  const PRE_SWITCH_CORRUPT_CODE = 'corrupt';
13
13
  function guardedSlot(o, key) {
14
14
  if (o === null || (typeof o !== 'object' && typeof o !== 'function'))
@@ -79,7 +79,7 @@ function failureOutcomeOf(e) {
79
79
  if (v.delivery === 'rejected' && v.status !== undefined) {
80
80
  if (v.status === 404)
81
81
  return Object.freeze({ kind: 'not-found' });
82
- if (v.status === 409 && v.code === NOT_RUNNING_CODE)
82
+ if (v.status === 409 && v.code === STEERING_NOT_RUNNING)
83
83
  return Object.freeze({ kind: 'not-running' });
84
84
  return Object.freeze({ kind: 'refused', status: v.status, ...(v.code !== undefined ? { errorCode: v.code } : {}) });
85
85
  }
@@ -1,23 +1,21 @@
1
1
  import { capForDisplay } from './fleetTaskDesc.js';
2
2
  import { readOwnDataValue } from './ownKey.js';
3
3
  import { SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE } from './engineErrorCodes.js';
4
- import { readErrorRecord, readErrorString } from './wireFailureShape.js';
4
+ import { liftLegacyRefusalFacts, readErrorString } from './wireFailureShape.js';
5
5
  import { effectiveWireErrorCode } from './wireErrorTriage.js';
6
6
  import { msg, renderMessage } from './i18n/translate.js';
7
7
  const SCENARIO_REFUSAL_ERROR_MAX = 200;
8
- function detailBits(detail) {
9
- if (detail === undefined)
10
- return {};
8
+ function scenarioBits(read) {
11
9
  let scenario;
12
10
  let source;
13
11
  try {
14
- scenario = readOwnDataValue(detail, 'scenario');
12
+ scenario = read('scenario');
15
13
  }
16
14
  catch {
17
15
  scenario = undefined;
18
16
  }
19
17
  try {
20
- source = readOwnDataValue(detail, 'source');
18
+ source = read('source');
21
19
  }
22
20
  catch {
23
21
  source = undefined;
@@ -42,20 +40,20 @@ export function scenarioRefusalOf(body) {
42
40
  try {
43
41
  if (!isPlainRecord(raw))
44
42
  return Object.freeze({});
45
- const own = (key) => {
43
+ const ownOf = (o) => (key) => {
46
44
  try {
47
- return readOwnDataValue(raw, key);
45
+ return readOwnDataValue(o, key);
48
46
  }
49
47
  catch {
50
48
  return undefined;
51
49
  }
52
50
  };
53
- const errorCode = own('errorCode');
54
- const error = own('error');
55
- const detail = own('detail');
51
+ const errorCode = ownOf(raw)('errorCode');
52
+ const error = ownOf(raw)('error');
53
+ const facts = liftLegacyRefusalFacts(SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, raw);
56
54
  let bits = {};
57
55
  try {
58
- bits = detailBits(isPlainRecord(detail) ? detail : undefined);
56
+ bits = scenarioBits(ownOf(facts));
59
57
  }
60
58
  catch {
61
59
  bits = {};
@@ -80,7 +78,7 @@ export function scenarioRefusalFromError(err) {
80
78
  return Object.freeze({
81
79
  errorCode: SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE,
82
80
  ...(error !== undefined && error.length > 0 ? { error: capForDisplay(error, SCENARIO_REFUSAL_ERROR_MAX) } : {}),
83
- ...detailBits(readErrorRecord(err, 'detail')),
81
+ ...scenarioBits((key) => readErrorString(err, key)),
84
82
  });
85
83
  }
86
84
  catch {
@@ -49,24 +49,29 @@ export function scenarioSkillsOf(card) {
49
49
  }
50
50
  }
51
51
  const SCENARIO_SKILLS_CAPABILITY_KEY = 'scenarioSkills';
52
+ const CAP_CONFIRMED = Object.freeze({ kind: 'confirmed' });
53
+ const CAP_ABSENT = Object.freeze({ kind: 'absent' });
54
+ const CAP_DECLINED = Object.freeze({ kind: 'declined' });
55
+ const CAP_UNREADABLE = Object.freeze({ kind: 'unreadable' });
56
+ const CAP_UNOBSERVED = Object.freeze({ kind: 'unobserved' });
52
57
  export function observedScenarioSkillsCapability(baseUrl) {
53
58
  try {
54
59
  const base = baseUrl === undefined ? engineWireTargetBaseUrl() : baseUrl;
55
60
  const slot = engineCapValue(typeof base === 'string' ? base : undefined, SCENARIO_SKILLS_CAPABILITY_KEY);
56
61
  switch (slot.kind) {
57
62
  case 'unobserved':
58
- return Object.freeze({ kind: 'unobserved' });
63
+ return CAP_UNOBSERVED;
59
64
  case 'not_reported':
60
- return Object.freeze({ kind: 'absent' });
65
+ return CAP_ABSENT;
61
66
  case 'unreadable':
62
- return Object.freeze({ kind: 'unreadable' });
67
+ return CAP_UNREADABLE;
63
68
  case 'null':
64
- return Object.freeze({ kind: 'declined' });
69
+ return CAP_DECLINED;
65
70
  case 'value':
66
- return slot.value === true ? Object.freeze({ kind: 'confirmed' }) : Object.freeze({ kind: 'declined' });
71
+ return slot.value === true ? CAP_CONFIRMED : CAP_DECLINED;
67
72
  }
68
73
  }
69
74
  catch {
70
- return Object.freeze({ kind: 'unobserved' });
75
+ return CAP_UNOBSERVED;
71
76
  }
72
77
  }
package/dist/seam.d.ts CHANGED
@@ -9,7 +9,9 @@ import type { PlanReviewCardFacts } from './planReviewCardFacts.js';
9
9
  import type { ToolKillCause } from './toolResult.js';
10
10
  import type { HumanInputAttachmentView } from './ownKey.js';
11
11
  import type { SubagentAliasScope } from './subagentContentStore.js';
12
- import type { TaskNotificationFields } from './notifications.js';
12
+ import type { SessionBoxNoticeFacts } from './peerFrames.js';
13
+ import type { HostSettingNotice } from './hostTurnSettings.js';
14
+ import type { ResupplyTruncatedSource, TaskNotificationFields } from './notifications.js';
13
15
  export interface AbortSignalLike {
14
16
  readonly aborted: boolean;
15
17
  }
@@ -166,7 +168,7 @@ export type ChromeEvent = {
166
168
  } | ({
167
169
  kind: 'run_cost_reconciled';
168
170
  laneProof: LaneProof;
169
- } & RunCostReconcile) | HumanInputChromeEvent | MessageCommittedChromeEvent | EngineNoticeChromeEvent | TextSegmentEndChromeEvent | ThinkingSegmentEndChromeEvent | ToolDisclosureChromeEvent | ToolProgressChromeEvent | ToolRosterDeltaChromeEvent | ContextUsageChromeEvent | CompactionOutcomeChromeEvent | CompactionStartedChromeEvent | SubagentStartedChromeEvent | PromptAssembledChromeEvent | MemorySavedChromeEvent | WiringManifestChromeEvent | ResultTextDivergedChromeEvent | ResultReplayedChromeEvent | ToolParkedChromeEvent | SubagentAliasChromeEvent | ApprovalRequestChromeEvent | ApprovalRevokeChromeEvent | ApprovalCompleteChromeEvent | SessionTitledChromeEvent | {
171
+ } & RunCostReconcile) | HumanInputChromeEvent | MessageCommittedChromeEvent | EngineNoticeChromeEvent | TextSegmentEndChromeEvent | ThinkingSegmentEndChromeEvent | ToolDisclosureChromeEvent | ToolProgressChromeEvent | ToolRosterDeltaChromeEvent | ContextUsageChromeEvent | CompactionOutcomeChromeEvent | CompactionStartedChromeEvent | SubagentStartedChromeEvent | PromptAssembledChromeEvent | MemorySavedChromeEvent | WiringManifestChromeEvent | ResultTextDivergedChromeEvent | ResultReplayedChromeEvent | ToolParkedChromeEvent | SubagentAliasChromeEvent | SessionBoxNoticeChromeEvent | ResupplyTruncatedChromeEvent | HostSettingNoticeChromeEvent | ApprovalRequestChromeEvent | ApprovalRevokeChromeEvent | ApprovalCompleteChromeEvent | SessionTitledChromeEvent | {
170
172
  kind: 'suspended_reopened';
171
173
  laneProof: LaneProof;
172
174
  reopen: Extract<SuspendedReopenReading, {
@@ -356,6 +358,26 @@ export interface SubagentAliasChromeEvent {
356
358
  scope: SubagentAliasScope;
357
359
  seq?: number;
358
360
  }
361
+ export type SessionBoxNoticeChromeEvent = SessionBoxNoticeChromeEnvelope & SessionBoxNoticeFacts;
362
+ export interface ResupplyTruncatedChromeEvent {
363
+ kind: 'resupply_truncated';
364
+ laneProof: LaneProof;
365
+ source: ResupplyTruncatedSource;
366
+ taskId: string;
367
+ bytes: number;
368
+ droppedKeys: readonly string[];
369
+ text: string;
370
+ }
371
+ export type HostSettingNoticeChromeEvent = {
372
+ kind: 'host_setting_notice';
373
+ laneProof: LaneProof;
374
+ } & HostSettingNotice;
375
+ export interface SessionBoxNoticeChromeEnvelope {
376
+ kind: 'session_box_notice';
377
+ laneProof: LaneProof;
378
+ text: string;
379
+ rowUuid: string;
380
+ }
359
381
  export interface EngineNoticeChromeEvent {
360
382
  kind: 'engine_notice';
361
383
  laneProof: LaneProof;
@@ -386,7 +408,10 @@ export interface HumanInputChromeEvent {
386
408
  eventId?: string;
387
409
  attachments?: HumanInputAttachmentView[];
388
410
  author?: string;
411
+ authorUnreadable?: true;
389
412
  extension?: string;
413
+ runOrigin?: string;
414
+ runOriginUnreadable?: true;
390
415
  }
391
416
  export type { HumanInputAttachmentView, HumanInputAttachmentDeclinedByView } from './ownKey.js';
392
417
  export interface MessageCommittedChromeEvent {
package/dist/seam.js CHANGED
@@ -146,6 +146,22 @@ const CHROME_ARM_TABLE = {
146
146
  '子代详情的实时输出才按子代任务 id 读得到(子代内容帧只带卡 id)。🔴 座位宿主零逻辑:本臂在座位词表里,按词表转发的宿主自动转发;适配层与渲染层同进程的端(浏览器 lane)适配层已登记,什么都不用做;' +
147
147
  '`scope: content` 只写内容归账那一半、`full` 两半都写(含续发目标),别把两者混着登;`full` 臂的 `seq`(帧自带代际号,可缺席)是续发目标「现卡」的顺序证据,交 `noteSeatSubagentAlias` 即可,别自己按到达序排;适配层每次登记都发(tick 逐条各一只),去重在登记口:同对重复收到答 ignored、无副作用;认不得的 `scope` 词整条不登记(读口答 undefined),别猜。',
148
148
  },
149
+ session_box_notice: {
150
+ required: false,
151
+ duty: '可选:会话箱通告 —— `noticeKind: inbox`(收件箱一行:pending / delivered 必有,urgent / resupplied 缺席 = 引擎没说,不渲 0)/ `delivery`(投递回执)/ `idle`(对端空闲)。' +
152
+ '渲 `text`(数据面英文)或按界面语言调 `sessionBoxNoticeSentence(本臂, lang)`;🔴 同一条通告有两个载体(转录行 + 本臂),接本臂的宿主按 `rowUuid` 把那一行摘掉、只渲一个;' +
153
+ '`state` 是开集机读位,别回显、别按它猜句子;typed 正体缺席时本臂整个不发(不铸状态词)。',
154
+ },
155
+ resupply_truncated: {
156
+ required: false,
157
+ duty: '可选:停驻补投帧只带了最小形的披露 —— 渲 `text`(数据面英文)或按界面语言调 `resupplyTruncatedSentence(本臂, lang)`,放在这条通知的转录行旁(task_notification)或完成通告旁(workflow_complete)。' +
158
+ '`droppedKeys` / `bytes` 是机读位,别拼进句子;披露位缺席(全形帧 / 老服务端)或坏形时本臂整个不发,不要自己据「摘要很短」推断截断。',
159
+ },
160
+ host_setting_notice: {
161
+ required: false,
162
+ duty: '可选:宿主自供设置项的一句通告(`hostTurnSettings()` 产物 `notices` 的一句;载荷 = `HostSettingNotice` 原样)。按 `plane` 呈现:`turn` 本回合系统行 / `session` 每会话每句一次 / ' +
163
+ '`diagnostic` 不渲只记;🔴 非终态:不是失败卡、不改回合状态;`key` / `cause` 缺席 = 这一句不挂某一行,不是坏形。铸口只有 `hostSettingNoticeEventsOf`,别手拼。',
164
+ },
149
165
  result_text_diverged: {
150
166
  required: false,
151
167
  duty: '可选:终帧正文与已上屏正文**互相都不是对方前缀**时的诚实披露。🔴 处置是把这一拍的转录行**改口**' +
@@ -157,7 +173,7 @@ const CHROME_ARM_TABLE = {
157
173
  required: true,
158
174
  duty: '用 sdk isApprovalRequestFrameV1 窄化 frame 才取 card/askId/窗三键;窄不下来 ⇒ 呈通用卡(安全元数据 + 人工 approve/deny),' +
159
175
  '🔴 永不 auto-deny;开卡前调 claimApprovalCard(身份, { signal }):joined / aborted ⇒ 不开卡,held ⇒ 开卡且每条出口恰调一次 hold.release(settled?)' +
160
- '(去重判定归包 —— legacy 帧那一路的持有与结局在进程级持有表 / 已结表里,宿主不自持 legacy 已收口集);流上下文经 approvalFrameContextOf(这只 chrome 事件) 查,查不到不开卡;' +
176
+ '(去重判定归包 —— 同一只审批的活卡 / 停驻行 / 另一条宿主路的持有与结局在进程级持有表 / 已结表里,宿主不自持已收口集;服务端 7.133.0 起一条腿一个帧族,不再有先旧族帧、后本帧的并发);流上下文经 approvalFrameContextOf(这只 chrome 事件) 查,查不到不开卡;' +
161
177
  '🔴 账本重放的历史帧只用于时间线渲染,卡集的全量对账基准是开流 preamble(它带的 expiresInMs 是铸帧时刻的旧值);' +
162
178
  'card 的 message/args 是模型/工具产文,只渲染永不回喂模型',
163
179
  },