* 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>
10 KiB
MkDocs Documentation Guide
This project uses MkDocs with the Material theme for documentation. This guide covers our specific configuration, extensions, and how to use them.
Quick Start
# Serve docs locally with live reload
just documentation::serve
# Build static site
just documentation::build
# Open docs in browser
just documentation::open
Theme Configuration
We use Material for MkDocs with dark mode as the default. Users can toggle between dark and light modes using the sun/moon icon in the header.
Color scheme: Deep purple primary with purple accent.
Markdown Extensions
Code Blocks
Syntax Highlighting
Standard fenced code blocks with language hints:
```python
def hello():
print("Hello, world!")
```
Line Numbers and Highlighting
```python linenums="1" hl_lines="2 3"
def hello():
# These lines are highlighted
print("Hello!")
```
Code Annotations
Add numbered annotations that expand on hover:
```python
def process(data): # (1)!
return data.strip() # (2)!
```
1. This function processes input data
2. Removes leading/trailing whitespace
Inline Code Highlighting
Use #!python print("inline") for inline syntax highlighting:
Use `#!python print("inline")` for inline code with highlighting.
Tabbed Content
Create tabs for platform-specific or alternative content:
=== "macOS"
```bash
~/Library/Application Support/FreeCAD/Macro/
```
=== "Linux"
```bash
~/.local/share/FreeCAD/Macro/
```
=== "Windows"
```bash
%APPDATA%/FreeCAD/Macro/
```
Renders as:
=== "macOS"
```bash
~/Library/Application Support/FreeCAD/Macro/
```
=== "Linux"
```bash
~/.local/share/FreeCAD/Macro/
```
=== "Windows"
```bash
%APPDATA%/FreeCAD/Macro/
```
Admonitions (Call-outs)
Create styled call-out boxes:
!!! note "Optional Title"
This is a note admonition.
!!! warning
This is a warning without a custom title.
!!! danger "Critical"
This is a danger/error admonition.
!!! tip
This is a tip admonition.
!!! info
This is an info admonition.
!!! example
This is an example admonition.
Collapsible admonitions:
??? note "Click to expand"
This content is hidden by default.
???+ note "Expanded by default"
This content is visible but can be collapsed.
Available types: note, abstract, info, tip, success, question, warning, failure, danger, bug, example, quote
Task Lists
Create checkbox lists:
- [x] Completed task
- [ ] Incomplete task
- [ ] Another task
Renders as:
- Completed task
- Incomplete task
- Another task
Keyboard Keys
Style keyboard shortcuts:
Press ++ctrl+c++ to copy.
Press ++cmd+shift+p++ on macOS.
Press ++enter++ to confirm.
Renders as: Press ++ctrl+c++ to copy.
Common keys: ctrl, alt, shift, cmd, enter, tab, esc, backspace, delete, up, down, left, right, f1-f12
Text Formatting
Highlighting
==This text is highlighted==
Renders as: ==This text is highlighted==
Subscript and Superscript
H~2~O (subscript)
x^2^ (superscript)
Renders as: H2O and x^2^
Strikethrough
~~deleted text~~
Renders as: deleted text
Critic Markup (for diffs/reviews)
{--deleted--}
{++added++}
{~~old~>new~~}
{==highlighted==}
{>>comment<<}
Definition Lists
Term 1
: Definition for term 1
Term 2
: Definition for term 2
: Can have multiple definitions
Renders as:
- Term 1
- Definition for term 1
- Term 2
- Definition for term 2
- Can have multiple definitions
Footnotes
This needs a citation[^1].
[^1]: This is the footnote content.
Mermaid Diagrams
Create diagrams using Mermaid syntax:
```mermaid
graph LR
A[MCP Client] --> B[Robust MCP Server]
B --> C[FreeCAD Bridge]
C --> D[FreeCAD]
```
Renders as:
graph LR
A[MCP Client] --> B[Robust MCP Server]
B --> C[FreeCAD Bridge]
C --> D[FreeCAD]
Supported diagram types: flowchart, sequence, class, state, ER, gantt, pie, journey
Plugins
Git Revision Date
Pages automatically show "Last updated X ago" at the bottom. No action needed.
Image Lightbox (GLightbox)
All images are automatically zoomable. Click any image to open in a lightbox overlay.
To exclude an image from lightbox:
{ .off-glb }
Minification
HTML is automatically minified in production builds. No action needed.
Search
Full-text search is enabled. Features:
- Search suggestions as you type
- Search result highlighting
- Shareable search URLs
Macros Plugin
Custom Delimiters
!!! warning "Important" We use custom delimiters to avoid conflicts with Python dict literals in code blocks.
- Variables: `{` `{@` and `@}` `}`
- Blocks: `{%` `@` and `@` `%}`
Standard Jinja2 `{` `{` `}` `}` syntax will NOT work.
Using Variables
Variables are defined in docs/variables.yaml:
# docs/variables.yaml
project_name: FreeCAD Robust MCP Server
package_name: freecad-robust-mcp
xmlrpc_port: 9875
socket_port: 9876
Use in Markdown:
The default XML-RPC port is {{@ xmlrpc_port @}}.
Install with: `pip install {{@ package_name @}}`
Available Variables
| Variable | Value | Description |
|---|---|---|
project_name |
FreeCAD Robust MCP Server | Display name |
package_name |
freecad-robust-mcp | PyPI package name |
docker_image |
spkane/freecad-robust-mcp | Docker image |
xmlrpc_port |
9875 | XML-RPC server port |
socket_port |
9876 | Socket server port |
paths.macos.macro |
~/Library/... | macOS macro path |
paths.linux.macro |
~/.local/share/... | Linux macro path |
paths.windows.macro |
%APPDATA%/... | Windows macro path |
Built-in Macros
Current time: {{@ now() @}}
Page URL: {{@ page.url @}}
API Documentation (mkdocstrings)
Auto-generate API docs from Python docstrings:
::: freecad_mcp.server
options:
show_source: true
heading_level: 3
This renders the module's docstrings, classes, and functions automatically.
Options:
show_source: true- Show source codeheading_level: 3- Start headings at h3members: [func1, func2]- Only show specific membersfilters: ["!^_"]- Exclude private members
Navigation
Features Enabled
- Instant navigation - Pages load without full refresh
- Navigation tabs - Top-level sections as tabs
- Section index pages - Click section to see overview
- Back to top - Button appears when scrolling
- Table of contents - Follows scroll position
Images
Basic Image

