feat: MCP Bridge Workbench, just command cleanup, testing, etc. (#24)

* fix: lots of fixes and name refactoring

* feat: Add workbench preferences

* fix: MCP bridge status widget and just command fixes

* fix(tests): Use the correct mesa-glx package

* fix(ci): Add fontconfig to GUI test dependencies

FreeCAD GUI was failing to start with:
"Fontconfig error: Cannot load default config file: No such file"

Added fontconfig and fonts-dejavu-core packages to the GUI test job
dependencies to resolve the font configuration issue.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(addon): Extract path utilities into shared module

Create path_utils.py module that consolidates duplicated path-finding
logic from commands.py and InitGui.py:
- get_addon_path(): Find addon directory with caching and fallbacks
- get_icon_path(): Get full path to an icon file
- get_icons_dir(): Get path to icons directory
- get_workbench_icon(): Get path to workbench main icon

This removes ~100 lines of duplicated code while preserving the same
behavior including _addon_path_cache and all fallback methods.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(addon): Prevent stale plugin state on startup failure

The StartMCPBridgeCommand.Activated method could leave _mcp_plugin in
a partially initialized state if FreecadMCPPlugin.start() failed after
the plugin was instantiated.

Changes:
- Create plugin in a local variable first
- Only assign to _mcp_plugin after start() succeeds
- Explicitly clear _mcp_plugin and _running_config in exception
  handlers to ensure clean state for subsequent retry attempts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Lot of broad improvements

* fix(ci): Use blocking headless_server.py for GUI tests

The GUI test was using startup_bridge.py which is non-blocking
(designed for interactive use). For CI, even in GUI mode, we need
the blocking headless_server.py that calls run_forever() to keep
FreeCAD running. GUI features are still available since we use
the 'freecad' executable instead of 'freecadcmd'.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(addon): Rename headless_server.py to blocking_bridge.py

The old name was misleading because:
- It works with both GUI (freecad) and headless (freecadcmd) modes
- The key characteristic is that it BLOCKS with run_forever()

New naming convention clarifies the difference:
- blocking_bridge.py: Starts bridge and blocks (for CI, servers)
- startup_bridge.py: Starts bridge and returns (for interactive GUI)

Updated all references across:
- GitHub workflow (macro-test.yaml)
- Just commands (freecad.just)
- Unit tests (test_addon_structure.py)
- Documentation (5 files)
- CLAUDE.md

Also improved the script to detect GUI mode dynamically using
FreeCAD.GuiUp and display the appropriate status message.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(just): Remove erroneous rm of startup_bridge.py on error

The startup script is now a permanent source file in the repository,
not a generated temporary file. The rm -f would have deleted source
code if FreeCAD wasn't found.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: General improvements

* fix: Lots of general fixes and only stable to PyPi

* fix: small cleanup

* fix: Small fixes and hopefully fixes the GUI tests

* fix: Add proper library paths for FreeCAD GUI in CI

- Create wrapper scripts instead of symlinks for AppImage binaries
- Set LD_LIBRARY_PATH, QT_PLUGIN_PATH for GUI mode
- Add diagnostic output to identify startup failures

* fix: Use apprun for GUI tests in CI

* fix: Improving Xvfb tests

* fix: GUI tests worlk

* chore: remove invalid --no-splash comments

* fix: ARM64 architecture support and other fixes

* fix: cleanup

* test: just commands test suite

* test: improve just command tests

* fix: more general improvements

* fix: more cleanup

* fix: more updates

* fix: small tweaks

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Sean P. Kane
2026-01-10 15:26:33 -08:00
committed by GitHub
co-authored by Claude Opus 4.5
parent bcc3048876
commit 8c338f6da7
110 changed files with 7821 additions and 1276 deletions
+30 -23
View File
@@ -9,7 +9,7 @@ repos:
# General File Hygiene
# ==========================================================================
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: v6.0.0
hooks:
- id: trailing-whitespace
exclude: \.md$ # Allow trailing spaces in markdown for line breaks
@@ -48,7 +48,7 @@ repos:
# Python - Linting and Formatting
# ==========================================================================
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.4
rev: v0.14.11
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
@@ -62,7 +62,7 @@ repos:
# Python - Type Checking
# ==========================================================================
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.14.0
rev: v1.19.1
hooks:
- id: mypy
additional_dependencies:
@@ -77,7 +77,7 @@ repos:
# Python - Security Scanning
# ==========================================================================
- repo: https://github.com/PyCQA/bandit
rev: 1.8.0
rev: 1.9.2
hooks:
- id: bandit
args: [-c, pyproject.toml, -r, src, macros]
@@ -107,7 +107,7 @@ repos:
# Scans git history and current files using regex patterns
# Config: .gitleaks.toml
- repo: https://github.com/gitleaks/gitleaks
rev: v8.21.2
rev: v8.30.0
hooks:
- id: gitleaks
name: gitleaks (secrets scanner)
@@ -141,7 +141,7 @@ repos:
# It's skipped in CI (via SKIP env var) but runs locally.
# See: https://github.com/trufflesecurity/trufflehog/issues/3321
- repo: https://github.com/trufflesecurity/trufflehog
rev: v3.88.7
rev: v3.92.4
hooks:
- id: trufflehog
name: trufflehog (verified secrets scan)
@@ -156,7 +156,7 @@ repos:
# markdownlint-cli2 - Comprehensive markdown linter with auto-fix
# Config: .markdownlint.yaml
- repo: https://github.com/DavidAnson/markdownlint-cli2
rev: v0.17.1
rev: v0.20.0
hooks:
- id: markdownlint-cli2
name: markdownlint (linter)
@@ -176,7 +176,7 @@ repos:
# Spell Checking
# ==========================================================================
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
rev: v2.4.1
hooks:
- id: codespell
additional_dependencies:
@@ -191,12 +191,12 @@ repos:
# Configuration Validation
# ==========================================================================
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.23
rev: v0.24.1
hooks:
- id: validate-pyproject
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.30.0
rev: 0.36.0
hooks:
- id: check-github-workflows
name: validate GitHub workflows
@@ -207,7 +207,7 @@ repos:
# GitHub Actions Linting
# ==========================================================================
- repo: https://github.com/rhysd/actionlint
rev: v1.7.4
rev: v1.7.10
hooks:
- id: actionlint
name: actionlint (GitHub Actions linter)
@@ -216,7 +216,7 @@ repos:
# Shell Script Linting
# ==========================================================================
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.10.0.1
rev: v0.11.0.1
hooks:
- id: shellcheck
name: shellcheck (shell linter)
@@ -225,26 +225,34 @@ repos:
# ==========================================================================
# Dockerfile Linting
# ==========================================================================
- repo: https://github.com/hadolint/hadolint
rev: v2.13.1-beta
# hadolint-py: Python wrapper that auto-downloads hadolint binary
# No Docker or system installation required
- repo: https://github.com/AleksaC/hadolint-py
rev: v2.14.0
hooks:
- id: hadolint-docker
name: hadolint (Dockerfile linter)
- id: hadolint
# ==========================================================================
# Dockerfile Security Scanning (Misconfigurations)
# ==========================================================================
- repo: https://github.com/mxab/pre-commit-trivy.git
rev: v0.16.0
# Uses mise-managed trivy binary instead of pre-commit repo.
# This avoids case-conflicting git refs in pre-commit-trivy repo that break
# `pre-commit autoupdate` on case-insensitive filesystems (macOS).
# Version is managed in .mise.toml - update with `mise upgrade trivy`
- repo: local
hooks:
- id: trivyconfig-docker
- id: trivy
name: trivy (Dockerfile misconfig)
entry: trivy
args:
- config
- --severity
- HIGH,CRITICAL
- --exit-code
- "1"
- .
language: system
files: (Dockerfile|\.dockerfile)$
pass_filenames: true
# ==========================================================================
# Documentation Build Validation
@@ -262,7 +270,7 @@ repos:
# Commit Message Linting
# ==========================================================================
- repo: https://github.com/commitizen-tools/commitizen
rev: v4.1.0
rev: v4.11.1
hooks:
- id: commitizen
name: commitizen (commit format)
@@ -303,7 +311,6 @@ ci:
autoupdate_commit_msg: "chore(deps): update pre-commit hooks"
skip:
- mypy # Needs dependencies installed
- hadolint-docker # Needs Docker
- trivyconfig-docker # Needs Docker
- trivy # Uses mise-managed binary (local repo)
- trufflehog # Can be slow in CI
- coderabbit # GitHub App handles PR reviews; CLI is for local use