Skip to content

macOS MeshAgent: Complete Rebuild and Enhancement#313

Open
PeetMcK wants to merge 20 commits intoYlianst:masterfrom
PeetMcK:_100-PR-macOS-MeshAgent-Rebuild
Open

macOS MeshAgent: Complete Rebuild and Enhancement#313
PeetMcK wants to merge 20 commits intoYlianst:masterfrom
PeetMcK:_100-PR-macOS-MeshAgent-Rebuild

Conversation

@PeetMcK
Copy link

@PeetMcK PeetMcK commented Nov 27, 2025

macOS MeshAgent: Complete Rebuild and Enhancement

Overview

This PR represents a comprehensive rebuild and enhancement of the macOS MeshAgent, implementing native macOS features, improving security, and providing a modern installation experience. The work includes KVM improvements, installation infrastructure, TCC permission handling, force agent updates with surgical plist management, configurable naming for white-label deployments, and extensive documentation.

Summary

This PR transforms the macOS MeshAgent into a first-class macOS application with:

  • 🖥️ Native macOS KVM architecture with LaunchD integration
  • 🔐 Comprehensive TCC permissions system with real-time detection
  • 📦 Professional Installation Assistant GUI for easy deployment
  • 🏢 Multi-tenancy support via ServiceID system
  • 🔄 Force agent updates with surgical plist preservation
  • 🏷️ White-label support via configurable naming derived from executable
  • 📚 Extensive documentation (103+ module docs, command reference, architecture guides)
  • 🛡️ Enhanced security with path validation and permission management

Commit Structure

This PR is organized into 9 chronological commit groups following the actual development timeline:

1. macOS: Implement KVM1 reversed socket architecture with LaunchD integration

  • Complete rewrite of macOS KVM (remote desktop) architecture
  • Reversed socket model: Agent creates socket, KVM connects through LaunchD
  • Eliminates security issues with traditional approach
  • Proper privilege separation and sandboxing support
  • Architecture: docs/macos-KVM-Architecture.md

2. macOS: Add ServiceID system for multiple installations

  • Reverse DNS-style service identification: meshagent[.serviceName][.companyName]
  • Enables multiple independent MeshAgent installations on same system
  • Support for multi-tenancy and service variants
  • Proper LaunchDaemon/LaunchAgent namespace separation
  • Documentation: docs/macOS-ServiceID-System.md

3. macOS: Unify -install and -upgrade commands with build infrastructure

  • Unified installation and upgrade logic for macOS
  • Professional logging infrastructure with timestamps
  • macOS application bundle support with proper Info.plist embedding
  • Build system improvements for universal binaries
  • Recursive directory creation for installation paths
  • Code-signing and notarization workflow integration

4. macOS: Add logger module and TCC permissions UI

  • New logger.js module with DEBUG/INFO/WARN/ERROR levels
  • Real-time TCC permission detection (Accessibility, Screen Recording, Full Disk Access)
  • Interactive permissions UI with visual status indicators
  • Pipe-based IPC for elevated permission checking
  • Preference-aware TCC checking (--disableTccCheck support)
  • Documentation: docs/macos-tcc-permissions.md

5. macOS: Add Installation Assistant UI and infrastructure improvements

  • Native Cocoa Installation Assistant with install/upgrade detection
  • Automatic .msh file discovery in app bundle and Downloads
  • Configuration viewer with value truncation
  • Admin credential prompting via Authorization Services
  • Installation path validation with security checks
  • Progress tracking and operation result display
  • Documentation: docs/macos-install-assistant.md

6. macOS: Final polish and stability improvements

  • Bug fixes:
    • Fixed normalizeInstallPath() incorrectly stripping 'meshagent' from paths
    • Fixed prepareFolders() to use recursive directory creation
    • Fixed validate_installation_path() to handle non-existent parent directories
  • Complete command reference documentation
  • 103+ comprehensive module documentation files
  • Updated README with full documentation index
  • macOS helper functions module (macOSHelpers.js)
  • Security permissions management module (security-permissions.js)

7. macOS: Polish install/upgrade, app bundle, and build system

Install/Upgrade Improvements:

  • Comprehensive argument validation system (whitelist-based security)
  • Fixed -fullinstall path construction and LaunchAgent handling
  • Enhanced service lookup for custom ServiceIDs during self-update
  • Install validation prevents blank .db creation
  • Installer logging with verbosity control
  • Launchctl job cleanup prevents upgrade conflicts
  • Replaced implicit self-upgrade detection with explicit LaunchDaemon plist scan
  • Refactored plist updates with cached customizations (surgical updates)

Force Agent Updates:

  • Server-triggered updates via MeshCentral -upgrade command
  • Surgical plist updates preserve user customizations during force updates
  • Atomic plist creation for fresh installations
  • Version tracking via meshagent_ver key in LaunchDaemon/LaunchAgent plists
  • Success/failure tracking via UpdateInProgress flag

App Bundle Enhancements:

  • Set app bundle capability bit (0x80) for proper .app bundle detection
  • Fixed critical bugs in bundle handling and upgrade process
  • Complete zip creation, signing, and notarization workflow
  • Runtime universal binary detection

Build System:

  • MODULESYNC_MODE build variable with macos-only default
  • Embedded version info exposed to JavaScript (DRY compliant)
  • -buildver and -fullversion flags for version reporting
  • Enhanced build output with version verification and improved formatting
  • Add meshagent_ver to LaunchDaemon/LaunchAgent plists

Bug Fixes:

  • AC power detection fix in pmset parsing
  • LaunchAgent log file permissions (666 for user access)
  • Improved Install UI version detection using meshagent binary

8. macOS: Configurable naming, ServiceID overhaul, UI enhancements, and DRY refactoring

Configurable Naming (White-Label Support):

  • Replace all hardcoded "meshagent" references with dynamic names derived from executable
  • Enables white-label deployments (e.g., AcmeMesh, CustomAgent)
  • ServiceID and config filenames (.msh/.db) derived from executable name
  • Read ServiceID from .msh configuration files
  • Add --setServiceID flag to override during install/upgrade
  • Resolve serviceID from LaunchDaemon plist Label as fallback
  • Reuse existing plist filenames during upgrade to prevent duplicates
  • Parameterize plist parser with configurable agent name

