@sema-agent/client-core 0.104.1 → 0.106.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 (175) hide show
  1. package/CHANGELOG.md +310 -0
  2. package/README.md +36 -14
  3. package/dist/adapt/arms.js +23 -6
  4. package/dist/adapter/activeRunSelfHeal.d.ts +14 -2
  5. package/dist/adapter/activeRunSelfHeal.js +90 -12
  6. package/dist/adapter/downstream/eventToSdkMessage.d.ts +0 -5
  7. package/dist/adapter/downstream/eventToSdkMessage.js +24 -23
  8. package/dist/adapter/downstream/terminalToSdkResult.js +2 -3
  9. package/dist/adapter/downstream/wiringManifestView.d.ts +7 -3
  10. package/dist/adapter/downstream/wiringManifestView.js +25 -1
  11. package/dist/adapter/runStream.js +8 -5
  12. package/dist/approvalReachWire.d.ts +1 -0
  13. package/dist/approvalReachWire.js +4 -1
  14. package/dist/approvalSeat.d.ts +21 -0
  15. package/dist/approvalSeat.js +73 -0
  16. package/dist/assistantInbox.d.ts +2 -0
  17. package/dist/assistantInbox.js +3 -0
  18. package/dist/checkpointRowVerdict.d.ts +23 -0
  19. package/dist/checkpointRowVerdict.js +89 -0
  20. package/dist/cloudConfigWireCaps.js +3 -0
  21. package/dist/compensations.js +6 -6
  22. package/dist/coreValuePorts.d.ts +14 -1
  23. package/dist/coreValuePorts.js +14 -0
  24. package/dist/decideFailureNote.js +3 -1
  25. package/dist/decideReceipt.d.ts +9 -0
  26. package/dist/decideReceipt.js +29 -1
  27. package/dist/declared/supportFloorDeclared.js +2 -2
  28. package/dist/deviceRebind.d.ts +7 -0
  29. package/dist/deviceRebind.js +39 -5
  30. package/dist/displayUntrusted.d.ts +4 -2
  31. package/dist/displayUntrusted.js +45 -22
  32. package/dist/engineAddress.d.ts +3 -0
  33. package/dist/engineAddress.js +25 -0
  34. package/dist/engineDirectory.js +9 -17
  35. package/dist/engineErrorCodes.d.ts +8 -0
  36. package/dist/engineErrorCodes.js +8 -0
  37. package/dist/engineGenerationPort.d.ts +11 -2
  38. package/dist/engineGenerationPort.js +63 -9
  39. package/dist/engineHealthFacts.d.ts +5 -0
  40. package/dist/engineHealthFacts.js +11 -0
  41. package/dist/engineNoticeCodes.d.ts +26 -3
  42. package/dist/engineNoticeCodes.js +52 -7
  43. package/dist/engineRowRef.js +1 -1
  44. package/dist/errorSupplementRoles.js +2 -0
  45. package/dist/eventLeg.d.ts +3 -3
  46. package/dist/eventLeg.js +25 -4
  47. package/dist/fleet/fleetProjection.js +26 -5
  48. package/dist/generated/engineFactTables.d.ts +3 -1
  49. package/dist/generated/engineFactTables.js +4 -1
  50. package/dist/generated/engineNoticeTables.js +19 -4
  51. package/dist/generated/sdkFactTables.d.ts +5 -0
  52. package/dist/generated/sdkFactTables.js +24 -0
  53. package/dist/generated/settingsSchemaFns.d.ts +11 -0
  54. package/dist/generated/settingsSchemaFns.js +2 -1
  55. package/dist/generated/settingsSchemaSafetyMergeSpec.js +1 -1
  56. package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -1
  57. package/dist/generated/settingsSchemaSettingsSources.js +22 -2
  58. package/dist/headlessReconnectWire.js +31 -4
  59. package/dist/hitl/approvalLiveFace.d.ts +17 -0
  60. package/dist/hitl/approvalLiveFace.js +35 -0
  61. package/dist/hitl/approvalQueueRow.d.ts +21 -0
  62. package/dist/hitl/approvalQueueRow.js +69 -0
  63. package/dist/hitl/approvalsFeed.d.ts +5 -4
  64. package/dist/hitl/approvalsFeed.js +38 -6
  65. package/dist/hitl/askGateWire.js +26 -2
  66. package/dist/hitl/askParkRowRouting.d.ts +4 -3
  67. package/dist/hitl/askParkRowRouting.js +15 -3
  68. package/dist/hitl/automaticAnswerVerdict.js +13 -10
  69. package/dist/hitl/crashConverged.d.ts +5 -1
  70. package/dist/hitl/decisionConflict.js +2 -1
  71. package/dist/hitl/decisionRefusal.js +1 -1
  72. package/dist/hitl/decisionSend.d.ts +1 -0
  73. package/dist/hitl/decisionSend.js +14 -2
  74. package/dist/hitl/frameRouter.d.ts +4 -0
  75. package/dist/hitl/frameRouter.js +18 -5
  76. package/dist/hitl/gateIdentity.d.ts +1 -0
  77. package/dist/hitl/gateIdentity.js +3 -0
  78. package/dist/hitl/hitlBridge.d.ts +1 -1
  79. package/dist/hitl/hitlBridge.js +26 -5
  80. package/dist/hitl/livePendingAsk.d.ts +5 -0
  81. package/dist/hitl/livePendingAsk.js +6 -1
  82. package/dist/hitl/planReviewCard.d.ts +23 -0
  83. package/dist/hitl/planReviewCard.js +250 -0
  84. package/dist/hitl/planReviewWire.d.ts +39 -14
  85. package/dist/hitl/planReviewWire.js +450 -163
  86. package/dist/hitl/sessionAllowRoute.d.ts +2 -0
  87. package/dist/hitl/sessionAllowRoute.js +7 -0
  88. package/dist/hitl/sessionPolicyWire.d.ts +1 -7
  89. package/dist/hitl/sessionPolicyWire.js +3 -43
  90. package/dist/hitl/subagentSource.d.ts +1 -0
  91. package/dist/hitl/subagentSource.js +13 -0
  92. package/dist/hitl/toolApprovalWire.d.ts +3 -2
  93. package/dist/hitl/toolApprovalWire.js +79 -37
  94. package/dist/hostSettingsSource.d.ts +5 -2
  95. package/dist/hostSettingsSource.js +19 -10
  96. package/dist/hostTurnSettings.d.ts +5 -6
  97. package/dist/hostTurnSettings.js +106 -26
  98. package/dist/i18n/messages.en.d.ts +85 -12
  99. package/dist/i18n/messages.en.js +85 -12
  100. package/dist/i18n/messages.zh.js +88 -12
  101. package/dist/index.d.ts +35 -4
  102. package/dist/index.js +19 -2
  103. package/dist/liveInitToolFace.js +0 -1
  104. package/dist/liveModelCatalog.d.ts +15 -0
  105. package/dist/liveModelCatalog.js +40 -0
  106. package/dist/mcpTransportKindsCapability.d.ts +18 -0
  107. package/dist/mcpTransportKindsCapability.js +75 -0
  108. package/dist/mcpWireCaps.d.ts +4 -1
  109. package/dist/mcpWireCaps.js +25 -14
  110. package/dist/modelCapabilityProbe.js +66 -33
  111. package/dist/notifications.d.ts +9 -0
  112. package/dist/notifications.js +11 -2
  113. package/dist/ownKey.d.ts +4 -1
  114. package/dist/ownKey.js +8 -2
  115. package/dist/permissionModeWriteCapability.d.ts +13 -0
  116. package/dist/permissionModeWriteCapability.js +35 -0
  117. package/dist/permissionsAllowGrantCapability.d.ts +3 -0
  118. package/dist/permissionsAllowGrantCapability.js +26 -3
  119. package/dist/permissionsDeclaration.d.ts +25 -3
  120. package/dist/permissionsDeclaration.js +69 -41
  121. package/dist/planReviewCardFacts.d.ts +116 -0
  122. package/dist/planReviewCardFacts.js +469 -0
  123. package/dist/projectSeed.d.ts +39 -0
  124. package/dist/projectSeed.js +80 -0
  125. package/dist/promptDelivery.js +1 -1
  126. package/dist/reattachWindow.d.ts +8 -1
  127. package/dist/reattachWindow.js +44 -12
  128. package/dist/replayBody.d.ts +7 -6
  129. package/dist/replayBody.js +62 -7
  130. package/dist/request/taskRequest.js +3 -4
  131. package/dist/ruleCompileVerdict.d.ts +0 -2
  132. package/dist/ruleCompileVerdict.js +0 -31
  133. package/dist/ruleRefusalSentence.js +0 -3
  134. package/dist/runFollow.d.ts +30 -0
  135. package/dist/runFollow.js +117 -0
  136. package/dist/runLedgerSnapshot.d.ts +20 -0
  137. package/dist/runLedgerSnapshot.js +272 -0
  138. package/dist/runPermissionModeSwitch.d.ts +57 -0
  139. package/dist/runPermissionModeSwitch.js +135 -0
  140. package/dist/runReattachPolicy.d.ts +16 -5
  141. package/dist/runReattachPolicy.js +72 -24
  142. package/dist/runTerminal.js +30 -8
  143. package/dist/sandboxWire.d.ts +0 -3
  144. package/dist/sandboxWire.js +0 -9
  145. package/dist/seam.d.ts +17 -7
  146. package/dist/seam.js +13 -1
  147. package/dist/seatContract.d.ts +57 -7
  148. package/dist/seatContract.js +133 -3
  149. package/dist/serverSupportRange.d.ts +18 -0
  150. package/dist/serverSupportRange.js +25 -0
  151. package/dist/sessionEngine.d.ts +156 -0
  152. package/dist/sessionEngine.js +464 -0
  153. package/dist/sessionMap.d.ts +11 -1
  154. package/dist/sessionMap.js +35 -9
  155. package/dist/sessionMemoryErase.d.ts +1 -1
  156. package/dist/sessionMemoryErase.js +5 -0
  157. package/dist/sessionMemoryStatus.d.ts +27 -1
  158. package/dist/sessionMemoryStatus.js +117 -0
  159. package/dist/sessionMemorySync.d.ts +31 -0
  160. package/dist/sessionMemorySync.js +95 -0
  161. package/dist/sessionRowTag.d.ts +4 -0
  162. package/dist/sessionRowTag.js +18 -0
  163. package/dist/settingsLayerAdmission.d.ts +1 -0
  164. package/dist/settingsLayerAdmission.js +4 -1
  165. package/dist/sseIdleTriage.d.ts +3 -1
  166. package/dist/sseIdleTriage.js +19 -4
  167. package/dist/subagent/engineSubagentTail.js +2 -0
  168. package/dist/subagentContentStore.d.ts +3 -0
  169. package/dist/subagentContentStore.js +10 -1
  170. package/dist/toolResult.js +1 -1
  171. package/dist/turnFailurePresentation.d.ts +5 -2
  172. package/dist/turnFailurePresentation.js +12 -4
  173. package/dist/wireRefusalCopy.js +2 -6
  174. package/docs/INTEGRATION-CLIENTS.md +1507 -18
  175. package/package.json +5 -5
