@agentshouse/mdruntime 0.1.0-cb2e390ee7b89 → 0.1.0-cb3bb3b233fa1

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 (407) hide show
  1. package/README.md +24 -19
  2. package/dist/acceptance.d.ts +3 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +299 -0
  5. package/dist/act-lanes.d.ts +30 -0
  6. package/dist/act-lanes.d.ts.map +1 -0
  7. package/dist/act-lanes.js +225 -0
  8. package/dist/actions.d.ts +26 -0
  9. package/dist/actions.d.ts.map +1 -0
  10. package/dist/actions.js +302 -0
  11. package/dist/adapter.d.ts +214 -123
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/attached-model.d.ts +6 -10
  14. package/dist/attached-model.d.ts.map +1 -1
  15. package/dist/attached-model.js +35 -41
  16. package/dist/authored.d.ts +88 -0
  17. package/dist/authored.d.ts.map +1 -0
  18. package/dist/authored.js +345 -0
  19. package/dist/binary.d.ts +0 -5
  20. package/dist/binary.d.ts.map +1 -1
  21. package/dist/binary.js +1 -1
  22. package/dist/bootstrap.d.ts +30 -11
  23. package/dist/bootstrap.d.ts.map +1 -1
  24. package/dist/bootstrap.js +309 -113
  25. package/dist/cell.d.ts +6 -0
  26. package/dist/cell.d.ts.map +1 -0
  27. package/dist/cell.js +9 -0
  28. package/dist/chain.d.ts +12 -0
  29. package/dist/chain.d.ts.map +1 -0
  30. package/dist/chain.js +64 -0
  31. package/dist/change-set.d.ts +13 -16
  32. package/dist/change-set.d.ts.map +1 -1
  33. package/dist/change-set.js +17 -89
  34. package/dist/change.d.ts +36 -1
  35. package/dist/change.d.ts.map +1 -1
  36. package/dist/change.js +17 -3
  37. package/dist/chat-types.d.ts +3 -0
  38. package/dist/chat-types.d.ts.map +1 -0
  39. package/dist/chat-types.js +11 -0
  40. package/dist/client.d.ts +39 -25
  41. package/dist/client.d.ts.map +1 -1
  42. package/dist/client.js +117 -23
  43. package/dist/collection.d.ts +32 -21
  44. package/dist/collection.d.ts.map +1 -1
  45. package/dist/collection.js +53 -288
  46. package/dist/column.d.ts +5 -0
  47. package/dist/column.d.ts.map +1 -0
  48. package/dist/column.js +9 -0
  49. package/dist/compile.d.ts +18 -0
  50. package/dist/compile.d.ts.map +1 -0
  51. package/dist/compile.js +723 -0
  52. package/dist/connection.d.ts +7 -134
  53. package/dist/connection.d.ts.map +1 -1
  54. package/dist/connection.js +109 -3606
  55. package/dist/context.d.ts +2 -0
  56. package/dist/context.d.ts.map +1 -0
  57. package/dist/{chat/context.js → context.js} +2 -5
  58. package/dist/conversation-live.d.ts +150 -0
  59. package/dist/conversation-live.d.ts.map +1 -0
  60. package/dist/conversation-live.js +259 -0
  61. package/dist/conversation-row.d.ts +40 -0
  62. package/dist/conversation-row.d.ts.map +1 -0
  63. package/dist/conversation-row.js +66 -0
  64. package/dist/conversation.d.ts +80 -50
  65. package/dist/conversation.d.ts.map +1 -1
  66. package/dist/conversation.js +1037 -793
  67. package/dist/declaration.d.ts +10 -0
  68. package/dist/declaration.d.ts.map +1 -0
  69. package/dist/declaration.js +24 -0
  70. package/dist/digest.d.ts +7 -0
  71. package/dist/digest.d.ts.map +1 -0
  72. package/dist/digest.js +113 -0
  73. package/dist/discovery.d.ts +10 -0
  74. package/dist/discovery.d.ts.map +1 -0
  75. package/dist/discovery.js +150 -0
  76. package/dist/durability.d.ts +20 -4
  77. package/dist/durability.d.ts.map +1 -1
  78. package/dist/durability.js +9 -0
  79. package/dist/entry.d.ts +5 -2
  80. package/dist/entry.d.ts.map +1 -1
  81. package/dist/entry.js +33 -28
  82. package/dist/expectation.d.ts +26 -13
  83. package/dist/expectation.d.ts.map +1 -1
  84. package/dist/expectation.js +72 -19
  85. package/dist/failure.d.ts +3 -0
  86. package/dist/failure.d.ts.map +1 -1
  87. package/dist/failure.js +6 -0
  88. package/dist/figures.d.ts +49 -0
  89. package/dist/figures.d.ts.map +1 -0
  90. package/dist/figures.js +199 -0
  91. package/dist/file.d.ts +2 -19
  92. package/dist/file.d.ts.map +1 -1
  93. package/dist/file.js +8 -122
  94. package/dist/holdings.d.ts +29 -0
  95. package/dist/holdings.d.ts.map +1 -0
  96. package/dist/holdings.js +95 -0
  97. package/dist/host.d.ts +21 -11
  98. package/dist/host.d.ts.map +1 -1
  99. package/dist/host.js +126 -53
  100. package/dist/identity.d.ts +0 -2
  101. package/dist/identity.d.ts.map +1 -1
  102. package/dist/identity.js +0 -6
  103. package/dist/index.d.ts +41 -16
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +19 -4
  106. package/dist/install.d.ts +60 -0
  107. package/dist/install.d.ts.map +1 -0
  108. package/dist/install.js +537 -0
  109. package/dist/lifecycle.d.ts +7 -0
  110. package/dist/lifecycle.d.ts.map +1 -0
  111. package/dist/lifecycle.js +282 -0
  112. package/dist/listing.d.ts +52 -0
  113. package/dist/listing.d.ts.map +1 -0
  114. package/dist/listing.js +152 -0
  115. package/dist/live.d.ts +25 -0
  116. package/dist/live.d.ts.map +1 -0
  117. package/dist/live.js +206 -0
  118. package/dist/loaded.d.ts +5 -0
  119. package/dist/loaded.d.ts.map +1 -0
  120. package/dist/loaded.js +40 -0
  121. package/dist/locks.d.ts +7 -0
  122. package/dist/locks.d.ts.map +1 -0
  123. package/dist/locks.js +32 -0
  124. package/dist/lost.d.ts +5 -0
  125. package/dist/lost.d.ts.map +1 -0
  126. package/dist/lost.js +49 -0
  127. package/dist/media.d.ts +13 -0
  128. package/dist/media.d.ts.map +1 -0
  129. package/dist/media.js +269 -0
  130. package/dist/memory.d.ts +20 -8
  131. package/dist/memory.d.ts.map +1 -1
  132. package/dist/memory.js +311 -121
  133. package/dist/messages.d.ts +58 -0
  134. package/dist/messages.d.ts.map +1 -0
  135. package/dist/messages.js +160 -0
  136. package/dist/model.d.ts +8 -11
  137. package/dist/model.d.ts.map +1 -1
  138. package/dist/model.js +6 -23
  139. package/dist/models.d.ts +10 -0
  140. package/dist/models.d.ts.map +1 -0
  141. package/dist/models.js +153 -0
  142. package/dist/name.d.ts +4 -0
  143. package/dist/name.d.ts.map +1 -0
  144. package/dist/name.js +122 -0
  145. package/dist/observation.d.ts +38 -10
  146. package/dist/observation.d.ts.map +1 -1
  147. package/dist/observation.js +232 -44
  148. package/dist/opened.d.ts +22 -0
  149. package/dist/opened.d.ts.map +1 -0
  150. package/dist/opened.js +107 -0
  151. package/dist/opening.d.ts +4 -0
  152. package/dist/opening.d.ts.map +1 -0
  153. package/dist/opening.js +53 -0
  154. package/dist/outcome.d.ts +57 -10
  155. package/dist/outcome.d.ts.map +1 -1
  156. package/dist/outcome.js +71 -2
  157. package/dist/overlay.d.ts +8 -6
  158. package/dist/overlay.d.ts.map +1 -1
  159. package/dist/overlay.js +121 -182
  160. package/dist/page-metadata.d.ts +8 -0
  161. package/dist/page-metadata.d.ts.map +1 -0
  162. package/dist/page-metadata.js +19 -0
  163. package/dist/parts.d.ts +4 -0
  164. package/dist/parts.d.ts.map +1 -0
  165. package/dist/parts.js +13 -0
  166. package/dist/paths.d.ts +2 -0
  167. package/dist/paths.d.ts.map +1 -1
  168. package/dist/paths.js +26 -0
  169. package/dist/preparation.d.ts +41 -0
  170. package/dist/preparation.d.ts.map +1 -0
  171. package/dist/preparation.js +314 -0
  172. package/dist/presence.d.ts +58 -0
  173. package/dist/presence.d.ts.map +1 -0
  174. package/dist/presence.js +231 -0
  175. package/dist/queries.d.ts +16 -0
  176. package/dist/queries.d.ts.map +1 -0
  177. package/dist/queries.js +308 -0
  178. package/dist/query.d.ts +21 -203
  179. package/dist/query.d.ts.map +1 -1
  180. package/dist/query.js +3 -491
  181. package/dist/{chat/questions.d.ts → questions.d.ts} +6 -7
  182. package/dist/questions.d.ts.map +1 -0
  183. package/dist/{chat/questions.js → questions.js} +12 -7
  184. package/dist/queue.d.ts +40 -0
  185. package/dist/queue.d.ts.map +1 -0
  186. package/dist/queue.js +480 -0
  187. package/dist/reach.d.ts +21 -11
  188. package/dist/reach.d.ts.map +1 -1
  189. package/dist/reach.js +358 -111
  190. package/dist/react.d.ts +19 -5
  191. package/dist/react.d.ts.map +1 -1
  192. package/dist/react.js +35 -15
  193. package/dist/{chat/read.d.ts → read.d.ts} +2 -0
  194. package/dist/read.d.ts.map +1 -0
  195. package/dist/{chat/read.js → read.js} +4 -0
  196. package/dist/readiness.d.ts +22 -20
  197. package/dist/readiness.d.ts.map +1 -1
  198. package/dist/readiness.js +5 -13
  199. package/dist/reads.d.ts +38 -10
  200. package/dist/reads.d.ts.map +1 -1
  201. package/dist/reads.js +163 -83
  202. package/dist/recovery.d.ts +5 -2
  203. package/dist/recovery.d.ts.map +1 -1
  204. package/dist/recovery.js +65 -8
  205. package/dist/refresh.d.ts +18 -15
  206. package/dist/refresh.d.ts.map +1 -1
  207. package/dist/refresh.js +145 -60
  208. package/dist/refusal.d.ts +5 -0
  209. package/dist/refusal.d.ts.map +1 -0
  210. package/dist/refusal.js +55 -0
  211. package/dist/replica.d.ts +49 -36
  212. package/dist/replica.d.ts.map +1 -1
  213. package/dist/replica.js +322 -198
  214. package/dist/retried.d.ts +30 -0
  215. package/dist/retried.d.ts.map +1 -0
  216. package/dist/retried.js +72 -0
  217. package/dist/room-draft.d.ts +55 -13
  218. package/dist/room-draft.d.ts.map +1 -1
  219. package/dist/room-draft.js +416 -122
  220. package/dist/room-drafts.d.ts +24 -0
  221. package/dist/room-drafts.d.ts.map +1 -0
  222. package/dist/room-drafts.js +220 -0
  223. package/dist/room-list.d.ts +10 -0
  224. package/dist/room-list.d.ts.map +1 -0
  225. package/dist/room-list.js +45 -0
  226. package/dist/rows.d.ts +32 -30
  227. package/dist/rows.d.ts.map +1 -1
  228. package/dist/rows.js +60 -120
  229. package/dist/runtime.d.ts +34 -0
  230. package/dist/runtime.d.ts.map +1 -0
  231. package/dist/runtime.js +1 -0
  232. package/dist/save.d.ts +43 -49
  233. package/dist/save.d.ts.map +1 -1
  234. package/dist/save.js +736 -304
  235. package/dist/saves.d.ts +34 -0
  236. package/dist/saves.d.ts.map +1 -0
  237. package/dist/saves.js +437 -0
  238. package/dist/search.d.ts +12 -95
  239. package/dist/search.d.ts.map +1 -1
  240. package/dist/search.js +10 -266
  241. package/dist/seed.d.ts +11 -2
  242. package/dist/seed.d.ts.map +1 -1
  243. package/dist/seed.js +71 -1
  244. package/dist/shared.d.ts +6 -7
  245. package/dist/shared.d.ts.map +1 -1
  246. package/dist/shared.js +75 -104
  247. package/dist/shown.d.ts +33 -0
  248. package/dist/shown.d.ts.map +1 -0
  249. package/dist/shown.js +309 -0
  250. package/dist/socket/admission.d.ts +7 -0
  251. package/dist/socket/admission.d.ts.map +1 -0
  252. package/dist/socket/admission.js +39 -0
  253. package/dist/socket/answers.d.ts +6 -0
  254. package/dist/socket/answers.d.ts.map +1 -0
  255. package/dist/socket/answers.js +20 -0
  256. package/dist/socket/lanes.d.ts +28 -0
  257. package/dist/socket/lanes.d.ts.map +1 -0
  258. package/dist/socket/lanes.js +103 -0
  259. package/dist/socket/reads.d.ts +10 -0
  260. package/dist/socket/reads.d.ts.map +1 -0
  261. package/dist/socket/reads.js +31 -0
  262. package/dist/socket/session.d.ts +38 -0
  263. package/dist/socket/session.d.ts.map +1 -0
  264. package/dist/socket/session.js +23 -0
  265. package/dist/socket.d.ts +67 -0
  266. package/dist/socket.d.ts.map +1 -0
  267. package/dist/socket.js +164 -0
  268. package/dist/source.d.ts +59 -0
  269. package/dist/source.d.ts.map +1 -0
  270. package/dist/source.js +93 -0
  271. package/dist/status.d.ts +4 -5
  272. package/dist/status.d.ts.map +1 -1
  273. package/dist/status.js +3 -7
  274. package/dist/store/installs.d.ts +30 -0
  275. package/dist/store/installs.d.ts.map +1 -0
  276. package/dist/store/installs.js +40 -0
  277. package/dist/store/readiness.d.ts +11 -0
  278. package/dist/store/readiness.d.ts.map +1 -0
  279. package/dist/store/readiness.js +68 -0
  280. package/dist/store/records.d.ts +223 -0
  281. package/dist/store/records.d.ts.map +1 -0
  282. package/dist/store/records.js +465 -0
  283. package/dist/store/room-held.d.ts +8 -0
  284. package/dist/store/room-held.d.ts.map +1 -0
  285. package/dist/store/room-held.js +17 -0
  286. package/dist/store/rooms-shown.d.ts +8 -0
  287. package/dist/store/rooms-shown.d.ts.map +1 -0
  288. package/dist/store/rooms-shown.js +13 -0
  289. package/dist/store/space.d.ts +11 -0
  290. package/dist/store/space.d.ts.map +1 -0
  291. package/dist/store/space.js +41 -0
  292. package/dist/store/watchers.d.ts +17 -0
  293. package/dist/store/watchers.d.ts.map +1 -0
  294. package/dist/store/watchers.js +56 -0
  295. package/dist/store/writes.d.ts +24 -0
  296. package/dist/store/writes.d.ts.map +1 -0
  297. package/dist/store/writes.js +125 -0
  298. package/dist/store.d.ts +114 -163
  299. package/dist/store.d.ts.map +1 -1
  300. package/dist/store.js +163 -754
  301. package/dist/stored.d.ts +167 -0
  302. package/dist/stored.d.ts.map +1 -0
  303. package/dist/stored.js +700 -0
  304. package/dist/surface.d.ts +90 -0
  305. package/dist/surface.d.ts.map +1 -0
  306. package/dist/surface.js +225 -0
  307. package/dist/sync.d.ts +19 -0
  308. package/dist/sync.d.ts.map +1 -0
  309. package/dist/sync.js +536 -0
  310. package/dist/tables.d.ts +376 -0
  311. package/dist/tables.d.ts.map +1 -0
  312. package/dist/tables.js +499 -0
  313. package/dist/tallies.d.ts +18 -0
  314. package/dist/tallies.d.ts.map +1 -0
  315. package/dist/tallies.js +128 -0
  316. package/dist/transfer.d.ts +0 -5
  317. package/dist/transfer.d.ts.map +1 -1
  318. package/dist/turn.d.ts +5 -3
  319. package/dist/turn.d.ts.map +1 -1
  320. package/dist/turn.js +51 -21
  321. package/dist/validation.d.ts +29 -0
  322. package/dist/validation.d.ts.map +1 -0
  323. package/dist/validation.js +98 -0
  324. package/dist/windows.d.ts +9 -16
  325. package/dist/windows.d.ts.map +1 -1
  326. package/dist/windows.js +11 -75
  327. package/dist/wire.d.ts +91 -9
  328. package/dist/wire.d.ts.map +1 -1
  329. package/dist/wire.js +31 -6
  330. package/package.json +19 -19
  331. package/AGENTS.md +0 -299
  332. package/dist/acquisition.d.ts +0 -14
  333. package/dist/acquisition.d.ts.map +0 -1
  334. package/dist/acquisition.js +0 -24
  335. package/dist/attempt.d.ts +0 -16
  336. package/dist/attempt.d.ts.map +0 -1
  337. package/dist/attempt.js +0 -70
  338. package/dist/chat/acts.d.ts +0 -33
  339. package/dist/chat/acts.d.ts.map +0 -1
  340. package/dist/chat/acts.js +0 -36
  341. package/dist/chat/context.d.ts +0 -3
  342. package/dist/chat/context.d.ts.map +0 -1
  343. package/dist/chat/earlier.d.ts +0 -10
  344. package/dist/chat/earlier.d.ts.map +0 -1
  345. package/dist/chat/earlier.js +0 -54
  346. package/dist/chat/input.d.ts +0 -9
  347. package/dist/chat/input.d.ts.map +0 -1
  348. package/dist/chat/input.js +0 -99
  349. package/dist/chat/kit.d.ts +0 -61
  350. package/dist/chat/kit.d.ts.map +0 -1
  351. package/dist/chat/kit.js +0 -123
  352. package/dist/chat/lasting.d.ts +0 -6
  353. package/dist/chat/lasting.d.ts.map +0 -1
  354. package/dist/chat/lasting.js +0 -19
  355. package/dist/chat/list.d.ts +0 -27
  356. package/dist/chat/list.d.ts.map +0 -1
  357. package/dist/chat/list.js +0 -99
  358. package/dist/chat/markdown.d.ts +0 -20
  359. package/dist/chat/markdown.d.ts.map +0 -1
  360. package/dist/chat/markdown.js +0 -188
  361. package/dist/chat/message.d.ts +0 -6
  362. package/dist/chat/message.d.ts.map +0 -1
  363. package/dist/chat/message.js +0 -192
  364. package/dist/chat/messages.d.ts +0 -22
  365. package/dist/chat/messages.d.ts.map +0 -1
  366. package/dist/chat/messages.js +0 -155
  367. package/dist/chat/name.d.ts +0 -6
  368. package/dist/chat/name.d.ts.map +0 -1
  369. package/dist/chat/name.js +0 -37
  370. package/dist/chat/opened.d.ts +0 -11
  371. package/dist/chat/opened.d.ts.map +0 -1
  372. package/dist/chat/opened.js +0 -17
  373. package/dist/chat/overlay.d.ts +0 -31
  374. package/dist/chat/overlay.d.ts.map +0 -1
  375. package/dist/chat/overlay.js +0 -97
  376. package/dist/chat/parts.d.ts +0 -57
  377. package/dist/chat/parts.d.ts.map +0 -1
  378. package/dist/chat/parts.js +0 -119
  379. package/dist/chat/process.d.ts +0 -20
  380. package/dist/chat/process.d.ts.map +0 -1
  381. package/dist/chat/process.js +0 -32
  382. package/dist/chat/provider.d.ts +0 -63
  383. package/dist/chat/provider.d.ts.map +0 -1
  384. package/dist/chat/provider.js +0 -635
  385. package/dist/chat/question.d.ts +0 -9
  386. package/dist/chat/question.d.ts.map +0 -1
  387. package/dist/chat/question.js +0 -69
  388. package/dist/chat/questions.d.ts.map +0 -1
  389. package/dist/chat/read.d.ts.map +0 -1
  390. package/dist/chat/ready.d.ts +0 -34
  391. package/dist/chat/ready.d.ts.map +0 -1
  392. package/dist/chat/ready.js +0 -91
  393. package/dist/chat/style.d.ts +0 -4
  394. package/dist/chat/style.d.ts.map +0 -1
  395. package/dist/chat/style.js +0 -302
  396. package/dist/chat.d.ts +0 -14
  397. package/dist/chat.d.ts.map +0 -1
  398. package/dist/chat.js +0 -8
  399. package/dist/fence.d.ts +0 -6
  400. package/dist/fence.d.ts.map +0 -1
  401. package/dist/fence.js +0 -10
  402. package/dist/log.d.ts +0 -5
  403. package/dist/log.d.ts.map +0 -1
  404. package/dist/log.js +0 -14
  405. package/dist/read-side.d.ts +0 -25
  406. package/dist/read-side.d.ts.map +0 -1
  407. package/dist/read-side.js +0 -761