Deployment Assistant UI Overhaul:

  • Add uninstall mode (standard + full uninstall) with confirmation dialogs
  • Replace SF Symbols with custom-drawn Lucide/Bootstrap vector icons (no macOS 11+ dependency for icons)
  • Settings card with 2×2 checkbox grid (updates, TCC, verbose logging, agent logging)
  • Dynamic button text and icon tinting based on selected mode
  • Pre-populate .msh and install path fields regardless of initial mode
  • .msh file viewer as modal sheet with sorted key-value table

TCC Permissions UI:

  • Replace SF Symbols checkmarks with custom Lucide circle-check-fill icons
  • Use shared mesh_createFloatingWindow() for window creation
  • Shared helpers for buttons and checkboxes

DRY Refactoring — Shared UI Helpers (mac_ui_helpers.h/m):

  • mesh_createVectorIcon() — generic vector icon with configurable viewBox size
  • mesh_createLucideIcon() — Lucide icon wrapper (24×24 viewBox)
  • mesh_bootstrapShieldCheckIcon() / mesh_lucideShieldCheckIcon() — shield icons
  • mesh_lucideCircleCheckFillIcon() — filled circle-check for success indicators
  • mesh_lucideNetworkIcon(), mesh_lucideImportIcon(), mesh_lucideUploadIcon(), mesh_lucideTrashIcon()
  • mesh_addRadioIcon() — attach icon to radio button
  • mesh_createCheckbox(), mesh_createRoundedButton(), mesh_createPathField()

Build System:

  • Parameterize with EXENAME and BUNDLE_DISPLAY_NAME make variables
  • Rename icon asset to generic AppIcon.icns
  • Update all build/sign/notarize scripts for configurable names

Other:

  • Fix argument validation to skip JS code after -exec/-b64exec
  • Remove companyName/meshServiceName from KVM path resolution
  • Remove TCC-DEBUG logging and orphaned format arguments
  • Update documentation for ServiceID system and commands

9. macOS: Consolidate build scripts, remove dead code, document makefile

Build Script Consolidation:

  • Replace 5 sign/notarize scripts with 2 unified multi-target scripts
    (macos-sign.sh and macos-notarize.sh) that auto-detect .app bundles
    vs bare binaries
  • Parallel notarization support for multiple targets (submit all, wait all)
  • Delete sign-app-bundle.sh, notarize-app-bundle.sh, notarize-app-bundles.sh
  • Update makefile to call consolidated scripts

Dead Code Removal:

  • Delete macos-build_sign_notarize.sh (makefile is the build interface)
  • Delete MeshAgent_pkg directory and --build-pkg option
  • Remove unused -request-fulldiskaccess CLI flag and standalone FDA dialog
  • Replace populate-FULL-polyfills.sh with minimal example in code-utils/

Build Toolchain Cleanup:

  • Move generate-build-timestamp.sh and generate-info-plist.sh into macos_build/
  • Unify visual output style (colors, formatting) across all macOS build scripts
  • Rewrite macos_build/README.md around makefile-driven workflows

Documentation:

  • Document macOS-specific build switches (SIGN, NOTARIZE, EXENAME,
    BUNDLE_DISPLAY_NAME, BUNDLE_ID, BUNDLE_ICON, SKIPSIGNNOTARY)
    in makefile header with usage examples
  • Add ARCHID=10005 (universal) to standard builds list

Net result: 22 files changed, +643 / −2,926 lines


Key Features

🖥️ Remote Desktop (KVM)

  • Reversed Socket Architecture: Agent creates Unix domain socket, KVM connects via LaunchD
  • LaunchD Integration: Proper service lifecycle management
  • Security: Eliminates need for KVM to bind sockets as root
  • TCC Compliance: Integrates with macOS permission system

🔐 Security & Permissions

  • TCC Permissions UI: Real-time detection and visual indicators for required permissions
  • Path Validation: Installation paths validated against allowed locations
  • Permission Management: Automated file permission setting with security policies
  • Code Signing: Integrated workflow for signing and notarization
  • Argument Validation: Whitelist-based security for macOS arguments

📦 Installation Experience

  • GUI Installation Assistant: Native Cocoa interface for install/upgrade/uninstall
  • Auto-Discovery: Automatic .msh file detection
  • White-Label: Configurable naming from executable name
  • Progress Tracking: Real-time feedback during operations

🏷️ White-Label Support

  • Executable-Derived Naming: All UI labels, file paths, and plist identifiers derived from binary name
  • --setServiceID Override: Explicit control over service naming during install/upgrade
  • Build Parameterization: EXENAME, BUNDLE_DISPLAY_NAME, BUNDLE_ID, and BUNDLE_ICON make variables
  • Default Fallbacks: "meshagent" used as default when executable name cannot be determined

🔄 Agent Updates & Plist Management

  • Force Updates: Server-triggered agent updates via MeshCentral
  • Surgical Plist Updates: Preserve user customizations during updates
  • Atomic vs Surgical: Intelligent update strategy based on plist state

🏗️ Build Infrastructure

  • Universal Binaries: ARM64 + x86_64 support
  • App Bundle Creation: Proper .app bundle structure with Info.plist
  • Module Embedding: JavaScript modules embedded at build time
  • Configurable Names: EXENAME / BUNDLE_DISPLAY_NAME / BUNDLE_ID / BUNDLE_ICON build variables
  • Consolidated Scripts: 2 unified sign/notarize scripts replace 5, with auto-detection and parallel support
  • Self-Documenting: All macOS build switches documented in makefile header
  • Version Management: Embedded version info with DRY compliance

📚 Documentation


New Modules

modules/logger.js

Professional logging infrastructure with:

  • Log levels: DEBUG, INFO, WARN, ERROR
  • Timestamp formatting
  • Runtime log level configuration
  • Zero dependencies, cross-platform

modules/macOSHelpers.js

macOS platform helper functions:

  • Bundle detection and path resolution
  • ServiceID generation with reverse DNS conventions
  • LaunchDaemon/LaunchAgent management
  • Plist manipulation utilities

modules/security-permissions.js

Security permissions management:

  • File permission policies for 9 critical file types
  • Permission verification and enforcement
  • Secure file creation with race condition prevention
  • Installation integrity validation

modules/agent-paths.js

Agent path resolution:

  • Dynamic path computation from executable name
  • Cross-platform path normalization

Testing

Tested On

  • ✅ macOS 15.x (Sequoia) - ARM64
  • ✅ macOS 12.x (Monterey) - x86_64
  • ✅ Universal binary functionality verified

