@agentshouse/mdruntime 0.1.0-cb2e390ee7b89 → 0.1.0-cb8a03985803b

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