autodev-cli 1.4.152 → 1.4.153

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.
@@ -211,10 +211,6 @@ class MCPPlugin(Gimp.PlugIn):
211
211
  global _main_loop
212
212
  started, message = self.ensure_server()
213
213
  _log(message)
214
- try:
215
- Gimp.message(message)
216
- except Exception:
217
- pass
218
214
  if not started:
219
215
  return procedure.new_return_values(Gimp.PDBStatusType.EXECUTION_ERROR, GLib.Error(message))
220
216
 
@@ -244,11 +240,12 @@ class MCPPlugin(Gimp.PlugIn):
244
240
 
245
241
  GimpUi.init('gimp_mcp_server.py')
246
242
  window = Gtk.Window(title='GIMP MCP Server')
247
- window.set_default_size(420, 160)
248
- window.set_keep_above(True)
243
+ window.set_default_size(360, 120)
244
+ window.set_keep_above(False)
245
+ window.set_skip_taskbar_hint(False)
249
246
  box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
250
247
  box.set_border_width(16)
251
- label = Gtk.Label(label=message + '\n\nLeave this window open while Grok talks to GIMP.')
248
+ label = Gtk.Label(label=message + '\nLeave this window open.')
252
249
  label.set_line_wrap(True)
253
250
  box.pack_start(label, True, True, 0)
254
251
  button = Gtk.Button(label='Stop server')
@@ -257,7 +254,6 @@ class MCPPlugin(Gimp.PlugIn):
257
254
  window.add(box)
258
255
  window.connect('destroy', self._on_status_closed)
259
256
  window.show_all()
260
- window.present()
261
257
  _log('Status window opened')
262
258
 
263
259
  def _on_status_closed(self, *_args):
@@ -1,4 +1,4 @@
1
1
  /** sha256 (first 12 hex) of the canonical media/gimp/gimp_mcp_server.py. */
2
- export declare const GIMP_PLUGIN_SOURCE_HASH = "c4b85cccece9";
2
+ export declare const GIMP_PLUGIN_SOURCE_HASH = "e9f5d21b82f7";
3
3
  /** Full body of the user-verified GIMP 3.x MCP server plug-in (media/gimp/gimp_mcp_server.py). */
