@sema-agent/client-core 0.94.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 (332) hide show
  1. package/CHANGELOG.md +521 -0
  2. package/README.md +104 -57
  3. package/dist/adapt/arms.js +12 -7
  4. package/dist/adapt/panelTasks.js +4 -10
  5. package/dist/adapt/toolCards.d.ts +1 -0
  6. package/dist/adapt/toolCards.js +18 -5
  7. package/dist/adapt/wireShapes.js +5 -24
  8. package/dist/adapter/activeRunSelfHeal.d.ts +12 -3
  9. package/dist/adapter/activeRunSelfHeal.js +50 -16
  10. package/dist/adapter/downstream/eventToSdkMessage.js +33 -18
  11. package/dist/adapter/downstream/terminalToSdkResult.js +19 -12
  12. package/dist/adapter/runStream.js +30 -46
  13. package/dist/adapter/types.d.ts +7 -0
  14. package/dist/adapter/types.js +15 -0
  15. package/dist/agentSession/backgroundView.js +5 -1
  16. package/dist/agentSession/engineAgentRegistryRead.js +7 -5
  17. package/dist/agentSession/engineSessionBackgroundStop.js +25 -17
  18. package/dist/agentsWireCaps.d.ts +2 -0
  19. package/dist/agentsWireCaps.js +13 -2
  20. package/dist/approvalDecidedByCapability.d.ts +0 -1
  21. package/dist/approvalDecidedByCapability.js +2 -7
  22. package/dist/approvalsStreamLiveCapability.d.ts +0 -1
  23. package/dist/approvalsStreamLiveCapability.js +2 -6
  24. package/dist/atMostOnce.d.ts +8 -0
  25. package/dist/atMostOnce.js +36 -0
  26. package/dist/attachmentSeatCapability.d.ts +0 -1
  27. package/dist/attachmentSeatCapability.js +0 -3
  28. package/dist/attachmentsWireCaps.js +11 -6
  29. package/dist/bashExitReading.d.ts +10 -0
  30. package/dist/bashExitReading.js +12 -0
  31. package/dist/callerCwdCapability.d.ts +0 -5
  32. package/dist/callerCwdCapability.js +2 -13
  33. package/dist/centerWiringCapability.d.ts +1 -7
  34. package/dist/centerWiringCapability.js +18 -27
  35. package/dist/classifierStatus.js +4 -4
  36. package/dist/classifierVerdictWire.js +4 -16
  37. package/dist/clientSlice.js +1 -1
  38. package/dist/cloudConfigWireCaps.d.ts +3 -3
  39. package/dist/cloudConfigWireCaps.js +85 -43
  40. package/dist/compensations.js +1 -1
  41. package/dist/coreValuePorts.d.ts +11 -7
  42. package/dist/coreValuePorts.js +5 -8
  43. package/dist/credentialProvenance.d.ts +28 -0
  44. package/dist/credentialProvenance.js +76 -0
  45. package/dist/cycleOrder.d.ts +15 -0
  46. package/dist/cycleOrder.js +45 -0
  47. package/dist/decideFailureNote.js +7 -2
  48. package/dist/decideReceipt.d.ts +2 -1
  49. package/dist/decideReceipt.js +39 -14
  50. package/dist/declared/supportFloorDeclared.d.ts +1 -0
  51. package/dist/declared/supportFloorDeclared.js +5 -0
  52. package/dist/deviceExecutorManagementCapability.d.ts +0 -1
  53. package/dist/deviceExecutorManagementCapability.js +7 -16
  54. package/dist/deviceRebind.d.ts +88 -0
  55. package/dist/deviceRebind.js +242 -0
  56. package/dist/displayUntrusted.d.ts +8 -3
  57. package/dist/displayUntrusted.js +661 -63
  58. package/dist/engineAgentAbsence.d.ts +2 -2
  59. package/dist/engineAgentPanelStore.d.ts +8 -18
  60. package/dist/engineAgentPanelStore.js +19 -537
  61. package/dist/engineCapReader.d.ts +6 -6
  62. package/dist/engineCapReader.js +30 -43
  63. package/dist/engineCapsCache.d.ts +13 -2
  64. package/dist/engineCapsCache.js +276 -44
  65. package/dist/engineCredentialRequirement.d.ts +9 -0
  66. package/dist/engineCredentialRequirement.js +23 -0
  67. package/dist/engineDirectory.d.ts +79 -0
  68. package/dist/engineDirectory.js +186 -0
  69. package/dist/engineEnvSourcing.d.ts +53 -0
  70. package/dist/engineEnvSourcing.js +81 -0
  71. package/dist/engineErrorCodes.d.ts +28 -4
  72. package/dist/engineErrorCodes.js +68 -25
  73. package/dist/engineIdentity.js +2 -0
  74. package/dist/engineNoticeCodes.d.ts +17 -0
  75. package/dist/engineNoticeCodes.js +57 -3
  76. package/dist/engineWireSdk.js +2 -2
  77. package/dist/engineWordRenames.d.ts +8 -0
  78. package/dist/engineWordRenames.js +13 -0
  79. package/dist/executionLaneCapability.d.ts +2 -3
  80. package/dist/executionLaneCapability.js +18 -23
  81. package/dist/fileHistoryCaptureCapability.d.ts +14 -1
  82. package/dist/fileHistoryCaptureCapability.js +72 -6
  83. package/dist/fileHistoryLegNotice.d.ts +3 -2
  84. package/dist/fileHistoryLegNotice.js +51 -2
  85. package/dist/fleet/bgSubagentRow.d.ts +15 -0
  86. package/dist/fleet/bgSubagentRow.js +67 -0
  87. package/dist/fleet/fleetLedger.d.ts +3 -0
  88. package/dist/fleet/fleetLedger.js +153 -122
  89. package/dist/fleet/fleetProjection.d.ts +1 -3
  90. package/dist/fleet/fleetProjection.js +19 -19
  91. package/dist/fleetAgentPanelProjection.d.ts +4 -17
  92. package/dist/fleetAgentPanelProjection.js +7 -197
  93. package/dist/fleetAgentRowLike.d.ts +16 -0
  94. package/dist/fleetAgentRowLike.js +1 -0
  95. package/dist/fleetTaskDesc.js +4 -17
  96. package/dist/gateOutcome.d.ts +12 -1
  97. package/dist/gateOutcome.js +87 -18
  98. package/dist/gateVocabulary.d.ts +7 -2
  99. package/dist/gateVocabulary.js +5 -1
  100. package/dist/generated/engineAskFaceTables.js +1 -1
  101. package/dist/generated/engineFactTables.d.ts +5 -3
  102. package/dist/generated/engineFactTables.js +17 -4
  103. package/dist/generated/engineNoticeTables.js +12 -3
  104. package/dist/generated/sdkFactTables.d.ts +2 -0
  105. package/dist/generated/sdkFactTables.js +17 -0
  106. package/dist/generated/settingsSchemaFns.d.ts +13 -0
  107. package/dist/generated/settingsSchemaFns.js +75 -0
  108. package/dist/generated/toolNameTables.d.ts +1 -0
  109. package/dist/generated/toolNameTables.js +1 -0
  110. package/dist/headlessPermissionModeWire.d.ts +1 -1
  111. package/dist/headlessPermissionModeWire.js +1 -1
  112. package/dist/headlessReconnectWire.js +49 -20
  113. package/dist/hitl/allowRuleShadow.d.ts +1 -1
  114. package/dist/hitl/allowRuleShadow.js +49 -8
  115. package/dist/hitl/approvalCompleteParked.d.ts +1 -0
  116. package/dist/hitl/approvalCompleteParked.js +14 -0
  117. package/dist/hitl/approvalEndingCause.d.ts +7 -0
  118. package/dist/hitl/approvalEndingCause.js +71 -0
  119. package/dist/hitl/approvalHolds.d.ts +12 -2
  120. package/dist/hitl/approvalHolds.js +53 -2
  121. package/dist/hitl/approvalsFeed.js +23 -11
  122. package/dist/hitl/askGateWire.d.ts +2 -1
  123. package/dist/hitl/askGateWire.js +26 -1
  124. package/dist/hitl/askParkRowRouting.js +1 -1
  125. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  126. package/dist/hitl/automaticAnswerVerdict.js +15 -10
  127. package/dist/hitl/crashConverged.js +2 -0
  128. package/dist/hitl/decisionConflict.d.ts +3 -0
  129. package/dist/hitl/decisionConflict.js +41 -0
  130. package/dist/hitl/decisionRefusal.d.ts +12 -0
  131. package/dist/hitl/decisionRefusal.js +63 -4
  132. package/dist/hitl/frameRouter.d.ts +0 -1
  133. package/dist/hitl/frameRouter.js +32 -57
  134. package/dist/hitl/gateLedger.d.ts +5 -0
  135. package/dist/hitl/gateLedger.js +21 -0
  136. package/dist/hitl/hitlBridge.d.ts +17 -2
  137. package/dist/hitl/hitlBridge.js +91 -55
  138. package/dist/hitl/hitlHostSurface.js +3 -11
  139. package/dist/hitl/livePendingAsk.d.ts +16 -6
  140. package/dist/hitl/livePendingAsk.js +36 -4
  141. package/dist/hitl/localAllowRule.d.ts +1 -0
  142. package/dist/hitl/localAllowRule.js +2 -2
  143. package/dist/hitl/noAllowCause.d.ts +2 -1
  144. package/dist/hitl/noAllowCause.js +3 -2
  145. package/dist/hitl/parkExpiryJudgements.d.ts +19 -0
  146. package/dist/hitl/parkExpiryJudgements.js +46 -0
  147. package/dist/hitl/parkResolver.d.ts +4 -7
  148. package/dist/hitl/parkResolver.js +12 -34
  149. package/dist/hitl/parkRowBirthWait.d.ts +1 -0
  150. package/dist/hitl/parkRowBirthWait.js +2 -2
  151. package/dist/hitl/persistedRulesWire.js +5 -1
  152. package/dist/hitl/planReviewWire.d.ts +3 -2
  153. package/dist/hitl/planReviewWire.js +154 -50
  154. package/dist/hitl/replayedApproval.d.ts +9 -0
  155. package/dist/hitl/replayedApproval.js +139 -10
  156. package/dist/hitl/resumeRunningCard.d.ts +2 -0
  157. package/dist/hitl/resumeRunningCard.js +15 -4
  158. package/dist/hitl/sessionPolicyDeliverable.js +8 -6
  159. package/dist/hitl/standingRows.d.ts +18 -0
  160. package/dist/hitl/standingRows.js +127 -0
  161. package/dist/hitl/toolApprovalWire.d.ts +39 -7
  162. package/dist/hitl/toolApprovalWire.js +351 -61
  163. package/dist/hookMatcherVerdict.d.ts +1 -9
  164. package/dist/hookMatcherVerdict.js +21 -61
  165. package/dist/hooksWireCaps.js +40 -8
  166. package/dist/host.d.ts +5 -0
  167. package/dist/host.js +3 -1
  168. package/dist/hostCallbackGuard.d.ts +2 -0
  169. package/dist/hostCallbackGuard.js +31 -0
  170. package/dist/index.d.ts +48 -17
  171. package/dist/index.js +36 -15
  172. package/dist/interactiveInterrupt.d.ts +8 -0
  173. package/dist/interactiveInterrupt.js +54 -0
  174. package/dist/limitsWire.d.ts +5 -0
  175. package/dist/limitsWire.js +49 -3
  176. package/dist/liveModelCatalog.d.ts +95 -0
  177. package/dist/liveModelCatalog.js +297 -32
  178. package/dist/mcpEngineLeg.d.ts +25 -0
  179. package/dist/mcpEngineLeg.js +71 -15
  180. package/dist/mcpPanel.js +2 -1
  181. package/dist/mcpProbeCapability.d.ts +0 -5
  182. package/dist/mcpProbeCapability.js +2 -12
  183. package/dist/mcpReconnect.d.ts +1 -3
  184. package/dist/mcpReconnect.js +10 -5
  185. package/dist/memoryComplianceCapability.d.ts +0 -5
  186. package/dist/memoryComplianceCapability.js +2 -12
  187. package/dist/memoryOriginCapability.d.ts +0 -5
  188. package/dist/memoryOriginCapability.js +2 -12
  189. package/dist/memorySpecWire.js +2 -2
  190. package/dist/memoryVerbsWire.d.ts +1 -1
  191. package/dist/memoryVerbsWire.js +4 -0
  192. package/dist/model/liveCatalogShape.d.ts +14 -0
  193. package/dist/model/liveCatalogShape.js +71 -0
  194. package/dist/model/modelSupplyRules.d.ts +1 -0
  195. package/dist/model/modelSupplyRules.js +30 -9
  196. package/dist/model/modelsPolicy.d.ts +21 -0
  197. package/dist/model/modelsPolicy.js +90 -0
  198. package/dist/modelIdentityResolvability.d.ts +2 -2
  199. package/dist/modelIdentityResolvability.js +14 -12
  200. package/dist/modelSwitchFallback.d.ts +69 -0
  201. package/dist/modelSwitchFallback.js +206 -0
  202. package/dist/noticePresentation.d.ts +68 -0
  203. package/dist/noticePresentation.js +247 -0
  204. package/dist/notifications.js +12 -11
  205. package/dist/outputStyleSeatCapability.d.ts +0 -2
  206. package/dist/outputStyleSeatCapability.js +2 -10
  207. package/dist/ownKey.d.ts +8 -0
  208. package/dist/ownKey.js +66 -0
  209. package/dist/panelReduce.d.ts +114 -0
  210. package/dist/panelReduce.js +1135 -0
  211. package/dist/panelStateHolder.d.ts +17 -0
  212. package/dist/panelStateHolder.js +201 -0
  213. package/dist/peerFrames.js +13 -9
  214. package/dist/peerLaneCapability.d.ts +0 -1
  215. package/dist/peerLaneCapability.js +2 -6
  216. package/dist/permissionModesCapability.d.ts +0 -5
  217. package/dist/permissionModesCapability.js +5 -16
  218. package/dist/permissionRuleIssue.js +0 -3
  219. package/dist/permissionRulesWriteCapability.d.ts +0 -1
  220. package/dist/permissionRulesWriteCapability.js +2 -6
  221. package/dist/permissionsAllowGrantCapability.d.ts +0 -1
  222. package/dist/permissionsAllowGrantCapability.js +3 -9
  223. package/dist/permissionsDeclaration.d.ts +8 -0
  224. package/dist/permissionsDeclaration.js +101 -41
  225. package/dist/printPermissionOutcome.d.ts +12 -0
  226. package/dist/printPermissionOutcome.js +50 -0
  227. package/dist/printToolResultFrame.d.ts +1 -0
  228. package/dist/printToolResultFrame.js +5 -17
  229. package/dist/promptBlockedCopy.d.ts +5 -0
  230. package/dist/promptBlockedCopy.js +35 -0
  231. package/dist/promptDelivery.js +0 -8
  232. package/dist/protocolSegment.d.ts +9 -6
  233. package/dist/protocolSegment.js +31 -21
  234. package/dist/providerRejection.d.ts +4 -0
  235. package/dist/providerRejection.js +75 -14
  236. package/dist/replayBody.d.ts +12 -0
  237. package/dist/replayBody.js +25 -0
  238. package/dist/resumeRefusalCopy.d.ts +18 -1
  239. package/dist/resumeRefusalCopy.js +127 -32
  240. package/dist/retryStatus.d.ts +9 -1
  241. package/dist/retryStatus.js +9 -2
  242. package/dist/rewindArchiveCapability.d.ts +5 -14
  243. package/dist/rewindArchiveCapability.js +18 -61
  244. package/dist/rewindArchiveReading.d.ts +15 -0
  245. package/dist/rewindArchiveReading.js +56 -0
  246. package/dist/rewindEngineAction.d.ts +21 -0
  247. package/dist/rewindEngineAction.js +36 -0
  248. package/dist/rewindWireCaps.d.ts +2 -1
  249. package/dist/rewindWireCaps.js +1 -0
  250. package/dist/ruleCompileVerdict.d.ts +9 -1
  251. package/dist/ruleCompileVerdict.js +29 -4
  252. package/dist/runTerminal.d.ts +15 -12
  253. package/dist/runTerminal.js +60 -35
  254. package/dist/sandboxWire.js +13 -0
  255. package/dist/sdkRegistryTransit.d.ts +2 -1
  256. package/dist/sdkRegistryTransit.js +1 -0
  257. package/dist/sealedKeyCapability.d.ts +0 -5
  258. package/dist/sealedKeyCapability.js +3 -15
  259. package/dist/seam.js +4 -2
  260. package/dist/seatContract.d.ts +125 -34
  261. package/dist/seatContract.js +583 -179
  262. package/dist/sessionIdSegment.d.ts +1 -0
  263. package/dist/sessionIdSegment.js +11 -0
  264. package/dist/sessionMemoryErase.d.ts +1 -1
  265. package/dist/sessionMemoryErase.js +6 -1
  266. package/dist/sessionMemoryStatus.js +3 -2
  267. package/dist/sessionPolicyCapability.d.ts +0 -1
  268. package/dist/sessionPolicyCapability.js +2 -6
  269. package/dist/sessionReadRedactionCapability.d.ts +0 -5
  270. package/dist/sessionReadRedactionCapability.js +2 -13
  271. package/dist/sessionSyncFileHistory.d.ts +4 -0
  272. package/dist/sessionSyncFileHistory.js +66 -0
  273. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -2
  274. package/dist/sessionSyncFileHistoryCapability.js +2 -9
  275. package/dist/skillToolListsCapability.d.ts +0 -2
  276. package/dist/skillToolListsCapability.js +2 -9
  277. package/dist/skillsWireCaps.d.ts +4 -0
  278. package/dist/skillsWireCaps.js +66 -1
  279. package/dist/sqlEngineCapability.d.ts +0 -1
  280. package/dist/sqlEngineCapability.js +9 -14
  281. package/dist/steerPriorityCapability.d.ts +0 -2
  282. package/dist/steerPriorityCapability.js +3 -12
  283. package/dist/storePostureCapability.d.ts +1 -5
  284. package/dist/storePostureCapability.js +16 -22
  285. package/dist/streamDrainingLegs.d.ts +6 -0
  286. package/dist/streamDrainingLegs.js +23 -0
  287. package/dist/subagent/engineCompactWire.js +13 -38
  288. package/dist/subagent/engineDelegatedPrompt.js +10 -6
  289. package/dist/subagent/engineSubagentOutput.d.ts +0 -1
  290. package/dist/subagent/engineSubagentOutput.js +5 -20
  291. package/dist/subagent/engineSubagentSteer.js +7 -5
  292. package/dist/subagent/engineSubagentTail.d.ts +0 -1
  293. package/dist/subagent/engineSubagentTail.js +7 -32
  294. package/dist/subagentContentStore.js +7 -18
  295. package/dist/supportFloor.d.ts +1 -0
  296. package/dist/supportFloor.js +15 -14
  297. package/dist/systemReminderTag.d.ts +1 -0
  298. package/dist/systemReminderTag.js +8 -0
  299. package/dist/terminalStatuses.d.ts +30 -0
  300. package/dist/terminalStatuses.js +67 -0
  301. package/dist/toolHistoryMismatch.d.ts +0 -3
  302. package/dist/toolHistoryMismatch.js +3 -7
  303. package/dist/toolResult.d.ts +6 -1
  304. package/dist/toolResult.js +90 -37
  305. package/dist/toolResultContent.d.ts +2 -0
  306. package/dist/toolResultContent.js +63 -0
  307. package/dist/types/engineState.d.ts +2 -1
  308. package/dist/usageAnalytics.d.ts +146 -0
  309. package/dist/usageAnalytics.js +335 -0
  310. package/dist/userInvokedSkillsCapability.d.ts +0 -2
  311. package/dist/userInvokedSkillsCapability.js +2 -9
  312. package/dist/webSearchBackendCapability.d.ts +0 -1
  313. package/dist/webSearchBackendCapability.js +3 -7
  314. package/dist/webSearchWireCaps.js +3 -11
  315. package/dist/wireErrorTriage.d.ts +2 -0
  316. package/dist/wireErrorTriage.js +34 -5
  317. package/dist/wireFailureShape.d.ts +23 -2
  318. package/dist/wireFailureShape.js +88 -43
  319. package/dist/wireRefusalCopy.js +2 -18
  320. package/dist/workflowClient.js +7 -11
  321. package/dist/workflowsJournalCapability.d.ts +0 -1
  322. package/dist/workflowsJournalCapability.js +2 -6
  323. package/dist/writeProtectionCapability.d.ts +0 -1
  324. package/dist/writeProtectionCapability.js +5 -10
  325. package/docs/INTEGRATION-CLIENTS.md +2279 -27
  326. package/package.json +5 -5
  327. package/dist/engineCapsGenerationGuard.d.ts +0 -4
  328. package/dist/engineCapsGenerationGuard.js +0 -19
  329. package/dist/panelRunningHistory.d.ts +0 -22
  330. package/dist/panelRunningHistory.js +0 -82
  331. package/dist/registryConflict.d.ts +0 -3
  332. package/dist/registryConflict.js +0 -44