package/dist/reach.js CHANGED
@@ -1,13 +1,13 @@
1
+ import { QueryError } from '@agentshouse/mdmodel';
2
+ import { selected } from './collection.js';
1
3
  import { unheldView } from './conversation.js';
2
4
  import { modelTypes, NO_MODEL } from './model.js';
3
- import { applied, observing } from './observation.js';
4
- import { runtimeError } from './failure.js';
5
- import { failure, undeclared, } from './outcome.js';
5
+ import { changeOf, digestApplied, digestOf, observing, unchanged, } from './observation.js';
6
+ import { runtimeError, uncaught } from './failure.js';
7
+ import { absentBinary, failure, lockedRoom, ROOM_LOCKED, undeclared, UNREADABLE, } from './outcome.js';
6
8
  import { beneath } from './paths.js';
7
- import { reconciled } from './read-side.js';
8
9
  import { moveTarget, readParts, staleWrite, } from './room-draft.js';
9
10
  import { documentKey } from './rows.js';
10
- import { undeclaredSearch } from './search.js';
11
11
  const UNHELD_TYPES = { collection: modelTypes(NO_MODEL), typedSelection: null };
12
12
  function unconversed(name) {
13
13
  return () => Promise.resolve(undeclared(name));
@@ -15,18 +15,37 @@ function unconversed(name) {
15
15
  const NO_CONVERSATION = {
16
16
  list: () => Promise.resolve([]),
17
17
  read: (conversation) => Promise.resolve(unheldView(conversation)),
18
- create: unconversed('conversation.create'),
19
- send: unconversed('conversation.send'),
20
- answer: unconversed('conversation.answer'),
21
- interrupt: unconversed('conversation.interrupt'),
22
- kill: unconversed('conversation.kill'),
23
- cancel: unconversed('conversation.cancel'),
24
- delete: unconversed('conversation.delete'),
18
+ create: unconversed('conversations/create'),
19
+ send: unconversed('conversations/send'),
20
+ answer: unconversed('conversations/interaction/answer'),
21
+ interrupt: unconversed('conversations/interrupt'),
22
+ kill: unconversed('conversations/kill'),
23
+ delete: unconversed('conversations/delete'),
24
+ takeOut: unconversed('conversations/take-out'),
25
+ decide: unconversed('agent-functions/decide'),
26
+ rename: unconversed('conversations/rename'),
27
+ option: unconversed('conversations/option/set'),
28
+ retry: unconversed('conversations/retry'),
29
+ pin: () => Promise.resolve(),
30
+ openTurn: () => Promise.resolve(),
31
+ dismissSuggestion: () => Promise.resolve(),
32
+ attach: () => Promise.resolve(undeclared('conversation.attach')),
33
+ attachment: (link) => Promise.resolve(absentBinary(link)),
25
34
  };
26
35
  const NO_CHAT_DRAFT = {
27
36
  write: () => Promise.resolve(),
37
+ prepend: () => Promise.resolve(),
38
+ append: () => Promise.resolve(),
28
39
  discard: () => Promise.resolve(),
29
40
  };
41
+ function areasOf(reach) {
42
+ return reach.areas ?? [];
43
+ }
44
+ function fenced(reach, room, path) {
45
+ return areasOf(reach).some((area) => area.room === room &&
46
+ beneath(area.path, path) &&
47
+ !area.open.some((open) => beneath(open, path)));
48
+ }
30
49
  export function holds(reach, room) {
31
50
  return (reach === null ||
32
51
  reach.rooms.includes(room) ||
@@ -39,33 +58,33 @@ export function governs(reach, room) {
39
58
  if (wholly(reach, room.locator)) {
40
59
  return { collection: true, selection: room.typedSelection !== null };
41
60
  }
42
- const selected = (path) => room.typedSelection?.roots.some((root) => beneath(root, path)) ?? false;
61
+ const within = (path) => selected({ selection: room.typedSelection }, path);
43
62
  const paths = reach.documents
44
63
  .filter((document) => document.room === room.locator)
45
64
  .map(({ path }) => path);
46
- return { collection: paths.some((path) => !selected(path)), selection: paths.some(selected) };
65
+ return { collection: paths.some((path) => !within(path)), selection: paths.some(within) };
47
66
  }
48
67
  function covers(reach, room, path) {
49
68
  return (reach === null ||
50
- reach.rooms.includes(room) ||
51
- reach.documents.some((document) => document.room === room && document.path === path));
69
+ (!fenced(reach, room, path) &&
70
+ (reach.rooms.includes(room) ||
71
+ reach.documents.some((document) => document.room === room && document.path === path))));
52
72
  }
53
73
  function conversing(reach) {
54
74
  return reach === null || reach.conversations;
55
75
  }
56
- function refers(reach, scope) {
57
- if (reach === null)
58
- return true;
59
- if (scope === null)
60
- return false;
61
- if (scope.kind === 'conversations')
62
- return reach.conversations;
63
- return scope.path === undefined
64
- ? wholly(reach, scope.locator)
65
- : covers(reach, scope.locator, scope.path);
76
+ function roomsAwaited(error, reach) {
77
+ return error.code === 'unknown-type' && reach !== null && reach.rooms.length === 0;
66
78
  }
67
- function unreachedReference(fileRef) {
68
- return { kind: 'absent', code: 'binary-file-absent', fields: { fileRef }, retryable: false };
79
+ async function planInReach(runtime, input, reach, answered) {
80
+ try {
81
+ return await runtime.plan(input, reach);
82
+ }
83
+ catch (error) {
84
+ if (error instanceof QueryError && (answered || roomsAwaited(error, reach)))
85
+ return null;
86
+ throw error;
87
+ }
69
88
  }
70
89
  export function planReach(reach) {
71
90
  return reach === null
@@ -75,11 +94,22 @@ export function planReach(reach) {
75
94
  documents: [
76
95
  ...new Set(reach.documents.map(({ room, path }) => documentKey(room, path))),
77
96
  ].sort(),
97
+ areas: areasOf(reach)
98
+ .map(({ room, path, open }) => ({ room, path, open: [...new Set(open)].sort() }))
99
+ .sort((left, right) => documentKey(left.room, left.path) < documentKey(right.room, right.path) ? -1 : 1),
78
100
  };
79
101
  }
80
102
  function roomsWithin(reach, rooms) {
81
103
  return rooms.filter((room) => wholly(reach, room.locator));
82
104
  }
105
+ function roomsChangeWithin(reach, { changed, removed, order }) {
106
+ const within = {
107
+ changed: changed.filter(([locator]) => wholly(reach, locator)),
108
+ removed,
109
+ order: order === null ? null : order.filter((locator) => wholly(reach, locator)),
110
+ };
111
+ return unchanged(within) ? null : within;
112
+ }
83
113
  function typesWithin(reach, room, types) {
84
114
  if (room === undefined)
85
115
  return structuredClone(UNHELD_TYPES);
@@ -90,7 +120,7 @@ function typesWithin(reach, room, types) {
90
120
  };
91
121
  }
92
122
  function moves(reach, room, move) {
93
- return move === undefined || covers(reach, room, moveTarget(move));
123
+ return move === undefined || covers(reach, move.room ?? room, moveTarget(move));
94
124
  }
95
125
  function draftWithin(reach, draft) {
96
126
  return covers(reach, draft.room, draft.path) && moves(reach, draft.room, draft.parts.move);
@@ -109,12 +139,13 @@ function writeWithin(reach, write) {
109
139
  function savedWithin(reach, room, result) {
110
140
  if (reach === null || result.outcome === 'saved')
111
141
  return result;
112
- const { file, location, referrers, ...refusal } = result;
142
+ const { file, location, line, referrers, ...refusal } = result;
113
143
  const hidden = file !== undefined && !covers(reach, room, file);
114
144
  return {
115
145
  ...refusal,
116
146
  ...(file === undefined || hidden ? {} : { file }),
117
147
  ...(location === undefined || hidden ? {} : { location }),
148
+ ...(line === undefined || hidden ? {} : { line }),
118
149
  ...(referrers === undefined
119
150
  ? {}
120
151
  : { referrers: referrers.filter((path) => covers(reach, room, path)) }),
@@ -123,85 +154,201 @@ function savedWithin(reach, room, result) {
123
154
  function statusWithin(reach, status) {
124
155
  return {
125
156
  ...status,
126
- attentionRequired: status.attentionRequired.filter((entry) => 'refusal' in entry ? wholly(reach, entry.room) : covers(reach, entry.room, entry.path)),
157
+ attentionRequired: status.attentionRequired.filter((entry) => covers(reach, entry.room, entry.path)),
158
+ unsent: status.unsent.filter((change) => covers(reach, change.room, change.path)),
127
159
  };
128
160
  }
129
161
  function queueWithin(reach, room, entries) {
130
- return entries.filter(({ batch }) => batch.changes.every((change) => covers(reach, room, change.path) &&
131
- (change.kind !== 'move' || covers(reach, room, change.to))));
162
+ return entries
163
+ .filter(({ batch }) => batch.changes.every((change) => covers(reach, room, change.path) &&
164
+ (change.kind !== 'move' || covers(reach, room, change.to))))
165
+ .map((entry) => {
166
+ const { between, ...batch } = entry.batch;
167
+ if (between === undefined)
168
+ return entry;
169
+ return wholly(reach, between.source.room) && wholly(reach, between.destination.room)
170
+ ? entry
171
+ : { ...entry, batch };
172
+ });
132
173
  }
133
174
  function unreached(room) {
134
- return runtimeError('room-not-held', `No Local Replica for ${room}`);
175
+ return runtimeError('unknown-room', `Unknown Room ${room}`);
176
+ }
177
+ function lockedError(room) {
178
+ return runtimeError(ROOM_LOCKED, `${room} is locked until House confirms its access`, true);
179
+ }
180
+ function deviceUnreached() {
181
+ return runtimeError('device-unreached', 'Only the panel reaches this device');
182
+ }
183
+ const ATTACH_REQUIRED = 'attach-required';
184
+ function attachRequired() {
185
+ return runtimeError(ATTACH_REQUIRED, 'App code takes a file in with binaryFile.attach');
135
186
  }
136
- export function narrowed(runtime, given, told) {
187
+ function carriesFile(parts) {
188
+ return parts !== null && typeof parts === 'object' && Object.hasOwn(parts, 'file');
189
+ }
190
+ export function narrowed(runtime, given, port) {
137
191
  const { md, watch } = runtime;
138
192
  let reach = given;
139
- let port = told;
140
193
  const open = new Set();
141
- function following(begin) {
194
+ function following(begin, locking = false) {
142
195
  let stop = begin();
143
196
  const restart = () => {
144
197
  stop();
145
198
  stop = begin();
146
199
  };
147
200
  open.add(restart);
201
+ const unwatch = locking ? runtime.watchLocks(restart) : () => { };
148
202
  return () => {
149
203
  open.delete(restart);
204
+ unwatch();
205
+ stop();
206
+ };
207
+ }
208
+ const unlocking = (rooms, locked) => {
209
+ const held = (rooms ?? []).filter((room) => locked.includes(room));
210
+ return held.length === 0 ? null : { pending: held.map((room) => ({ room, awaits: 'unlock' })) };
211
+ };
212
+ const unlocked = (entries, locked) => entries.filter((entry) => !locked.includes(entry.room));
213
+ const intoLocked = async (held) => {
214
+ for (const move of held) {
215
+ if (move?.room !== undefined && (await runtime.locked(move.room)))
216
+ return true;
217
+ }
218
+ return false;
219
+ };
220
+ function ordered(deliver) {
221
+ let open = true;
222
+ let shown = Promise.resolve();
223
+ return {
224
+ push(making) {
225
+ shown = shown.then(() => making.then((value) => {
226
+ if (open)
227
+ deliver(value);
228
+ }, uncaught), uncaught);
229
+ },
230
+ stop() {
231
+ open = false;
232
+ },
233
+ };
234
+ }
235
+ function unlockedWatch(topic, input, deliver, fail, within) {
236
+ const shown = ordered(deliver);
237
+ const stop = watch(topic, input, (message) => {
238
+ shown.push(runtime.lockedRooms().then((locked) => within(message, locked)));
239
+ }, fail);
240
+ return () => {
241
+ shown.stop();
242
+ stop();
243
+ };
244
+ }
245
+ function lockedFirst(room, start, shut) {
246
+ let open = true;
247
+ let stop = () => { };
248
+ void (async () => {
249
+ const closed = !holds(reach, room) || (await runtime.locked(room));
250
+ if (!open)
251
+ return;
252
+ if (closed)
253
+ shut();
254
+ else
255
+ stop = start();
256
+ })();
257
+ return () => {
258
+ open = false;
150
259
  stop();
151
260
  };
152
261
  }
153
- const within = (topic, input, deliver) => {
262
+ const within = (topic, input, deliver, fail) => {
263
+ if (topic === 'read' && reach !== null) {
264
+ fail(deviceUnreached());
265
+ return () => { };
266
+ }
154
267
  if (topic === 'rooms') {
155
- return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms))));
268
+ return following(() => watch(topic, input, (rooms) => {
269
+ const shown = Array.isArray(rooms)
270
+ ? roomsWithin(reach, rooms)
271
+ : roomsChangeWithin(reach, rooms);
272
+ if (shown !== null)
273
+ deliver(shown);
274
+ }, fail));
156
275
  }
157
276
  if (topic === 'readiness') {
158
277
  return following(() => runtime.watchReadiness(port, reach, deliver));
159
278
  }
160
279
  if (topic === 'sync-status') {
161
- return following(() => watch(topic, input, (status) => deliver(statusWithin(reach, status))));
280
+ return following(() => unlockedWatch(topic, input, deliver, fail, (status, locked) => {
281
+ const shown = statusWithin(reach, status);
282
+ return { ...shown, attentionRequired: unlocked(shown.attentionRequired, locked) };
283
+ }), true);
162
284
  }
163
285
  if (topic === 'room-drafts') {
164
- return following(() => watch(topic, input, (drafts) => deliver(draftsWithin(reach, drafts))));
286
+ return following(() => unlockedWatch(topic, input, deliver, fail, (drafts, locked) => unlocked(draftsWithin(reach, drafts), locked)), true);
165
287
  }
166
288
  if (topic === 'queue') {
167
289
  const room = input[0];
168
- return following(() => {
169
- if (!holds(reach, room)) {
170
- deliver([]);
171
- return () => { };
172
- }
173
- return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)));
174
- });
290
+ return following(() => lockedFirst(room, () => watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)), fail), () => deliver([])), true);
175
291
  }
176
292
  if (topic === 'query') {
177
- const plan = runtime.plan(input[0], reach);
178
293
  let held = null;
294
+ let planning = null;
295
+ const waiting = (result) => {
296
+ const answer = { result, keys: [] };
297
+ if (held === null || changeOf(held, answer) !== null)
298
+ deliver(answer);
299
+ held = digestOf(answer);
300
+ };
179
301
  return following(() => {
180
- let first = true;
181
- return runtime.watchPlan({ ...plan, reach: planReach(reach) }, (message) => {
182
- if (!first) {
183
- held = applied(held, message);
184
- deliver(message);
185
- return;
186
- }
187
- first = false;
188
- if (held === null) {
189
- held = message;
190
- deliver(message);
191
- return;
192
- }
193
- const next = reconciled(held, message);
194
- if (next === null)
302
+ let open = true;
303
+ let stop = () => { };
304
+ if (planning?.reach !== reach) {
305
+ planning = { reach, plan: planInReach(runtime, input[0], reach, held !== null) };
306
+ }
307
+ const planned = planning.plan;
308
+ void (async () => {
309
+ const plan = await planned;
310
+ const locked = await runtime.lockedRooms();
311
+ if (!open)
195
312
  return;
196
- held = next.keyed;
197
- deliver(next.message);
313
+ if (plan === null)
314
+ return waiting({ pending: [] });
315
+ const pending = unlocking(plan.rooms, locked);
316
+ if (pending !== null)
317
+ return waiting(pending);
318
+ let first = true;
319
+ const heard = (message) => {
320
+ if (!first) {
321
+ held = digestApplied(held, message);
322
+ deliver(message);
323
+ return;
324
+ }
325
+ first = false;
326
+ const change = held === null ? message : changeOf(held, message);
327
+ held = digestOf(message);
328
+ if (change !== null)
329
+ deliver(change);
330
+ };
331
+ stop = runtime.watchPlan({ ...plan, locked }, (message) => {
332
+ if (open)
333
+ heard(message);
334
+ }, (error) => {
335
+ if (open)
336
+ fail(error);
337
+ });
338
+ })().catch((error) => {
339
+ if (open)
340
+ fail(error);
198
341
  });
199
- });
342
+ return () => {
343
+ open = false;
344
+ stop();
345
+ };
346
+ }, true);
200
347
  }
201
348
  if (topic === 'conversation') {
202
349
  return following(() => {
203
350
  if (conversing(reach))
204
- return watch(topic, input, deliver);
351
+ return watch(topic, input, deliver, fail);
205
352
  deliver(unheldView(input[0]));
206
353
  return () => { };
207
354
  });
@@ -209,69 +356,163 @@ export function narrowed(runtime, given, told) {
209
356
  if (topic === 'conversations' || topic === 'agents') {
210
357
  return following(() => {
211
358
  if (conversing(reach))
212
- return watch(topic, input, deliver);
359
+ return watch(topic, input, deliver, fail);
213
360
  deliver([]);
214
361
  return () => { };
215
362
  });
216
363
  }
217
- return watch(topic, input, deliver);
364
+ if (topic === 'figures' ||
365
+ topic === 'holdings' ||
366
+ topic === 'listed-agents' ||
367
+ topic === 'room-list') {
368
+ if (reach === null)
369
+ return watch(topic, input, deliver, fail);
370
+ fail(deviceUnreached());
371
+ return () => { };
372
+ }
373
+ return watch(topic, input, deliver, fail);
218
374
  };
375
+ const files = new Map();
376
+ let handed = 0;
377
+ async function hand(reading) {
378
+ const answer = await reading;
379
+ if (answer.kind !== 'binary')
380
+ return answer;
381
+ handed += 1;
382
+ const file = String(handed);
383
+ files.set(file, answer.file);
384
+ return { ...answer, file };
385
+ }
219
386
  const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
220
387
  const chatDraft = () => (conversing(reach) ? md.chatDraft : NO_CHAT_DRAFT);
221
388
  const view = {
222
389
  ...md,
223
- rooms: () => roomsWithin(reach, md.rooms()),
224
- query: ((input) => runtime.query(runtime.plan(input, reach))),
225
- search: (input) => port.search === 'required'
226
- ? runtime.search(input, reach)
227
- : Promise.resolve(undeclaredSearch()),
228
- types(room) {
390
+ rooms: () => md.rooms().then((rooms) => roomsWithin(reach, rooms)),
391
+ query: (async (input) => {
392
+ const plan = await planInReach(runtime, input, reach, false);
393
+ if (plan === null)
394
+ return { pending: [] };
395
+ const locked = await runtime.lockedRooms();
396
+ return unlocking(plan.rooms, locked) ?? runtime.query({ ...plan, locked });
397
+ }),
398
+ search: (input) => runtime.search(input, reach),
399
+ async types(room) {
400
+ if (holds(reach, room) && (await runtime.locked(room)))
401
+ throw lockedError(room);
229
402
  if (wholly(reach, room))
230
403
  return md.types(room);
231
404
  if (!holds(reach, room))
232
405
  return structuredClone(UNHELD_TYPES);
233
- const listed = md.rooms().find(({ locator }) => locator === room);
234
- return typesWithin(reach, listed, md.types(room));
406
+ return typesWithin(reach, await runtime.room(room), await md.types(room));
235
407
  },
236
408
  async save(room, roomDrafts, writtenBy) {
237
409
  if (!holds(reach, room))
238
410
  throw unreached(room);
239
- const outside = roomDrafts.find(({ path }) => !covers(reach, room, path) ||
240
- !moves(reach, room, md.roomDraft.read(room, path)?.parts.move));
411
+ if (await runtime.locked(room)) {
412
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
413
+ }
414
+ const held = (await Promise.all(roomDrafts.map(({ path }) => md.roomDraft.read(room, path)))).map((draft) => draft?.parts.move);
415
+ const outside = roomDrafts.find(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]));
241
416
  if (outside !== undefined) {
242
417
  return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
243
418
  }
419
+ if (await intoLocked(held))
420
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
244
421
  return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
245
422
  },
246
- history: (room, path, query) => covers(reach, room, path)
247
- ? md.history(room, path, query)
248
- : Promise.resolve(failure({ kind: 'room-not-readable', locator: room })),
423
+ async saveParts(room, parts, writtenBy) {
424
+ if (!holds(reach, room))
425
+ throw unreached(room);
426
+ const filed = reach === null ? undefined : parts.find(({ parts: one }) => carriesFile(one));
427
+ if (filed !== undefined) {
428
+ return { outcome: 'refused', code: ATTACH_REQUIRED, retryable: false, file: filed.path };
429
+ }
430
+ if (await runtime.locked(room)) {
431
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
432
+ }
433
+ const held = parts.map(({ path, parts: one }) => readParts(one, path).move);
434
+ if (parts.some(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]))) {
435
+ throw unreached(room);
436
+ }
437
+ if (await intoLocked(held))
438
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
439
+ return savedWithin(reach, room, await md.saveParts(room, parts, writtenBy));
440
+ },
441
+ async resolve(room, path, destination) {
442
+ const at = await runtime.located(room, path, destination);
443
+ return at !== null && !covers(reach, at.room, at.path)
444
+ ? UNREADABLE
445
+ : md.resolve(room, path, destination);
446
+ },
447
+ history: async (room, path, query) => !covers(reach, room, path)
448
+ ? failure({ kind: 'room-not-readable', locator: room })
449
+ : (await runtime.locked(room))
450
+ ? lockedRoom(room)
451
+ : md.history(room, path, query),
249
452
  binaryFile: {
250
- read: (room, path, revision) => covers(reach, room, path)
251
- ? md.binaryFile.read(room, path, revision)
252
- : Promise.resolve(failure({ kind: 'room-not-readable', locator: room })),
253
- link: (room, path, revision) => covers(reach, room, path)
254
- ? md.binaryFile.link(room, path, revision)
255
- : Promise.resolve(failure({ kind: 'room-not-readable', locator: room })),
256
- readReference: (reference) => refers(reach, runtime.referrerScope(reference.referrer))
257
- ? md.binaryFile.readReference(reference)
258
- : Promise.resolve(unreachedReference(reference.fileRef)),
453
+ read: async (room, path, revision) => !covers(reach, room, path)
454
+ ? failure({ kind: 'room-not-readable', locator: room })
455
+ : (await runtime.locked(room))
456
+ ? lockedRoom(room)
457
+ : hand(md.binaryFile.read(room, path, revision)),
458
+ link: async (room, path, revision) => !covers(reach, room, path)
459
+ ? failure({ kind: 'room-not-readable', locator: room })
460
+ : (await runtime.locked(room))
461
+ ? lockedRoom(room)
462
+ : md.binaryFile.link(room, path, revision),
463
+ show: async (room, path, revision) => !covers(reach, room, path)
464
+ ? failure({ kind: 'room-not-readable', locator: room })
465
+ : (await runtime.locked(room))
466
+ ? lockedRoom(room)
467
+ : hand(md.binaryFile.show(room, path, revision)),
468
+ attach: async (room, file) => !wholly(reach, room)
469
+ ? failure({ kind: 'room-not-readable', locator: room })
470
+ : (await runtime.locked(room))
471
+ ? lockedRoom(room)
472
+ : md.binaryFile.attach(room, file),
473
+ async part(file, part) {
474
+ const key = files.get(file);
475
+ if (key === undefined)
476
+ return null;
477
+ const bytes = await md.binaryFile.part(key, part);
478
+ if (bytes === null)
479
+ files.delete(file);
480
+ return bytes;
481
+ },
259
482
  },
260
- reached: (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
261
- md.reached(room, roomVersion, path),
262
- log: () => (reach === null ? md.log() : ''),
483
+ reached: async (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
484
+ !(await runtime.locked(room)) &&
485
+ (await md.reached(room, roomVersion, path)),
486
+ cleanUp: () => (reach === null ? md.cleanUp() : Promise.reject(deviceUnreached())),
487
+ unsent: () => (reach === null ? md.unsent() : Promise.reject(deviceUnreached())),
488
+ reset: () => (reach === null ? md.reset() : Promise.reject(deviceUnreached())),
489
+ readAgain: () => (reach === null ? md.readAgain() : Promise.reject(deviceUnreached())),
263
490
  roomDraft: {
264
- list: () => md.roomDraft.list().then((drafts) => draftsWithin(reach, drafts)),
265
- read: (room, path) => covers(reach, room, path) ? shownDraft(reach, md.roomDraft.read(room, path)) : null,
266
- async write(room, path, revision, parts) {
267
- if (!covers(reach, room, path) || !moves(reach, room, readParts(parts).move)) {
491
+ list: async () => unlocked(draftsWithin(reach, await md.roomDraft.list()), await runtime.lockedRooms()),
492
+ async read(room, path) {
493
+ if (!covers(reach, room, path))
494
+ return null;
495
+ if (await runtime.locked(room))
496
+ throw lockedError(room);
497
+ return shownDraft(reach, await md.roomDraft.read(room, path));
498
+ },
499
+ async write(room, path, revision, parts, next) {
500
+ if (reach !== null && carriesFile(parts))
501
+ throw attachRequired();
502
+ const move = readParts(parts, path).move;
503
+ if (!covers(reach, room, path) || !moves(reach, room, move))
268
504
  throw unreached(room);
269
- }
270
- return writeWithin(reach, await md.roomDraft.write(room, path, revision, parts));
505
+ if (await runtime.locked(room))
506
+ throw lockedError(room);
507
+ if (await intoLocked([move]))
508
+ throw lockedError(move.room);
509
+ return writeWithin(reach, await md.roomDraft.write(room, path, revision, parts, next));
271
510
  },
272
511
  async discard(room, path, revision) {
273
512
  if (!covers(reach, room, path))
274
513
  return staleWrite(null);
514
+ if (await runtime.locked(room))
515
+ throw lockedError(room);
275
516
  return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
276
517
  },
277
518
  },
@@ -280,14 +521,25 @@ export function narrowed(runtime, given, told) {
280
521
  read: (id, options) => conversation().read(id, options),
281
522
  create: (input) => conversation().create(input),
282
523
  send: (id, operation, draft) => conversation().send(id, operation, draft),
283
- answer: (id, answer) => conversation().answer(id, answer),
284
- interrupt: (id) => conversation().interrupt(id),
285
- kill: (id) => conversation().kill(id),
286
- cancel: (id, turn) => conversation().cancel(id, turn),
287
- delete: (id) => conversation().delete(id),
524
+ answer: (id, answer, operation) => conversation().answer(id, answer, operation),
525
+ interrupt: (id, operation) => conversation().interrupt(id, operation),
526
+ kill: (id, operation) => conversation().kill(id, operation),
527
+ delete: (id, operation) => conversation().delete(id, operation),
528
+ takeOut: (id, message, operation) => conversation().takeOut(id, message, operation),
529
+ decide: (request, decision, operation) => conversation().decide(request, decision, operation),
530
+ rename: (id, name, operation) => conversation().rename(id, name, operation),
531
+ option: (id, option, value, operation) => conversation().option(id, option, value, operation),
532
+ retry: (id, message, operation) => conversation().retry(id, message, operation),
533
+ pin: (figures) => conversation().pin(figures),
534
+ openTurn: (id, turn) => conversation().openTurn(id, turn),
535
+ dismissSuggestion: (id, suggestion) => conversation().dismissSuggestion(id, suggestion),
536
+ attach: (file) => conversation().attach(file),
537
+ attachment: (link) => conversation().attachment(link),
288
538
  },
289
539
  chatDraft: {
290
540
  write: (id, draft, revision) => chatDraft().write(id, draft, revision),
541
+ prepend: (id, draft) => chatDraft().prepend(id, draft),
542
+ append: (id, draft) => chatDraft().append(id, draft),
291
543
  discard: (id) => chatDraft().discard(id),
292
544
  },
293
545
  observe: observing(within),
@@ -300,10 +552,5 @@ export function narrowed(runtime, given, told) {
300
552
  for (const restart of [...open])
301
553
  restart();
302
554
  },
303
- facts(next) {
304
- port = next;
305
- for (const restart of [...open])
306
- restart();
307
- },
308
555
  };
309
556
  }