@motionharness/bridge-davinci 0.0.0-stage → 0.0.23

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.
@@ -0,0 +1,117 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "name": "@motionharness/bridge-davinci",
4
+ "version": "0.0.23",
5
+ "protocol": 1,
6
+ "cliVersion": "0.0.23",
7
+ "files": [
8
+ {
9
+ "path": "dist/inspector_runtime.py",
10
+ "sha256": "c02486992b71d8ecb506f9ede4c4d6bfcf32fcea4fcc00da6011e25b28b2dd0d"
11
+ },
12
+ {
13
+ "path": "dist/instance_runtime.py",
14
+ "sha256": "cdffb0aedf244a61991c378feed419f406dbf2f0fa635d33d24aa0b3381fb1ec"
15
+ },
16
+ {
17
+ "path": "dist/intrinsic_runtime.py",
18
+ "sha256": "a8841de53cfcb68e315cce58bb9f729bdf6feec10392b792d0d442ebefe2488f"
19
+ },
20
+ {
21
+ "path": "dist/legacy_conversion.py",
22
+ "sha256": "3c595b7f5a34611d20f59bdd8181414b5191aadd27fee02667dfdd6c59f6d464"
23
+ },
24
+ {
25
+ "path": "dist/resolve_rpc.py",
26
+ "sha256": "f10440c19783605f0aec00b206a6520d7a3dafd6f28ddf307cae6b7e08802691"
27
+ },
28
+ {
29
+ "path": "dist/runner.mjs",
30
+ "sha256": "8a7c2c89b465ed32ce0e3e275edf8e4e8b0b2c5cd61b01dbf7690daaf2e235d5"
31
+ },
32
+ {
33
+ "path": "dist/runtime_io.py",
34
+ "sha256": "52efdd2ddf9b35d5c69e67e32d3dc92cf37ee350281de5f7afc5552681f1445c"
35
+ },
36
+ {
37
+ "path": "LICENSE",
38
+ "sha256": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
39
+ },
40
+ {
41
+ "path": "NOTICE",
42
+ "sha256": "08da1a97f3e888dc31f14a8489f4ddbc2a8471a588831c6c1a784c57b55d2d88"
43
+ },
44
+ {
45
+ "path": "OPENFX_LICENSE",
46
+ "sha256": "2f35ced026e843f83d3fdcc6b58976151ad4eab14eec6e8376783925393040c7"
47
+ },
48
+ {
49
+ "path": "README.md",
50
+ "sha256": "a60beff9902034f0d59739ae714659feb00c7e4e2bb747c8b36d1ed25bec6451"
51
+ },
52
+ {
53
+ "path": "resources/HotionHarness.ofx.bundle/Contents/Info.plist",
54
+ "sha256": "a5316a00995683460edc87123ad958425cd1be36a2dc64edd26b1063b6acefed",
55
+ "executable": false
56
+ },
57
+ {
58
+ "path": "resources/HotionHarness.ofx.bundle/Contents/MacOS/HotionHarness.ofx",
59
+ "sha256": "750369116eac4aec476a903685690bb488088f881f82d7b3ec0596e9b38a1aa2",
60
+ "executable": true
61
+ },
62
+ {
63
+ "path": "resources/HotionHarnessInstall",
64
+ "sha256": "39213a6e45578f0bb9f0c49bd6dd12c5402cf687b8eba2c6044cc4e1a20c5969",
65
+ "executable": true
66
+ },
67
+ {
68
+ "path": "resources/HotionHarnessStatus.app/Contents/Info.plist",
69
+ "sha256": "ec9e19f3f74cbc09c076382a1fe49c2553a8592887680449d8645ed4adca3fd9",
70
+ "executable": false
71
+ },
72
+ {
73
+ "path": "resources/HotionHarnessStatus.app/Contents/MacOS/HotionHarnessStatus",
74
+ "sha256": "8894fd5809549ab4281adc525d447d0c847c8720dd5705e4df4be40098cacd08",
75
+ "executable": true
76
+ },
77
+ {
78
+ "path": "resources/HotionHarnessStatus.app/Contents/Resources/en.lproj/InfoPlist.strings",
79
+ "sha256": "a2ace2734255bc9751b7ea734d7cf19b1d1386604b8cb838f0e529839846f419",
80
+ "executable": false
81
+ },
82
+ {
83
+ "path": "resources/HotionHarnessStatus.app/Contents/Resources/zh-Hans.lproj/InfoPlist.strings",
84
+ "sha256": "834876e910caa01c120735fc3cb927db473014cc336e4977aae8d390591e1be2",
85
+ "executable": false
86
+ },
87
+ {
88
+ "path": "resources/legacy-forwarder.lua",
89
+ "sha256": "342b396ac9fd68dbb9e8cd166c2e99b8d0740c7dc01cac3a5064d6fd092b8900",
90
+ "executable": false
91
+ },
92
+ {
93
+ "path": "resources/legacy-inspector-v1.lua",
94
+ "sha256": "808965d5fabc6b9b457ef4b08fa4635e47d1efebc74e0e3d036e73ca2ef75ac5",
95
+ "executable": false
96
+ },
97
+ {
98
+ "path": "resources/menu-entry.py",
99
+ "sha256": "15f8dafb4d3c4a8020007b20764d4e3c1700f9585be107769efefd8ba4877e94",
100
+ "executable": false
101
+ },
102
+ {
103
+ "path": "resources/sidebar-help/en.html",
104
+ "sha256": "838c7af75c332e6427d78c97a67d4cd44f142633e97dc5200c2a079145d0d4cd",
105
+ "executable": false
106
+ },
107
+ {
108
+ "path": "resources/sidebar-help/index.html",
109
+ "sha256": "ad201ec81af3728ec4a3d0219ca55b5d00fdba2bacb694dcaf47652d368eb8a4",
110
+ "executable": false
111
+ },
112
+ {
113
+ "path": "THIRD_PARTY_NOTICES.md",
114
+ "sha256": "ca3e1bb03bf5601dda94cdb82fe69710cdd84147891710da5bce982e57d81e25"
115
+ }
116
+ ]
117
+ }
@@ -0,0 +1,113 @@
1
+ """Conservative readback for the experimental, image-routing-only MH macro.
2
+
3
+ No module import connects to Resolve. Native acceptance is deliberately separate
4
+ from this graph identity check; normal sync retains its previous support boundary.
5
+ """
6
+ import hashlib
7
+ import json
8
+ import os
9
+
10
+ DATA_KEY = 'MotionHarness.Inspector.v1'
11
+ PRESENTATION = {'ViewInfo', 'CtrlWZoom', 'CtrlWShown', 'NameSet', 'ActiveTool', '__flags'}
12
+
13
+
14
+ def canonical(value):
15
+ if isinstance(value, dict):
16
+ return {str(key): canonical(item) for key, item in value.items() if key not in PRESENTATION}
17
+ if isinstance(value, (tuple, list)):
18
+ return [canonical(item) for item in value]
19
+ if value is None or isinstance(value, (str, int, float, bool)):
20
+ return value
21
+ raise ValueError('unrecognized Fusion settings value')
22
+
23
+
24
+ def signature(value):
25
+ return 'sha256:' + hashlib.sha256(json.dumps(canonical(value), ensure_ascii=False, sort_keys=True, separators=(',', ':'), allow_nan=False).encode()).hexdigest()
26
+
27
+
28
+ def callbacks():
29
+ return {name: 'local entry = dofile(comp:MapPath("Scripts:Utility/MHBridgeInspector.lua")); entry({ action = "%s", workspaceKey = tool:GetInput("MHWorkspaceKey"), sourceId = tool:GetInput("MHSourceId"), bindingId = tool:GetInput("MHBindingId") })' % action
30
+ for name, action in (('MHEdit', 'edit'), ('MHMore', 'more'))}
31
+
32
+
33
+ def attrs(tool):
34
+ data = tool.GetAttrs()
35
+ if not isinstance(data, dict): raise ValueError('missing Fusion tool attributes')
36
+ return data
37
+
38
+
39
+ def tool_name(tool): return attrs(tool).get('TOOLS_Name')
40
+ def tool_id(tool): return attrs(tool).get('TOOLS_RegID')
41
+
42
+
43
+ def settings(tool):
44
+ saved = tool.SaveSettings()
45
+ value = saved.get('Tools', {}).get(tool_name(tool)) if isinstance(saved, dict) else None
46
+ if not isinstance(value, dict): raise ValueError('unrecognized Fusion tool serialization')
47
+ return value
48
+
49
+
50
+ def connected_to(tool, name):
51
+ input_ = tool.FindMainInput(1)
52
+ output = input_.GetConnectedOutput() if input_ else None
53
+ return bool(output and tool_name(output.GetTool()) == name)
54
+
55
+
56
+ def graph(comp, identity):
57
+ tools = list((comp.GetToolList(False) or {}).values())
58
+ expected = {'MediaIn1': 'MediaIn', 'MHBridge': 'MacroOperator', 'MediaOut1': 'MediaOut'}
59
+ # Resolve includes macro children in GetToolList(False), unlike a top-level
60
+ # tools-only list. Accept exactly that one documented child in either form.
61
+ actual = {tool_name(t): tool_id(t) for t in tools}
62
+ if len(tools) != len(actual) or actual not in (expected, {**expected, 'MHBridgePipe': 'PipeRouter'}):
63
+ raise ValueError('not the isolated MH entry composition')
64
+ by_name = {tool_name(t): t for t in tools}
65
+ macro = by_name['MHBridge']
66
+ children = list((macro.GetChildrenList(False) or {}).values())
67
+ if len(children) != 1 or tool_id(children[0]) != 'PipeRouter' or tool_name(children[0]) != 'MHBridgePipe':
68
+ raise ValueError('the macro contains an unknown image operation')
69
+ if not connected_to(macro, 'MediaIn1') or not (connected_to(by_name['MediaOut1'], 'MHBridge') or connected_to(by_name['MediaOut1'], 'MHBridgePipe')):
70
+ raise ValueError('the native image route differs from the MH template')
71
+ own = settings(macro)
72
+ for group, key, source in (('Inputs', 'MainInput1', 'Input'), ('Outputs', 'MainOutput1', 'Output')):
73
+ link = own.get(group, {}).get(key, {})
74
+ if link.get('SourceOp') != 'MHBridgePipe' or link.get('Source') != source:
75
+ raise ValueError('the macro image interface was changed')
76
+ fields = {'MHSchema': 1, 'MHWorkspaceKey': identity['workspaceKey'], 'MHSourceId': identity['sourceId'], 'MHBindingId': identity['bindingId'],
77
+ 'MHMediaPoolItemId': identity['mediaPoolItemId'], 'MHDatabaseId': identity['databaseId'], 'MHProjectId': identity['projectId']}
78
+ if any(macro.GetInput(key) != value for key, value in fields.items()):
79
+ raise ValueError('the macro ownership differs from the selected binding')
80
+ controls = own.get('UserControls', {})
81
+ if any(controls.get(key, {}).get('BTNCS_Execute') != code for key, code in callbacks().items()):
82
+ raise ValueError('the Inspector callback was changed')
83
+ return signature({tool_name(t): settings(t) for t in tools})
84
+
85
+
86
+ def read_entry(item):
87
+ """An edited/foreign graph is unknown, even if it retains an MH display name."""
88
+ try:
89
+ if item.GetFusionCompCount() != 1: return None
90
+ comp = item.GetFusionCompByIndex(1)
91
+ receipt = comp.GetData(DATA_KEY) if comp else None
92
+ if not isinstance(receipt, dict) or receipt.get('schemaVersion') != 1: return None
93
+ identity = receipt['identity']
94
+ media = item.GetMediaPoolItem()
95
+ link = json.loads((media.GetThirdPartyMetadata() or {}).get('motionharness.bridge', 'null')) if media else None
96
+ if (not isinstance(link, dict) or link.get('bindingId') != identity['bindingId'] or link.get('sourceId') != identity['sourceId']
97
+ or media.GetUniqueId() != identity['mediaPoolItemId']): return None
98
+ current = graph(comp, identity)
99
+ if current != receipt.get('graphFingerprint'): return None
100
+ return {**receipt, 'graphFingerprint': current}
101
+ except (AttributeError, TypeError, ValueError, KeyError, RuntimeError):
102
+ return None
103
+
104
+
105
+ def experimental_enabled():
106
+ # This flag is for a later isolated acceptance run. The installer and button
107
+ # launcher never set it, and current release behavior remains conservative.
108
+ return os.environ.get('MH_BRIDGE_EXPERIMENTAL_INSPECTOR') == '1'
109
+
110
+
111
+ def unknown_effects(effects, supported):
112
+ return [effect for effect in effects if not (str(effect.get('OTIO_SCHEMA', '')).startswith('Effect.')
113
+ and effect.get('effect_name') == 'Resolve Effect' and effect.get('metadata', {}).get('Resolve_OTIO', {}).get('Effect Name') in supported)]