@kortix/sdk 0.12.8 → 0.13.1

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 (274) hide show
  1. package/README.md +3 -6
  2. package/dist/browser/session-sync/session-sync-registry.d.ts +7 -2
  3. package/dist/browser/session-sync/session-sync-registry.d.ts.map +1 -1
  4. package/dist/browser/session-sync/session-sync-registry.js +33 -44
  5. package/dist/browser/session-sync/session-sync-registry.js.map +1 -1
  6. package/dist/browser/session-sync/session-transcript-cache.d.ts +9 -2
  7. package/dist/browser/session-sync/session-transcript-cache.d.ts.map +1 -1
  8. package/dist/browser/session-sync/session-transcript-cache.js +15 -5
  9. package/dist/browser/session-sync/session-transcript-cache.js.map +1 -1
  10. package/dist/browser/stores/opencode-compaction-store.d.ts +9 -3
  11. package/dist/browser/stores/opencode-compaction-store.d.ts.map +1 -1
  12. package/dist/browser/stores/opencode-compaction-store.js +5 -12
  13. package/dist/browser/stores/opencode-compaction-store.js.map +1 -1
  14. package/dist/browser/stores/sandbox-connection-store.d.ts +28 -17
  15. package/dist/browser/stores/sandbox-connection-store.d.ts.map +1 -1
  16. package/dist/browser/stores/sandbox-connection-store.js +32 -84
  17. package/dist/browser/stores/sandbox-connection-store.js.map +1 -1
  18. package/dist/browser/stores/session-working-store.d.ts +73 -0
  19. package/dist/browser/stores/session-working-store.d.ts.map +1 -0
  20. package/dist/browser/stores/session-working-store.js +86 -0
  21. package/dist/browser/stores/session-working-store.js.map +1 -0
  22. package/dist/browser/stores/sync-store/types.d.ts +14 -4
  23. package/dist/browser/stores/sync-store/types.d.ts.map +1 -1
  24. package/dist/browser/stores/sync-store.d.ts +179 -4
  25. package/dist/browser/stores/sync-store.d.ts.map +1 -1
  26. package/dist/browser/stores/sync-store.js +777 -65
  27. package/dist/browser/stores/sync-store.js.map +1 -1
  28. package/dist/core/client/kortix.d.ts +95 -0
  29. package/dist/core/client/kortix.d.ts.map +1 -1
  30. package/dist/core/client/kortix.js +78 -0
  31. package/dist/core/client/kortix.js.map +1 -1
  32. package/dist/core/files/client.d.ts +50 -2
  33. package/dist/core/files/client.d.ts.map +1 -1
  34. package/dist/core/files/client.js +253 -44
  35. package/dist/core/files/client.js.map +1 -1
  36. package/dist/core/files/types.d.ts +11 -0
  37. package/dist/core/files/types.d.ts.map +1 -1
  38. package/dist/core/http/abort-error.d.ts +89 -0
  39. package/dist/core/http/abort-error.d.ts.map +1 -0
  40. package/dist/core/http/abort-error.js +190 -0
  41. package/dist/core/http/abort-error.js.map +1 -0
  42. package/dist/core/http/api-client.d.ts.map +1 -1
  43. package/dist/core/http/api-client.js +18 -4
  44. package/dist/core/http/api-client.js.map +1 -1
  45. package/dist/core/http/opencode-errors.d.ts +7 -0
  46. package/dist/core/http/opencode-errors.d.ts.map +1 -1
  47. package/dist/core/http/opencode-errors.js +45 -13
  48. package/dist/core/http/opencode-errors.js.map +1 -1
  49. package/dist/core/rest/platform-client/github-app.d.ts +13 -0
  50. package/dist/core/rest/platform-client/github-app.d.ts.map +1 -1
  51. package/dist/core/rest/platform-client/github-app.js +2 -0
  52. package/dist/core/rest/platform-client/github-app.js.map +1 -1
  53. package/dist/core/rest/platform-client/members.d.ts +10 -64
  54. package/dist/core/rest/platform-client/members.d.ts.map +1 -1
  55. package/dist/core/rest/platform-client/members.js +10 -28
  56. package/dist/core/rest/platform-client/members.js.map +1 -1
  57. package/dist/core/rest/projects-client/accounts.d.ts +30 -5
  58. package/dist/core/rest/projects-client/accounts.d.ts.map +1 -1
  59. package/dist/core/rest/projects-client/accounts.js +1 -1
  60. package/dist/core/rest/projects-client/accounts.js.map +1 -1
  61. package/dist/core/rest/projects-client/apps.d.ts +13 -0
  62. package/dist/core/rest/projects-client/apps.d.ts.map +1 -1
  63. package/dist/core/rest/projects-client/apps.js.map +1 -1
  64. package/dist/core/rest/projects-client/assignments.d.ts +114 -0
  65. package/dist/core/rest/projects-client/assignments.d.ts.map +1 -0
  66. package/dist/core/rest/projects-client/assignments.js +91 -0
  67. package/dist/core/rest/projects-client/assignments.js.map +1 -0
  68. package/dist/core/rest/projects-client/billing.d.ts +10 -1
  69. package/dist/core/rest/projects-client/billing.d.ts.map +1 -1
  70. package/dist/core/rest/projects-client/billing.js +11 -2
  71. package/dist/core/rest/projects-client/billing.js.map +1 -1
  72. package/dist/core/rest/projects-client/connectors.d.ts +69 -1
  73. package/dist/core/rest/projects-client/connectors.d.ts.map +1 -1
  74. package/dist/core/rest/projects-client/connectors.js +17 -0
  75. package/dist/core/rest/projects-client/connectors.js.map +1 -1
  76. package/dist/core/rest/projects-client/files.js +2 -2
  77. package/dist/core/rest/projects-client/files.js.map +1 -1
  78. package/dist/core/rest/projects-client/gateway.d.ts +51 -0
  79. package/dist/core/rest/projects-client/gateway.d.ts.map +1 -1
  80. package/dist/core/rest/projects-client/gateway.js.map +1 -1
  81. package/dist/core/rest/projects-client/iam.d.ts +51 -3
  82. package/dist/core/rest/projects-client/iam.d.ts.map +1 -1
  83. package/dist/core/rest/projects-client/iam.js +18 -1
  84. package/dist/core/rest/projects-client/iam.js.map +1 -1
  85. package/dist/core/rest/projects-client/index.d.ts +1 -0
  86. package/dist/core/rest/projects-client/index.d.ts.map +1 -1
  87. package/dist/core/rest/projects-client/index.js +1 -0
  88. package/dist/core/rest/projects-client/index.js.map +1 -1
  89. package/dist/core/rest/projects-client/projects.d.ts +1 -1
  90. package/dist/core/rest/projects-client/projects.d.ts.map +1 -1
  91. package/dist/core/rest/projects-client/projects.js +2 -0
  92. package/dist/core/rest/projects-client/projects.js.map +1 -1
  93. package/dist/core/rest/projects-client/secrets.d.ts +19 -1
  94. package/dist/core/rest/projects-client/secrets.d.ts.map +1 -1
  95. package/dist/core/rest/projects-client/secrets.js +1 -1
  96. package/dist/core/rest/projects-client/secrets.js.map +1 -1
  97. package/dist/core/rest/projects-client/session-costs.d.ts +33 -0
  98. package/dist/core/rest/projects-client/session-costs.d.ts.map +1 -1
  99. package/dist/core/rest/projects-client/session-costs.js.map +1 -1
  100. package/dist/core/rest/projects-client/sessions.d.ts +261 -2
  101. package/dist/core/rest/projects-client/sessions.d.ts.map +1 -1
  102. package/dist/core/rest/projects-client/sessions.js +106 -4
  103. package/dist/core/rest/projects-client/sessions.js.map +1 -1
  104. package/dist/core/rest/projects-client/shared.d.ts +10 -1
  105. package/dist/core/rest/projects-client/shared.d.ts.map +1 -1
  106. package/dist/core/rest/projects-client/shared.js.map +1 -1
  107. package/dist/core/rest/projects-client/tokens.d.ts +13 -1
  108. package/dist/core/rest/projects-client/tokens.d.ts.map +1 -1
  109. package/dist/core/rest/projects-client/tokens.js +7 -2
  110. package/dist/core/rest/projects-client/tokens.js.map +1 -1
  111. package/dist/core/rest/projects-client/triggers.d.ts +69 -2
  112. package/dist/core/rest/projects-client/triggers.d.ts.map +1 -1
  113. package/dist/core/rest/projects-client/triggers.js +1 -1
  114. package/dist/core/rest/projects-client/triggers.js.map +1 -1
  115. package/dist/core/session/compaction.d.ts +98 -0
  116. package/dist/core/session/compaction.d.ts.map +1 -0
  117. package/dist/core/session/compaction.js +108 -0
  118. package/dist/core/session/compaction.js.map +1 -0
  119. package/dist/core/session/health.d.ts +22 -0
  120. package/dist/core/session/health.d.ts.map +1 -1
  121. package/dist/core/session/health.js +31 -5
  122. package/dist/core/session/health.js.map +1 -1
  123. package/dist/core/session/index.d.ts +2 -0
  124. package/dist/core/session/index.d.ts.map +1 -1
  125. package/dist/core/session/index.js +2 -0
  126. package/dist/core/session/index.js.map +1 -1
  127. package/dist/core/session/message-queue.d.ts +79 -15
  128. package/dist/core/session/message-queue.d.ts.map +1 -1
  129. package/dist/core/session/message-queue.js +73 -27
  130. package/dist/core/session/message-queue.js.map +1 -1
  131. package/dist/core/session/rewind.d.ts +76 -10
  132. package/dist/core/session/rewind.d.ts.map +1 -1
  133. package/dist/core/session/rewind.js +68 -11
  134. package/dist/core/session/rewind.js.map +1 -1
  135. package/dist/core/session/working.d.ts +241 -0
  136. package/dist/core/session/working.d.ts.map +1 -0
  137. package/dist/core/session/working.js +261 -0
  138. package/dist/core/session/working.js.map +1 -0
  139. package/dist/core/session-sync/session-sync-controller.d.ts +35 -20
  140. package/dist/core/session-sync/session-sync-controller.d.ts.map +1 -1
  141. package/dist/core/session-sync/session-sync-controller.js +48 -115
  142. package/dist/core/session-sync/session-sync-controller.js.map +1 -1
  143. package/dist/core/stream/event-stream.d.ts +22 -0
  144. package/dist/core/stream/event-stream.d.ts.map +1 -1
  145. package/dist/core/stream/event-stream.js +132 -36
  146. package/dist/core/stream/event-stream.js.map +1 -1
  147. package/dist/core/turns/grouping.d.ts +18 -2
  148. package/dist/core/turns/grouping.d.ts.map +1 -1
  149. package/dist/core/turns/grouping.js +45 -2
  150. package/dist/core/turns/grouping.js.map +1 -1
  151. package/dist/core/turns/index.d.ts +1 -0
  152. package/dist/core/turns/index.d.ts.map +1 -1
  153. package/dist/core/turns/index.js +1 -0
  154. package/dist/core/turns/index.js.map +1 -1
  155. package/dist/core/turns/open-turn.d.ts +81 -0
  156. package/dist/core/turns/open-turn.d.ts.map +1 -0
  157. package/dist/core/turns/open-turn.js +77 -0
  158. package/dist/core/turns/open-turn.js.map +1 -0
  159. package/dist/core/turns/state.js +26 -26
  160. package/dist/core/turns/state.js.map +1 -1
  161. package/dist/core/turns/types.d.ts +5 -0
  162. package/dist/core/turns/types.d.ts.map +1 -1
  163. package/dist/index.d.ts +2 -1
  164. package/dist/index.d.ts.map +1 -1
  165. package/dist/index.js +2 -1
  166. package/dist/index.js.map +1 -1
  167. package/dist/kortix.esm.min.js +25 -25
  168. package/dist/kortix.global.js +25 -25
  169. package/dist/node/server.d.ts.map +1 -1
  170. package/dist/node/server.js +14 -2
  171. package/dist/node/server.js.map +1 -1
  172. package/dist/react/index.d.ts +2 -1
  173. package/dist/react/index.d.ts.map +1 -1
  174. package/dist/react/index.js +7 -1
  175. package/dist/react/index.js.map +1 -1
  176. package/dist/react/initial-session-pin.d.ts +17 -0
  177. package/dist/react/initial-session-pin.d.ts.map +1 -1
  178. package/dist/react/initial-session-pin.js +58 -0
  179. package/dist/react/initial-session-pin.js.map +1 -1
  180. package/dist/react/opencode.d.ts +6 -2
  181. package/dist/react/opencode.d.ts.map +1 -1
  182. package/dist/react/opencode.js +5 -1
  183. package/dist/react/opencode.js.map +1 -1
  184. package/dist/react/prefetch-session-start.d.ts +10 -4
  185. package/dist/react/prefetch-session-start.d.ts.map +1 -1
  186. package/dist/react/prefetch-session-start.js +10 -4
  187. package/dist/react/prefetch-session-start.js.map +1 -1
  188. package/dist/react/query-contracts.d.ts +2 -0
  189. package/dist/react/query-contracts.d.ts.map +1 -1
  190. package/dist/react/query-contracts.js +2 -0
  191. package/dist/react/query-contracts.js.map +1 -1
  192. package/dist/react/query-keys.d.ts +13 -2
  193. package/dist/react/query-keys.d.ts.map +1 -1
  194. package/dist/react/query-keys.js +13 -2
  195. package/dist/react/query-keys.js.map +1 -1
  196. package/dist/react/session-start-stash.d.ts +25 -0
  197. package/dist/react/session-start-stash.d.ts.map +1 -1
  198. package/dist/react/session-start-stash.js +34 -3
  199. package/dist/react/session-start-stash.js.map +1 -1
  200. package/dist/react/session-title-sync.d.ts +5 -1
  201. package/dist/react/session-title-sync.d.ts.map +1 -1
  202. package/dist/react/session-title-sync.js +16 -4
  203. package/dist/react/session-title-sync.js.map +1 -1
  204. package/dist/react/use-can.d.ts +105 -0
  205. package/dist/react/use-can.d.ts.map +1 -0
  206. package/dist/react/use-can.js +190 -0
  207. package/dist/react/use-can.js.map +1 -0
  208. package/dist/react/use-canonical-opencode-session.d.ts +6 -1
  209. package/dist/react/use-canonical-opencode-session.d.ts.map +1 -1
  210. package/dist/react/use-canonical-opencode-session.js +46 -3
  211. package/dist/react/use-canonical-opencode-session.js.map +1 -1
  212. package/dist/react/use-opencode-events/handle-event.d.ts +10 -0
  213. package/dist/react/use-opencode-events/handle-event.d.ts.map +1 -1
  214. package/dist/react/use-opencode-events/handle-event.js +76 -7
  215. package/dist/react/use-opencode-events/handle-event.js.map +1 -1
  216. package/dist/react/use-opencode-events/helpers.d.ts +21 -8
  217. package/dist/react/use-opencode-events/helpers.d.ts.map +1 -1
  218. package/dist/react/use-opencode-events/helpers.js +25 -26
  219. package/dist/react/use-opencode-events/helpers.js.map +1 -1
  220. package/dist/react/use-opencode-events/index.d.ts.map +1 -1
  221. package/dist/react/use-opencode-events/index.js +43 -26
  222. package/dist/react/use-opencode-events/index.js.map +1 -1
  223. package/dist/react/use-opencode-events/use-event-stream-refs.d.ts.map +1 -1
  224. package/dist/react/use-opencode-events/use-event-stream-refs.js +66 -3
  225. package/dist/react/use-opencode-events/use-event-stream-refs.js.map +1 -1
  226. package/dist/react/use-opencode-local.d.ts +17 -0
  227. package/dist/react/use-opencode-local.d.ts.map +1 -1
  228. package/dist/react/use-opencode-local.js +41 -7
  229. package/dist/react/use-opencode-local.js.map +1 -1
  230. package/dist/react/use-opencode-sessions/messages.d.ts +101 -1
  231. package/dist/react/use-opencode-sessions/messages.d.ts.map +1 -1
  232. package/dist/react/use-opencode-sessions/messages.js +481 -63
  233. package/dist/react/use-opencode-sessions/messages.js.map +1 -1
  234. package/dist/react/use-project-apps.d.ts +24 -1
  235. package/dist/react/use-project-apps.d.ts.map +1 -1
  236. package/dist/react/use-project-apps.js +5 -3
  237. package/dist/react/use-project-apps.js.map +1 -1
  238. package/dist/react/use-runtime-boot-stalled.d.ts +32 -0
  239. package/dist/react/use-runtime-boot-stalled.d.ts.map +1 -0
  240. package/dist/react/use-runtime-boot-stalled.js +48 -0
  241. package/dist/react/use-runtime-boot-stalled.js.map +1 -0
  242. package/dist/react/use-runtime-reconnect.d.ts +67 -1
  243. package/dist/react/use-runtime-reconnect.d.ts.map +1 -1
  244. package/dist/react/use-runtime-reconnect.js +116 -18
  245. package/dist/react/use-runtime-reconnect.js.map +1 -1
  246. package/dist/react/use-session-prompts.d.ts +113 -0
  247. package/dist/react/use-session-prompts.d.ts.map +1 -0
  248. package/dist/react/use-session-prompts.js +250 -0
  249. package/dist/react/use-session-prompts.js.map +1 -0
  250. package/dist/react/use-session-send.d.ts +169 -20
  251. package/dist/react/use-session-send.d.ts.map +1 -1
  252. package/dist/react/use-session-send.js +183 -30
  253. package/dist/react/use-session-send.js.map +1 -1
  254. package/dist/react/use-session-sync.d.ts +35 -2
  255. package/dist/react/use-session-sync.d.ts.map +1 -1
  256. package/dist/react/use-session-sync.js +49 -11
  257. package/dist/react/use-session-sync.js.map +1 -1
  258. package/dist/react/use-session-working.d.ts +57 -0
  259. package/dist/react/use-session-working.d.ts.map +1 -0
  260. package/dist/react/use-session-working.js +178 -0
  261. package/dist/react/use-session-working.js.map +1 -0
  262. package/dist/react/use-session.d.ts +131 -5
  263. package/dist/react/use-session.d.ts.map +1 -1
  264. package/dist/react/use-session.js +358 -69
  265. package/dist/react/use-session.js.map +1 -1
  266. package/package.json +2 -2
  267. package/dist/browser/stores/tab-store.d.ts +0 -91
  268. package/dist/browser/stores/tab-store.d.ts.map +0 -1
  269. package/dist/browser/stores/tab-store.js +0 -369
  270. package/dist/browser/stores/tab-store.js.map +0 -1
  271. package/dist/core/session/send-queue.d.ts +0 -70
  272. package/dist/core/session/send-queue.d.ts.map +0 -1
  273. package/dist/core/session/send-queue.js +0 -116
  274. package/dist/core/session/send-queue.js.map +0 -1
