@motionharness/bridge-davinci 0.0.23 → 0.0.25

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/runner.mjs CHANGED
@@ -1621,7 +1621,7 @@ import { spawn as spawn2 } from "node:child_process";
1621
1621
  import { closeSync, fstatSync, statSync, writeSync } from "node:fs";
1622
1622
  import { Socket } from "node:net";
1623
1623
  import { open as open5, mkdir as mkdir9, readFile as readFile11, writeFile as writeFile2, copyFile as copyFile4, realpath as realpath6, stat as stat7 } from "node:fs/promises";
1624
- import { basename as basename5, dirname as dirname9, join as join9, resolve as resolve11, sep as sep2 } from "node:path";
1624
+ import { basename as basename5, dirname as dirname10, join as join9, resolve as resolve11, sep as sep2 } from "node:path";
1625
1625
  import { fileURLToPath as fileURLToPath2 } from "node:url";
1626
1626
 
1627
1627
  // ../../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
@@ -15497,7 +15497,7 @@ async function runBytes(executable, args, options = {}) {
15497
15497
  child.kill("SIGINT");
15498
15498
  const grace = options.graceMs ?? 1e4;
15499
15499
  termTimer = setTimeout(() => {
15500
- failure = new BridgeError("PROCESS_OUTCOME_UNKNOWN", "\u5B50\u8FDB\u7A0B\u672A\u786E\u8BA4\u6B63\u5E38\u53D6\u6D88\uFF0C\u5DF2\u7EC8\u6B62\u672C\u4EFB\u52A1\u62E5\u6709\u7684\u8FDB\u7A0B\uFF1BMotion Harness \u5BBF\u4E3B\u7ED3\u679C\u9700\u6838\u5BF9\u3002", "process");
15500
+ failure = new BridgeError("PROCESS_OUTCOME_UNKNOWN", "\u5B50\u8FDB\u7A0B\u672A\u786E\u8BA4\u6B63\u5E38\u53D6\u6D88\uFF0C\u5DF2\u7EC8\u6B62\u672C\u4EFB\u52A1\u62E5\u6709\u7684\u8FDB\u7A0B\uFF1BMotionHarness \u5BBF\u4E3B\u7ED3\u679C\u9700\u6838\u5BF9\u3002", "process");
15501
15501
  child.kill("SIGTERM");
15502
15502
  }, grace);
15503
15503
  killTimer = setTimeout(() => child.kill("SIGKILL"), grace * 2);
@@ -16282,7 +16282,7 @@ function observeState(raw, cliVersion, sdkVersion, dependencyHash) {
16282
16282
  const parsed = inspectSchema.safeParse(raw);
16283
16283
  if (!parsed.success) throw new BridgeError("MH_CONTRACT_UNSUPPORTED", "mh inspect \u8FD4\u56DE\u7684\u516C\u5171\u5B57\u6BB5\u4E0D\u7B26\u5408\u5DF2\u5B9E\u73B0\u7684\u9002\u914D\u5951\u7EA6\u3002", "inspect", false, { issues: parsed.error.issues });
16284
16284
  const data = parsed.data;
16285
- assert2(data.sourceCurrent && !data.preparing && !data.error && !data.migration && !data.documentConflict && !data.lifecycle?.saveError, "BUILD_FAILED", "Motion Harness \u6E90\u7801\u3001\u6784\u5EFA\u3001\u4FDD\u5B58\u6216\u8FC1\u79FB\u72B6\u6001\u5C1A\u672A\u5C31\u7EEA\u3002", { sourceCurrent: data.sourceCurrent, preparing: data.preparing, diagnostic: data.error, migration: data.migration, documentConflict: data.documentConflict, saveError: data.lifecycle?.saveError });
16285
+ assert2(data.sourceCurrent && !data.preparing && !data.error && !data.migration && !data.documentConflict && !data.lifecycle?.saveError, "BUILD_FAILED", "MotionHarness \u6E90\u7801\u3001\u6784\u5EFA\u3001\u4FDD\u5B58\u6216\u8FC1\u79FB\u72B6\u6001\u5C1A\u672A\u5C31\u7EEA\u3002", { sourceCurrent: data.sourceCurrent, preparing: data.preparing, diagnostic: data.error, migration: data.migration, documentConflict: data.documentConflict, saveError: data.lifecycle?.saveError });
16286
16286
  const { revision: _revision, ...document } = data.document;
16287
16287
  const assets = data.sourceAssets.map((a) => ({ hash: a.$asset, kind: a.kind })).sort((a, b) => a.hash.localeCompare(b.hash));
16288
16288
  const audioPresent = Object.values(data.document.instances).some((instance) => data.schema.components[instance.componentId]?.audio != null);
@@ -16312,7 +16312,7 @@ var MhAdapter = class {
16312
16312
  return resolved;
16313
16313
  } catch (error48) {
16314
16314
  if (error48 instanceof BridgeError) throw error48;
16315
- throw new BridgeError("SOURCE_MISSING", "Motion Harness \u5DE5\u7A0B\u6216 package.json / pnpm-lock.yaml \u4E0D\u5B58\u5728\u3002", "inspect", false, {}, "\u6307\u5B9A\u5B8C\u6574\u7684 Motion Harness \u5DE5\u7A0B\u76EE\u5F55\uFF1B\u901A\u8FC7\u516C\u5F00 mh unpack \u6062\u590D\u5DE5\u7A0B\u3002");
16315
+ throw new BridgeError("SOURCE_MISSING", "MotionHarness \u5DE5\u7A0B\u6216 package.json / pnpm-lock.yaml \u4E0D\u5B58\u5728\u3002", "inspect", false, {}, "\u6307\u5B9A\u5B8C\u6574\u7684 MotionHarness \u5DE5\u7A0B\u76EE\u5F55\uFF1B\u901A\u8FC7\u516C\u5F00 mh unpack \u6062\u590D\u5DE5\u7A0B\u3002");
16316
16316
  }
16317
16317
  }
16318
16318
  async json(args, project, signal, timeoutMs) {
@@ -16321,7 +16321,7 @@ var MhAdapter = class {
16321
16321
  return parseJson(result2.stdout);
16322
16322
  } catch (error48) {
16323
16323
  if (error48 instanceof BridgeError && String(error48.details.stderr).includes("incompatible with this CLI")) {
16324
- throw new BridgeError("MH_DAEMON_VERSION_CONFLICT", "Motion Harness CLI \u4E0E\u5F53\u524D\u8FD0\u884C\u7684 daemon \u7248\u672C\u4E0D\u4E00\u81F4\uFF0C\u672A\u505C\u6B62\u73B0\u6709\u4F1A\u8BDD\u3002", "mh", false, { executable: this.executable, diagnostic: error48.details.stderr }, "\u4F7F\u7528\u4E0E\u5F53\u524D\u5BBF\u4E3B\u5339\u914D\u7684\u4E3B Motion Harness CLI\uFF1B\u5982\u9700\u91CD\u542F\u5BF9\u5E94 daemon\uFF0C\u5148\u4FDD\u5B58\u5E76\u5904\u7406\u73B0\u6709\u4F1A\u8BDD\uFF0C\u6865\u63A5\u4E0D\u4F1A\u81EA\u52A8\u505C\u6B62\u5B83\u4EEC\u3002");
16324
+ throw new BridgeError("MH_DAEMON_VERSION_CONFLICT", "MotionHarness CLI \u4E0E\u5F53\u524D\u8FD0\u884C\u7684 daemon \u7248\u672C\u4E0D\u4E00\u81F4\uFF0C\u672A\u505C\u6B62\u73B0\u6709\u4F1A\u8BDD\u3002", "mh", false, { executable: this.executable, diagnostic: error48.details.stderr }, "\u4F7F\u7528\u4E0E\u5F53\u524D\u5BBF\u4E3B\u5339\u914D\u7684\u4E3B MotionHarness CLI\uFF1B\u5982\u9700\u91CD\u542F\u5BF9\u5E94 daemon\uFF0C\u5148\u4FDD\u5B58\u5E76\u5904\u7406\u73B0\u6709\u4F1A\u8BDD\uFF0C\u6865\u63A5\u4E0D\u4F1A\u81EA\u52A8\u505C\u6B62\u5B83\u4EEC\u3002");
16325
16325
  }
16326
16326
  throw error48;
16327
16327
  }
@@ -16416,7 +16416,7 @@ var MhAdapter = class {
16416
16416
  async plan(path, spec, sourceDuration) {
16417
16417
  const plan = await this.json(["render", "plan", "--json", JSON.stringify(this.renderOptions(spec, sourceDuration))], path);
16418
16418
  const result2 = external_exports.object({ frameCount: external_exports.number().int().positive(), request: external_exports.object({ width: external_exports.number(), height: external_exports.number(), fps: external_exports.number(), start: external_exports.number(), duration: external_exports.number() }).passthrough() }).parse(plan);
16419
- assert2(result2.frameCount === spec.frameCount, "OUTPUT_SPEC_MISMATCH", "Motion Harness \u91C7\u6837\u8BA1\u5212\u5E27\u6570\u4E0E\u6865\u63A5\u8BF7\u6C42\u4E0D\u4E00\u81F4\u3002");
16419
+ assert2(result2.frameCount === spec.frameCount, "OUTPUT_SPEC_MISMATCH", "MotionHarness \u91C7\u6837\u8BA1\u5212\u5E27\u6570\u4E0E\u6865\u63A5\u8BF7\u6C42\u4E0D\u4E00\u81F4\u3002");
16420
16420
  return result2;
16421
16421
  }
16422
16422
  renderOptions(spec, sourceDuration) {
@@ -16468,9 +16468,9 @@ var MhAdapter = class {
16468
16468
  const result2 = external_exports.object({ id: external_exports.string(), rendered: external_exports.literal(true), saved: external_exports.literal(true), output: external_exports.string(), format: external_exports.enum(["mp4", "mov"]), progress: external_exports.object({ completed: external_exports.number(), total: external_exports.number() }) }).parse(rendered);
16469
16469
  assert2(result2.format === (spec.format ?? "mp4"), "RENDER_RECEIPT_MISMATCH", "\u5BFC\u51FA\u6587\u4EF6\u683C\u5F0F\u4E0E\u8BF7\u6C42\u4E0D\u4E00\u81F4\u3002");
16470
16470
  const checked = renderStatusSchema.safeParse(await this.json(["render", "status"], path));
16471
- if (!checked.success) throw new BridgeError("MH_RENDER_STATUS_UNVERIFIED", "Motion Harness \u672A\u786E\u8BA4\u672C\u6B21\u6E32\u67D3\u5DF2\u5B8C\u6210\u3001\u4FDD\u5B58\u5E76\u91CA\u653E\u8D44\u6E90\u3002", "render", false, { issues: checked.error.issues }, "\u4FDD\u7559\u539F\u4EFB\u52A1\u548C\u4EA7\u7269\uFF0C\u901A\u8FC7\u516C\u5F00 mh render status \u6838\u5BF9\u72B6\u6001\uFF1B\u672A\u6838\u5B9E\u524D\u4E0D\u5C06\u6587\u4EF6\u6807\u8BB0\u4E3A\u5DF2\u9A8C\u8BC1\u7248\u672C\u3002");
16471
+ if (!checked.success) throw new BridgeError("MH_RENDER_STATUS_UNVERIFIED", "MotionHarness \u672A\u786E\u8BA4\u672C\u6B21\u6E32\u67D3\u5DF2\u5B8C\u6210\u3001\u4FDD\u5B58\u5E76\u91CA\u653E\u8D44\u6E90\u3002", "render", false, { issues: checked.error.issues }, "\u4FDD\u7559\u539F\u4EFB\u52A1\u548C\u4EA7\u7269\uFF0C\u901A\u8FC7\u516C\u5F00 mh render status \u6838\u5BF9\u72B6\u6001\uFF1B\u672A\u6838\u5B9E\u524D\u4E0D\u5C06\u6587\u4EF6\u6807\u8BB0\u4E3A\u5DF2\u9A8C\u8BC1\u7248\u672C\u3002");
16472
16472
  const status = checked.data;
16473
- assert2(status.id === result2.id && result2.output === output && result2.progress.completed === spec.frameCount && result2.progress.total === spec.frameCount, "RENDER_RECEIPT_MISMATCH", "Motion Harness \u6E32\u67D3\u56DE\u6267\u3001\u5B8C\u6210\u72B6\u6001\u6216\u5E27\u6570\u4E0D\u5C5E\u4E8E\u672C\u6B21\u8BF7\u6C42\u3002");
16473
+ assert2(status.id === result2.id && result2.output === output && result2.progress.completed === spec.frameCount && result2.progress.total === spec.frameCount, "RENDER_RECEIPT_MISMATCH", "MotionHarness \u6E32\u67D3\u56DE\u6267\u3001\u5B8C\u6210\u72B6\u6001\u6216\u5E27\u6570\u4E0D\u5C5E\u4E8E\u672C\u6B21\u8BF7\u6C42\u3002");
16474
16474
  return { ...result2, status };
16475
16475
  }
16476
16476
  async pack(path, output) {
@@ -16985,23 +16985,23 @@ var Store = class {
16985
16985
  };
16986
16986
 
16987
16987
  // src/version.ts
16988
- var BRIDGE_VERSION = "0.0.23";
16988
+ var BRIDGE_VERSION = "0.0.25";
16989
16989
 
16990
16990
  // src/core/selection.ts
16991
16991
  function selectedSource(catalog, selection) {
16992
16992
  const unavailable = (status, message) => ({ selection, fingerprint: selection.fingerprint, canOpen: false, status, message, target: null });
16993
16993
  if (!selection.scope || !selection.timelineId) return unavailable("no-timeline", "\u8BF7\u6253\u5F00\u5DE5\u7A0B\u4E0E\u65F6\u95F4\u7EBF\u3002");
16994
- if (!selection.selectedCount) return unavailable("no-selection", "\u8BF7\u9009\u62E9\u4E00\u4E2A Motion Harness \u7247\u6BB5\u3002");
16995
- if (selection.selectedCount !== 1 || !selection.item) return unavailable("multiple-selection", "\u8BF7\u53EA\u9009\u62E9\u4E00\u4E2A Motion Harness \u7247\u6BB5\u3002");
16994
+ if (!selection.selectedCount) return unavailable("no-selection", "\u8BF7\u9009\u62E9\u4E00\u4E2A MotionHarness \u7247\u6BB5\u3002");
16995
+ if (selection.selectedCount !== 1 || !selection.item) return unavailable("multiple-selection", "\u8BF7\u53EA\u9009\u62E9\u4E00\u4E2A MotionHarness \u7247\u6BB5\u3002");
16996
16996
  let link2;
16997
16997
  try {
16998
16998
  const parsed = JSON.parse(selection.item.bridgeMetadata ?? "null");
16999
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return unavailable("not-linked", "\u6240\u9009\u7247\u6BB5\u672A\u5173\u8054 Motion Harness \u5DE5\u7A0B\u3002");
16999
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return unavailable("not-linked", "\u6240\u9009\u7247\u6BB5\u672A\u5173\u8054 MotionHarness \u5DE5\u7A0B\u3002");
17000
17000
  link2 = parsed;
17001
17001
  } catch {
17002
- return unavailable("invalid-link", "\u7247\u6BB5\u7684 Motion Harness \u5173\u8054\u4FE1\u606F\u65E0\u6548\u3002");
17002
+ return unavailable("invalid-link", "\u7247\u6BB5\u7684 MotionHarness \u5173\u8054\u4FE1\u606F\u65E0\u6548\u3002");
17003
17003
  }
17004
- if (link2.schemaVersion !== 1 || typeof link2.bindingId !== "string" || typeof link2.sourceId !== "string") return unavailable("invalid-link", "\u7247\u6BB5\u7684 Motion Harness \u5173\u8054\u4FE1\u606F\u65E0\u6548\u3002");
17004
+ if (link2.schemaVersion !== 1 || typeof link2.bindingId !== "string" || typeof link2.sourceId !== "string") return unavailable("invalid-link", "\u7247\u6BB5\u7684 MotionHarness \u5173\u8054\u4FE1\u606F\u65E0\u6548\u3002");
17005
17005
  const binding = Object.hasOwn(catalog.bindings, link2.bindingId) ? catalog.bindings[link2.bindingId] : void 0;
17006
17006
  const source = Object.hasOwn(catalog.sources, link2.sourceId) ? catalog.sources[link2.sourceId] : void 0;
17007
17007
  if (!binding || !source) return unavailable("unknown-workspace", "\u5F53\u524D\u6865\u63A5\u5DE5\u4F5C\u76EE\u5F55\u6CA1\u6709\u8FD9\u6BB5\u7D20\u6750\u7684\u5173\u8054\u8BB0\u5F55\u3002");
@@ -17009,7 +17009,7 @@ function selectedSource(catalog, selection) {
17009
17009
  if (Object.values(catalog.bindings).filter((item) => digest(item.resolve) === digest(binding.resolve)).length !== 1)
17010
17010
  return unavailable("binding-conflict", "\u540C\u4E00\u539F\u7D20\u6750\u5B58\u5728\u591A\u4E2A\u5173\u8054\uFF0C\u8BF7\u5148\u6838\u5BF9\u5173\u8054\u8BB0\u5F55\u3002");
17011
17011
  const target = { sourceId: source.id, bindingId: binding.id, sourceName: source.name, sourceRevision: source.revision, bindingRevision: binding.revision };
17012
- return { selection, fingerprint: digest({ selection: selection.fingerprint, target }), canOpen: true, status: "linked", message: "\u5DF2\u5B9A\u4F4D\u5BF9\u5E94 Motion Harness \u5DE5\u7A0B\u3002", target };
17012
+ return { selection, fingerprint: digest({ selection: selection.fingerprint, target }), canOpen: true, status: "linked", message: "\u5DF2\u5B9A\u4F4D\u5BF9\u5E94 MotionHarness \u5DE5\u7A0B\u3002", target };
17013
17013
  }
17014
17014
 
17015
17015
  // src/core/legacy-conversion.ts
@@ -17416,9 +17416,9 @@ function checkOwnership(binding, media) {
17416
17416
  assert2(link2.schemaVersion === 1 && link2.bindingId === binding.id && link2.sourceId === binding.sourceId && link2.artifactId === binding.artifactId, "VERSION_CONFLICT", "Resolve \u5173\u8054\u5143\u6570\u636E\u5DF2\u6539\u53D8\uFF0C\u672A\u8986\u76D6\u5176\u4ED6\u63A7\u5236\u7AEF\u7684\u5173\u8054\u3002");
17417
17417
  }
17418
17418
  function checkObservation(obs, spec) {
17419
- assert2(!obs.audioPresent, "AUDIO_UNSUPPORTED", "Motion Harness \u5DE5\u7A0B\u5305\u542B\u97F3\u9891\u7EC4\u4EF6\u6216\u89C6\u9891\u539F\u4EF6\u97F3\u8F68\uFF0C\u9996\u7248\u753B\u9762\u6865\u63A5\u4E0D\u4E22\u5F03\u8FD9\u4E9B\u58F0\u97F3\u3002");
17419
+ assert2(!obs.audioPresent, "AUDIO_UNSUPPORTED", "MotionHarness \u5DE5\u7A0B\u5305\u542B\u97F3\u9891\u7EC4\u4EF6\u6216\u89C6\u9891\u539F\u4EF6\u97F3\u8F68\uFF0C\u9996\u7248\u753B\u9762\u6865\u63A5\u4E0D\u4E22\u5F03\u8FD9\u4E9B\u58F0\u97F3\u3002");
17420
17420
  assert2([[25, 1], [30, 1], [3e4, 1001]].some(([n, d]) => n * spec.fps.den === spec.fps.num * d), "UNSUPPORTED_FPS", "\u9996\u7248\u652F\u6301 25\u300130 \u548C 30000/1001 fps\u3002");
17421
- assert2((spec.startFrame + spec.frameCount - 1) * spec.fps.den / spec.fps.num < obs.settings.duration + 1e-8, "OUTPUT_SPEC_MISMATCH", "\u6307\u5B9A\u6E90\u533A\u95F4\u8D85\u8FC7 Motion Harness \u5DE5\u7A0B\u65F6\u957F\u3002");
17421
+ assert2((spec.startFrame + spec.frameCount - 1) * spec.fps.den / spec.fps.num < obs.settings.duration + 1e-8, "OUTPUT_SPEC_MISMATCH", "\u6307\u5B9A\u6E90\u533A\u95F4\u8D85\u8FC7 MotionHarness \u5DE5\u7A0B\u65F6\u957F\u3002");
17422
17422
  }
17423
17423
  function checkReplacementSpec(media, artifact) {
17424
17424
  const properties = media.clipProperties;
@@ -17502,7 +17502,7 @@ var Bridge = class {
17502
17502
  const matches = Object.values(catalog.bindings).filter((b) => digest(b.resolve) === digest(request.resolve));
17503
17503
  assert2(matches.length <= 1, "BINDING_CONFLICT", "\u540C\u4E00\u539F\u7D20\u6750\u5B58\u5728\u591A\u4E2A\u5173\u8054\uFF0C\u672A\u731C\u6D4B\u76EE\u6807\u3002");
17504
17504
  binding = matches[0];
17505
- assert2(!binding || binding.sourceId === source.id, "BINDING_CONFLICT", "\u8BE5\u5A92\u4F53\u6C60\u5BF9\u8C61\u5DF2\u5173\u8054\u5176\u4ED6 Motion Harness \u5DE5\u7A0B\u3002");
17505
+ assert2(!binding || binding.sourceId === source.id, "BINDING_CONFLICT", "\u8BE5\u5A92\u4F53\u6C60\u5BF9\u8C61\u5DF2\u5173\u8054\u5176\u4ED6 MotionHarness \u5DE5\u7A0B\u3002");
17506
17506
  if (!binding) {
17507
17507
  binding = { id: id("binding"), sourceId: source.id, resolve: request.resolve, revision: 1, state: "unbound", lastReadback: actual, createdAt: now() };
17508
17508
  catalog.bindings[binding.id] = binding;
@@ -17681,7 +17681,7 @@ var Bridge = class {
17681
17681
  await this.mh.projectPath(this.store.path(catalog.sources[result2.target.sourceId].locator));
17682
17682
  } catch (error48) {
17683
17683
  if (!(error48 instanceof BridgeError) || error48.code !== "SOURCE_MISSING") throw error48;
17684
- return { ...result2, canOpen: false, status: "source-missing", message: "Motion Harness \u5DE5\u7A0B\u76EE\u5F55\u4E0D\u53EF\u7528\uFF0C\u8BF7\u901A\u8FC7\u66F4\u591A\u6865\u63A5\u64CD\u4F5C\u6062\u590D\u6216\u91CD\u5B9A\u4F4D\u5DE5\u7A0B\u3002" };
17684
+ return { ...result2, canOpen: false, status: "source-missing", message: "MotionHarness \u5DE5\u7A0B\u76EE\u5F55\u4E0D\u53EF\u7528\uFF0C\u8BF7\u901A\u8FC7\u66F4\u591A\u6865\u63A5\u64CD\u4F5C\u6062\u590D\u6216\u91CD\u5B9A\u4F4D\u5DE5\u7A0B\u3002" };
17685
17685
  }
17686
17686
  }
17687
17687
  return result2;
@@ -17894,7 +17894,7 @@ var Bridge = class {
17894
17894
  reconciled = request.targets.every((target) => job.results.some((r) => r.bindingId === target.bindingId && r.applied === true));
17895
17895
  for (const target of request.targets.filter((t) => !job.results.some((r) => r.bindingId === t.bindingId && r.applied === true))) {
17896
17896
  const binding = get((await this.store.read()).bindings, target.bindingId, "\u7ED1\u5B9A"), source = get(catalog.sources, binding.sourceId, "\u6E90");
17897
- assert2(!(await this.mh.renderStatus(this.store.path(source.locator))).locked, "RECOVERY_WAIT", "Motion Harness \u4ECD\u6709\u6E32\u67D3\u6301\u9501\uFF0C\u8BF7\u7B49\u5F85\u8BE5\u4EFB\u52A1\u91CA\u653E\u540E\u6838\u5BF9\u3002");
17897
+ assert2(!(await this.mh.renderStatus(this.store.path(source.locator))).locked, "RECOVERY_WAIT", "MotionHarness \u4ECD\u6709\u6E32\u67D3\u6301\u9501\uFF0C\u8BF7\u7B49\u5F85\u8BE5\u4EFB\u52A1\u91CA\u653E\u540E\u6838\u5BF9\u3002");
17898
17898
  }
17899
17899
  }
17900
17900
  } else if (job.operation === "render") {
@@ -17906,7 +17906,7 @@ var Bridge = class {
17906
17906
  reconciled = true;
17907
17907
  } else {
17908
17908
  const source = get(catalog.sources, renderSchema.parse(job.request).sourceId, "\u6E90");
17909
- assert2(!(await this.mh.renderStatus(this.store.path(source.locator))).locked, "RECOVERY_WAIT", "Motion Harness \u4ECD\u6709\u6E32\u67D3\u6301\u9501\uFF0C\u8BF7\u7B49\u5F85\u6E05\u7406\u3002");
17909
+ assert2(!(await this.mh.renderStatus(this.store.path(source.locator))).locked, "RECOVERY_WAIT", "MotionHarness \u4ECD\u6709\u6E32\u67D3\u6301\u9501\uFF0C\u8BF7\u7B49\u5F85\u6E05\u7406\u3002");
17910
17910
  }
17911
17911
  } else if (job.operation === "duplicate") {
17912
17912
  const checkpoint = journal.duplicate;
@@ -17961,7 +17961,7 @@ var Bridge = class {
17961
17961
  const observation = await this.mh.inspect(this.store.path(checkpoint.destination));
17962
17962
  assert2(observation.coverage === "public-package-v1" && observation.contentVersion === checkpoint.contentVersion, "RECOVERY_CONFLICT", "\u526F\u672C\u76EE\u5F55\u4E0D\u5B8C\u6574\u6216\u5185\u5BB9\u5DF2\u6539\u53D8\uFF0C\u4FDD\u7559\u73B0\u573A\u4E14\u4E0D\u91CD\u65B0\u89E3\u5305\u3002");
17963
17963
  await this.store.mutate((c) => {
17964
- const source = c.sources[checkpoint.sourceId] ?? { id: checkpoint.sourceId, name: duplicateSchema.parse(job.request).name ?? "Motion Harness \u72EC\u7ACB\u526F\u672C", locator: checkpoint.destination, revision: 1, createdAt: now(), observation };
17964
+ const source = c.sources[checkpoint.sourceId] ?? { id: checkpoint.sourceId, name: duplicateSchema.parse(job.request).name ?? "MotionHarness \u72EC\u7ACB\u526F\u672C", locator: checkpoint.destination, revision: 1, createdAt: now(), observation };
17965
17965
  c.sources[source.id] = source;
17966
17966
  if (!("bindingId" in duplicateSchema.parse(job.request))) get(c.jobs, taskId, "\u4EFB\u52A1").results = [{ source, originalSourceId: checkpoint.originalSourceId, independent: true, applied: true, recovered: true }];
17967
17967
  });
@@ -18158,7 +18158,6 @@ var Bridge = class {
18158
18158
  assert2(request.scope || !request.timelineId || request.timelineId === target.timelineId, "INVALID_REQUEST", "\u8DE8\u65F6\u95F4\u7EBF\u63D2\u5165\u9700\u8981\u540C\u65F6\u6307\u5B9A Resolve \u5DE5\u7A0B\u8EAB\u4EFD\u3002");
18159
18159
  assert2(timelineId === target.timelineId || request.recordFrame !== void 0, "INVALID_REQUEST", "\u6307\u5B9A\u5176\u4ED6\u65F6\u95F4\u7EBF\u65F6\uFF0C\u9700\u8981\u660E\u786E\u8BE5\u65F6\u95F4\u7EBF\u7684 recordFrame\u3002");
18160
18160
  const timeline = await this.host.timeline(scope, timelineId);
18161
- assert2(timeline.validatedHost !== false, "CAPABILITY_UNAVAILABLE", "\u6B64 Resolve \u5E73\u53F0\u6216\u6784\u5EFA\u5C1A\u672A\u9A8C\u8BC1\u81EA\u52A8\u63D2\u5165\uFF0C\u672A\u5F00\u59CB\u6E32\u67D3\u3002");
18162
18161
  const recordFrame = request.recordFrame ?? target.recordFrame;
18163
18162
  const timelineFrames = nativeTimelineFrames(spec.frameCount, spec.fps, timeline.fps);
18164
18163
  assert2(timeline.items.every((item) => Number.isFinite(item.startFrame) && Number.isFinite(item.endFrame) && Number.isSafeInteger(item.track)), "UNSUPPORTED_TIMELINE_ITEM", "\u65E0\u6CD5\u5B8C\u6574\u8BFB\u53D6\u8F68\u9053\u5360\u7528\u533A\u95F4\u3002");
@@ -18451,7 +18450,7 @@ var Bridge = class {
18451
18450
  assert2(
18452
18451
  after.contentVersion === observation.contentVersion && after.runtimeIdentity === observation.runtimeIdentity && after.sessionIdentity === observation.sessionIdentity,
18453
18452
  "VERSION_CONFLICT",
18454
- "\u6E32\u67D3\u524D\u540E\u7684 Motion Harness \u5185\u5BB9\u3001\u8FD0\u884C\u65F6\u6216\u4F1A\u8BDD\u4E0D\u4E00\u81F4\uFF0C\u672A\u5E94\u7528\u65B0\u7ED3\u679C\u3002"
18453
+ "\u6E32\u67D3\u524D\u540E\u7684 MotionHarness \u5185\u5BB9\u3001\u8FD0\u884C\u65F6\u6216\u4F1A\u8BDD\u4E0D\u4E00\u81F4\uFF0C\u672A\u5E94\u7528\u65B0\u7ED3\u679C\u3002"
18455
18454
  );
18456
18455
  await this.store.mutate((catalog) => {
18457
18456
  const current = get(catalog.sources, sourceId, "\u6E90");
@@ -18478,7 +18477,7 @@ var Bridge = class {
18478
18477
  async renderSource(taskId, input, signal) {
18479
18478
  const request = renderSchema.parse(input), source = get((await this.store.read()).sources, request.sourceId, "\u6E90");
18480
18479
  const observation = await this.mh.inspect(this.store.path(source.locator));
18481
- assert2(observation.contentVersion === request.expectedContentVersion, "VERSION_CONFLICT", "Motion Harness \u5185\u5BB9\u4E0E\u8BF7\u6C42\u7684\u7248\u672C\u4E0D\u4E00\u81F4\u3002");
18480
+ assert2(observation.contentVersion === request.expectedContentVersion, "VERSION_CONFLICT", "MotionHarness \u5185\u5BB9\u4E0E\u8BF7\u6C42\u7684\u7248\u672C\u4E0D\u4E00\u81F4\u3002");
18482
18481
  const artifact = await this.renderArtifact(taskId, source.id, observation, request.outputSpec, request.purpose, signal);
18483
18482
  await this.store.mutate((c) => {
18484
18483
  get(c.jobs, taskId, "\u4EFB\u52A1").results = [{ sourceId: source.id, artifactId: artifact.id, verification: artifact.verification, applied: false }];
@@ -18640,7 +18639,7 @@ var Bridge = class {
18640
18639
  const c = await this.store.read(), binding = get(c.bindings, target.bindingId, "\u7ED1\u5B9A"), source = get(c.sources, binding.sourceId, "\u6E90");
18641
18640
  assert2(binding.revision === target.expectedRevision, "VERSION_CONFLICT", "\u7ED1\u5B9A\u7248\u672C\u5DF2\u6539\u53D8\u3002");
18642
18641
  const obs = await this.mh.inspect(this.store.path(source.locator));
18643
- assert2(obs.contentVersion === target.expectedContentVersion, "VERSION_CONFLICT", "Motion Harness \u5185\u5BB9\u5DF2\u6539\u53D8\u3002");
18642
+ assert2(obs.contentVersion === target.expectedContentVersion, "VERSION_CONFLICT", "MotionHarness \u5185\u5BB9\u5DF2\u6539\u53D8\u3002");
18644
18643
  checkObservation(obs, request.outputSpec);
18645
18644
  if (binding.artifactId) assert2(sameOutputSpec(get(c.artifacts, binding.artifactId, "\u4EA7\u7269").spec, request.outputSpec), "OUTPUT_SPEC_MISMATCH", "\u540C\u6B65\u4E0D\u80FD\u6539\u53D8\u5DF2\u5E94\u7528\u7684\u5E27\u533A\u95F4\u3001\u5C3A\u5BF8\u3001\u5E27\u7387\u6216\u989C\u8272\u89E3\u91CA\u3002");
18646
18645
  const previousSettings = binding.artifactId ? c.artifacts[binding.artifactId]?.receipt?.before.settings : void 0;
@@ -18870,7 +18869,7 @@ var Bridge = class {
18870
18869
  await mkdir5(directory, { recursive: true });
18871
18870
  const output = resolve3(directory, "source.png");
18872
18871
  await this.mh.preview(path, time3, output);
18873
- assert2((await this.mh.inspect(path)).contentVersion === before.contentVersion, "VERSION_CONFLICT", "\u622A\u56FE\u671F\u95F4 Motion Harness \u5185\u5BB9\u5DF2\u6539\u53D8\u3002");
18872
+ assert2((await this.mh.inspect(path)).contentVersion === before.contentVersion, "VERSION_CONFLICT", "\u622A\u56FE\u671F\u95F4 MotionHarness \u5185\u5BB9\u5DF2\u6539\u53D8\u3002");
18874
18873
  const image = await readFile4(output);
18875
18874
  assert2(image.length <= 10 * 1024 * 1024 && image.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])), "INVALID_IMAGE", "\u68C0\u67E5\u56FE\u7247\u4E0D\u662F\u53D7\u652F\u6301\u5927\u5C0F\u7684 PNG\u3002");
18876
18875
  return { origin: "mh-source", sourceId, contentVersion: before.contentVersion, timeSeconds: time3, filePath: output, mimeType: "image/png", data: image.toString("base64"), provesResolveComposite: false };
@@ -20552,7 +20551,7 @@ import { execFileSync } from "node:child_process";
20552
20551
 
20553
20552
  // src/i18n/en.json
20554
20553
  var en_default2 = {
20555
- "Motion Harness \u6865\u63A5\u7EC4\u4EF6": "Motion Harness Bridge Component",
20554
+ "MotionHarness \u6865\u63A5\u7EC4\u4EF6": "MotionHarness Bridge Component",
20556
20555
  " \u526F\u672C": " Copy",
20557
20556
  "\u4E3A\u8FD9\u4E2A\u7247\u6BB5\u521B\u5EFA\u72EC\u7ACB\u526F\u672C\u2026": "Create an independent copy for this clip\u2026",
20558
20557
  "\u4EFB\u52A1\u4E0E\u72B6\u6001\u2026": "Tasks and status\u2026",
@@ -20563,9 +20562,9 @@ var en_default2 = {
20563
20562
  "\u4FA7\u680F\u6765\u6E90\u5FEB\u7167\u65E0\u6548\u3002": "The sidebar source snapshot is invalid.",
20564
20563
  "\u4FA7\u680F\u7BA1\u7406\u5165\u53E3\u4E0D\u80FD\u6DF7\u7528\u76EE\u6807\u5FEB\u7167\u6216\u64CD\u4F5C\u53C2\u6570\u3002": "The sidebar management request cannot mix target snapshots with operation parameters.",
20565
20564
  "\u4FA7\u680F\u7BA1\u7406\u5165\u53E3\u8BF7\u6C42\u65E0\u6548\u3002": "The sidebar management request is invalid.",
20566
- "\u4FA7\u680F\u7BA1\u7406\u5165\u53E3\u9700\u8981\u65B0\u7248\u6865\u63A5\u7EC4\u4EF6\uFF0C\u8BF7\u66F4\u65B0\u7EC4\u4EF6\u3002": "Update the Motion Harness Bridge Component to use sidebar management.",
20567
- "\u4FA7\u680F\u9700\u8981\u652F\u6301\u6E90\u8EAB\u4EFD\u6838\u5BF9\u7684\u65B0\u7248\u6865\u63A5\u7EC4\u4EF6\u3002": "The sidebar requires a newer Motion Harness Bridge Component with source verification.",
20568
- "\u4FA7\u680F\u9700\u8981\u65B0\u7248\u6865\u63A5\u7EC4\u4EF6\uFF0C\u8BF7\u5148\u66F4\u65B0\u7EC4\u4EF6\u3002\u672A\u53D1\u9001\u8BF7\u6C42\u5230\u65E7\u7248\u5165\u53E3\u3002": "Update the Motion Harness Bridge Component to use the sidebar. No request was sent to the old entry.",
20565
+ "\u4FA7\u680F\u7BA1\u7406\u5165\u53E3\u9700\u8981\u65B0\u7248\u6865\u63A5\u7EC4\u4EF6\uFF0C\u8BF7\u66F4\u65B0\u7EC4\u4EF6\u3002": "Update the MotionHarness Bridge Component to use sidebar management.",
20566
+ "\u4FA7\u680F\u9700\u8981\u652F\u6301\u6E90\u8EAB\u4EFD\u6838\u5BF9\u7684\u65B0\u7248\u6865\u63A5\u7EC4\u4EF6\u3002": "The sidebar requires a newer MotionHarness Bridge Component with source verification.",
20567
+ "\u4FA7\u680F\u9700\u8981\u65B0\u7248\u6865\u63A5\u7EC4\u4EF6\uFF0C\u8BF7\u5148\u66F4\u65B0\u7EC4\u4EF6\u3002\u672A\u53D1\u9001\u8BF7\u6C42\u5230\u65E7\u7248\u5165\u53E3\u3002": "Update the MotionHarness Bridge Component to use the sidebar. No request was sent to the old entry.",
20569
20568
  \u4FDD\u5B58\u72EC\u7ACB\u5DE5\u7A0B: "Save independent project",
20570
20569
  "\u4FEE\u590D\u5173\u8054\u2026": "Repair association\u2026",
20571
20570
  "\u4FEE\u590D\u5DE5\u7A0B\u5173\u8054\u2026": "Repair project association\u2026",
@@ -20579,7 +20578,7 @@ var en_default2 = {
20579
20578
  "\u53EF\u5173\u95ED\u7A97\u53E3\uFF0C\u6309\u4E0A\u65B9\u63D0\u793A\u7EE7\u7EED\u64CD\u4F5C\u3002": "You can close this window and follow the instructions above.",
20580
20579
  "\u53EF\u7EE7\u7EED\u4F7F\u7528\u8FBE\u82AC\u5947\u3002": "You can continue using DaVinci Resolve.",
20581
20580
  "\u53EF\u7EE7\u7EED\u4F7F\u7528\u8FBE\u82AC\u5947\u3002\u5173\u95ED\u7A97\u53E3\u4E0D\u4F1A\u53D6\u6D88\u4EFB\u52A1\u3002": "You can continue using DaVinci Resolve. Closing this window keeps the task running.",
20582
- "\u56FE\u6587\u6B65\u9AA4\u6682\u4E0D\u53EF\u7528\uFF0C\u8BF7\u66F4\u65B0\u6865\u63A5\u7EC4\u4EF6\u540E\u91CD\u8BD5\u3002": "The illustrated guide is unavailable. Update the Motion Harness Bridge Component and try again.",
20581
+ "\u56FE\u6587\u6B65\u9AA4\u6682\u4E0D\u53EF\u7528\uFF0C\u8BF7\u66F4\u65B0\u6865\u63A5\u7EC4\u4EF6\u540E\u91CD\u8BD5\u3002": "The illustrated guide is unavailable. Update the MotionHarness Bridge Component and try again.",
20583
20582
  "\u5C1A\u672A\u786E\u8BA4\u6240\u9009\u5DE5\u7A0B\u7684\u7F16\u8F91\u5668\u5DF2\u6253\u5F00\uFF0C\u8BF7\u68C0\u67E5\u540E\u91CD\u8BD5\u3002": "The editor has not confirmed opening the selected project. Check and try again.",
20584
20583
  \u5DE5\u7A0B\u5173\u8054\u5DF2\u4FEE\u590D: "Project association repaired",
20585
20584
  "\u5DE5\u7A0B\u5DF2\u4FEE\u6539\uFF0C\u53EF\u4EE5\u66F4\u65B0\u8FBE\u82AC\u5947\u89C6\u9891\u3002": "The project has changed. You can update the video in DaVinci Resolve.",
@@ -20590,16 +20589,16 @@ var en_default2 = {
20590
20589
  "\u6062\u590D\u5386\u53F2\u7248\u672C\u2026": "Restore previous version\u2026",
20591
20590
  \u6062\u590D\u5DF2\u5E94\u7528\u7248\u672C: "Restore applied version",
20592
20591
  "\u6062\u590D\u7248\u672C\u4F1A\u5F71\u54CD\u6B64\u7D20\u6750\u7684\u5168\u90E8\u5F15\u7528\u3002": "Restoring a version affects every use of this media.",
20593
- "\u6240\u9009 Motion Harness \u7247\u6BB5": "Selected Motion Harness clip",
20592
+ "\u6240\u9009 MotionHarness \u7247\u6BB5": "Selected MotionHarness clip",
20594
20593
  \u6240\u9009\u7247\u6BB5: "Selected clip",
20595
- "\u627E\u4E0D\u5230 Motion Harness\u3002\u8BF7\u91CD\u65B0\u5B89\u88C5\u6865\u63A5\u7EC4\u4EF6\u3002": "Motion Harness was not found. Reinstall the Motion Harness Bridge Component.",
20594
+ "\u627E\u4E0D\u5230 MotionHarness\u3002\u8BF7\u91CD\u65B0\u5B89\u88C5\u6865\u63A5\u7EC4\u4EF6\u3002": "MotionHarness was not found. Reinstall the MotionHarness Bridge Component.",
20596
20595
  "\u627E\u4E0D\u5230\u6E90\u5DE5\u7A0B\uFF0C\u8BF7\u4ECE\u4FA7\u680F\u201C\u66F4\u591A\u2026\u201D\u91CD\u65B0\u5B9A\u4F4D\u3002": "The source project was not found. Relocate it using More\u2026 in the sidebar.",
20597
20596
  "\u64CD\u4F5C\u6CA1\u6709\u5B8C\u6210\u3002\u8BF7\u8FD0\u884C\u6865\u63A5\u8BCA\u65AD\u67E5\u770B\u8BE6\u60C5\u3002": "The operation did not complete. Run bridge diagnostics for details.",
20598
20597
  "\u64CD\u4F5C\u6CA1\u6709\u5B8C\u6210\uFF0C\u8BF7\u68C0\u67E5\u6865\u63A5\u8FDE\u63A5\u3002": "The operation did not complete. Check the bridge connection.",
20599
20598
  "\u65E0\u6CD5\u4FDD\u5B58\u672C\u5730\u8BF7\u6C42\u72B6\u6001\u3002": "Unable to save the local request state.",
20600
20599
  "\u65E0\u6CD5\u521B\u5EFA\u672C\u5730\u8BF7\u6C42\u901A\u9053\u3002": "Unable to create the local request channel.",
20601
- "\u65E0\u6CD5\u542F\u52A8 Motion Harness\uFF0C\u8BF7\u4FEE\u590D\u7EC4\u4EF6\u5B89\u88C5\u3002": "Unable to start Motion Harness. Repair the Motion Harness Bridge Component installation.",
20602
- "\u65E0\u6CD5\u542F\u52A8 Motion Harness\uFF0C\u8BF7\u91CD\u65B0\u5B89\u88C5\u6865\u63A5\u7EC4\u4EF6\u3002": "Unable to start Motion Harness. Reinstall the Motion Harness Bridge Component.",
20600
+ "\u65E0\u6CD5\u542F\u52A8 MotionHarness\uFF0C\u8BF7\u4FEE\u590D\u7EC4\u4EF6\u5B89\u88C5\u3002": "Unable to start MotionHarness. Repair the MotionHarness Bridge Component installation.",
20601
+ "\u65E0\u6CD5\u542F\u52A8 MotionHarness\uFF0C\u8BF7\u91CD\u65B0\u5B89\u88C5\u6865\u63A5\u7EC4\u4EF6\u3002": "Unable to start MotionHarness. Reinstall the MotionHarness Bridge Component.",
20603
20602
  "\u65E0\u6CD5\u6253\u5F00\u672C\u5730\u8BF7\u6C42\u72B6\u6001\u3002": "Unable to open the local request state.",
20604
20603
  "\u65E7\u5165\u53E3\u6CA1\u6709\u8FD4\u56DE\u53EF\u6838\u5BF9\u7684\u7247\u6BB5\u8EAB\u4EFD\u3002": "The legacy entry did not return a verifiable clip identity.",
20605
20604
  "\u65E7\u5165\u53E3\u7F3A\u5C11\u70B9\u51FB\u65F6\u7684\u7247\u6BB5\u8EAB\u4EFD\uFF0C\u8BF7\u4FEE\u590D\u65E7\u5165\u53E3\u8F6C\u53D1\u3002": "The legacy entry lacks the clip identity captured on click. Repair its forwarder.",
@@ -20657,15 +20656,15 @@ var en_default2 = {
20657
20656
  \u76F8\u5173\u6587\u4EF6: "related file",
20658
20657
  "\u7B49\u5F85\u5DF2\u7ED3\u675F\uFF1B\u8BF7\u6C42\u53EF\u80FD\u4ECD\u5728\u540E\u53F0\u5904\u7406\uFF0C\u8BF7\u5148\u67E5\u770B\u72B6\u6001\u3002": "The wait has ended. The request may still be running in the background. Check its status first.",
20659
20658
  "\u7B49\u5F85\u8D85\u65F6\u3002\u8BF7\u6C42\u53EF\u80FD\u4ECD\u5728\u5904\u7406\uFF0C\u8BF7\u5148\u67E5\u770B\u73B0\u6709\u4EFB\u52A1\u72B6\u6001\u3002": "The request timed out and may still be running. Check the existing task status first.",
20660
- "\u7EC4\u4EF6\u672A\u914D\u7F6E\u3002\u8BF7\u8FD0\u884C mh bridge davinci install \u4FEE\u590D\u3002": "The Motion Harness Bridge Component is not configured. Run mh bridge davinci install to repair it.",
20661
- "\u7EC4\u4EF6\u7F3A\u5C11\u72B6\u6001\u7A97\u53E3\uFF0C\u8BF7\u4FEE\u590D Motion Harness \u6865\u63A5\u7EC4\u4EF6\u5B89\u88C5\u3002": "The status window is missing. Repair the Motion Harness Bridge Component installation.",
20659
+ "\u7EC4\u4EF6\u672A\u914D\u7F6E\u3002\u8BF7\u8FD0\u884C mh bridge davinci install \u4FEE\u590D\u3002": "The MotionHarness Bridge Component is not configured. Run mh bridge davinci install to repair it.",
20660
+ "\u7EC4\u4EF6\u7F3A\u5C11\u72B6\u6001\u7A97\u53E3\uFF0C\u8BF7\u4FEE\u590D MotionHarness \u6865\u63A5\u7EC4\u4EF6\u5B89\u88C5\u3002": "The status window is missing. Repair the MotionHarness Bridge Component installation.",
20662
20661
  "\u7EC4\u4EF6\u914D\u7F6E\u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84\u3002": "The component configuration path must be absolute.",
20663
20662
  \u7EE7\u7EED: "Continue",
20664
20663
  \u7EE7\u7EED\u539F\u4EFB\u52A1: "Resume original task",
20665
20664
  "\u7EE7\u7EED\u539F\u4EFB\u52A1\u2026": "Resume original task\u2026",
20666
20665
  "\u7EE7\u7EED\u539F\u4EFB\u52A1\u4E2D\u5C1A\u672A\u5B8C\u6210\u7684\u64CD\u4F5C\uFF1F": "Resume unfinished operations in the original task?",
20667
20666
  \u7EE7\u7EED\u6838\u5BF9\u6E90\u5DE5\u7A0B\u4F4D\u7F6E: "Continue checking source project location",
20668
- "\u7F16\u8F91 Motion Harness \u5DE5\u7A0B": "Edit Motion Harness project",
20667
+ "\u7F16\u8F91 MotionHarness \u5DE5\u7A0B": "Edit MotionHarness project",
20669
20668
  \u7F16\u8F91\u5DE5\u7A0B: "Edit project",
20670
20669
  "\u7F3A\u5C11\u8BF7\u6C42\u53C2\u6570\u3002": "Request parameters are missing.",
20671
20670
  "\u89C6\u9891\u5DF2\u51C6\u5907\uFF0C\u5C1A\u672A\u66F4\u65B0\u5230\u8FBE\u82AC\u5947\u3002": "The video is ready but has not been updated in DaVinci Resolve.",
@@ -20674,7 +20673,7 @@ var en_default2 = {
20674
20673
  "\u89C6\u9891\u5DF2\u751F\u6210\uFF0C\u5C1A\u672A\u66F4\u65B0\u5230\u8FBE\u82AC\u5947\u3002": "The video has been generated but has not been updated in DaVinci Resolve.",
20675
20674
  "\u89C6\u9891\u7248\u672C\u5C1A\u5F85\u6838\u5B9E\uFF0C\u8BF7\u67E5\u770B\u4EFB\u52A1\u8BE6\u60C5\u3002": "The video version needs verification. Check task details.",
20676
20675
  "\u8BF7\u5728\u7BA1\u7406\u7A97\u53E3\u4E2D\u6838\u5BF9\u5DE5\u7A0B\u548C\u67E5\u770B\u72B6\u6001\u3002": "Check the project and status in the management window.",
20677
- "\u8BF7\u66F4\u65B0\u6865\u63A5\u7EC4\u4EF6\u540E\u4F7F\u7528\u66F4\u591A\u64CD\u4F5C\u3002": "Update the Motion Harness Bridge Component to use more actions.",
20676
+ "\u8BF7\u66F4\u65B0\u6865\u63A5\u7EC4\u4EF6\u540E\u4F7F\u7528\u66F4\u591A\u64CD\u4F5C\u3002": "Update the MotionHarness Bridge Component to use more actions.",
20678
20677
  "\u8BF7\u6C42\u53D6\u6D88\uFF0C\u5E76\u6838\u5BF9\u5DF2\u7ECF\u5B8C\u6210\u7684\u7ED3\u679C\u3002": "Request cancellation and check results already completed.",
20679
20678
  "\u8BF7\u6C42\u5931\u8D25\uFF0C\u8BF7\u8FD0\u884C mh bridge davinci doctor \u68C0\u67E5\u8FDE\u63A5\u3002": "The request failed. Run mh bridge davinci doctor to check the connection.",
20680
20679
  \u8BF7\u6C42\u5DF2\u53D7\u7406: "Request accepted",
@@ -20684,7 +20683,7 @@ var en_default2 = {
20684
20683
  "\u8FBE\u82AC\u5947\u5DF2\u8FDE\u63A5\uFF0C\u6682\u65E0\u8FDB\u884C\u4E2D\u7684\u4EFB\u52A1\u3002": "DaVinci Resolve is connected. No task is running.",
20685
20684
  "\u8FBE\u82AC\u5947\u5DF2\u8FDE\u63A5\uFF0C\u672A\u627E\u5230\u6B64\u7247\u6BB5\u7684\u5173\u8054\u3002": "DaVinci Resolve is connected, but this clip has no association.",
20686
20685
  "\u8FBE\u82AC\u5947\u672A\u63D0\u4F9B\u6B64\u6548\u679C\u7684\u6E90\u89C6\u9891\u8DEF\u5F84\u3002\u8BF7\u4ECE\u5DE5\u4F5C\u533A\u83DC\u5355\u7BA1\u7406\u7247\u6BB5\u3002": "DaVinci Resolve did not provide the source video path for this effect. Manage the clip through the Workspace menu.",
20687
- "\u8FBE\u82AC\u5947\u6865\u63A5\u7EC4\u4EF6\u5C1A\u672A\u5B89\u88C5\u3002": "The Motion Harness Bridge Component is not installed.",
20686
+ "\u8FBE\u82AC\u5947\u6865\u63A5\u7EC4\u4EF6\u5C1A\u672A\u5B89\u88C5\u3002": "The MotionHarness Bridge Component is not installed.",
20688
20687
  \u8FD9\u4E2A\u7247\u6BB5\u7684\u72EC\u7ACB\u526F\u672C\u5DF2\u521B\u5EFA: "An independent copy has been created for this clip",
20689
20688
  "\u8FD9\u4E2A\u7248\u672C\u7684\u89C6\u9891\u6587\u4EF6\u5DF2\u4E0D\u53EF\u7528\u3002": "The video file for this version is unavailable.",
20690
20689
  \u9009\u62E9\u4F4D\u7F6E: "Choose location",
@@ -20694,14 +20693,14 @@ var en_default2 = {
20694
20693
  "\u91CD\u65B0\u5B9A\u4F4D\u6E90\u5DE5\u7A0B\u2026": "Relocate source project\u2026",
20695
20694
  "\u9884\u89C8\u672A\u5237\u65B0\u8BF7\u64AD\u653E\uFF1B\u5B9A\u683C\u53EF\u80FD\u4FDD\u7559\u65E7\u753B\u9762\u3002": "Play to refresh the preview. Freeze frames may retain the previous image.",
20696
20695
  "\u9884\u89C8\u89C6\u9891\u5DF2\u5173\u8054\uFF0C\u6682\u65E0\u8FDB\u884C\u4E2D\u7684\u4EFB\u52A1\u3002": "The preview video is linked. No task is running.",
20697
- "\u7F3A\u5C11 Motion Harness \u72B6\u6001\u7A97\u53E3\uFF0C\u8BF7\u8FD0\u884C mh bridge davinci install \u4FEE\u590D\u7EC4\u4EF6\u3002": "The Motion Harness Bridge Component status window is missing. Run mh bridge davinci install to repair it.",
20698
- "\u627E\u4E0D\u5230 Motion Harness \u4E3B\u7A0B\u5E8F\uFF0C\u8BF7\u8FD0\u884C mh bridge davinci install \u4FEE\u590D\u7EC4\u4EF6\u3002": "The Motion Harness executable was not found. Run mh bridge davinci install to repair the bridge component.",
20699
- "\u8BF7\u6253\u5F00\u65F6\u95F4\u7EBF\u5E76\u9009\u62E9\u4E00\u4E2A Motion Harness \u7247\u6BB5\u3002": "Open a timeline and select a Motion Harness clip.",
20700
- "\u8BF7\u53EA\u9009\u62E9\u4E00\u4E2A Motion Harness \u89C6\u9891\u7247\u6BB5\u3002": "Select exactly one Motion Harness video clip.",
20701
- "\u6240\u9009\u89C6\u9891\u672A\u5173\u8054 Motion Harness \u5DE5\u7A0B\u3002": "The selected video is not linked to a Motion Harness project.",
20702
- "\u6B63\u5728\u6253\u5F00 Motion Harness \u5DE5\u7A0B\u2026": "Opening Motion Harness project\u2026",
20703
- "\u6B63\u5728\u8BFB\u53D6\u6240\u9009 Motion Harness \u7247\u6BB5\u2026": "Reading selected Motion Harness clip\u2026",
20704
- "\u6B63\u5728\u63D0\u4EA4 Motion Harness \u8BF7\u6C42\uFF0C\u72B6\u6001\u7A97\u53E3\u5C06\u663E\u793A\u8FDB\u5EA6\u3002": "Submitting the Motion Harness request. The status window will show progress.",
20696
+ "\u7F3A\u5C11 MotionHarness \u72B6\u6001\u7A97\u53E3\uFF0C\u8BF7\u8FD0\u884C mh bridge davinci install \u4FEE\u590D\u7EC4\u4EF6\u3002": "The MotionHarness Bridge Component status window is missing. Run mh bridge davinci install to repair it.",
20697
+ "\u627E\u4E0D\u5230 MotionHarness \u4E3B\u7A0B\u5E8F\uFF0C\u8BF7\u8FD0\u884C mh bridge davinci install \u4FEE\u590D\u7EC4\u4EF6\u3002": "The MotionHarness executable was not found. Run mh bridge davinci install to repair the bridge component.",
20698
+ "\u8BF7\u6253\u5F00\u65F6\u95F4\u7EBF\u5E76\u9009\u62E9\u4E00\u4E2A MotionHarness \u7247\u6BB5\u3002": "Open a timeline and select a MotionHarness clip.",
20699
+ "\u8BF7\u53EA\u9009\u62E9\u4E00\u4E2A MotionHarness \u89C6\u9891\u7247\u6BB5\u3002": "Select exactly one MotionHarness video clip.",
20700
+ "\u6240\u9009\u89C6\u9891\u672A\u5173\u8054 MotionHarness \u5DE5\u7A0B\u3002": "The selected video is not linked to a MotionHarness project.",
20701
+ "\u6B63\u5728\u6253\u5F00 MotionHarness \u5DE5\u7A0B\u2026": "Opening MotionHarness project\u2026",
20702
+ "\u6B63\u5728\u8BFB\u53D6\u6240\u9009 MotionHarness \u7247\u6BB5\u2026": "Reading selected MotionHarness clip\u2026",
20703
+ "\u6B63\u5728\u63D0\u4EA4 MotionHarness \u8BF7\u6C42\uFF0C\u72B6\u6001\u7A97\u53E3\u5C06\u663E\u793A\u8FDB\u5EA6\u3002": "Submitting the MotionHarness request. The status window will show progress.",
20705
20704
  "\u8FBE\u82AC\u5947\u5C1A\u672A\u8FDE\u63A5\u3002\u8BF7\u6253\u5F00\u5DE5\u7A0B\u540E\u91CD\u8BD5\u3002": "DaVinci Resolve is not connected. Open a project and try again.",
20706
20705
  "\u8FBE\u82AC\u5947\u6B63\u5728\u5BFC\u51FA\uFF0C\u8BF7\u5B8C\u6210\u540E\u91CD\u8BD5\u3002": "DaVinci Resolve is rendering. Try again when it finishes.",
20707
20706
  "\u6240\u9009\u7247\u6BB5\u6CA1\u6709\u666E\u901A\u89C6\u9891\u7D20\u6750\u3002\u8BF7\u5148\u8F6C\u6362\u65E7\u7248\u751F\u6210\u5668\u3002": "The selected clip has no ordinary video media. Convert the legacy generator first.",
@@ -20749,7 +20748,7 @@ var en_default2 = {
20749
20748
  "\u6B64\u7D20\u6750\u643A\u5E26\u4E0D\u540C\u7684\u5173\u8054\u8EAB\u4EFD\uFF0C\u4E0D\u80FD\u8986\u76D6\u3002": "This media carries a different association identity and cannot be overwritten.",
20750
20749
  "\u6B64\u7D20\u6750\u6CA1\u6709\u53EF\u6838\u5BF9\u7684\u672C\u673A\u5173\u8054\u3002": "This media has no verifiable local association.",
20751
20750
  "\u6CA1\u6709\u53EF\u6062\u590D\u7684\u5DF2\u5E94\u7528\u7248\u672C\uFF0C\u6216\u5386\u53F2\u89C6\u9891\u6587\u4EF6\u4E0D\u53EF\u7528\u3002": "No applied version can be restored, or the historical video file is unavailable.",
20752
- "\u7247\u6BB5\u5DF2\u5173\u8054 Motion Harness\u3002\u53EF\u4EE5\u7F16\u8F91\u6E90\u5DE5\u7A0B\u6216\u66F4\u65B0\u753B\u9762\u3002": "The clip is linked to Motion Harness. You can edit the source project or update the video.",
20751
+ "\u7247\u6BB5\u5DF2\u5173\u8054 MotionHarness\u3002\u53EF\u4EE5\u7F16\u8F91\u6E90\u5DE5\u7A0B\u6216\u66F4\u65B0\u753B\u9762\u3002": "The clip is linked to MotionHarness. You can edit the source project or update the video.",
20753
20752
  "\u72EC\u7ACB\u526F\u672C\u9700\u8981\u53EF\u5B8C\u6574\u6821\u9A8C\u7684\u516C\u5F00\u5DE5\u7A0B\u5305\u3002": "An independent copy requires a fully verifiable public project package.",
20754
20753
  "\u72EC\u7ACB\u526F\u672C\u9700\u8981\u53EF\u7528\u7684\u6E90\u5DE5\u7A0B\u4E0E\u5F53\u524D\u89C6\u9891\u3002": "An independent copy requires the source project and current video to be available.",
20755
20754
  "\u7BA1\u7406\u6B64\u7D20\u6750\u7684\u5386\u53F2\u7248\u672C\u4E0E\u5DE5\u7A0B\u5173\u8054\u3002": "Manage this media's version history and project association.",
@@ -20776,11 +20775,11 @@ var en_default2 = {
20776
20775
  "\u6B64\u7D20\u6750\u6CA1\u6709\u53EF\u521B\u5EFA\u72EC\u7ACB\u526F\u672C\u7684\u65F6\u95F4\u7EBF\u7247\u6BB5\u3002": "This media has no timeline clips available for an independent copy.",
20777
20776
  \u4FEE\u590D\u8FDE\u63A5: "Repair connection",
20778
20777
  "\u6865\u63A5\u914D\u7F6E\u7F3A\u5931\u6216\u635F\u574F\uFF0C\u8BF7\u8FD0\u884C mh bridge davinci install \u4FEE\u590D\u7EC4\u4EF6\u3002": "Bridge configuration is missing or damaged. Run mh bridge davinci install to repair it.",
20779
- "MH \u672A\u8FDE\u63A5\uFF0C\u8BF7\u70B9\u51FB\u201C\u4FEE\u590D\u8FDE\u63A5\u201D\u3002": "MH is disconnected. Click Repair connection.",
20780
- "MH \u5165\u53E3\u5C31\u7EEA\uFF1B\u66F4\u65B0\u5F71\u54CD\u5168\u90E8\u5F15\u7528": "MH is ready; updates affect all references",
20781
- "\u627E\u4E0D\u5230 MH \u4E3B\u7A0B\u5E8F\u3002\u8BF7\u5B89\u88C5\u6216\u5347\u7EA7 CLI \u540E\u70B9\u51FB\u201C\u4FEE\u590D\u8FDE\u63A5\u201D\u3002": "MH could not be found. Install or upgrade the CLI, then click Repair connection.",
20782
- "\u6B63\u5728\u4FEE\u590D MH \u8FDE\u63A5\u2026": "Repairing the MH connection\u2026",
20783
- "MH \u8FDE\u63A5\u5DF2\u4FEE\u590D\uFF0C\u53EF\u91CD\u65B0\u70B9\u51FB\u7F16\u8F91\u6216\u66F4\u65B0\u3002": "MH connection repaired. You can click Edit or Update again.",
20778
+ "MotionHarness \u672A\u8FDE\u63A5\uFF0C\u8BF7\u70B9\u51FB\u201C\u4FEE\u590D\u8FDE\u63A5\u201D\u3002": "MotionHarness is disconnected. Click Repair connection.",
20779
+ "MotionHarness \u5165\u53E3\u5C31\u7EEA\uFF1B\u66F4\u65B0\u5F71\u54CD\u5168\u90E8\u5F15\u7528": "MotionHarness is ready; updates affect all references",
20780
+ "\u627E\u4E0D\u5230 MotionHarness \u4E3B\u7A0B\u5E8F\u3002\u8BF7\u5B89\u88C5\u6216\u5347\u7EA7 CLI \u540E\u70B9\u51FB\u201C\u4FEE\u590D\u8FDE\u63A5\u201D\u3002": "MotionHarness could not be found. Install or upgrade the CLI, then click Repair connection.",
20781
+ "\u6B63\u5728\u4FEE\u590D MotionHarness \u8FDE\u63A5\u2026": "Repairing the MotionHarness connection\u2026",
20782
+ "MotionHarness \u8FDE\u63A5\u5DF2\u4FEE\u590D\uFF0C\u53EF\u91CD\u65B0\u70B9\u51FB\u7F16\u8F91\u6216\u66F4\u65B0\u3002": "MotionHarness connection repaired. You can click Edit or Update again.",
20784
20783
  "\u8FDE\u63A5\u5C1A\u672A\u6062\u590D\uFF0C\u8BF7\u8FD0\u884C mh bridge davinci install \u4FEE\u590D\u7EC4\u4EF6\u3002": "The connection is still unavailable. Run mh bridge davinci install to repair the component.",
20785
20784
  "CLI \u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84\u3002": "The CLI path must be absolute.",
20786
20785
  "\u6865\u63A5\u5B89\u88C5\u8BB0\u5F55\u7F3A\u5931\uFF0C\u8BF7\u8FD0\u884C mh bridge davinci install\u3002": "The bridge installation record is missing. Run mh bridge davinci install.",
@@ -20812,7 +20811,7 @@ function bridgeText(source, locale = bridgeLocale()) {
20812
20811
  function bridgeMessage(source, values, locale = bridgeLocale()) {
20813
20812
  return bridgeText(source, locale).replace(/\{(\d+)\}/g, (token, index) => values[Number(index)] === void 0 ? token : String(values[Number(index)]));
20814
20813
  }
20815
- var bridgeName = (locale = bridgeLocale()) => bridgeText("Motion Harness \u6865\u63A5\u7EC4\u4EF6", locale);
20814
+ var bridgeName = (locale = bridgeLocale()) => bridgeText("MotionHarness \u6865\u63A5\u7EC4\u4EF6", locale);
20816
20815
  var bridgeEnglishCatalog = en_default2;
20817
20816
 
20818
20817
  // src/core/entry-context.ts
@@ -20860,7 +20859,7 @@ var OfxEntry = class {
20860
20859
  assert2(
20861
20860
  !Object.values(catalog.artifacts).some((artifact2) => this.store.artifactPath(artifact2.relativePath) === path),
20862
20861
  "OFX_SOURCE_STALE",
20863
- "\u4FA7\u680F\u4ECD\u63D0\u4F9B\u65E7\u7248\u89C6\u9891\u8DEF\u5F84\u3002\u8BF7\u4ECE\u300C\u5DE5\u4F5C\u533A \u2192 \u811A\u672C \u2192 Utility \u2192 Motion Harness \u6865\u63A5\u7EC4\u4EF6\u300D\u4E2D\u7684\u300C\u7F16\u8F91\u5DE5\u7A0B\u300D\u6216\u300C\u66F4\u65B0\u5230\u8FBE\u82AC\u5947\u300D\u7EE7\u7EED\u3002"
20862
+ "\u4FA7\u680F\u4ECD\u63D0\u4F9B\u65E7\u7248\u89C6\u9891\u8DEF\u5F84\u3002\u8BF7\u4ECE\u300C\u5DE5\u4F5C\u533A \u2192 \u811A\u672C \u2192 Utility \u2192 MotionHarness \u6865\u63A5\u7EC4\u4EF6\u300D\u4E2D\u7684\u300C\u7F16\u8F91\u5DE5\u7A0B\u300D\u6216\u300C\u66F4\u65B0\u5230\u8FBE\u82AC\u5947\u300D\u7EE7\u7EED\u3002"
20864
20863
  );
20865
20864
  }
20866
20865
  assert2(candidates.length === 1, "BINDING_CONFLICT", candidates.length ? "\u591A\u4E2A\u5173\u8054\u4F7F\u7528\u540C\u4E00\u89C6\u9891\uFF0C\u4FA7\u680F\u65E0\u6CD5\u786E\u5B9A\u76EE\u6807\u3002\u8BF7\u4F7F\u7528\u83DC\u5355\u7BA1\u7406\u7247\u6BB5\u3002" : "\u6B64\u89C6\u9891\u6CA1\u6709\u552F\u4E00\u7684\u5F53\u524D\u6865\u63A5\u5173\u8054\u3002");
@@ -21106,12 +21105,12 @@ var EntryContext = class {
21106
21105
  const ready = Boolean(binding && source && !conflict && !missingAssociation), busy = Boolean(task);
21107
21106
  const blocked = conflict ? bridgeText("\u6B64\u7D20\u6750\u643A\u5E26\u4E0D\u540C\u7684\u5173\u8054\u8EAB\u4EFD\uFF0C\u4E0D\u80FD\u8986\u76D6\u3002") : missingAssociation ? bridgeText("\u8BF7\u5148\u4FEE\u590D\u6B64\u7D20\u6750\u7684\u5173\u8054\u3002") : !binding || !source ? bridgeText("\u6B64\u7D20\u6750\u6CA1\u6709\u53EF\u6838\u5BF9\u7684\u672C\u673A\u5173\u8054\u3002") : task?.phase === "outcome-unknown" ? bridgeText("\u8BF7\u5148\u6838\u5B9E\u5DF2\u6709\u4EFB\u52A1\u7684\u7ED3\u679C\u3002") : busy ? bridgeText("\u8BF7\u7B49\u5F85\u5F53\u524D\u4EFB\u52A1\u7ED3\u675F\u3002") : "";
21108
21107
  const status = conflict ? "association-conflict" : !binding || !source ? "unlinked" : task?.phase === "outcome-unknown" ? "outcome-unknown" : busy ? "busy" : missingAssociation ? "association-missing" : !sourcePresent ? "source-missing" : "linked";
21109
- const message = blocked || (!sourcePresent ? bridgeText("\u627E\u4E0D\u5230\u6E90\u5DE5\u7A0B\u3002\u73B0\u6709\u89C6\u9891\u4ECD\u4FDD\u7559\uFF0C\u53EF\u9009\u62E9\u201C\u91CD\u65B0\u5B9A\u4F4D\u6E90\u5DE5\u7A0B\u201D\u3002") : selection.path ? bridgeText("\u7BA1\u7406\u6B64\u7D20\u6750\u7684\u5386\u53F2\u7248\u672C\u4E0E\u5DE5\u7A0B\u5173\u8054\u3002") : bridgeText("\u7247\u6BB5\u5DF2\u5173\u8054 Motion Harness\u3002\u53EF\u4EE5\u7F16\u8F91\u6E90\u5DE5\u7A0B\u6216\u66F4\u65B0\u753B\u9762\u3002"));
21108
+ const message = blocked || (!sourcePresent ? bridgeText("\u627E\u4E0D\u5230\u6E90\u5DE5\u7A0B\u3002\u73B0\u6709\u89C6\u9891\u4ECD\u4FDD\u7559\uFF0C\u53EF\u9009\u62E9\u201C\u91CD\u65B0\u5B9A\u4F4D\u6E90\u5DE5\u7A0B\u201D\u3002") : selection.path ? bridgeText("\u7BA1\u7406\u6B64\u7D20\u6750\u7684\u5386\u53F2\u7248\u672C\u4E0E\u5DE5\u7A0B\u5173\u8054\u3002") : bridgeText("\u7247\u6BB5\u5DF2\u5173\u8054 MotionHarness\u3002\u53EF\u4EE5\u7F16\u8F91\u6E90\u5DE5\u7A0B\u6216\u66F4\u65B0\u753B\u9762\u3002"));
21110
21109
  const location = [target.native.projectName, target.native.timelineName].filter((value) => typeof value === "string" && value.trim().length > 0).join(" / ");
21111
21110
  const scopeMessage = taskScope?.message ?? bridgeText("\u66F4\u65B0\u6216\u6062\u590D\u7248\u672C\u4F1A\u5F71\u54CD\u6B64\u7D20\u6750\u5728\u5F53\u524D\u8FBE\u82AC\u5947\u5DE5\u7A0B\u4E2D\u7684\u5168\u90E8\u5F15\u7528\u3002");
21112
21111
  const context = {
21113
21112
  selection: target.selection,
21114
- title: source?.name ?? target.native.name ?? "Motion Harness",
21113
+ title: source?.name ?? target.native.name ?? "MotionHarness",
21115
21114
  status,
21116
21115
  message,
21117
21116
  sourceDirectory: source && !conflict ? this.store.path(source.locator) : void 0,
@@ -21271,15 +21270,62 @@ var EntryContext = class {
21271
21270
 
21272
21271
  // src/native-install.ts
21273
21272
  import { homedir as homedir3 } from "node:os";
21274
- import { basename as basename4, delimiter as delimiter3, dirname as dirname8, isAbsolute as isAbsolute8, join as join7, resolve as resolve10 } from "node:path";
21275
- import { access as access3, mkdir as mkdir8, readFile as readFile9, writeFile, rename as rename6, rm as rm7, rmdir, readdir as readdir2, stat as stat6, lstat as lstat5 } from "node:fs/promises";
21273
+ import { basename as basename4, delimiter as delimiter3, dirname as dirname9, isAbsolute as isAbsolute8, join as join8, resolve as resolve10 } from "node:path";
21274
+ import { access as access3, mkdir as mkdir8, readFile as readFile10, writeFile, rename as rename6, rm as rm7, rmdir, readdir as readdir2, stat as stat6, lstat as lstat5 } from "node:fs/promises";
21276
21275
  import { constants as constants6 } from "node:fs";
21277
21276
  import { randomUUID as randomUUID7 } from "node:crypto";
21278
21277
 
21278
+ // src/sidebar-guide.ts
21279
+ import { readFile as readFile9 } from "node:fs/promises";
21280
+ import { dirname as dirname7, join as join6 } from "node:path";
21281
+ var sidebarHint = {
21282
+ optional: true,
21283
+ title: "\u6DFB\u52A0\u4FA7\u680F\u7F16\u8F91\u5165\u53E3\uFF08\u53EF\u9009\uFF09",
21284
+ message: "\u7D20\u6750\u5DF2\u53D1\u9001\u5E76\u5173\u8054\u5DE5\u7A0B\u3002\u60F3\u4ECE\u8FBE\u82AC\u5947\u4FA7\u680F\u76F4\u63A5\u7F16\u8F91\uFF0C\u53EF\u6DFB\u52A0 MotionHarness \u6865\u63A5\u7EC4\u4EF6\u3002",
21285
+ steps: [
21286
+ "\u5728\u8FBE\u82AC\u5947\u300C\u526A\u8F91\u300D\u9875\u6253\u5F00\u5DE6\u4E0A\u89D2\u300C\u7279\u6548\u5E93\u300D\uFF08\u9B54\u68D2\u56FE\u6807\uFF09\u3002",
21287
+ "\u70B9\u51FB\u653E\u5927\u955C\uFF0C\u641C\u7D22 MotionHarness \u6865\u63A5\u7EC4\u4EF6\uFF0C\u5C06 Open FX \u4E2D\u7684\u540C\u540D\u6548\u679C\u62D6\u5230\u76EE\u6807\u52A8\u6548\u7247\u6BB5\u3002",
21288
+ "\u9009\u4E2D\u7247\u6BB5\uFF0C\u5728\u300C\u68C0\u67E5\u5668 \u2192 \u7279\u6548 \u2192 Open FX\u300D\u4E2D\u70B9\u51FB\u300C\u7F16\u8F91 MotionHarness \u5DE5\u7A0B\u300D\u3002"
21289
+ ],
21290
+ shortcut: "\u4E5F\u53EF\u5148\u9009\u4E2D\u7247\u6BB5\uFF0C\u6309 Shift + Space \u641C\u7D22\u5E76\u6DFB\u52A0\u3002",
21291
+ alternative: "\u4E0D\u6DFB\u52A0\u4E5F\u80FD\u4ECE\u300C\u5DE5\u4F5C\u533A \u2192 \u811A\u672C \u2192 Utility \u2192 MotionHarness \u6865\u63A5\u7EC4\u4EF6 \u2192 \u7F16\u8F91\u5DE5\u7A0B\u300D\u6253\u5F00\u3002",
21292
+ guideCommand: "mh bridge davinci sidebar-guide"
21293
+ };
21294
+ function sidebarHintForLocale(locale = bridgeLocale()) {
21295
+ if (locale !== "en") return sidebarHint;
21296
+ return {
21297
+ ...sidebarHint,
21298
+ title: "Add sidebar entry (optional)",
21299
+ message: `The media is linked to its source project. Add the ${bridgeName(locale)} to edit from the DaVinci Resolve sidebar.`,
21300
+ steps: [
21301
+ "On the Edit page in DaVinci Resolve, open the Effects Library (magic wand icon).",
21302
+ "Search for MotionHarness Bridge Component and drag the Open FX effect onto the target clip.",
21303
+ "Select the clip and click Edit MotionHarness project under Inspector \u2192 Effects \u2192 Open FX."
21304
+ ],
21305
+ shortcut: "You can also select the clip, press Shift + Space, then search and add the effect.",
21306
+ alternative: "You can also open the project from Workspace \u2192 Scripts \u2192 Utility \u2192 MotionHarness Bridge Component \u2192 Edit project."
21307
+ };
21308
+ }
21309
+ async function readSidebarGuideDocument(guidePath) {
21310
+ const html = await readFile9(guidePath, "utf8");
21311
+ const link2 = '<link rel="stylesheet" href="guide.css">';
21312
+ if (!html.includes(link2)) return html;
21313
+ const css = await readFile9(join6(dirname7(guidePath), "guide.css"), "utf8");
21314
+ return html.replace(link2, () => `<style>
21315
+ ${css}</style>`);
21316
+ }
21317
+ async function readSidebarGuide(componentRoot, inline = false, locale = bridgeLocale()) {
21318
+ const directory = join6(componentRoot, "resources/sidebar-help");
21319
+ const guidePath = join6(directory, locale === "en" ? "en.html" : "index.html");
21320
+ const hint = sidebarHintForLocale(locale);
21321
+ if (!inline) return { ...hint, guidePath };
21322
+ return { ...hint, html: await readSidebarGuideDocument(guidePath) };
21323
+ }
21324
+
21279
21325
  // src/native-permissions.ts
21280
21326
  import { access as access2, lstat as lstat4 } from "node:fs/promises";
21281
21327
  import { constants as constants5 } from "node:fs";
21282
- import { dirname as dirname7, join as join6, resolve as resolve9 } from "node:path";
21328
+ import { dirname as dirname8, join as join7, resolve as resolve9 } from "node:path";
21283
21329
  var systemPluginRoot = "/Library/OFX/Plugins";
21284
21330
  async function prepareOfxPermissions(componentRoot, pluginRoot, directories) {
21285
21331
  let writable = true;
@@ -21299,11 +21345,11 @@ async function prepareOfxPermissions(componentRoot, pluginRoot, directories) {
21299
21345
  }
21300
21346
  break;
21301
21347
  }
21302
- const parent = dirname7(current);
21348
+ const parent = dirname8(current);
21303
21349
  assert2(parent !== current, "INSTALL_CONFLICT", "\u627E\u4E0D\u5230 OFX \u5B89\u88C5\u76EE\u5F55\u7684\u7236\u76EE\u5F55\u3002");
21304
21350
  current = parent;
21305
21351
  }
21306
- for (let ancestor = dirname7(current); ancestor !== dirname7(ancestor); ancestor = dirname7(ancestor)) {
21352
+ for (let ancestor = dirname8(current); ancestor !== dirname8(ancestor); ancestor = dirname8(ancestor)) {
21307
21353
  const info2 = await lstat4(ancestor);
21308
21354
  assert2(info2.isDirectory() && !info2.isSymbolicLink(), "INSTALL_CONFLICT", "OFX \u5B89\u88C5\u8DEF\u5F84\u5305\u542B\u7B26\u53F7\u94FE\u63A5\u3002", { path: ancestor });
21309
21355
  }
@@ -21320,7 +21366,7 @@ async function prepareOfxPermissions(componentRoot, pluginRoot, directories) {
21320
21366
  "\u4FEE\u590D\u81EA\u5B9A\u4E49 OFX \u76EE\u5F55\u6743\u9650\u540E\u91CD\u65B0\u8FD0\u884C mh bridge davinci install\uFF1B\u4E0D\u8981\u4EE5 root \u8FD0\u884C\u6574\u4E2A CLI\u3002"
21321
21367
  );
21322
21368
  }
21323
- const helper = join6(componentRoot, "resources/HotionHarnessInstall");
21369
+ const helper = join7(componentRoot, "resources/MotionHarnessInstall");
21324
21370
  const info = await lstat4(helper);
21325
21371
  assert2(info.isFile() && !info.isSymbolicLink(), "INSTALL_CONFLICT", "OFX \u6743\u9650\u52A9\u624B\u5FC5\u987B\u662F\u7ECF\u8FC7\u7EC4\u4EF6\u6821\u9A8C\u7684\u666E\u901A\u53EF\u6267\u884C\u6587\u4EF6\u3002");
21326
21372
  await access2(helper, constants5.X_OK);
@@ -21346,11 +21392,11 @@ end timeout`;
21346
21392
  }
21347
21393
 
21348
21394
  // src/native-install.ts
21349
- var statusAppName = "HotionHarnessStatus.app";
21350
- var statusAppBinary = join7("Contents", "MacOS", "HotionHarnessStatus");
21351
- var recordPath = (root) => join7(root, "native-install.json");
21395
+ var statusAppName = "MotionHarnessBridge.app";
21396
+ var statusAppBinary = join8("Contents", "MacOS", "MotionHarnessBridge");
21397
+ var recordPath = (root) => join8(root, "native-install.json");
21352
21398
  async function previous(root) {
21353
- return readFile9(recordPath(root), "utf8").then(JSON.parse).catch((error48) => {
21399
+ return readFile10(recordPath(root), "utf8").then(JSON.parse).catch((error48) => {
21354
21400
  if (error48.code !== "ENOENT") throw error48;
21355
21401
  return { version: 1, files: [], entry: { automaticAttachment: false, ofx: "unavailable" } };
21356
21402
  });
@@ -21358,12 +21404,12 @@ async function previous(root) {
21358
21404
  async function nativeStatus(configRoot) {
21359
21405
  const manifest = await previous(configRoot);
21360
21406
  const matches = async (file2) => Boolean(file2 && await fileDigest(file2.path).then(async (actual) => actual === file2.sha256 && (process.platform === "win32" || file2.mode === void 0 || ((await stat6(file2.path)).mode & 511) === file2.mode), () => false));
21361
- const helperPath = manifest.statusExecutable ?? join7(configRoot, "bin/HotionHarnessStatus");
21362
- const applicationRoot = join7(configRoot, "bin", statusAppName);
21363
- const application = helperPath === join7(applicationRoot, statusAppBinary);
21407
+ const helperPath = manifest.statusExecutable ?? join8(configRoot, "bin/HotionHarnessStatus");
21408
+ const applicationRoot = join8(configRoot, "bin", statusAppName);
21409
+ const application = helperPath === join8(applicationRoot, statusAppBinary);
21364
21410
  const helper = manifest.files.find((file2) => file2.path === helperPath);
21365
21411
  const applicationFiles = application ? manifest.files.filter((file2) => file2.path.startsWith(applicationRoot + "/")) : [];
21366
- const applicationComplete = !application || applicationFiles.some((file2) => file2.path === join7(applicationRoot, "Contents/Info.plist")) && (await Promise.all(applicationFiles.map(matches))).every(Boolean);
21412
+ const applicationComplete = !application || applicationFiles.some((file2) => file2.path === join8(applicationRoot, "Contents/Info.plist")) && (await Promise.all(applicationFiles.map(matches))).every(Boolean);
21367
21413
  const helperInstalled = manifest.entry.statusHelper === "installed" && await matches(helper) && applicationComplete;
21368
21414
  const names = [["\u7F16\u8F91\u5DE5\u7A0B.py", "Edit project.py"], ["\u66F4\u65B0\u5230\u8FBE\u82AC\u5947.py", "Update in DaVinci Resolve.py"]];
21369
21415
  const menusInstalled = helperInstalled && (await Promise.all(names.map(async (alternatives) => (await Promise.all(manifest.files.filter((file2) => alternatives.includes(basename4(file2.path))).map(matches))).some(Boolean)))).every(Boolean);
@@ -21379,7 +21425,7 @@ async function nativeStatus(configRoot) {
21379
21425
  };
21380
21426
  }
21381
21427
  async function publish(path, bytes, mode = 384) {
21382
- await mkdir8(dirname8(path), { recursive: true });
21428
+ await mkdir8(dirname9(path), { recursive: true });
21383
21429
  const pending = `${path}.${randomUUID7()}.pending`;
21384
21430
  try {
21385
21431
  await writeFile(pending, bytes, { flag: "wx", mode });
@@ -21402,10 +21448,10 @@ async function toolPath(command) {
21402
21448
  async function cliLauncher(cliPath) {
21403
21449
  const packageJson = process.env.MH_NPM_PACKAGE_JSON;
21404
21450
  if (!packageJson || !isAbsolute8(packageJson)) return void 0;
21405
- const pkg = JSON.parse(await readFile9(packageJson, "utf8"));
21451
+ const pkg = JSON.parse(await readFile10(packageJson, "utf8"));
21406
21452
  if (pkg.name !== "@motionharness/cli" || typeof pkg.bin?.mh !== "string") return void 0;
21407
- const script = resolve10(dirname8(packageJson), pkg.bin.mh);
21408
- if (!script.startsWith(dirname8(packageJson) + "/") || !(await stat6(script)).isFile()) return void 0;
21453
+ const script = resolve10(dirname9(packageJson), pkg.bin.mh);
21454
+ if (!script.startsWith(dirname9(packageJson) + "/") || !(await stat6(script)).isFile()) return void 0;
21409
21455
  assert2(isAbsolute8(cliPath), "INSTALL_CONFLICT", "CLI \u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84\u3002");
21410
21456
  return { executable: process.execPath, script };
21411
21457
  }
@@ -21426,9 +21472,9 @@ async function repairNativeConnection(options) {
21426
21472
  const value = JSON.parse(config2.bytes.toString("utf8"));
21427
21473
  const launcher = await cliLauncher(options.cliPath);
21428
21474
  const tools = { ...value.tools, node: process.execPath };
21429
- const toolDirectories = [...new Set(Object.values(tools).filter((path) => typeof path === "string" && isAbsolute8(path)).map(dirname8))];
21475
+ const toolDirectories = [...new Set(Object.values(tools).filter((path) => typeof path === "string" && isAbsolute8(path)).map(dirname9))];
21430
21476
  const bytes = JSON.stringify({ ...value, cliPath: options.cliPath, ...launcher ? { cliLauncher: launcher } : {}, tools, toolDirectories }, null, 2) + "\n";
21431
- const toolchainPath = join7(options.configRoot, "toolchain.json");
21477
+ const toolchainPath = join8(options.configRoot, "toolchain.json");
21432
21478
  const toolchain = await readNativeFile(toolchainPath), savedTools = manifest.files.find((file2) => file2.path === toolchainPath);
21433
21479
  assert2(toolchain && savedTools?.sha256 === "sha256:" + toolchain.sha256 && (savedTools.mode === void 0 || savedTools.mode === toolchain.mode), "INSTALL_CONFLICT", "\u6865\u63A5\u5DE5\u5177\u914D\u7F6E\u5DF2\u88AB\u4FEE\u6539\uFF0C\u672A\u8986\u76D6\u3002");
21434
21480
  const changes = [
@@ -21443,12 +21489,12 @@ async function repairNativeConnection(options) {
21443
21489
  async function bundleFiles(source, destination, executable) {
21444
21490
  const files = [];
21445
21491
  for (const item of await readdir2(source, { withFileTypes: true })) {
21446
- const path = join7(source, item.name), output = join7(destination, item.name);
21492
+ const path = join8(source, item.name), output = join8(destination, item.name);
21447
21493
  assert2(!item.isSymbolicLink(), "INSTALL_CONFLICT", "\u539F\u751F\u5B89\u88C5\u8D44\u6E90\u4E0D\u80FD\u5305\u542B\u7B26\u53F7\u94FE\u63A5\u3002");
21448
21494
  if (item.isDirectory()) files.push(...await bundleFiles(path, output, executable));
21449
21495
  else {
21450
21496
  assert2(item.isFile(), "INSTALL_CONFLICT", "\u539F\u751F\u5B89\u88C5\u8D44\u6E90\u53EA\u80FD\u5305\u542B\u666E\u901A\u6587\u4EF6\u3002");
21451
- files.push({ path: output, bytes: await readFile9(path), mode: output === executable || (await stat6(path)).mode & 73 ? 493 : 420 });
21497
+ files.push({ path: output, bytes: await readFile10(path), mode: output === executable || (await stat6(path)).mode & 73 ? 493 : 420 });
21452
21498
  }
21453
21499
  }
21454
21500
  return files;
@@ -21457,7 +21503,7 @@ async function installNative(options) {
21457
21503
  assert2(!options.requireComplete || process.platform === "darwin", "PLATFORM_UNSUPPORTED", "\u5305\u542B\u83DC\u5355\u3001\u5C0F\u7A97\u53E3\u4E0E OFX \u7684\u6865\u63A5\u5B89\u88C5\u76EE\u524D\u53EA\u652F\u6301 macOS\u3002");
21458
21504
  assert2(!options.requireComplete || process.getuid?.() !== 0, "INSTALL_AS_USER", "\u8BF7\u4EE5\u666E\u901A\u7528\u6237\u8FD0\u884C mh bridge davinci install\uFF1B\u9700\u8981\u7CFB\u7EDF\u6743\u9650\u65F6\u4F1A\u5355\u72EC\u8BF7\u6C42\u6388\u6743\u3002");
21459
21505
  await finishNativeInstall(options.configRoot);
21460
- const previousRecord = await readFile9(recordPath(options.configRoot)).catch((error48) => {
21506
+ const previousRecord = await readFile10(recordPath(options.configRoot)).catch((error48) => {
21461
21507
  if (error48.code === "ENOENT") return null;
21462
21508
  throw error48;
21463
21509
  });
@@ -21466,11 +21512,11 @@ async function installNative(options) {
21466
21512
  const expectedRecord = previousRecord ? { sha256: sha256(previousRecord), mode: (await stat6(recordPath(options.configRoot))).mode & 511 } : null;
21467
21513
  const validated = /* @__PURE__ */ new Map();
21468
21514
  const locale = bridgeLocale(), label = bridgeName(locale);
21469
- const scriptsRoot = process.env.MH_DAVINCI_SCRIPTS_DIR ?? (process.platform === "darwin" ? join7(homedir3(), "Library/Application Support/Blackmagic Design/DaVinci Resolve/Fusion/Scripts/Utility", label) : process.platform === "win32" ? join7(process.env.APPDATA ?? homedir3(), "Blackmagic Design/DaVinci Resolve/Support/Fusion/Scripts/Utility", label) : join7(homedir3(), ".local/share/DaVinciResolve/Fusion/Scripts/Utility", label));
21470
- const nativeConfig = process.env.MH_DAVINCI_NATIVE_CONFIG ?? (process.platform === "darwin" ? join7(homedir3(), "Library/Application Support/Hotion Harness/bridge/davinci/native-entry.json") : join7(options.configRoot, "native-entry.json"));
21471
- const template = await readFile9(join7(options.componentRoot, "resources/menu-entry.py"), "utf8");
21472
- const helper = join7(options.componentRoot, "resources/HotionHarnessStatus");
21473
- const application = join7(options.componentRoot, "resources", statusAppName);
21515
+ const scriptsRoot = process.env.MH_DAVINCI_SCRIPTS_DIR ?? (process.platform === "darwin" ? join8(homedir3(), "Library/Application Support/Blackmagic Design/DaVinci Resolve/Fusion/Scripts/Utility", label) : process.platform === "win32" ? join8(process.env.APPDATA ?? homedir3(), "Blackmagic Design/DaVinci Resolve/Support/Fusion/Scripts/Utility", label) : join8(homedir3(), ".local/share/DaVinciResolve/Fusion/Scripts/Utility", label));
21516
+ const nativeConfig = process.env.MH_DAVINCI_NATIVE_CONFIG ?? (process.platform === "darwin" ? join8(homedir3(), "Library/Application Support/Hotion Harness/bridge/davinci/native-entry.json") : join8(options.configRoot, "native-entry.json"));
21517
+ const template = await readFile10(join8(options.componentRoot, "resources/menu-entry.py"), "utf8");
21518
+ const helper = join8(options.componentRoot, "resources/HotionHarnessStatus");
21519
+ const application = join8(options.componentRoot, "resources", statusAppName);
21474
21520
  const resourceInfo = async (path) => process.platform === "darwin" ? lstat5(path).catch((error48) => {
21475
21521
  if (error48.code === "ENOENT") return null;
21476
21522
  throw error48;
@@ -21479,39 +21525,39 @@ async function installNative(options) {
21479
21525
  assert2(!applicationInfo || applicationInfo.isDirectory(), "INSTALL_CONFLICT", "\u72B6\u6001\u7A97\u53E3\u5E94\u7528\u5FC5\u987B\u662F\u666E\u901A\u76EE\u5F55\u3002");
21480
21526
  const helperInfo = applicationInfo ? null : await resourceInfo(helper);
21481
21527
  assert2(!helperInfo || helperInfo.isFile(), "INSTALL_CONFLICT", "\u72B6\u6001\u7A97\u53E3\u8D44\u6E90\u5FC5\u987B\u662F\u666E\u901A\u53EF\u6267\u884C\u6587\u4EF6\u3002");
21482
- const statusExecutable = applicationInfo ? join7(options.configRoot, "bin", statusAppName, statusAppBinary) : helperInfo ? join7(options.configRoot, "bin/HotionHarnessStatus") : void 0;
21528
+ const statusExecutable = applicationInfo ? join8(options.configRoot, "bin", statusAppName, statusAppBinary) : helperInfo ? join8(options.configRoot, "bin/HotionHarnessStatus") : void 0;
21483
21529
  const tools = {
21484
21530
  node: process.execPath,
21485
21531
  pnpm: await toolPath(process.platform === "win32" ? "pnpm.cmd" : "pnpm"),
21486
21532
  ffmpeg: await toolPath(process.env.MH_FFMPEG ?? "ffmpeg"),
21487
21533
  ffprobe: await toolPath(process.env.MH_FFPROBE ?? "ffprobe")
21488
21534
  };
21489
- const toolDirectories = [...new Set(Object.values(tools).filter((path) => Boolean(path)).map(dirname8))];
21535
+ const toolDirectories = [...new Set(Object.values(tools).filter((path) => Boolean(path)).map(dirname9))];
21490
21536
  const toolchain = { schemaVersion: 1, tools, toolDirectories };
21491
21537
  const desired = [];
21492
- const translationsPath = join7(options.configRoot, "i18n/en.json");
21538
+ const translationsPath = join8(options.configRoot, "i18n/en.json");
21493
21539
  desired.push({ path: translationsPath, bytes: JSON.stringify(bridgeEnglishCatalog), mode: 420 });
21494
21540
  const guideNames = ["index.html", "en.html"];
21495
- const guideDirectory = join7(options.componentRoot, "resources/sidebar-help");
21496
- const guideAvailable = (await Promise.all(guideNames.map((name) => lstat5(join7(guideDirectory, name)).then((info) => info.isFile(), (error48) => {
21541
+ const guideDirectory = join8(options.componentRoot, "resources/sidebar-help");
21542
+ const guideAvailable = (await Promise.all(guideNames.map((name) => lstat5(join8(guideDirectory, name)).then((info) => info.isFile(), (error48) => {
21497
21543
  if (error48.code === "ENOENT") return false;
21498
21544
  throw error48;
21499
21545
  })))).every(Boolean);
21500
- const sidebarGuidePath = guideAvailable ? join7(options.configRoot, "help/sidebar", locale === "en" ? "en.html" : "index.html") : void 0;
21546
+ const sidebarGuidePath = guideAvailable ? join8(options.configRoot, "help/sidebar", locale === "en" ? "en.html" : "index.html") : void 0;
21501
21547
  if (guideAvailable) for (const name of guideNames) desired.push({
21502
- path: join7(options.configRoot, "help/sidebar", name),
21503
- bytes: await readFile9(join7(guideDirectory, name)),
21548
+ path: join8(options.configRoot, "help/sidebar", name),
21549
+ bytes: await readSidebarGuideDocument(join8(guideDirectory, name)),
21504
21550
  mode: 420
21505
21551
  });
21506
21552
  if (applicationInfo) {
21507
- desired.push(...await bundleFiles(application, join7(options.configRoot, "bin", statusAppName), statusExecutable));
21553
+ desired.push(...await bundleFiles(application, join8(options.configRoot, "bin", statusAppName), statusExecutable));
21508
21554
  assert2(
21509
- desired.some((file2) => file2.path === statusExecutable) && desired.some((file2) => file2.path === join7(options.configRoot, "bin", statusAppName, "Contents/Info.plist")),
21555
+ desired.some((file2) => file2.path === statusExecutable) && desired.some((file2) => file2.path === join8(options.configRoot, "bin", statusAppName, "Contents/Info.plist")),
21510
21556
  "INSTALL_CONFLICT",
21511
21557
  "\u72B6\u6001\u7A97\u53E3\u5E94\u7528\u7F3A\u5C11\u53EF\u6267\u884C\u6587\u4EF6\u6216 Info.plist\u3002"
21512
21558
  );
21513
- } else if (statusExecutable) desired.push({ path: statusExecutable, bytes: await readFile9(helper), mode: 493 });
21514
- desired.push({ path: join7(options.configRoot, "toolchain.json"), bytes: JSON.stringify(toolchain, null, 2) + "\n", mode: 384 });
21559
+ } else if (statusExecutable) desired.push({ path: statusExecutable, bytes: await readFile10(helper), mode: 493 });
21560
+ desired.push({ path: join8(options.configRoot, "toolchain.json"), bytes: JSON.stringify(toolchain, null, 2) + "\n", mode: 384 });
21515
21561
  const launcher = await cliLauncher(options.cliPath);
21516
21562
  desired.push({ path: nativeConfig, bytes: JSON.stringify({
21517
21563
  schemaVersion: 1,
@@ -21521,7 +21567,7 @@ async function installNative(options) {
21521
21567
  cliPath: options.cliPath,
21522
21568
  ...launcher ? { cliLauncher: launcher } : {},
21523
21569
  workspace: options.workspace,
21524
- bridgeDirectory: dirname8(options.configRoot),
21570
+ bridgeDirectory: dirname9(options.configRoot),
21525
21571
  tools,
21526
21572
  toolDirectories,
21527
21573
  locale,
@@ -21530,18 +21576,18 @@ async function installNative(options) {
21530
21576
  ...statusExecutable ? { statusExecutable } : {}
21531
21577
  }, null, 2) + "\n", mode: 384 });
21532
21578
  for (const [label2, action2] of statusExecutable ? [["\u7F16\u8F91\u5DE5\u7A0B", "edit"], ["\u66F4\u65B0\u5230\u8FBE\u82AC\u5947", "update"]] : []) {
21533
- desired.push({ path: join7(scriptsRoot, `${bridgeText(label2, locale)}.py`), bytes: template.replaceAll("__HOTION_ACTION_JSON__", JSON.stringify(action2)).replaceAll("__HOTION_CONFIG_PATH_JSON__", JSON.stringify(nativeConfig)).replaceAll("__HOTION_STATUS_PATH_JSON__", JSON.stringify(statusExecutable)), mode: 384 });
21579
+ desired.push({ path: join8(scriptsRoot, `${bridgeText(label2, locale)}.py`), bytes: template.replaceAll("__HOTION_ACTION_JSON__", JSON.stringify(action2)).replaceAll("__HOTION_CONFIG_PATH_JSON__", JSON.stringify(nativeConfig)).replaceAll("__HOTION_STATUS_PATH_JSON__", JSON.stringify(statusExecutable)), mode: 384 });
21534
21580
  }
21535
21581
  const registeredForwarder = await prepareRegisteredForwarder(options, old, statusExecutable, nativeConfig);
21536
21582
  if (registeredForwarder) desired.push(registeredForwarder.file);
21537
- const bundle = join7(options.componentRoot, "resources", "HotionHarness.ofx.bundle");
21583
+ const bundle = join8(options.componentRoot, "resources", "HotionHarness.ofx.bundle");
21538
21584
  const bundleInfo = process.platform === "darwin" ? await lstat5(bundle).catch((error48) => {
21539
21585
  if (error48.code === "ENOENT") return null;
21540
21586
  throw error48;
21541
21587
  }) : null;
21542
21588
  assert2(!bundleInfo || bundleInfo.isDirectory(), "INSTALL_CONFLICT", "OFX \u5B89\u88C5\u8D44\u6E90\u5FC5\u987B\u662F\u666E\u901A\u76EE\u5F55\u3002");
21543
21589
  const pluginRoot = process.env.MH_DAVINCI_OFX_DIR ?? (process.platform === "darwin" ? "/Library/OFX/Plugins" : void 0);
21544
- const pluginFiles = bundleInfo && pluginRoot ? await bundleFiles(bundle, join7(pluginRoot, "HotionHarness.ofx.bundle")) : [];
21590
+ const pluginFiles = bundleInfo && pluginRoot ? await bundleFiles(bundle, join8(pluginRoot, "HotionHarness.ofx.bundle")) : [];
21545
21591
  if (options.requireComplete) {
21546
21592
  assert2(
21547
21593
  applicationInfo && pluginFiles.some((file2) => file2.path.endsWith("/Contents/MacOS/HotionHarness.ofx")) && pluginFiles.some((file2) => file2.path.endsWith("/Contents/Info.plist")),
@@ -21583,7 +21629,7 @@ async function installNative(options) {
21583
21629
  } catch (error48) {
21584
21630
  if (!["EACCES", "EPERM"].includes(error48.code ?? "")) throw error48;
21585
21631
  }
21586
- await prepareOfxPermissions(options.componentRoot, pluginRoot, pluginFiles.map((file2) => dirname8(file2.path)));
21632
+ await prepareOfxPermissions(options.componentRoot, pluginRoot, pluginFiles.map((file2) => dirname9(file2.path)));
21587
21633
  }
21588
21634
  let pluginAccessible = true;
21589
21635
  try {
@@ -21643,9 +21689,9 @@ async function installNative(options) {
21643
21689
  if (!pluginAccessible || !["EACCES", "EPERM", "EROFS"].includes(failure.code ?? "") || !optionalPath) throw error48;
21644
21690
  await apply(false);
21645
21691
  }
21646
- const retiredGroups = ["Hotion Harness", "Motion Harness", "Motion Harness \u6865\u63A5\u7EC4\u4EF6", "Motion Harness Bridge Component"];
21647
- for (const directory of new Set(removed.map(dirname8))) {
21648
- if (directory === scriptsRoot || !retiredGroups.includes(basename4(directory)) || basename4(dirname8(directory)) !== "Utility") continue;
21692
+ const retiredGroups = ["Hotion Harness", "Motion Harness", "Motion Harness \u6865\u63A5\u7EC4\u4EF6", "Motion Harness Bridge Component", "MotionHarness", "MotionHarness \u6865\u63A5\u7EC4\u4EF6", "MotionHarness Bridge Component"];
21693
+ for (const directory of new Set(removed.map(dirname9))) {
21694
+ if (directory === scriptsRoot || !retiredGroups.includes(basename4(directory)) || basename4(dirname9(directory)) !== "Utility") continue;
21649
21695
  await rmdir(directory).catch((error48) => {
21650
21696
  if (!["ENOENT", "ENOTEMPTY", "EEXIST", "EACCES", "EPERM"].includes(error48.code)) throw error48;
21651
21697
  });
@@ -21682,46 +21728,6 @@ async function uninstallNative({ configRoot }) {
21682
21728
  return { installed: false, removed, retained: retained.map((file2) => file2.path), associationsPreserved: true, legacyForwarder };
21683
21729
  }
21684
21730
 
21685
- // src/sidebar-guide.ts
21686
- import { readFile as readFile10 } from "node:fs/promises";
21687
- import { join as join8 } from "node:path";
21688
- var sidebarHint = {
21689
- optional: true,
21690
- title: "\u6DFB\u52A0\u4FA7\u680F\u7F16\u8F91\u5165\u53E3\uFF08\u53EF\u9009\uFF09",
21691
- message: "\u7D20\u6750\u5DF2\u53D1\u9001\u5E76\u5173\u8054\u5DE5\u7A0B\u3002\u60F3\u4ECE\u8FBE\u82AC\u5947\u4FA7\u680F\u76F4\u63A5\u7F16\u8F91\uFF0C\u53EF\u6DFB\u52A0 Motion Harness \u6865\u63A5\u7EC4\u4EF6\u3002",
21692
- steps: [
21693
- "\u5728\u8FBE\u82AC\u5947\u300C\u526A\u8F91\u300D\u9875\u6253\u5F00\u5DE6\u4E0A\u89D2\u300C\u7279\u6548\u5E93\u300D\uFF08\u9B54\u68D2\u56FE\u6807\uFF09\u3002",
21694
- "\u70B9\u51FB\u653E\u5927\u955C\uFF0C\u641C\u7D22 Motion Harness \u6865\u63A5\u7EC4\u4EF6\uFF0C\u5C06 Open FX \u4E2D\u7684\u540C\u540D\u6548\u679C\u62D6\u5230\u76EE\u6807\u52A8\u6548\u7247\u6BB5\u3002",
21695
- "\u9009\u4E2D\u7247\u6BB5\uFF0C\u5728\u300C\u68C0\u67E5\u5668 \u2192 \u7279\u6548 \u2192 Open FX\u300D\u4E2D\u70B9\u51FB\u300C\u7F16\u8F91 Motion Harness \u5DE5\u7A0B\u300D\u3002"
21696
- ],
21697
- shortcut: "\u4E5F\u53EF\u5148\u9009\u4E2D\u7247\u6BB5\uFF0C\u6309 Shift + Space \u641C\u7D22\u5E76\u6DFB\u52A0\u3002",
21698
- alternative: "\u4E0D\u6DFB\u52A0\u4E5F\u80FD\u4ECE\u300C\u5DE5\u4F5C\u533A \u2192 \u811A\u672C \u2192 Utility \u2192 Motion Harness \u6865\u63A5\u7EC4\u4EF6 \u2192 \u7F16\u8F91\u5DE5\u7A0B\u300D\u6253\u5F00\u3002",
21699
- guideCommand: "mh bridge davinci sidebar-guide"
21700
- };
21701
- function sidebarHintForLocale(locale = bridgeLocale()) {
21702
- if (locale !== "en") return sidebarHint;
21703
- return {
21704
- ...sidebarHint,
21705
- title: "Add sidebar entry (optional)",
21706
- message: `The media is linked to its source project. Add the ${bridgeName(locale)} to edit from the DaVinci Resolve sidebar.`,
21707
- steps: [
21708
- "On the Edit page in DaVinci Resolve, open the Effects Library (magic wand icon).",
21709
- "Search for Motion Harness Bridge Component and drag the Open FX effect onto the target clip.",
21710
- "Select the clip and click Edit Motion Harness project under Inspector \u2192 Effects \u2192 Open FX."
21711
- ],
21712
- shortcut: "You can also select the clip, press Shift + Space, then search and add the effect.",
21713
- alternative: "You can also open the project from Workspace \u2192 Scripts \u2192 Utility \u2192 Motion Harness Bridge Component \u2192 Edit project."
21714
- };
21715
- }
21716
- async function readSidebarGuide(componentRoot, inline = false, locale = bridgeLocale()) {
21717
- const directory = join8(componentRoot, "resources/sidebar-help");
21718
- const guidePath = join8(directory, locale === "en" ? "en.html" : "index.html");
21719
- const hint = sidebarHintForLocale(locale);
21720
- if (!inline) return { ...hint, guidePath };
21721
- const html = await readFile10(guidePath, "utf8");
21722
- return { ...hint, html };
21723
- }
21724
-
21725
21731
  // src/runner.ts
21726
21732
  var taskView = (job) => ({
21727
21733
  ...job,
@@ -22115,18 +22121,18 @@ async function execute(request) {
22115
22121
  const key = digest(sourceId).slice(7), marker = bridge.store.path(`.scratch/editor-${key}.json`);
22116
22122
  return bridge.store.withLock(`editor-${key}`, async () => {
22117
22123
  if (bindingId) {
22118
- await mkdir9(dirname9(marker), { recursive: true });
22124
+ await mkdir9(dirname10(marker), { recursive: true });
22119
22125
  await writeFile2(bridge.store.path(`.scratch/edit-context-${key}.json`), JSON.stringify({ bindingId, nonce: randomUUID8(), at: Date.now() }), { mode: 384 });
22120
22126
  }
22121
22127
  const previous2 = await readFile11(marker, "utf8").then(JSON.parse).catch(() => null);
22122
22128
  if (previous2?.at && Date.now() - previous2.at < 1500) return { opened: true, reused: true, sourceId };
22123
22129
  await bridge.openStudio(sourceId);
22124
- await mkdir9(dirname9(marker), { recursive: true });
22130
+ await mkdir9(dirname10(marker), { recursive: true });
22125
22131
  await writeFile2(marker, JSON.stringify({ at: Date.now() }), { mode: 384 });
22126
22132
  return { opened: true, sourceId };
22127
22133
  });
22128
22134
  }
22129
- if (request.operation === "entry-restore") throw new BridgeError("CAPABILITY_UNAVAILABLE", "\u8FBE\u82AC\u5947\u516C\u5F00\u63A5\u53E3\u5C1A\u4E0D\u652F\u6301\u81EA\u52A8\u91CD\u65B0\u9644\u52A0\u4FA7\u680F\u5165\u53E3\u3002\u5DE5\u7A0B\u5173\u8054\u4ECD\u4FDD\u7559\uFF0C\u53EF\u4ECE\u300C\u5DE5\u4F5C\u533A \u2192 \u811A\u672C \u2192 Utility \u2192 Motion Harness \u6865\u63A5\u7EC4\u4EF6\u300D\u7F16\u8F91\u6216\u66F4\u65B0\u3002", "entry", false, { automaticAttachment: false }, "\u4F7F\u7528\u56FA\u5B9A\u811A\u672C\u83DC\u5355\u7EE7\u7EED\u7F16\u8F91\u3002\u5B9E\u9A8C\u4FA7\u680F\u53EA\u53EF\u5728\u5BBF\u4E3B\u63D0\u4F9B\u6709\u6548\u6E90\u8DEF\u5F84\u5E76\u5B8C\u6210\u4E25\u683C\u8EAB\u4EFD\u6838\u5BF9\u65F6\u5904\u7406\u8BF7\u6C42\uFF0C\u81EA\u52A8\u9644\u52A0\u4ECD\u672A\u5F00\u653E\u3002");
22135
+ if (request.operation === "entry-restore") throw new BridgeError("CAPABILITY_UNAVAILABLE", "\u8FBE\u82AC\u5947\u516C\u5F00\u63A5\u53E3\u5C1A\u4E0D\u652F\u6301\u81EA\u52A8\u91CD\u65B0\u9644\u52A0\u4FA7\u680F\u5165\u53E3\u3002\u5DE5\u7A0B\u5173\u8054\u4ECD\u4FDD\u7559\uFF0C\u53EF\u4ECE\u300C\u5DE5\u4F5C\u533A \u2192 \u811A\u672C \u2192 Utility \u2192 MotionHarness \u6865\u63A5\u7EC4\u4EF6\u300D\u7F16\u8F91\u6216\u66F4\u65B0\u3002", "entry", false, { automaticAttachment: false }, "\u4F7F\u7528\u56FA\u5B9A\u811A\u672C\u83DC\u5355\u7EE7\u7EED\u7F16\u8F91\u3002\u5B9E\u9A8C\u4FA7\u680F\u53EA\u53EF\u5728\u5BBF\u4E3B\u63D0\u4F9B\u6709\u6548\u6E90\u8DEF\u5F84\u5E76\u5B8C\u6210\u4E25\u683C\u8EAB\u4EFD\u6838\u5BF9\u65F6\u5904\u7406\u8BF7\u6C42\uFF0C\u81EA\u52A8\u9644\u52A0\u4ECD\u672A\u5F00\u653E\u3002");
22130
22136
  if (request.operation === "relink") return bridge.relink(input);
22131
22137
  if (request.operation === "recover") {
22132
22138
  const checked = reconcileSchema.parse(input);
@@ -22230,7 +22236,7 @@ async function proposedWorkspaceRoot(path) {
22230
22236
  return resolve11(await realpath6(existing), ...suffix);
22231
22237
  } catch (error48) {
22232
22238
  if (error48.code !== "ENOENT") throw error48;
22233
- const parent = dirname9(existing);
22239
+ const parent = dirname10(existing);
22234
22240
  if (parent === existing) throw error48;
22235
22241
  suffix.unshift(basename5(existing));
22236
22242
  existing = parent;
@@ -22371,7 +22377,7 @@ async function migrate(bridge, input) {
22371
22377
  const source = old.artifactPath(artifact.relativePath);
22372
22378
  assert2(await fileDigest(source) === artifact.sha256, "ARTIFACT_CHANGED", "\u65E7\u7248\u4E0D\u53EF\u53D8\u4EA7\u7269\u6821\u9A8C\u5931\u8D25\uFF0C\u539F\u6587\u4EF6\u672A\u6539\u53D8\u3002");
22373
22379
  const destination = bridge.store.artifactPath(artifact.relativePath);
22374
- await mkdir9(dirname9(destination), { recursive: true });
22380
+ await mkdir9(dirname10(destination), { recursive: true });
22375
22381
  try {
22376
22382
  await copyFile4(source, destination, 1);
22377
22383
  } catch (error48) {