Test Coverage

  • ✅ Fresh installation with GUI
  • ✅ Fresh installation via command-line
  • ✅ Upgrade from existing installation
  • ✅ Uninstall and full uninstall via GUI
  • ✅ Multiple installations with different ServiceIDs
  • ✅ White-label deployment with custom executable name
  • ✅ TCC permission detection and UI
  • ✅ KVM functionality with LaunchD
  • ✅ Installation path validation
  • ✅ Recursive directory creation
  • ✅ Bundle detection and operations
  • ✅ Code signing and notarization workflow
  • ✅ Force update from MeshCentral server
  • ✅ Surgical plist update preserves customizations
  • ✅ Atomic update for fresh installations
  • ✅ Version tracking and verification
  • ✅ Argument validation and security
  • ✅ Self-upgrade detection via LaunchDaemon plist scan
  • ✅ Consolidated build scripts (multi-target sign/notarize)

Security Testing

  • ✅ Path validation (injection prevention)
  • ✅ Permission verification
  • ✅ Race condition prevention in file creation
  • ✅ Privilege escalation handling
  • ✅ TCC compliance verification
  • ✅ Argument validation against malicious inputs

Migration Guide

For Users Upgrading from Previous Versions

Installation:

  1. Download new MeshAgent.app and .msh file (if new install)
  2. Hold CMD key and double-click MeshAgent.app
  3. Follow Installation Assistant (auto-detects upgrade)

Or via command-line:

sudo ./meshagent -install --installPath="/existing/path/"

ServiceID Migration:

  • Existing installations maintain compatibility
  • New installations use reverse DNS format
  • Multiple installations now supported via ServiceID

Force Updates:

  • Existing installations will receive surgical updates (customizations preserved)
  • Fresh installations use atomic plist creation
  • Version tracking helps detect update success/failure

For Developers

Build Requirements:

  • Xcode Command Line Tools
  • Code signing certificate (optional, for distribution)

Building:

make macos ARCHID=10005                                        # Universal binary (default naming)
make macos ARCHID=29                                           # ARM only
make macos ARCHID=10005 SIGN=1 NOTARIZE=1                     # Signed + notarized
make macos ARCHID=10005 EXENAME=acmemesh                      # White-label binary name
make macos ARCHID=10005 BUNDLE_DISPLAY_NAME="AcmeMesh"        # White-label display name
make macos ARCHID=10005 BUNDLE_ID=com.acme.mesh                # Custom bundle identifier
make macos ARCHID=10005 BUNDLE_ICON=/path/to/icon.icns         # Custom icon
make macos ARCHID=10005 SIGN=1 SKIPSIGNNOTARY=bundle           # Sign binary only

Documentation:


Compatibility

Maintains Compatibility With:

  • ✅ MeshCentral server communication protocol
  • ✅ Existing .msh configuration files
  • ✅ Existing LaunchDaemon configurations
  • ✅ Cross-platform module APIs

Platform Support:

  • macOS: Full support (primary focus of this PR)
  • Windows: Unaffected
  • Linux: Unaffected
  • BSD: Unaffected

Related Issues

This PR addresses multiple long-standing issues and feature requests for macOS:

  • macOS KVM architecture improvements
  • Installation experience enhancement
  • TCC permission handling
  • Multi-tenancy support
  • White-label deployment support
  • Force agent updates with customization preservation
  • Documentation completeness

Related MeshCentral PR:


Checklist

  • Self-review completed
  • Documentation updated
  • Manual testing completed
  • Backward compatibility verified
  • Security considerations addressed
  • Commit history is clean and organized
  • PR description is comprehensive

Issues & Bug Reports

If you encounter any problems with this PR, please open an issue on my fork:

…ration

Reverse the KVM socket architecture so the agent connects TO the KVM process
instead of the KVM process connecting to the agent. This enables proper macOS
LaunchAgent integration for TCC (Transparency, Consent, Control) permissions.

Core changes:
- mac_kvm_auth.c/h: New authentication module for KVM socket connections
- mac_kvm.c/h: Implement reversed socket architecture with LaunchD support
- linux_kvm.c/h: Update Linux KVM to support new architecture patterns
- agentcore.c/h: Add KVM1 infrastructure and configuration support

This is the foundational architectural change that enables proper macOS
permission handling and multi-installation support via ServiceID system.
Implement ServiceID system to support multiple MeshAgent installations on the
same machine with complete isolation between instances.

Core changes:
- agent-installer.js: Add service-specific installation paths (~/.mesh_serviceId/)
- service-manager.js: LaunchDaemon/LaunchAgent integration with ServiceID support

Key features:
- Service-specific data directories prevent conflicts between installations
- LaunchDaemon integration for proper macOS service management
- Each installation maintains independent configuration and state
- Enables testing, development, and production instances side-by-side

This builds on the KVM1 architecture to enable proper isolation between
multiple agent instances.
Major overhaul of installation system and build infrastructure:

Installation System:
- Unified installServiceUnified() function replaces separate -install/-upgrade
- Auto-upgrade mode when existing installation detected
- 4-tier config discovery: command flags → plist → .msh → .db
- LaunchDaemon/LaunchAgent plist generation for KVM1 architecture
- Support for service-specific installation paths

App Bundle Support:
- bundle_detection.c/h for runtime .app bundle detection
- Automatic .app bundle creation during build
- Support for both bundled and standalone binary installations
- Proper resource path resolution for different execution modes

Build System Overhaul:
- Universal binary support (arm64 + x86_64) via ARCHID=10005
- Automated code signing (macos-sign.sh) and notarization (macos-notarize.sh)
- Consolidated build scripts (macos-build_with_test.sh)
- Info.plist template system for binary and bundle modes
- Module synchronization and timestamp generation tooling
- Code-utils for minimal 8-module development builds

Platform Helpers:
- macOSHelpers.js module with shared macOS utilities
- security-permissions.js for file permission management
- Cross-platform compatibility improvements

This builds on KVM1 and ServiceID to deliver a complete modern macOS
installation and build system.
@PeetMcK PeetMcK force-pushed the _100-PR-macOS-MeshAgent-Rebuild branch 2 times, most recently from c0dd959 to 984ccb5 Compare November 27, 2025 11:37
@PeetMcK PeetMcK marked this pull request as ready for review November 27, 2025 11:39
@llambkin
Copy link

@PeetMcK

Congratulations and thankyou for your hard work on this functionality. Its been great to watch and test this as the process moves along. I can't wait for this to get pushed through to main line, and I can start deploying the agent to all our Mac clients.