@@ -1,9 +1,20 @@
1
1
  /**
2
+ * @deprecated since 0.12.9 — Kortix owns prompt ordering server-side
3
+ * (`POST /v1/projects/:projectId/sessions/:sessionId/prompts`). This module is
4
+ * retained ONLY so `@kortix/sdk/message-queue`, published in 0.12.8, keeps
5
+ * resolving for external consumers. It is not used by any Kortix host and will
6
+ * be removed in the next major.
7
+ *
2
8
  * The rules a message queue obeys, as pure functions.
3
9
  *
4
10
  * A message typed while the agent is mid-run is held until the turn ends. That
5
- * much is easy. What is not easy — and what three previous implementations got
6
- * wrong — is *when* it is released and *how many times*.
11
+ * much is easy. What is not easy — and what four implementations got wrong — is
12
+ * *when* it is released and *how many times*. The answer this module could
13
+ * never reach is that a browser tab does not know: it reads one guess at the
14
+ * session's state, a second tab reads another, and a closed tab loses the queue
15
+ * outright. The durable inbox above decides admission from the same turn
16
+ * authority `GET .../turn` serves from, so there is one queue per session
17
+ * rather than one per tab.
7
18
  *
8
19
  * The failures this module exists to make impossible:
9
20
  *
@@ -19,16 +30,23 @@
19
30
  * - **A queued message sending under the wrong model.** `agent`, `model`, and
20
31
  * `variant` are captured at enqueue and carried verbatim.
21
32
  *
22
- * The claimed item stays at `pending[0]` while it is in flight rather than
23
- * being spliced out. That makes `inFlightId` a real lock (one field to check),
24
- * makes "reorder cannot cross the in-flight slot" an index clamp rather than a
25
- * special case, and means a crash between claim and dispatch leaves the message
26
- * visible in the queue instead of silently gone.
33
+ * Claimed items stay at the head of `pending` while they are in flight rather
34
+ * than being spliced out. That makes the in-flight ids a real lock (one field
35
+ * to check), makes "reorder cannot cross what is sending" an index clamp rather
36
+ * than a special case, and means a crash between claim and dispatch leaves the
37
+ * messages visible in the queue instead of silently gone.
27
38
  *
28
39
  * Framework-free, storage-free, and timer-free by construction. There is no
29
40
  * `Date.now()` and no `crypto` here: ids and timestamps are inputs, so every
30
41
  * transition is deterministic and testable without fakes. Persistence and the
31
42
  * decision of *when* the turn ended belong to the host.
43
+ *
44
+ * **The export list is frozen at what 0.12.8 published.** `claimBatch` and
45
+ * `inFlightIdsOf` were added after that release, drove the browser batch drain
46
+ * that no longer exists, and are absent from the published `.d.ts` — so they
47
+ * are gone rather than deprecated. Nothing new may be added here either: an
48
+ * addition would be a new promise made by a module that exists only to keep an
49
+ * old one.
32
50
  */
