@sema-agent/client-core 0.108.0 → 0.110.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 (179) hide show
  1. package/CHANGELOG.md +294 -0
  2. package/README.md +77 -40
  3. package/dist/adapt/arms.js +41 -13
  4. package/dist/adapt/textStream.d.ts +2 -0
  5. package/dist/adapt/textStream.js +37 -16
  6. package/dist/adapter/activeRunSelfHeal.js +1 -1
  7. package/dist/adapter/downstream/eventToSdkMessage.js +11 -5
  8. package/dist/agentSession/engineAgentRegistryRead.js +2 -0
  9. package/dist/bashExitReading.d.ts +12 -0
  10. package/dist/bashExitReading.js +44 -0
  11. package/dist/checkpointRowVerdict.d.ts +1 -1
  12. package/dist/checkpointRowVerdict.js +4 -2
  13. package/dist/compensations.js +1 -1
  14. package/dist/declared/supportFloorDeclared.js +1 -1
  15. package/dist/displayUntrusted.js +132 -14
  16. package/dist/engineAgentAbsence.d.ts +2 -0
  17. package/dist/engineAgentAbsence.js +28 -0
  18. package/dist/engineErrorCodes.d.ts +7 -0
  19. package/dist/engineErrorCodes.js +7 -0
  20. package/dist/engineHealthFacts.d.ts +26 -0
  21. package/dist/engineHealthFacts.js +63 -4
  22. package/dist/engineInlineTaskStats.d.ts +4 -3
  23. package/dist/engineInlineTaskStats.js +18 -2
  24. package/dist/engineNoticeCodes.d.ts +138 -0
  25. package/dist/engineNoticeCodes.js +662 -55
  26. package/dist/engineRepoint.d.ts +140 -0
  27. package/dist/engineRepoint.js +285 -0
  28. package/dist/engineRowRef.js +2 -0
  29. package/dist/engineSessionMessages.d.ts +2 -1
  30. package/dist/engineSessionMessages.js +5 -0
  31. package/dist/errorSupplementRoles.js +5 -1
  32. package/dist/fleet/fleetProjection.js +3 -2
  33. package/dist/fleetTaskDesc.js +3 -3
  34. package/dist/generated/engineFactTables.d.ts +3 -0
  35. package/dist/generated/engineFactTables.js +18 -0
  36. package/dist/generated/engineNoticeTables.js +3 -0
  37. package/dist/generated/sdkFactTables.d.ts +1 -0
  38. package/dist/generated/sdkFactTables.js +4 -0
  39. package/dist/hitl/approvalAskers.d.ts +6 -0
  40. package/dist/hitl/approvalAskers.js +30 -0
  41. package/dist/hitl/approvalCardReasons.js +25 -4
  42. package/dist/hitl/approvalRequestFrameReading.d.ts +21 -0
  43. package/dist/hitl/approvalRequestFrameReading.js +90 -0
  44. package/dist/hitl/approvalResolution.d.ts +8 -1
  45. package/dist/hitl/approvalResolution.js +4 -0
  46. package/dist/hitl/approvalsFeed.js +1 -1
  47. package/dist/hitl/askGateWire.js +0 -2
  48. package/dist/hitl/askParkRowRouting.js +5 -2
  49. package/dist/hitl/automaticAnswerVerdict.d.ts +5 -2
  50. package/dist/hitl/automaticAnswerVerdict.js +18 -4
  51. package/dist/hitl/decisionConflict.d.ts +2 -1
  52. package/dist/hitl/decisionConflict.js +10 -4
  53. package/dist/hitl/decisionRefusal.js +1 -0
  54. package/dist/hitl/decisionSend.d.ts +3 -0
  55. package/dist/hitl/decisionSend.js +29 -11
  56. package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
  57. package/dist/hitl/editedApprovalAcceptance.js +26 -0
  58. package/dist/hitl/frameRouter.js +13 -19
  59. package/dist/hitl/gateLedger.d.ts +0 -4
  60. package/dist/hitl/gateLedger.js +0 -19
  61. package/dist/hitl/hitlBridge.d.ts +5 -0
  62. package/dist/hitl/hitlBridge.js +13 -9
  63. package/dist/hitl/hitlHostSurface.d.ts +1 -0
  64. package/dist/hitl/hitlHostSurface.js +7 -2
  65. package/dist/hitl/hostWithdrawal.d.ts +15 -0
  66. package/dist/hitl/hostWithdrawal.js +38 -0
  67. package/dist/hitl/livePendingAsk.js +17 -16
  68. package/dist/hitl/localAllowRule.js +2 -1
  69. package/dist/hitl/noAllowCause.d.ts +1 -1
  70. package/dist/hitl/noAllowCause.js +4 -2
  71. package/dist/hitl/parkExpiryJudgements.js +26 -1
  72. package/dist/hitl/parkOwnership.d.ts +2 -0
  73. package/dist/hitl/parkOwnership.js +48 -8
  74. package/dist/hitl/parkResolver.js +32 -16
  75. package/dist/hitl/parkedUnresumable.d.ts +13 -0
  76. package/dist/hitl/parkedUnresumable.js +80 -0
  77. package/dist/hitl/permissionRuleScope.d.ts +4 -0
  78. package/dist/hitl/permissionRuleScope.js +31 -0
  79. package/dist/hitl/persistedRulesWire.d.ts +2 -0
  80. package/dist/hitl/persistedRulesWire.js +13 -12
  81. package/dist/hitl/planReviewWire.js +14 -4
  82. package/dist/hitl/sessionAllowRoute.js +5 -4
  83. package/dist/hitl/sessionPolicyWire.js +6 -4
  84. package/dist/hitl/standingRows.d.ts +2 -5
  85. package/dist/hitl/standingRows.js +30 -15
  86. package/dist/hitl/toolApprovalWire.d.ts +42 -9
  87. package/dist/hitl/toolApprovalWire.js +267 -44
  88. package/dist/hooksWireCaps.js +35 -4
  89. package/dist/hostSettingsSource.js +2 -0
  90. package/dist/hostTurnSettings.d.ts +10 -4
  91. package/dist/hostTurnSettings.js +112 -5
  92. package/dist/i18n/messages.en.d.ts +251 -0
  93. package/dist/i18n/messages.en.js +254 -2
  94. package/dist/i18n/messages.zh.js +264 -2
  95. package/dist/index.d.ts +48 -12
  96. package/dist/index.js +29 -7
  97. package/dist/inheritEnvCapability.js +2 -0
  98. package/dist/inputAuthor.d.ts +16 -0
  99. package/dist/inputAuthor.js +44 -0
  100. package/dist/interruptRefusalNote.d.ts +2 -0
  101. package/dist/interruptRefusalNote.js +17 -0
  102. package/dist/liveModelCatalog.d.ts +2 -0
  103. package/dist/liveModelCatalog.js +21 -7
  104. package/dist/liveQuestionStore.d.ts +4 -1
  105. package/dist/liveQuestionStore.js +12 -3
  106. package/dist/localEngineJudge.d.ts +75 -0
  107. package/dist/localEngineJudge.js +242 -0
  108. package/dist/localEngineOccupancy.d.ts +88 -0
  109. package/dist/localEngineOccupancy.js +269 -0
  110. package/dist/localEngineSeatReading.d.ts +29 -0
  111. package/dist/localEngineSeatReading.js +294 -0
  112. package/dist/localEngineSpawn.d.ts +113 -0
  113. package/dist/localEngineSpawn.js +486 -0
  114. package/dist/localEngineStep.d.ts +286 -0
  115. package/dist/localEngineStep.js +1086 -0
  116. package/dist/localEngineStopLadder.d.ts +29 -0
  117. package/dist/localEngineStopLadder.js +139 -0
  118. package/dist/localEngineSwapCard.d.ts +43 -0
  119. package/dist/localEngineSwapCard.js +205 -0
  120. package/dist/localEngineTiming.d.ts +8 -0
  121. package/dist/localEngineTiming.js +8 -0
  122. package/dist/mcpEngineLeg.d.ts +3 -0
  123. package/dist/mcpEngineLeg.js +38 -1
  124. package/dist/mcpPanel.js +2 -0
  125. package/dist/mcpReconnect.d.ts +9 -1
  126. package/dist/mcpReconnect.js +132 -20
  127. package/dist/mcpWireCaps.js +2 -2
  128. package/dist/memoryEntriesWire.d.ts +1 -1
  129. package/dist/memoryEntriesWire.js +5 -0
  130. package/dist/modelCapabilityProbe.js +4 -3
  131. package/dist/modsFace.d.ts +8 -1
  132. package/dist/modsFace.js +27 -0
  133. package/dist/noticePresentation.d.ts +2 -0
  134. package/dist/noticePresentation.js +79 -1
  135. package/dist/notifications.d.ts +17 -6
  136. package/dist/notifications.js +67 -19
  137. package/dist/ownKey.d.ts +5 -0
  138. package/dist/ownKey.js +8 -1
  139. package/dist/peerFrames.d.ts +40 -2
  140. package/dist/peerFrames.js +158 -3
  141. package/dist/pluginHooksWire.d.ts +2 -1
  142. package/dist/pluginHooksWire.js +56 -1
  143. package/dist/replayBody.js +10 -2
  144. package/dist/request/taskRequest.d.ts +5 -0
  145. package/dist/request/taskRequest.js +138 -21
  146. package/dist/resumeRefusalCopy.d.ts +1 -3
  147. package/dist/resumeRefusalCopy.js +2 -1
  148. package/dist/retryStatus.d.ts +2 -2
  149. package/dist/retryStatus.js +2 -0
  150. package/dist/ruleReadings.js +1 -1
  151. package/dist/seam.d.ts +24 -2
  152. package/dist/seam.js +15 -2
  153. package/dist/seatContract.d.ts +125 -10
  154. package/dist/seatContract.js +373 -7
  155. package/dist/sessionBackground.js +4 -1
  156. package/dist/sessionBackgroundHandoff.js +2 -1
  157. package/dist/sessionEngine.d.ts +2 -0
  158. package/dist/sessionEngine.js +111 -0
  159. package/dist/sessionMemoryStatus.d.ts +2 -1
  160. package/dist/sessionSyncFileHistory.d.ts +4 -0
  161. package/dist/sessionSyncFileHistory.js +28 -0
  162. package/dist/sseIdleTriage.d.ts +13 -1
  163. package/dist/sseIdleTriage.js +24 -6
  164. package/dist/subagent/engineSubagentTail.js +6 -0
  165. package/dist/subagentContentStore.d.ts +12 -0
  166. package/dist/subagentContentStore.js +72 -11
  167. package/dist/terminalStatuses.d.ts +1 -0
  168. package/dist/terminalStatuses.js +4 -1
  169. package/dist/toolResult.js +18 -5
  170. package/dist/turnFailurePresentation.js +9 -2
  171. package/dist/typePins.d.ts +11 -0
  172. package/dist/usageAnalytics.d.ts +17 -0
  173. package/dist/usageAnalytics.js +44 -2
  174. package/dist/wireFailureShape.d.ts +22 -5
  175. package/dist/wireFailureShape.js +47 -26
  176. package/dist/wireRefusalCopy.d.ts +31 -1
  177. package/dist/wireRefusalCopy.js +167 -2
  178. package/docs/INTEGRATION-CLIENTS.md +3269 -21
  179. package/package.json +5 -5
