@agentshouse/mdruntime-adapter 0.1.0-ca764edcceec6 → 0.1.0-caaa68a6ba2a5

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 (58) hide show
  1. package/README.md +2 -2
  2. package/dist/actions.d.ts +4 -22
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +21 -134
  5. package/dist/adapter.d.ts.map +1 -1
  6. package/dist/adapter.js +280 -170
  7. package/dist/app-reference.d.ts +2 -0
  8. package/dist/app-reference.d.ts.map +1 -0
  9. package/dist/app-reference.js +2 -0
  10. package/dist/crockford.d.ts +4 -0
  11. package/dist/crockford.d.ts.map +1 -0
  12. package/dist/crockford.js +3 -0
  13. package/dist/discovery.d.ts +6 -10
  14. package/dist/discovery.d.ts.map +1 -1
  15. package/dist/discovery.js +38 -34
  16. package/dist/gather.d.ts +1 -1
  17. package/dist/gather.d.ts.map +1 -1
  18. package/dist/gather.js +4 -14
  19. package/dist/house-model.d.ts +2 -0
  20. package/dist/house-model.d.ts.map +1 -0
  21. package/dist/house-model.js +483 -0
  22. package/dist/index.d.ts +7 -2
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +6 -1
  25. package/dist/model.d.ts +5 -1
  26. package/dist/model.d.ts.map +1 -1
  27. package/dist/model.js +11 -13
  28. package/dist/part.d.ts +15 -0
  29. package/dist/part.d.ts.map +1 -0
  30. package/dist/part.js +82 -0
  31. package/dist/read.d.ts +57 -26
  32. package/dist/read.d.ts.map +1 -1
  33. package/dist/read.js +268 -152
  34. package/dist/room-types.d.ts +7 -0
  35. package/dist/room-types.d.ts.map +1 -0
  36. package/dist/room-types.js +125 -0
  37. package/dist/site.d.ts.map +1 -1
  38. package/dist/site.js +82 -105
  39. package/dist/stream.d.ts +5 -5
  40. package/dist/stream.d.ts.map +1 -1
  41. package/dist/stream.js +61 -39
  42. package/dist/transport.d.ts +26 -15
  43. package/dist/transport.d.ts.map +1 -1
  44. package/dist/transport.js +2 -1
  45. package/dist/upload.d.ts +12 -0
  46. package/dist/upload.d.ts.map +1 -0
  47. package/dist/upload.js +63 -0
  48. package/dist/write.d.ts +12 -1
  49. package/dist/write.d.ts.map +1 -1
  50. package/dist/write.js +92 -55
  51. package/package.json +8 -4
  52. package/AGENTS.md +0 -299
  53. package/dist/handed.d.ts +0 -15
  54. package/dist/handed.d.ts.map +0 -1
  55. package/dist/handed.js +0 -38
  56. package/dist/referrer.d.ts +0 -7
  57. package/dist/referrer.d.ts.map +0 -1
  58. package/dist/referrer.js +0 -35
package/dist/transport.js CHANGED
@@ -9,5 +9,6 @@ export const SITE_DOOR_BOOTSTRAP = '/_house/door/bootstrap/';
9
9
  export const SITE_DOOR_ENUMERATE = '/_house/door/enumerate';
10
10
  export const SITE_DOOR_SUBMIT = '/_house/door/submit';
11
11
  export const DOOR_FILES_GET = '/door/files/get';
12
+ export const DOOR_FILES_ATTACH = '/door/files/attach';
13
+ export const DOOR_FILES_FINISH = '/door/files/finish';
12
14
  export const SITE_FILES = '/_house/files/';