33
51
  /** What a host hands in when the user queues a message. */
34
52
  export interface QueuedMessageInput<TFile = unknown, TMention = unknown> {
@@ -49,6 +67,29 @@ export interface QueuedMessageInput<TFile = unknown, TMention = unknown> {
49
67
  modelID: string;
50
68
  } | null;
51
69
  variant?: string | null;
70
+ /**
71
+ * A `/` slash command, when this entry runs one instead of sending `text`.
72
+ *
73
+ * The queue held only prompts, so a host with a command to send had nowhere
74
+ * to put it and ran it immediately — straight past a busy agent, ahead of
75
+ * everything already waiting. Ordering is the queue's entire purpose, and a
76
+ * command is a turn like any other; the only difference is which call puts it
77
+ * on the wire, which is the host's business at dispatch time.
78
+ *
79
+ * `name`, not a resolved command object: entries are serialized to survive a
80
+ * reload, and the command list is re-read when the entry actually runs, so a
81
+ * queued command can never go stale against a list that changed underneath
82
+ * it. `text` still carries the arguments, so an entry stays renderable and
83
+ * editable with no special case.
84
+ */
85
+ command?: {
86
+ name: string;
87
+ /** Where the chip sat in `text`, for display. See the host's serializer. */
88
+ split?: {
89
+ before: string;
90
+ after: string;
91
+ };
92
+ };
52
93
  createdAt: number;
53
94
  }
