@sema-agent/client-core 0.95.0 → 0.96.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 (181) hide show
  1. package/CHANGELOG.md +180 -0
  2. package/README.md +49 -25
  3. package/dist/adapt/arms.js +7 -1
  4. package/dist/adapt/toolCards.d.ts +1 -0
  5. package/dist/adapt/toolCards.js +16 -3
  6. package/dist/adapt/wireShapes.js +2 -16
  7. package/dist/adapter/activeRunSelfHeal.d.ts +4 -0
  8. package/dist/adapter/activeRunSelfHeal.js +30 -4
  9. package/dist/adapter/downstream/eventToSdkMessage.js +11 -3
  10. package/dist/adapter/downstream/terminalToSdkResult.js +8 -9
  11. package/dist/adapter/runStream.js +30 -47
  12. package/dist/agentSession/engineAgentRegistryRead.js +5 -4
  13. package/dist/agentSession/engineSessionBackgroundStop.js +22 -15
  14. package/dist/agentsWireCaps.js +13 -2
  15. package/dist/callerCwdCapability.d.ts +0 -4
  16. package/dist/callerCwdCapability.js +0 -6
  17. package/dist/centerWiringCapability.d.ts +0 -4
  18. package/dist/centerWiringCapability.js +0 -6
  19. package/dist/classifierVerdictWire.js +4 -16
  20. package/dist/clientSlice.js +1 -1
  21. package/dist/cloudConfigWireCaps.d.ts +3 -3
  22. package/dist/cloudConfigWireCaps.js +65 -45
  23. package/dist/coreValuePorts.d.ts +11 -7
  24. package/dist/coreValuePorts.js +5 -8
  25. package/dist/credentialProvenance.d.ts +28 -0
  26. package/dist/credentialProvenance.js +76 -0
  27. package/dist/decideFailureNote.js +3 -1
  28. package/dist/decideReceipt.js +7 -10
  29. package/dist/declared/supportFloorDeclared.js +3 -3
  30. package/dist/displayUntrusted.d.ts +7 -3
  31. package/dist/displayUntrusted.js +356 -60
  32. package/dist/engineCapsCache.d.ts +6 -0
  33. package/dist/engineCapsCache.js +226 -32
  34. package/dist/engineDirectory.d.ts +79 -0
  35. package/dist/engineDirectory.js +186 -0
  36. package/dist/engineErrorCodes.d.ts +14 -1
  37. package/dist/engineErrorCodes.js +37 -15
  38. package/dist/engineNoticeCodes.d.ts +17 -0
  39. package/dist/engineNoticeCodes.js +57 -3
  40. package/dist/engineWordRenames.d.ts +8 -0
  41. package/dist/engineWordRenames.js +13 -0
  42. package/dist/fileHistoryCaptureCapability.d.ts +14 -0
  43. package/dist/fileHistoryCaptureCapability.js +70 -0
  44. package/dist/fleet/bgSubagentRow.d.ts +15 -0
  45. package/dist/fleet/bgSubagentRow.js +67 -0
  46. package/dist/fleet/fleetLedger.d.ts +1 -0
  47. package/dist/fleet/fleetLedger.js +103 -89
  48. package/dist/fleet/fleetProjection.d.ts +1 -0
  49. package/dist/fleet/fleetProjection.js +10 -3
  50. package/dist/fleetTaskDesc.js +4 -17
  51. package/dist/gateOutcome.d.ts +12 -1
  52. package/dist/gateOutcome.js +58 -1
  53. package/dist/gateVocabulary.d.ts +7 -2
  54. package/dist/gateVocabulary.js +5 -1
  55. package/dist/generated/engineAskFaceTables.js +1 -1
  56. package/dist/generated/engineFactTables.d.ts +5 -3
  57. package/dist/generated/engineFactTables.js +17 -4
  58. package/dist/generated/engineNoticeTables.js +12 -3
  59. package/dist/generated/settingsSchemaFns.d.ts +3 -0
  60. package/dist/generated/settingsSchemaFns.js +53 -0
  61. package/dist/generated/toolNameTables.d.ts +1 -0
  62. package/dist/generated/toolNameTables.js +1 -0
  63. package/dist/hitl/approvalEndingCause.d.ts +2 -0
  64. package/dist/hitl/approvalEndingCause.js +31 -21
  65. package/dist/hitl/askParkRowRouting.js +1 -1
  66. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  67. package/dist/hitl/automaticAnswerVerdict.js +13 -8
  68. package/dist/hitl/decisionConflict.js +0 -2
  69. package/dist/hitl/decisionRefusal.d.ts +8 -0
  70. package/dist/hitl/decisionRefusal.js +48 -14
  71. package/dist/hitl/frameRouter.d.ts +0 -1
  72. package/dist/hitl/frameRouter.js +6 -14
  73. package/dist/hitl/hitlBridge.d.ts +6 -2
  74. package/dist/hitl/hitlBridge.js +28 -7
  75. package/dist/hitl/localAllowRule.d.ts +1 -0
  76. package/dist/hitl/localAllowRule.js +2 -2
  77. package/dist/hitl/noAllowCause.d.ts +2 -1
  78. package/dist/hitl/noAllowCause.js +3 -2
  79. package/dist/hitl/parkResolver.d.ts +1 -0
  80. package/dist/hitl/parkResolver.js +8 -54
  81. package/dist/hitl/parkRowBirthWait.d.ts +1 -0
  82. package/dist/hitl/parkRowBirthWait.js +2 -2
  83. package/dist/hitl/planReviewWire.d.ts +1 -0
  84. package/dist/hitl/planReviewWire.js +98 -20
  85. package/dist/hitl/replayedApproval.d.ts +1 -0
  86. package/dist/hitl/replayedApproval.js +14 -0
  87. package/dist/hitl/sessionPolicyDeliverable.js +8 -6
  88. package/dist/hitl/standingRows.d.ts +18 -0
  89. package/dist/hitl/standingRows.js +127 -0
  90. package/dist/hitl/toolApprovalWire.d.ts +15 -3
  91. package/dist/hitl/toolApprovalWire.js +238 -25
  92. package/dist/hookMatcherVerdict.d.ts +1 -9
  93. package/dist/hookMatcherVerdict.js +21 -61
  94. package/dist/hooksWireCaps.js +2 -2
  95. package/dist/hostCallbackGuard.d.ts +1 -0
  96. package/dist/hostCallbackGuard.js +6 -0
  97. package/dist/index.d.ts +21 -9
  98. package/dist/index.js +17 -8
  99. package/dist/mcpProbeCapability.d.ts +0 -4
  100. package/dist/mcpProbeCapability.js +0 -6
  101. package/dist/memoryComplianceCapability.d.ts +0 -4
  102. package/dist/memoryComplianceCapability.js +0 -6
  103. package/dist/memoryOriginCapability.d.ts +0 -4
  104. package/dist/memoryOriginCapability.js +0 -6
  105. package/dist/memorySpecWire.js +2 -2
  106. package/dist/modelIdentityResolvability.d.ts +2 -2
  107. package/dist/modelIdentityResolvability.js +12 -3
  108. package/dist/noticePresentation.d.ts +68 -0
  109. package/dist/noticePresentation.js +247 -0
  110. package/dist/outputStyleSeatCapability.d.ts +0 -1
  111. package/dist/outputStyleSeatCapability.js +0 -3
  112. package/dist/ownKey.d.ts +2 -0
  113. package/dist/ownKey.js +18 -0
  114. package/dist/peerFrames.js +13 -9
  115. package/dist/permissionModesCapability.d.ts +0 -4
  116. package/dist/permissionModesCapability.js +0 -6
  117. package/dist/permissionRuleIssue.js +0 -3
  118. package/dist/permissionsDeclaration.d.ts +2 -0
  119. package/dist/permissionsDeclaration.js +56 -41
  120. package/dist/printPermissionOutcome.d.ts +12 -0
  121. package/dist/printPermissionOutcome.js +50 -0
  122. package/dist/printToolResultFrame.d.ts +1 -0
  123. package/dist/printToolResultFrame.js +5 -9
  124. package/dist/promptBlockedCopy.d.ts +5 -0
  125. package/dist/promptBlockedCopy.js +35 -0
  126. package/dist/protocolSegment.d.ts +9 -6
  127. package/dist/protocolSegment.js +31 -21
  128. package/dist/providerRejection.d.ts +4 -0
  129. package/dist/providerRejection.js +75 -14
  130. package/dist/replayBody.d.ts +12 -0
  131. package/dist/replayBody.js +25 -0
  132. package/dist/resumeRefusalCopy.js +5 -21
  133. package/dist/retryStatus.d.ts +9 -1
  134. package/dist/retryStatus.js +9 -2
  135. package/dist/rewindArchiveCapability.d.ts +3 -13
  136. package/dist/rewindArchiveCapability.js +7 -58
  137. package/dist/rewindArchiveReading.d.ts +15 -0
  138. package/dist/rewindArchiveReading.js +56 -0
  139. package/dist/ruleCompileVerdict.d.ts +9 -1
  140. package/dist/ruleCompileVerdict.js +29 -4
  141. package/dist/runTerminal.d.ts +15 -1
  142. package/dist/runTerminal.js +56 -8
  143. package/dist/sandboxWire.js +13 -0
  144. package/dist/sealedKeyCapability.d.ts +0 -4
  145. package/dist/sealedKeyCapability.js +0 -6
  146. package/dist/seam.js +4 -2
  147. package/dist/seatContract.d.ts +73 -11
  148. package/dist/seatContract.js +195 -14
  149. package/dist/sessionReadRedactionCapability.d.ts +0 -4
  150. package/dist/sessionReadRedactionCapability.js +0 -6
  151. package/dist/sessionSyncFileHistory.d.ts +4 -0
  152. package/dist/sessionSyncFileHistory.js +66 -0
  153. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
  154. package/dist/sessionSyncFileHistoryCapability.js +0 -3
  155. package/dist/skillToolListsCapability.d.ts +0 -1
  156. package/dist/skillToolListsCapability.js +0 -3
  157. package/dist/steerPriorityCapability.d.ts +0 -1
  158. package/dist/steerPriorityCapability.js +0 -3
  159. package/dist/storePostureCapability.d.ts +0 -4
  160. package/dist/storePostureCapability.js +0 -6
  161. package/dist/subagent/engineSubagentSteer.js +7 -5
  162. package/dist/subagentContentStore.js +4 -15
  163. package/dist/supportFloor.d.ts +1 -0
  164. package/dist/supportFloor.js +13 -9
  165. package/dist/systemReminderTag.d.ts +1 -0
  166. package/dist/systemReminderTag.js +8 -0
  167. package/dist/toolHistoryMismatch.d.ts +0 -3
  168. package/dist/toolHistoryMismatch.js +3 -7
  169. package/dist/toolResult.d.ts +1 -1
  170. package/dist/toolResult.js +2 -1
  171. package/dist/toolResultContent.d.ts +2 -0
  172. package/dist/toolResultContent.js +63 -0
  173. package/dist/usageAnalytics.js +40 -16
  174. package/dist/userInvokedSkillsCapability.d.ts +0 -1
  175. package/dist/userInvokedSkillsCapability.js +0 -3
  176. package/dist/wireErrorTriage.d.ts +2 -0
  177. package/dist/wireErrorTriage.js +34 -5
  178. package/dist/wireFailureShape.d.ts +19 -2
  179. package/dist/wireFailureShape.js +55 -50
  180. package/docs/INTEGRATION-CLIENTS.md +1262 -17
  181. package/package.json +5 -5