13
- export const SITE_FILE_RECORD = 'record';
@@ -0,0 +1,12 @@
1
+ import { type HouseDoorAnswer, type HouseTransport } from './transport.js';
2
+ export type HouseUpload = {
3
+ readonly id: string;
4
+ readonly partBytes: number;
5
+ readonly parts: readonly {
6
+ readonly part: number;
7
+ readonly url: string;
8
+ }[];
9
+ };
10
+ export declare function houseUpload(value: unknown): HouseUpload | null;
11
+ export declare function finishedUpload(transport: HouseTransport, first: HouseUpload, blob: Blob): Promise<HouseDoorAnswer | null>;
12
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE9F,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC5E,CAAC;AAeF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAQ9D;AA8BD,wBAAsB,cAAc,CAClC,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAejC"}
package/dist/upload.js ADDED
@@ -0,0 +1,63 @@
1
+ import { sha256 } from '@agentshouse/mdruntime/digest';
2
+ import { DOOR_FILES_FINISH } from './transport.js';
3
+ const FINISHING_ROUNDS = 24;
4
+ function record(value) {
5
+ return value !== null && typeof value === 'object' ? value : {};
6
+ }
7
+ function part(value) {
8
+ const { part: number, url } = record(value);
9
+ return Number.isSafeInteger(number) && number > 0 && typeof url === 'string'
10
+ ? { part: number, url }
11
+ : null;
12
+ }
13
+ export function houseUpload(value) {
14
+ const { id, part_bytes: partBytes, parts = [] } = record(value);
15
+ if (typeof id !== 'string' || !Number.isSafeInteger(partBytes) || partBytes <= 0)
16
+ return null;
17
+ if (!Array.isArray(parts))
18
+ return null;
19
+ const named = parts.map(part);
20
+ if (named.some((one) => one === null))
21
+ return null;
22
+ return { id, partBytes: partBytes, parts: named };
23
+ }
24
+ function checksum(hex) {
25
+ let bytes = '';
26
+ for (let at = 0; at < hex.length; at += 2)
27
+ bytes += String.fromCharCode(Number.parseInt(hex.slice(at, at + 2), 16));
28
+ return { 'x-amz-checksum-sha256': btoa(bytes) };
29
+ }
30
+ async function partSha256(blob, partBytes) {
31
+ const parts = [];
32
+ for (let start = 0; start === 0 || start < blob.size; start += partBytes)
33
+ parts.push(await sha256(blob.slice(start, start + partBytes)));
34
+ return parts;
35
+ }
36
+ async function sent(transport, upload, blob, digests) {
37
+ for (const { part: number, url } of upload.parts) {
38
+ const start = (number - 1) * upload.partBytes;
39
+ const slice = blob.slice(start, start + upload.partBytes);
40
+ if ((await transport.put(url, slice, checksum(digests[number - 1]))) !== 200)
41
+ return false;
42
+ }
43
+ return true;
44
+ }
45
+ export async function finishedUpload(transport, first, blob) {
46
+ const digests = await partSha256(blob, first.partBytes);
47
+ let upload = first;
48
+ for (let round = 0; round < FINISHING_ROUNDS; round += 1) {
49
+ if (!(await sent(transport, upload, blob, digests)))
50
+ return null;
51
+ const answer = await transport.door(DOOR_FILES_FINISH, {
52
+ upload: upload.id,
53
+ part_sha256: digests,
54
+ });
55
+ if (answer.status !== 200)
56
+ return answer;
57
+ const missing = houseUpload(record(answer.body).upload);
58
+ if (missing === null)
59
+ return answer;
60
+ upload = missing;
61
+ }
62
+ return null;
63
+ }
package/dist/write.d.ts CHANGED
@@ -10,6 +10,7 @@ export type ChangeMapping = {
10
10
  rule: string;
11
11
  };
12
12
  export declare function houseChanges(batch: ChangeBatch, handle: string): ChangeMapping;