@@ -1,22 +1,41 @@
1
+ import { tupleOriginUrlOf } from './engineAddress.js';
2
+ import { readOwnDataValue } from './ownKey.js';
1
3
  export function engineNamespaceKeyFor(baseUrl) {
2
4
  if (!baseUrl)
3
5
  return 'local';
4
- try {
5
- const u = new URL(baseUrl);
6
- if (!/^(?:https?|wss?|ftp):$/.test(u.protocol))
7
- return baseUrl.toLowerCase();
8
- return u.origin.toLowerCase() + u.pathname.replace(/\/+$/, '');
9
- }
10
- catch {
6
+ const u = tupleOriginUrlOf(baseUrl);
7
+ if (u === undefined)
11
8
  return baseUrl.toLowerCase();
12
- }
9
+ return u.origin.toLowerCase() + u.pathname.replace(/\/+$/, '');
10
+ }
11
+ function boundEntryKept(prior, nextEngines) {
12
+ const key = prior?.boundEngine?.key;
13
+ if (typeof key !== 'string')
14
+ return true;
15
+ const before = prior?.engines !== undefined && Object.hasOwn(prior.engines, key) ? prior.engines[key] : undefined;
16
+ const has = nextEngines !== undefined && nextEngines !== null && Object.hasOwn(nextEngines, key);
17
+ const after = has ? readOwnDataValue(nextEngines, key) : undefined;
18
+ if (has && after === undefined)
19
+ return false;
20
+ if (before === undefined || after === undefined)
21
+ return before === after;
22
+ if (after === before)
23
+ return true;
24
+ return typeof after === 'object' && after !== null && readOwnDataValue(after, 'engineSessionId') === before.engineSessionId;
13
25
  }