54
95
  /** A queued message, once the queue owns it. */
@@ -60,12 +101,33 @@ export interface QueuedMessage<TFile = unknown, TMention = unknown> extends Queu
60
101
  }
61
102
  /** One session's queue. */
62
103
  export interface SessionQueue<TFile = unknown, TMention = unknown> {
63
- /** Waiting to send, oldest first. `pending[0]` is in flight when claimed. */
104
+ /** Waiting to send, oldest first. The leading run is in flight when claimed. */
64
105
  pending: QueuedMessage<TFile, TMention>[];
65
106
  /** Gave up. Never blocks `pending`; a host offers these a retry. */
66
107
  failed: QueuedMessage<TFile, TMention>[];
67
- /** The id of the item currently on the wire, or null. This is the lock. */
108
+ /**
109
+ * The head of what is on the wire, or null.
110
+ *
111
+ * Kept because it is published API and because most readers only ever want
112
+ * "is something sending, and which row is it". `inFlightIds[0]` and this
113
+ * field are the same value by construction — every transition writes both.
114
+ */
68
115
  inFlightId: string | null;
116
+ /**
117
+ * Every id on the wire right now, oldest first. Empty when idle.
118
+ *
119
+ * A batch claim puts more than one message on a single prompt, so the lock
120
+ * has to name all of them: a row the user can still edit, remove or reorder
121
+ * is a row that is not being sent, and `inFlightId` alone could only ever
122
+ * protect the first.
123
+ *
124
+ * Optional because it was added after this type shipped, and requiring it
125
+ * would stop a consumer's hand-built `SessionQueue` literal from compiling.
126
+ * Every transition in this module writes it, and `createSessionQueue()`
127
+ * returns it, so it is absent only on a state that predates it — which is
128
+ * why every read goes through `inFlight` below rather than `?? []`.
129
+ */
130
+ inFlightIds?: string[];
69
131
  }