@PeetMcK PeetMcK force-pushed the _100-PR-macOS-MeshAgent-Rebuild branch from 984ccb5 to 3670129 Compare November 28, 2025 18:41
@si458
Copy link
Collaborator

si458 commented Dec 3, 2025

you accidently pushed ur tactial agent into the repo, please can u remove it

PeetMcK and others added 5 commits December 4, 2025 08:40
Professional logging infrastructure and TCC permissions detection:

Logger Module:
- logger.js: Centralized logging with timestamps and log levels
- Migrate agent-installer.js to use logger (107 instances)
- Consistent logging format across install/upgrade/uninstall operations
- Support for both console and file-based logging

TCC Permissions UI:
- mac_permissions_window.m/h: Native Cocoa UI for permission management
- mac_tcc_detection.c/h: Real-time TCC permission detection
- Detects Accessibility, Full Disk Access, and Screen Recording permissions
- Native "Open System Settings" buttons for each permission
- "Do not remind me again" preference support
- SHIFT+double-click activation from agent binary
- Integration with install flow

This builds on the installation system to provide better visibility into
installation progress and help users grant required macOS permissions.
Complete macOS Installation Assistant with professional UI:

Installation Assistant:
- mac_install_window.m/h: Native macOS installation wizard
- mac_authorized_install.m/h: Admin credential prompting with Authorization Services
- Real-time progress display with scrollable log output
- .msh file viewer with validation
- Version display (current + installed for upgrade mode)
- CMD+double-click activation from agent binary
- TCC check toggle, auto-update toggle
- Professional macOS-style interface with native controls

UI Infrastructure:
- mac_ui_helpers.m/h: Shared UI utilities for both TCC and Install UI
- mac_plist_utils.c/h: Plist parsing for reading configuration
- mac_logging_utils.c/h: Native logging utilities for Objective-C code

TCC UI Improvements:
- Fix TCC UI spawning during install/upgrade
- Improve permission detection reliability
- Better integration with installation flow

Build System Enhancements:
- generate-build-timestamp.sh: Centralized timestamp generation
- generate-info-plist.sh: Dynamic Info.plist generation
- sync-modules.sh: Unified module synchronization
- Improved create-app-bundle.sh with better error handling

Documentation:
- FDA (Full Disk Access) tutorial with screenshots
- TCC permissions comprehensive guide
- Installation Assistant usage documentation

Critical Security Fix:
- Fix CRITICAL command injection in KVM cleanup (CVE-candidate)
- Replace unsafe system() calls with fork/execvp
- Strict input validation for session IDs

This completes the major user-facing features and hardens security.
Final refinements and bug fixes:

Security and Stability:
- Additional memory safety improvements in KVM authentication
- Thread-unsafe progress callback fix in Installation UI
- Memory leak fixes in TCC permission checks
- Buffer overflow prevention in UI components

Code Quality:
- Remove all debug logging from production code
- Fix Accessibility detection edge cases (window removal via '-' button)
- Fix Screen Recording detection false negatives (3-window limit removed)
- Improve error handling in KVM and TCC UI components

Build System:
- Update embedded module timestamps
- Polyfills synchronization
- Build metadata refinements

This completes the macOS MeshAgent rebuild with all features stable and
production-ready.

Clean up macOS build script and rename to reflect actual purpose

Removed all MSH_EXEC functionality and 22 --msh-* arguments that were
added to support executing meshagent commands after building. This
simplifies the script to focus on its core purpose: building, signing,
and notarizing the macOS MeshAgent.

Changes:
- Removed all MSH_* variable declarations and argument parsing
- Removed command execution section (~175 lines)
- Fixed notarization validation to skip when signing is skipped
- Cleaned up final output messages
- Removed interactive prompt to open build folder
- Updated help text to remove all MSH_* documentation
- Renamed: macos-build_with_test.sh → macos-build_sign_notarize.sh
- Added version display and Install UI launch instructions at end
- Improved "must run as root" error to mention -E flag for signing

Result: Script reduced from 1138 to ~700 lines (38% reduction)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

Add build-info.plist to gitignore (auto-generated by build script)

This file is automatically updated with the current version on every build.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

Rename bundle_detection.c to mac_bundle_detection.c for consistency

All macOS utility files now follow the mac_* naming convention:
- Renamed bundle_detection.c → mac_bundle_detection.c
- Renamed bundle_detection.h → mac_bundle_detection.h
- Updated 3 include statements (agentcore.c, main.c, self-include)
- Updated makefile MACOSUTILSOURCES variable
- Updated 6 documentation files and cross-references

Tested: Build successful, functionality verified

Add missing build-info.plist for munkipkg and remove from .gitignore

The build-info.plist file is required by munkipkg to build the macOS
installer package. Previously it was deleted and gitignored with the
assumption it would be auto-generated, but no generation script exists.

Changes:
- Created build-info.plist with standard munkipkg template
- Removed build-info.plist from .gitignore
- Build script will now update version in this file during builds

The file contains:
- identifier: meshagent
- install_location: /
- version: 0.1 (updated by build script)

Make .pkg building opt-in with --build-pkg flag

Packaging functionality is not yet complete, so .pkg building should
be disabled by default and only enabled when explicitly requested.

Changes:
- Added --build-pkg flag to enable .pkg building
- Updated help text to document new flag
- Pkg building now skipped by default with info message
- Shows "Skipping .pkg build (use --build-pkg to enable)" when disabled

This prevents incomplete packaging from running on every build while
still allowing testing when needed.

Update Install UI launch instructions with open command

Simplified the final output message to show a single command that opens
Finder directly to the output directory, rather than multi-step manual
navigation instructions.

Changes:
- Changed from 3-step manual navigation to single 'open' command
- Uses full path: open $REPO_DIR/build/output/osx-universal-64-app/
- Users can then navigate to MeshAgent.app and launch it from Finder

This makes it easier to locate and launch the Install UI for testing.

Fix Install UI instructions: restore steps and make path dynamic

Fixed two issues with previous commit:
1. Restored steps 2 and 3 (CMD+double-click instructions)
2. Made path dynamic using $(dirname "$BUNDLE_PATH") instead of hardcoding

The path now adapts to the architecture being built:
- osx-x86-64-app for Intel
- osx-arm-64-app for Apple Silicon
- osx-universal-64-app for Universal binary

Example output:
  1. Navigate to: open /Users/peet/GitHub/MeshAgent/build/output/osx-universal-64-app/
  2. Hold CMD and double-click MeshAgent.app (or select it and press CMD+O)
  3. Keep holding CMD until prompted to authenticate