13
+ export declare function houseMove(batch: ChangeBatch, source: string, destination: string): ChangeMapping;
13
14
  export type OperationHead = {
14
15
  readonly operation_id: string;
15
16
  readonly app_ref?: string;
@@ -21,7 +22,17 @@ export declare function deltaBody(changes: readonly HouseOperation[]): string;
21
22
  export declare function deltaBytes(delta: string): number;
22
23
  export declare function uploadable(inline: Readonly<Record<string, unknown>>, bytes: number, bounds: Pick<HouseBounds, 'max_inline_body_bytes' | 'max_upload_bytes'>): boolean;
23
24
  export declare function deltaDigest(delta: string): Promise<string>;
24
- export declare function mutationOutcome(status: number, body: unknown, locator: string, handle: string): MutationResult;
25
+ export type MoveAuthorities = {
26
+ readonly source: {
27
+ readonly authority: string;
28
+ readonly handle: string;
29
+ };
30
+ readonly destination: {
31
+ readonly authority: string;
32
+ readonly handle: string;
33
+ };
34
+ };
35
+ export declare function mutationOutcome(status: number, body: unknown, locator: string, handle: string, move?: MoveAuthorities): Generator<number, MutationResult, void>;
25
36
  export declare function rejectedMapping(mapping: Extract<ChangeMapping, {
26
37
  kind: 'unmapped';
27
38
  }>): {
@@ -1 +1 @@
1
- {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../src/write.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EAEhB,KAAK,aAAa,EAElB,KAAK,cAAc,EAEpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAOlD,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE/D,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAwHrD,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAQ9E;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAK/D;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,MAAM,EAAE,CAQhF;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAEpE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,uBAAuB,GAAG,kBAAkB,CAAC,GACtE,OAAO,CAKT;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE1D;AAiDD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,cAAc,CAmFhB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;IAEjF,IAAI,EAAE,UAAU;IAChB,QAAQ;IACR,IAAI;IACJ,MAAM;QAAI,IAAI;;IACd,SAAS;EAEZ;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAM1B;AA4BD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C,aAAa,CAyDf"}
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../src/write.ts"],"names":[],"mappings":"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"}
package/dist/write.js CHANGED
@@ -1,5 +1,5 @@
1
- import { departure, } from '@agentshouse/mdruntime';
2
- import { binaryFileOf, headChange, identities } from './read.js';
1
+ import { departure, ROW_WEIGHT, } from '@agentshouse/mdruntime';
2
+ import { answered, answering, binaryFileOf, headChange, revised } from './read.js';
3
3
  import { sha256Hex, textBytes } from './digest.js';
4
4
  import { nativePath, roomLocalPath } from './map.js';
5
5
  import { classifyDoor, doorRefusal, scopedRefusal } from './refusal.js';
@@ -120,6 +120,24 @@ export function houseChanges(batch, handle) {
120
120
  }
121
121
  return { kind: 'changes', changes };
122
122
  }
123
+ export function houseMove(batch, source, destination) {
124
+ const changes = [];
125
+ for (const { path, to } of batch.between?.moves ?? []) {
126
+ const existence = priorExistence(batch, path);
127
+ if (existence === undefined)
128
+ return { kind: 'unmapped', path, rule: 'precondition-missing' };
129
+ if (!('base' in existence)) {
130
+ return { kind: 'unmapped', path, rule: 'presence-base-unrepresentable' };
131
+ }
132
+ changes.push({
133
+ op: 'rename',
134
+ path: nativePath(path, source),
135
+ to: nativePath(to, destination),
136
+ base: existence.base,
137
+ });
138
+ }
139
+ return { kind: 'changes', changes };
140
+ }
123
141
  export function operationHead(batch) {
124
142
  const writer = batch.writtenBy;
125
143
  return writer === undefined
@@ -129,7 +147,7 @@ export function operationHead(batch) {
129
147
  export function batchPaths(changes) {
130
148
  return [
131
149
  ...new Set(changes.flatMap((change) => change.op === 'rename' ? [String(change.path), String(change.to)] : [String(change.path)])),
132
- ].sort();
150
+ ];
133
151
  }
134
152
  export function deltaBody(changes) {
135
153
  return JSON.stringify({ changes });
@@ -144,16 +162,19 @@ export function uploadable(inline, bytes, bounds) {
144
162
  export function deltaDigest(delta) {
145
163
  return sha256Hex(delta);
146
164
  }
147
- function material(value, handle) {
165
+ function* material(value, handle, within = () => true) {
148
166
  if (!Array.isArray(value))
149
167
  return null;
150
168
  const held = [];
151
169
  for (const entry of value) {
170
+ yield ROW_WEIGHT;
152
171
  if (typeof entry !== 'object' || entry === null)
153
172
  return null;
154
173
  const file = entry;
155
174
  if (typeof file.path !== 'string')
156
175
  return null;
176
+ if (!within(file.path))
177
+ continue;
157
178
  if (file.content !== null && typeof file.content !== 'string')
158
179
  return null;
159
180
  if (file.revision !== null && file.revision !== undefined && typeof file.revision !== 'string')
@@ -181,15 +202,59 @@ function material(value, handle) {
181
202
  }
182
203
  return held;
183
204
  }
184
- function affectedOf(held) {
205
+ function* affectedOf(held) {
185
206
  const affected = {};
186
207
  for (const entry of held) {
187
208
  if (entry.content !== null)
188
209
  affected[entry.path] = entry.content;
210
+ yield ROW_WEIGHT;
189
211
  }
190
212
  return affected;
191
213
  }
192
- export function mutationOutcome(status, body, locator, handle) {
214
+ function* acceptedOf(at, contents) {
215
+ const answer = answering();
216
+ for (const entry of contents) {
217
+ yield ROW_WEIGHT + (entry.content?.length ?? 0);
218
+ if (entry.revision === null) {
219
+ answer.removals.add(entry.path);
220
+ continue;
221
+ }
222
+ if (entry.content !== null)
223
+ answer.documents.set(entry.path, entry.content);
224
+ if (entry.binary !== undefined)
225
+ answer.binaryFiles.set(entry.path, entry.binary);
226
+ revised(answer, entry.path, entry.revision);
227
+ if (entry.head !== undefined)
228
+ answer.changes.set(entry.path, entry.head);
229
+ }
230
+ const unbinaried = answer.binaryFiles.size === 0;
231
+ const { binaryFiles, ...room } = yield* answered(answer);
232
+ return { roomVersion: roomVersion(at), ...room, ...(unbinaried ? {} : { binaryFiles }) };
233
+ }
234
+ function* movedOutcome(held, move) {
235
+ const authorities = Array.isArray(held.authorities) ? held.authorities : [];
236
+ const at = (authority) => {
237
+ const entry = authorities.find((one) => typeof one === 'object' &&
238
+ one !== null &&
239
+ one.authority === authority);
240
+ return entry === undefined ? null : readPosition(entry);
241
+ };
242
+ const left = at(move.source.authority);
243
+ const arrived = at(move.destination.authority);
244
+ if (left === null || arrived === null)
245
+ return { kind: 'transport-uncertainty' };
246
+ const under = (handle) => (path) => path.startsWith(`/rooms/${handle}/`);
247
+ const leaving = yield* material(held.contents, move.source.handle, under(move.source.handle));
248
+ const arriving = yield* material(held.contents, move.destination.handle, under(move.destination.handle));
249
+ if (leaving === null || arriving === null)
250
+ return { kind: 'transport-uncertainty' };
251
+ return {
252
+ kind: 'accepted',
253
+ ...(yield* acceptedOf(left, leaving)),
254
+ destination: yield* acceptedOf(arrived, arriving),
255
+ };
256
+ }
257
+ export function* mutationOutcome(status, body, locator, handle, move) {
193
258
  const refusal = doorRefusal(body);
194
259
  if (refusal !== null && refusal.code === 'service_mode_write_halted') {
195
260
  return { kind: 'write-halted' };
@@ -201,10 +266,10 @@ export function mutationOutcome(status, body, locator, handle) {
201
266
  }
202
267
  if (refusal !== null && refusal.code === 'edit_conflict') {
203
268
  const { current, ...fields } = refusal.fields;
204
- const held = material(current, handle) ?? [];
269
+ const held = (yield* material(current, handle)) ?? [];
205
270
  return {
206
271
  kind: 'conflicted',
207
- affected: affectedOf(held),
272
+ affected: yield* affectedOf(held),
208
273
  code: refusal.code,
209
274
  fields,
210
275
  retryable: refusal.retryable,
@@ -228,8 +293,9 @@ export function mutationOutcome(status, body, locator, handle) {
228
293
  }
229
294
  if (classified !== null && classified.kind !== 'scoped-refusal')
230
295
  return classified;
231
- if (classified !== null && status === 403)
296
+ if (classified !== null && status === 403 && refusal?.code === 'operation_denied') {
232
297
  return classified;
298
+ }
233
299
  if (refusal !== null && status >= 400) {
234
300
  return {
235
301
  kind: 'rejected',
@@ -243,40 +309,15 @@ export function mutationOutcome(status, body, locator, handle) {
243
309
  return { kind: 'transport-uncertainty' };
244
310
  }
245
311
  const held = body;
312
+ if (move !== undefined)
313
+ return yield* movedOutcome(held, move);
246
314
  const at = readPosition(held);
247
315
  if (at === null)
248
316
  return { kind: 'transport-uncertainty' };
249
- const contents = material(held.contents, handle);
317
+ const contents = yield* material(held.contents, handle);
250
318
  if (contents === null)
251
319
  return { kind: 'transport-uncertainty' };
252
- const documents = {};
253
- const revisions = {};
254
- const changes = {};
255
- const binaryFiles = {};
256
- const removals = [];
257
- for (const entry of contents) {
258
- if (entry.revision === null) {
259
- removals.push(entry.path);
260
- continue;
261
- }
262
- if (entry.content !== null)
263
- documents[entry.path] = entry.content;
264
- if (entry.binary !== undefined)
265
- binaryFiles[entry.path] = entry.binary;
266
- revisions[entry.path] = entry.revision;
267
- if (entry.head !== undefined)
268
- changes[entry.path] = entry.head;
269
- }
270
- return {
271
- kind: 'accepted',
272
- roomVersion: roomVersion(at),
273
- documents,
274
- revisions,
275
- ...identities(revisions),
276
- changes,
277
- removals: removals.sort(),
278
- ...(Object.keys(binaryFiles).length === 0 ? {} : { binaryFiles }),
279
- };
320
+ return { kind: 'accepted', ...(yield* acceptedOf(at, contents)) };
280
321
  }
281
322
  export function rejectedMapping(mapping) {
282
323
  return {
@@ -297,26 +338,22 @@ export function revisionBody(input) {
297
338
  function revisionAuthor(entry) {
298
339
  const user = entry.author_user;
299
340
  const site = entry.author_site;
300
- const name = entry.author_site_name;
301
- if (typeof user === 'string' && site === undefined && name === undefined) {
341
+ const siteName = entry.author_site_name;
342
+ const inbox = entry.author_inbox;
343
+ const inboxName = entry.author_inbox_name;
344
+ const named = [site, siteName, inbox, inboxName].filter((held) => held !== undefined);
345
+ if (typeof user === 'string' && named.length === 0)
302
346
  return { kind: 'user', id: user };
347
+ if (user !== null || named.length !== 2)
348
+ return null;
349
+ if (typeof site === 'string' && typeof siteName === 'string') {
350
+ return { kind: 'site', id: site, name: siteName };
303
351
  }
304
- if (user === null && typeof site === 'string' && typeof name === 'string') {
305
- return { kind: 'site', id: site, name };
352
+ if (typeof inbox === 'string' && typeof inboxName === 'string') {
353
+ return { kind: 'inbox', id: inbox, name: inboxName };
306
354
  }
307
355
  return null;
308
356
  }
309
- function historyBinary(entry) {
310
- if (entry.file === undefined)
311
- return undefined;
312
- const { file, bytes, media_type: mediaType, sha256 } = entry;
313
- if (typeof file !== 'string' ||
314
- typeof bytes !== 'number' ||
315
- typeof mediaType !== 'string' ||
316
- typeof sha256 !== 'string')
317
- return null;
318
- return { fileRef: file, byteLength: bytes, mediaType, sha256 };
319
- }
320
357
  export function historyOutcome(status, body, locator, request) {
321
358
  const classified = classifyDoor(status, body, locator);
322
359
  if (classified !== null)
@@ -347,7 +384,7 @@ export function historyOutcome(status, body, locator, request) {
347
384
  retryable: false,
348
385
  };
349
386
  }
350
- if (typeof named.file === 'string')
387
+ if (typeof named.media_type === 'string')
351
388
  return { kind: 'no-history' };
352
389
  if (typeof named.content !== 'string')
353
390
  return { kind: 'transport-uncertainty' };
@@ -363,7 +400,7 @@ export function historyOutcome(status, body, locator, request) {
363
400
  typeof entry.created_at !== 'string') {
364
401
  return { kind: 'transport-uncertainty' };
365
402
  }
366
- const binaryFile = historyBinary(entry);
403
+ const binaryFile = binaryFileOf(entry);
367
404
  if (binaryFile === null)
368
405
  return { kind: 'transport-uncertainty' };
369
406
  revisions.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentshouse/mdruntime-adapter",
3
- "version": "0.1.0-ca764edcceec6",
3
+ "version": "0.1.0-caaa68a6ba2a5",
4
4
  "description": "Agents House Adapter for the MD Runtime",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,7 +9,7 @@
9
9
  "access": "public"
10
10
  },
11
11
  "engines": {
12
- "node": ">=24.21.0"
12
+ "node": ">=24.22.1"
13
13
  },
14
14
  "exports": {
15
15
  ".": {
@@ -20,11 +20,15 @@
20
20
  },
21
21
  "files": [
22
22
  "dist",
23
- "AGENTS.md",
24
23
  "README.md",
25
24
  "LICENSE"
26
25
  ],
27
26
  "dependencies": {
28
- "@agentshouse/mdruntime": "0.1.0-c6fd2cbbff187"
27
+ "@agentshouse/mdruntime": "0.1.0-cf5a27915a9b1"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/agentshouse/core.git",
32
+ "directory": "mdruntime/packages/mdruntime-adapter"
29
33
  }
30
34
  }