70
132
  export declare function createSessionQueue<TFile = unknown, TMention = unknown>(): SessionQueue<TFile, TMention>;
71
133
  /**
@@ -87,7 +149,7 @@ export declare function claimNext<TFile, TMention>(state: SessionQueue<TFile, TM
87
149
  state: SessionQueue<TFile, TMention>;
88
150
  claimed?: QueuedMessage<TFile, TMention>;
89
151
  };
90
- /** The send landed. Drop the item and free the queue. */
152
+ /** The send landed. Drop everything it carried and free the queue. */
91
153
  export declare function completeInFlight<TFile, TMention>(state: SessionQueue<TFile, TMention>): SessionQueue<TFile, TMention>;
92
154
  /**
93
155
  * The send failed for good. Set it aside — do not put it back at the head.
@@ -99,16 +161,18 @@ export declare function completeInFlight<TFile, TMention>(state: SessionQueue<TF
99
161
  export declare function failInFlight<TFile, TMention>(state: SessionQueue<TFile, TMention>, error: string): SessionQueue<TFile, TMention>;
100
162
  /** Put a failed item back at the tail, with its error cleared. */
101
163
  export declare function retryFailed<TFile, TMention>(state: SessionQueue<TFile, TMention>, id: string): SessionQueue<TFile, TMention>;
102
- /** Drop a message. Refuses the in-flight item — it is already on the wire. */
164
+ /** Drop a message. Refuses anything in flight — it is already on the wire. */
103
165
  export declare function removeQueued<TFile, TMention>(state: SessionQueue<TFile, TMention>, id: string): SessionQueue<TFile, TMention>;
104
- /** Rewrite a queued message. Refuses the in-flight item. */
166
+ /** Rewrite a queued message. Refuses anything in flight. */
105
167
  export declare function editQueued<TFile, TMention>(state: SessionQueue<TFile, TMention>, id: string, text: string): SessionQueue<TFile, TMention>;
106
168
  /**
107
169
  * Move a pending message to `toIndex`.
108
170
  *
109
- * `toIndex` is clamped to the movable range. While something is in flight that
110
- * range starts at 1, so nothing can be reordered into or past the slot that is
111
- * already sending — and the in-flight item itself cannot move at all.
171
+ * `toIndex` is clamped to the movable range. That range starts after whatever
172
+ * is in flight, so nothing can be reordered into or past a message already on
173
+ * the wire — and an in-flight message cannot move at all. That is one slot for
174
+ * a `claimNext` lock, and several for a state rehydrated from a host that
175
+ * claimed a batch.
112
176
  */
113
177
  export declare function reorderQueued<TFile, TMention>(state: SessionQueue<TFile, TMention>, id: string, toIndex: number): SessionQueue<TFile, TMention>;
114
178
  //# sourceMappingURL=message-queue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"message-queue.d.ts","sourceRoot":"","sources":["../../../src/core/session/message-queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"message-queue.d.ts","sourceRoot":"","sources":["../../../src/core/session/message-queue.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,20 @@
1
1
  /**
2
+ * @deprecated since 0.12.9 — Kortix owns prompt ordering server-side
3
+ * (`POST /v1/projects/:projectId/sessions/:sessionId/prompts`). This module is
4
+ * retained ONLY so `@kortix/sdk/message-queue`, published in 0.12.8, keeps
5
+ * resolving for external consumers. It is not used by any Kortix host and will
6
+ * be removed in the next major.
7
+ *
2
8
  * The rules a message queue obeys, as pure functions.
3
9
  *
4
10
  * A message typed while the agent is mid-run is held until the turn ends. That
5
- * much is easy. What is not easy — and what three previous implementations got
6
- * wrong — is *when* it is released and *how many times*.
11
+ * much is easy. What is not easy — and what four implementations got wrong — is
12
+ * *when* it is released and *how many times*. The answer this module could
13
+ * never reach is that a browser tab does not know: it reads one guess at the
14
+ * session's state, a second tab reads another, and a closed tab loses the queue
15
+ * outright. The durable inbox above decides admission from the same turn
16
+ * authority `GET .../turn` serves from, so there is one queue per session
17
+ * rather than one per tab.
7
18
  *
8
19
  * The failures this module exists to make impossible:
9
20
  *
@@ -19,19 +30,42 @@
19
30
  * - **A queued message sending under the wrong model.** `agent`, `model`, and
20
31
  * `variant` are captured at enqueue and carried verbatim.
21
32
  *
22
- * The claimed item stays at `pending[0]` while it is in flight rather than
23
- * being spliced out. That makes `inFlightId` a real lock (one field to check),
24
- * makes "reorder cannot cross the in-flight slot" an index clamp rather than a
25
- * special case, and means a crash between claim and dispatch leaves the message
26
- * visible in the queue instead of silently gone.
33
+ * Claimed items stay at the head of `pending` while they are in flight rather
34
+ * than being spliced out. That makes the in-flight ids a real lock (one field
35
+ * to check), makes "reorder cannot cross what is sending" an index clamp rather
36
+ * than a special case, and means a crash between claim and dispatch leaves the
37
+ * messages visible in the queue instead of silently gone.
27
38
  *
28
39
  * Framework-free, storage-free, and timer-free by construction. There is no
29
40
  * `Date.now()` and no `crypto` here: ids and timestamps are inputs, so every
30
41
  * transition is deterministic and testable without fakes. Persistence and the
31
42
  * decision of *when* the turn ended belong to the host.
43
+ *
44
+ * **The export list is frozen at what 0.12.8 published.** `claimBatch` and
45
+ * `inFlightIdsOf` were added after that release, drove the browser batch drain
46
+ * that no longer exists, and are absent from the published `.d.ts` — so they
47
+ * are gone rather than deprecated. Nothing new may be added here either: an
48
+ * addition would be a new promise made by a module that exists only to keep an
49
+ * old one.
32
50
  */