Image with Caption
<figure markdown>

<figcaption>This is the caption</figcaption>
</figure>
Image Alignment
{ align=left }
{ align=right }
Image Size
{ width="300" }
Links
Internal Links
[Installation Guide](../getting-started/installation.md)
[Config section](configuration.md#environment-variables)
External Links
External links automatically open in new tab (Material theme default).
[FreeCAD](https://www.freecad.org/)
Tables
Standard Markdown tables with sorting enabled:
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Data 1 | Data 2 | Data 3 |
| Data 4 | Data 5 | Data 6 |
File Structure
docs/
├── index.md # Home page
├── variables.yaml # Macros variables
├── overrides/ # Theme customizations
│ └── .gitkeep
├── assets/ # Images, favicon, etc.
├── getting-started/
│ ├── installation.md
│ ├── configuration.md
│ └── quickstart.md
├── guide/
│ └── ...
├── api/
│ └── ...
└── development/
├── contributing.md
├── architecture.md
├── releasing.md
└── mkdocs-guide.md # This file
Common Tasks
Adding a New Page
- Create the markdown file in the appropriate directory
- Add to
nav:section inmkdocs.yaml
Adding Redirects
If you move/rename a page, add a redirect in mkdocs.yaml:
plugins:
- redirects:
redirect_maps:
'old-page.md': 'new-location/new-page.md'
Custom CSS
Add custom styles in docs/overrides/stylesheets/extra.css and reference in mkdocs.yaml:
extra_css:
- overrides/stylesheets/extra.css
Custom JavaScript
Add scripts in docs/overrides/javascripts/extra.js and reference in mkdocs.yaml:
extra_javascript:
- overrides/javascripts/extra.js
Troubleshooting
Macros Not Rendering
Remember to use custom delimiters: {{@ variable @}} not {{ variable }}.
Git Revision Date Warnings
New files not yet committed will show warnings. Commit the file to fix.
Build Errors
# Check for syntax errors
uv run mkdocs build --strict
# Verbose output
uv run mkdocs build -v
Serve Not Auto-Reloading
Some changes (like mkdocs.yaml) require restarting the server.