This folder contains test builds and should not be included in the upstream PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@PeetMcK PeetMcK force-pushed the _100-PR-macOS-MeshAgent-Rebuild branch from 3b3b240 to cbc52b8 Compare December 4, 2025 15:41
@PeetMcK
Copy link
Author

PeetMcK commented Dec 4, 2025

you accidently pushed ur tactial agent into the repo, please can u remove it

https://github.com/Ylianst/MeshAgent/compare/3b3b2408ea618fe37a4e5772991197df3f35fc76..cbc52b8e4e93d7b6569e0d51aaf26dcea6dab4f4

Cheers.Peet

@PeetMcK PeetMcK force-pushed the _100-PR-macOS-MeshAgent-Rebuild branch 2 times, most recently from 7ba681b to 9538dc5 Compare December 12, 2025 02:40
Install/Upgrade Improvements:
- Add comprehensive argument validation system
- Fix -fullinstall path construction and LaunchAgent handling
- Enhance service lookup for custom ServiceIDs during self-update
- Add install validation to prevent blank .db creation
- Improve installer logging with verbosity control
- Add launchctl job cleanup to prevent upgrade conflicts
- Replace implicit self-upgrade detection with explicit LaunchDaemon plist scan
- Refactor plist updates to use cached customizations (surgical updates)

App Bundle Enhancements:
- Set app bundle capability bit (0x80) for proper .app bundle detection
- Fix critical bugs in bundle handling and upgrade process
- Complete zip creation, signing, and notarization workflow
- Add runtime universal binary detection

Build System:
- Add MODULESYNC_MODE build variable with macos-only default
- Expose embedded version info to JavaScript (DRY compliant)
- Add -buildver and -fullversion flags for version reporting
- Enhance build output with version verification and improved formatting
- Add meshagent_ver to LaunchDaemon/LaunchAgent plists

Logging & Permissions:
- Set LaunchAgent log files to 666 permissions for user access
- Add comprehensive logging throughout install/upgrade process
- Improve Install UI version detection using meshagent binary

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@PeetMcK PeetMcK force-pushed the _100-PR-macOS-MeshAgent-Rebuild branch from c0178dd to 1bd5ad0 Compare December 14, 2025 10:22
@PeetMcK
Copy link
Author

PeetMcK commented Dec 14, 2025

#313
and
Ylianst/MeshCentral#7486

Both updated and I'm calling it good. If anyone runs into issues testin feel free to open an issue:

https://github.com/PeetMcK/MeshAgent/issues/
and
https://github.com/PeetMcK/MeshCentral/issues/

Remove excessive debug logging from TCC permission system and simplify
mesh_log_message utility to use severity-based routing instead of file
logging. Makes daemon logs cleaner and more production-ready.

Changes:

1. Simplified mesh_log_message utility (mac_logging_utils.c):
   - Changed from dual-output (stderr + file) to severity-based routing
   - Routes ERROR/WARN/FATAL/CRITICAL to stderr, everything else to stdout
   - Removed /tmp/meshagent-install-ui.log file logging
   - Auto-detects severity from message content (keyword matching)
   - Maintains immediate flush behavior for crash safety

2. Removed 89 debug logging statements across 3 components:

   TCC Permissions Window (mac_permissions_window.m): 29 logs removed
   - Removed TCCUI_LOG macro definition
   - Removed [TCC-UI] lifecycle logging (window open/close/update)
   - Removed [TCC-ASYNC] verbose posix_spawn logging
   - Kept functional code, removed visibility of internal operations

   TCC Check Command (meshconsole/main.c): 44 logs removed
   - Removed all [TCC-CHECK] verbose logging from -check-tcc handler
   - Condensed handler from ~160 lines to ~95 lines
   - Silent operation: checks permissions, shows UI if needed, exits
   - Preserved all logic (bundle detection, DB access, permission checks)

   Agent Core (meshcore/agentcore.c): 16 logs removed
   - Removed [TCC-SPAWN] logging from KVM and startup TCC spawning
   - Removed DEBUG: logging from importSettings and .msh file detection
   - Silent spawn decision tree (checks disableTccCheck flag, spawns UI)
   - Kept all functional code paths intact

3. Updated documentation to reflect new logging behavior:
   - mac_logging_utils.md: Updated for severity-based routing
   - macos-tcc-permissions.md: Removed log file references
   - macos-install-assistant.md: Updated logging examples
   - meshagent-commands.md: Updated -check-tcc description

Debug log prefixes removed:
  [TCC-UI]     - TCC permissions UI window lifecycle
  [TCC-CHECK]  - TCC permission check process details
  [TCC-SPAWN]  - TCC check spawning from daemon
  [TCC-ASYNC]  - Async TCC window spawning via posix_spawn
  DEBUG:       - General debug statements

Impact:
  - 13 files changed: 206 insertions, 388 deletions (-182 lines)
  - Production daemon logs now clean and focused on errors/warnings
  - Debugging still possible via Console.app (stderr/stdout streams)
  - No functional changes - only removed logging visibility

Rationale:
  - Debug logs were cluttering daemon logs in production deployments
  - File logging to /tmp/ was unnecessary for production use
  - Severity-based routing provides better log organization
  - Reduced noise makes actual errors/warnings more visible

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@PeetMcK PeetMcK force-pushed the _100-PR-macOS-MeshAgent-Rebuild branch from 4590fab to b00dd69 Compare December 15, 2025 20:23
Updated TCC permissions window Accessibility "Open Settings" button to
spawn `meshagent -request-accessibility` as the console user via su.

Changes:
- TCCButtonHandler: Added exePath and consoleUID properties
- openAccessibilitySettings: Spawns via `su -l <user> -c "meshagent -request-accessibility"`
- main.c: Added console user UID detection helper function
- main.c: Updated all show_tcc_permissions_window() calls to pass exe_path and uid
- main.c: Added handlers for -request-accessibility, -request-screenrecording, -request-fulldiskaccess flags
- main.c: Updated -help documentation with warning about terminal usage

Implementation notes:
- Uses su instead of launchctl asuser to ensure process runs with actual user credentials
- getpwuid() converts UID to username for su command
- Help text warns that running -request-* from terminal requests permissions for terminal app

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@kirill-567
Copy link

Hi @PeetMcK,
Thank you for your job!
I have the issue with Screen Sharing permissions when I install service using app bundle.

