@sema-agent/client-core 0.108.0 → 0.109.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 (103) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/README.md +37 -24
  3. package/dist/adapt/arms.js +23 -8
  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 +2 -1
  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/engineAgentAbsence.d.ts +2 -0
  15. package/dist/engineAgentAbsence.js +28 -0
  16. package/dist/engineErrorCodes.d.ts +4 -0
  17. package/dist/engineErrorCodes.js +4 -0
  18. package/dist/engineHealthFacts.d.ts +17 -0
  19. package/dist/engineHealthFacts.js +42 -3
  20. package/dist/engineNoticeCodes.d.ts +128 -0
  21. package/dist/engineNoticeCodes.js +630 -55
  22. package/dist/errorSupplementRoles.js +4 -1
  23. package/dist/fleetTaskDesc.js +3 -3
  24. package/dist/generated/engineFactTables.d.ts +1 -0
  25. package/dist/generated/engineFactTables.js +6 -0
  26. package/dist/generated/engineNoticeTables.js +3 -0
  27. package/dist/hitl/approvalCardReasons.js +22 -4
  28. package/dist/hitl/approvalRequestFrameReading.d.ts +14 -0
  29. package/dist/hitl/approvalRequestFrameReading.js +79 -0
  30. package/dist/hitl/approvalsFeed.js +1 -1
  31. package/dist/hitl/askParkRowRouting.js +5 -2
  32. package/dist/hitl/automaticAnswerVerdict.d.ts +5 -2
  33. package/dist/hitl/automaticAnswerVerdict.js +16 -2
  34. package/dist/hitl/decisionConflict.d.ts +2 -1
  35. package/dist/hitl/decisionConflict.js +4 -1
  36. package/dist/hitl/frameRouter.js +9 -1
  37. package/dist/hitl/hitlBridge.d.ts +4 -0
  38. package/dist/hitl/hitlBridge.js +9 -5
  39. package/dist/hitl/livePendingAsk.js +17 -16
  40. package/dist/hitl/localAllowRule.js +2 -1
  41. package/dist/hitl/noAllowCause.d.ts +1 -1
  42. package/dist/hitl/noAllowCause.js +4 -2
  43. package/dist/hitl/parkExpiryJudgements.js +26 -1
  44. package/dist/hitl/parkOwnership.d.ts +2 -0
  45. package/dist/hitl/parkOwnership.js +48 -8
  46. package/dist/hitl/parkResolver.js +7 -7
  47. package/dist/hitl/parkedUnresumable.d.ts +13 -0
  48. package/dist/hitl/parkedUnresumable.js +80 -0
  49. package/dist/hitl/permissionRuleScope.d.ts +4 -0
  50. package/dist/hitl/permissionRuleScope.js +31 -0
  51. package/dist/hitl/persistedRulesWire.d.ts +2 -0
  52. package/dist/hitl/persistedRulesWire.js +11 -10
  53. package/dist/hitl/sessionAllowRoute.js +5 -4
  54. package/dist/hitl/standingRows.d.ts +1 -5
  55. package/dist/hitl/standingRows.js +15 -14
  56. package/dist/hitl/toolApprovalWire.d.ts +8 -2
  57. package/dist/hitl/toolApprovalWire.js +35 -14
  58. package/dist/hooksWireCaps.js +4 -3
  59. package/dist/hostSettingsSource.js +2 -0
  60. package/dist/i18n/messages.en.d.ts +168 -0
  61. package/dist/i18n/messages.en.js +169 -1
  62. package/dist/i18n/messages.zh.js +169 -1
  63. package/dist/index.d.ts +29 -7
  64. package/dist/index.js +16 -4
  65. package/dist/localEngineJudge.d.ts +75 -0
  66. package/dist/localEngineJudge.js +242 -0
  67. package/dist/localEngineOccupancy.d.ts +88 -0
  68. package/dist/localEngineOccupancy.js +269 -0
  69. package/dist/localEngineSeatReading.d.ts +29 -0
  70. package/dist/localEngineSeatReading.js +294 -0
  71. package/dist/localEngineSpawn.d.ts +113 -0
  72. package/dist/localEngineSpawn.js +486 -0
  73. package/dist/localEngineStep.d.ts +286 -0
  74. package/dist/localEngineStep.js +1086 -0
  75. package/dist/localEngineStopLadder.d.ts +29 -0
  76. package/dist/localEngineStopLadder.js +139 -0
  77. package/dist/localEngineSwapCard.d.ts +43 -0
  78. package/dist/localEngineSwapCard.js +205 -0
  79. package/dist/localEngineTiming.d.ts +8 -0
  80. package/dist/localEngineTiming.js +8 -0
  81. package/dist/mcpReconnect.js +12 -5
  82. package/dist/mcpWireCaps.js +2 -2
  83. package/dist/memoryEntriesWire.d.ts +1 -1
  84. package/dist/memoryEntriesWire.js +5 -0
  85. package/dist/noticePresentation.d.ts +2 -0
  86. package/dist/noticePresentation.js +79 -1
  87. package/dist/ownKey.d.ts +10 -0
  88. package/dist/ownKey.js +15 -1
  89. package/dist/ruleReadings.js +1 -1
  90. package/dist/seam.d.ts +13 -2
  91. package/dist/seam.js +8 -1
  92. package/dist/seatContract.d.ts +42 -4
  93. package/dist/seatContract.js +180 -3
  94. package/dist/sessionBackground.js +2 -0
  95. package/dist/subagentContentStore.d.ts +12 -0
  96. package/dist/subagentContentStore.js +72 -11
  97. package/dist/toolResult.js +18 -5
  98. package/dist/wireFailureShape.d.ts +20 -0
  99. package/dist/wireFailureShape.js +37 -6
  100. package/dist/wireRefusalCopy.d.ts +21 -1
  101. package/dist/wireRefusalCopy.js +91 -2
  102. package/docs/INTEGRATION-CLIENTS.md +1152 -10
  103. package/package.json +3 -3
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);
@@ -186,6 +193,13 @@ export function humanInputAttachmentsOf(frame) {
186
193
  return undefined;
187
194
  }