@@ -0,0 +1,56 @@
1
+ import { createEngineCapReader } from './engineCapReader.js';
2
+ import { ownDataField } from './ownKey.js';
3
+ const CAPS_KEYS = {
4
+ conversationAnchor: 'resumeAt',
5
+ forkRestore: 'rewindFiles',
6
+ codeOnly: 'rewindFilesTo',
7
+ restoreFilesEpoch: 'restoreFiles',
8
+ };
9
+ const _capsKeyPin = true;
10
+ void _capsKeyPin;
11
+ function bitOf(caps, key) {
12
+ const v = ownDataField(caps, key);
13
+ if (v === undefined)
14
+ return 'not_reported';
15
+ if (v === true)
16
+ return 'on';
17
+ if (v === false)
18
+ return 'off';
19
+ return 'malformed';
20
+ }
21
+ export function projectRewindArchiveCapability(caps) {
22
+ try {
23
+ if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
24
+ return undefined;
25
+ return {
26
+ kind: 'present',
27
+ conversationAnchor: bitOf(caps, CAPS_KEYS.conversationAnchor),
28
+ forkRestore: bitOf(caps, CAPS_KEYS.forkRestore),
29
+ codeOnly: bitOf(caps, CAPS_KEYS.codeOnly),
30
+ restoreFilesEpoch: bitOf(caps, CAPS_KEYS.restoreFilesEpoch),
31
+ };
32
+ }
33
+ catch {
34
+ return undefined;
35
+ }
36
+ }
37
+ const reader = createEngineCapReader({
38
+ name: 'rewindArchive',
39
+ project: projectRewindArchiveCapability,
40
+ makeUnobserved: () => ({ kind: 'unobserved' }),
41
+ });
42
+ export function rewindArchiveReadingAt(baseUrl) {
43
+ return reader.observed(baseUrl);
44
+ }
45
+ export function resetRewindArchiveReader() {
46
+ reader.__resetForTests();
47
+ }
48
+ export function rewindConversationAvailability(reading) {
49
+ if (reading.kind !== 'present')
50
+ return 'unknown';
51
+ if (reading.conversationAnchor === 'on')
52
+ return 'available';
53
+ if (reading.conversationAnchor === 'off')
54
+ return 'unavailable';
55
+ return 'unknown';
56
+ }
@@ -1,2 +1,10 @@
1
- export type RuleCompileVerdict = 'compiles' | 'refused' | 'unknown';
1
+ export type RuleCompileVerdict = {
2
+ readonly kind: 'compiles';
3
+ } | {
4
+ readonly kind: 'refused';
5
+ readonly code?: string;
6
+ readonly message?: string;
7
+ } | {
8
+ readonly kind: 'unknown';
9
+ };
2
10
  export declare function ruleCompileVerdict(rule: string, behavior: 'deny' | 'ask'): RuleCompileVerdict;