package/dist/ownKey.d.ts CHANGED
@@ -32,6 +32,11 @@ export interface HumanInputAttachmentView {
32
32
  kind?: string;
33
33
  outcome: string;
34
34
  label?: string;
35
+ declinedBy?: HumanInputAttachmentDeclinedByView;
36
+ }
37
+ export interface HumanInputAttachmentDeclinedByView {
38
+ kind: 'extension';
39
+ name: string;
35
40
  }
36
41
  export declare function humanInputAttachmentsOf(frame: {} | null | undefined): HumanInputAttachmentView[] | undefined;
37
42
  export declare function markMcpSectionDroppedNamedRows(rows: object, dropped: ReadonlyMap<string, number>): void;
package/dist/ownKey.js CHANGED
@@ -175,7 +175,14 @@ export function humanInputAttachmentsOf(frame) {
175
175
  return undefined;
176
176
  const kind = readOwnDataNonEmptyString(r, 'kind');
177
177
  const label = readOwnDataNonEmptyString(r, 'label');
178
- return { ordinal, ...(kind !== undefined ? { kind } : {}), outcome, ...(label !== undefined ? { label } : {}) };
178
+ const declinedBy = guardedRead(() => {
179
+ const d = readOwnDataValue(r, 'declinedBy');
180
+ if (typeof d !== 'object' || d === null || Array.isArray(d))
181
+ return undefined;
182
+ const name = readOwnDataNonEmptyString(d, 'name');
183
+ return readOwnDataValue(d, 'kind') === 'extension' && name !== undefined ? { kind: 'extension', name } : undefined;
184
+ });
185
+ return { ordinal, ...(kind !== undefined ? { kind } : {}), outcome, ...(label !== undefined ? { label } : {}), ...(declinedBy !== undefined ? { declinedBy } : {}) };
179
186
  });
