@synthetic-ai/premiere-mcp 2.3.1-dev.1 → 2.3.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # Changelog
2
2
 
3
+ ## [v2.3.4] — The "Reload panel" button no longer reloads in place
4
+
5
+ v2.3.3's `stopBridge()`-before-`location.reload()` fix wasn't enough —
6
+ confirmed live, twice, on a clean install + full Premiere Pro restart, that
7
+ `location.reload()` doesn't reliably re-run `init()` in this CEP host. Root
8
+ cause found: each reload leaks the old page's `CEPHtmlEngine` subprocesses
9
+ instead of terminating them — 37 orphaned processes were found accumulated
10
+ from repeated testing today, versus ~6 for one cleanly opened panel. Rather
11
+ than keep guessing at ways to make an in-place reload work, the ⟳ button no
12
+ longer calls `location.reload()` at all — it stops the bridge and tells the
13
+ user to restart Premiere Pro, the one path confirmed to always leave the
14
+ panel correct.
15
+
16
+ ## [v2.3.3] — Fixed the "Reload panel" button
17
+
18
+ It called a bare `location.reload()`, which could leave the old poll
19
+ interval running underneath the fresh page and race with `init()`
20
+ re-running — the panel could get stuck showing the raw HTML placeholder
21
+ badge, an empty temp dir field, and a spurious "Please set a temp
22
+ directory" error, all while the actually-installed files were fine. Now
23
+ stops the bridge (clearing the interval) before reloading, same fix class
24
+ as Photoshop MCP's `wss.close()`-before-reload.
25
+
26
+ ## [v2.3.2] — Reverted the license.json USER_DATA change
27
+
28
+ v2.3.1 (panel side, unreleased separately from the npm tag) moved
29
+ `getLicensePath()` from `SystemPath.EXTENSION` to `SystemPath.USER_DATA` to
30
+ fix license saves failing with EPERM under a system-wide install. Live
31
+ testing found a deeper issue: the CEP panel's embedded Node
32
+ `fs.writeFileSync` can report success without the write actually landing on
33
+ disk on this Premiere Pro version — confirmed by writing the target file
34
+ directly and watching Premiere's own "successful" save leave it untouched.
35
+ Reverted back to `SystemPath.EXTENSION` (pre-fix behavior) until this CEP
36
+ Node.js reliability issue is understood; the original EPERM bug is still
37
+ open, to be investigated outside production.
38
+
3
39
  ## [v2.3.1] — macOS example paths in tool descriptions
4
40
 
5
41
  `create_sequence`'s description and example calls only showed Windows
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <ExtensionManifest Version="7.0" ExtensionBundleId="com.mcp.premiere.bridge" ExtensionBundleVersion="1.1.6" ExtensionBundleName="MCP Bridge">
2
+ <ExtensionManifest Version="7.0" ExtensionBundleId="com.mcp.premiere.bridge" ExtensionBundleVersion="1.1.6" ExtensionBundleName="Synthetic Premiere MCP">
3
3
  <ExtensionList>
4
4
  <Extension Id="com.mcp.premiere.bridge.panel" Version="1.1.6"/>
5
5
  </ExtensionList>