4
- export declare const GIMP_PLUGIN_SOURCE = "#!/usr/bin/env python3\n# ---------------------------------------------------------------------------\n# gimp_mcp_server.py \u2014 vendored, USER-VERIFIED GIMP 3.2 MCP bridge (plug-in).\n#\n# Derived from libreearth/gimp-mcp (GPL-3.0; see media/gimp/LICENSE) and fixed by\n# the user / AutoDev for GIMP 3.2 (Store / MSIX). Verified working on real GIMP\n# 3.2.44: a menu-triggered PLUGIN (Tools -> MCP / Filters -> Development -> Start\n# MCP Server) that listens on 127.0.0.1:9876 and drives GIMP. Keep the \"GIMP MCP\n# Server\" window open \u2014 GLib.MainLoop() holds the out-of-process plug-in alive.\n#\n# This is the user's verified file; the body below is kept byte-for-byte. The\n# lines in THIS block are a provenance comment only \u2014 do not edit the code below.\n# ---------------------------------------------------------------------------\n\n# GIMP MCP Server Plugin (GIMP 3.2)\n# Listens on localhost:9876 so the libreearth gimp-mcp client can drive GIMP.\n\nimport gi\ngi.require_version('Gimp', '3.0')\nfrom gi.repository import Gimp\nfrom gi.repository import GLib\nfrom gi.repository import Gio\nfrom gi.repository import GObject\n\nimport io\nimport json\nimport os\nimport socket\nimport sys\nimport threading\nimport traceback\n\nHOST = '127.0.0.1'\nPORT = 9876\n# Store GIMP redirects GLib config dir into the MSIX LocalCache. Also write\n# to the real roaming profile so the log is findable.\n_LOG_PATHS = [\n os.path.join(GLib.get_user_config_dir(), 'GIMP', '3.2', 'gimp_mcp_server.log'),\n os.path.join(os.environ.get('APPDATA', ''), 'GIMP', '3.2', 'gimp_mcp_server.log'),\n]\n\n_server_lock = threading.Lock()\n_server_started = False\n_exec_globals = None\n_main_loop = None\n\n\ndef _log(msg):\n line = msg.rstrip() + '\\n'\n for path in _LOG_PATHS:\n if not path:\n continue\n try:\n os.makedirs(os.path.dirname(path), exist_ok=True)\n with open(path, 'a', encoding='utf-8') as fh:\n fh.write(line)\n except Exception:\n pass\n print(msg, flush=True)\n\n\ndef N_(message):\n return message\n\n\ndef _(message):\n return GLib.dgettext(None, message)\n\n\ndef _serialize(obj):\n if obj is None or isinstance(obj, (str, int, float, bool)):\n return obj\n if isinstance(obj, (list, tuple)):\n return [_serialize(item) for item in obj]\n if isinstance(obj, dict):\n return {str(k): _serialize(v) for k, v in obj.items()}\n data = {'type': obj.__class__.__name__}\n if hasattr(obj, 'get_id'):\n try:\n data['id'] = int(obj.get_id())\n except Exception:\n pass\n elif hasattr(obj, 'ID'):\n data['id'] = obj.ID\n if hasattr(obj, 'get_name'):\n try:\n data['name'] = obj.get_name()\n except Exception:\n pass\n if 'id' not in data and len(data) == 1:\n return str(obj)\n return data\n\n\ndef _resolve_api(api_path):\n parts = [p for p in str(api_path).split('.') if p]\n if parts and parts[0] == 'Gimp':\n parts = parts[1:]\n elif len(parts) >= 3 and parts[0] == 'gi' and parts[1] == 'repository' and parts[2] == 'Gimp':\n parts = parts[3:]\n\n aliases = {\n 'list_images': 'get_images',\n 'list_fonts': 'get_fonts',\n 'fonts_get_list': 'get_fonts',\n }\n\n if not parts:\n return Gimp\n\n obj = Gimp\n for part in parts:\n part = aliases.get(part, part)\n obj = getattr(obj, part)\n return obj\n\n\ndef _exec_namespace():\n global _exec_globals\n if _exec_globals is None:\n ns = {\n '__builtins__': __builtins__,\n '__name__': '__main__',\n 'Gimp': Gimp,\n 'GLib': GLib,\n 'Gio': Gio,\n 'GObject': GObject,\n 'sys': sys,\n 'os': os,\n 'json': json,\n }\n try:\n gi.require_version('Gegl', '0.4')\n from gi.repository import Gegl\n ns['Gegl'] = Gegl\n except Exception as exc:\n _log(f'Gegl import failed: {exc}')\n try:\n gi.require_version('Babl', '0.1')\n from gi.repository import Babl\n ns['Babl'] = Babl\n except Exception:\n pass\n _exec_globals = ns\n return _exec_globals\n\n\ndef _extract_code(args, kwargs):\n if kwargs.get('code'):\n return str(kwargs['code'])\n if not args:\n return ''\n if len(args) >= 2 and args[0] in ('exec', 'eval', 'pyGObject-console'):\n payload = args[1]\n if isinstance(payload, (list, tuple)):\n return '\\n'.join(str(item) for item in payload)\n return str(payload)\n if isinstance(args[0], (list, tuple)):\n return '\\n'.join(str(item) for item in args[0])\n return str(args[0])\n\n\ndef _run_python(code):\n ns = _exec_namespace()\n stdout = io.StringIO()\n old_stdout = sys.stdout\n sys.stdout = stdout\n try:\n exec(code, ns)\n finally:\n sys.stdout = old_stdout\n printed = stdout.getvalue()\n result = ns.get('_result')\n if result is not None:\n return {'printed': printed, 'result': _serialize(result)}\n return {'printed': printed, 'result': None}\n\n\nclass MCPPlugin(Gimp.PlugIn):\n def do_set_i18n(self, name):\n return False\n\n def do_query_procedures(self):\n return ['plug-in-mcp-server']\n\n def do_create_procedure(self, name):\n procedure = Gimp.Procedure.new(\n self, name, Gimp.PDBProcType.PLUGIN, self.run, None\n )\n procedure.set_menu_label(_('Start MCP Server'))\n procedure.set_documentation(\n _('Starts an MCP server to control GIMP externally'),\n _('Listens on 127.0.0.1:9876 for the GIMP MCP client'),\n name,\n )\n procedure.set_attribution('GIMP MCP', 'GIMP MCP', '2026')\n procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.ALWAYS)\n procedure.add_enum_argument(\n 'run-mode',\n _('Run mode'),\n _('The run mode'),\n Gimp.RunMode,\n Gimp.RunMode.INTERACTIVE,\n GObject.ParamFlags.READWRITE,\n )\n procedure.add_menu_path('<Image>/Tools/MCP')\n procedure.add_menu_path('<Image>/Filters/Development/')\n return procedure\n\n def run(self, procedure, config, data):\n global _main_loop\n started, message = self.ensure_server()\n _log(message)\n try:\n Gimp.message(message)\n except Exception:\n pass\n if not started:\n return procedure.new_return_values(Gimp.PDBStatusType.EXECUTION_ERROR, GLib.Error(message))\n\n # GIMP 3 launches Python plug-ins out of process. Returning from run()\n # would exit that process and kill the socket thread. Stay alive and\n # dispatch GLib.idle_add work (API calls) on this main loop.\n # A visible window is required: otherwise \"Start MCP Server\" looks like\n # it did not open anything.\n try:\n self._show_status_window(message)\n except Exception as exc:\n _log(f'Status window failed: {exc}\\n{traceback.format_exc()}')\n\n _main_loop = GLib.MainLoop()\n _log('Entering GLib.MainLoop to keep MCP server process alive')\n try:\n _main_loop.run()\n except Exception as exc:\n _log(f'MainLoop exited: {exc}')\n return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())\n\n def _show_status_window(self, message):\n gi.require_version('Gtk', '3.0')\n gi.require_version('GimpUi', '3.0')\n from gi.repository import Gtk\n from gi.repository import GimpUi\n\n GimpUi.init('gimp_mcp_server.py')\n window = Gtk.Window(title='GIMP MCP Server')\n window.set_default_size(420, 160)\n window.set_keep_above(True)\n box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)\n box.set_border_width(16)\n label = Gtk.Label(label=message + '\\n\\nLeave this window open while Grok talks to GIMP.')\n label.set_line_wrap(True)\n box.pack_start(label, True, True, 0)\n button = Gtk.Button(label='Stop server')\n button.connect('clicked', lambda *_: window.destroy())\n box.pack_start(button, False, False, 0)\n window.add(box)\n window.connect('destroy', self._on_status_closed)\n window.show_all()\n window.present()\n _log('Status window opened')\n\n def _on_status_closed(self, *_args):\n global _main_loop\n _log('Status window closed; stopping MCP server')\n if _main_loop is not None:\n _main_loop.quit()\n\n def ensure_server(self):\n global _server_started\n with _server_lock:\n if _server_started:\n return True, f'MCP Server already listening on {HOST}:{PORT}'\n try:\n thread = threading.Thread(target=self.start_server, daemon=True)\n thread.start()\n _server_started = True\n return True, f'MCP Server started on {HOST}:{PORT}'\n except Exception as exc:\n return False, f'Failed to start MCP Server: {exc}'\n\n def start_server(self):\n sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n try:\n sock.bind((HOST, PORT))\n sock.listen(8)\n _log(f'Server listening on {HOST}:{PORT}')\n except Exception as exc:\n _log(f'Bind/listen failed: {exc}')\n return\n\n while True:\n try:\n client, addr = sock.accept()\n _log(f'Connected to {addr}')\n threading.Thread(target=self.handle_client, args=(client,), daemon=True).start()\n except Exception as exc:\n _log(f'Server accept error: {exc}')\n break\n sock.close()\n\n def handle_client(self, client):\n buffer = b''\n try:\n client.settimeout(120)\n while True:\n chunk = client.recv(65536)\n if not chunk:\n break\n buffer += chunk\n while buffer:\n try:\n command = json.loads(buffer.decode('utf-8'))\n buffer = b''\n except json.JSONDecodeError:\n break\n GLib.idle_add(self.execute_command, command, client)\n except Exception as exc:\n _log(f'Client error: {exc}')\n finally:\n try:\n client.close()\n except Exception:\n pass\n\n def execute_command(self, command, client):\n cmd_type = command.get('type')\n params = command.get('params', {}) or {}\n try:\n if cmd_type == 'ping':\n response = {'status': 'success', 'result': 'pong'}\n elif cmd_type == 'exec':\n code = _extract_code(params.get('args', []), params.get('kwargs', {}))\n if not code:\n code = str(params.get('code', ''))\n response = {'status': 'success', 'result': _run_python(code)}\n elif cmd_type == 'call_api':\n api_path = params.get('api_path', '')\n args = params.get('args', []) or []\n kwargs = params.get('kwargs', {}) or {}\n if api_path in ('exec', 'eval', '__exec__'):\n response = {'status': 'success', 'result': _run_python(_extract_code(args, kwargs))}\n else:\n method = _resolve_api(api_path)\n result = method(*args, **kwargs)\n response = {'status': 'success', 'result': _serialize(result)}\n else:\n response = {'status': 'error', 'message': f'Unknown command: {cmd_type}'}\n except Exception as exc:\n response = {\n 'status': 'error',\n 'message': str(exc),\n 'traceback': traceback.format_exc(),\n }\n _log(f'Command error: {response[\"message\"]}\\n{response[\"traceback\"]}')\n\n try:\n payload = json.dumps(response).encode('utf-8')\n client.sendall(payload)\n except Exception as exc:\n _log(f'Response send failed: {exc}')\n return False\n\n\nGimp.main(MCPPlugin.__gtype__, sys.argv)\n";
4
+ export declare const GIMP_PLUGIN_SOURCE = "#!/usr/bin/env python3\n# ---------------------------------------------------------------------------\n# gimp_mcp_server.py \u2014 vendored, USER-VERIFIED GIMP 3.2 MCP bridge (plug-in).\n#\n# Derived from libreearth/gimp-mcp (GPL-3.0; see media/gimp/LICENSE) and fixed by\n# the user / AutoDev for GIMP 3.2 (Store / MSIX). Verified working on real GIMP\n# 3.2.44: a menu-triggered PLUGIN (Tools -> MCP / Filters -> Development -> Start\n# MCP Server) that listens on 127.0.0.1:9876 and drives GIMP. Keep the \"GIMP MCP\n# Server\" window open \u2014 GLib.MainLoop() holds the out-of-process plug-in alive.\n#\n# This is the user's verified file; the body below is kept byte-for-byte. The\n# lines in THIS block are a provenance comment only \u2014 do not edit the code below.\n# ---------------------------------------------------------------------------\n\n# GIMP MCP Server Plugin (GIMP 3.2)\n# Listens on localhost:9876 so the libreearth gimp-mcp client can drive GIMP.\n\nimport gi\ngi.require_version('Gimp', '3.0')\nfrom gi.repository import Gimp\nfrom gi.repository import GLib\nfrom gi.repository import Gio\nfrom gi.repository import GObject\n\nimport io\nimport json\nimport os\nimport socket\nimport sys\nimport threading\nimport traceback\n\nHOST = '127.0.0.1'\nPORT = 9876\n# Store GIMP redirects GLib config dir into the MSIX LocalCache. Also write\n# to the real roaming profile so the log is findable.\n_LOG_PATHS = [\n os.path.join(GLib.get_user_config_dir(), 'GIMP', '3.2', 'gimp_mcp_server.log'),\n os.path.join(os.environ.get('APPDATA', ''), 'GIMP', '3.2', 'gimp_mcp_server.log'),\n]\n\n_server_lock = threading.Lock()\n_server_started = False\n_exec_globals = None\n_main_loop = None\n\n\ndef _log(msg):\n line = msg.rstrip() + '\\n'\n for path in _LOG_PATHS:\n if not path:\n continue\n try:\n os.makedirs(os.path.dirname(path), exist_ok=True)\n with open(path, 'a', encoding='utf-8') as fh:\n fh.write(line)\n except Exception:\n pass\n print(msg, flush=True)\n\n\ndef N_(message):\n return message\n\n\ndef _(message):\n return GLib.dgettext(None, message)\n\n\ndef _serialize(obj):\n if obj is None or isinstance(obj, (str, int, float, bool)):\n return obj\n if isinstance(obj, (list, tuple)):\n return [_serialize(item) for item in obj]\n if isinstance(obj, dict):\n return {str(k): _serialize(v) for k, v in obj.items()}\n data = {'type': obj.__class__.__name__}\n if hasattr(obj, 'get_id'):\n try:\n data['id'] = int(obj.get_id())\n except Exception:\n pass\n elif hasattr(obj, 'ID'):\n data['id'] = obj.ID\n if hasattr(obj, 'get_name'):\n try:\n data['name'] = obj.get_name()\n except Exception:\n pass\n if 'id' not in data and len(data) == 1:\n return str(obj)\n return data\n\n\ndef _resolve_api(api_path):\n parts = [p for p in str(api_path).split('.') if p]\n if parts and parts[0] == 'Gimp':\n parts = parts[1:]\n elif len(parts) >= 3 and parts[0] == 'gi' and parts[1] == 'repository' and parts[2] == 'Gimp':\n parts = parts[3:]\n\n aliases = {\n 'list_images': 'get_images',\n 'list_fonts': 'get_fonts',\n 'fonts_get_list': 'get_fonts',\n }\n\n if not parts:\n return Gimp\n\n obj = Gimp\n for part in parts:\n part = aliases.get(part, part)\n obj = getattr(obj, part)\n return obj\n\n\ndef _exec_namespace():\n global _exec_globals\n if _exec_globals is None:\n ns = {\n '__builtins__': __builtins__,\n '__name__': '__main__',\n 'Gimp': Gimp,\n 'GLib': GLib,\n 'Gio': Gio,\n 'GObject': GObject,\n 'sys': sys,\n 'os': os,\n 'json': json,\n }\n try:\n gi.require_version('Gegl', '0.4')\n from gi.repository import Gegl\n ns['Gegl'] = Gegl\n except Exception as exc:\n _log(f'Gegl import failed: {exc}')\n try:\n gi.require_version('Babl', '0.1')\n from gi.repository import Babl\n ns['Babl'] = Babl\n except Exception:\n pass\n _exec_globals = ns\n return _exec_globals\n\n\ndef _extract_code(args, kwargs):\n if kwargs.get('code'):\n return str(kwargs['code'])\n if not args:\n return ''\n if len(args) >= 2 and args[0] in ('exec', 'eval', 'pyGObject-console'):\n payload = args[1]\n if isinstance(payload, (list, tuple)):\n return '\\n'.join(str(item) for item in payload)\n return str(payload)\n if isinstance(args[0], (list, tuple)):\n return '\\n'.join(str(item) for item in args[0])\n return str(args[0])\n\n\ndef _run_python(code):\n ns = _exec_namespace()\n stdout = io.StringIO()\n old_stdout = sys.stdout\n sys.stdout = stdout\n try:\n exec(code, ns)\n finally:\n sys.stdout = old_stdout\n printed = stdout.getvalue()\n result = ns.get('_result')\n if result is not None:\n return {'printed': printed, 'result': _serialize(result)}\n return {'printed': printed, 'result': None}\n\n\nclass MCPPlugin(Gimp.PlugIn):\n def do_set_i18n(self, name):\n return False\n\n def do_query_procedures(self):\n return ['plug-in-mcp-server']\n\n def do_create_procedure(self, name):\n procedure = Gimp.Procedure.new(\n self, name, Gimp.PDBProcType.PLUGIN, self.run, None\n )\n procedure.set_menu_label(_('Start MCP Server'))\n procedure.set_documentation(\n _('Starts an MCP server to control GIMP externally'),\n _('Listens on 127.0.0.1:9876 for the GIMP MCP client'),\n name,\n )\n procedure.set_attribution('GIMP MCP', 'GIMP MCP', '2026')\n procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.ALWAYS)\n procedure.add_enum_argument(\n 'run-mode',\n _('Run mode'),\n _('The run mode'),\n Gimp.RunMode,\n Gimp.RunMode.INTERACTIVE,\n GObject.ParamFlags.READWRITE,\n )\n procedure.add_menu_path('<Image>/Tools/MCP')\n procedure.add_menu_path('<Image>/Filters/Development/')\n return procedure\n\n def run(self, procedure, config, data):\n global _main_loop\n started, message = self.ensure_server()\n _log(message)\n if not started:\n return procedure.new_return_values(Gimp.PDBStatusType.EXECUTION_ERROR, GLib.Error(message))\n\n # GIMP 3 launches Python plug-ins out of process. Returning from run()\n # would exit that process and kill the socket thread. Stay alive and\n # dispatch GLib.idle_add work (API calls) on this main loop.\n # A visible window is required: otherwise \"Start MCP Server\" looks like\n # it did not open anything.\n try:\n self._show_status_window(message)\n except Exception as exc:\n _log(f'Status window failed: {exc}\\n{traceback.format_exc()}')\n\n _main_loop = GLib.MainLoop()\n _log('Entering GLib.MainLoop to keep MCP server process alive')\n try:\n _main_loop.run()\n except Exception as exc:\n _log(f'MainLoop exited: {exc}')\n return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())\n\n def _show_status_window(self, message):\n gi.require_version('Gtk', '3.0')\n gi.require_version('GimpUi', '3.0')\n from gi.repository import Gtk\n from gi.repository import GimpUi\n\n GimpUi.init('gimp_mcp_server.py')\n window = Gtk.Window(title='GIMP MCP Server')\n window.set_default_size(360, 120)\n window.set_keep_above(False)\n window.set_skip_taskbar_hint(False)\n box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)\n box.set_border_width(16)\n label = Gtk.Label(label=message + '\\nLeave this window open.')\n label.set_line_wrap(True)\n box.pack_start(label, True, True, 0)\n button = Gtk.Button(label='Stop server')\n button.connect('clicked', lambda *_: window.destroy())\n box.pack_start(button, False, False, 0)\n window.add(box)\n window.connect('destroy', self._on_status_closed)\n window.show_all()\n _log('Status window opened')\n\n def _on_status_closed(self, *_args):\n global _main_loop\n _log('Status window closed; stopping MCP server')\n if _main_loop is not None:\n _main_loop.quit()\n\n def ensure_server(self):\n global _server_started\n with _server_lock:\n if _server_started:\n return True, f'MCP Server already listening on {HOST}:{PORT}'\n try:\n thread = threading.Thread(target=self.start_server, daemon=True)\n thread.start()\n _server_started = True\n return True, f'MCP Server started on {HOST}:{PORT}'\n except Exception as exc:\n return False, f'Failed to start MCP Server: {exc}'\n\n def start_server(self):\n sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n try:\n sock.bind((HOST, PORT))\n sock.listen(8)\n _log(f'Server listening on {HOST}:{PORT}')\n except Exception as exc:\n _log(f'Bind/listen failed: {exc}')\n return\n\n while True:\n try:\n client, addr = sock.accept()\n _log(f'Connected to {addr}')\n threading.Thread(target=self.handle_client, args=(client,), daemon=True).start()\n except Exception as exc:\n _log(f'Server accept error: {exc}')\n break\n sock.close()\n\n def handle_client(self, client):\n buffer = b''\n try:\n client.settimeout(120)\n while True:\n chunk = client.recv(65536)\n if not chunk:\n break\n buffer += chunk\n while buffer:\n try:\n command = json.loads(buffer.decode('utf-8'))\n buffer = b''\n except json.JSONDecodeError:\n break\n GLib.idle_add(self.execute_command, command, client)\n except Exception as exc:\n _log(f'Client error: {exc}')\n finally:\n try:\n client.close()\n except Exception:\n pass\n\n def execute_command(self, command, client):\n cmd_type = command.get('type')\n params = command.get('params', {}) or {}\n try:\n if cmd_type == 'ping':\n response = {'status': 'success', 'result': 'pong'}\n elif cmd_type == 'exec':\n code = _extract_code(params.get('args', []), params.get('kwargs', {}))\n if not code:\n code = str(params.get('code', ''))\n response = {'status': 'success', 'result': _run_python(code)}\n elif cmd_type == 'call_api':\n api_path = params.get('api_path', '')\n args = params.get('args', []) or []\n kwargs = params.get('kwargs', {}) or {}\n if api_path in ('exec', 'eval', '__exec__'):\n response = {'status': 'success', 'result': _run_python(_extract_code(args, kwargs))}\n else:\n method = _resolve_api(api_path)\n result = method(*args, **kwargs)\n response = {'status': 'success', 'result': _serialize(result)}\n else:\n response = {'status': 'error', 'message': f'Unknown command: {cmd_type}'}\n except Exception as exc:\n response = {\n 'status': 'error',\n 'message': str(exc),\n 'traceback': traceback.format_exc(),\n }\n _log(f'Command error: {response[\"message\"]}\\n{response[\"traceback\"]}')\n\n try:\n payload = json.dumps(response).encode('utf-8')\n client.sendall(payload)\n except Exception as exc:\n _log(f'Response send failed: {exc}')\n return False\n\n\nGimp.main(MCPPlugin.__gtype__, sys.argv)\n";
@@ -11,7 +11,7 @@
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.GIMP_PLUGIN_SOURCE = exports.GIMP_PLUGIN_SOURCE_HASH = void 0;
13
13
  /** sha256 (first 12 hex) of the canonical media/gimp/gimp_mcp_server.py. */