180
187
  if (row !== undefined)
181
188
  appendOwnElement(rows, row);
@@ -1,6 +1,7 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
1
2
  export declare const AGENT_MESSAGE_TAG = "agent-message";
2
3
  export declare const CROSS_SESSION_MESSAGE_TAG = "cross-session-message";
3
- export declare const PEER_FRAME_LANES: readonly ["agent_message", "cross_session_message", "cross_session_notice"];
4
+ export declare const PEER_FRAME_LANES: readonly ["agent_message", "cross_session_message", "cross_session_notice", "inbox_notice"];
4
5
  export declare const CROSS_SESSION_NOTICE_KINDS: readonly ["delivery_notice", "idle_notice"];
5
6
  export type CrossSessionNoticeKind = (typeof CROSS_SESSION_NOTICE_KINDS)[number];
6
7
  export declare const PEER_MODE_CLASSES: readonly ["bypass", "prompting"];
@@ -22,13 +23,50 @@ export type CrossSessionMessageFrame = {
22
23
  fromScope?: string;
23
24
  seq?: number;
24
25
  };
26
+ export type PeerNoticeFacts = {
27
+ state: string;
28
+ recipient?: string;
29
+ target?: string;
30
+ detail?: string;
31
+ dropReason?: string;
32
+ refSeq?: number;
33
+ finishedAt?: number;
34
+ };
25
35
  export type CrossSessionNoticeFrame = {
26
36
  lane: 'cross_session_notice';
27
37
  kind: CrossSessionNoticeKind;
28
38
  text: string;
39
+ notice?: PeerNoticeFacts;
40
+ };
41
+ export type InboxNoticeFrame = {
42
+ lane: 'inbox_notice';
43
+ pending: number;
44
+ delivered: number;
45
+ urgent?: number;
46
+ resupplied?: number;
29
47
  };