@@ -1,4 +1,4 @@
1
- import { RESUME_CONTEXT_UNAVAILABLE } from './engineErrorCodes.js';
1
+ import { RESUME_CONTEXT_UNAVAILABLE, CHECKPOINT_UNSUPPORTED_VERSION, CHECKPOINT_WALLTIME_AXIS_RETIRED, CHECKPOINT_CONFIG_REFUSED } from './engineErrorCodes.js';
2
2
  export declare const RESUME_REFUSAL_CODES: readonly string[];
3
3
  export interface ResumeRefusalDetail {
4
4
  code: string;
@@ -50,6 +50,8 @@ export declare function parkedResumeStartupContent(detail: ParkedResumeStartupDe
50
50
  export interface CheckpointUnsupportedVersionDetail {
51
51
  code: 'checkpoint.unsupported_version';
52
52
  retriable: true;
53
+ writerVersion?: string;
54
+ readerVersion?: string;
53
55
  }
54
56
  export declare function checkpointUnsupportedVersionFromError(err: unknown): CheckpointUnsupportedVersionDetail | null;
55
57
  export type CheckpointUnsupportedParkKind = 'tool_approval' | 'plan_review' | 'resource_park' | 'wake' | 'workflow_host';
@@ -58,3 +60,18 @@ export interface CheckpointUnsupportedVersionContext {
58
60
  readonly runId?: string;
59
61
  }
60
62
  export declare function checkpointUnsupportedVersionContent(detail: CheckpointUnsupportedVersionDetail, ctx?: CheckpointUnsupportedVersionContext): string;
63
+ export type RefusedParkCode = typeof CHECKPOINT_UNSUPPORTED_VERSION | typeof CHECKPOINT_WALLTIME_AXIS_RETIRED | typeof CHECKPOINT_CONFIG_REFUSED;
64
+ export interface RefusedParkFacts {
65
+ readonly code: RefusedParkCode;
66
+ readonly field?: string;
67
+ readonly stillPending?: boolean;
68
+ }
69
+ export declare function refusedParkFromError(failure: unknown): RefusedParkFacts | null;
70
+ export interface RefusedParkContentInput {
71
+ readonly what: string;
72
+ readonly facts: RefusedParkFacts;
73
+ readonly lane: 'interactive' | 'print';
74
+ readonly runId?: string;
75
+ }
76
+ export declare function refusedParkContent(input: RefusedParkContentInput): string;
77
+ export declare function refusedParkBlockedContent(taskId: string, lane?: 'interactive' | 'print'): string;
@@ -1,7 +1,8 @@
1
- import { readErrorNumber, readErrorString } from './wireFailureShape.js';
1
+ import { readBlockedBy, readErrorNumber, readErrorString } from './wireFailureShape.js';
2
2
  import { readOwnDataNonEmptyString } from './ownKey.js';
3
- import { RESUME_CONTEXT_UNAVAILABLE, RESUME_PLACEMENT_MISMATCH, RESUME_PREFLIGHT_REJECTED, RESUME_POLICY_FOLD_CODE, PARKED_RESUME_STARTUP_FAILED, isStatusDerivedCoarseCode, RESUME_SESSION_NOT_FOUND, REQUEST_FIELD_CONFLICT, CHECKPOINT_UNSUPPORTED_VERSION, refusalSaysStillPending, } from './engineErrorCodes.js';
3
+ import { RESUME_CONTEXT_UNAVAILABLE, RESUME_PLACEMENT_MISMATCH, RESUME_PREFLIGHT_REJECTED, RESUME_POLICY_FOLD_CODE, PARKED_RESUME_STARTUP_FAILED, isStatusDerivedCoarseCode, RESUME_SESSION_NOT_FOUND, REQUEST_FIELD_CONFLICT, CHECKPOINT_UNSUPPORTED_VERSION, CHECKPOINT_WALLTIME_AXIS_RETIRED, CHECKPOINT_CONFIG_REFUSED, isRefusedParkCode, refusalSaysStillPending, refusalRetriableReading, } from './engineErrorCodes.js';
4
4
  import { capForDisplay } from './fleetTaskDesc.js';
5
+ import { engineVersionTier } from './supportFloor.js';
5
6
  import { resumeRetryLaterFromError } from './wireErrorTriage.js';
6
7
  export const RESUME_REFUSAL_CODES = Object.freeze([
7
8
  RESUME_PLACEMENT_MISMATCH,
@@ -54,22 +55,7 @@ export function resumePolicyBlockFromError(err) {
54
55
  }
55
56
  if (outer !== RESUME_POLICY_FOLD_CODE)
56
57
  return null;
57
- const judge = (v) => ({
58
- blockedBy: typeof v === 'string' && v.length > 0 ? { kind: 'named', code: v } : { kind: 'unreadable' },
59
- });
60
- try {
61
- const top = o['blockedBy'];
62
- if (top !== undefined)
63
- return judge(top);
64
- const extra = o['extra'];
65
- if (typeof extra === 'object' && extra !== null && !Array.isArray(extra) && Object.hasOwn(extra, 'blockedBy')) {
66
- return judge(extra['blockedBy']);
67
- }
68
- return { blockedBy: { kind: 'absent' } };
69
- }
70
- catch {
71
- return { blockedBy: { kind: 'unreadable' } };
72
- }
58
+ return { blockedBy: readBlockedBy(o) };
73
59
  }
74
60
  export function resumePolicyBlockContent(detail) {
75
61
  const b = detail.blockedBy;
@@ -87,10 +73,9 @@ export function resumePolicyBlockContent(detail) {
87
73
  ].join(' · ');
88
74
  }
89
75
  export { resumeReopenFromError, resumeReopenContent } from './hitl/suspendedReopen.js';
90
- const RESUME_SESSION_NOT_FOUND_TAIL = `(${RESUME_SESSION_NOT_FOUND})`;
91
76
  const REQUIRE_EXISTING_BY_STATUS = new Map([
92
- [404, Object.freeze({ form: 'session_not_found', code: RESUME_SESSION_NOT_FOUND, coarse: 'not_found.resource' })],
93
- [422, Object.freeze({ form: 'session_id_missing', code: REQUEST_FIELD_CONFLICT, coarse: 'request.unprocessable' })],
77
+ [404, Object.freeze({ form: 'session_not_found', code: RESUME_SESSION_NOT_FOUND })],
78
+ [422, Object.freeze({ form: 'session_id_missing', code: REQUEST_FIELD_CONFLICT })],
94
79
  ]);
95
80
  export function requireExistingSessionRefusalFromError(err) {
96
81
  if (typeof err !== 'object' || err === null)
@@ -101,15 +86,7 @@ export function requireExistingSessionRefusalFromError(err) {
101
86
  const byStatus = typeof status === 'number' ? REQUIRE_EXISTING_BY_STATUS.get(status) : undefined;
102
87
  if (byStatus === undefined)
103
88
  return null;
104
- const code = o['errorCode'];
105
- if (code === byStatus.code)
106
- return Object.freeze({ code: RESUME_SESSION_NOT_FOUND, form: byStatus.form });
107
- if (code !== byStatus.coarse)
108
- return null;
109
- const message = o['message'];
110
- return typeof message === 'string' && message.endsWith(RESUME_SESSION_NOT_FOUND_TAIL)
111
- ? Object.freeze({ code: RESUME_SESSION_NOT_FOUND, form: byStatus.form })
112
- : null;
89
+ return o['errorCode'] === byStatus.code ? Object.freeze({ code: RESUME_SESSION_NOT_FOUND, form: byStatus.form }) : null;
113
90
  }
114
91
  catch {
115
92
  return null;
@@ -221,7 +198,15 @@ export function checkpointUnsupportedVersionFromError(err) {
221
198
  }
222
199
  if (code !== CHECKPOINT_UNSUPPORTED_VERSION || !refusalSaysStillPending(err))
223
200
  return null;
224
- return { code: CHECKPOINT_UNSUPPORTED_VERSION, retriable: true };
201
+ const writerVersion = readErrorString(err, 'writerVersion');
202
+ const readerVersion = readErrorString(err, 'readerVersion');
203
+ const versions = writerVersion !== undefined && writerVersion !== '' && readerVersion !== undefined && readerVersion !== '' ? { writerVersion, readerVersion } : {};
204
+ return { code: CHECKPOINT_UNSUPPORTED_VERSION, retriable: true, ...versions };
205
+ }
206
+ function writerEngineIsNewer(writer, reader) {
207
+ if (engineVersionTier(writer) === 'unknown' || engineVersionTier(reader) !== 'engine')
208
+ return false;
209
+ return engineVersionTier(reader, writer) === 'legacy';
225
210
  }
226
211
  function checkpointUnsupportedHasRun(kind) {
227
212
  switch (kind) {
@@ -240,7 +225,23 @@ const CHECKPOINT_UNSUPPORTED_WHAT = 'This server cannot continue this parked wor
240
225
  const CHECKPOINT_UNSUPPORTED_STILL_WAITING = 'Nothing was decided or resumed and the parked work is still waiting, but sending the same request again will not by itself continue it';
241
226
  const CHECKPOINT_UNSUPPORTED_DRAIN = " — whoever operates this deployment can find such parked work before an upgrade with the server's pre-upgrade drain check";
242
227
  export function checkpointUnsupportedVersionContent(detail, ctx) {
243
- void detail;
228
+ let writer;
229
+ let reader;
230
+ try {
231
+ writer = detail.writerVersion;
232
+ reader = detail.readerVersion;
233
+ }
234
+ catch {
235
+ writer = undefined;
236
+ reader = undefined;
237
+ }
238
+ if (writerEngineIsNewer(writer, reader)) {
239
+ return [
240
+ `This parked work was stored by a newer engine version (${String(writer)}) than this engine (${String(reader)})`,
241
+ CHECKPOINT_UNSUPPORTED_STILL_WAITING,
242
+ `Continue it on an engine at version ${String(writer)} or newer`,
243
+ ].join(' · ');
244
+ }
244
245
  let kind;
245
246
  let runId;
246
247
  try {
@@ -266,3 +267,97 @@ export function checkpointUnsupportedVersionContent(detail, ctx) {
266
267
  }
267
268
  return [CHECKPOINT_UNSUPPORTED_WHAT, CHECKPOINT_UNSUPPORTED_STILL_WAITING, outlet + CHECKPOINT_UNSUPPORTED_DRAIN].join(' · ');
268
269
  }
270
+ const REFUSED_PARK_FIELD_TOKEN = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;
271
+ export function refusedParkFromError(failure) {
272
+ if (typeof failure !== 'object' || failure === null)
273
+ return null;
274
+ let code;
275
+ let status;
276
+ try {
277
+ code = failure.errorCode;
278
+ status = failure.status;
279
+ }
280
+ catch {
281
+ return null;
282
+ }
283
+ if (typeof code !== 'string' || !isRefusedParkCode(code))
284
+ return null;
285
+ if (status !== undefined && status !== 409)
286
+ return null;
287
+ const reading = refusalRetriableReading(failure);
288
+ const stillPending = reading === true ? true : status === 409 && reading === false ? false : undefined;
289
+ const rawField = code === CHECKPOINT_CONFIG_REFUSED ? readErrorString(failure, 'field') : undefined;
290
+ const field = rawField !== undefined && REFUSED_PARK_FIELD_TOKEN.test(rawField) ? rawField : undefined;
291
+ return Object.freeze({
292
+ code,
293
+ ...(field !== undefined ? { field } : {}),
294
+ ...(stillPending !== undefined ? { stillPending } : {}),
295
+ });
296
+ }
297
+ function refusedParkShownRunId(runId) {
298
+ return typeof runId === 'string' && /^[A-Za-z0-9._:-]{1,128}$/.test(runId) ? runId : undefined;
299
+ }
300
+ function refusedParkWhy(code, field) {
301
+ switch (code) {
302
+ case CHECKPOINT_WALLTIME_AXIS_RETIRED:
303
+ return 'its run carries a wall-clock time allowance, which this engine version no longer enforces';
304
+ case CHECKPOINT_CONFIG_REFUSED:
305
+ return field === 'inheritedGate'
306
+ ? 'the permission-mode setting it was parked with can no longer be read'
307
+ : 'the engine refuses the task configuration it was parked with';
308
+ default:
309
+ return 'it was parked under conditions this engine version does not support (for example, by an earlier engine version)';
310
+ }
311
+ }
312
+ export function refusedParkContent(input) {
313
+ let what;
314
+ let lane;
315
+ let runId;
316
+ let rawCode;
317
+ let field;
318
+ let stillPending;
319
+ try {
320
+ what = input.what;
321
+ lane = input.lane;
322
+ runId = input.runId;
323
+ }
324
+ catch {
325
+ what = lane = runId = undefined;
326
+ }
327
+ try {
328
+ const facts = input.facts;
329
+ rawCode = facts.code;
330
+ field = facts.field;
331
+ stillPending = facts.stillPending;
332
+ }
333
+ catch {
334
+ rawCode = field = stillPending = undefined;
335
+ }
336
+ const code = rawCode === CHECKPOINT_WALLTIME_AXIS_RETIRED || rawCode === CHECKPOINT_CONFIG_REFUSED ? rawCode : CHECKPOINT_UNSUPPORTED_VERSION;
337
+ const shownWhat = typeof what === 'string' && what !== '' ? capForDisplay(what, 40) : 'parked step';
338
+ const why = refusedParkWhy(code, typeof field === 'string' ? field : undefined);
339
+ const shownRun = refusedParkShownRunId(runId);
340
+ const head = `This ${shownWhat} cannot be resumed by this engine version: ${why}. The same refusal comes back every time, so ` +
341
+ `answering it again will not help (nothing was decided and nothing was resumed).`;
342
+ const configMayReturn = code === CHECKPOINT_CONFIG_REFUSED && field !== 'inheritedGate' ? ' If that configuration is restored, the same answer can go through again.' : '';
343
+ if (lane === 'print') {
344
+ if (stillPending === false) {
345
+ return `${head} The engine ended that run (${code}); submit the work again as a new task.`;
346
+ }
347
+ const cancel = `POST /v1/runs/${shownRun ?? '<run id>'}/cancel`;
348
+ return `${head}${configMayReturn} The parked run still holds this session (${code}): cancel it (${cancel}), then submit the work again as a new task.`;
349
+ }
350
+ if (stillPending === false) {
351
+ return `${head} The engine ended that parked run, so this conversation is free: send the work again as a new message.`;
352
+ }
353
+ return `${head}${configMayReturn} The parked run keeps this conversation busy until it is cancelled.`;
354
+ }
355
+ export function refusedParkBlockedContent(taskId, lane = 'interactive') {
356
+ const runId = refusedParkShownRunId(taskId);
357
+ const head = `sema will not put the card for run ${runId ?? '<unknown>'} back on screen by itself: this engine version refuses to resume it.`;
358
+ if (lane === 'print') {
359
+ return `${head} Cancel the run (POST /v1/runs/${runId ?? '<run id>'}/cancel) and submit the work again as a new task.`;
360
+ }
361
+ return (`${head} To free this conversation, send a message to bring the card back and answer it — sema then offers to cancel ` +
362
+ `that run, after which you can send the work again as a new message.`);
363
+ }
@@ -6,6 +6,8 @@ export type RetryStatus = {
6
6
  errClass?: BrainRetryErrClass | (string & {});
7
7
  retryAtMs?: number;
8
8
  errorStatus?: number;
9
+ providerCondition?: string;
10
+ providerConditionSource?: string;
9
11
  elapsedMs?: number;
10
12
  timeoutMs?: number;
11
13
  detail?: string;
@@ -17,6 +19,8 @@ export type RetryStatus = {
17
19
  errClass?: BrainRetryErrClass | (string & {});
18
20
  retryAtMs?: number;
19
21
  errorStatus?: number;
22
+ providerCondition?: string;
23
+ providerConditionSource?: string;
20
24
  terminal?: true;
21
25
  error: RetryStatusErrorPayload;
22
26
  elapsedMs?: number;
@@ -29,6 +33,8 @@ export type RetryStatus = {
29
33
  errClass?: BrainRetryErrClass | (string & {});
30
34
  retryAtMs?: number;
31
35
  errorStatus?: number;
36
+ providerCondition?: string;
37
+ providerConditionSource?: string;
32
38
  elapsedMs?: number;
33
39
  timeoutMs?: number;
34
40
  terminal?: never;
@@ -60,7 +66,9 @@ export interface BrainStatusPayload {
60
66
  errClass?: BrainRetryErrClass | (string & {});
61
67
  elapsedMs?: number;
62
68
  timeoutMs?: number;
69
+ providerCondition?: string;
70
+ providerConditionSource?: string;
63
71
  }
64
- export declare const BRAIN_STATUS_PAYLOAD_KEYS: readonly ["phase", "detail", "retryInSec", "retryInMs", "attempt", "maxRetries", "errClass", "retryAtMs", "errorStatus", "elapsedMs", "timeoutMs"];
72
+ export declare const BRAIN_STATUS_PAYLOAD_KEYS: readonly ["phase", "detail", "retryInSec", "retryInMs", "attempt", "maxRetries", "errClass", "retryAtMs", "errorStatus", "elapsedMs", "timeoutMs", "providerCondition", "providerConditionSource"];
65
73
  export declare function mapBrainStatusToRetry(p: BrainStatusPayload, nowMs: number): RetryStatus | null;
66
74
  export {};
@@ -20,6 +20,8 @@ export const BRAIN_STATUS_PAYLOAD_KEYS = [
20
20
  'errorStatus',
21
21
  'elapsedMs',
22
22
  'timeoutMs',
23
+ 'providerCondition',
24
+ 'providerConditionSource',
23
25
  ];
24
26
  const _brainStatusKeyPin = [true, true];
25
27
  void _brainStatusKeyPin;
@@ -33,6 +35,10 @@ export function mapBrainStatusToRetry(p, nowMs) {
33
35
  const cause = typeof p.errClass === 'string' && p.errClass.length > 0 ? { errClass: p.errClass } : {};
34
36
  const producerTiming = typeof p.retryAtMs === 'number' ? { retryAtMs: p.retryAtMs } : {};
35
37
  const failureStatus = typeof p.errorStatus === 'number' ? { errorStatus: p.errorStatus } : {};
38
+ const providerJudged = {
39
+ ...(typeof p.providerCondition === 'string' && p.providerCondition.length > 0 ? { providerCondition: p.providerCondition } : {}),
40
+ ...(typeof p.providerConditionSource === 'string' && p.providerConditionSource.length > 0 ? { providerConditionSource: p.providerConditionSource } : {}),
41
+ };
36
42
  const saneMs = (v) => typeof v === 'number' && Number.isFinite(v) && v >= 0 ? v : undefined;
37
43
  const elapsedMs = saneMs(p.elapsedMs);
38
44
  const timeoutMs = saneMs(p.timeoutMs);
@@ -40,9 +46,10 @@ export function mapBrainStatusToRetry(p, nowMs) {
40
46
  ...(elapsedMs !== undefined ? { elapsedMs } : {}),
41
47
  ...(timeoutMs !== undefined ? { timeoutMs } : {}),
42
48
  };
43
- const stalledDetail = typeof p.detail === 'string' && p.detail.length > 0 ? { detail: p.detail } : {};
49
+ const stalledShown = typeof p.detail === 'string' && p.detail.length > 0 ? displayUntrusted(p.detail) : '';
50
+ const stalledDetail = stalledShown.length > 0 ? { detail: stalledShown } : {};
44
51
  const shown = (absent) => (typeof p.detail === 'string' ? displayUntrusted(p.detail) : absent);
45
- const extra = { ...counts, ...cause, ...producerTiming, ...failureStatus, ...waitProgress };
52
+ const extra = { ...counts, ...cause, ...producerTiming, ...failureStatus, ...providerJudged, ...waitProgress };
46
53
  switch (p.phase) {
47
54
  case 'recovered':
48
55
  return null;
@@ -1,24 +1,15 @@
1
- export type RewindArchiveBit = 'on' | 'off' | 'not_reported' | 'malformed';
2
- export type RewindArchiveReading = {
3
- kind: 'unobserved';
4
- } | {
5
- kind: 'present';
6
- conversationAnchor: RewindArchiveBit;
7
- forkRestore: RewindArchiveBit;
8
- codeOnly: RewindArchiveBit;
9
- restoreFilesEpoch: RewindArchiveBit;
10
- };
1
+ import { type RewindArchiveReading, type RewindCodeArchive } from './rewindArchiveReading.js';
2
+ import type { RewindMode } from './rewindWireCaps.js';
3
+ export { projectRewindArchiveCapability, rewindConversationAvailability } from './rewindArchiveReading.js';
4
+ export type { RewindArchiveBit, RewindArchiveReading, RewindCodeArchive } from './rewindArchiveReading.js';
11
5
  export type RewindArchiveMode = 'both' | 'code';
12
- export type RewindCodeArchive = 'available' | 'unavailable' | 'unknown';
13
- export declare function projectRewindArchiveCapability(caps: unknown): RewindArchiveReading | undefined;
14
6
  export declare function noteEngineCapsForRewindArchive(baseUrl: string, caps: unknown, opts?: {
15
7
  generation?: number;
16
8
  }): void;
17
9
  export declare function observedRewindArchive(baseUrl?: string | undefined): RewindArchiveReading;
18
10
  export declare function rewindCodeArchiveAvailability(reading: RewindArchiveReading, mode: RewindArchiveMode): RewindCodeArchive;
19
11
  export declare function rewindArchiveDoctorDetail(reading: RewindArchiveReading, mode: RewindArchiveMode): string;
20
- export declare function rewindConversationAvailability(reading: RewindArchiveReading): RewindCodeArchive;
12
+ export declare function engineRewindRefusedNow(option: RewindMode, reading?: RewindArchiveReading): boolean;
21
13
  export declare function rewindConversationDoctorDetail(reading: RewindArchiveReading): string;
22
14
  export declare function rewindRestoreFilesEpochDetail(reading: RewindArchiveReading): string;
23
- export declare function forgetRewindArchiveReading(baseUrl: string | undefined): void;
24
15
  export declare function __resetRewindArchiveReadingsForTests(): void;
@@ -1,56 +1,13 @@
1
1
  import { engineWireTarget } from './engineWireTarget.js';
2
- import { createEngineCapReader } from './engineCapReader.js';
3
- import { _wireConversationRewindJudge } from './toolHistoryMismatch.js';
4
- const CAPS_KEYS = {
5
- conversationAnchor: 'resumeAt',
6
- forkRestore: 'rewindFiles',
7
- codeOnly: 'rewindFilesTo',
8
- restoreFilesEpoch: 'restoreFiles',
9
- };
10
- const _capsKeyPin = true;
11
- void _capsKeyPin;
12
- function bitOf(caps, key) {
13
- if (!Object.hasOwn(caps, key))
14
- return 'not_reported';
15
- const v = caps[key];
16
- if (v === undefined)
17
- return 'not_reported';
18
- if (v === true)
19
- return 'on';
20
- if (v === false)
21
- return 'off';
22
- return 'malformed';
23
- }
24
- export function projectRewindArchiveCapability(caps) {
25
- try {
26
- if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
27
- return undefined;
28
- return {
29
- kind: 'present',
30
- conversationAnchor: bitOf(caps, CAPS_KEYS.conversationAnchor),
31
- forkRestore: bitOf(caps, CAPS_KEYS.forkRestore),
32
- codeOnly: bitOf(caps, CAPS_KEYS.codeOnly),
33
- restoreFilesEpoch: bitOf(caps, CAPS_KEYS.restoreFilesEpoch),
34
- };
35
- }
36
- catch {
37
- return undefined;
38
- }
39
- }
40
- const reader = createEngineCapReader({
41
- name: 'rewindArchive',
42
- project: projectRewindArchiveCapability,
43
- makeUnobserved: () => ({ kind: 'unobserved' }),
44
- });
2
+ import { resetRewindArchiveReader, rewindArchiveReadingAt, rewindConversationAvailability, } from './rewindArchiveReading.js';
3
+ export { projectRewindArchiveCapability, rewindConversationAvailability } from './rewindArchiveReading.js';
45
4
  export function noteEngineCapsForRewindArchive(baseUrl, caps, opts) {
46
- _wireConversationRewindJudge(conversationRewindJudge);
47
- reader.note(baseUrl, caps, opts);
48
- }
49
- function conversationRewindJudge(engineBaseUrl) {
50
- return rewindConversationAvailability(observedRewindArchive(engineBaseUrl));
5
+ void baseUrl;
6
+ void caps;
7
+ void opts;
51
8
  }
52
9
  export function observedRewindArchive(baseUrl = engineWireTarget()?.baseUrl) {
53
- return reader.observed(baseUrl);
10
+ return rewindArchiveReadingAt(baseUrl);
54
11
  }
55
12
  export function rewindCodeArchiveAvailability(reading, mode) {
56
13
  if (reading.kind !== 'present')
@@ -87,14 +44,17 @@ export function rewindArchiveDoctorDetail(reading, mode) {
87
44
  return `${lane} reported in a shape this reader cannot read — the value is neither true nor false, so the answer is unknown, not "no"`;
88
45
  }
89
46
  }
90
- export function rewindConversationAvailability(reading) {
91
- if (reading.kind !== 'present')
92
- return 'unknown';
93
- if (reading.conversationAnchor === 'on')
94
- return 'available';
95
- if (reading.conversationAnchor === 'off')
96
- return 'unavailable';
97
- return 'unknown';
47
+ export function engineRewindRefusedNow(option, reading = observedRewindArchive()) {
48
+ switch (option) {
49
+ case 'both':
50
+ return rewindCodeArchiveAvailability(reading, 'both') === 'unavailable';
51
+ case 'code':
52
+ return rewindCodeArchiveAvailability(reading, 'code') === 'unavailable';
53
+ case 'conversation':
54
+ return rewindConversationAvailability(reading) === 'unavailable';
55
+ default:
56
+ return false;
57
+ }
98
58
  }
99
59
  export function rewindConversationDoctorDetail(reading) {
100
60
  const lane = 'rewind to a message';
@@ -127,9 +87,6 @@ export function rewindRestoreFilesEpochDetail(reading) {
127
87
  return 'the restore-files epoch bit is reported in an unreadable shape, so a rewind with code restore built from this reading leaves the key out and moves the conversation only';
128
88
  }
129
89
  }
130
- export function forgetRewindArchiveReading(baseUrl) {
131
- reader.forget(baseUrl);
132
- }
133
90
  export function __resetRewindArchiveReadingsForTests() {
134
- reader.__resetForTests();
91
+ resetRewindArchiveReader();
135
92
  }
@@ -0,0 +1,15 @@
1
+ export type RewindArchiveBit = 'on' | 'off' | 'not_reported' | 'malformed';
2
+ export type RewindArchiveReading = {
3
+ kind: 'unobserved';
4
+ } | {
5
+ kind: 'present';
6
+ conversationAnchor: RewindArchiveBit;
7
+ forkRestore: RewindArchiveBit;
8
+ codeOnly: RewindArchiveBit;
9
+ restoreFilesEpoch: RewindArchiveBit;
10
+ };
11
+ export type RewindCodeArchive = 'available' | 'unavailable' | 'unknown';
12
+ export declare function projectRewindArchiveCapability(caps: unknown): RewindArchiveReading | undefined;
13
+ export declare function rewindArchiveReadingAt(baseUrl: string | undefined): RewindArchiveReading;
14
+ export declare function resetRewindArchiveReader(): void;
15
+ export declare function rewindConversationAvailability(reading: RewindArchiveReading): RewindCodeArchive;
@@ -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
+ }
@@ -0,0 +1,21 @@
1
+ import { type RewindArchiveReading } from './rewindArchiveCapability.js';
2
+ import { type RewindMode, type SeamRewindSpec } from './rewindWireCaps.js';
3
+ export type RewindRestoreOption = RewindMode | 'summarize' | 'summarize_up_to' | 'nevermind';
4
+ export type RewindTargetPosition = 'root' | 'after-root' | 'unknown';
5
+ export interface RewindTargetResolution {
6
+ readonly position: RewindTargetPosition;
7
+ readonly targetEntryId?: string;
8
+ readonly anchorUnresolved?: true;
9
+ }
10
+ export type RewindEngineNoneReason = 'not-an-engine-rewind' | 'no-engine-turn-to-rewind' | 'unresolved';
11
+ export type RewindEngineAction = {
12
+ readonly kind: 'none';
13
+ readonly reason: RewindEngineNoneReason;
14
+ } | {
15
+ readonly kind: 'arm';
16
+ readonly spec: SeamRewindSpec;
17
+ } | {
18
+ readonly kind: 'reopen';
19
+ };
20
+ export declare function decideRewindEngineAction(option: RewindRestoreOption, resolved: RewindTargetResolution, reading?: RewindArchiveReading): RewindEngineAction;
21
+ export declare function previewEngineRewind(option: RewindRestoreOption, resolved: RewindTargetResolution, reading?: RewindArchiveReading): RewindEngineAction['kind'];
@@ -0,0 +1,36 @@
1
+ import { observedRewindArchive } from './rewindArchiveCapability.js';
2
+ import { REWIND_MODES, rewindSpecForMode } from './rewindWireCaps.js';
3
+ import { readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
4
+ function modeOfOption(option) {
5
+ return REWIND_MODES.includes(option) ? option : undefined;
6
+ }
7
+ function carriesResumeAt(mode) {
8
+ return rewindSpecForMode(mode, 'x').resumeAt !== undefined;
9
+ }
10
+ function positionOf(resolved) {
11
+ const p = readOwnDataValue(resolved, 'position');
12
+ return p === 'root' || p === 'after-root' ? p : 'unknown';
13
+ }
14
+ export function decideRewindEngineAction(option, resolved, reading = observedRewindArchive()) {
15
+ const mode = modeOfOption(option);
16
+ if (mode === undefined)
17
+ return { kind: 'none', reason: 'not-an-engine-rewind' };
18
+ const position = positionOf(resolved);
19
+ const targetEntryId = readOwnDataNonEmptyString(resolved, 'targetEntryId');
20
+ if (!carriesResumeAt(mode)) {
21
+ if (targetEntryId !== undefined)
22
+ return { kind: 'arm', spec: rewindSpecForMode(mode, targetEntryId, reading) };
23
+ const unresolved = position === 'unknown' || readOwnDataValue(resolved, 'anchorUnresolved') === true;
24
+ return { kind: 'none', reason: unresolved ? 'unresolved' : 'no-engine-turn-to-rewind' };
25
+ }
26
+ if (position === 'root')
27
+ return { kind: 'reopen' };
28
+ if (position === 'unknown')
29
+ return { kind: 'none', reason: 'unresolved' };
30
+ return targetEntryId !== undefined
31
+ ? { kind: 'arm', spec: rewindSpecForMode(mode, targetEntryId, reading) }
32
+ : { kind: 'none', reason: 'no-engine-turn-to-rewind' };
33
+ }
34
+ export function previewEngineRewind(option, resolved, reading = observedRewindArchive()) {
35
+ return decideRewindEngineAction(option, resolved, reading).kind;
36
+ }
@@ -5,6 +5,7 @@ export interface SeamRewindSpec {
5
5
  restoreFiles?: boolean;
6
6
  rewindFilesTo?: string;
7
7
  }
8
- export type RewindMode = 'both' | 'conversation' | 'code';
8
+ export declare const REWIND_MODES: readonly ["both", "conversation", "code"];
9
+ export type RewindMode = (typeof REWIND_MODES)[number];
9
10
  export declare function rewindSpecForMode(mode: RewindMode, targetEntryId: string, reading?: RewindArchiveReading): SeamRewindSpec;
10
11
  export declare function projectRewind(pending: SeamRewindSpec | undefined): SeamRewindSpec;
@@ -1,3 +1,4 @@
1
+ export const REWIND_MODES = Object.freeze(['both', 'conversation', 'code']);
1
2
  function restoreFilesKeyMaySend(reading) {
2
3
  if (reading === undefined)
3
4
  return true;
@@ -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
  }