@agentshouse/mdruntime-adapter 0.1.0-cd59fd8945dcb → 0.1.0-cd8cfa169a55d

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 (62) hide show
  1. package/README.md +2 -2
  2. package/dist/actions.d.ts +11 -6
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +37 -114
  5. package/dist/adapter.d.ts +1 -0
  6. package/dist/adapter.d.ts.map +1 -1
  7. package/dist/adapter.js +389 -100
  8. package/dist/app-reference.d.ts +2 -0
  9. package/dist/app-reference.d.ts.map +1 -0
  10. package/dist/app-reference.js +2 -0
  11. package/dist/crockford.d.ts +4 -0
  12. package/dist/crockford.d.ts.map +1 -0
  13. package/dist/crockford.js +3 -0
  14. package/dist/discovery.d.ts +7 -10
  15. package/dist/discovery.d.ts.map +1 -1
  16. package/dist/discovery.js +43 -34
  17. package/dist/gather.d.ts +1 -1
  18. package/dist/gather.d.ts.map +1 -1
  19. package/dist/gather.js +4 -14
  20. package/dist/house-model.d.ts +2 -0
  21. package/dist/house-model.d.ts.map +1 -0
  22. package/dist/house-model.js +484 -0
  23. package/dist/index.d.ts +7 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +6 -1
  26. package/dist/model.d.ts +5 -2
  27. package/dist/model.d.ts.map +1 -1
  28. package/dist/model.js +10 -15
  29. package/dist/part.d.ts +15 -0
  30. package/dist/part.d.ts.map +1 -0
  31. package/dist/part.js +82 -0
  32. package/dist/read.d.ts +77 -23
  33. package/dist/read.d.ts.map +1 -1
  34. package/dist/read.js +358 -144
  35. package/dist/refusal.d.ts.map +1 -1
  36. package/dist/refusal.js +2 -1
  37. package/dist/room-types.d.ts +7 -0
  38. package/dist/room-types.d.ts.map +1 -0
  39. package/dist/room-types.js +124 -0
  40. package/dist/site.d.ts +1 -1
  41. package/dist/site.d.ts.map +1 -1
  42. package/dist/site.js +163 -59
  43. package/dist/stream.d.ts +5 -4
  44. package/dist/stream.d.ts.map +1 -1
  45. package/dist/stream.js +356 -43
  46. package/dist/transport.d.ts +68 -10
  47. package/dist/transport.d.ts.map +1 -1
  48. package/dist/transport.js +4 -0
  49. package/dist/upload.d.ts +12 -0
  50. package/dist/upload.d.ts.map +1 -0
  51. package/dist/upload.js +63 -0
  52. package/dist/version.d.ts +1 -0
  53. package/dist/version.d.ts.map +1 -1
  54. package/dist/version.js +1 -1
  55. package/dist/write.d.ts +13 -9
  56. package/dist/write.d.ts.map +1 -1
  57. package/dist/write.js +130 -40
  58. package/package.json +8 -5
  59. package/AGENTS.md +0 -290
  60. package/dist/links.d.ts +0 -20
  61. package/dist/links.d.ts.map +0 -1
  62. package/dist/links.js +0 -104