30
- export type PeerFrameProjection = AgentMessageFrame | CrossSessionMessageFrame | CrossSessionNoticeFrame;
48
+ export type PeerFrameProjection = AgentMessageFrame | CrossSessionMessageFrame | CrossSessionNoticeFrame | InboxNoticeFrame;
31
49
  export declare function classifyPeerNotification(raw: Record<string, unknown>): PeerFrameProjection | null;
50
+ export type SessionBoxNoticeFacts = {
51
+ noticeKind: 'inbox';
52
+ pending: number;
53
+ delivered: number;
54
+ urgent?: number;
55
+ resupplied?: number;
56
+ } | {
57
+ noticeKind: 'delivery' | 'idle';
58
+ state: string;
59
+ peerLabel?: string;
60
+ detail?: string;
61
+ dropReason?: string;
62
+ refSeq?: number;
63
+ finishedAt?: number;
64
+ };
65
+ export type SessionBoxNoticeBody = SessionBoxNoticeFacts & {
66
+ text: string;
67
+ };
68
+ export declare function sessionBoxNoticeSentence(facts: SessionBoxNoticeFacts, lang?: UiLanguage): string | undefined;
69
+ export declare function sessionBoxNoticeOf(p: PeerFrameProjection): SessionBoxNoticeBody | undefined;
32
70
  export declare function renderPeerFrameTranscriptText(p: PeerFrameProjection): string;
33
71
  export declare function parsePeerFrameText(text: string): AgentMessageFrame | CrossSessionMessageFrame | null;
34
72
  export declare function peerFrameDisplayName(p: AgentMessageFrame | CrossSessionMessageFrame): string;
@@ -1,4 +1,5 @@
1
- import { applyDisplayFace, PEER_NAME_FACE } from './displayUntrusted.js';
1
+ import { applyDisplayFace, displayUntrusted, PEER_NAME_FACE } from './displayUntrusted.js';
2
+ import { msg, renderMessage } from './i18n/translate.js';
2
3
  import { ownSnapshotRecord } from './ownKey.js';
3
4
  import { CORE_ENGINE_AUTHORITY_ENVELOPE_TAGS, CORE_PERMISSION_MODE_CLASSES } from './generated/engineFactTables.js';
4
5
  const WIRE_KEY_FROM = 'from';
@@ -12,6 +13,20 @@ const WIRE_KEY_AGENT_TYPE = 'agentType';
12
13
  const WIRE_KEY_AGENT_MESSAGE = 'agentMessage';
13
14
  const WIRE_KEY_CROSS_SESSION_MESSAGE = 'crossSessionMessage';
14
15
  const WIRE_KEY_CROSS_SESSION_NOTICE = 'crossSessionNotice';
16
+ const WIRE_KEY_INBOX_NOTICE = 'inboxNotice';
17
+ const WIRE_KEY_PENDING = 'pending';
18
+ const WIRE_KEY_DELIVERED = 'delivered';
19
+ const WIRE_KEY_URGENT = 'urgent';
20
+ const WIRE_KEY_RESUPPLIED = 'resupplied';
21
+ const WIRE_KEY_PEER_META = 'peerMeta';
22
+ const WIRE_KEY_NOTICE = 'notice';
23
+ const WIRE_KEY_STATE = 'state';
24
+ const WIRE_KEY_REF_SEQ = 'refSeq';
25
+ const WIRE_KEY_RECIPIENT = 'recipient';
26
+ const WIRE_KEY_TARGET = 'target';
27
+ const WIRE_KEY_DETAIL = 'detail';
28
+ const WIRE_KEY_DROP_REASON = 'dropReason';
29
+ const WIRE_KEY_FINISHED_AT = 'finishedAt';
15
30
  const WIRE_KEY_PROVENANCE = '_sema_provenance';
16
31
  const WIRE_KEY_FROM_SESSION = 'fromSession';
17
32
  const WIRE_KEY_FROM_NAME = 'fromName';
@@ -20,7 +35,7 @@ const WIRE_KEY_FROM_SCOPE = 'fromScope';
20
35
  const FROM_ATTR = WIRE_KEY_FROM;
21
36
  export const AGENT_MESSAGE_TAG = 'agent-message';
22
37
  export const CROSS_SESSION_MESSAGE_TAG = 'cross-session-message';