188
195
  }
196
+ export function humanInputAuthorKeys(frame) {
197
+ if (typeof frame !== 'object' || frame === null || Array.isArray(frame))
198
+ return {};
199
+ const author = guardedRead(() => readOwnDataNonEmptyString(frame, 'author'));
200
+ const extension = guardedRead(() => readOwnDataNonEmptyString(frame, 'extension'));
201
+ return { ...(author !== undefined ? { author } : {}), ...(extension !== undefined ? { extension } : {}) };
202
+ }
189
203
  const DROPPED_NAMED_ROWS = Symbol.for('@sema-agent/client-core/mcpSectionDroppedNamedRows');
190
204
  export function markMcpSectionDroppedNamedRows(rows, dropped) {
191
205
  if (dropped.size === 0)
@@ -122,7 +122,7 @@ export function ruleNearMissSentence(rows, lang) {
122
122
  const named = shown
123
123
  .map((it) => renderMessage(msg('rules.refusal.item', {
124
124
  rule: `"${capForDisplay(it.rule, NEAR_MISS_RULE_MAX)}"`,
125
- reason: renderMessage(msg('rules.nearMiss.reason', { mounted: capForDisplay(displayUntrusted(it.mounted), NEAR_MISS_NAME_MAX) }), lang),
125
+ reason: renderMessage(msg('rules.nearMiss.reason', { mounted: displayUntrusted(it.mounted, { max: NEAR_MISS_NAME_MAX, escapeBackslashes: 'auto' }) }), lang),
126
126
  }), lang))
127
127
  .join(separator);
128
128
  const rest = items.length - shown.length;
package/dist/seam.d.ts CHANGED
@@ -8,6 +8,7 @@ import type { SuspendedReopenReading } from './hitl/suspendedReopen.js';
8
8
  import type { PlanReviewCardFacts } from './planReviewCardFacts.js';
9
9
  import type { ToolKillCause } from './toolResult.js';
10
10
  import type { HumanInputAttachmentView } from './ownKey.js';
11
+ import type { SubagentAliasScope } from './subagentContentStore.js';
11
12
  import type { TaskNotificationFields } from './notifications.js';
12
13
  export interface AbortSignalLike {
13
14
  readonly aborted: boolean;
@@ -165,7 +166,7 @@ export type ChromeEvent = {
165
166
  } | ({
166
167
  kind: 'run_cost_reconciled';
167
168
  laneProof: LaneProof;
168
- } & RunCostReconcile) | HumanInputChromeEvent | MessageCommittedChromeEvent | EngineNoticeChromeEvent | TextSegmentEndChromeEvent | ThinkingSegmentEndChromeEvent | ToolDisclosureChromeEvent | ToolProgressChromeEvent | ToolRosterDeltaChromeEvent | ContextUsageChromeEvent | CompactionOutcomeChromeEvent | CompactionStartedChromeEvent | SubagentStartedChromeEvent | PromptAssembledChromeEvent | MemorySavedChromeEvent | WiringManifestChromeEvent | ResultTextDivergedChromeEvent | ResultReplayedChromeEvent | ToolParkedChromeEvent | ApprovalRequestChromeEvent | ApprovalRevokeChromeEvent | ApprovalCompleteChromeEvent | SessionTitledChromeEvent | {
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 | {
169
170
  kind: 'suspended_reopened';
170
171
  laneProof: LaneProof;
171
172
  reopen: Extract<SuspendedReopenReading, {
@@ -347,6 +348,14 @@ export interface ToolParkedChromeEvent {
347
348
  toolUseId: string;
348
349
  rowUuid?: string;
349
350
  }
351
+ export interface SubagentAliasChromeEvent {
352
+ kind: 'subagent_alias';
353
+ laneProof: LaneProof;
354
+ parentToolCallId: string;
355
+ taskId: string;
356
+ scope: SubagentAliasScope;
357
+ seq?: number;
358
+ }
350
359
  export interface EngineNoticeChromeEvent {
351
360
  kind: 'engine_notice';
352
361
  laneProof: LaneProof;
@@ -376,8 +385,10 @@ export interface HumanInputChromeEvent {
376
385
  entryId?: string;
377
386
  eventId?: string;
378
387
  attachments?: HumanInputAttachmentView[];
388
+ author?: string;
389
+ extension?: string;
379
390
  }
380
- export type { HumanInputAttachmentView } from './ownKey.js';
391
+ export type { HumanInputAttachmentView, HumanInputAttachmentDeclinedByView } from './ownKey.js';
381
392
  export interface MessageCommittedChromeEvent {
382
393
  kind: 'message_committed';
383
394
  laneProof: LaneProof;
package/dist/seam.js CHANGED
@@ -140,6 +140,12 @@ const CHROME_ARM_TABLE = {
140
140
  '按开始行 uuid 认行,不按 toolUseId(调用 id 只在同一条助手消息内唯一)。它的终态由执行腿的结果铸(续跑带见证时接回原行),或永远缺席(停驻被取消 / 过期)。' +
141
141
  '连坐旁观者 / 普通错误 / 停驻卡上 Esc(包已自发中断拒绝,行照铸 Interrupted)零枚。',
142
142
  },
143
+ subagent_alias: {
144
+ required: false,
145
+ duty: '可选:「委派卡 id → 子代任务 id」别名对(`parentToolCallId` / `taskId` / `scope`)—— 座位 lane 的渲染端收到就调 `noteSeatSubagentAlias(chrome)` 写自己账本里的同一半,' +
146
+ '子代详情的实时输出才按子代任务 id 读得到(子代内容帧只带卡 id)。🔴 座位宿主零逻辑:本臂在座位词表里,按词表转发的宿主自动转发;适配层与渲染层同进程的端(浏览器 lane)适配层已登记,什么都不用做;' +
147
+ '`scope: content` 只写内容归账那一半、`full` 两半都写(含续发目标),别把两者混着登;`full` 臂的 `seq`(帧自带代际号,可缺席)是续发目标「现卡」的顺序证据,交 `noteSeatSubagentAlias` 即可,别自己按到达序排;适配层每次登记都发(tick 逐条各一只),去重在登记口:同对重复收到答 ignored、无副作用;认不得的 `scope` 词整条不登记(读口答 undefined),别猜。',
148
+ },
143
149
  result_text_diverged: {
144
150
  required: false,
145
151
  duty: '可选:终帧正文与已上屏正文**互相都不是对方前缀**时的诚实披露。🔴 处置是把这一拍的转录行**改口**' +
@@ -170,7 +176,8 @@ const CHROME_ARM_TABLE = {
170
176
  },
171
177
  approval_complete: {
172
178
  required: true,
173
- duty: '用 sdk isApprovalCompleteFrameV1 窄化 frame 取 askId/outcome/cause/parked;窄不下来按 askId(若有)清卡、别猜结局;按开卡帧的 askId 清本地卡' +
179
+ duty: '结局三态只读 classifyApprovalCompleteFrame(frame)(live-expired-parked / live-expired-retract / settled;null = 认不出、别猜结局),不自拼 outcome / cause / parked 的读法;' +
180
+ '清卡用的 askId 经 sdk isApprovalCompleteFrameV1 窄化取,窄不下来按 askId(若有)清卡;按开卡帧的 askId 清本地卡,三态任一都清' +
174
181
  '(与撤卡帧不冲突,两帧都可能到;清卡是这张卡的一条出口,呈卡臂登记的持有句柄照放);🔴 永不据本帧推断 run 的归宿(读 run 行 / 停驻面),' +
175
182
  'expired 不是拒绝,带 parked 的是转进耐久队列、还在等人;账本重放的消卡帧只用于时间线渲染,卡集对账基准恒为开流 preamble(帧可能整帧丢失)',
176
183
  },
@@ -16,6 +16,8 @@ import type { McpToolToggleKey } from "./mcpToolToggles.js";
16
16
  import { type ThinkingLatchEvent, type ThinkingLatchRowWord } from "./thinkingLatchWords.js";
17
17
  import type { SessionRowPatchFields, SessionRowUnreadable } from "./sessionRowTag.js";
18
18
  import { type SessionEngineKind, type SessionEngineView } from "./sessionEngine.js";
19
+ import type { ParkedUnresumableRow } from "./hitl/parkedUnresumable.js";
20
+ import { type EngineSwapCard } from "./localEngineSwapCard.js";
19
21
  export interface SeatValidationFailure {
20
22
  reason: string;
21
23
  field?: string;
@@ -56,6 +58,7 @@ export interface LocalSessionRecord {
56
58
  thinkingLatch?: ThinkingLatchRowWord;
57
59
  engine?: SessionEngineView;
58
60
  executionLane?: string;
61
+ parkedUnresumable?: readonly ParkedUnresumableRow[];
59
62
  }
60
63
  export declare const TOOL_PERMISSION_REQUEST_ID_DOMAINS: readonly ["live:", "durable:", "question:", "elicit:", "plan:"];
61
64
  export type ToolPermissionRequestIdDomain = (typeof TOOL_PERMISSION_REQUEST_ID_DOMAINS)[number];
@@ -106,6 +109,7 @@ declare const CHROME_ARM_SEAT_ROUTE: {
106
109
  readonly compaction_started: "seat";
107
110
  readonly compaction_outcome: "seat";
108
111
  readonly engine_notice: "seat";
112
+ readonly subagent_alias: "seat";
109
113
  readonly workflow_notification_enqueue: "host";
110
114
  readonly plan_review_park: "host";
111
115
  readonly approval_request: "host";
@@ -478,9 +482,40 @@ export type SeatLocalMcpReading = {
478
482
  readAt: string;
479
483
  restartRequired?: true;
480
484
  };
485
+ export declare const LOCAL_ENGINE_DOWN_REASONS: readonly ["lock-unavailable", "spawn-failed", "spawn-refused", "stop-failed", "crash-loop", "high-water-unreadable", "principal-unknown"];
486
+ export type LocalEngineDownReason = (typeof LOCAL_ENGINE_DOWN_REASONS)[number];
487
+ export declare const LOCAL_ENGINE_WAITING_REASONS: readonly ["starting", "dormant", "draining", "unanswered", "peer"];
488
+ export type LocalEngineWaitingReason = (typeof LOCAL_ENGINE_WAITING_REASONS)[number];
489
+ export type LocalEngineSeatReading = {
490
+ phase: "waiting";
491
+ why: LocalEngineWaitingReason;
492
+ unverifiable?: true;
493
+ } | {
494
+ phase: "attached";
495
+ } | {
496
+ phase: "pending";
497
+ serving: boolean;
498
+ card?: EngineSwapCard;
499
+ } | {
500
+ phase: "swapping";
501
+ mode: "idle" | "forced";
502
+ } | {
503
+ phase: "down";
504
+ reason: LocalEngineDownReason;
505
+ } | {
506
+ phase: "behind";
507
+ running: string;
508
+ own: string;
509
+ upgrade: "available" | "unavailable";
510
+ };
511
+ export declare const ENGINE_SWAP_ANSWER_OUTCOMES: readonly ["started", "stale-card", "nothing-pending"];
512
+ export type EngineSwapAnswerOutcome = (typeof ENGINE_SWAP_ANSWER_OUTCOMES)[number];
513
+ export declare const SELF_UPGRADE_OUTCOMES: readonly ["started", "unavailable"];
514
+ export type SelfUpgradeOutcome = (typeof SELF_UPGRADE_OUTCOMES)[number];
481
515
  export interface EngineTargetLocal {
482
516
  lastBootError?: string;
483
517
  mcp?: SeatLocalMcpReading;
518
+ lifecycle?: LocalEngineSeatReading;
484
519
  }
485
520
  export interface EngineTargetState {
486
521
  mode: "local" | "cloud";
@@ -708,6 +743,8 @@ export interface LocalSessionsApi {
708
743
  connectCloudEngine(req: CloudEngineConnectRequest): Promise<CloudConnectResult>;
709
744
  configureCloudEngine(req: CloudEngineConfigureRequest): Promise<CloudConnectResult>;
710
745
  clearCloudEngine(): Promise<EngineTargetResult>;
746
+ answerEngineSwap(choice: "force" | "wait", fingerprint: string): Promise<EngineSwapAnswerOutcome>;
747
+ beginSelfUpgrade(): Promise<SelfUpgradeOutcome>;
711
748
  listOnboardProviders(): Promise<OnboardProvidersResult>;
712
749
  probeOnboardEntry(req: OnboardEntryRequest): Promise<OnboardProbeResult>;
713
750
  applyOnboardEntry(req: OnboardApplyRequest): Promise<OnboardApplyResult>;
@@ -728,6 +765,7 @@ export interface LocalSessionsApi {
728
765
  engineTargetStateStore: EipcStoreClient<EngineTargetState>;
729
766
  }
730
767
  export declare function isLocalSessionRecord(s: unknown): s is LocalSessionRecord;
768
+ export declare function readSeatParkedUnresumable(record: object): readonly ParkedUnresumableRow[] | undefined;
731
769
  export declare function isToolPermissionRequest(r: unknown): r is ToolPermissionRequest;
732
770
  export declare function readSeatSubagentContent(event: object): SubagentContentEvent | undefined;
733
771
  export declare function isLocalSessionEvent(v: unknown): v is LocalSessionEvent;
@@ -766,12 +804,12 @@ export declare const checkStartSessionOptions: (v: unknown) => SeatValidation;
766
804
  export declare const checkSeatResourceScope: (v: unknown) => SeatValidation;
767
805
  export declare function isSendMessageAck(v: unknown): v is SendMessageAck;
768
806
  export declare const LOCAL_SESSIONS_SPEC: EipcServiceSpec;
769
- export declare const SEAT_METHOD_NAMES: readonly ["start", "sendMessage", "interrupt", "stop", "respondToToolPermission", "cancelQueuedMessage", "reorderQueuedMessage", "promoteQueuedMessage", "setFocusedSession", "setModel", "getTranscript", "searchSessions", "uploadAttachment", "listModels", "applyModelConfig", "pickFolder", "listRecentFolders", "noteRecentFolder", "patchSession", "listDevices", "readSessionBinding", "rebindSession", "issueEnrollToken", "revokeDevice", "setEngineMode", "startCloudLogin", "cancelCloudLogin", "connectCloudEngine", "configureCloudEngine", "clearCloudEngine", "listOnboardProviders", "probeOnboardEntry", "applyOnboardEntry", "readSessionMcpPanel", "listMcpToolToggles", "setMcpToolToggle", "setThinkingLatch", "getComputerUse", "setComputerUse", "claimSeatActions", "onEvent", "onToolPermissionRequest", "onSeatAction"];
807
+ export declare const SEAT_METHOD_NAMES: readonly ["start", "sendMessage", "interrupt", "stop", "respondToToolPermission", "cancelQueuedMessage", "reorderQueuedMessage", "promoteQueuedMessage", "setFocusedSession", "setModel", "getTranscript", "searchSessions", "uploadAttachment", "listModels", "applyModelConfig", "pickFolder", "listRecentFolders", "noteRecentFolder", "patchSession", "listDevices", "readSessionBinding", "rebindSession", "issueEnrollToken", "revokeDevice", "setEngineMode", "startCloudLogin", "cancelCloudLogin", "connectCloudEngine", "configureCloudEngine", "clearCloudEngine", "answerEngineSwap", "beginSelfUpgrade", "listOnboardProviders", "probeOnboardEntry", "applyOnboardEntry", "readSessionMcpPanel", "listMcpToolToggles", "setMcpToolToggle", "setThinkingLatch", "getComputerUse", "setComputerUse", "claimSeatActions", "onEvent", "onToolPermissionRequest", "onSeatAction"];
770
808
  export declare const SEAT_STORE_PROPS: readonly ["sessionsStateStore", "focusedSessionStateStore", "settingsStateStore", "seatCapabilitiesStateStore", "engineTargetStateStore"];
771
809
  export declare const SEAT_EVENT_METHOD_NAMES: readonly ["onEvent", "onToolPermissionRequest", "onSeatAction"];
772
810
  export declare const LOCAL_SESSION_EVENT_KEYS: readonly ["type", "sessionId", "message", "error", "errorCategory", "code", "session", "userMessageUuid", "requestId", "outcome", "parked", "chrome", "_sema_turnFailure", "subagentContent"];
773
811
  export declare const TOOL_PERMISSION_REQUEST_KEYS: readonly ["requestId", "sessionId", "toolName", "toolCallId", "input", "message", "toctouBinding", "createdAtMs", "governanceForced", "delegation", "mandated", "mandate", "origin", "ruleOffersAbsence", "askClass", "classes", "sessionRow"];
774
- export declare const LOCAL_SESSION_RECORD_KEYS: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned", "rowTag", "unreadable", "thinkingLatch", "engine", "executionLane"];
812
+ export declare const LOCAL_SESSION_RECORD_KEYS: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned", "rowTag", "unreadable", "thinkingLatch", "engine", "executionLane", "parkedUnresumable"];
775
813
  export declare const SEND_MESSAGE_REQUEST_KEYS: readonly ["sessionId", "text", "model", "userMessageUuid", "permissionMode", "attachmentIds", "reasoningEffort", "retainBackgroundProcesses", "forwardSubagentEvents", "retainSubagentSessions", "settings", "scenario", "rewind"];
776
814
  export declare const SEAT_SEND_MESSAGE_KEY_ORIGINS: {
777
815
  readonly sessionId: {
@@ -821,7 +859,7 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
821
859
  readonly LocalSessionRecord: {
822
860
  readonly guard: "isLocalSessionRecord";
823
861
  readonly check: (v: unknown) => SeatValidation;
824
- readonly validated: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned", "rowTag", "unreadable", "thinkingLatch", "engine", "executionLane"];
862
+ readonly validated: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned", "rowTag", "unreadable", "thinkingLatch", "engine", "executionLane", "parkedUnresumable"];
825
863
  readonly unchecked: readonly [];
826
864
  };
827
865
  readonly ToolPermissionRequest: {
@@ -1021,7 +1059,7 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
1021
1059
  };
1022
1060
  };
1023
1061
  export declare const SEAT_VALIDATOR_COVERAGE_EXEMPT: readonly [...{
1024
- label: "DeviceListOutcome" | "DeviceSessionBindingOutcome" | "DeviceRebindOutcome" | "DeviceEnrollTokenOutcome" | "DeviceRevokeOutcome" | "SeatDeviceRebindRequest" | "SeatDeviceRevokeRequest" | "EngineTargetState" | "EngineTargetResult" | "CloudLoginStart" | "CloudLoginCancelAck" | "CloudConnectResult" | "CloudLoginRequest" | "CloudEngineConnectRequest" | "CloudEngineConfigureRequest" | "OnboardProvidersResult" | "OnboardProbeResult" | "OnboardApplyResult" | "OnboardEntryRequest" | "OnboardApplyRequest" | "McpToolTogglesResult" | "McpToolToggleKey" | "ComputerUseState" | "SetComputerUseResult" | "SetComputerUseRequest" | "SeatAction";
1062
+ label: "DeviceListOutcome" | "DeviceSessionBindingOutcome" | "DeviceRebindOutcome" | "DeviceEnrollTokenOutcome" | "DeviceRevokeOutcome" | "SeatDeviceRebindRequest" | "SeatDeviceRevokeRequest" | "EngineTargetState" | "EngineTargetResult" | "CloudLoginStart" | "CloudLoginCancelAck" | "CloudConnectResult" | "CloudLoginRequest" | "CloudEngineConnectRequest" | "CloudEngineConfigureRequest" | "OnboardProvidersResult" | "OnboardProbeResult" | "OnboardApplyResult" | "OnboardEntryRequest" | "OnboardApplyRequest" | "McpToolTogglesResult" | "McpToolToggleKey" | "ComputerUseState" | "SetComputerUseResult" | "SetComputerUseRequest" | "SeatAction" | "EngineSwapAnswerOutcome" | "SelfUpgradeOutcome";
1025
1063
  check: (v: unknown) => SeatValidation;
1026
1064
  why: string;
1027
1065
  }[], {
@@ -10,6 +10,7 @@ import { MCP_LIVENESS_STATES } from "./mcpLiveness.js";
10
10
  import { THINKING_LATCH_EVENTS, THINKING_LATCH_ROW_WORDS } from "./thinkingLatchWords.js";
11
11
  import { EXECUTION_PLACEMENT_ROLES } from "./executionPlacementWords.js";
12
12
  import { isSessionEngineView } from "./sessionEngine.js";
13
+ import { LOCAL_ENGINE_SWAP_CAUSES } from "./localEngineSwapCard.js";
13
14
  const bad = (reason, field) => field === undefined ? { reason } : { reason, field };
14
15
  const nested = (prefix, verdict) => {
15
16
  const path = verdict.field === undefined
@@ -184,6 +185,21 @@ const R_INT0 = ruleOf("non-negative integer", (v) => typeof v === "number" && Nu
184
185
  const R_INT1 = ruleOf("positive integer", (v) => typeof v === "number" && Number.isSafeInteger(v) && v > 0);
185
186
  const SESSION_ENGINE_KIND_WORDS = Object.freeze(["local", "cloud"]);
186
187
  const R_ENGINE_LANE = oneOfRule("engine lane", SESSION_ENGINE_KIND_WORDS);
188
+ const R_ROW_BAR = armsRule("row verdict", "kind", {
189
+ lacking: { code: reqF(R_NONEMPTY), reason: optF(R_NONEMPTY), requires: optF(arrayRule(R_NONEMPTY)), sentence: reqF(R_NONEMPTY) },
190
+ damaged: { code: reqF(R_NONEMPTY), reason: optF(R_NONEMPTY), requires: optF(arrayRule(R_NONEMPTY)), sentence: reqF(R_NONEMPTY) },
191
+ unknown: { word: reqF(R_NONEMPTY), sentence: optF(R_NONEMPTY) },
192
+ unreadable: {},
193
+ });
194
+ const PARKED_ROW_DEADLINE_WORDS = Object.freeze(["armed", "none"]);
195
+ const R_PARKED_ROW = shapeRule("parked row", {
196
+ rowVerdict: reqF(R_ROW_BAR),
197
+ rowKey: optF(R_NONEMPTY),
198
+ taskId: optF(R_NONEMPTY),
199
+ toolName: optF(R_NONEMPTY),
200
+ rowDeadline: optF(oneOfRule("deadline word", PARKED_ROW_DEADLINE_WORDS)),
201
+ });
202
+ const R_PARKED_UNRESUMABLE = arrayRule(R_PARKED_ROW, true);
187
203
  const keyWords = (k) => k
188
204
  .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
189
205
  .toLowerCase()
@@ -293,6 +309,7 @@ const CHROME_ARM_SEAT_ROUTE = {
293
309
  compaction_started: "seat",
294
310
  compaction_outcome: "seat",
295
311
  engine_notice: "seat",
312
+ subagent_alias: "seat",
296
313
  workflow_notification_enqueue: "host",
297
314
  plan_review_park: "host",
298
315
  approval_request: "host",
@@ -687,6 +704,18 @@ export const CLOUD_LOGIN_FAILURES = Object.freeze([
687
704
  "no_tokens",
688
705
  "other",
689
706
  ]);
707
+ export const LOCAL_ENGINE_DOWN_REASONS = Object.freeze([
708
+ "lock-unavailable",
709
+ "spawn-failed",
710
+ "spawn-refused",
711
+ "stop-failed",
712
+ "crash-loop",
713
+ "high-water-unreadable",
714
+ "principal-unknown",
715
+ ]);
716
+ export const LOCAL_ENGINE_WAITING_REASONS = Object.freeze(["starting", "dormant", "draining", "unanswered", "peer"]);
717
+ export const ENGINE_SWAP_ANSWER_OUTCOMES = Object.freeze(["started", "stale-card", "nothing-pending"]);
718
+ export const SELF_UPGRADE_OUTCOMES = Object.freeze(["started", "unavailable"]);
690
719
  const R_ISO = R_NONEMPTY;
691
720
  const R_LOGIN_FAILURE = oneOfRule("login failure", CLOUD_LOGIN_FAILURES);
692
721
  const R_DISPLAY_URL = ruleOf("display url", (v) => {
@@ -763,10 +792,82 @@ const ENGINE_TARGET_CLOUD = shapeRule("cloud", {
763
792
  })),
764
793
  orgEngine: optF(shapeRule("org engine", { url: reqF(R_DISPLAY_URL), required: reqF(R_BOOL) })),
765
794
  });
766
- const ENGINE_TARGET_LOCAL = shapeRule("local", {
795
+ const R_FINITE_TIME = ruleOf("non-negative integer", (v) => typeof v === "number" && Number.isSafeInteger(v) && v >= 0);
796
+ const SWAP_CARD_IDENTITY = shapeRule("engine identity", {
797
+ pid: optF(R_INT1),
798
+ instanceId: optF(R_NONEMPTY),
799
+ startedAt: optF(R_FINITE_TIME),
800
+ });
801
+ const SWAP_CARD_REF_SPEC = {
802
+ pid: reqF(R_INT1),
803
+ port: reqF(ruleOf("port", (v) => typeof v === "number" && Number.isInteger(v) && v >= 1 && v <= 65535)),
804
+ identity: reqF(SWAP_CARD_IDENTITY),
805
+ version: optF(R_NONEMPTY),
806
+ };
807
+ const SWAP_CARD_PROCESS_SPEC = { pid: reqF(R_INT1), startedAt: optF(R_INT1) };
808
+ const R_SWAP_CARD_TARGET = {
809
+ label: "card target",
810
+ test: (v, path) => {
811
+ if (!isPlainRecord(v))
812
+ return bad("not object", path === "" ? undefined : path);
813
+ return shapeVerdict(isAbsent(own(v, "identity")) ? SWAP_CARD_PROCESS_SPEC : SWAP_CARD_REF_SPEC, v, path);
814
+ },
815
+ };
816
+ const SWAP_CARD = shapeRule("swap card", {
817
+ cause: reqF(oneOfRule("swap cause", LOCAL_ENGINE_SWAP_CAUSES)),
818
+ target: reqF(R_SWAP_CARD_TARGET),
819
+ running: optF(R_NONEMPTY),
820
+ own: optF(R_NONEMPTY),
821
+ others: reqF(ruleOf("others count|null", (v) => {
822
+ if (v === null)
823
+ return true;
824
+ if (!isPlainRecord(v))
825
+ return false;
826
+ return shapeVerdict({ total: reqF(R_INT0), midTurn: reqF(R_INT0) }, v, "") === true;
827
+ })),
828
+ inflight: reqF(ruleOf("count|null", (v) => v === null || (typeof v === "number" && Number.isSafeInteger(v) && v >= 0))),
829
+ bgLive: reqF(ruleOf("count|null", (v) => v === null || (typeof v === "number" && Number.isSafeInteger(v) && v >= 0))),
830
+ unknown: reqF(arrayRule(oneOfRule("card unknown", ["others", "inflight", "bg", "self"]))),
831
+ forcedWithinMs: reqF(R_INT0),
832
+ fingerprint: reqF(R_NONEMPTY),
833
+ });
834
+ const LOCAL_ENGINE_SEAT_READING = armsRule("engine lifecycle", "phase", {
835
+ waiting: { why: reqF(oneOfRule("waiting reason", LOCAL_ENGINE_WAITING_REASONS)), unverifiable: optF(R_TRUE) },
836
+ attached: {},
837
+ pending: { serving: reqF(R_BOOL), card: optF(SWAP_CARD) },
838
+ swapping: { mode: reqF(oneOfRule("swap mode", ["idle", "forced"])) },
839
+ down: { reason: reqF(oneOfRule("down reason", LOCAL_ENGINE_DOWN_REASONS)) },
840
+ behind: { running: reqF(R_NONEMPTY), own: reqF(R_NONEMPTY), upgrade: reqF(oneOfRule("upgrade entry", ["available", "unavailable"])) },
841
+ });
842
+ const R_LIFECYCLE_DERIVED = ruleOf("lifecycle-derived", () => false);
843
+ const R_LIFECYCLE_WITHDRAWN = ruleOf("lifecycle-withdrawn", () => false);
844
+ const R_UNANSWERED_ONLY = ruleOf("unanswered-only", () => false);
845
+ const ENGINE_TARGET_LOCAL_SPEC = {
767
846
  lastBootError: optF(R_STR),
768
847
  mcp: optF(SEAT_LOCAL_MCP_READING),
769
- });
848
+ lifecycle: optF(LOCAL_ENGINE_SEAT_READING),
849
+ };
850
+ const ENGINE_TARGET_LOCAL = {
851
+ label: "local",
852
+ test: (v, path) => {
853
+ const verdict = shapeVerdict(ENGINE_TARGET_LOCAL_SPEC, v, path);
854
+ if (verdict !== true)
855
+ return verdict;
856
+ const rec = v;
857
+ const lifecycle = own(rec, "lifecycle");
858
+ if (isAbsent(lifecycle))
859
+ return true;
860
+ const phase = own(lifecycle, "phase");
861
+ const bootError = !isAbsent(own(rec, "lastBootError"));
862
+ if (bootError !== (phase === "down"))
863
+ return R_LIFECYCLE_DERIVED.test(undefined, pathAt(path, "lastBootError"));
864
+ if (phase !== "attached" && phase !== "pending" && !isAbsent(own(rec, "mcp")))
865
+ return R_LIFECYCLE_WITHDRAWN.test(undefined, pathAt(path, "mcp"));
866
+ if (phase === "waiting" && own(lifecycle, "why") !== "unanswered" && !isAbsent(own(lifecycle, "unverifiable")))
867
+ return R_UNANSWERED_ONLY.test(undefined, pathAt(pathAt(path, "lifecycle"), "unverifiable"));
868
+ return true;
869
+ },
870
+ };
770
871
  const ENGINE_TARGET_STATE = shapeRule("engine target", {
771
872
  mode: reqF(R_ENGINE_LANE),
772
873
  generation: reqF(R_INT0),
@@ -794,6 +895,8 @@ const ENGINE_TARGET_REFUSED_SPEC = {
794
895
  detail: optF(R_STR),
795
896
  };
796
897
  const checkEngineTargetResult = seatShapeCheck(okArmsRule("engineTarget result", {}, ENGINE_TARGET_REFUSED_SPEC));
898
+ const checkEngineSwapAnswerOutcome = seatShapeCheck(oneOfRule("swap answer", ENGINE_SWAP_ANSWER_OUTCOMES));
899
+ const checkSelfUpgradeOutcome = seatShapeCheck(oneOfRule("self upgrade", SELF_UPGRADE_OUTCOMES));
797
900
  const checkCancelCloudLogin = seatShapeCheck(shapeRule("cancel ack", { ok: reqF(R_BOOL) }));
798
901
  const checkCloudLoginStart = seatShapeCheck(okArmsRule("startCloudLogin result", {
799
902
  verificationUri: reqF(R_DISPLAY_URL),
@@ -1240,11 +1343,77 @@ const checkLocalSessionRecord = seatCheck((s) => {
1240
1343
  if (!isAbsent(lane) && (typeof lane !== "string" || lane.length === 0)) {
1241
1344
  return bad("executionLane must be a non-empty string when present (absent = no writer lane reading)", "executionLane");
1242
1345
  }
1346
+ const parkedRows = own(s, "parkedUnresumable");
1347
+ if (!isAbsent(parkedRows)) {
1348
+ const verdict = R_PARKED_UNRESUMABLE.test(parkedRows, "parkedUnresumable");
1349
+ if (verdict !== true)
1350
+ return verdict;
1351
+ if (parked === false)
1352
+ return bad("bad value (parked:false)", "parkedUnresumable");
1353
+ }
1243
1354
  return true;
1244
1355
  });
1245
1356
  export function isLocalSessionRecord(s) {
1246
1357
  return checkLocalSessionRecord(s) === true;
1247
1358
  }
1359
+ const checkParkedUnresumableSlot = seatCheck((v) => R_PARKED_UNRESUMABLE.test(v, "parkedUnresumable"));
1360
+ const parkedVerdictCopy = (rv) => {
1361
+ const kind = own(rv, "kind");
1362
+ const str = (k) => {
1363
+ const x = own(rv, k);
1364
+ return typeof x === "string" ? x : undefined;
1365
+ };
1366
+ const sentence = str("sentence");
1367
+ if (kind === "lacking" || kind === "damaged") {
1368
+ const reason = str("reason");
1369
+ const requires = own(rv, "requires");
1370
+ return Object.freeze({
1371
+ kind,
1372
+ code: str("code") ?? "",
1373
+ ...(reason !== undefined ? { reason } : {}),
1374
+ ...(Array.isArray(requires) ? { requires: Object.freeze(ownItems(requires).filter((w) => typeof w === "string")) } : {}),
1375
+ sentence: sentence ?? "",
1376
+ });
1377
+ }
1378
+ if (kind === "unknown")
1379
+ return Object.freeze({ kind, word: str("word") ?? "", ...(sentence !== undefined ? { sentence } : {}) });
1380
+ return Object.freeze({ kind: "unreadable" });
1381
+ };
1382
+ const parkedRowCopy = (item) => {
1383
+ const str = (k) => {
1384
+ const x = own(item, k);
1385
+ return typeof x === "string" ? x : undefined;
1386
+ };
1387
+ const rv = own(item, "rowVerdict");
1388
+ const rowKey = str("rowKey");
1389
+ const taskId = str("taskId");
1390
+ const toolName = str("toolName");
1391
+ const rowDeadline = str("rowDeadline");
1392
+ return Object.freeze({
1393
+ rowVerdict: parkedVerdictCopy(typeof rv === "object" && rv !== null ? rv : {}),
1394
+ ...(rowKey !== undefined ? { rowKey } : {}),
1395
+ ...(taskId !== undefined ? { taskId } : {}),
1396
+ ...(toolName !== undefined ? { toolName } : {}),
1397
+ ...(rowDeadline === "armed" || rowDeadline === "none" ? { rowDeadline } : {}),
1398
+ });
1399
+ };
1400
+ export function readSeatParkedUnresumable(record) {
1401
+ try {
1402
+ if (typeof record !== "object" || record === null)
1403
+ return undefined;
1404
+ const v = own(record, "parkedUnresumable");
1405
+ if (isAbsent(v))
1406
+ return undefined;
1407
+ if (own(record, "parked") === false)
1408
+ return undefined;
1409
+ if (checkParkedUnresumableSlot(v) !== true)
1410
+ return undefined;
1411
+ return Object.freeze(ownItems(v).map((item) => parkedRowCopy(item)));
1412
+ }
1413
+ catch {
1414
+ return undefined;
1415
+ }
1416
+ }
1248
1417
  const checkToctouBinding = seatCheck((v) => {
1249
1418
  if (!isPlainRecord(v))
1250
1419
  return bad("toctouBinding must be a plain object", "toctouBinding");
@@ -1898,6 +2067,8 @@ export const LOCAL_SESSIONS_SPEC = {
1898
2067
  connectCloudEngine: { kind: "invoke", check: checkCloudConnectResult },
1899
2068
  configureCloudEngine: { kind: "invoke", check: checkCloudConnectResult },
1900
2069
  clearCloudEngine: { kind: "invoke", check: checkEngineTargetResult },
2070
+ answerEngineSwap: { kind: "invoke", check: checkEngineSwapAnswerOutcome },
2071
+ beginSelfUpgrade: { kind: "invoke", check: checkSelfUpgradeOutcome },
1901
2072
  listOnboardProviders: { kind: "invoke", check: checkOnboardProvidersResult },
1902
2073
  probeOnboardEntry: { kind: "invoke", check: checkOnboardProbeResult },
1903
2074
  applyOnboardEntry: { kind: "invoke", check: checkOnboardApplyResult },
@@ -1950,6 +2121,8 @@ export const SEAT_METHOD_NAMES = [
1950
2121
  "connectCloudEngine",
1951
2122
  "configureCloudEngine",
1952
2123
  "clearCloudEngine",
2124
+ "answerEngineSwap",
2125
+ "beginSelfUpgrade",
1953
2126
  "listOnboardProviders",
1954
2127
  "probeOnboardEntry",
1955
2128
  "applyOnboardEntry",
@@ -2024,6 +2197,7 @@ export const LOCAL_SESSION_RECORD_KEYS = [
2024
2197
  "thinkingLatch",
2025
2198
  "engine",
2026
2199
  "executionLane",
2200
+ "parkedUnresumable",
2027
2201
  ];
2028
2202
  export const SEND_MESSAGE_REQUEST_KEYS = [
2029
2203
  "sessionId",
@@ -2068,7 +2242,7 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
2068
2242
  LocalSessionRecord: {
2069
2243
  guard: "isLocalSessionRecord",
2070
2244
  check: checkLocalSessionRecord,
2071
- validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned", "rowTag", "unreadable", "thinkingLatch", "engine", "executionLane"],
2245
+ validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned", "rowTag", "unreadable", "thinkingLatch", "engine", "executionLane", "parkedUnresumable"],
2072
2246
  unchecked: [],
2073
2247
  },
2074
2248
  ToolPermissionRequest: {
@@ -2341,6 +2515,8 @@ export const SEAT_VALIDATOR_COVERAGE_EXEMPT = [
2341
2515
  ["SetComputerUseResult", checkSetComputerUseResult],
2342
2516
  ["SetComputerUseRequest", checkSetComputerUseRequest],
2343
2517
  ["SeatAction", checkSeatAction],
2518
+ ["EngineSwapAnswerOutcome", checkEngineSwapAnswerOutcome],
2519
+ ["SelfUpgradeOutcome", checkSelfUpgradeOutcome],
2344
2520
  ].map(([label, check]) => ({
2345
2521
  label,
2346
2522
  check,
@@ -2404,5 +2580,6 @@ const _seatContractPins = [
2404
2580
  true, true, true, true,
2405
2581
  true, true,
2406
2582
  true, true, true, true, true, true, true,
2583
+ true, true, true, true, true, true, true, true,
2407
2584
  ];
2408
2585
  void _seatContractPins;
@@ -34,6 +34,8 @@ export function readSessionBackgroundable(baseUrl = engineWireTargetBaseUrl()) {
34
34
  return Object.freeze({ kind: 'unobserved' });
35
35
  }
36
36
  }
37
+ const localEngineLanePin = true;
38
+ void localEngineLanePin;
37
39
  export const OPENING_RECORD_CAP = 256;
38
40
  const wireStates = new WeakMap();
39
41
  const isObj = (v) => (typeof v === 'object' && v !== null) || typeof v === 'function';
@@ -49,6 +49,18 @@ export declare function __resetSubagentContentStoreConfigForTests(): void;
49
49
  export declare function bindSubagentIdentityReader(fn: (id: string) => readonly string[] | undefined): void;
50
50
  export declare function registerSubagentContentAlias(parentToolCallId: string, taskId: string): void;
51
51
  export declare function registerSubagentAlias(parentToolCallId: string, taskId: string): void;
52
+ export declare const SUBAGENT_ALIAS_SCOPES: readonly ["content", "full"];
53
+ export type SubagentAliasScope = (typeof SUBAGENT_ALIAS_SCOPES)[number];
54
+ export type SubagentAliasOutcome = 'new' | 'unchanged' | 'rejected';
55
+ export declare function applySubagentAlias(parentToolCallId: string, taskId: string, scope: SubagentAliasScope, seq?: number): SubagentAliasOutcome;
56
+ export interface SeatSubagentAlias {
57
+ readonly parentToolCallId: string;
58
+ readonly taskId: string;
59
+ readonly scope: SubagentAliasScope;
60
+ readonly seq?: number;
61
+ }
62
+ export declare function readSeatSubagentAlias(ev: object | null | undefined): SeatSubagentAlias | undefined;
63
+ export declare function noteSeatSubagentAlias(ev: object | null | undefined): 'registered' | 'ignored';
52
64
  export declare function publishSubagentContentEvent(ev: SubagentContentEvent): void;
53
65
  export declare function pushSubagentLocalEcho(taskId: string, text: string): void;
54
66
  export interface SubagentContentSnapshot {