@@ -0,0 +1,124 @@
1
+ import { APP_REFERENCE_PATTERN } from './app-reference.js';
2
+ import { HOUSE_MODEL_TYPES } from './house-model.js';
3
+ export const INBOX_CHANNEL_KINDS = [
4
+ 'telegram-bot',
5
+ 'whatsapp',
6
+ 'messenger',
7
+ 'instagram',
8
+ 'viber',
9
+ 'tiktok',
10
+ ];
11
+ export const INBOX_CHAT_TYPE = 'inbox-chat';
12
+ export const INBOX_MESSAGE_TYPE = 'inbox-message';
13
+ export const HOUSE_NAMEABLE_ROOM_TYPES = [INBOX_CHAT_TYPE, INBOX_MESSAGE_TYPE];
14
+ const WAYFINDING_MAP_TYPE = 'wayfinding-map';
15
+ const WAYFINDING_TICKET_TYPE = 'wayfinding-ticket';
16
+ const WAYFINDING_MAP_SECTIONS = [
17
+ 'Destination',
18
+ 'Notes',
19
+ 'Decisions so far',
20
+ 'Not yet specified',
21
+ 'Out of scope',
22
+ ];
23
+ const IDENTITY = "{ type: string, pattern: '^\\S+$' }";
24
+ const AGENT = [' agent: { type: string, format: uuid }', ' name: { type: string }'];
25
+ const ASSIGNEE = [
26
+ ' type: object',
27
+ ' properties:',
28
+ ' user: { type: string, format: uuid }',
29
+ ...AGENT,
30
+ ];
31
+ export const HOUSE_ROOM_TYPES = [
32
+ `${INBOX_CHAT_TYPE}:`,
33
+ ' properties:',
34
+ ' inbox: { type: string, format: uuid }',
35
+ ` channel: { enum: [${INBOX_CHANNEL_KINDS.join(', ')}] }`,
36
+ ` chat: ${IDENTITY}`,
37
+ ' customer:',
38
+ ' type: object',
39
+ ' properties:',
40
+ ' name: { type: string }',
41
+ ` username: ${IDENTITY}`,
42
+ ` phone: ${IDENTITY}`,
43
+ ' assignee:',
44
+ ...ASSIGNEE,
45
+ ' return_to:',
46
+ ' type: object',
47
+ ' properties:',
48
+ ...AGENT,
49
+ ' conversation: { type: string, format: uuid }',
50
+ ' required: [inbox, channel, chat, customer]',
51
+ `${INBOX_MESSAGE_TYPE}:`,
52
+ ' properties:',
53
+ ' direction: { enum: [in, out] }',
54
+ ' sender:',
55
+ ' type: object',
56
+ ' properties:',
57
+ ' name: { type: string }',
58
+ ` username: ${IDENTITY}`,
59
+ ' sent_at: { type: string, format: date-time }',
60
+ ` channel_message: ${IDENTITY}`,
61
+ ' state: { enum: [sending, sent, failed] }',
62
+ ' reason: { type: string }',
63
+ ' reactions:',
64
+ ' type: array',
65
+ ' items:',
66
+ ' type: object',
67
+ ' properties:',
68
+ ' reaction: { type: string, minLength: 1 }',
69
+ ' sender:',
70
+ ' type: object',
71
+ ' properties:',
72
+ ` id: ${IDENTITY}`,
73
+ ' name: { type: string }',
74
+ ` username: ${IDENTITY}`,
75
+ ' count: { type: integer, minimum: 1 }',
76
+ ' required: [reaction]',
77
+ ` post: ${IDENTITY}`,
78
+ ' assignee:',
79
+ ...ASSIGNEE,
80
+ ' sent_outside: { const: true }',
81
+ ' template:',
82
+ ' type: object',
83
+ ' properties:',
84
+ ' name: { type: string, minLength: 1 }',
85
+ ' language: { type: string, minLength: 1 }',
86
+ ' required: [name, language]',
87
+ ' values:',
88
+ ' type: object',
89
+ ' additionalProperties: { type: string }',
90
+ ' withheld: { const: true }',
91
+ ' required: [direction]',
92
+ ' if: { properties: { direction: { const: in } } }',
93
+ ' then: { required: [sent_at] }',
94
+ `${WAYFINDING_MAP_TYPE}:`,
95
+ ' properties:',
96
+ ' title: { type: string }',
97
+ ' required: [title]',
98
+ ' sections:',
99
+ ...WAYFINDING_MAP_SECTIONS.map((name) => ` ${name}: { kind: text, required: true }`),
100
+ `${WAYFINDING_TICKET_TYPE}:`,
101
+ ' properties:',
102
+ ' title: { type: string }',
103
+ ' kind: { enum: [research, prototype, grilling, task] }',
104
+ ' status: { enum: [open, in-progress, done, out-of-scope] }',
105
+ ` map: { type: string, reference: ${WAYFINDING_MAP_TYPE} }`,
106
+ ` blocked_by: { type: array, items: { type: string, reference: ${WAYFINDING_TICKET_TYPE} } }`,
107
+ ' assignee:',
108
+ ...ASSIGNEE,
109
+ ' conversation: { type: string, format: uuid }',
110
+ ` app: { type: string, pattern: '${APP_REFERENCE_PATTERN.source}' }`,
111
+ ' required: [title, kind, status, map, blocked_by]',
112
+ ' sections:',
113
+ ' Question: { kind: text }',
114
+ ' Answer: { kind: text }',
115
+ ' allOf:',
116
+ ' - if: { properties: { status: { enum: [in-progress, done, out-of-scope] } }, required: [status] }',
117
+ ' then: { required: [assignee] }',
118
+ ' else: { properties: { assignee: false } }',
119
+ ' - if: { properties: { assignee: { required: [agent] } }, required: [assignee] }',
120
+ ' else: { properties: { conversation: false } }',
121
+ ' - if: { properties: { status: { enum: [done, out-of-scope] } }, required: [status] }',
122
+ ' then: { sections: { Answer: { kind: text, required: true } } }',
123
+ HOUSE_MODEL_TYPES,
124
+ ].join('\n');
package/dist/site.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import type { Adapter } from '@agentshouse/mdruntime';
2
2
  import { type HouseSiteTransport } from './transport.js';