@@ -0,0 +1,224 @@
1
+ /* synthetic-idiomas · core/i18n-core.cjs
2
+ *
3
+ * Runtime de idiomas compartido por todos los productos Synthetic (servers MCP en Node y
4
+ * paneles CEP en el navegador). Sin dependencias. UMD: `require()`/`import` desde Node,
5
+ * o <script> (queda en window.SyntheticI18n).
6
+ *
7
+ * Reglas:
8
+ * - Inglés es el idioma fuente. Cualquier clave que falte en otro idioma cae al inglés; si
9
+ * tampoco está, al texto por defecto que pase el código; si tampoco, a la clave. Nunca vacío.
10
+ * - Las traducciones de descripciones de tools llevan la huella (hash) del inglés del que se
11
+ * tradujeron. Si el inglés cambió desde entonces, se usa el inglés nuevo: nunca se muestra
12
+ * una traducción vieja que ya no corresponde.
13
+ */
14
+ (function (root, factory) {
15
+ var api = factory();
16
+ if (typeof module === 'object' && module.exports) module.exports = api;
17
+ // En CEP con Node habilitado existen `module` y `window` a la vez: el panel lo busca en window.
18
+ if (root && (typeof module !== 'object' || typeof root.document !== 'undefined')) root.SyntheticI18n = api;
19
+ })(typeof self !== 'undefined' ? self : this, function () {
20
+ 'use strict';
21
+
22
+ // Idiomas soportados, en el orden en que se muestran en los selectores.
23
+ var LANGUAGES = [
24
+ { code: 'en', name: 'English' },
25
+ { code: 'es', name: 'Español' },
26
+ { code: 'pt-BR', name: 'Português (Brasil)' },
27
+ { code: 'fr', name: 'Français' },
28
+ { code: 'de', name: 'Deutsch' },
29
+ { code: 'ja', name: '日本語' }
30
+ ];
31
+ var CODES = LANGUAGES.map(function (l) { return l.code; });
32
+ var SOURCE = 'en';
33
+
34
+ // "es-AR", "es_419" → "es"; "pt", "pt-PT" → "pt-BR"; "EN-us" → "en"; desconocido → null.
35
+ function normalizeLanguage(input) {
36
+ if (!input || typeof input !== 'string') return null;
37
+ var s = input.trim().replace('_', '-').toLowerCase();
38
+ if (!s) return null;
39
+ for (var i = 0; i < CODES.length; i++) if (CODES[i].toLowerCase() === s) return CODES[i];
40
+ var base = s.split('-')[0];
41
+ if (base === 'pt') return 'pt-BR';
42
+ for (var j = 0; j < CODES.length; j++) if (CODES[j].toLowerCase() === base) return CODES[j];
43
+ return null;
44
+ }
45
+
46
+ // FNV-1a de 32 bits sobre UTF-16: rápido, determinístico e idéntico en Node y navegador.
47
+ function hash(text) {
48
+ var h = 0x811c9dc5;
49
+ var s = String(text);
50
+ for (var i = 0; i < s.length; i++) {
51
+ h ^= s.charCodeAt(i);
52
+ h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;
53
+ }
54
+ return ('0000000' + h.toString(16)).slice(-8);
55
+ }
56
+
57
+ // "Hola {name}" + {name:"Ana"} → "Hola Ana". Placeholders sin valor quedan tal cual.
58
+ function interpolate(text, vars) {
59
+ if (!vars) return text;
60
+ return String(text).replace(/\{([a-zA-Z0-9_]+)\}/g, function (m, k) {
61
+ return Object.prototype.hasOwnProperty.call(vars, k) && vars[k] != null ? String(vars[k]) : m;
62
+ });
63
+ }
64
+
65
+ /**
66
+ * @param {object} opts
67
+ * locales: { en: {key: text}, es: {...}, ... } diccionarios planos
68
+ * hashes: { es: {key: hashDelInglés}, ... } (opcional) huellas de las traducciones de tools
69
+ * language: código pedido (se normaliza; si no está soportado, inglés)
70
+ */
71
+ function createI18n(opts) {
72
+ opts = opts || {};
73
+ var locales = opts.locales || {};
74
+ var hashes = opts.hashes || {};
75
+ var language = normalizeLanguage(opts.language) || SOURCE;
76
+ if (!locales[language] && language !== SOURCE) language = SOURCE;
77
+ var en = locales[SOURCE] || {};
78
+ var lockMap = hashes[language] || {};
79
+ // Una traducción cuyo inglés cambió desde que se tradujo no se usa (cae al inglés actual).
80
+ var dict = {};
81
+ var raw = locales[language] || {};
82
+ Object.keys(raw).forEach(function (k) {
83
+ var lock = lockMap[k];
84
+ if (lock && typeof en[k] === 'string' && hash(en[k]) !== lock) return;
85
+ dict[k] = raw[k];
86
+ });
87
+
88
+ function has(key) { return Object.prototype.hasOwnProperty.call(dict, key) && typeof dict[key] === 'string' && dict[key] !== ''; }
89
+
90
+ // Texto de una clave de UI/mensajes con caída al inglés.
91
+ function t(key, vars, fallbackText) {
92
+ var text = has(key) ? dict[key]
93
+ : (typeof en[key] === 'string' && en[key] !== '') ? en[key]
94
+ : (fallbackText != null && fallbackText !== '') ? fallbackText
95
+ : key;
96
+ return interpolate(text, vars);
97
+ }
98
+
99
+ // Traducción de un texto en inglés "vivo" (tomado del código en ejecución): solo si la
100
+ // traducción se hizo a partir de ese mismo inglés. Si no, devuelve el inglés.
101
+ function translateLive(key, englishNow) {
102
+ if (language === SOURCE || typeof englishNow !== 'string' || englishNow === '') return englishNow;
103
+ if (!has(key)) return englishNow;
104
+ var lock = lockMap[key];
105
+ if (lock && lock !== hash(englishNow)) return englishNow;
106
+ return dict[key];
107
+ }
108
+
109
+ // Recorre un JSON Schema y traduce cada `description` (y `title`) con claves estables:
110
+ // tool.<nombre>.param.<ruta> ej.: tool.apply_effect.param.clipId
111
+ // rutas anidadas con ".", ítems de arrays con "[]", ramas anyOf/oneOf con "|n".
112
+ function localizeSchema(schema, keyBase) {
113
+ if (!schema || typeof schema !== 'object') return schema;
114
+ var out = Array.isArray(schema) ? schema.slice() : Object.assign({}, schema);
115
+ if (typeof out.description === 'string') out.description = translateLive(keyBase, out.description);
116
+ if (typeof out.title === 'string') out.title = translateLive(keyBase + '#title', out.title);
117
+ if (out.properties && typeof out.properties === 'object') {
118
+ var props = {};
119
+ Object.keys(out.properties).forEach(function (name) {
120
+ props[name] = localizeSchema(out.properties[name], joinPath(keyBase, name));
121
+ });
122
+ out.properties = props;
123
+ }
124
+ if (out.items && typeof out.items === 'object' && !Array.isArray(out.items)) out.items = localizeSchema(out.items, keyBase + '[]');
125
+ ['anyOf', 'oneOf', 'allOf'].forEach(function (k) {
126
+ if (Array.isArray(out[k])) out[k] = out[k].map(function (s, i) { return localizeSchema(s, keyBase + '|' + i); });
127
+ });
128
+ if (out.additionalProperties && typeof out.additionalProperties === 'object') {
129
+ out.additionalProperties = localizeSchema(out.additionalProperties, keyBase + '{}');
130
+ }
131
+ return out;
132
+ }
133
+
134
+ // Traduce la lista de tools de una respuesta tools/list. Devuelve copias; no toca el original.
135
+ function localizeTools(tools) {
136
+ if (language === SOURCE || !Array.isArray(tools)) return tools;
137
+ return tools.map(function (tool) {
138
+ if (!tool || typeof tool.name !== 'string') return tool;
139
+ var base = 'tool.' + tool.name;
140
+ var copy = Object.assign({}, tool);
141
+ if (typeof copy.description === 'string') copy.description = translateLive(base, copy.description);
142
+ if (typeof copy.title === 'string') copy.title = translateLive(base + '#title', copy.title);
143
+ if (copy.inputSchema) copy.inputSchema = localizeSchemaRoot(copy.inputSchema, base);
144
+ return copy;
145
+ });
146
+ }
147
+ // En la raíz del inputSchema la descripción del objeto no se usa como parámetro.
148
+ function localizeSchemaRoot(schema, base) {
149
+ var out = Object.assign({}, schema);
150
+ if (out.properties) {
151
+ var props = {};
152
+ Object.keys(out.properties).forEach(function (name) {
153
+ props[name] = localizeSchema(out.properties[name], base + '.param.' + name);
154
+ });
155
+ out.properties = props;
156
+ }
157
+ return out;
158
+ }
159
+
160
+ // Plurales: busca "<clave>.<categoría>" según las reglas del idioma (Intl.PluralRules:
161
+ // one/other, en japonés solo other), después "<clave>.other" y por último "<clave>".
162
+ // {count} queda disponible como placeholder.
163
+ var pluralRules = null;
164
+ try { pluralRules = new Intl.PluralRules(language === 'pt-BR' ? 'pt-BR' : language); } catch (e) { pluralRules = null; }
165
+ function tn(key, count, vars) {
166
+ var v = Object.assign({ count: count }, vars || {});
167
+ var cat = pluralRules ? pluralRules.select(count) : (count === 1 ? 'one' : 'other');
168
+ var candidates = [key + '.' + cat, key + '.other', key];
169
+ for (var i = 0; i < candidates.length; i++) {
170
+ var k = candidates[i];
171
+ if (has(k) || (typeof en[k] === 'string' && en[k] !== '')) return t(k, v);
172
+ }
173
+ return t(key, v);
174
+ }
175
+
176
+ return {
177
+ language: language,
178
+ t: t,
179
+ tn: tn,
180
+ translateLive: translateLive,
181
+ localizeTools: localizeTools,
182
+ has: has
183
+ };
184
+ }
185
+
186
+ function joinPath(base, name) { return base + '.' + name; }
187
+
188
+ // Aplana la lista de tools de tools/list a { clave: inglés } con las mismas claves que usa
189
+ // localizeTools. Lo usa el extractor para generar el diccionario fuente.
190
+ function flattenTools(tools) {
191
+ var out = {};
192
+ (tools || []).forEach(function (tool) {
193
+ if (!tool || typeof tool.name !== 'string') return;
194
+ var base = 'tool.' + tool.name;
195
+ if (typeof tool.description === 'string' && tool.description) out[base] = tool.description;
196
+ if (typeof tool.title === 'string' && tool.title) out[base + '#title'] = tool.title;
197
+ var props = tool.inputSchema && tool.inputSchema.properties;
198
+ if (props) Object.keys(props).forEach(function (name) { walk(props[name], base + '.param.' + name); });
199
+ });
200
+ function walk(schema, key) {
201
+ if (!schema || typeof schema !== 'object') return;
202
+ if (typeof schema.description === 'string' && schema.description) out[key] = schema.description;
203
+ if (typeof schema.title === 'string' && schema.title) out[key + '#title'] = schema.title;
204
+ if (schema.properties) Object.keys(schema.properties).forEach(function (n) { walk(schema.properties[n], key + '.' + n); });
205
+ if (schema.items && typeof schema.items === 'object' && !Array.isArray(schema.items)) walk(schema.items, key + '[]');
206
+ ['anyOf', 'oneOf', 'allOf'].forEach(function (k) {
207
+ if (Array.isArray(schema[k])) schema[k].forEach(function (s, i) { walk(s, key + '|' + i); });
208
+ });
209
+ if (schema.additionalProperties && typeof schema.additionalProperties === 'object') walk(schema.additionalProperties, key + '{}');
210
+ }
211
+ return out;
212
+ }
213
+
214
+ return {
215
+ LANGUAGES: LANGUAGES,
216
+ CODES: CODES,
217
+ SOURCE: SOURCE,
218
+ normalizeLanguage: normalizeLanguage,
219
+ hash: hash,
220
+ interpolate: interpolate,
221
+ createI18n: createI18n,
222
+ flattenTools: flattenTools
223
+ };
224
+ });