33
51
  export function createSessionQueue() {
34
- return { pending: [], failed: [], inFlightId: null };
52
+ return { pending: [], failed: [], inFlightId: null, inFlightIds: [] };
53
+ }
54
+ /**
55
+ * Everything on the wire, oldest first. Empty when the queue is idle.
56
+ *
57
+ * Module-private since 0.12.9. It was exported as `inFlightIdsOf` only for the
58
+ * browser drain that read the batch lock, and that drain is gone; 0.12.8 never
59
+ * published the name, so nothing external can be holding it.
60
+ *
61
+ * Tolerates a state that predates `inFlightIds` — a queue rehydrated from a
62
+ * host that persisted the older shape has only `inFlightId`, and reading
63
+ * through here means no call site has to know that.
64
+ */
65
+ function inFlight(state) {
66
+ if (state.inFlightIds?.length)
67
+ return state.inFlightIds;
68
+ return state.inFlightId ? [state.inFlightId] : [];
35
69
  }
36
70
  /**
37
71
  * Add a message to the tail.
@@ -51,7 +85,7 @@ export function enqueue(state, input) {
51
85
  * in flight — so a caller that races itself sends once, not twice.
52
86
  */
53
87
  export function claimNext(state) {
54
- if (state.inFlightId !== null)
88
+ if (inFlight(state).length > 0)
55
89
  return { state };
56
90
  const head = state.pending[0];
57
91
  if (!head)
@@ -62,18 +96,21 @@ export function claimNext(state) {
62
96
  ...state,
63
97
  pending: [claimed, ...state.pending.slice(1)],
64
98
  inFlightId: claimed.id,
99
+ inFlightIds: [claimed.id],
65
100
  },
66
101
  claimed,
67
102
  };
68
103
  }
69
- /** The send landed. Drop the item and free the queue. */
104
+ /** The send landed. Drop everything it carried and free the queue. */
70
105
  export function completeInFlight(state) {
71
- if (state.inFlightId === null)
106
+ const sending = inFlight(state);
107
+ if (sending.length === 0)
72
108
  return state;
73
109
  return {
74
110
  ...state,
75
- pending: state.pending.filter((m) => m.id !== state.inFlightId),
111
+ pending: state.pending.filter((m) => !sending.includes(m.id)),
76
112
  inFlightId: null,
113
+ inFlightIds: [],
77
114
  };
78
115
  }
79
116
  /**
@@ -84,15 +121,21 @@ export function completeInFlight(state) {
84
121
  * item lands in `failed` with its reason, and `pending` keeps moving.
85
122
  */
86
123
  export function failInFlight(state, error) {
87
- if (state.inFlightId === null)
124
+ const sending = inFlight(state);
125
+ if (sending.length === 0)
88
126
  return state;
89
- const item = state.pending.find((m) => m.id === state.inFlightId);
90
- if (!item)
91
- return { ...state, inFlightId: null };
127
+ // A list, not a single id: `claimNext` only ever locks one, but a state
128
+ // rehydrated from a host that claimed several still carries them, and one
129
+ // send failing is all of their failure. They land as separate rows so the
130
+ // user can retry the message that matters instead of re-sending three.
131
+ const items = state.pending.filter((m) => sending.includes(m.id));
132
+ if (items.length === 0)
133
+ return { ...state, inFlightId: null, inFlightIds: [] };
92
134
  return {
93
- pending: state.pending.filter((m) => m.id !== state.inFlightId),
94
- failed: [...state.failed, { ...item, lastError: error }],
135
+ pending: state.pending.filter((m) => !sending.includes(m.id)),
136
+ failed: [...state.failed, ...items.map((item) => ({ ...item, lastError: error }))],
95
137
  inFlightId: null,
138
+ inFlightIds: [],
96
139
  };
97
140
  }
98
141
  /** Put a failed item back at the tail, with its error cleared. */
@@ -107,9 +150,9 @@ export function retryFailed(state, id) {
107
150
  failed: state.failed.filter((m) => m.id !== id),
108
151
  };
109
152
  }