3
- export declare function createSiteAdapter(transport: HouseSiteTransport): Adapter;
3
+ export declare function createSiteAdapter(transport: HouseSiteTransport, snapshot?: boolean): Adapter;
4
4
  //# sourceMappingURL=site.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAMR,MAAM,wBAAwB,CAAC;AAsBhC,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAgCxB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,GAAG,OAAO,CAwIxE"}
1
+ {"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAWR,MAAM,wBAAwB,CAAC;AA+BhC,OAAO,EAML,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAoCxB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,EAAE,QAAQ,UAAQ,GAAG,OAAO,CA4P1F"}
package/dist/site.js CHANGED
@@ -1,73 +1,108 @@
1
- import { actionOutcome } from './actions.js';
1
+ import { stepped } from '@agentshouse/mdruntime';
2
+ import { actionOutcome, SITE_SUBMIT } from './actions.js';
2
3
  import { mapDiscovery, parseSiteDiscovery, siteCapabilities, siteTracked, } from './discovery.js';
3
- import { scopeModels, streamedModels, viewModels } from './model.js';
4
- import { advancedScope, bootstrapOf, parseEnumeration, parseSiteBootstrap, refreshFrom, viewOf, } from './read.js';
4
+ import { manifestedModels, partModels, streamedModels, viewModels } from './model.js';
5
+ import { bootstrapping, emptyScope, housePart, manifested, parseEnumeration, parseSiteParted, partInventory, refreshFrom, viewOf, wholeView, } from './read.js';
6
+ import { PART_ATTEMPTS, partArrival, partFrame, unverifiedPart } from './part.js';
5
7
  import { classifyDoor, classifyRead, discoveryFailure } from './refusal.js';
8
+ import { HOUSE_NAMEABLE_ROOM_TYPES, HOUSE_ROOM_TYPES } from './room-types.js';
6
9
  import { houseNotifications } from './stream.js';
7
- import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT, } from './transport.js';
10
+ import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT, SITE_FILES, } from './transport.js';
8
11
  import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
9
12
  const UNCERTAIN = { kind: 'transport-uncertainty' };