23
- export const PEER_FRAME_LANES = Object.freeze(['agent_message', 'cross_session_message', 'cross_session_notice']);
38
+ export const PEER_FRAME_LANES = Object.freeze(['agent_message', 'cross_session_message', 'cross_session_notice', 'inbox_notice']);
24
39
  export const CROSS_SESSION_NOTICE_KINDS = Object.freeze(['delivery_notice', 'idle_notice']);
25
40
  export const PEER_MODE_CLASSES = CORE_PERMISSION_MODE_CLASSES;
26
41
  function dataProp(o, key) {
@@ -43,6 +58,40 @@ function nonEmptyString(v) {
43
58
  function finiteNumber(v) {
44
59
  return typeof v === 'number' && Number.isFinite(v) ? v : undefined;
45
60
  }
61
+ function countOf(v) {
62
+ return typeof v === 'number' && Number.isSafeInteger(v) && v >= 0 ? v : undefined;
63
+ }
64
+ function shownLabel(v, max) {
65
+ if (typeof v !== 'string')
66
+ return undefined;
67
+ const s = displayUntrusted(v, { blanks: true, max });
68
+ return s.length > 0 ? s : undefined;
69
+ }
70
+ const NOTICE_LABEL_MAX = 64;
71
+ const NOTICE_TEXT_MAX = 200;
72
+ function peerNoticeOf(n) {
73
+ const notice = dataProp(dataProp(dataProp(n, WIRE_KEY_PROVENANCE), WIRE_KEY_PEER_META), WIRE_KEY_NOTICE);
74
+ if (notice === null || typeof notice !== 'object')
75
+ return undefined;
76
+ const state = nonEmptyString(dataProp(notice, WIRE_KEY_STATE));
77
+ if (state === undefined)
78
+ return undefined;
79
+ const recipient = shownLabel(dataProp(notice, WIRE_KEY_RECIPIENT), NOTICE_LABEL_MAX);
80
+ const target = shownLabel(dataProp(notice, WIRE_KEY_TARGET), NOTICE_LABEL_MAX);
81
+ const detail = shownLabel(dataProp(notice, WIRE_KEY_DETAIL), NOTICE_TEXT_MAX);
82
+ const dropReason = shownLabel(dataProp(notice, WIRE_KEY_DROP_REASON), NOTICE_TEXT_MAX);
83
+ const refSeq = countOf(dataProp(notice, WIRE_KEY_REF_SEQ));
84
+ const finishedAt = countOf(dataProp(notice, WIRE_KEY_FINISHED_AT));
85
+ return {
86
+ state,
87
+ ...(recipient !== undefined ? { recipient } : {}),
88
+ ...(target !== undefined ? { target } : {}),
89
+ ...(detail !== undefined ? { detail } : {}),
90
+ ...(dropReason !== undefined ? { dropReason } : {}),
91
+ ...(refSeq !== undefined ? { refSeq } : {}),
92
+ ...(finishedAt !== undefined ? { finishedAt } : {}),
93
+ };
94
+ }
46
95
  function provenanceAgrees(n, lane, carrierFromRaw) {
47
96
  const prov = dataProp(n, WIRE_KEY_PROVENANCE);
48
97
  if (prov === null || typeof prov !== 'object')
@@ -112,7 +161,24 @@ export function classifyPeerNotification(raw) {
112
161
  const text = nonEmptyString(dataProp(crossSessionNotice, WIRE_KEY_TEXT));
113
162
  if (kind === undefined || text === undefined || !provenanceAgrees(n, 'cross_session_notice'))
114
163
  return null;
115
- return { lane: 'cross_session_notice', kind, text };
164
+ const notice = peerNoticeOf(n);
165
+ return { lane: 'cross_session_notice', kind, text, ...(notice !== undefined ? { notice } : {}) };
166
+ }
167
+ const inboxNotice = dataProp(n, WIRE_KEY_INBOX_NOTICE);
168
+ if (inboxNotice !== undefined) {
169
+ const pending = countOf(dataProp(inboxNotice, WIRE_KEY_PENDING));
170
+ const delivered = countOf(dataProp(inboxNotice, WIRE_KEY_DELIVERED));
171
+ if (pending === undefined || delivered === undefined || !provenanceAgrees(n, 'inbox_notice'))
172
+ return null;
173
+ const urgent = countOf(dataProp(inboxNotice, WIRE_KEY_URGENT));
174
+ const resupplied = countOf(dataProp(inboxNotice, WIRE_KEY_RESUPPLIED));
175
+ return {
176
+ lane: 'inbox_notice',
177
+ pending,
178
+ delivered,
179
+ ...(urgent !== undefined ? { urgent } : {}),
180
+ ...(resupplied !== undefined ? { resupplied } : {}),
181
+ };
116
182
  }
117
183
  return null;
118
184
  }
@@ -140,9 +206,98 @@ function attr(v) {
140
206
  function unattr(v) {
141
207
  return v.replace(/&quot;/g, '"').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
142
208
  }
209
+ const DELIVERY_SENTENCE_KEYS = Object.freeze({
210
+ delivered: 'notice.sessionBox.delivery.delivered',
211
+ held: 'notice.sessionBox.delivery.held',
212
+ held_by_policy: 'notice.sessionBox.delivery.heldByPolicy',
213
+ denied: 'notice.sessionBox.delivery.denied',
214
+ refused: 'notice.sessionBox.delivery.refused',
215
+ expired: 'notice.sessionBox.delivery.expired',
216
+ });
217
+ const IDLE_SENTENCE_KEYS = Object.freeze({
218
+ exited: 'notice.sessionBox.idle.exited',
219
+ unavailable: 'notice.sessionBox.idle.unavailable',
220
+ expired: 'notice.sessionBox.idle.expired',
221
+ });
222
+ function sentenceKeyOf(table, word) {
223
+ return Object.hasOwn(table, word) ? table[word] : undefined;
224
+ }
225
+ function joinParts(parts, lang) {
226
+ return parts.join(lang === 'zh' ? '' : ' ');
227
+ }
228
+ function inboxLine(pending, urgent, resupplied, lang) {
229
+ const parts = [renderMessage(pending === 1 ? msg('notice.sessionBox.inbox.one') : msg('notice.sessionBox.inbox.many', { pending }), lang)];
230
+ if (urgent !== undefined)
231
+ parts.push(renderMessage(msg('notice.sessionBox.inbox.urgent', { urgent }), lang));
232
+ if (resupplied !== undefined)
233
+ parts.push(renderMessage(msg('notice.sessionBox.inbox.resupplied', { resupplied }), lang));
234
+ return joinParts(parts, lang);
235
+ }
236
+ export function sessionBoxNoticeSentence(facts, lang) {
237
+ try {
238
+ const noticeKind = dataProp(facts, 'noticeKind');
239
+ if (noticeKind === 'inbox') {
240
+ const pending = countOf(dataProp(facts, WIRE_KEY_PENDING));
241
+ if (pending === undefined)
242
+ return undefined;
243
+ return inboxLine(pending, countOf(dataProp(facts, WIRE_KEY_URGENT)), countOf(dataProp(facts, WIRE_KEY_RESUPPLIED)), lang);
244
+ }
245
+ if (noticeKind !== 'delivery' && noticeKind !== 'idle')
246
+ return undefined;
247
+ const state = nonEmptyString(dataProp(facts, WIRE_KEY_STATE));
248
+ if (state === undefined)
249
+ return undefined;
250
+ const label = shownLabel(dataProp(facts, 'peerLabel'), NOTICE_LABEL_MAX);
251
+ const detail = shownLabel(dataProp(facts, WIRE_KEY_DETAIL), NOTICE_TEXT_MAX);
252
+ const dropReason = shownLabel(dataProp(facts, WIRE_KEY_DROP_REASON), NOTICE_TEXT_MAX);
253
+ if (noticeKind === 'delivery') {
254
+ const peer = label ?? renderMessage(msg('notice.sessionBox.peer.another'), lang);
255
+ if (state === 'dropped')
256
+ return renderMessage(dropReason !== undefined ? msg('notice.sessionBox.delivery.dropped', { peer, reason: dropReason }) : msg('notice.sessionBox.delivery.droppedPlain', { peer }), lang);
257
+ return renderMessage(msg(sentenceKeyOf(DELIVERY_SENTENCE_KEYS, state) ?? 'notice.sessionBox.delivery.other', { peer }), lang);
258
+ }
259
+ const peer = label ?? renderMessage(msg('notice.sessionBox.peer.anotherStart'), lang);
260
+ if (state === 'idle')
261
+ return renderMessage(detail !== undefined ? msg('notice.sessionBox.idle.finishedDetail', { peer, detail }) : msg('notice.sessionBox.idle.finished', { peer }), lang);
262
+ return renderMessage(msg(sentenceKeyOf(IDLE_SENTENCE_KEYS, state) ?? 'notice.sessionBox.idle.other', { peer }), lang);
263
+ }
264
+ catch {
265
+ return undefined;
266
+ }
267
+ }
268
+ export function sessionBoxNoticeOf(p) {
269
+ if (p.lane === 'inbox_notice') {
270
+ const facts = {
271
+ noticeKind: 'inbox',
272
+ pending: p.pending,
273
+ delivered: p.delivered,
274
+ ...(p.urgent !== undefined ? { urgent: p.urgent } : {}),
275
+ ...(p.resupplied !== undefined ? { resupplied: p.resupplied } : {}),
276
+ };
277
+ const text = sessionBoxNoticeSentence(facts);
278
+ return text === undefined ? undefined : { ...facts, text };
279
+ }
280
+ if (p.lane !== 'cross_session_notice' || p.notice === undefined)
281
+ return undefined;
282
+ const delivery = p.kind === 'delivery_notice';
283
+ const peerLabel = delivery ? (p.notice.recipient ?? p.notice.target) : (p.notice.target ?? p.notice.recipient);
284
+ const facts = {
285
+ noticeKind: delivery ? 'delivery' : 'idle',
286
+ state: p.notice.state,
287
+ ...(peerLabel !== undefined ? { peerLabel } : {}),
288
+ ...(p.notice.detail !== undefined ? { detail: p.notice.detail } : {}),
289
+ ...(p.notice.dropReason !== undefined ? { dropReason: p.notice.dropReason } : {}),
290
+ ...(p.notice.refSeq !== undefined ? { refSeq: p.notice.refSeq } : {}),
291
+ ...(p.notice.finishedAt !== undefined ? { finishedAt: p.notice.finishedAt } : {}),
292
+ };
293
+ const text = sessionBoxNoticeSentence(facts);
294
+ return text === undefined ? undefined : { ...facts, text };
295
+ }
143
296
  export function renderPeerFrameTranscriptText(p) {
144
297
  if (p.lane === 'cross_session_notice')
145
298
  return escapeEnvelopeTag(CROSS_SESSION_MESSAGE_TAG, escapeEnvelopeTag(AGENT_MESSAGE_TAG, neutralizeAuthorityTags(p.text)));
299
+ if (p.lane === 'inbox_notice')
300
+ return inboxLine(p.pending, p.urgent, p.resupplied, undefined);
146
301
  if (p.lane === 'agent_message') {
147
302
  const body = escapeEnvelopeTag(AGENT_MESSAGE_TAG, neutralizeAuthorityTags(p.body));
148
303
  return `<${AGENT_MESSAGE_TAG} ${FROM_ATTR}="${attr(p.from)}">\n${body}\n</${AGENT_MESSAGE_TAG}>`;
@@ -12,7 +12,7 @@ export declare const PLUGIN_HOOK_REASONS: readonly ["projected", "shell_event",
12
12
  export type PluginHookReason = (typeof PLUGIN_HOOK_REASONS)[number];
13
13
  export declare const PLUGIN_HOOK_EXCLUSION_REASONS: readonly ["workspace_untrusted", "governance_unreadable", "policy_disable_all", "startup_mode", "managed_plugins_only", "prompt_not_user_authored"];
14
14
  export type PluginHookExclusionReason = (typeof PLUGIN_HOOK_EXCLUSION_REASONS)[number];
15
- export declare const SETTINGS_HOOK_DROP_REASONS: readonly ["exec_form_unsupported", "mcp_tool_unsupported", "key_not_read", "source_not_authored"];
15
+ export declare const SETTINGS_HOOK_DROP_REASONS: readonly ["exec_form_unsupported", "mcp_tool_unsupported", "key_not_read", "source_not_authored", "workspace_untrusted", "governance_unreadable", "policy_disable_all"];
16
16
  export type SettingsHookDropReason = (typeof SETTINGS_HOOK_DROP_REASONS)[number];
17
17
  export type HookSettingsSource = 'policySettings' | 'userSettings' | 'projectSettings' | 'localSettings' | 'flagSettings';
18
18
  export interface PluginHookKey {
@@ -196,6 +196,7 @@ export interface SettingsHooksLocalGroup<T> {
196
196
  export declare function settingsHooksKeptLocally<T>(plan: HooksWirePlan, event: string, group: SettingsHooksLocalGroup<T>, opts?: {
197
197
  readonly engineCompaction?: 'performed' | 'not_performed';
198
198
  }): readonly T[];
199
+ export declare function pluginHooksKeptLocally<T>(plan: HooksWirePlan, pluginId: string, event: string, groupIndex: number, hooks: readonly T[]): readonly T[];
199
200
  export declare function pluginHookReasonText(reason: PluginHookReason): string;
200
201
  export declare function settingsHookDropText(reason: SettingsHookDropReason): string;
201
202
  export declare function pluginHookExecutorLabel(v: PluginHookVerdict): string;
@@ -1,5 +1,6 @@
1
1
  import { displayUntrusted } from './displayUntrusted.js';
2
2
  import { appendOwnElement, readOwnDataValue } from './ownKey.js';
3
+ import { inSlotReadOf } from './wireFailureShape.js';
3
4
  import { msg, renderMessage } from './i18n/translate.js';
4
5
  import { SETTINGS_ENGINE_OWNED_HOOK_EVENTS } from './generated/settingsSchemaTables.js';
5
6
  import { HOOK_SETTINGS_SOURCE_TEXT, hooksEntryUnreadKeys, hooksGroupAuthoredSource, hooksGroupUnreadKeys, hooksKeyCoordinateText, hooksSalvageMaskOf, salvageSettingsHooksEntries, } from './settingsHooksSalvage.js';
@@ -40,7 +41,15 @@ export const PLUGIN_HOOK_EXCLUSION_REASONS = [
40
41
  'managed_plugins_only',
41
42
  'prompt_not_user_authored',
42
43
  ];
43
- export const SETTINGS_HOOK_DROP_REASONS = ['exec_form_unsupported', 'mcp_tool_unsupported', 'key_not_read', 'source_not_authored'];
44
+ export const SETTINGS_HOOK_DROP_REASONS = [
45
+ 'exec_form_unsupported',
46
+ 'mcp_tool_unsupported',
47
+ 'key_not_read',
48
+ 'source_not_authored',
49
+ 'workspace_untrusted',
50
+ 'governance_unreadable',
51
+ 'policy_disable_all',
52
+ ];
44
53
  export function hooksWirePlanShapeOf(v) {
45
54
  try {
46
55
  if (typeof v !== 'object' || v === null || Array.isArray(v))
@@ -729,6 +738,8 @@ function skipMatcherKey(matcher) {
729
738
  return matcher === undefined || matcher === null || matcher === '' || matcher === '*' ? 'null' : JSON.stringify(matcher);
730
739
  }
731
740
  export function settingsHooksKeptLocally(plan, event, group, opts) {
741
+ if (planClosedLocally(plan))
742
+ return [];
732
743
  let raw;
733
744
  try {
734
745
  raw = group?.hooks;
@@ -802,6 +813,42 @@ export function settingsHooksKeptLocally(plan, event, group, opts) {
802
813
  return hooks;
803
814
  }
804
815
  }
816
+ function planClosedLocally(plan) {
817
+ if (typeof plan !== 'object' || plan === null)
818
+ return false;
819
+ let slot;
820
+ try {
821
+ slot = inSlotReadOf(plan, 'closedBy');
822
+ }
823
+ catch {
824
+ return true;
825
+ }
826
+ if (slot.state === 'absent')
827
+ return false;
828
+ if (slot.state !== 'present')
829
+ return true;
830
+ return slot.value !== null && slot.value !== undefined;
831
+ }
832
+ export function pluginHooksKeptLocally(plan, pluginId, event, groupIndex, hooks) {
833
+ if (planClosedLocally(plan))
834
+ return [];
835
+ if (!Array.isArray(hooks))
836
+ return hooks;
837
+ try {
838
+ let kept = null;
839
+ hooks.forEach((h, i) => {
840
+ const engineRuns = pluginHookVerdictOf(plan, pluginId, event, groupIndex, i)?.disposition === 'engine';
841
+ if (engineRuns)
842
+ kept ??= hooks.slice(0, i);
843
+ else if (kept !== null)
844
+ appendOwnElement(kept, h);
845
+ });
846
+ return kept ?? hooks;
847
+ }
848
+ catch {
849
+ return hooks;
850
+ }
851
+ }
805
852
  function settingsRowBaseOf(v) {
806
853
  if (!isRecord(v))
807
854
  return undefined;
@@ -881,6 +928,9 @@ const DROP_TEXT = {
881
928
  mcp_tool_unsupported: 'MCP tool hooks are not supported by the engine',
882
929
  key_not_read: REASON_TEXT.key_not_read,
883
930
  source_not_authored: REASON_TEXT.source_not_authored,
931
+ workspace_untrusted: renderMessage(msg('config.hooks.plan.reason.closedUntrusted')),
932
+ governance_unreadable: renderMessage(msg('config.hooks.plan.reason.closedGovernanceUnreadable')),
933
+ policy_disable_all: renderMessage(msg('config.hooks.plan.reason.closedDisableAll')),
884
934
  };
885
935
  const SOURCE_TEXT = HOOK_SETTINGS_SOURCE_TEXT;
886
936
  export function pluginHookReasonText(reason) {
@@ -958,6 +1008,9 @@ function namedPathsOfRow(d) {
958
1008
  return typeof d.event === 'string' && Number.isInteger(d.groupIndex) && d.groupIndex >= 0 ? [['hooks', d.event, d.groupIndex, 'source']] : [];
959
1009
  case 'exec_form_unsupported':
960
1010
  case 'mcp_tool_unsupported':
1011
+ case 'workspace_untrusted':
1012
+ case 'governance_unreadable':
1013
+ case 'policy_disable_all':
961
1014
  return [];
962
1015
  }
963
1016
  }
@@ -1009,6 +1062,8 @@ export function hooksNotRunNotice(plan) {
1009
1062
  for (const d of plan.settingsDropped) {
1010
1063
  if (!d.notRun)
1011
1064
  continue;
1065
+ if (d.reason === 'workspace_untrusted' || d.reason === 'policy_disable_all')
1066
+ continue;
1012
1067
  const named = d.reason === 'key_not_read' || d.reason === 'source_not_authored' ? namedPathsOfRow(d) : [];
1013
1068
  if (named.length > 0 && (d.reason === 'key_not_read' || d.reason === 'source_not_authored')) {
1014
1069
  const nk = `${d.source}\u0000${d.reason}`;
@@ -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[];