Write me please to kirill@flamingo.cx
We're open for the sponsorship.

cc @si458

@PeetMcK
Copy link
Author

PeetMcK commented Dec 22, 2025

@kirill-567 I'd need more information here.

Basic troublshooting information:

  • Please clearly describe the issue with Screen Sharing permissions.
  • Please describe the environment your testing.
  • Is it a fresh macOS install?
  • What version of macOS?
  • If not fresh, have you reset your screen recording tcc?
  • What troubeshooting steps have you performed?

Signing information:

What is the output of
codesign -dr - /path/to/MeshAgent.app

% codesign -dr - ./build/output/osx-universal-64-app/MeshAgent.app
Executable=/Users/peet/GitHub/MeshAgent/build/output/osx-universal-64-app/MeshAgent.app/Contents/MacOS/meshagent
# designated => cdhash H"593be24dfcd02ef8eb73e1632d223f4bfb4814f1" or cdhash H"ae4d87bdd8441dadb6e3811a3df302166d6f2531"

codesign -dv /path/to/MeshAgent.app

% codesign -dv ./build/output/osx-universal-64-app/MeshAgent.app
Executable=/Users/peet/GitHub/MeshAgent/build/output/osx-universal-64-app/MeshAgent.app/Contents/MacOS/meshagent
Identifier=meshagent
Format=app bundle with Mach-O universal (x86_64 arm64)
CodeDirectory v=20400 size=8994 flags=0x2(adhoc) hashes=275+3 location=embedded
Signature=adhoc
Info.plist entries=14
TeamIdentifier=not set
Sealed Resources version=2 rules=13 files=1
Internal requirements count=0 size=12

@kirill-567
Copy link

kirill-567 commented Dec 22, 2025

@PeetMcK

Issue description (Screen Sharing / Screen Recording permissions):
We are experiencing a black screen on the remote desktop when connecting via MeshCentral. The issue is directly related to macOS Screen Recording permissions and how they are handled across installations, reinstalls, and system restarts.

Testing environment:

  • Device: macOS system
  • macOS version: macOS Sequoia 15.6
  • MeshAgent executable: unsigned
  • Tested both with and without manually removing all permissions before testing

Is this a fresh macOS install?

  • No, this is not a fresh macOS installation.
    macOS version: macOS Sequoia Version 15.6

Have you reset Screen Recording (TCC) permissions?
Yes. We tested both scenarios:

  • With existing Screen Recording permissions removed manually before installation
  • Without removing existing permissions

Troubleshooting steps performed:

  1. Installation using -install flag
  • If no Screen Recording permission existed from a previous installation, the first remote desktop session works correctly.
  • If Screen Recording permission already existed from a previous installation, the remote desktop shows a black screen.
  1. Default mode (launching MeshAgent without arguments)
  • Even after manually removing the previous Screen Recording permission and granting it again directly to the executable, the remote desktop still shows a black screen.
  1. Launching from .app bundle
  • We were unable to fully test remote desktop functionality.
  • After self-update, the executable loses the ability to read the .msh file located next to it, which prevents proper connection to MeshCentral.
  1. Most successful scenario (-install flag)
  • When installed with -install and no prior Screen Recording permission exists, macOS prompts for permission on first remote connection.
  • After granting permission, remote desktop works as expected.
  • After a system reboot, the remote desktop again results in a black screen.

Signing:

  • We suspect behavior may differ when using a properly signed executable, but this has not yet been tested.

- Fix findInstallation() to use plist-based detection only, removing
  the .msh file detection that incorrectly treated distribution bundle
  locations as existing installations
- Add automatic polyfill regeneration to Makefile macos target so JS
  module changes are always compiled into the binary
- Add debug logging to findInstallation() for troubleshooting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix BUILD_TIMESTAMP variable name in recursive make calls (was using
  undefined BUILD_TIME)
- Fix version verification to combine CFBundleShortVersionString (date)
  and CFBundleVersion (time) from plist
- Skip module sync and polyfill regeneration on recursive calls using
  BUILD_TIMESTAMP check
- Move full polyfills regeneration before success message so build ends
  with paths output
- Default SKIP_POLYFILLS=yes in macos-build_sign_notarize.sh since
  Makefile now handles polyfill regeneration automatically
- Add modules/embedded.info to .gitignore

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@PeetMcK
Copy link
Author

PeetMcK commented Dec 23, 2025

Issues with a black screen are not relateded to Screen Recording TCC. Black screen issues with meshagent/MeshAgent.app are cased by the -kvm1/LaunchAgent on the device. Screen Recording TCC issues virtually always present as seeing a desktop with a menubar, but no windows (this is for any macOS screen recording software).

While it might not be neccessary given the extended information, it may still prove useful to provide the requested signing information

What is the output of
codesign -dr - /path/to/MeshAgent.app
codesign -dv /path/to/MeshAgent.app

For troubleshooting the black screen lets start from a known state. First make sure to build from the most current commit ... 70ddb69 ... then do the following:

  • Place your MeshAgent.app somehwere like ~/Downloads
  • sudo ~/Downloads/MeshAgent.app/Conents/MacOS/meshagent -fulluninstall --installPath={YOUR_installPath} --log=3
  • {YOUR_installPath} should not exist
  • /Library/LaunchAgents/meshagent-agent.plist should not exist
  • /Library/LaunchDaemons/meshagent.plist should not exist
  • launchctl list | grep meshagent should not have output
  • sudo launchctl list | grep meshagent should not have output
  • pgrep meshagent should not have output

Now lets reinstall:

  • Place your MeshAgent.app somehwere like ~/Downloads
  • ensure you have a valide meshagent.msh in the same directory
  • The next steps assume default installation directory /usr/local/mesh_services/meshagent/
  • sudo ~/Downloads/MeshAgent.app/Conents/MacOS/meshagent -fullinstall --copy-msh=1 --meshAgentLogging=1 --log=3
  • TCC check UI - "MeshAgent - Security & Privacy Settings" - should run here if TCC permissions are not satisfied.
  • /Library/LaunchDaemons/meshagent.plist should exist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Disabled</key>
	<false/>
	<key>KeepAlive</key>
	<true/>
	<key>Label</key>
	<string>meshagent</string>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/local/mesh_services/meshagent/MeshAgent.app/Contents/MacOS/meshagent</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
	<key>StandardErrorPath</key>
	<string>/tmp/meshagent-daemon.log</string>
	<key>StandardOutPath</key>
	<string>/tmp/meshagent-daemon.log</string>
	<key>WorkingDirectory</key>
	<string>/usr/local/mesh_services/meshagent</string>
	<key>meshagent_ver</key>
	<string>25.12.22</string>