14
26
  const isoNow = () => new Date().toISOString();
15
27
  export function mergeSessionMapRecord(prior, partial, now = isoNow) {
16
28
  const shellSessionId = partial.shellSessionId ?? prior?.shellSessionId;
17
29
  if (!shellSessionId)
18
30
  return { ok: false, reason: 'no-shell-session-id' };
19
- return { ok: true, record: { ...prior, ...partial, shellSessionId, updatedAt: now() } };
31
+ const record = { ...prior, ...partial, shellSessionId, updatedAt: now() };
32
+ if (prior?.boundEngine !== undefined)
33
+ record.boundEngine = prior.boundEngine;
34
+ else
35
+ delete record.boundEngine;
36
+ if (!boundEntryKept(prior, record.engines))
37
+ return { ok: false, reason: 'bound-entry-conflict' };
38
+ return { ok: true, record };
20
39
  }
21
40
  export function mergeEngineEntry(prior, key, partial, shellSessionId, now = isoNow) {
22
41
  const priorEntry = prior?.engines?.[key];
@@ -26,6 +45,13 @@ export function mergeEngineEntry(prior, key, partial, shellSessionId, now = isoN
26
45
  const sid = shellSessionId ?? prior?.shellSessionId;
27
46
  if (!sid)
28
47
  return { ok: false, reason: 'no-shell-session-id' };
48
+ if (prior?.boundEngine !== undefined && key === prior.boundEngine.key) {
49
+ if (priorEntry === undefined ||
50
+ engineSessionId !== priorEntry.engineSessionId ||
51
+ (Object.hasOwn(partial, 'engineSessionId') && readOwnDataValue(partial, 'engineSessionId') !== priorEntry.engineSessionId)) {
52
+ return { ok: false, reason: 'bound-entry-conflict' };
53
+ }
54
+ }
29
55
  const entry = { ...priorEntry, ...partial, engineSessionId, updatedAt: now() };
30
56
  return {
31
57
  ok: true,
@@ -33,7 +33,7 @@ export type SessionMemoryEraseAnswer = {
33
33
  detail: string;
34
34
  };
35
35
  export declare function eraseSessionMemory(call: SessionMemoryEraseCall, wire: SessionMemoryEraseWire, opts?: SessionMemoryEraseOptions): Promise<SessionMemoryEraseAnswer>;
36
- export type SessionMemoryEraseRefusalReason = 'bad_input' | 'no_connection' | 'cancelled_before_send' | 'credentials_required' | 'not_permitted' | 'memory_engine_absent' | 'session_not_found' | 'route_absent' | 'request_rejected' | 'evidence_unavailable' | 'request_id_reused' | 'store_unreadable';
36
+ export type SessionMemoryEraseRefusalReason = 'bad_input' | 'no_connection' | 'cancelled_before_send' | 'credentials_required' | 'not_permitted' | 'memory_engine_absent' | 'session_not_found' | 'route_absent' | 'request_rejected' | 'evidence_unavailable' | 'request_id_reused' | 'store_unreadable' | 'personal_store_unjudged';
37
37
  export type SessionMemoryEraseUnconfirmedWhy = 'no_answer' | 'receipt_unreadable' | 'receipt_mismatch' | 'store_link_outside' | 'store_home_not_directory' | 'control_plane_corrupt' | 'engine_fault' | 'unclassified' | 'no_code' | 'unreadable';
38
38
  export type SessionMemoryEraseRetry = 'not_needed' | 'same_request_id' | 'new_request_id' | 'needs_operator' | 'needs_consent' | 'human_decision' | 'pointless';
39
39
  type SessionMemoryEraseReceipt = Extract<MemoryEraseReceiptReading, {
@@ -3,6 +3,7 @@ import { INJECTED_WIRE_SETTLE_MS, connectionLostDetail, noAnswerDetailFrom, noAn
3
3
  import { memoryEraseReplayPosture, readMemoryEraseReceipt } from './memoryEntriesWire.js';
4
4
  import { normalizeWirePrincipal } from './principalWire.js';
5
5
  import { isSessionIdPathSegment } from './sessionIdSegment.js';
6
+ import { msg, renderMessage } from './i18n/translate.js';
6
7
  const PRINCIPAL_HEADER = 'x-agent-principal';
7
8
  const MAX_TIMER_MS = 2_147_483_647;
8
9
  const NOT_SENT = ' — nothing was sent';
@@ -231,6 +232,7 @@ const REFUSAL_TEXT = {
231
232
  evidence_unavailable: "Nothing was erased: this deployment's memory store cannot keep proof of an erase, so the erase was declined.",
232
233
  request_id_reused: 'Nothing was erased: this request id was already used for a different erase.',
233
234
  store_unreadable: 'Nothing was erased: part of the memory store could not be read, so the erase was declined before anything changed; the deployment operator needs to repair the store.',
235
+ personal_store_unjudged: renderMessage(msg('session.memoryErase.personalStoreUnjudged')),
234
236
  };
235
237
  const UNCONFIRMED_TEXT = {
236
238
  no_answer: 'Not confirmed: no answer came back from the engine, so the erase may or may not have happened.',
@@ -290,6 +292,7 @@ const REFUSAL_RETRY = {
290
292
  evidence_unavailable: 'needs_consent',
291
293
  request_id_reused: 'new_request_id',
292
294
  store_unreadable: 'needs_operator',
295
+ personal_store_unjudged: 'pointless',
293
296
  };
294
297
  export const SESSION_MEMORY_ERASE_REFUSAL_REASONS = Object.freeze(Object.keys(REFUSAL_TEXT));
295
298
  export const SESSION_MEMORY_ERASE_UNCONFIRMED_WHYS = Object.freeze(Object.keys(UNCONFIRMED_TEXT));
@@ -350,6 +353,8 @@ function bandOfCode(code) {
350
353
  return { refused: 'request_id_reused' };
351
354
  case 'memory.erasure_census_incomplete':
352
355
  return { refused: 'store_unreadable' };
356
+ case 'memory.erasure_store_unjudged':
357
+ return { refused: 'personal_store_unjudged' };
353
358
  case 'memory.target_outside_store':
354
359
  return { unconfirmed: 'store_link_outside' };
355
360
  case 'memory.scope_home_not_directory':
@@ -1,4 +1,5 @@
1
1
  import type { SessionMemoryStatus, SessionMemoryStatusResponse } from '@sema-agent/sdk';
2
+ import { type UiLanguage } from './env/uiLanguage.js';
2
3
  export interface MemoryStatusClientLike {
3
4
  sessions: {
4
5
  memoryStatus(sessionId: string, opts?: {
@@ -8,7 +9,17 @@ export interface MemoryStatusClientLike {
8
9
  } & SessionMemoryStatus>;
9
10
  };
10
11
  }
11
- export type MemoryStatusFacts = Omit<SessionMemoryStatusResponse, 'sessionId'>;
12
+ export type MemoryStatusFacts = Omit<SessionMemoryStatusResponse, 'sessionId' | 'memorySync'> & {
13
+ readonly memorySync?: MemorySyncFacts;
14
+ };
15
+ export interface MemorySyncFacts {
16
+ readonly parked: readonly MemorySyncParkedFacts[];
17
+ }
18
+ export interface MemorySyncParkedFacts {
19
+ readonly scope: string;
20
+ readonly wayOut: string;
21
+ }
22
+ export declare const MEMORY_SYNC_WAY_OUT_DELETE_CURSOR: "delete_cursor";
12
23
  export type MemoryStatusVerdict = {
13
24
  readonly kind: 'ok';
14
25
  readonly sessionId: string;
@@ -44,4 +55,19 @@ export declare function readLastCapture(s: SessionMemoryStatus): LastCaptureRead
44
55
  export declare function readSessionMemoryStatus(client: MemoryStatusClientLike, sessionId: string, opts?: {
45
56
  signal?: AbortSignal;
46
57
  }): Promise<MemoryStatusVerdict>;
58
+ export type MemorySyncParkingReading = {
59
+ readonly state: 'syncing';
60
+ } | {
61
+ readonly state: 'parked';
62
+ readonly layers: readonly MemorySyncParkedLayerReading[];
63
+ } | {
64
+ readonly state: 'not_reported';
65
+ };
66
+ export interface MemorySyncParkedLayerReading {
67
+ readonly scope: string;
68
+ readonly wayOut: string;
69
+ readonly deleteCursor: boolean;
70
+ }
71
+ export declare function readMemorySyncParking(facts: MemoryStatusFacts | null | undefined): MemorySyncParkingReading;
72
+ export declare function memorySyncParkingNotice(reading: MemorySyncParkingReading, lang?: UiLanguage | (string & {})): string | undefined;
47
73
  export declare function readAutoConsolidationArmed(facts: MemoryStatusFacts | null | undefined): 'armed' | 'unarmed' | 'indeterminate';
@@ -1,5 +1,9 @@
1
1
  import { isSessionIdPathSegment } from './sessionIdSegment.js';
2
2
  import { readThrownSlot, THROWN_SLOT_UNREADABLE } from './wireFailureShape.js';
3
+ import { isUiLanguage } from './env/uiLanguage.js';
4
+ import { msg, renderMessage } from './i18n/translate.js';
5
+ export const MEMORY_SYNC_WAY_OUT_DELETE_CURSOR = 'delete_cursor';
6
+ const MEMORY_SYNC_PARKED_READ_MAX = 256;
3
7
  export function classifyMemoryStatusFailure(e) {
4
8
  const rawCode = readThrownSlot(e, 'errorCode', 'data');
5
9
  const rawStatus = readThrownSlot(e, 'status', 'data');
@@ -64,6 +68,7 @@ export async function readSessionMemoryStatus(client, sessionId, opts) {
64
68
  : {}),
65
69
  ...(typeof o.lastCaptureAt === 'number' ? { lastCaptureAt: o.lastCaptureAt } : {}),
66
70
  ...(typeof o.autoConsolidationArmed === 'boolean' ? { autoConsolidationArmed: o.autoConsolidationArmed } : {}),
71
+ ...memorySyncSpread(o),
67
72
  },
68
73
  };
69
74
  }
@@ -71,6 +76,118 @@ export async function readSessionMemoryStatus(client, sessionId, opts) {
71
76
  return classifyMemoryStatusFailure(e);
72
77
  }
73
78
  }
79
+ function ownDataSlot(o, key) {
80
+ try {
81
+ const d = Object.getOwnPropertyDescriptor(o, key);
82
+ if (d === undefined)
83
+ return { ok: true, value: undefined };
84
+ return Object.hasOwn(d, 'value') ? { ok: true, value: d.value } : { ok: false };
85
+ }
86
+ catch {
87
+ return { ok: false };
88
+ }
89
+ }
90
+ const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
91
+ function memorySyncFactsOf(raw) {
92
+ try {
93
+ if (!isPlainObject(raw))
94
+ return undefined;
95
+ const parkedSlot = ownDataSlot(raw, 'parked');
96
+ if (!parkedSlot.ok || !Array.isArray(parkedSlot.value))
97
+ return undefined;
98
+ const arr = parkedSlot.value;
99
+ const len = ownDataSlot(arr, 'length');
100
+ if (!len.ok || typeof len.value !== 'number' || !Number.isSafeInteger(len.value) || len.value < 0 || len.value > MEMORY_SYNC_PARKED_READ_MAX)
101
+ return undefined;
102
+ const parked = [];
103
+ for (let i = 0; i < len.value; i++) {
104
+ const el = ownDataSlot(arr, String(i));
105
+ if (!el.ok || !isPlainObject(el.value))
106
+ return undefined;
107
+ const scope = ownDataSlot(el.value, 'scope');
108
+ const wayOut = ownDataSlot(el.value, 'wayOut');
109
+ if (!scope.ok || !wayOut.ok || typeof scope.value !== 'string' || scope.value.length === 0 || typeof wayOut.value !== 'string' || wayOut.value.length === 0)
110
+ return undefined;
111
+ parked.push(Object.freeze({ scope: scope.value, wayOut: wayOut.value }));
112
+ }
113
+ return Object.freeze({ parked: Object.freeze(parked) });
114
+ }
115
+ catch {
116
+ return undefined;
117
+ }
118
+ }
119
+ function memorySyncSpread(o) {
120
+ const slot = ownDataSlot(o, 'memorySync');
121
+ if (!slot.ok || slot.value === undefined)
122
+ return {};
123
+ const facts = memorySyncFactsOf(slot.value);
124
+ return facts === undefined ? {} : { memorySync: facts };
125
+ }
126
+ export function readMemorySyncParking(facts) {
127
+ let sync;
128
+ try {
129
+ if (!isPlainObject(facts))
130
+ return Object.freeze({ state: 'not_reported' });
131
+ const slot = ownDataSlot(facts, 'memorySync');
132
+ sync = slot.ok ? memorySyncFactsOf(slot.value) : undefined;
133
+ }
134
+ catch {
135
+ sync = undefined;
136
+ }
137
+ if (sync === undefined)
138
+ return Object.freeze({ state: 'not_reported' });
139
+ if (sync.parked.length === 0)
140
+ return Object.freeze({ state: 'syncing' });
141
+ return Object.freeze({
142
+ state: 'parked',
143
+ layers: Object.freeze(sync.parked.map((p) => Object.freeze({ scope: p.scope, wayOut: p.wayOut, deleteCursor: p.wayOut === MEMORY_SYNC_WAY_OUT_DELETE_CURSOR }))),
144
+ });
145
+ }
146
+ const MEMORY_SYNC_SCOPE_NAME_MAX = 120;
147
+ export function memorySyncParkingNotice(reading, lang) {
148
+ try {
149
+ if (typeof reading !== 'object' || reading === null)
150
+ return undefined;
151
+ const state = Object.getOwnPropertyDescriptor(reading, 'state');
152
+ if (state === undefined || !Object.hasOwn(state, 'value') || state.value !== 'parked')
153
+ return undefined;
154
+ const layersSlot = Object.getOwnPropertyDescriptor(reading, 'layers');
155
+ if (layersSlot === undefined || !Object.hasOwn(layersSlot, 'value') || !Array.isArray(layersSlot.value))
156
+ return undefined;
157
+ const raw = layersSlot.value;
158
+ const lenSlot = Object.getOwnPropertyDescriptor(raw, 'length');
159
+ const count = lenSlot?.value;
160
+ if (typeof count !== 'number' || !Number.isSafeInteger(count) || count < 1 || count > MEMORY_SYNC_PARKED_READ_MAX)
161
+ return undefined;
162
+ const scopes = [];
163
+ let named = true;
164
+ let allDeleteCursor = true;
165
+ for (let i = 0; i < count; i++) {
166
+ const el = Object.getOwnPropertyDescriptor(raw, String(i));
167
+ const layer = el !== undefined && Object.hasOwn(el, 'value') ? el.value : undefined;
168
+ if (typeof layer !== 'object' || layer === null)
169
+ return undefined;
170
+ const scope = Object.getOwnPropertyDescriptor(layer, 'scope');
171
+ const del = Object.getOwnPropertyDescriptor(layer, 'deleteCursor');
172
+ const s = scope !== undefined && Object.hasOwn(scope, 'value') ? scope.value : undefined;
173
+ if (typeof s !== 'string' || s.length === 0 || s.length > MEMORY_SYNC_SCOPE_NAME_MAX || /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(s))
174
+ named = false;
175
+ else
176
+ scopes.push(s);
177
+ if (del === undefined || !Object.hasOwn(del, 'value') || del.value !== true)
178
+ allDeleteCursor = false;
179
+ }
180
+ const wayOut = msg(allDeleteCursor ? 'session.memorySync.wayOut.deleteCursor' : 'session.memorySync.wayOut.unrecognized');
181
+ if (!named)
182
+ return renderMessage(msg(count === 1 ? 'session.memorySync.parkedUnnamed.one' : 'session.memorySync.parkedUnnamed.other', { count, wayOut }), isUiLanguage(lang) ? lang : undefined);
183
+ if (count === 1)
184
+ return renderMessage(msg('session.memorySync.parked.one', { scope: scopes[0] ?? '', wayOut }), isUiLanguage(lang) ? lang : undefined);
185
+ return renderMessage(msg('session.memorySync.parked.other', { count, scopes: scopes.join(lang === 'zh' ? '、' : ', '), wayOut }), isUiLanguage(lang) ? lang : undefined);
186
+ }
187
+ catch {
188
+ return undefined;
189
+ }
190
+ }
74
191
  export function readAutoConsolidationArmed(facts) {
75
192
  if (typeof facts !== 'object' || facts === null)
76
193
  return 'indeterminate';
@@ -0,0 +1,31 @@
1
+ import { SDK_SESSION_MEMORY_UNOBSERVED_REASONS } from './generated/sdkFactTables.js';
2
+ import { type UiLanguage } from './env/uiLanguage.js';
3
+ type UnobservedReason = (typeof SDK_SESSION_MEMORY_UNOBSERVED_REASONS)[number];
4
+ export type SessionMemorySyncReportReading = {
5
+ readonly scopes: readonly string[];
6
+ } & ({
7
+ readonly layers: readonly object[];
8
+ readonly refused?: undefined;
9
+ } | {
10
+ readonly refused: object;
11
+ readonly layers?: undefined;
12
+ });
13
+ export type SessionMemorySyncState = {
14
+ readonly kind: 'not_configured';
15
+ readonly report: SessionMemorySyncReportReading;
16
+ } | {
17
+ readonly kind: 'reported';
18
+ readonly report: SessionMemorySyncReportReading;
19
+ } | {
20
+ readonly kind: 'unobtainable';
21
+ readonly reason?: UnobservedReason;
22
+ readonly activeTaskId?: string;
23
+ };
24
+ export type SessionMemorySyncSettled = {
25
+ readonly report: {} | null | undefined;
26
+ } | {
27
+ readonly error: {} | null | undefined;
28
+ };
29
+ export declare function sessionMemorySyncStateOf(settled: SessionMemorySyncSettled | null | undefined): SessionMemorySyncState | null;
30
+ export declare function sessionMemorySyncNotice(state: SessionMemorySyncState | null | undefined, lang?: UiLanguage | (string & {})): string | undefined;
31
+ export {};
@@ -0,0 +1,95 @@
1
+ import { CONFLICT_SESSION_MEMORY_UNOBSERVED } from './engineErrorCodes.js';
2
+ import { SDK_SESSION_MEMORY_UNOBSERVED_REASONS } from './generated/sdkFactTables.js';
3
+ import { isUiLanguage } from './env/uiLanguage.js';
4
+ import { msg, renderMessage } from './i18n/translate.js';
5
+ import { slotReadOf, isSlotCarrier, readErrorString } from './wireFailureShape.js';
6
+ import { effectiveWireErrorCode } from './wireErrorTriage.js';
7
+ const reasonOf = (v) => SDK_SESSION_MEMORY_UNOBSERVED_REASONS.find((w) => w === v);
8
+ function scopesOf(report) {
9
+ const r = slotReadOf(report, 'scopes');
10
+ if (r.presence !== 'present' || !Array.isArray(r.value))
11
+ return undefined;
12
+ const out = [];
13
+ const len = r.value.length;
14
+ if (typeof len !== 'number' || !Number.isSafeInteger(len) || len < 0)
15
+ return undefined;
16
+ for (let i = 0; i < len; i++) {
17
+ const item = r.value[i];
18
+ if (typeof item !== 'string')
19
+ return undefined;
20
+ out.push(item);
21
+ }
22
+ return out;
23
+ }
24
+ export function sessionMemorySyncStateOf(settled) {
25
+ try {
26
+ if (typeof settled !== 'object' || settled === null)
27
+ return null;
28
+ const reportSlot = slotReadOf(settled, 'report');
29
+ const errorSlot = slotReadOf(settled, 'error');
30
+ if (reportSlot.presence === 'present' && errorSlot.presence === 'absent') {
31
+ const report = reportSlot.value;
32
+ if (typeof report !== 'object' || report === null || Array.isArray(report))
33
+ return null;
34
+ const scopes = scopesOf(report);
35
+ if (scopes === undefined)
36
+ return null;
37
+ const refused = slotReadOf(report, 'refused');
38
+ const layers = slotReadOf(report, 'layers');
39
+ if (refused.presence === 'unreadable' || layers.presence === 'unreadable')
40
+ return null;
41
+ const refusedArm = refused.presence === 'present';
42
+ if (refusedArm === (layers.presence === 'present'))
43
+ return null;
44
+ if (refusedArm ? typeof refused.value !== 'object' || refused.value === null || Array.isArray(refused.value) : !Array.isArray(layers.value))
45
+ return null;
46
+ const kind = scopes.length === 0 && !refusedArm ? 'not_configured' : 'reported';
47
+ return Object.freeze({ kind, report: report });
48
+ }
49
+ if (errorSlot.presence === 'present' && reportSlot.presence === 'absent') {
50
+ const err = errorSlot.value;
51
+ if (!isSlotCarrier(err))
52
+ return null;
53
+ if (effectiveWireErrorCode(err) !== CONFLICT_SESSION_MEMORY_UNOBSERVED)
54
+ return null;
55
+ const o = err;
56
+ const reason = reasonOf(readErrorString(o, 'reason'));
57
+ const active = readErrorString(o, 'activeTaskId');
58
+ return Object.freeze({
59
+ kind: 'unobtainable',
60
+ ...(reason !== undefined ? { reason } : {}),
61
+ ...(typeof active === 'string' && active !== '' ? { activeTaskId: active } : {}),
62
+ });
63
+ }
64
+ return null;
65
+ }
66
+ catch {
67
+ return null;
68
+ }
69
+ }
70
+ const UNOBTAINABLE_KEYS = Object.freeze({
71
+ no_settled_run: 'session.memorySyncTrigger.noSettledRun',
72
+ run_result_missing: 'session.memorySyncTrigger.runUnobserved',
73
+ run_result_unobserved: 'session.memorySyncTrigger.runUnobserved',
74
+ memory_not_mounted: 'session.memorySyncTrigger.memoryNotMounted',
75
+ no_leaf: 'session.memorySyncTrigger.noLeaf',
76
+ });
77
+ export function sessionMemorySyncNotice(state, lang) {
78
+ try {
79
+ if (typeof state !== 'object' || state === null)
80
+ return undefined;
81
+ const kind = slotReadOf(state, 'kind');
82
+ if (kind.presence !== 'present')
83
+ return undefined;
84
+ if (kind.value === 'not_configured')
85
+ return renderMessage(msg('session.memorySyncTrigger.notConfigured'), isUiLanguage(lang) ? lang : undefined);
86
+ if (kind.value !== 'unobtainable')
87
+ return undefined;
88
+ const reason = slotReadOf(state, 'reason');
89
+ const word = reason.presence === 'present' && typeof reason.value === 'string' ? reasonOf(reason.value) : undefined;
90
+ return renderMessage(msg(word !== undefined ? UNOBTAINABLE_KEYS[word] : 'session.memorySyncTrigger.unobtainable'), isUiLanguage(lang) ? lang : undefined);
91
+ }
92
+ catch {
93
+ return undefined;
94
+ }
95
+ }
@@ -20,5 +20,9 @@ export type SessionRowPatchRefusal = {
20
20
  } | {
21
21
  readonly kind: 'tag-unsupported';
22
22
  };
23
+ export interface SessionRowUnreadable {
24
+ readonly errorCode?: string;
25
+ }
26
+ export declare function sessionRowUnreadableOf(row: object | null | undefined): SessionRowUnreadable | undefined;
23
27
  export declare function sessionRowTagOf(row: object | null | undefined): string | undefined;
24
28
  export declare function sessionRowPatchRefusalOf(error: {} | null | undefined, sent: Readonly<SessionRowPatchFields> | null | undefined): SessionRowPatchRefusal | null;
@@ -8,6 +8,24 @@ function ownData(v, key) {
8
8
  return undefined;
9
9
  return guardedRead(() => readOwnDataValue(v, key));
10
10
  }
11
+ export function sessionRowUnreadableOf(row) {
12
+ try {
13
+ const marker = ownData(row, 'unreadable');
14
+ if (!isPlainMarker(marker))
15
+ return undefined;
16
+ const code = ownData(marker, 'errorCode');
17
+ return Object.freeze(typeof code === 'string' && code.length > 0 ? { errorCode: code } : {});
18
+ }
19
+ catch {
20
+ return undefined;
21
+ }
22
+ }
23
+ function isPlainMarker(v) {
24
+ if (typeof v !== 'object' || v === null || Array.isArray(v))
25
+ return false;
26
+ const proto = Object.getPrototypeOf(v);
27
+ return proto === null || (typeof proto === 'object' && Object.getPrototypeOf(proto) === null);
28
+ }
11
29
  export function sessionRowTagOf(row) {
12
30
  const v = ownData(row, 'rowTag');
13
31
  return typeof v === 'string' && v.length > 0 ? v : undefined;
@@ -1,4 +1,5 @@
1
1
  import type { HostSettingsLayer, WorkspaceTrustState } from './hostSettingsSource.js';
2
+ export declare function layerAdmissionReading(trust: WorkspaceTrustState | 'unreadable'): WorkspaceTrustState;
2
3
  export declare function layerAdmissionWord(layer: HostSettingsLayer, trust: WorkspaceTrustState | 'unreadable', category: string, member?: string): string;
3
4
  export declare function layerAdmitted(layer: HostSettingsLayer, trust: WorkspaceTrustState | 'unreadable', category: string, member?: string): boolean;
4
5
  export declare function admittedLayers<L extends HostSettingsLayer>(layers: readonly L[], trust: WorkspaceTrustState | 'unreadable', category: string, member?: string): readonly L[];
@@ -1,8 +1,11 @@
1
1
  import { SETTINGS_LAYER_ADMISSION } from './generated/settingsSchemaFns.js';
2
2
  const TRUST_UNREADABLE_READING = 'declined';
3
3
  const ADMITTED = 'admitted';
4
+ export function layerAdmissionReading(trust) {
5
+ return trust === 'unreadable' ? TRUST_UNREADABLE_READING : trust;
6
+ }
4
7
  function layerAdmissionOf(layer, trust, category, member) {
5
- const reading = trust === 'unreadable' ? TRUST_UNREADABLE_READING : trust;
8
+ const reading = layerAdmissionReading(trust);
6
9
  return member === undefined ? SETTINGS_LAYER_ADMISSION(layer, reading, category) : SETTINGS_LAYER_ADMISSION(layer, reading, category, member);
7
10
  }
8
11
  export function layerAdmissionWord(layer, trust, category, member) {
@@ -1,4 +1,5 @@
1
1
  import { type EnvLike } from './hostEnv.js';
2
+ import { type RunNotFollowed } from './runFollow.js';
2
3
  export declare const SSE_HEARTBEAT_GRACE_ENV = "SEMA_SSE_HEARTBEAT_GRACE_MS";
3
4
  export declare const SSE_GRACE_MIN_MS = 5000;
4
5
  export declare const SSE_GRACE_MAX_MS = 600000;
@@ -7,9 +8,10 @@ export declare function resolveSseHeartbeatGraceMs(env?: EnvLike): number | unde
7
8
  export declare function markEngineAliveIdle<E extends Error>(err: E): E;
8
9
  export declare function engineAliveIdleElapsedMs(err: unknown): number | undefined;
9
10
  export declare function isSseIdleError(err: unknown): boolean;
11
+ export declare function isStreamEndedWithoutTerminalError(err: {} | null | undefined): boolean;
10
12
  export declare function probeEngineAlive(baseUrl: string, timeoutMs?: number): Promise<boolean>;
11
13
  export declare function diagnoseSseIdleTear<T>(inner: AsyncGenerator<T>, baseUrl: string, signal?: AbortSignal): AsyncGenerator<T>;
12
14
  export declare function engineAliveIdleContent(elapsedMs: number, detach?: {
13
15
  detached: true;
14
16
  taskId?: string;
15
- }): string;
17
+ }, notFollowed?: RunNotFollowed): string;
@@ -1,6 +1,8 @@
1
1
  import { hostEnv } from './hostEnv.js';
2
- import { SseIdleError, probeHealth as sdkProbeHealth } from '@sema-agent/sdk';
2
+ import { SseIdleError, StreamEndedWithoutTerminalError, probeHealth as sdkProbeHealth } from '@sema-agent/sdk';
3
3
  import { readThrownSlot, thrownIsInstanceOf } from './wireFailureShape.js';
4
+ import { msg, renderMessage } from './i18n/translate.js';
5
+ import { runNotFollowedNoticeRef } from './runFollow.js';
4
6
  export const SSE_HEARTBEAT_GRACE_ENV = 'SEMA_SSE_HEARTBEAT_GRACE_MS';
5
7
  export const SSE_GRACE_MIN_MS = 5_000;
6
8
  export const SSE_GRACE_MAX_MS = 600_000;
@@ -17,8 +19,12 @@ export function resolveSseHeartbeatGraceMs(env = hostEnv()) {
17
19
  return n;
18
20
  }
19
21
  export function markEngineAliveIdle(err) {
20
- ;
21
- err.semaTearVerdict = 'engine-alive-idle';
22
+ try {
23
+ ;
24
+ err.semaTearVerdict = 'engine-alive-idle';
25
+ }
26
+ catch {
27
+ }
22
28
  return err;
23
29
  }
24
30
  export function engineAliveIdleElapsedMs(err) {
@@ -32,6 +38,11 @@ export function isSseIdleError(err) {
32
38
  return true;
33
39
  return readThrownSlot(err, 'name', 'data') === 'SseIdleError';
34
40
  }
41
+ export function isStreamEndedWithoutTerminalError(err) {
42
+ if (thrownIsInstanceOf(err, StreamEndedWithoutTerminalError))
43
+ return true;
44
+ return readThrownSlot(err, 'name', 'data') === 'StreamEndedWithoutTerminalError';
45
+ }
35
46
  export async function probeEngineAlive(baseUrl, timeoutMs = 2_000) {
36
47
  return (await sdkProbeHealth(baseUrl, timeoutMs)).alive;
37
48
  }
@@ -46,8 +57,12 @@ export async function* diagnoseSseIdleTear(inner, baseUrl, signal) {
46
57
  throw err;
47
58
  }
48
59
  }
49
- export function engineAliveIdleContent(elapsedMs, detach) {
60
+ export function engineAliveIdleContent(elapsedMs, detach, notFollowed) {
50
61
  const secs = Math.max(1, Math.round((elapsedMs > 0 ? elapsedMs : SDK_DEFAULT_GRACE_MS) / 1000));
62
+ if (notFollowed !== undefined && notFollowed !== null) {
63
+ const grace = msg('follow.notFollowed.idleGrace', { env: SSE_HEARTBEAT_GRACE_ENV, min: SSE_GRACE_MIN_MS, max: SSE_GRACE_MAX_MS, default: SDK_DEFAULT_GRACE_MS });
64
+ return renderMessage(msg('follow.notFollowed.idleTear', { secs, notice: runNotFollowedNoticeRef(notFollowed), grace }));
65
+ }
51
66
  const graceTail = `If your tasks legitimately go quiet this long (e.g. a long build), raise the idle grace: set ${SSE_HEARTBEAT_GRACE_ENV} ` +
52
67
  `(settings env, integer ms, ${SSE_GRACE_MIN_MS}-${SSE_GRACE_MAX_MS}; default ${SDK_DEFAULT_GRACE_MS}).`;
53
68
  if (detach?.detached) {
@@ -6,6 +6,7 @@ import { engineSessionParamFor } from '../engineSessionParam.js';
6
6
  import { resolveOwnerContext } from './engineSubagentResume.js';
7
7
  import { coerceOutput, parentToolCallIdOf, publishSubagentContentEvent, settleSubagentContent, } from '../subagentContentStore.js';
8
8
  import { noteBgOwnerAbsence } from './subagentOwnerAbsence.js';
9
+ import { readFrameTrueMark } from '../ownKey.js';
9
10
  function usableTailClient(client) {
10
11
  return clientHasVerbs(client, [['capabilities'], ['runs', 'subagentStream']]);
11
12
  }
@@ -140,6 +141,7 @@ export function tailEngineSubagent(taskId, opts) {
140
141
  ...(typeof d.toolName === 'string' ? { toolName: d.toolName } : {}),
141
142
  ...(out !== undefined ? { output: out } : {}),
142
143
  ...(d.isError === true ? { isError: true } : {}),
144
+ ...(readFrameTrueMark(d, 'notExecuted') ? { notExecuted: true } : {}),
143
145
  });
144
146
  }
145
147
  else if (t === 'task_settled') {
@@ -11,6 +11,7 @@ export type SubagentContentItem = {
11
11
  input: unknown;
12
12
  output?: string;
13
13
  isError?: boolean;
14
+ notExecuted?: true;
14
15
  } | {
15
16
  kind: 'echo';
16
17
  text: string;
@@ -31,6 +32,7 @@ export interface SubagentContentEvent {
31
32
  args?: unknown;
32
33
  output?: string | undefined;
33
34
  isError?: boolean | undefined;
35
+ notExecuted?: true | undefined;
34
36
  }
35
37
  export declare function coerceOutput(v: unknown): string | undefined;
36
38
  export declare function subagentContentEventOf(ev: {
@@ -82,6 +84,7 @@ export type SubagentViewSlot = {
82
84
  input: unknown;
83
85
  output?: string;
84
86
  isError?: boolean;
87
+ notExecuted?: true;
85
88
  };
86
89
  export declare function planSubagentViewSlots(taskId: string): SubagentViewSlot[];
87
90
  export declare function parentToolCallIdOf(taskId: string): string | undefined;
@@ -1,4 +1,5 @@
1
1
  import { DEFAULT_SESSION_KEY } from './sessionSlot.js';
2
+ import { readFrameTrueMark } from './ownKey.js';
2
3
  import { toolEndOutputText } from './toolResultContent.js';
3
4
  export function coerceOutput(v) {
4
5
  return toolEndOutputText(v);
@@ -23,6 +24,7 @@ export function subagentContentEventOf(ev) {
23
24
  args: sub.args,
24
25
  output: coerceOutput(sub.output),
25
26
  isError: sub.isError,
27
+ notExecuted: readFrameTrueMark(sub, 'notExecuted') ? true : undefined,
26
28
  };
27
29
  }
28
30
  const MAX_ITEMS_PER_TASK = 200;
@@ -567,12 +569,17 @@ export function publishSubagentContentEvent(ev) {
567
569
  const before = itemBytesOf(it);
568
570
  const outBefore = it.output;
569
571
  const errBefore = it.isError;
572
+ const notExecBefore = it.notExecuted;
570
573
  it.output = ev.output ?? '';
571
574
  it.isError = ev.isError === true;
575
+ if (ev.notExecuted === true)
576
+ it.notExecuted = true;
577
+ else
578
+ delete it.notExecuted;
572
579
  const delta = itemBytesOf(it) - before;
573
580
  s.itemBytes[at] = (s.itemBytes[at] ?? 0) + delta;
574
581
  addBytes(s, delta);
575
- stampPhase(s, it.id, 'end', ev.eventId, it.output !== outBefore || it.isError !== errBefore);
582
+ stampPhase(s, it.id, 'end', ev.eventId, it.output !== outBefore || it.isError !== errBefore || it.notExecuted !== notExecBefore);
576
583
  break;
577
584
  }
578
585
  const synthId = id ?? `${ev.taskId}-tool-${s.items.length}`;
@@ -583,6 +590,7 @@ export function publishSubagentContentEvent(ev) {
583
590
  input: ev.args ?? {},
584
591
  output: ev.output ?? '',
585
592
  isError: ev.isError === true,
593
+ ...(ev.notExecuted === true ? { notExecuted: true } : {}),
586
594
  });
587
595
  recordCut(s);
588
596
  stampPhase(s, synthId, 'end', ev.eventId, true);
@@ -626,6 +634,7 @@ export function planSubagentViewSlots(taskId) {
626
634
  input: it.input,
627
635
  ...(it.output !== undefined ? { output: it.output } : {}),
628
636
  ...(it.isError === true ? { isError: true } : {}),
637
+ ...(it.notExecuted === true ? { notExecuted: true } : {}),
629
638
  });
630
639
  }
631
640
  else if (it.kind === 'text') {
@@ -28,7 +28,7 @@ export const PROTOCOL_MARKERS = {
28
28
  delegationTrailer: 'Verify this result before concluding. If it leaves more to do, continue or delegate again.',
29
29
  delegationTrailerFork: 'Verify this result before concluding. If it leaves more to do, continue the work yourself or fork again.',
30
30
  delegationFieldLine: /^(status|error|error_kind|observer|stats|worktree):(?: ([^\r\u2028\u2029\u0085]*))?/,
31
- taskOutputLabel: /^TaskOutput\s+(\S+)$/,
31
+ taskOutputLabel: /^(?:TaskOutput|task)\s+(\S+)$/,
32
32
  taskOutputStatus: /^status:\s*(.+)$/m,
33
33
  taskOutputHeadSlots: /^(\r?\n)(?:(state: ([^\r\n\u2028\u2029\u0085]*)(?:\r?\n|$)))?(?:(error: ([^\r\n\u2028\u2029\u0085]*)(?:\r?\n|$)))?/,
34
34
  taskOutputResultNote: /^--- result \(([^)\n]*)\) ---/,