14
- exports.GIMP_PLUGIN_SOURCE_HASH = "c4b85cccece9";
14
+ exports.GIMP_PLUGIN_SOURCE_HASH = "e9f5d21b82f7";
15
15
  /** Full body of the user-verified GIMP 3.x MCP server plug-in (media/gimp/gimp_mcp_server.py). */
16
16
  exports.GIMP_PLUGIN_SOURCE = `#!/usr/bin/env python3
17
17
  # ---------------------------------------------------------------------------
@@ -226,10 +226,6 @@ class MCPPlugin(Gimp.PlugIn):
226
226
  global _main_loop
227
227
  started, message = self.ensure_server()
228
228
  _log(message)
229
- try:
230
- Gimp.message(message)
231
- except Exception:
232
- pass
233
229
  if not started:
234
230
  return procedure.new_return_values(Gimp.PDBStatusType.EXECUTION_ERROR, GLib.Error(message))
235
231
 
@@ -259,11 +255,12 @@ class MCPPlugin(Gimp.PlugIn):
259
255
 
260
256
  GimpUi.init('gimp_mcp_server.py')
261
257
  window = Gtk.Window(title='GIMP MCP Server')
262
- window.set_default_size(420, 160)
263
- window.set_keep_above(True)
258
+ window.set_default_size(360, 120)
259
+ window.set_keep_above(False)
260
+ window.set_skip_taskbar_hint(False)
264
261
  box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
265
262
  box.set_border_width(16)
266
- label = Gtk.Label(label=message + '\\n\\nLeave this window open while Grok talks to GIMP.')
263
+ label = Gtk.Label(label=message + '\\nLeave this window open.')
267
264
  label.set_line_wrap(True)
268
265
  box.pack_start(label, True, True, 0)
269
266
  button = Gtk.Button(label='Stop server')
@@ -272,7 +269,6 @@ class MCPPlugin(Gimp.PlugIn):
272
269
  window.add(box)
273
270
  window.connect('destroy', self._on_status_closed)
274
271
  window.show_all()
275
- window.present()
276
272
  _log('Status window opened')
277
273
 
278
274
  def _on_status_closed(self, *_args):
@@ -1 +1 @@
1
- {"version":3,"file":"gimpPluginSource.js","sourceRoot":"","sources":["../../src/core/gimpPluginSource.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,wDAAwD;AACxD,EAAE;AACF,oFAAoF;AACpF,wFAAwF;AACxF,EAAE;AACF,4GAA4G;AAC5G,0DAA0D;AAC1D,8EAA8E;;;AAE9E,4EAA4E;AAC/D,QAAA,uBAAuB,GAAG,cAAc,CAAC;AAEtD,kGAAkG;AACrF,QAAA,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8WjC,CAAC"}
1
+ {"version":3,"file":"gimpPluginSource.js","sourceRoot":"","sources":["../../src/core/gimpPluginSource.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,wDAAwD;AACxD,EAAE;AACF,oFAAoF;AACpF,wFAAwF;AACxF,EAAE;AACF,4GAA4G;AAC5G,0DAA0D;AAC1D,8EAA8E;;;AAE9E,4EAA4E;AAC/D,QAAA,uBAAuB,GAAG,cAAc,CAAC;AAEtD,kGAAkG;AACrF,QAAA,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0WjC,CAAC"}
@@ -167,6 +167,7 @@ function getCatalog(platform) {
167
167
  notes: [
168
168
  `Log: ${gimpLogPath(platform)} (Store/MSIX GIMP also mirrors a copy inside its sandbox LocalCache).`,
169
169
  `The client runs via \`uv run --with ${exports.GIMP_MCP_PIN} <installed client>\`; the ${exports.GIMP_MCP_PIN} pin is load-bearing (current mcp releases break the client on a removed description= kwarg).`,
170
+ 'GIMP 3.2.4 can crash (access-violation) on TextLayer merge_down/merge_filter — rasterize text via Gimp.Layer.new_from_visible first, then filter/merge the raster copy.',
170
171
  ],
171
172
  },
172
173
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"mcpCatalog.js","sourceRoot":"","sources":["../../src/core/mcpCatalog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcpCatalog.js","sourceRoot":"","sources":["../../src/core/mcpCatalog.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autodev-cli",
3
- "version": "1.4.152",
3
+ "version": "1.4.153",
4
4
  "description": "AutoAIDev CLI — autonomous AI task loop with VS Code / Cursor launcher",
5
5
  "author": "Peter Ivanov <peter@microweber.com>",
6
6
  "license": "MIT",