110
- /** Drop a message. Refuses the in-flight item — it is already on the wire. */
153
+ /** Drop a message. Refuses anything in flight — it is already on the wire. */
111
154
  export function removeQueued(state, id) {
112
- if (id === state.inFlightId)
155
+ if (inFlight(state).includes(id))
113
156
  return state;
114
157
  if (state.pending.some((m) => m.id === id)) {
115
158
  return { ...state, pending: state.pending.filter((m) => m.id !== id) };
@@ -119,9 +162,9 @@ export function removeQueued(state, id) {
119
162
  }
120
163
  return state;
121
164
  }
122
- /** Rewrite a queued message. Refuses the in-flight item. */
165
+ /** Rewrite a queued message. Refuses anything in flight. */
123
166
  export function editQueued(state, id, text) {
124
- if (id === state.inFlightId)
167
+ if (inFlight(state).includes(id))
125
168
  return state;
126
169
  if (!state.pending.some((m) => m.id === id))
127
170
  return state;
@@ -133,17 +176,20 @@ export function editQueued(state, id, text) {
133
176
  /**
134
177
  * Move a pending message to `toIndex`.
135
178
  *
136
- * `toIndex` is clamped to the movable range. While something is in flight that
137
- * range starts at 1, so nothing can be reordered into or past the slot that is
138
- * already sending — and the in-flight item itself cannot move at all.
179
+ * `toIndex` is clamped to the movable range. That range starts after whatever
180
+ * is in flight, so nothing can be reordered into or past a message already on
181
+ * the wire — and an in-flight message cannot move at all. That is one slot for
182
+ * a `claimNext` lock, and several for a state rehydrated from a host that
183
+ * claimed a batch.
139
184
  */
140
185
  export function reorderQueued(state, id, toIndex) {
141
- if (id === state.inFlightId)
186
+ const sending = inFlight(state);
187
+ if (sending.includes(id))
142
188
  return state;
143
189
  const from = state.pending.findIndex((m) => m.id === id);
144
190
  if (from === -1)
145
191
  return state;
146
- const first = state.inFlightId === null ? 0 : 1;
192
+ const first = sending.length;
147
193
  const to = Math.min(Math.max(toIndex, first), state.pending.length - 1);
148
194
  if (to === from)
149
195
  return state;
@@ -1 +1 @@
1
- {"version":3,"file":"message-queue.js","sourceRoot":"","sources":["../../../src/core/session/message-queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"message-queue.js","sourceRoot":"","sources":["../../../src/core/session/message-queue.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,84 @@
1
- export declare function messagesBeforeRewind<T extends {
2
- info: {
3
- id: string;
4
- };
5
- }>(messages: T[], messageId: string | null): T[];
1
+ /**
2
+ * Client-side projection of a staged/committed session rewind.
3
+ *
4
+ * `session.revert` is a STAGED pointer server-side — OpenCode never deletes
5
+ * anything until the next prompt COMMITS it (and `unrevert` restores it while
6
+ * staged). Nothing here talks to the network; this module is the pure math
7
+ * the sync store and `useSession` share for two questions:
8
+ *
9
+ * 1. Which locally-known messages does a staged rewind hide?
10
+ * 2. When is a message id inside the range a committed rewind must delete?
11
+ *
12
+ * `watermark` exists to fix a real bug: hiding used to be "everything at-or-
13
+ * after the boundary id", recomputed on every render off the CURRENT message
14
+ * list. A message minted AFTER staging — the user's replacement prompt, its
15
+ * answer — sorts above the boundary by id exactly like every OTHER later
16
+ * message, so it fell inside "everything after the boundary" too and never
17
+ * rendered until an unrelated remount flooded the whole transcript back,
18
+ * interleaved. `watermark` freezes the upper edge of the hide window at the
19
+ * newest message id known AT STAGE TIME, so only messages that were already
20
+ * part of the abandoned trajectory are ever hidden — anything newer always
21
+ * renders.
22
+ */
6
23
  export interface SessionRewindState {
24
+ /** The message the rewind pointer sits at — hidden along with everything
25
+ * up to `watermark`. */
7
26
  messageId: string;
27
+ /**
28
+ * The newest message id known locally at the moment this rewind was staged
29
+ * (or first observed). The upper bound of the hide window — fixed once,
30
+ * never recomputed against a later, larger message list.
31
+ */
32
+ watermark: string;
33
+ /**
34
+ * False once the replacement prompt has been sent (or a
35
+ * `session.next.revert.committed` wire event says the server has). The
36
+ * hide window still applies while this is false — what stops being offered
37
+ * is Restore (`unrevert`), not the hiding. A committed rewind's window is
38
+ * deleted outright once the store observes it, not merely hidden — see
39
+ * `applyCommittedRevert` on the sync store.
40
+ */
8
41
  staged: boolean;
9
42
  }
10
- /** Mark the rewind as committed while its removed path remains hidden locally. */
11
- export declare function commitSessionRewind(rewind: SessionRewindState | null): SessionRewindState | null;
12
- /** Drop the local boundary after runtime synchronization confirms cleanup. */
13
- export declare function reconcileCommittedSessionRewind<T extends {
43
+ /** Whether `id` falls inside the [messageId, watermark] hide range both
44
+ * bounds inclusive: the boundary message itself is part of what an edit
45
+ * replaces, and the watermark is the last message known at stage time. */
46
+ export declare function isWithinRewindWindow(id: string, rewind: SessionRewindState): boolean;
47
+ /**
48
+ * The newest (highest sort-order) message id in `messages`, or `null` for an
49
+ * empty list. Deliberately a max-scan, not "the last element" — most callers
50
+ * pass an ascending-sorted list, but an optimistic entry appended out of
51
+ * order must never win the max by position alone.
52
+ */
53
+ export declare function newestMessageId<T extends {
14
54
  info: {
15
55
  id: string;
16
56
  };
17
- }>(messages: T[], rewind: SessionRewindState | null): SessionRewindState | null;
57
+ }>(messages: T[]): string | null;
58
+ /**
59
+ * Build the state for a freshly staged (or freshly discovered) rewind.
60
+ * `watermark` is captured HERE, from the message list at this exact moment —
61
+ * never recomputed later. Falls back to `messageId` itself when nothing is
62
+ * known locally yet (a cross-tab or reload discovery with no synced messages
63
+ * for this session), which hides only the boundary message and nothing
64
+ * else — the narrowest correct answer with no other information available.
65
+ */
66
+ export declare function stageSessionRewind<T extends {
67
+ info: {
68
+ id: string;
69
+ };
70
+ }>(messages: T[], messageId: string): SessionRewindState;
71
+ /** Hide the target message and every message up to the staged watermark.
72
+ * Returns the SAME array reference when nothing is actually hidden — a
73
+ * fresh array on every call would defeat memoization in every consumer. */
74
+ export declare function messagesBeforeRewind<T extends {
75
+ info: {
76
+ id: string;
77
+ };
78
+ }>(messages: T[], rewind: SessionRewindState | null): T[];
79
+ /** Mark the rewind as committed while its removed path remains hidden
80
+ * locally (the actual deletion is a separate, explicit store action driven
81
+ * by the wire's `.committed` event — see `applyCommittedRevert`). Returns
82
+ * the SAME reference when already committed or when `rewind` is `null`. */
83
+ export declare function commitSessionRewind(rewind: SessionRewindState | null): SessionRewindState | null;
18
84
  //# sourceMappingURL=rewind.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rewind.d.ts","sourceRoot":"","sources":["../../../src/core/session/rewind.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EACrE,QAAQ,EAAE,CAAC,EAAE,EACb,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,CAAC,EAAE,CAIL;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,kFAAkF;AAClF,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAChC,kBAAkB,GAAG,IAAI,CAE3B;AAED,8EAA8E;AAC9E,wBAAgB,+BAA+B,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAChF,QAAQ,EAAE,CAAC,EAAE,EACb,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAChC,kBAAkB,GAAG,IAAI,CAG3B"}
1
+ {"version":3,"file":"rewind.d.ts","sourceRoot":"","sources":["../../../src/core/session/rewind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,kBAAkB;IACjC;6BACyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;2EAE2E;AAC3E,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAEpF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAChE,QAAQ,EAAE,CAAC,EAAE,GACZ,MAAM,GAAG,IAAI,CAMf;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EACnE,QAAQ,EAAE,CAAC,EAAE,EACb,SAAS,EAAE,MAAM,GAChB,kBAAkB,CAMpB;AAED;;4EAE4E;AAC5E,wBAAgB,oBAAoB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EACrE,QAAQ,EAAE,CAAC,EAAE,EACb,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAChC,CAAC,EAAE,CAIL;AAED;;;4EAG4E;AAC5E,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAChC,kBAAkB,GAAG,IAAI,CAE3B"}
@@ -1,17 +1,74 @@
1
- export function messagesBeforeRewind(messages, messageId) {
2
- if (!messageId)
1
+ /**
2
+ * Client-side projection of a staged/committed session rewind.
3
+ *
4
+ * `session.revert` is a STAGED pointer server-side — OpenCode never deletes
5
+ * anything until the next prompt COMMITS it (and `unrevert` restores it while
6
+ * staged). Nothing here talks to the network; this module is the pure math
7
+ * the sync store and `useSession` share for two questions:
8
+ *
9
+ * 1. Which locally-known messages does a staged rewind hide?
10
+ * 2. When is a message id inside the range a committed rewind must delete?
11
+ *
12
+ * `watermark` exists to fix a real bug: hiding used to be "everything at-or-
13
+ * after the boundary id", recomputed on every render off the CURRENT message
14
+ * list. A message minted AFTER staging — the user's replacement prompt, its
15
+ * answer — sorts above the boundary by id exactly like every OTHER later
16
+ * message, so it fell inside "everything after the boundary" too and never
17
+ * rendered until an unrelated remount flooded the whole transcript back,
18
+ * interleaved. `watermark` freezes the upper edge of the hide window at the
19
+ * newest message id known AT STAGE TIME, so only messages that were already
20
+ * part of the abandoned trajectory are ever hidden — anything newer always
21
+ * renders.
22
+ */
23
+ /** Whether `id` falls inside the [messageId, watermark] hide range — both
24
+ * bounds inclusive: the boundary message itself is part of what an edit
25
+ * replaces, and the watermark is the last message known at stage time. */
26
+ export function isWithinRewindWindow(id, rewind) {
27
+ return id >= rewind.messageId && id <= rewind.watermark;
28
+ }
29
+ /**
30
+ * The newest (highest sort-order) message id in `messages`, or `null` for an
31
+ * empty list. Deliberately a max-scan, not "the last element" — most callers
32
+ * pass an ascending-sorted list, but an optimistic entry appended out of
33
+ * order must never win the max by position alone.
34
+ */
35
+ export function newestMessageId(messages) {
36
+ let max = null;
37
+ for (const message of messages) {
38
+ if (max === null || message.info.id > max)
39
+ max = message.info.id;
40
+ }
41
+ return max;
42
+ }
43
+ /**
44
+ * Build the state for a freshly staged (or freshly discovered) rewind.
45
+ * `watermark` is captured HERE, from the message list at this exact moment —
46
+ * never recomputed later. Falls back to `messageId` itself when nothing is
47
+ * known locally yet (a cross-tab or reload discovery with no synced messages
48
+ * for this session), which hides only the boundary message and nothing
49
+ * else — the narrowest correct answer with no other information available.
50
+ */
51
+ export function stageSessionRewind(messages, messageId) {
52
+ return {
53
+ messageId,
54
+ watermark: newestMessageId(messages) ?? messageId,
55
+ staged: true,
56
+ };
57
+ }
58
+ /** Hide the target message and every message up to the staged watermark.
59
+ * Returns the SAME array reference when nothing is actually hidden — a
60
+ * fresh array on every call would defeat memoization in every consumer. */
61
+ export function messagesBeforeRewind(messages, rewind) {
62
+ if (!rewind)
3
63
  return messages;
4
- const boundary = messages.findIndex((message) => message.info.id === messageId);
5
- return boundary < 0 ? messages : messages.slice(0, boundary);
64
+ const kept = messages.filter((message) => !isWithinRewindWindow(message.info.id, rewind));
65
+ return kept.length === messages.length ? messages : kept;
6
66
  }
7
- /** Mark the rewind as committed while its removed path remains hidden locally. */
67
+ /** Mark the rewind as committed while its removed path remains hidden
68
+ * locally (the actual deletion is a separate, explicit store action driven
69
+ * by the wire's `.committed` event — see `applyCommittedRevert`). Returns
70
+ * the SAME reference when already committed or when `rewind` is `null`. */
8
71
  export function commitSessionRewind(rewind) {
9
72
  return rewind?.staged ? { ...rewind, staged: false } : rewind;
10
73
  }
11
- /** Drop the local boundary after runtime synchronization confirms cleanup. */
12
- export function reconcileCommittedSessionRewind(messages, rewind) {
13
- if (!rewind || rewind.staged)
14
- return rewind;
15
- return messages.some((message) => message.info.id === rewind.messageId) ? rewind : null;
16
- }
17
74
  //# sourceMappingURL=rewind.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rewind.js","sourceRoot":"","sources":["../../../src/core/session/rewind.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,oBAAoB,CAClC,QAAa,EACb,SAAwB;IAExB,IAAI,CAAC,SAAS;QAAE,OAAO,QAAQ,CAAC;IAChC,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;IAChF,OAAO,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC/D,CAAC;AAOD,kFAAkF;AAClF,MAAM,UAAU,mBAAmB,CACjC,MAAiC;IAEjC,OAAO,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AAChE,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,+BAA+B,CAC7C,QAAa,EACb,MAAiC;IAEjC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC;IAC5C,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1F,CAAC"}
1
+ {"version":3,"file":"rewind.js","sourceRoot":"","sources":["../../../src/core/session/rewind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAuBH;;2EAE2E;AAC3E,MAAM,UAAU,oBAAoB,CAAC,EAAU,EAAE,MAA0B;IACzE,OAAO,EAAE,IAAI,MAAM,CAAC,SAAS,IAAI,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC;AAC1D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAa;IAEb,IAAI,GAAG,GAAkB,IAAI,CAAC;IAC9B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG;YAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAa,EACb,SAAiB;IAEjB,OAAO;QACL,SAAS;QACT,SAAS,EAAE,eAAe,CAAC,QAAQ,CAAC,IAAI,SAAS;QACjD,MAAM,EAAE,IAAI;KACb,CAAC;AACJ,CAAC;AAED;;4EAE4E;AAC5E,MAAM,UAAU,oBAAoB,CAClC,QAAa,EACb,MAAiC;IAEjC,IAAI,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC;IAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1F,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3D,CAAC;AAED;;;4EAG4E;AAC5E,MAAM,UAAU,mBAAmB,CACjC,MAAiC;IAEjC,OAAO,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AAChE,CAAC"}