@mengine/medeo-tool 2.0.1-alpha.6 → 2.0.1-alpha.7

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.
package/dist/index.d.mts CHANGED
@@ -11,6 +11,14 @@ import { JournalEntry, ManualSyncDoc, MediaAssetFact, PartIdFactory, SemanticOpN
11
11
  * `fromVideoDocument`.
12
12
  */
13
13
  interface CompactProjectionOptions {
14
+ /**
15
+ * Document identity for the header. Stated by the caller: the document
16
+ * content no longer carries its own id or revision (business metadata left
17
+ * the CRDT), and the model needs to know which draft this summary describes.
18
+ * Omitted values keep the header's fixed shape with the historical blanks.
19
+ */
20
+ docId?: string;
21
+ revision?: number;
14
22
  /** Only render these parts (header still reports the full timeline total). Default = all. */
15
23
  onlyPartIds?: ReadonlySet<string>;
16
24
  /** Caption text preview truncation length. Default 24. */
@@ -30,7 +38,10 @@ declare function collectAffectedPartIds(journal: readonly JournalEntry[]): Set<s
30
38
  * Render a ChangePlan preview: header + rows for journal-affected parts only.
31
39
  * Empty journal → empty `onlyPartIds` (header alone), matching the T2 contract.
32
40
  */
33
- declare function renderPreview(document: VideoDocument, journal: readonly JournalEntry[]): string;
41
+ declare function renderPreview(document: VideoDocument, journal: readonly JournalEntry[], identity?: {
42
+ docId?: string;
43
+ revision?: number;
44
+ }): string;
34
45
  //#endregion
35
46
  //#region src/entity/entity-asset.d.ts
36
47
  /** Immutable resource content resolved by the host for a document Entity. */
@@ -63,6 +74,12 @@ interface ChangePlan {
63
74
  logs: string[];
64
75
  }
65
76
  interface EditSandboxSessionOptions {
77
+ /**
78
+ * Document this session edits. Stated by the host: the document content no
79
+ * longer carries its own identity (business metadata left the CRDT), and a
80
+ * plan must name the document it will be committed against.
81
+ */
82
+ docId?: string;
66
83
  idFactory?: PartIdFactory;
67
84
  onEntry?: (entry: JournalEntry) => void;
68
85
  onLog?: (line: string) => void;
@@ -89,6 +106,8 @@ interface ConsoleShim {
89
106
  * injects loaders that break worker boot.
90
107
  */
91
108
  interface RunEditScriptOptions {
109
+ /** Document the plan will be committed against; stated by the host. */
110
+ docId: string;
92
111
  loadEntityAsset?: (entity: SandboxEntity) => Promise<EntityAssetContent>;
93
112
  writeEntityAsset?: (entity: SandboxEntity, content: EntityAssetContent['content']) => Promise<EntityAssetContent>;
94
113
  document: VideoDocument;
@@ -379,13 +398,6 @@ interface CreateMedeoToolOptions {
379
398
  userId?: ContextualValue<string>;
380
399
  /** Stable agent peer id. Supply a host-scoped value so audit provenance is durable. */
381
400
  peerId?: ContextualValue<string>;
382
- /**
383
- * Load the authoritative legacy draft used to create a missing Mengine
384
- * document. The tool owns the get-or-create flow: it first probes Mengine,
385
- * converts this draft into a VideoDocument only on a 404, bootstraps the
386
- * snapshot, and tolerates a concurrent creator winning the race.
387
- */
388
- loadInitialDraft?: (docId: string) => Promise<VideoDraft>;
389
401
  /**
390
402
  * Resolve factual generation lineage by external asset id after a confirmed
391
403
  * entity commit. Return every known generation record involving the given
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { c as isMediaAssetVariantKind, i as businessState, o as createEntityId, s as createRelationId, t as EntitySandbox } from "./entity-sandbox-DSFbfybl.mjs";
2
- import { LoroEntityDocument, ManualSyncDoc, MengineHttpClient, MengineHttpRequestError, ValidationError, base64ToBytes, bytesToBase64, compileEntityRows, createMirrorVideoDocument, createPlainMemoryAdapter, decodeDocVersionMark, effectiveVideoClipDurationMs, encodeDocVersionMark, ensureEditorFoundation, replayJournal, solveVideoDocument, speedOf, toVideoDocument } from "@mengine/medeo-client";
2
+ import { ManualSyncDoc, MengineHttpClient, ValidationError, base64ToBytes, bytesToBase64, compileEntityRows, createPlainMemoryAdapter, decodeDocVersionMark, effectiveVideoClipDurationMs, encodeDocVersionMark, replayJournal, solveVideoDocument, speedOf } from "@mengine/medeo-client";
3
3
  import { Worker } from "node:worker_threads";
4
4
  import { createHash, randomUUID } from "node:crypto";
5
5
  //#region src/document/compact-projection.ts
@@ -79,7 +79,7 @@ function renderCompactProjection(document, options) {
79
79
  rows.push(`${tag} ${partId} ${lane} [${abs},${abs + dur}) ${attrs}`);
80
80
  }
81
81
  }
82
- return [`# draft=${document.meta.draft_id ?? ""} v=${document.meta.version ?? 0} duration=${solved.durationMs} parts=${totalParts} shown=${rows.length}`, ...rows].join("\n");
82
+ return [`# draft=${options?.docId ?? ""} v=${options?.revision ?? 0} duration=${solved.durationMs} parts=${totalParts} shown=${rows.length}`, ...rows].join("\n");
83
83
  }
84
84
  //#endregion
85
85
  //#region src/sandbox/preview.ts
@@ -132,8 +132,12 @@ function collectFromValue(value, ids) {
132
132
  * Render a ChangePlan preview: header + rows for journal-affected parts only.
133
133
  * Empty journal → empty `onlyPartIds` (header alone), matching the T2 contract.
134
134
  */
135
- function renderPreview(document, journal) {
136
- return renderCompactProjection(document, { onlyPartIds: journal.length === 0 ? /* @__PURE__ */ new Set() : collectAffectedPartIds(journal) });
135
+ function renderPreview(document, journal, identity) {
136
+ const onlyPartIds = journal.length === 0 ? /* @__PURE__ */ new Set() : collectAffectedPartIds(journal);
137
+ return renderCompactProjection(document, {
138
+ ...identity,
139
+ onlyPartIds
140
+ });
137
141
  }
138
142
  //#endregion
139
143
  //#region src/sandbox/node-host.ts
@@ -165,6 +169,7 @@ function runEditScript(options) {
165
169
  let timer;
166
170
  const worker = new Worker(workerEntryUrl, {
167
171
  workerData: {
172
+ docId: options.docId,
168
173
  document: options.document,
169
174
  script: options.script,
170
175
  inputs: options.inputs,
@@ -275,7 +280,7 @@ function runEditScript(options) {
275
280
  ok: true,
276
281
  plan: {
277
282
  plan_kind: message.planKind,
278
- doc_id: options.document.meta.draft_id ?? "",
283
+ doc_id: options.docId,
279
284
  base_version: options.baseVersion,
280
285
  ops: ops.slice(),
281
286
  ...message.loroUpdate ? { loro_update: message.loroUpdate } : {},
@@ -1218,7 +1223,7 @@ async function commitPlan(doc, plan, options) {
1218
1223
  * integrity throws are not wrapped.
1219
1224
  */
1220
1225
  async function commitPlanPreflight(doc, plan) {
1221
- const scratch = createPlainMemoryAdapter(doc.snapshot());
1226
+ const scratch = createPlainMemoryAdapter(doc.snapshot(), { readOnly: doc.isEntityDocument() });
1222
1227
  for (let index = 0; index < plan.ops.length; index++) {
1223
1228
  const entry = plan.ops[index];
1224
1229
  if (entry == null) continue;
@@ -1410,13 +1415,13 @@ function createMedeoTool(options) {
1410
1415
  const existing = documents.get(docId);
1411
1416
  if (existing != null) return await existing;
1412
1417
  const created = (async () => {
1413
- return await getOrCreateDocument(new MengineHttpClient({
1418
+ return await openDocument(new MengineHttpClient({
1414
1419
  docId,
1415
1420
  httpOrigin: requiredContext(options.httpOrigin, docId, "httpOrigin"),
1416
1421
  ...options.authToken !== void 0 ? { authToken: () => optionalContext(options.authToken, docId) } : {},
1417
1422
  ...options.userId !== void 0 ? { userId: () => optionalContext(options.userId, docId) } : {},
1418
1423
  ...options.fetchImpl !== void 0 ? { fetchImpl: options.fetchImpl } : {}
1419
- }), docId, optionalContext(options.peerId, docId));
1424
+ }), optionalContext(options.peerId, docId));
1420
1425
  })();
1421
1426
  documents.set(docId, created);
1422
1427
  try {
@@ -1456,36 +1461,14 @@ function createMedeoTool(options) {
1456
1461
  if (documentTails.get(docId) === tail) documentTails.delete(docId);
1457
1462
  }
1458
1463
  }
1459
- async function getOrCreateDocument(client, docId, peerId) {
1460
- try {
1461
- return await ManualSyncDoc.open({
1462
- client,
1463
- ...peerId !== void 0 ? { peerId } : {}
1464
- });
1465
- } catch (error) {
1466
- if (!(error instanceof MengineHttpRequestError) || error.status !== 404) throw error;
1467
- if (options.loadInitialDraft === void 0) throw error;
1468
- }
1469
- const document = toVideoDocument(await options.loadInitialDraft(docId));
1470
- if (Object.keys(document.part_library ?? {}).length > 0) throw new Error("Legacy content cannot bootstrap a Loro entity project");
1471
- const seed = createMirrorVideoDocument(document, {
1472
- ...peerId !== void 0 ? { peerId } : {},
1473
- origin: "mengine.medeo_tool.bootstrap"
1474
- });
1475
- const foundation = ensureEditorFoundation({
1476
- entities: [],
1477
- relations: []
1478
- });
1479
- const entities = LoroEntityDocument.create(foundation.rows, {
1480
- timelineEntityId: foundation.timelineEntityId,
1481
- audioScriptEntityId: foundation.audioScriptEntityId
1482
- });
1483
- seed.import(entities.doc.export({ mode: "snapshot" }));
1484
- try {
1485
- await client.bootstrapSnapshot(seed.export({ mode: "snapshot" }));
1486
- } catch (error) {
1487
- if (!(error instanceof MengineHttpRequestError) || error.status !== 400) throw error;
1488
- }
1464
+ /**
1465
+ * Open an existing Mengine document. Creation belongs to Director, which
1466
+ * initializes every project's document (`POST .../initialize`) before any
1467
+ * agent edit; Mengine's `bootstrap` is the internal Legacy-migration route
1468
+ * and is deliberately absent from the client SDK. A 404 here is a real
1469
+ * missing document, not something this tool may paper over.
1470
+ */
1471
+ async function openDocument(client, peerId) {
1489
1472
  return await ManualSyncDoc.open({
1490
1473
  client,
1491
1474
  ...peerId !== void 0 ? { peerId } : {}
@@ -1657,6 +1640,7 @@ function createMedeoTool(options) {
1657
1640
  const document = doc.snapshot();
1658
1641
  const baseVersion = encodeDocVersionMark(doc.versionMark());
1659
1642
  const result = await runEditScript({
1643
+ docId: input.doc_id,
1660
1644
  document,
1661
1645
  baseVersion,
1662
1646
  entityState,