</dict>
</plist>
  • /Library/LaunchAgents/meshagent-agent.plist should exist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Disabled</key>
	<false/>
	<key>KeepAlive</key>
	<false/>
	<key>Label</key>
	<string>meshagent-agent</string>
	<key>LimitLoadToSessionType</key>
	<array>
		<string>Aqua</string>
		<string>LoginWindow</string>
	</array>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/local/mesh_services/meshagent/MeshAgent.app/Contents/MacOS/meshagent</string>
		<string>-kvm1</string>
		<string>--serviceId=meshagent</string>
	</array>
	<key>QueueDirectories</key>
	<array>
		<string>/var/run/meshagent</string>
	</array>
	<key>StandardErrorPath</key>
	<string>/tmp/meshagent-agent.log</string>
	<key>StandardOutPath</key>
	<string>/tmp/meshagent-agent.log</string>
	<key>Umask</key>
	<integer>0</integer>
	<key>WorkingDirectory</key>
	<string>/usr/local/mesh_services/meshagent/</string>
	<key>meshagent_ver</key>
	<string>25.12.22</string>
</dict>
</plist>
  • sudo launchctl list | grep meshagent -> [PID] 0 meshagent
  • launchctl list | grep meshagent -> - 0 meshagent-agent
  • pgrep meshagent -> [SAME_PID_AS_ABOVE] (if you have more than one PID, is TCC check UI still running?)

At this point you should be set.

If you're still getting a black screen, refer to your /tmp/meshagent* logs and to ./docs/macos-KVM-Architecture.md to continue troubleshooting the process.

PeetMcK and others added 3 commits December 25, 2025 14:22
Updated ensure_running_as_root() to use shell wrapper for launchctl asuser.
This ensures the elevated process runs with root privileges AND in the user's
GUI session, allowing the Installation Assistant window to display properly.

Changes:
- Use /bin/sh -c to execute: launchctl asuser <uid> <path> -show-install-ui
- AuthorizationExecuteWithPrivileges alone launches outside GUI session
- Shell wrapper successfully combines privilege elevation + GUI access

Fixes CMD+double-click Installation UI functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Document post-Nov-27 work including:
- Installation UI launch fix via launchctl asuser
- Version race condition fix
- Polyfill handling improvements
- TCC Accessibility enhancement
- Install location detection improvements
- Debug logging cleanup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changes default install/upgrade behavior from "backup by default" to
"no backup by default" for faster operations, with explicit --backup
flag to enable comprehensive backups when needed.

Changes:
- Default: NO backup (matches Windows/Linux behavior)
- New flag: --backup to enable backup on demand
- Comprehensive: Backs up binary/bundle, .msh, and .db with same timestamp
- Unconditional: Works even during self-upgrades when explicitly requested

C code (meshcore/agentcore.c):
- Added handling for simple flags without values (e.g., --backup)
- Simple flags now cached as paramName=1 and passed to JavaScript
- Fixes issue where only --param=value flags were passed to JS

C code (meshconsole/main.c):
- Removed old --omit-backup and --skip-backup flags
- Added new --backup flag (both simple and value formats)

JavaScript (modules/agent-installer.js):
- Reversed logic: backup only when --backup specified
- Enhanced backupInstallation() to include .msh and .db files
- All backup files use same timestamp for easy restoration
- Updated cleanup code to recognize .msh and .db backup patterns
- Removed --omit-backup parameter normalization

Example usage:
  sudo meshagent -upgrade --backup
  # Creates: meshagent.TIMESTAMP, meshagent.msh.TIMESTAMP, meshagent.db.TIMESTAMP

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

# Default paths
MESHAGENT_BINARY="$REPO_DIR/build/tools/code-utils/macos/meshagent_code-utils"
DEFAULT_DB_PATH="/opt/tacticalmesh/meshagent.db"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would only be for a tactical mesh agent, not native mesh

echo ""
echo "Examples:"
echo " $0"
echo " $0 /opt/tacticalmesh/meshagent.db"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would only be for a tactical mesh agent, not native mesh

echo "Examples:"
echo " $0"
echo " $0 /opt/tacticalmesh/meshagent.db"
echo " $0 /opt/tacticalmesh/"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would only be for a tactical mesh agent, not native mesh

echo " $0"
echo " $0 /opt/tacticalmesh/meshagent.db"
echo " $0 /opt/tacticalmesh/"
echo " $0 /opt/tacticalmesh/meshagent.db dump.txt"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would only be for a tactical mesh agent, not native mesh

- Used for installations from .pkg installer or manual .app deployment

**Mode 2: Standalone Binary**
- Agent runs as bare binary `/opt/tacticalmesh/meshagent`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Referencing Tacticalmesh

| Deployment Mode | Execution Path | Initial Working Dir | After Adjustment |
|-----------------|----------------|---------------------|------------------|
| Bundle | `/Applications/MeshAgent.app/Contents/MacOS/meshagent` | `Contents/MacOS/` | `/Applications/` |
| Standalone | `/opt/tacticalmesh/meshagent` | `/opt/tacticalmesh/` | `/opt/tacticalmesh/` (unchanged) |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tactical references


