@agentshouse/mdruntime 0.1.0-c069136dcb4e8 → 0.1.0-c076b00ebf42a

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