13
+ function unfound() {
14
+ return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
15
+ }
10
16
  function siteRoom(tracked) {
11
17
  return {
12
18
  name: tracked.handle,
13
19
  locator: tracked.locator,
14
20
  handle: tracked.handle,
15
21
  roomVersion: roomVersion(tracked),
16
- operations: { read: [''], sync: [''], write: [], delete: [] },
17
- replica: { selection: tracked.locator, admission: 'admitted' },
22
+ operations: { write: [], delete: [] },
23
+ replica: { selection: tracked.locator, admission: 'admitted', offline: 'open' },
18
24
  providerOwnedPaths: [],
19
25
  };
20
26
  }
21
- function settled(refused) {
22
- return refused.kind === 'beyond-horizon' ? UNCERTAIN : refused;
23
- }
24
- export function createSiteAdapter(transport) {
27
+ export function createSiteAdapter(transport, snapshot = false) {
25
28
  const notifications = houseNotifications(transport, 'site');
26
29
  const tracked = new Map();
27
- async function enumeration(entry, from) {
30
+ const expired = new Map();
31
+ function fileRoute(request) {
32
+ const entry = tracked.get(request.locator);
33
+ if (entry === undefined)
34
+ return { kind: 'room-not-readable', locator: request.locator };
35
+ return `${SITE_FILES}${entry.authority}/${encodeURIComponent(request.revision)}/${encodeURIComponent(request.path)}`;
36
+ }
37
+ async function enumerated(entry, from, page) {
28
38
  const answer = await transport.door(SITE_DOOR_ENUMERATE, {
29
- positions: [presented(entry.authority, from)],
39
+ positions: [
40
+ page === undefined
41
+ ? presented(entry.authority, from)
42
+ : {
43
+ ...presented(entry.authority, { position: page.after, logEpoch: from.logEpoch }),
44
+ page: { through: page.through, read: page.read },
45
+ },
46
+ ],
30
47
  });
31
48
  const classified = classifyRead(answer.status, answer.body, entry.locator);
32
49
  if (classified !== null)
33
50
  return classified;
34
- return parseEnumeration(answer.body, 'site') ?? UNCERTAIN;
51
+ const found = parseEnumeration(answer.body, 'site');
52
+ if (found === null)
53
+ return UNCERTAIN;
54
+ return viewOf(found, entry) ?? { kind: 'room-not-readable', locator: entry.locator };
35
55
  }
36
- async function caughtUp(entry) {
37
- const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}`);
56
+ async function enumeration(entry, from) {
57
+ const first = await enumerated(entry, from);
58
+ return 'kind' in first ? first : wholeView(first, (page) => enumerated(entry, from, page));
59
+ }
60
+ async function partedRoom(entry) {
61
+ const cut = expired.get(entry.locator);
62
+ const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}${cut === undefined ? '' : `?expired=${cut}`}`);
38
63
  const classified = classifyDoor(answer.status, answer.body, entry.locator);
39
64
  if (classified !== null)
40
- return { failure: classified };
41
- const scope = parseSiteBootstrap(answer.body);
42
- if (scope === null)
43
- return { failure: UNCERTAIN };
44
- if (roomVersion(scope) === roomVersion(entry))
45
- return { scope };
46
- const found = await enumeration(entry, scope);
47
- if ('kind' in found)
48
- return { failure: settled(found) };
49
- const view = viewOf(found, entry);
50
- if (view === undefined)
51
- return { failure: { kind: 'room-not-readable', locator: entry.locator } };
52
- return { scope: advancedScope(scope, view) };
65
+ return classified;
66
+ const room = parseSiteParted(answer.body);
67
+ return room === null || room.anchor !== entry.authority ? UNCERTAIN : room;
68
+ }
69
+ async function fetchedPart(entry, room, listed, received, arriving) {
70
+ if (received !== undefined) {
71
+ const kept = new Uint8Array(received);
72
+ const held = await housePart(room, kept, listed, 'site');
73
+ if (held !== null)
74
+ return 'kind' in held ? held : { scope: held, frame: kept };
75
+ }
76
+ for (let attempt = 0; attempt < PART_ATTEMPTS; attempt += 1) {
77
+ const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}?part=${encodeURIComponent(listed.part)}`, partArrival(listed, arriving));
78
+ const failure = classifyRead(answer.status, answer.body, entry.locator);
79
+ if (failure?.kind === 'beyond-horizon')
80
+ expired.set(entry.locator, room.position);
81
+ if (failure !== null)
82
+ return failure;
83
+ const frame = partFrame(answer.body);
84
+ if (frame === null)
85
+ continue;
86
+ const scope = await housePart(room, frame, listed, 'site');
87
+ if (scope !== null)
88
+ return 'kind' in scope ? scope : { scope, frame };
89
+ }
90
+ return unverifiedPart(entry.locator);
53
91
  }
54
92
  async function refreshed(entry, fromRoomVersion) {
55
93
  const from = logPosition(fromRoomVersion);
56
94
  if (from === null)
57
95
  return { kind: 'beyond-horizon' };
58
- const streamed = notifications.advance(entry, from);
96
+ const streamed = await stepped(notifications.advance(entry, from));
59
97
  if (streamed !== null) {
60
98
  const models = await streamedModels(streamed.schemas, entry, 'site');
61
99
  return models === undefined ? streamed.page : { ...streamed.page, models };
62
100
  }
63
- const found = await enumeration(entry, from);
64
- if ('kind' in found)
65
- return found;
66
- const view = viewOf(found, entry);
67
- if (view === undefined)
68
- return { kind: 'room-not-readable', locator: entry.locator };
101
+ const view = await enumeration(entry, from);
102
+ if ('kind' in view)
103
+ return view;
69
104
  notifications.reach(entry.authority, view);
70
- const answer = refreshFrom(view, fromRoomVersion);
105
+ const answer = await refreshFrom(view, fromRoomVersion);
71
106
  if (answer.kind !== 'net-advancement')
72
107
  return answer;
73
108
  const models = await viewModels(view, entry);
@@ -75,6 +110,9 @@ export function createSiteAdapter(transport) {
75
110
  }
76
111
  return {
77
112
  localSaves: true,
113
+ exhaustiveDiscovery: true,
114
+ roomTypes: HOUSE_ROOM_TYPES,
115
+ nameableRoomTypes: HOUSE_NAMEABLE_ROOM_TYPES,
78
116
  async authorize() {
79
117
  return {};
80
118
  },
@@ -97,14 +135,44 @@ export function createSiteAdapter(transport) {
97
135
  const entry = tracked.get(request.locator);
98
136
  if (entry === undefined)
99
137
  return { kind: 'room-not-readable', locator: request.locator };
100
- if (request.pageToken !== undefined)
101
- return UNCERTAIN;
102
- const held = await caughtUp(entry);
103
- if ('failure' in held)
104
- return held.failure;
105
- notifications.reach(entry.authority, held.scope);
106
- const models = await scopeModels(held.scope, entry);
107
- return { ...bootstrapOf(held.scope), ...(models === undefined ? {} : { models }) };
138
+ let continued;
139
+ let inventory;
140
+ if (request.pageToken === undefined) {
141
+ const room = await partedRoom(entry);
142
+ if ('kind' in room)
143
+ return room;
144
+ const { models, seen } = await manifestedModels(room, entry);
145
+ continued = { room, next: 0, seen };
146
+ inventory = partInventory(room);
147
+ if (inventory.parts > 0) {
148
+ return manifested(room, inventory, JSON.stringify(continued), models);
149
+ }
150
+ }
151
+ else
152
+ continued = JSON.parse(request.pageToken);
153
+ const listed = continued.room.parts[continued.next];
154
+ const sent = listed === undefined
155
+ ? { scope: emptyScope(continued.room), frame: null }
156
+ : await fetchedPart(entry, continued.room, listed, request.received, request.arriving);
157
+ if ('kind' in sent)
158
+ return sent;
159
+ const { scope } = sent;
160
+ notifications.reach(entry.authority, scope);
161
+ const next = continued.next + 1;
162
+ const more = next < continued.room.parts.length;
163
+ const seen = [
164
+ ...continued.seen,
165
+ ...(scope.files.some((file) => file.path === entry.schema) ? [entry.schema] : []),
166
+ ];
167
+ const models = await partModels(scope, entry, new Set(seen), !more);
168
+ const { folders: _folders, ...page } = await stepped(bootstrapping(scope));
169
+ return {
170
+ ...page,
171
+ ...(models === undefined ? {} : { models }),
172
+ ...(more ? { pageToken: JSON.stringify({ ...continued, next, seen }) } : {}),
173
+ ...(inventory === undefined ? {} : { inventory }),
174
+ ...(sent.frame === null ? {} : { received: sent.frame }),
175
+ };
108
176
  },
109
177
  async refresh(_authorization, request) {
110
178
  const entry = tracked.get(request.locator);
@@ -112,14 +180,43 @@ export function createSiteAdapter(transport) {
112
180
  return { kind: 'room-not-readable', locator: request.locator };
113
181
  if (request.pageToken !== undefined)
114
182
  return UNCERTAIN;
183
+ if (snapshot) {
184
+ return request.fromRoomVersion === roomVersion(entry)
185
+ ? { kind: 'still-current' }
186
+ : { kind: 'beyond-horizon' };
187
+ }
115
188
  return refreshed(entry, request.fromRoomVersion);
116
189
  },
117
190
  async mutate() {
118
191
  return { kind: 'rejected', affected: {}, code: 'write-grant', fields: {}, retryable: false };
119
192
  },
193
+ async attach() {
194
+ return { kind: 'rejected', code: 'write-grant', fields: {}, retryable: false };
195
+ },
120
196
  async history() {
121
197
  return { kind: 'no-history' };
122
198
  },
199
+ async binary(_authorization, request) {
200
+ const route = fileRoute(request);
201
+ if (typeof route !== 'string')
202
+ return route;
203
+ const read = await transport.download(route);
204
+ if (read.status === 404)
205
+ return unfound();
206
+ return read.status === 200 && read.body !== null
207
+ ? { kind: 'binary', body: read.body, mediaType: read.mediaType }
208
+ : UNCERTAIN;
209
+ },
210
+ async link(_authorization, request) {
211
+ const route = fileRoute(request);
212
+ if (typeof route !== 'string')
213
+ return route;
214
+ return {
215
+ kind: 'link',
216
+ url: route,
217
+ name: request.path.slice(request.path.lastIndexOf('/') + 1),
218
+ };
219
+ },
123
220
  reached(locator, version, target) {
124
221
  return reachedVersion(version, target, tracked.get(locator)?.logEpoch);
125
222
  },
@@ -127,7 +224,7 @@ export function createSiteAdapter(transport) {
127
224
  return followsVersion(version, next);
128
225
  },
129
226
  async action(_authorization, request) {
130
- if (request.name !== 'submit') {
227
+ if (request.name !== SITE_SUBMIT) {
131
228
  return {
132
229
  kind: 'rejected',
133
230
  code: 'action-unimplemented',
@@ -137,22 +234,29 @@ export function createSiteAdapter(transport) {
137
234
  }
138
235
  if (!transport.online())
139
236
  return UNCERTAIN;
140
- return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input), 'submit');
237
+ return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input), SITE_SUBMIT);
141
238
  },
142
- roomStream: {
143
- hold(rooms) {
144
- notifications.send(rooms.flatMap((room) => {
145
- const entry = tracked.get(room.locator);
146
- const at = logPosition(room.roomVersion);
147
- if (entry === undefined || at === null)
148
- return [];
149
- notifications.reach(entry.authority, at);
150
- return [presented(entry.authority, at)];
151
- }));
239
+ roomStream: snapshot
240
+ ? undefined
241
+ : {
242
+ hold(rooms) {
243
+ notifications.send(rooms.flatMap((room) => {
244
+ const entry = tracked.get(room.locator);
245
+ const at = logPosition(room.roomVersion);
246
+ if (entry === undefined || at === null)
247
+ return [];
248
+ notifications.reach(entry.authority, at);
249
+ return [presented(entry.authority, at)];
250
+ }));
251
+ },
252
+ reopen: notifications.reopen,
253
+ observe: notifications.observe,
254
+ published(locator, roomVersion) {
255
+ const at = logPosition(roomVersion);
256
+ if (at !== null)
257
+ notifications.published(locator, at);
258
+ },
152
259
  },
153
- reopen: notifications.reopen,
154
- observe: notifications.observe,
155
- },
156
260
  serviceMode: notifications.serviceMode,
157
261
  };
158
262
  }
package/dist/stream.d.ts CHANGED
@@ -1,21 +1,22 @@
1
- import type { ConversationStream, RefreshPage, RoomStreamEvent, ServiceModeSignal } from '@agentshouse/mdruntime';
1
+ import { type ConversationStream, type RefreshPage, type RoomStreamEvent, type ServiceModeSignal, type StreamReceipts } from '@agentshouse/mdruntime';
2
2
  import type { TrackedAuthority } from './discovery.js';
3
3
  import type { HouseDoor, HouseHeldRoom, HouseMode, HouseStreamEntry } from './transport.js';
4
4
  import { type LogPosition } from './version.js';
5
5
  export type HeldRevision = (path: string, revision: string) => boolean;
6
6
  export type StreamedAdvancement = {
7
7
  page: RefreshPage;
8
- entries: readonly HouseStreamEntry[];
9
8
  schemas: ReadonlyMap<string, HouseStreamEntry>;
10
9
  };
11
10
  export type HouseNotifications = {
12
11
  runtime: string;
13
- observe(notify: (event: RoomStreamEvent) => void): () => void;
12
+ observe(notify: (event: RoomStreamEvent) => void, receipts: StreamReceipts): () => void;
14
13
  send(rooms: readonly HouseHeldRoom[]): void;
14
+ published(locator: string, at: LogPosition): void;
15
15
  reopen(): void;
16
16
  track(authorities: readonly TrackedAuthority[]): void;
17
17
  reach(authority: string, at: LogPosition): void;
18
- advance(tracked: TrackedAuthority, from: LogPosition, holds?: HeldRevision): StreamedAdvancement | null;
18
+ edited(tracked: TrackedAuthority, from: LogPosition): readonly string[];
19
+ advance(tracked: TrackedAuthority, from: LogPosition, holds?: HeldRevision): Generator<number, StreamedAdvancement | null, void>;
19
20
  conversations: ConversationStream;
20
21
  serviceMode: ServiceModeSignal;
21
22
  };
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,kBAAkB,EAElB,WAAW,EACX,eAAe,EAEf,iBAAiB,EAElB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EAEb,SAAS,EAET,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAgB7D,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;AAEvE,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACrC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC9D,IAAI,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAC;IAC5C,MAAM,IAAI,IAAI,CAAC;IACf,KAAK,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACtD,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD,OAAO,CACL,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,WAAW,EACjB,KAAK,CAAC,EAAE,YAAY,GACnB,mBAAmB,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAuBF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,kBAAkB,CAyS5F"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,kBAAkB,EAEvB,KAAK,WAAW,EAChB,KAAK,eAAe,EAEpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEpB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAUvD,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EAEb,SAAS,EAET,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AA0C7D,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;AAEvE,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI,CAAC;IACxF,IAAI,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAC;IAC5C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAClD,MAAM,IAAI,IAAI,CAAC;IACf,KAAK,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACtD,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,MAAM,EAAE,CAAC;IACxE,OAAO,CACL,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,WAAW,EACjB,KAAK,CAAC,EAAE,YAAY,GACnB,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;IACvD,aAAa,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAmFF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,kBAAkB,CA8jB5F"}