**Example:**
```c
char* label = mesh_plist_get_label("/Library/LaunchDaemons/meshagent.tactical.plist");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tactical examples

```c
char* label = mesh_plist_get_label("/Library/LaunchDaemons/meshagent.tactical.plist");
if (label) {
printf("Service label: %s\n", label); // "meshagent.tactical"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tactical examples

**Example:**
```c
MeshPlistInfo info;
if (mesh_parse_launchdaemon_plist("/Library/LaunchDaemons/meshagent.tactical.plist", &info)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tactical examples

<plist version="1.0">
<dict>
<key>Label</key>
<string>meshagent.tacticalmesh</string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for native mesh, only Tactical


<key>ProgramArguments</key>
<array>
<string>/opt/tacticalmesh/meshagent</string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for native mesh, only Tactical

└─────────────────────────────────────────────────────────────┘

1. Command-Line Flags (Transient)
└─ --meshServiceName=Tactical --companyName="ACME Corp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Referencing Tactical RMM

|-------------|-------------|---------------------|----------|
| (default) | (none) | `meshagent` | Standard installation |
| (default) | `acme-corp` | `meshagent.acme-corp` | Company-specific, default service |
| `tactical` | (none) | `meshagent.tactical` | Custom service, no company branding |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole file is filled with Tactical References. I think this is just as an optional service documentation reference, but should review

**Read current preference**:
```bash
./build/tools/code-utils/macos/meshagent_code-utils -db-get \
/opt/tacticalmesh/meshagent.db disableTccCheck
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tactical DB references.

**Manually disable UI**:
```bash
./build/tools/code-utils/macos/meshagent_code-utils -db-put \
/opt/tacticalmesh/meshagent.db disableTccCheck "1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tactical DB references.

**Clear preference**:
```bash
./build/tools/code-utils/macos/meshagent_code-utils -db-delete \
/opt/tacticalmesh/meshagent.db disableTccCheck
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tactical DB references.

Copy link
Contributor

@silversword411 silversword411 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've only gotten to the MESHCORE_OVERVIEW.MD so far...and this is high level atm just keyword searching for tact after getting the first jist of changes.

I know you're a tactical user, but this PR has to be mesh specific, and then TRMM will need to customize the extra fixes specific to Tactical in their deployment.

@PeetMcK PeetMcK marked this pull request as draft January 28, 2026 19:54
PeetMcK and others added 2 commits January 29, 2026 16:10
- Add modules/agent-paths.js helper to derive .msh/.db filenames from binary name
- Update meshconsole/main.c TCC check to use executable-derived paths
- Update agent-installer.js to use dynamic filenames (~40 references)
- Update _agentNodeId.js and security-permissions.js to use agent-paths
- Add testing/build-lithium-remote.sh with sign/notarize/staple by default
- Add testing/test-configurable-names.sh for verification

Binary named 'lithium-remote' now uses lithium-remote.msh and lithium-remote.db
instead of hardcoded meshagent.msh/meshagent.db names.

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

Replaces all hardcoded "meshagent" references with dynamic names derived
from the executable, enabling white-label deployments (e.g., AcmeMesh).

ServiceID system:
- Derive ServiceID and config filenames (.msh/.db) from executable name
- Read ServiceID from .msh configuration files
- Add --setServiceID flag to override during install/upgrade
- Resolve serviceID from LaunchDaemon plist Label as fallback
- Reuse existing plist filenames during upgrade to prevent duplicates
- Parameterize plist parser with configurable agent name

Deployment Assistant UI:
- Add uninstall mode (standard + full uninstall) with confirmation dialogs
- Replace SF Symbols with custom-drawn Lucide/Bootstrap vector icons
- Extract shared UI helpers (mac_ui_helpers.h/m) to reduce duplication
- Add shared helpers: checkbox, rounded button, path field, vector icons
- Settings card with 2x2 checkbox grid (updates, TCC, verbose, agent logging)
- Pre-populate .msh and install path fields regardless of initial mode
- Dynamic button text and icon tinting based on selected mode
- Progress window with real-time streaming output and completion status
- .msh file viewer (sorted key-value table view as modal sheet)

TCC Permissions UI:
- Use shared mesh_createFloatingWindow() for window creation
- Replace Bootstrap icon with shared mesh_createVectorIcon() framework
- Replace SF Symbols checkmarks with custom Lucide circle-check-fill icons
- Use shared helpers for buttons and checkboxes

Build system:
- Parameterize with EXENAME and BUNDLE_DISPLAY_NAME make variables
- Rename icon asset to generic AppIcon.icns
- Update all build/sign/notarize scripts for configurable names

Other:
- Fix argument validation to skip JS code after -exec/-b64exec
- Remove companyName/meshServiceName from KVM path resolution
- Remove TCC-DEBUG logging, orphaned format arguments
- Update documentation for ServiceID system and commands
- Remove obsolete test scripts and PR description file

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@PeetMcK
Copy link
Author

PeetMcK commented Jan 30, 2026

I've only gotten to the MESHCORE_OVERVIEW.MD so far...and this is high level atm just keyword searching for tact after getting the first jist of changes.

I know you're a tactical user, but this PR has to be mesh specific, and then TRMM will need to customize the extra fixes specific to Tactical in their deployment.

Thanks for pointing out the non-generic references. I've removed them. If you see anyothers, please feel fee to correct them if the PR is ever merged.

Cheers.Peet

@PeetMcK PeetMcK marked this pull request as ready for review January 30, 2026 21:08
PeetMcK and others added 2 commits February 1, 2026 01:00
…ript output

Universal builds (ARCHID=10005) now sign and notarize all 3 app bundles
(universal, arm-64, x86-64) instead of only the universal one. Notarization
of all bundles is submitted to Apple in parallel to avoid expanding wall-clock
time. After sign/notarize, zip archives are regenerated with properly signed
bundles.

- Add notarize-app-bundles.sh for parallel multi-bundle notarization
- Update makefile universal block to sign all 3 bundles sequentially
  and notarize all 3 in parallel via the new script
- Add zip archive regeneration after sign/notarize for all 3 bundles
- Unify output style across all 5 sign/notarize scripts: consistent
  color scheme (red=error, green=success, yellow=warning, cyan=headers),
  indented detail lines, no unicode emojis or decorative banners

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Build script consolidation:
- Replace 5 sign/notarize scripts with 2 unified multi-target scripts
  (macos-sign.sh and macos-notarize.sh) that auto-detect .app bundles
  vs bare binaries, with parallel notarization for multiple targets
- Delete sign-app-bundle.sh, notarize-app-bundle.sh, notarize-app-bundles.sh
- Update makefile to call consolidated scripts

Dead code removal:
- Delete macos-build_sign_notarize.sh (makefile is the build interface)
- Delete MeshAgent_pkg directory and --build-pkg option
- Remove unused -request-fulldiskaccess CLI flag and standalone FDA dialog
- Replace populate-FULL-polyfills.sh with minimal example in code-utils/

Build toolchain cleanup:
- Move generate-build-timestamp.sh and generate-info-plist.sh into macos_build/
- Unify visual output style (colors, formatting) across all macOS scripts
- Rewrite macos_build/README.md around makefile-driven workflows
- Document macOS-specific build switches (SIGN, NOTARIZE, EXENAME,
  BUNDLE_DISPLAY_NAME, BUNDLE_ID, BUNDLE_ICON, SKIPSIGNNOTARY) in
  makefile header with usage examples
- Add ARCHID=10005 (universal) to standard builds list

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants