@sema-agent/client-core 0.93.1 → 0.95.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 (321) hide show
  1. package/CHANGELOG.md +554 -0
  2. package/README.md +89 -55
  3. package/dist/adapt/arms.js +13 -11
  4. package/dist/adapt/panelTasks.js +4 -10
  5. package/dist/adapt/toolCards.js +2 -2
  6. package/dist/adapt/wireShapes.js +3 -8
  7. package/dist/adapter/activeRunSelfHeal.d.ts +8 -3
  8. package/dist/adapter/activeRunSelfHeal.js +20 -12
  9. package/dist/adapter/downstream/eventToSdkMessage.js +24 -17
  10. package/dist/adapter/downstream/terminalToSdkResult.js +13 -6
  11. package/dist/adapter/runStream.js +2 -1
  12. package/dist/adapter/types.d.ts +7 -0
  13. package/dist/adapter/types.js +15 -0
  14. package/dist/agentSession/backgroundView.js +5 -1
  15. package/dist/agentSession/engineAgentRegistryRead.js +2 -1
  16. package/dist/agentSession/engineSessionBackgroundStop.js +5 -3
  17. package/dist/agentsWireCaps.d.ts +17 -0
  18. package/dist/agentsWireCaps.js +111 -1
  19. package/dist/approvalDecidedByCapability.d.ts +0 -1
  20. package/dist/approvalDecidedByCapability.js +2 -7
  21. package/dist/approvalReachWire.d.ts +18 -0
  22. package/dist/approvalReachWire.js +58 -0
  23. package/dist/approvalsStreamLiveCapability.d.ts +0 -1
  24. package/dist/approvalsStreamLiveCapability.js +15 -14
  25. package/dist/atMostOnce.d.ts +8 -0
  26. package/dist/atMostOnce.js +36 -0
  27. package/dist/attachmentSeatCapability.d.ts +0 -1
  28. package/dist/attachmentSeatCapability.js +0 -3
  29. package/dist/attachmentsWireCaps.js +11 -6
  30. package/dist/bashExitReading.d.ts +10 -0
  31. package/dist/bashExitReading.js +12 -0
  32. package/dist/callerCwdCapability.d.ts +15 -0
  33. package/dist/callerCwdCapability.js +42 -0
  34. package/dist/centerWiringCapability.d.ts +1 -3
  35. package/dist/centerWiringCapability.js +18 -21
  36. package/dist/classifierStatus.js +4 -4
  37. package/dist/cloudConfigWireCaps.js +43 -21
  38. package/dist/compensations.js +1 -1
  39. package/dist/controlRouter.js +3 -10
  40. package/dist/coreValuePorts.d.ts +64 -1
  41. package/dist/coreValuePorts.js +30 -0
  42. package/dist/cycleOrder.d.ts +15 -0
  43. package/dist/cycleOrder.js +45 -0
  44. package/dist/decideFailureNote.js +4 -1
  45. package/dist/decideReceipt.d.ts +2 -1
  46. package/dist/decideReceipt.js +41 -13
  47. package/dist/declared/supportFloorDeclared.d.ts +1 -0
  48. package/dist/declared/supportFloorDeclared.js +5 -0
  49. package/dist/detachWire.d.ts +1 -4
  50. package/dist/detachWire.js +1 -1
  51. package/dist/deviceExecutorManagementCapability.d.ts +0 -1
  52. package/dist/deviceExecutorManagementCapability.js +36 -40
  53. package/dist/deviceFlowPolling.d.ts +5 -0
  54. package/dist/deviceFlowPolling.js +28 -0
  55. package/dist/deviceRebind.d.ts +88 -0
  56. package/dist/deviceRebind.js +242 -0
  57. package/dist/displayUntrusted.d.ts +1 -0
  58. package/dist/displayUntrusted.js +963 -30
  59. package/dist/engineAgentAbsence.d.ts +2 -2
  60. package/dist/engineAgentPanelStore.d.ts +8 -18
  61. package/dist/engineAgentPanelStore.js +19 -537
  62. package/dist/engineCapReader.d.ts +6 -6
  63. package/dist/engineCapReader.js +30 -43
  64. package/dist/engineCapsCache.d.ts +7 -2
  65. package/dist/engineCapsCache.js +64 -26
  66. package/dist/engineCredentialRequirement.d.ts +9 -0
  67. package/dist/engineCredentialRequirement.js +23 -0
  68. package/dist/engineEnvSourcing.d.ts +53 -0
  69. package/dist/engineEnvSourcing.js +81 -0
  70. package/dist/engineErrorCodes.d.ts +19 -4
  71. package/dist/engineErrorCodes.js +39 -21
  72. package/dist/engineIdentity.js +2 -0
  73. package/dist/engineNoticeCodes.d.ts +22 -2
  74. package/dist/engineNoticeCodes.js +73 -6
  75. package/dist/engineRefusedToolName.d.ts +1 -0
  76. package/dist/engineRefusedToolName.js +8 -0
  77. package/dist/engineWireSdk.js +2 -2
  78. package/dist/executionLaneCapability.d.ts +2 -3
  79. package/dist/executionLaneCapability.js +28 -28
  80. package/dist/fileHistoryCaptureCapability.d.ts +0 -1
  81. package/dist/fileHistoryCaptureCapability.js +13 -12
  82. package/dist/fileHistoryLegNotice.d.ts +14 -2
  83. package/dist/fileHistoryLegNotice.js +101 -15
  84. package/dist/fleet/fleetLedger.d.ts +2 -0
  85. package/dist/fleet/fleetLedger.js +74 -52
  86. package/dist/fleet/fleetProjection.d.ts +0 -3
  87. package/dist/fleet/fleetProjection.js +9 -16
  88. package/dist/fleetAgentPanelProjection.d.ts +4 -17
  89. package/dist/fleetAgentPanelProjection.js +7 -197
  90. package/dist/fleetAgentRowLike.d.ts +16 -0
  91. package/dist/fleetAgentRowLike.js +1 -0
  92. package/dist/gateOutcome.d.ts +2 -1
  93. package/dist/gateOutcome.js +33 -18
  94. package/dist/gateVocabulary.js +1 -1
  95. package/dist/generated/engineAskFaceTables.d.ts +3 -0
  96. package/dist/generated/engineAskFaceTables.js +12 -0
  97. package/dist/generated/engineFactTables.d.ts +4 -2
  98. package/dist/generated/engineFactTables.js +13 -0
  99. package/dist/generated/engineNoticeTables.d.ts +5 -0
  100. package/dist/generated/engineNoticeTables.js +7 -0
  101. package/dist/generated/sdkFactTables.d.ts +5 -0
  102. package/dist/generated/sdkFactTables.js +34 -0
  103. package/dist/generated/settingsSchemaFns.d.ts +10 -0
  104. package/dist/generated/settingsSchemaFns.js +22 -0
  105. package/dist/generated/settingsSchemaTables.d.ts +3 -0
  106. package/dist/generated/settingsSchemaTables.js +3 -0
  107. package/dist/headlessPermissionModeWire.d.ts +2 -2
  108. package/dist/headlessPermissionModeWire.js +11 -21
  109. package/dist/headlessReconnectWire.js +49 -20
  110. package/dist/hitl/allowRuleShadow.d.ts +1 -1
  111. package/dist/hitl/allowRuleShadow.js +49 -8
  112. package/dist/hitl/approvalCompleteParked.d.ts +1 -0
  113. package/dist/hitl/approvalCompleteParked.js +14 -0
  114. package/dist/hitl/approvalEndingCause.d.ts +5 -0
  115. package/dist/hitl/approvalEndingCause.js +61 -0
  116. package/dist/hitl/approvalHolds.d.ts +46 -0
  117. package/dist/hitl/approvalHolds.js +140 -0
  118. package/dist/hitl/approvalOutcomeNote.js +2 -1
  119. package/dist/hitl/approvalResolution.js +9 -1
  120. package/dist/hitl/approvalsFeed.js +23 -6
  121. package/dist/hitl/askGateWire.d.ts +2 -1
  122. package/dist/hitl/askGateWire.js +29 -1
  123. package/dist/hitl/automaticAnswerVerdict.d.ts +8 -2
  124. package/dist/hitl/automaticAnswerVerdict.js +71 -23
  125. package/dist/hitl/crashConverged.js +2 -0
  126. package/dist/hitl/decisionConflict.d.ts +3 -0
  127. package/dist/hitl/decisionConflict.js +43 -0
  128. package/dist/hitl/decisionRefusal.d.ts +23 -0
  129. package/dist/hitl/decisionRefusal.js +88 -0
  130. package/dist/hitl/frameRouter.d.ts +10 -0
  131. package/dist/hitl/frameRouter.js +71 -32
  132. package/dist/hitl/gateLedger.d.ts +8 -0
  133. package/dist/hitl/gateLedger.js +38 -0
  134. package/dist/hitl/hitlBridge.d.ts +14 -3
  135. package/dist/hitl/hitlBridge.js +75 -62
  136. package/dist/hitl/hitlHostSurface.d.ts +3 -0
  137. package/dist/hitl/hitlHostSurface.js +17 -15
  138. package/dist/hitl/livePendingAsk.d.ts +16 -6
  139. package/dist/hitl/livePendingAsk.js +36 -4
  140. package/dist/hitl/localAllowRule.js +2 -1
  141. package/dist/hitl/noAllowCause.d.ts +9 -0
  142. package/dist/hitl/noAllowCause.js +26 -0
  143. package/dist/hitl/parkExpiryJudgements.d.ts +19 -0
  144. package/dist/hitl/parkExpiryJudgements.js +46 -0
  145. package/dist/hitl/parkResolver.d.ts +3 -7
  146. package/dist/hitl/parkResolver.js +55 -28
  147. package/dist/hitl/parkRowBirthWait.js +2 -1
  148. package/dist/hitl/persistedRulesWire.d.ts +6 -1
  149. package/dist/hitl/persistedRulesWire.js +16 -4
  150. package/dist/hitl/planReviewWire.d.ts +2 -3
  151. package/dist/hitl/planReviewWire.js +86 -39
  152. package/dist/hitl/replayedApproval.d.ts +8 -0
  153. package/dist/hitl/replayedApproval.js +125 -10
  154. package/dist/hitl/resumeRunningCard.d.ts +2 -0
  155. package/dist/hitl/resumeRunningCard.js +15 -4
  156. package/dist/hitl/sessionPolicyDeliverable.d.ts +1 -1
  157. package/dist/hitl/sessionPolicyDeliverable.js +3 -8
  158. package/dist/hitl/sessionPolicyWire.js +1 -1
  159. package/dist/hitl/toolApprovalWire.d.ts +50 -5
  160. package/dist/hitl/toolApprovalWire.js +368 -56
  161. package/dist/hooksWireCaps.js +38 -6
  162. package/dist/host.d.ts +5 -0
  163. package/dist/host.js +3 -1
  164. package/dist/hostCallbackGuard.d.ts +1 -0
  165. package/dist/hostCallbackGuard.js +25 -0
  166. package/dist/humanTurnRead.d.ts +15 -1
  167. package/dist/humanTurnRead.js +28 -2
  168. package/dist/index.d.ts +45 -14
  169. package/dist/index.js +33 -12
  170. package/dist/interactiveInterrupt.d.ts +8 -0
  171. package/dist/interactiveInterrupt.js +54 -0
  172. package/dist/limitsWire.d.ts +5 -1
  173. package/dist/limitsWire.js +51 -13
  174. package/dist/liveModelCatalog.d.ts +109 -0
  175. package/dist/liveModelCatalog.js +344 -18
  176. package/dist/mcpEngineLeg.d.ts +25 -0
  177. package/dist/mcpEngineLeg.js +71 -15
  178. package/dist/mcpPanel.js +2 -1
  179. package/dist/mcpProbeCapability.d.ts +0 -1
  180. package/dist/mcpProbeCapability.js +13 -12
  181. package/dist/mcpReconnect.d.ts +1 -3
  182. package/dist/mcpReconnect.js +20 -10
  183. package/dist/memoryComplianceCapability.d.ts +0 -1
  184. package/dist/memoryComplianceCapability.js +14 -13
  185. package/dist/memoryOriginCapability.d.ts +0 -1
  186. package/dist/memoryOriginCapability.js +14 -13
  187. package/dist/memoryVerbsWire.d.ts +1 -1
  188. package/dist/memoryVerbsWire.js +4 -0
  189. package/dist/model/liveCatalogShape.d.ts +14 -0
  190. package/dist/model/liveCatalogShape.js +71 -0
  191. package/dist/model/modelSupplyRules.d.ts +1 -0
  192. package/dist/model/modelSupplyRules.js +30 -9
  193. package/dist/model/modelsPolicy.d.ts +21 -0
  194. package/dist/model/modelsPolicy.js +90 -0
  195. package/dist/modelIdentityResolvability.d.ts +4 -2
  196. package/dist/modelIdentityResolvability.js +25 -5
  197. package/dist/modelSwitchFallback.d.ts +69 -0
  198. package/dist/modelSwitchFallback.js +206 -0
  199. package/dist/notifications.js +12 -11
  200. package/dist/outputStyleSeatCapability.d.ts +15 -0
  201. package/dist/outputStyleSeatCapability.js +42 -0
  202. package/dist/ownKey.d.ts +7 -0
  203. package/dist/ownKey.js +58 -0
  204. package/dist/panelReduce.d.ts +114 -0
  205. package/dist/panelReduce.js +1135 -0
  206. package/dist/panelStateHolder.d.ts +17 -0
  207. package/dist/panelStateHolder.js +201 -0
  208. package/dist/peerLaneCapability.d.ts +0 -1
  209. package/dist/peerLaneCapability.js +15 -14
  210. package/dist/permissionModesCapability.d.ts +0 -1
  211. package/dist/permissionModesCapability.js +5 -10
  212. package/dist/permissionRuleIssue.js +1 -1
  213. package/dist/permissionRulesWriteCapability.d.ts +0 -1
  214. package/dist/permissionRulesWriteCapability.js +15 -14
  215. package/dist/permissionsAllowGrantCapability.d.ts +2 -1
  216. package/dist/permissionsAllowGrantCapability.js +35 -19
  217. package/dist/permissionsDeclaration.d.ts +16 -1
  218. package/dist/permissionsDeclaration.js +142 -15
  219. package/dist/printToolResultFrame.js +2 -10
  220. package/dist/promptDelivery.js +0 -8
  221. package/dist/protocolSegment.d.ts +1 -0
  222. package/dist/protocolSegment.js +13 -1
  223. package/dist/request/taskRequest.d.ts +11 -3
  224. package/dist/request/taskRequest.js +13 -1
  225. package/dist/resultFrameKeys.d.ts +4 -0
  226. package/dist/resultFrameKeys.js +13 -0
  227. package/dist/resumeRefusalCopy.d.ts +18 -1
  228. package/dist/resumeRefusalCopy.js +132 -31
  229. package/dist/retryStatus.js +6 -4
  230. package/dist/rewindArchiveCapability.d.ts +2 -1
  231. package/dist/rewindArchiveCapability.js +28 -15
  232. package/dist/rewindEngineAction.d.ts +21 -0
  233. package/dist/rewindEngineAction.js +36 -0
  234. package/dist/rewindWireCaps.d.ts +2 -1
  235. package/dist/rewindWireCaps.js +1 -0
  236. package/dist/{hitl/rosterMountedNames.d.ts → rosterMountedNames.d.ts} +1 -1
  237. package/dist/runCancelContext.js +2 -1
  238. package/dist/runTerminal.d.ts +0 -11
  239. package/dist/runTerminal.js +4 -27
  240. package/dist/sdkRegistryTransit.d.ts +2 -1
  241. package/dist/sdkRegistryTransit.js +1 -0
  242. package/dist/sealedKeyCapability.d.ts +0 -1
  243. package/dist/sealedKeyCapability.js +19 -20
  244. package/dist/seatContract.d.ts +85 -28
  245. package/dist/seatContract.js +512 -148
  246. package/dist/sessionIdSegment.d.ts +1 -0
  247. package/dist/sessionIdSegment.js +11 -0
  248. package/dist/sessionMemoryErase.d.ts +1 -1
  249. package/dist/sessionMemoryErase.js +6 -1
  250. package/dist/sessionMemoryStatus.js +3 -2
  251. package/dist/sessionPolicyCapability.d.ts +0 -1
  252. package/dist/sessionPolicyCapability.js +14 -13
  253. package/dist/sessionReadRedactionCapability.d.ts +15 -0
  254. package/dist/sessionReadRedactionCapability.js +42 -0
  255. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
  256. package/dist/sessionSyncFileHistoryCapability.js +13 -12
  257. package/dist/skillToolListsCapability.d.ts +0 -1
  258. package/dist/skillToolListsCapability.js +13 -12
  259. package/dist/skillsWireCaps.d.ts +4 -0
  260. package/dist/skillsWireCaps.js +66 -1
  261. package/dist/sqlEngineCapability.d.ts +0 -1
  262. package/dist/sqlEngineCapability.js +21 -21
  263. package/dist/steerPriorityCapability.d.ts +0 -1
  264. package/dist/steerPriorityCapability.js +18 -19
  265. package/dist/storePostureCapability.d.ts +1 -1
  266. package/dist/storePostureCapability.js +16 -16
  267. package/dist/streamDrainingLegs.d.ts +6 -0
  268. package/dist/streamDrainingLegs.js +23 -0
  269. package/dist/subagent/agentStateDetail.d.ts +1 -0
  270. package/dist/subagent/agentStateDetail.js +41 -0
  271. package/dist/subagent/engineCompactWire.d.ts +15 -0
  272. package/dist/subagent/engineCompactWire.js +82 -45
  273. package/dist/subagent/engineDelegatedPrompt.js +10 -6
  274. package/dist/subagent/engineSubagentOutput.d.ts +0 -1
  275. package/dist/subagent/engineSubagentOutput.js +5 -20
  276. package/dist/subagent/engineSubagentTail.d.ts +0 -1
  277. package/dist/subagent/engineSubagentTail.js +7 -32
  278. package/dist/subagentContentStore.js +3 -3
  279. package/dist/supportFloor.js +2 -5
  280. package/dist/taskRequestWords.d.ts +2 -4
  281. package/dist/taskRequestWords.js +3 -2
  282. package/dist/terminalStatuses.d.ts +30 -0
  283. package/dist/terminalStatuses.js +67 -0
  284. package/dist/toolResult.d.ts +5 -0
  285. package/dist/toolResult.js +88 -36
  286. package/dist/types/engineState.d.ts +2 -1
  287. package/dist/usageAnalytics.d.ts +146 -0
  288. package/dist/usageAnalytics.js +311 -0
  289. package/dist/userAttachmentEnvelope.d.ts +22 -1
  290. package/dist/userAttachmentEnvelope.js +90 -2
  291. package/dist/userInvokedSkillsCapability.d.ts +0 -1
  292. package/dist/userInvokedSkillsCapability.js +13 -12
  293. package/dist/webSearchBackendCapability.d.ts +0 -1
  294. package/dist/webSearchBackendCapability.js +20 -19
  295. package/dist/webSearchWireCaps.js +3 -11
  296. package/dist/wireErrorTriage.d.ts +11 -0
  297. package/dist/wireErrorTriage.js +35 -0
  298. package/dist/wireFailureShape.d.ts +10 -0
  299. package/dist/wireFailureShape.js +72 -5
  300. package/dist/wireRefusalCopy.d.ts +6 -1
  301. package/dist/wireRefusalCopy.js +23 -25
  302. package/dist/wiringInstructionsAttribution.d.ts +10 -0
  303. package/dist/wiringInstructionsAttribution.js +67 -0
  304. package/dist/workflowClient.js +19 -2
  305. package/dist/workflowsJournalCapability.d.ts +0 -1
  306. package/dist/workflowsJournalCapability.js +13 -12
  307. package/dist/writeProtectionCapability.d.ts +0 -1
  308. package/dist/writeProtectionCapability.js +26 -26
  309. package/docs/INTEGRATION-CLIENTS.md +1733 -52
  310. package/package.json +5 -5
  311. package/dist/askSurvivesStandingAnswer.d.ts +0 -13
  312. package/dist/askSurvivesStandingAnswer.js +0 -53
  313. package/dist/engineCapsGenerationGuard.d.ts +0 -4
  314. package/dist/engineCapsGenerationGuard.js +0 -19
  315. package/dist/hitl/askSurvivesPosture.d.ts +0 -20
  316. package/dist/hitl/askSurvivesPosture.js +0 -48
  317. package/dist/panelRunningHistory.d.ts +0 -22
  318. package/dist/panelRunningHistory.js +0 -82
  319. package/dist/registryConflict.d.ts +0 -3
  320. package/dist/registryConflict.js +0 -44
  321. /package/dist/{hitl/rosterMountedNames.js → rosterMountedNames.js} +0 -0
@@ -0,0 +1,28 @@
1
+ import { SETTINGS_DEVICE_CODE_TTL_SECONDS, SETTINGS_DEVICE_POLL_INTERVAL_SECONDS } from './generated/settingsSchemaTables.js';
2
+ function positiveSecondsOf(reading, key) {
3
+ try {
4
+ const desc = Object.getOwnPropertyDescriptor(reading, key);
5
+ if (desc === undefined || !('value' in desc))
6
+ return undefined;
7
+ const v = desc.value;
8
+ return typeof v === 'number' && Number.isFinite(v) && v > 0 ? v : undefined;
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ }
14
+ export function deviceFlowPollingPlan(reading) {
15
+ let isObjectReading = false;
16
+ try {
17
+ isObjectReading = typeof reading === 'object' && reading !== null && !Array.isArray(reading);
18
+ }
19
+ catch {
20
+ isObjectReading = false;
21
+ }
22
+ if (!isObjectReading)
23
+ return undefined;
24
+ const r = reading;
25
+ const ttlSeconds = positiveSecondsOf(r, 'expires_in') ?? SETTINGS_DEVICE_CODE_TTL_SECONDS;
26
+ const intervalSeconds = Math.max(1, positiveSecondsOf(r, 'interval') ?? SETTINGS_DEVICE_POLL_INTERVAL_SECONDS);
27
+ return Object.freeze({ timeoutMs: ttlSeconds * 1000, intervalSeconds });
28
+ }
@@ -0,0 +1,88 @@
1
+ import type { AgentClient } from '@sema-agent/sdk';
2
+ export type DeviceListVerb = Pick<AgentClient['devices'], 'list'>;
3
+ export type DeviceSessionBindingVerb = Pick<AgentClient['devices'], 'sessionBinding'>;
4
+ export type DeviceRebindVerb = Pick<AgentClient['devices'], 'rebind'>;
5
+ export interface DeviceRosterRow {
6
+ readonly deviceId: string;
7
+ readonly name?: string;
8
+ readonly status: 'online' | 'offline' | 'unknown';
9
+ readonly lastSeenAt?: string;
10
+ }
11
+ export interface DeviceBindingReading {
12
+ readonly deviceId: string;
13
+ readonly rev: number;
14
+ readonly boundAt?: string;
15
+ }
16
+ export interface DeviceRefused {
17
+ readonly kind: 'refused';
18
+ readonly status: number;
19
+ readonly errorCode?: string;
20
+ readonly message?: string;
21
+ }
22
+ export interface DeviceLaneAbsent {
23
+ readonly kind: 'lane-absent';
24
+ readonly runStoreOnly?: true;
25
+ }
26
+ export interface DeviceTransport {
27
+ readonly kind: 'transport';
28
+ readonly detail?: string;
29
+ }
30
+ export interface DeviceUnreadable {
31
+ readonly kind: 'unreadable';
32
+ readonly why: string;
33
+ }
34
+ export interface DeviceUnarmed {
35
+ readonly kind: 'unarmed';
36
+ }
37
+ export type DeviceListOutcome = {
38
+ readonly kind: 'ok';
39
+ readonly devices: readonly DeviceRosterRow[];
40
+ readonly dropped: number;
41
+ } | DeviceUnreadable | DeviceLaneAbsent | DeviceRefused | DeviceTransport | DeviceUnarmed;
42
+ export type DeviceSessionBindingOutcome = {
43
+ readonly kind: 'ok';
44
+ readonly rootSessionId: string;
45
+ readonly boundDevice: DeviceBindingReading;
46
+ } | {
47
+ readonly kind: 'not-found';
48
+ } | DeviceUnreadable | DeviceLaneAbsent | DeviceRefused | DeviceTransport | DeviceUnarmed;
49
+ export interface DeviceRebindInput {
50
+ readonly rootSessionId: string;
51
+ readonly toDeviceId: string;
52
+ readonly expectedRev: number;
53
+ readonly fromDeviceId: string;
54
+ }
55
+ export interface DeviceRebindUnconfirmed {
56
+ readonly kind: 'unconfirmed';
57
+ readonly why: 'accepted-unreadable' | 'transport' | 'server-error';
58
+ readonly detail?: string;
59
+ readonly mayStillBeRunning: boolean;
60
+ }
61
+ export type DeviceRebindOutcome = {
62
+ readonly kind: 'ok';
63
+ readonly deviceId: string;
64
+ readonly rev: number;
65
+ readonly workspaceCarryover?: 'none';
66
+ } | {
67
+ readonly kind: 'active-run';
68
+ readonly activeTaskId?: string;
69
+ } | {
70
+ readonly kind: 'rev-conflict';
71
+ readonly currentRev?: number;
72
+ } | {
73
+ readonly kind: 'not-found';
74
+ } | DeviceRebindUnconfirmed | DeviceLaneAbsent | DeviceRefused | DeviceUnarmed;
75
+ export type DeviceRebindReconcileVerdict = 'landed' | 'already-there' | 'unchanged' | 'unknown';
76
+ export declare function listDevices(devices: DeviceListVerb | null | undefined, opts?: {
77
+ readonly signal?: AbortSignal | undefined;
78
+ }): Promise<DeviceListOutcome>;
79
+ export declare function readSessionBinding(devices: DeviceSessionBindingVerb | null | undefined, rootSessionId: string, opts?: {
80
+ readonly signal?: AbortSignal | undefined;
81
+ }): Promise<DeviceSessionBindingOutcome>;
82
+ export declare function rebindSession(devices: DeviceRebindVerb | null | undefined, req: DeviceRebindInput, opts?: {
83
+ readonly signal?: AbortSignal | undefined;
84
+ }): Promise<DeviceRebindOutcome>;
85
+ export declare function reconcileRebindOutcome(before: DeviceBindingReading, toDeviceId: string, after: DeviceBindingReading | null, opts: {
86
+ readonly serverMayStillBeRunning: boolean;
87
+ }): DeviceRebindReconcileVerdict;
88
+ export declare function rebindProvesRequestNotApplied(outcome: DeviceRebindOutcome): boolean;
@@ -0,0 +1,242 @@
1
+ import { atMostOnceVerdictOf } from './atMostOnce.js';
2
+ import { readOwnDataValue } from './ownKey.js';
3
+ const LANE_ABSENT = 'capability.device_lane_required';
4
+ const RUN_STORE_ABSENT = 'capability.run_store_required';
5
+ const NOT_FOUND = 'not_found.device';
6
+ const ACTIVE_RUN = 'device.rebind_active_run';
7
+ const REV_CONFLICT = 'device.rebind_rev_conflict';
8
+ const SERVICE_TOKEN_REQUIRED = 'auth.service_token_required';
9
+ function own(v, key) {
10
+ if (v === null || typeof v !== 'object')
11
+ return undefined;
12
+ try {
13
+ return readOwnDataValue(v, key);
14
+ }
15
+ catch {
16
+ return undefined;
17
+ }
18
+ }
19
+ function slot(e, key) {
20
+ if (e === null || (typeof e !== 'object' && typeof e !== 'function'))
21
+ return undefined;
22
+ try {
23
+ return e[key];
24
+ }
25
+ catch {
26
+ return undefined;
27
+ }
28
+ }
29
+ function nonEmpty(v) {
30
+ return typeof v === 'string' && v !== '' ? v : undefined;
31
+ }
32
+ function nonNegInt(v) {
33
+ return typeof v === 'number' && Number.isInteger(v) && v >= 0 ? v : undefined;
34
+ }
35
+ function isArraySafely(v) {
36
+ try {
37
+ return Array.isArray(v);
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ }
43
+ function refusedOf(status, code, e) {
44
+ const message = nonEmpty(slot(e, 'message'));
45
+ return { kind: 'refused', status, ...(code !== undefined ? { errorCode: code } : {}), ...(message !== undefined ? { message } : {}) };
46
+ }
47
+ function transportOf(v) {
48
+ return { kind: 'transport', ...(v.name !== undefined ? { detail: v.name } : {}) };
49
+ }
50
+ function commonOf(status, code) {
51
+ if (status === 501 && code === LANE_ABSENT)
52
+ return { kind: 'lane-absent' };
53
+ if (status === 501 && code === RUN_STORE_ABSENT)
54
+ return { kind: 'lane-absent', runStoreOnly: true };
55
+ if (status === 404 && code === NOT_FOUND)
56
+ return { kind: 'not-found' };
57
+ return null;
58
+ }
59
+ function readFailureOf(e) {
60
+ const v = atMostOnceVerdictOf(e);
61
+ const common = commonOf(v.status, v.code);
62
+ if (common !== null)
63
+ return common;
64
+ return v.status !== undefined ? refusedOf(v.status, v.code, e) : transportOf(v);
65
+ }
66
+ function verbOf(slice, name) {
67
+ const v = slot(slice, name);
68
+ return typeof v === 'function' ? v : undefined;
69
+ }
70
+ function signalOpts(opts) {
71
+ const s = slot(opts, 'signal');
72
+ return s !== undefined && s !== null ? { signal: s } : {};
73
+ }
74
+ function rowOf(raw) {
75
+ const deviceId = nonEmpty(own(raw, 'deviceId'));
76
+ if (deviceId === undefined)
77
+ return null;
78
+ const st = own(raw, 'status');
79
+ const name = nonEmpty(own(raw, 'name'));
80
+ const lastSeenAt = nonEmpty(own(raw, 'lastSeenAt'));
81
+ return {
82
+ deviceId,
83
+ ...(name !== undefined ? { name } : {}),
84
+ status: st === 'online' ? 'online' : st === 'offline' ? 'offline' : 'unknown',
85
+ ...(lastSeenAt !== undefined ? { lastSeenAt } : {}),
86
+ };
87
+ }
88
+ export async function listDevices(devices, opts) {
89
+ const verb = verbOf(devices, 'list');
90
+ if (verb === undefined)
91
+ return { kind: 'unarmed' };
92
+ let body;
93
+ try {
94
+ body = await verb.call(devices, signalOpts(opts));
95
+ }
96
+ catch (e) {
97
+ const f = readFailureOf(e);
98
+ return f.kind === 'not-found' ? refusedOf(404, NOT_FOUND, e) : f;
99
+ }
100
+ const raw = own(body, 'devices');
101
+ if (!isArraySafely(raw)) {
102
+ return { kind: 'unreadable', why: 'the body carries no device list (the `devices` key is absent or not an array) — refusing to render that as an empty roster' };
103
+ }
104
+ const rows = [];
105
+ let dropped = 0;
106
+ const len = nonNegInt(own(raw, 'length')) ?? 0;
107
+ for (let i = 0; i < len; i++) {
108
+ const r = rowOf(own(raw, String(i)));
109
+ if (r === null)
110
+ dropped++;
111
+ else
112
+ rows.push(r);
113
+ }
114
+ return { kind: 'ok', devices: rows, dropped };
115
+ }
116
+ function bindingOf(raw) {
117
+ const deviceId = nonEmpty(own(raw, 'deviceId'));
118
+ const rev = nonNegInt(own(raw, 'rev'));
119
+ if (deviceId === undefined || rev === undefined)
120
+ return null;
121
+ const boundAt = nonEmpty(own(raw, 'boundAt'));
122
+ return { deviceId, rev, ...(boundAt !== undefined ? { boundAt } : {}) };
123
+ }
124
+ export async function readSessionBinding(devices, rootSessionId, opts) {
125
+ const verb = verbOf(devices, 'sessionBinding');
126
+ if (verb === undefined)
127
+ return { kind: 'unarmed' };
128
+ let body;
129
+ try {
130
+ body = await verb.call(devices, rootSessionId, signalOpts(opts));
131
+ }
132
+ catch (e) {
133
+ return readFailureOf(e);
134
+ }
135
+ const rid = own(body, 'rootSessionId');
136
+ if (typeof rid !== 'string' || rid !== rootSessionId) {
137
+ return { kind: 'unreadable', why: "the binding it returned does not echo the session id that was asked for — refusing to use another session's binding as this one's prior state" };
138
+ }
139
+ const bound = bindingOf(own(body, 'boundDevice'));
140
+ if (bound === null) {
141
+ return { kind: 'unreadable', why: 'the binding it returned has no usable prior state (deviceId + rev) — refusing to treat it as a binding' };
142
+ }
143
+ return { kind: 'ok', rootSessionId: rid, boundDevice: bound };
144
+ }
145
+ function rebindFailureOf(e) {
146
+ const v = atMostOnceVerdictOf(e);
147
+ const { status, code } = v;
148
+ const common = commonOf(status, code);
149
+ if (common !== null)
150
+ return common;
151
+ if (status === 409 && code === ACTIVE_RUN) {
152
+ const activeTaskId = nonEmpty(own(e, 'activeTaskId'));
153
+ return { kind: 'active-run', ...(activeTaskId !== undefined ? { activeTaskId } : {}) };
154
+ }
155
+ if (status === 409 && code === REV_CONFLICT) {
156
+ const currentRev = nonNegInt(own(e, 'currentRev'));
157
+ return { kind: 'rev-conflict', ...(currentRev !== undefined ? { currentRev } : {}) };
158
+ }
159
+ if (status === 503 && code === SERVICE_TOKEN_REQUIRED)
160
+ return refusedOf(status, code, e);
161
+ if (v.delivery === 'rejected' && status !== undefined)
162
+ return refusedOf(status, code, e);
163
+ if (status !== undefined)
164
+ return { kind: 'unconfirmed', why: 'server-error', detail: String(status), mayStillBeRunning: true };
165
+ return { kind: 'unconfirmed', why: 'transport', ...(v.name !== undefined ? { detail: v.name } : {}), mayStillBeRunning: true };
166
+ }
167
+ export async function rebindSession(devices, req, opts) {
168
+ const rootSessionId = slot(req, 'rootSessionId');
169
+ const toDeviceId = slot(req, 'toDeviceId');
170
+ const expectedRev = slot(req, 'expectedRev');
171
+ const fromDeviceId = slot(req, 'fromDeviceId');
172
+ if (nonNegInt(expectedRev) === undefined) {
173
+ return {
174
+ kind: 'refused',
175
+ status: 0,
176
+ errorCode: 'request.field_invalid',
177
+ message: 'expectedRev must be a non-negative integer read from the current binding — refusing to send a made-up prior state',
178
+ };
179
+ }
180
+ const verb = verbOf(devices, 'rebind');
181
+ if (verb === undefined)
182
+ return { kind: 'unarmed' };
183
+ let body;
184
+ try {
185
+ body = await verb.call(devices, rootSessionId, { toDeviceId, expectedRev }, signalOpts(opts));
186
+ }
187
+ catch (e) {
188
+ return rebindFailureOf(e);
189
+ }
190
+ const deviceId = nonEmpty(own(body, 'deviceId'));
191
+ const rev = nonNegInt(own(body, 'rev'));
192
+ const echoed = own(body, 'rootSessionId');
193
+ const prior = expectedRev;
194
+ const sound = deviceId !== undefined &&
195
+ rev !== undefined &&
196
+ typeof echoed === 'string' &&
197
+ echoed === rootSessionId &&
198
+ deviceId === toDeviceId &&
199
+ (rev === prior + 1 || (rev === prior && fromDeviceId === toDeviceId));
200
+ if (!sound)
201
+ return { kind: 'unconfirmed', why: 'accepted-unreadable', mayStillBeRunning: false };
202
+ const carry = own(body, 'workspaceCarryover') === 'none' ? 'none' : undefined;
203
+ return { kind: 'ok', deviceId, rev, ...(carry !== undefined ? { workspaceCarryover: carry } : {}) };
204
+ }
205
+ export function reconcileRebindOutcome(before, toDeviceId, after, opts) {
206
+ if (after === null)
207
+ return 'unknown';
208
+ const b = bindingOf(before);
209
+ const a = bindingOf(after);
210
+ if (b === null || a === null || typeof toDeviceId !== 'string')
211
+ return 'unknown';
212
+ const onTarget = a.deviceId === toDeviceId;
213
+ const revStepped = a.rev === b.rev + 1;
214
+ const revStatic = a.rev === b.rev;
215
+ const wasMoveRequest = b.deviceId !== toDeviceId;
216
+ if (onTarget && revStepped && wasMoveRequest)
217
+ return 'landed';
218
+ if (slot(opts, 'serverMayStillBeRunning') !== false)
219
+ return 'unknown';
220
+ if (onTarget && revStatic && !wasMoveRequest)
221
+ return 'already-there';
222
+ if (!onTarget && a.deviceId === b.deviceId && revStatic)
223
+ return 'unchanged';
224
+ return 'unknown';
225
+ }
226
+ export function rebindProvesRequestNotApplied(outcome) {
227
+ const kind = slot(outcome, 'kind');
228
+ switch (kind) {
229
+ case 'active-run':
230
+ case 'rev-conflict':
231
+ case 'not-found':
232
+ case 'lane-absent':
233
+ case 'unarmed':
234
+ return true;
235
+ case 'refused': {
236
+ const status = slot(outcome, 'status');
237
+ return typeof status === 'number' && (status < 500 || slot(outcome, 'errorCode') === SERVICE_TOKEN_REQUIRED);
238
+ }
239
+ default:
240
+ return false;
241
+ }
242
+ }
@@ -38,4 +38,5 @@ export declare function credentialWashPasses(text: string, opts?: DisplayUntrust
38
38
  capped: boolean;
39
39
  };
40
40
  export declare function displayUntrusted(text: string, opts?: DisplayUntrustedOptions): string;
41
+ export declare function quoteUntrustedForSentence(text: string, max: number): string | undefined;
41
42
  export declare function displayUntrustedMarks(text: string, opts?: DisplayUntrustedOptions): DisplayUntrustedMarked;