@@ -1,13 +1,38 @@
1
1
  import { validatePermissionRules } from './coreValuePorts.js';
2
2
  const RULE_COMPILE_ROOT = '/';
3
+ function issueText(issue, key) {
4
+ try {
5
+ if (typeof issue !== 'object' || issue === null || !Object.hasOwn(issue, key))
6
+ return undefined;
7
+ const v = issue[key];
8
+ return typeof v === 'string' && v.length > 0 ? v : undefined;
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ }
14
+ function firstIssue(issues) {
15
+ try {
16
+ return issues[0];
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ }
3
22
  export function ruleCompileVerdict(rule, behavior) {
23
+ let issues;
4
24
  try {
5
- const issues = validatePermissionRules([{ rule, behavior }], { pathBases: { root: RULE_COMPILE_ROOT } });
25
+ issues = validatePermissionRules([{ rule, behavior }], { pathBases: { root: RULE_COMPILE_ROOT } });
6
26
  if (!Array.isArray(issues))
7
- return 'unknown';
8
- return issues.length === 0 ? 'compiles' : 'refused';
27
+ return { kind: 'unknown' };
28
+ if (issues.length === 0)
29
+ return { kind: 'compiles' };
9
30
  }
10
31
  catch {
11
- return 'unknown';
32
+ return { kind: 'unknown' };
12
33
  }
34
+ const issue = firstIssue(issues);
35
+ const code = issueText(issue, 'code');
36
+ const message = issueText(issue, 'message');
37
+ return { kind: 'refused', ...(code !== undefined ? { code } : {}), ...(message !== undefined ? { message } : {}) };
13
38
  }
@@ -15,7 +15,16 @@ export interface RunTerminalFailureDetail {
15
15
  kind: string;
16
16
  status?: number;
17
17
  code?: string;
18
+ providerCondition?: string;
19
+ providerConditionSource?: string;
18
20
  }
21
+ export type RunTerminalCompletedDetail = {
22
+ kind: 'finish_reason_unknown';
23
+ finishReasonUnknown: string;
24
+ } | {
25
+ kind: 'unrecognized';
26
+ word: string;
27
+ };
19
28
  export declare const PROMPT_BLOCK_CAUSES: readonly ["block", "crashed", "timeout", "cancelled"];
20
29
  export type PromptBlockCause = (typeof PROMPT_BLOCK_CAUSES)[number];
21
30
  export type RunTerminalBlockedDetail = {
@@ -31,9 +40,13 @@ export type RunTerminalBlockedDetail = {
31
40
  kind: 'unrecognized';
32
41
  word: string;
33
42
  };
34
- export type RunTerminalRead = {
43
+ export type RunTerminalRead = RunTerminalReadArm & {
44
+ readonly replay?: true;
45
+ };
46
+ type RunTerminalReadArm = {
35
47
  kind: 'completed';
36
48
  plane: RunTerminalPlane;
49
+ detail?: RunTerminalCompletedDetail;
37
50
  } | {
38
51
  kind: 'failed';
39
52
  plane: RunTerminalPlane;
@@ -60,3 +73,4 @@ export declare function runTerminalGateKind(read: RunTerminalRead | null): strin
60
73
  export declare function runTerminalGateToolName(read: RunTerminalRead | null): string | undefined;
61
74
  export declare function runTerminalCode(read: RunTerminalRead | null): string | undefined;
62
75
  export declare function isReviewPark(read: RunTerminalRead | null): boolean;
76
+ export {};
@@ -1,5 +1,7 @@
1
1
  import { CORE_PROMPT_BLOCK_CAUSES } from './generated/engineFactTables.js';
2
2
  import { isSdkRunParked } from './terminalStatuses.js';
3
+ import { readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
4
+ import { doneResultView } from './replayBody.js';
3
5
  export const PROMPT_BLOCK_CAUSES = CORE_PROMPT_BLOCK_CAUSES;
4
6
  const PROMPT_BLOCKED_BY_HOOK_DETAIL_KIND = 'prompt_blocked_by_hook';
5
7
  function str(v) {
@@ -41,7 +43,42 @@ function failureDetailOf(cause) {
41
43
  if (kind === PROVIDER_REJECTED_DETAIL_KIND && (status === undefined || status < 400))
42
44
  return undefined;
43
45
  const code = str(own(v, 'code'));
44
- return { kind, ...(status !== undefined ? { status } : {}), ...(code !== undefined ? { code } : {}) };
46
+ const isRejection = kind === PROVIDER_REJECTED_DETAIL_KIND;
47
+ const providerCondition = isRejection ? optionalDetailString(v, 'providerCondition') : undefined;
48
+ const providerConditionSource = isRejection ? optionalDetailString(v, 'providerConditionSource') : undefined;
49
+ return {
50
+ kind,
51
+ ...(status !== undefined ? { status } : {}),
52
+ ...(code !== undefined ? { code } : {}),
53
+ ...(providerCondition !== undefined ? { providerCondition } : {}),
54
+ ...(providerConditionSource !== undefined ? { providerConditionSource } : {}),
55
+ };
56
+ }
57
+ catch {
58
+ return undefined;
59
+ }
60
+ }
61
+ function optionalDetailString(d, key) {
62
+ try {
63
+ return readOwnDataNonEmptyString(d, key);
64
+ }
65
+ catch {
66
+ return undefined;
67
+ }
68
+ }
69
+ const FINISH_REASON_UNKNOWN_DETAIL_KIND = 'finish_reason_unknown';
70
+ function completedDetailOf(cause) {
71
+ try {
72
+ const v = readOwnDataValue(cause, 'detail');
73
+ if (typeof v !== 'object' || v === null || Array.isArray(v))
74
+ return undefined;
75
+ const kind = readOwnDataNonEmptyString(v, 'kind');
76
+ if (kind === undefined)
77
+ return undefined;
78
+ if (kind !== FINISH_REASON_UNKNOWN_DETAIL_KIND)
79
+ return { kind: 'unrecognized', word: kind };
80
+ const word = readOwnDataNonEmptyString(v, 'finishReasonUnknown');
81
+ return word === undefined ? undefined : { kind: FINISH_REASON_UNKNOWN_DETAIL_KIND, finishReasonUnknown: word };
45
82
  }
46
83
  catch {
47
84
  return undefined;
@@ -71,6 +108,16 @@ function blockedDetailOf(cause) {
71
108
  }
72
109
  }
73
110
  export function readRunTerminal(result) {
111
+ if (typeof result !== 'object' || result === null || Array.isArray(result))
112
+ return null;
113
+ const view = doneResultView(result);
114
+ if (view.replay) {
115
+ const inner = readRunTerminalArm(view.engine) ?? readRunTerminalArm({ status: view.row?.status, errorCode: view.row?.errorCode, errorMessage: view.row?.error });
116
+ return inner === null ? null : { ...inner, replay: true };
117
+ }
118
+ return readRunTerminalArm(result);
119
+ }
120
+ function readRunTerminalArm(result) {
74
121
  if (typeof result !== 'object' || result === null || Array.isArray(result))
75
122
  return null;
76
123
  const r = result;
@@ -87,8 +134,10 @@ export function readRunTerminal(result) {
87
134
  return { kind: 'paused', plane: 'cause', flatStatus: parkWord, ...(kind === 'paused' ? (pauseOf(c) ?? {}) : {}) };
88
135
  }
89
136
  switch (kind) {
90
- case 'completed':
91
- return { kind: 'completed', plane: 'cause' };
137
+ case 'completed': {
138
+ const detail = completedDetailOf(c);
139
+ return { kind: 'completed', plane: 'cause', ...(detail !== undefined ? { detail } : {}) };
140
+ }
92
141
  case 'failed': {
93
142
  const code = str(c.code);
94
143
  const message = str(c.message);
@@ -160,11 +209,10 @@ export function readRunTerminal(result) {
160
209
  ...(message !== undefined ? { message } : {}),
161
210
  };
162
211
  }
163
- export const REVIEW_PARK_GATE_KINDS = Object.freeze([
164
- 'plan_review',
165
- 'dry_run_review',
166
- 'needs_review',
167
- ]);
212
+ const REVIEW_PARK_GATE_KIND_TUPLE = ['plan_review', 'needs_review'];
213
+ const _reviewParkGateKindPins = [true, true];
214
+ void _reviewParkGateKindPins;
215
+ export const REVIEW_PARK_GATE_KINDS = Object.freeze([...REVIEW_PARK_GATE_KIND_TUPLE]);
168
216
  export function runTerminalGateKind(read) {
169
217
  return read !== null && read.kind === 'paused' ? str(read.gate?.kind) : undefined;
170
218
  }
@@ -1,4 +1,5 @@
1
1
  import { lastFlagValue } from './argvFlagValue.js';
2
+ import { CAPABILITY_IMAGE_INDEX_REQUIRED } from './engineErrorCodes.js';
2
3
  const MAX_PROFILE_LEN = 128;
3
4
  const USAGE_HINT = "sema: --sandbox expects a profile name or 'auto'.\n" +
4
5
  ' --sandbox <profile> run on that sandbox image profile (k8s-lane workers; list: sema cloud images list)\n' +
@@ -45,8 +46,20 @@ export const SANDBOX_K8S_ONLY_400_ANCHOR = 'only supported on the k8s sandbox ba
45
46
  export const SANDBOX_NO_IMAGE_INDEX_400_ANCHOR = 'requires the image index';
46
47
  export const SANDBOX_NO_PUBLISHED_IMAGE_404_ANCHOR = 'no published sandbox image for profile';
47
48
  export const SANDBOX_CASCADE_CONFLICT_400_ANCHOR = 'not supported together with cascade/verify';
49
+ const SANDBOX_IMAGE_INDEX_501_HINT = 'Cloud sandbox images are not available on this engine: its storage backend keeps no image index, so profiles cannot be listed or selected here.\n' +
50
+ 'Use a worker backed by a SQL store (it has the image index), or re-run without --sandbox.';
51
+ function imageIndexRequiredCode(err) {
52
+ try {
53
+ return typeof err === 'object' && err !== null && err.errorCode === CAPABILITY_IMAGE_INDEX_REQUIRED;
54
+ }
55
+ catch {
56
+ return false;
57
+ }
58
+ }
48
59
  export function sandboxDegradeHint(err) {
49
60
  const e = err;
61
+ if (e?.status === 501 && imageIndexRequiredCode(err))
62
+ return SANDBOX_IMAGE_INDEX_501_HINT;
50
63
  if (typeof e?.status !== 'number' || typeof e?.message !== 'string')
51
64
  return undefined;
52
65
  const msg = e.message;
@@ -9,8 +9,4 @@ export type SealedKeyReading = {
9
9
  publicKey: string;
10
10
  };
11
11
  export declare function projectSealedKeyCapability(caps: unknown): SealedKeyReading | undefined;
12
- export declare function noteEngineCapsForSealedKey(baseUrl: string, caps: unknown, opts?: {
13
- generation?: number;
14
- }): void;
15
12
  export declare function observedSealedKey(baseUrl?: string | undefined): SealedKeyReading;
16
- export declare function __resetSealedKeyReadingsForTests(): void;
@@ -30,12 +30,6 @@ const reader = createEngineCapReader({
30
30
  project: projectSealedKeyCapability,
31
31
  makeUnobserved: () => ({ kind: 'unobserved' }),
32
32
  });
33
- export function noteEngineCapsForSealedKey(baseUrl, caps, opts) {
34
- reader.note(baseUrl, caps, opts);
35
- }
36
33
  export function observedSealedKey(baseUrl = engineWireTarget()?.baseUrl) {
37
34
  return reader.observed(baseUrl);
38
35
  }
39
- export function __resetSealedKeyReadingsForTests() {
40
- reader.__resetForTests();
41
- }
package/dist/seam.js CHANGED
@@ -102,7 +102,8 @@ const CHROME_ARM_TABLE = {
102
102
  required: true,
103
103
  duty: '整段替换:①`diverged`(never false)在场 ⇒ 自己拼 thinking stream_delta 上屏的端按 content 重渲该块;' +
104
104
  '②`committedPrefixDiverged`(never false)在场 ⇒ 所有端把 `committedUuids` 首行就地换成 content,其余行**删除或清空其推理正文**(宿主按自身转录结构选:有父链/压缩段依赖的转录清空优于删,保行身份;安全目标 = 未脱敏字节零留盘;整段换不切片;`committedUuid` = 末条兼容位;`committedPrefixLen` = 全部行全文长度之和,单位 UTF-16 代码单元);' +
105
- '本包在这一形上一个字节都不再交;③三键全缺席 ⇒ 照旧只当对账/定界;④缺席 ≠ 段没结束,按整条流判。',
105
+ '本包在这一形上一个字节都不再交;③三键全缺席 ⇒ 照旧只当对账/定界;④缺席 ≠ 段没结束,按整条流判;' +
106
+ '⑤序:该段推理尾部的活体增量一律先于本事件到达,本事件之后不再有同段推理增量。',
106
107
  },
107
108
  wiring_manifest: {
108
109
  required: false,
@@ -150,7 +151,8 @@ const CHROME_ARM_TABLE = {
150
151
  '🔴 **单位 = JS 字符串长度(UTF-16 代码单元),不是 UTF-8 字节、也不是几条消息**' +
151
152
  '(按 UTF-8 字节截会在非 ASCII 正文上截错位置把凭据留在屏上;按消息丢会连合并在同一条消息里的上一段定稿一起删掉),' +
152
153
  '照抄 `已committed正文.slice(0, 长度 - committedPrefixLen) + content`;按**增量拼文**计长、不是 content 上的偏移;④三键全缺席 ⇒ 照旧只当对账/定界,拿 content 再渲一行 = 同一段上屏两遍;⑤`segmentId`(恒在场)= 段身份,与本段已过境的 committed 文本行顶层 `_sema_segment_id` 同值 —— 换掉已提交那截时认行的钥匙是**两把**:行 uuid ∧ 段身份(按字节相等找行会被同后缀的独立行冒充)。' +
153
- '🔴 缺席只表示「没报」,绝不等于「段没结束」——要退回自家启发式必须按整条流判、不按单帧判;⑥`committedUuids[]`(0.71.0 起,在场 = 本窗口已提交行按序、`[]` = 零行、整键缺席 = 本包说不出):`committedPrefixDiverged` ⇒ **按 `committedRows[]` 逐行写回正文**(包已算好:首行 = 前段定稿前缀 + content、其余行空;别整行换首行,提交行可能带上一段定稿),端不再自己数窗口里过境的行,也不再对多行段整发放弃;`committedUuid` = 末条兼容位。',
154
+ '🔴 缺席只表示「没报」,绝不等于「段没结束」——要退回自家启发式必须按整条流判、不按单帧判;⑥`committedUuids[]`(0.71.0 起,在场 = 本窗口已提交行按序、`[]` = 零行、整键缺席 = 本包说不出):`committedPrefixDiverged` ⇒ **按 `committedRows[]` 逐行写回正文**(包已算好:首行 = 前段定稿前缀 + content、其余行空;别整行换首行,提交行可能带上一段定稿),端不再自己数窗口里过境的行,也不再对多行段整发放弃;`committedUuid` = 末条兼容位;' +
155
+ '⑦序:该段尾部的活体增量(`stream_delta`)一律先于本事件到达,本事件之后不再有同段增量(下一条增量属于下一段)。',
154
156
  },
155
157
  };
156
158
  export const CHROME_ARMS = Object.entries(CHROME_ARM_TABLE).map(([kind, d]) => ({ kind, required: d.required, duty: d.duty }));
@@ -1,6 +1,6 @@
1
1
  import type { ReasoningEffort } from "./effortWire.js";
2
2
  import type { PermissionMode } from "./permissionWireCaps.js";
3
- import type { LaneProof } from "./seam.js";
3
+ import type { ChromeArmKind, LaneProof } from "./seam.js";
4
4
  import type { QuestionAnswer } from "./liveQuestionStore.js";
5
5
  import type { ToolApprovalDelegation } from "./hitl/toolApprovalWire.js";
6
6
  import type { ApprovalMandateWord } from "./gateVocabulary.js";
@@ -40,6 +40,7 @@ export interface LocalSessionRecord {
40
40
  text: string;
41
41
  }>;
42
42
  parked?: boolean;
43
+ pinned?: boolean;
43
44
  }
44
45
  export declare const TOOL_PERMISSION_REQUEST_ID_DOMAINS: readonly ["live:", "durable:", "question:", "elicit:", "plan:"];
45
46
  export type ToolPermissionRequestIdDomain = (typeof TOOL_PERMISSION_REQUEST_ID_DOMAINS)[number];
@@ -67,12 +68,13 @@ export interface ToolPermissionRequest {
67
68
  ruleOffersAbsence?: string;
68
69
  askClass?: string;
69
70
  classes?: readonly string[];
71
+ rememberRefused?: true;
70
72
  }
71
73
  declare const SEAT_EVENT_TYPE_TUPLE: readonly ["start", "close", "session_updated", "message", "stream_event", "chrome_event", "error", "tool_permission_resolved"];
72
74
  export type SeatEventType = (typeof SEAT_EVENT_TYPE_TUPLE)[number];
73
75
  export declare const SEAT_EVENT_TYPES: readonly SeatEventType[];
74
- declare const CHROME_EVENT_KIND_TUPLE: readonly ["panel_task", "notification_terminal", "prompt_suggestions", "subagent_lifecycle"];
75
- export type ChromeEventKind = (typeof CHROME_EVENT_KIND_TUPLE)[number];
76
+ declare const CHROME_EVENT_KIND_TUPLE: readonly ["panel_task", "notification_terminal", "prompt_suggestions", "subagent_lifecycle", "text_segment_end", "thinking_segment_end"];
77
+ export type ChromeEventKind = Extract<ChromeArmKind, (typeof CHROME_EVENT_KIND_TUPLE)[number]>;
76
78
  export declare const CHROME_EVENT_KINDS: readonly ChromeEventKind[];
77
79
  export interface SeatChromeEnvelopeBase {
78
80
  kind: ChromeEventKind;
@@ -103,11 +105,13 @@ export interface LocalSessionEvent {
103
105
  chrome?: SeatChromeEnvelope;
104
106
  }
105
107
  export declare const HITL_RESOLUTION_OUTCOMES: readonly string[];
106
- export declare const SEAT_CAPABILITY_NAMES: readonly ["pickFolder", "rewind"];
108
+ export declare const SEAT_CAPABILITY_NAMES: readonly ["pickFolder", "rewind", "recents", "patchSession"];
107
109
  export type SeatCapabilityName = (typeof SEAT_CAPABILITY_NAMES)[number];
108
110
  export interface SeatCapabilitiesState {
109
111
  pickFolder?: boolean;
110
112
  rewind?: boolean;
113
+ recents?: boolean;
114
+ patchSession?: boolean;
111
115
  }
112
116
  export type SeatCapabilityReading = {
113
117
  readonly kind: "reported";
@@ -120,6 +124,28 @@ export type SeatCapabilityReading = {
120
124
  export declare function seatCapability(state: unknown, name: SeatCapabilityName): SeatCapabilityReading;
121
125
  export declare function watchSeatCapability(store: EipcStoreClient<SeatCapabilitiesState> | undefined, name: SeatCapabilityName, onReading: (reading: SeatCapabilityReading) => void): () => void;
122
126
  export declare function seatCapabilityUnavailableDetail(name: SeatCapabilityName, reading: SeatCapabilityReading): string | undefined;
127
+ export interface RecentFolderSession {
128
+ readonly cwd?: string;
129
+ readonly lastActivityAt?: string;
130
+ readonly createdAt?: string;
131
+ }
132
+ export interface RecentFoldersInput {
133
+ readonly sessions?: readonly RecentFolderSession[] | null | undefined;
134
+ readonly registered?: readonly RecentFolderRow[] | null | undefined;
135
+ }
136
+ export declare function recentFoldersOf(input: RecentFoldersInput): string[] | null;
137
+ export type RecentFoldersHostReading = "listed" | "skipped" | "unreadable";
138
+ export interface RecentFoldersReading {
139
+ readonly folders: string[] | null;
140
+ readonly host: RecentFoldersHostReading;
141
+ readonly unreadableRows: number;
142
+ }
143
+ export interface ReadRecentFoldersInput {
144
+ readonly capability: SeatCapabilityReading;
145
+ readonly list: () => Promise<RecentFoldersResult>;
146
+ readonly sessions?: readonly RecentFolderSession[] | null | undefined;
147
+ }
148
+ export declare function readRecentFolders(input: ReadRecentFoldersInput): Promise<RecentFoldersReading>;
123
149
  export interface StartSessionOptions {
124
150
  model?: string;
125
151
  title?: string;
@@ -183,6 +209,12 @@ export declare const ATTACHMENT_UPLOAD_REQUEST_KEYS: readonly ["name", "mimeType
183
209
  export interface SessionScopedRequest {
184
210
  sessionId: string;
185
211
  }
212
+ export interface SessionRowPatchRequest {
213
+ sessionId: string;
214
+ title?: string | null;
215
+ pinned?: boolean;
216
+ }
217
+ export declare const SESSION_ROW_PATCH_REQUEST_KEYS: readonly ["sessionId", "title", "pinned"];
186
218
  export interface AttachmentUploadReceipt {
187
219
  id: string;
188
220
  name: string;
@@ -209,7 +241,6 @@ export interface EipcStoreClient<T> {
209
241
  onStateChange(cb: (state: T) => void): () => void;
210
242
  }
211
243
  export interface SettingsState {
212
- defaultModel: string | null;
213
244
  engineVersion?: string;
214
245
  dataRoot?: string;
215
246
  }
@@ -244,6 +275,13 @@ export interface SessionsState {
244
275
  export interface FocusedSessionState {
245
276
  sessionId: string | null;
246
277
  }
278
+ export interface RecentFolderRow {
279
+ path: string;
280
+ lastUsedAt?: string;
281
+ }
282
+ export interface RecentFoldersResult {
283
+ folders: RecentFolderRow[];
284
+ }
247
285
  export interface LocalSessionsApi {
248
286
  start(opts?: StartSessionOptions): Promise<LocalSessionRecord>;
249
287
  sendMessage(req: SendMessageRequest): Promise<SendMessageAck>;
@@ -261,6 +299,9 @@ export interface LocalSessionsApi {
261
299
  listModels(): Promise<LiveModelCatalog>;
262
300
  applyModelConfig(req: ApplyModelConfigRequest): Promise<ApplyModelConfigResult>;
263
301
  pickFolder(): Promise<string | null>;
302
+ listRecentFolders(): Promise<RecentFoldersResult>;
303
+ noteRecentFolder(path: string): Promise<OkAck>;
304
+ patchSession(req: SessionRowPatchRequest): Promise<LocalSessionRecord>;
264
305
  onEvent(cb: (ev: LocalSessionEvent) => void): () => void;
265
306
  onToolPermissionRequest(cb: (req: ToolPermissionRequest) => void): () => void;
266
307
  sessionsStateStore: EipcStoreClient<SessionsState>;
@@ -294,14 +335,16 @@ export interface ApplyModelConfigResult {
294
335
  }
295
336
  export declare function checkSendMessageRequest(v: unknown): SeatValidation;
296
337
  export declare function isSendMessageRequest(v: unknown): v is SendMessageRequest;
338
+ export declare const checkSessionRowPatchRequest: (v: unknown) => SeatValidation;
339
+ export declare function isSessionRowPatchRequest(v: unknown): v is SessionRowPatchRequest;
297
340
  export declare function isSendMessageAck(v: unknown): v is SendMessageAck;
298
341
  export declare const LOCAL_SESSIONS_SPEC: EipcServiceSpec;
299
- export declare const SEAT_METHOD_NAMES: readonly ["start", "sendMessage", "interrupt", "stop", "respondToToolPermission", "cancelQueuedMessage", "reorderQueuedMessage", "promoteQueuedMessage", "setFocusedSession", "setModel", "getTranscript", "searchSessions", "uploadAttachment", "listModels", "applyModelConfig", "pickFolder", "onEvent", "onToolPermissionRequest"];
342
+ 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", "onEvent", "onToolPermissionRequest"];
300
343
  export declare const SEAT_STORE_PROPS: readonly ["sessionsStateStore", "focusedSessionStateStore", "settingsStateStore", "seatCapabilitiesStateStore"];
301
344
  export declare const SEAT_EVENT_METHOD_NAMES: readonly ["onEvent", "onToolPermissionRequest"];
302
345
  export declare const LOCAL_SESSION_EVENT_KEYS: readonly ["type", "sessionId", "message", "messages", "error", "errorCategory", "code", "request", "data", "sources", "permissionMode", "session", "userMessageUuid", "hasPreClearSession", "requestId", "outcome", "parked", "chrome"];
303
- export declare const TOOL_PERMISSION_REQUEST_KEYS: readonly ["requestId", "sessionId", "toolName", "toolCallId", "input", "message", "toctouBinding", "createdAtMs", "governanceForced", "delegation", "mandated", "mandate", "origin", "ruleOffersAbsence", "askClass", "classes"];
304
- export declare const LOCAL_SESSION_RECORD_KEYS: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked"];
346
+ export declare const TOOL_PERMISSION_REQUEST_KEYS: readonly ["requestId", "sessionId", "toolName", "toolCallId", "input", "message", "toctouBinding", "createdAtMs", "governanceForced", "delegation", "mandated", "mandate", "origin", "ruleOffersAbsence", "askClass", "classes", "rememberRefused"];
347
+ export declare const LOCAL_SESSION_RECORD_KEYS: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned"];
305
348
  export declare const SEND_MESSAGE_REQUEST_KEYS: readonly ["sessionId", "text", "model", "userMessageUuid", "permissionMode", "attachmentIds", "reasoningEffort", "retainBackgroundProcesses", "forwardSubagentEvents", "retainSubagentSessions", "settings", "scenario", "rewind"];
306
349
  export declare const SEAT_SEND_MESSAGE_KEY_ORIGINS: {
307
350
  readonly sessionId: {
@@ -351,7 +394,7 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
351
394
  readonly LocalSessionRecord: {
352
395
  readonly guard: "isLocalSessionRecord";
353
396
  readonly check: (v: unknown) => SeatValidation;
354
- readonly validated: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked"];
397
+ readonly validated: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned"];
355
398
  readonly unchecked: readonly [];
356
399
  };
357
400
  readonly ToolPermissionRequest: {
@@ -382,6 +425,9 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
382
425
  }, {
383
426
  readonly key: "classes";
384
427
  readonly why: "与 askClass 同一对(CC-284),同在同缺、同一只成对窄读(非空、每员非空串、无重复、首员等于 askClass;开集、原样顺序);座位门不设第二判官,理由同 askClass。";
428
+ }, {
429
+ readonly key: "rememberRefused";
430
+ readonly why: "展示增强位(CC-642),权威窄读在卡口两条腿与过境口 toolPermissionRequestAskBits(同一只 readApprovalRememberRefused:自有键 ∧ 严格 true 才上座,永不铸 false);座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。消费端 `=== true` 读,其余(缺席 / 坏形)一律当缺席 ⇒ 照旧渲「本会话放行」。缺席 = 服务端没说(记得住或老服务端),不是 false。不经过境口自铸座位请求的宿主要自己按同一把窄读。";
385
431
  }, {
386
432
  readonly key: "ruleOffersAbsence";
387
433
  readonly why: "喂强制判据口 approvalIsMandated 的位(CC-203;寄存行那条腿的强制只以缺席词 mandated 表达),按开集读(非空串原文字节、词表不校);权威窄读在卡口与过境口,座位门不设第二判官,理由同 mandated。坏形读成缺席 ⇒ 这一路不判强制(放宽方向:寄存行上的强制就丢了;另两路 mandated / mandate 照判);表外串只是不等于 mandated。不经过境口自铸座位请求的宿主要自己按同一把窄读。";
@@ -416,6 +462,12 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
416
462
  readonly validated: readonly ["sessionId", "text", "model", "userMessageUuid", "permissionMode", "attachmentIds", "reasoningEffort", "retainBackgroundProcesses", "forwardSubagentEvents", "retainSubagentSessions", "settings", "scenario", "rewind"];
417
463
  readonly unchecked: readonly [];
418
464
  };
465
+ readonly SessionRowPatchRequest: {
466
+ readonly guard: "isSessionRowPatchRequest";
467
+ readonly check: (v: unknown) => SeatValidation;
468
+ readonly validated: readonly ["sessionId", "title", "pinned"];
469
+ readonly unchecked: readonly [];
470
+ };
419
471
  readonly ApplyModelConfigResult: {
420
472
  readonly check: (v: unknown) => SeatValidation;
421
473
  readonly validated: readonly ["ok", "requiresRestart", "reason"];
@@ -464,12 +516,22 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
464
516
  };
465
517
  readonly SettingsState: {
466
518
  readonly check: (v: unknown) => SeatValidation;
467
- readonly validated: readonly ["defaultModel", "engineVersion", "dataRoot"];
519
+ readonly validated: readonly ["engineVersion", "dataRoot"];
468
520
  readonly unchecked: readonly [];
469
521
  };
470
522
  readonly SeatCapabilitiesState: {
471
523
  readonly check: (v: unknown) => SeatValidation;
472
- readonly validated: readonly ["pickFolder", "rewind"];
524
+ readonly validated: readonly ["pickFolder", "rewind", "recents", "patchSession"];
525
+ readonly unchecked: readonly [];
526
+ };
527
+ readonly RecentFoldersResult: {
528
+ readonly check: (v: unknown) => SeatValidation;
529
+ readonly validated: readonly ["folders"];
530
+ readonly unchecked: readonly [];
531
+ };
532
+ readonly RecentFolderRow: {
533
+ readonly check: (v: unknown) => SeatValidation;
534
+ readonly validated: readonly ["path", "lastUsedAt"];
473
535
  readonly unchecked: readonly [];
474
536
  };
475
537
  readonly SeatRewindIntent: {