Skip to content

Total rebuild#41

Draft
jrock2004 wants to merge 19 commits intomainfrom
total-rebuild
Draft

Total rebuild#41
jrock2004 wants to merge 19 commits intomainfrom
total-rebuild

Conversation

@jrock2004
Copy link
Copy Markdown
Owner

No description provided.

jrock2004 and others added 19 commits February 8, 2026 13:34
…nt (Phases 1-3) (#29)

* fix: resolve 7 critical bugs in install.sh (Phase 1)

- Fix hardcoded username path to use $HOME variable
- Replace undefined info() function calls with echo
- Update Lua Language Server repo from sumneko to LuaLS
- Make setupTmux idempotent with directory existence check
- Make setupLua idempotent with directory existence check
- Make setupRust non-interactive with -y flag and cargo env sourcing
- Add zap plugin manager installation to setupShell

These changes make the installation script more portable, idempotent,
and automated for unattended installations.

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

* feat: add comprehensive reliability improvements (Phase 2)

- Add error handling with set -euo pipefail and error traps
- Implement logging system with timestamps (log, log_error, log_success, log_warning)
- Add retry logic with exponential backoff for network operations
- Add progress tracking with step counter (Step X/Y)
- Make all setup functions idempotent with directory checks
- Add backup functionality for existing dotfiles with restore on error
- Add comprehensive CLI flags support:
  * --help: Show usage information
  * --version: Show version
  * --dry-run: Preview actions without executing
  * --non-interactive: Use defaults for CI/automation
  * --force: Override idempotency checks
  * --skip <components>: Exclude specific components
  * --only <components>: Install only specific components
  * --list-components: Show all available components

These improvements make the installation script production-ready with
proper error handling, logging, user control, and safety features.

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

* fix: resolve dry-run mode and array handling issues

- Fix unbound variable errors with array parameters using ${arr[@]:-0}
- Improve dry-run mode handling for piped commands
- Add proper dry-run support for Homebrew, VS Code, and fonts installation
- Ensure --skip and --only flags work correctly with empty arrays

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

* feat: implement cross-platform package management system (Phase 3 - Part 1)

- Create packages/ directory structure with platform-specific organization
- Add common.txt (31 packages): cross-platform CLI tools
- Add optional.txt (16 packages): nice-to-have utilities
- Add macOS package files:
  * core.txt (3 packages): macOS-specific CLI tools
  * gui-apps.txt (13 packages): GUI applications
  * fonts.txt (14 packages): programming fonts and Nerd Fonts
  * macos-only.txt (5 packages): window managers, status bars
  * taps.txt: Homebrew custom repositories
- Add Linux/WSL placeholder files for future cross-platform support
- Create package name mapping system:
  * common-to-macos.map: Homebrew package names
  * common-to-ubuntu.map: Ubuntu/Debian (apt) package names
  * common-to-arch.map: Arch Linux (pacman) package names
  * common-to-fedora.map: Fedora/RHEL (dnf) package names
- Add validate-packages.sh script to verify package system integrity
- Add comprehensive README.md documentation for package system

Total: 82 packages organized across 6 categories
This provides a foundation for cross-platform dotfiles installation.

Note: Package manager abstraction layer and Brewfile migration will
follow in Part 2 to integrate this system with install.sh.

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

* feat: integrate package management system with installer (Phase 3 - Part 2)

- Add package manager abstraction layer to install.sh:
  * detect_package_manager(): Auto-detect brew, apt, pacman, dnf, yum
  * get_platform(): Map package manager to platform (macos, ubuntu, arch, fedora)
  * get_mapped_package_name(): Translate package names via mapping files
  * pkg_install_single(): Install single package with proper package manager
  * pkg_install_from_file(): Batch install from package files
  * pkg_install_optional(): Install optional packages (don't fail if missing)
  * pkg_tap(): Install Homebrew taps
  * pkg_install_cask(): Install Homebrew casks

- Update setupForMac() to use new package system:
  * Installs taps from macos/taps.txt
  * Installs common packages from common.txt
  * Installs macOS core packages from macos/core.txt
  * Installs macOS-only packages (yabai, skhd, etc.)
  * Installs optional packages (gracefully skips if unavailable)
  * Installs GUI apps from macos/gui-apps.txt
  * Installs fonts from macos/fonts.txt
  * No longer uses `brew bundle` - uses package files instead

- Add Brewfile migration tools:
  * migrate-brewfile.sh: Analyzes migration status
  * Shows package counts from both systems
  * Provides next steps for migration
  * Add deprecation notice to Brewfile

Migration Status:
- Brewfile: 86 packages (57 formulae, 27 casks, 2 taps)
- New system: 85 packages (cleaned up duplicates)
- install.sh now fully uses packages/ directory

This completes the package management system implementation.
The installer is now ready for cross-platform expansion.

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

* chore: add .install.log to gitignore

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
**UI Library (lib/ui.sh):**
- Color constants for terminal output (RED, GREEN, YELLOW, BLUE, etc.)
- Unicode symbols (✓, ✗, →, ℹ, ⚠, 🚀, 📦, 🔧, ✨)
- Styled output functions:
  * show_header() - Boxed headers with borders
  * show_banner() - ASCII art banner
  * box() - Styled message boxes
  * show_progress() - Progress bar with percentage
  * spinner() - Animated spinner for background tasks
  * print_success/error/warning/info/step() - Colored status messages
  * section/subsection/list_item() - Structured content
  * hr() - Horizontal rules
  * confirm() - Yes/no prompts

**Gum Integration (lib/gum-wrapper.sh):**
- Intelligent fallback system: gum → fzf → bash built-ins
- Wrapper functions with graceful degradation:
  * ui_choose() - Single selection from list
  * ui_multi_select() - Multiple selection from list
  * ui_spin() - Spinner for long-running commands
  * ui_confirm() - Yes/no confirmation dialogs
  * ui_input() - Text input prompts
  * ui_filter() - Search/filter interface
  * ui_styled() - Styled text output
  * ui_pager() - Paginated content display
  * ui_join() - Join items with delimiter
  * select_components() - Interactive component selection

**Enhanced Installation Flow:**
- Load UI libraries at startup
- Show ASCII banner on startup
- Improved OS selection with styled prompts
- Better desktop environment confirmation
- Installation summary before proceeding
- Styled progress and status messages throughout
- Fallback to basic output if UI tools unavailable

**Package Updates:**
- Added gum to packages/optional.txt for enhanced UI

**Benefits:**
- Professional, polished installation experience
- Works beautifully with gum installed
- Gracefully degrades without gum/fzf
- Color-coded status messages
- Clear visual hierarchy
- Better user guidance

**Testing:**
With gum: Beautiful colored, interactive UI
With fzf: Good interactive selection, basic colors
Without both: Functional bash-only interface

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
**OS Detection System (lib/detect.sh):**
- Comprehensive OS detection (macOS, Linux, Windows, WSL)
- Linux distribution detection (Ubuntu, Debian, Fedora, Arch, RHEL)
- Architecture detection (x86_64, arm64, armv7, i386)
- macOS type detection (Intel vs ARM)
- WSL detection (WSL1 vs WSL2)
- System information (CPU cores, memory, Homebrew prefix)
- Export all detection results as environment variables

**Linux Package Files:**
- packages/linux/core.txt - Linux build tools
- packages/linux/gui-apps.txt - Native package manager apps
- packages/linux/gui-apps-flatpak.txt - Flatpak applications
- packages/linux/gui-apps-snap.txt - Snap applications
- Updated package mappings for Linux distributions

**Linux Installation Support:**
- setupForLinux() function with distro-specific package installation
- Support for apt (Ubuntu/Debian), dnf (Fedora/RHEL), pacman (Arch)
- Automatic build tools installation per distro
- Common packages installation using existing abstraction layer
- Full component support (directories, shell, tmux, volta, etc.)
- Respects all CLI flags (--dry-run, --skip, --only, etc.)

**Enhanced OS Selection:**
- Added Linux option to interactive OS selection
- Updated initialQuestions with Linux support
- Updated conditional logic to route to setupForLinux()
- Graceful fallback for unknown/unsupported OS

**Detection Features:**
- detect_os() - Returns macos, linux, windows, unknown
- detect_linux_distro() - Returns ubuntu, debian, fedora, arch, rhel, etc.
- detect_arch() - Returns x86_64, arm64, armv7, i386
- detect_macos_type() - Returns arm or intel
- detect_wsl() - Returns true/false for WSL detection
- get_cpu_cores() - System CPU count
- get_total_memory() - System memory in GB
- show_system_info() - Display all detected information

**Benefits:**
- True cross-platform support (macOS + Linux foundation)
- Intelligent distribution detection
- Distro-specific package handling
- Same professional UI on Linux
- Consistent CLI experience across platforms
- Ready for WSL support (Phase 6)

**Testing:**
- ✅ Syntax validation passed
- ✅ Help output works
- ✅ OS detection works on macOS
- ✅ Ready for Linux testing

**Status:**
Foundation complete - ready for Linux testing and enhancement.
Font installation and GUI app handling can be expanded in future PRs.

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Add comprehensive WSL support with Windows interop, systemd, and
optimization features for WSL1 and WSL2 environments.

Features:
- Enhanced WSL detection (WSL1 vs WSL2)
- lib/wsl.sh with WSL-specific setup functions
- Systemd configuration for WSL2
- Windows interop (clipboard, browser, path helpers)
- Clock drift fixes with automatic sync
- WSLg detection and GUI support
- Performance optimizations (.wslconfig)
- Package filtering (skip incompatible packages)
- WSL-specific package file (38 packages)

Changes:
- lib/detect.sh: Enhanced WSL2 detection (microsoft-standard)
- lib/wsl.sh: New 418-line WSL library
- install.sh: Integrated WSL setup in setupForLinux()
- packages/wsl/wsl-specific.txt: WSL-specific packages

Total: 4 files changed, +488 lines

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated task tracking to reflect completed work from PRs #29-#32:
- Phase 1: Critical bug fixes
- Phase 2: Reliability improvements
- Phase 3: Package management system
- Phase 4: UI/UX improvements with gum
- Phase 5: Linux support foundation
- Phase 6: WSL support

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit implements a complete modular restructuring of the dotfiles
installation system, reducing complexity and improving maintainability.

Key Changes:
- Reduced main install.sh from 1159 lines to 339 lines (71% reduction)
- Created component-based architecture with 9 self-contained components
- Implemented OS-specific orchestration (macOS/Linux/WSL)
- Added reusable utility libraries with proper dependency management
- Added configuration file support (.dotfiles.env)
- Maintained backward compatibility with install-legacy.sh backup

New Directory Structure:
scripts/
├── install.sh (new modular version)
├── lib/ (common utilities)
│   ├── common.sh (logging, helpers, backup, retry, error handling)
│   ├── detect.sh (OS/distro detection)
│   ├── package-manager.sh (package abstraction layer)
│   ├── ui.sh (UI functions)
│   └── gum-wrapper.sh (interactive prompts)
├── os/ (platform-specific orchestration)
│   ├── macos.sh
│   ├── linux.sh
│   └── wsl.sh
└── components/ (self-contained setup modules)
    ├── directories.sh
    ├── shell.sh (zsh + zap + FZF)
    ├── neovim.sh
    ├── tmux.sh
    ├── rust.sh
    ├── volta.sh
    ├── lua.sh
    ├── claude.sh
    └── stow.sh

Features Added:
- Configuration file support via .dotfiles.env
- Array conversion for comma-separated component lists
- Proper library loading order to avoid circular dependencies
- All CLI flags preserved and tested (--help, --version, --list-components,
  --dry-run, --non-interactive, --force, --skip, --only)

Testing:
- ✅ Dry-run mode works end-to-end
- ✅ Component selection (--only) works
- ✅ Component skipping (--skip) works
- ✅ Configuration file loading works
- ✅ All logging functions work correctly

Breaking Changes:
- Old lib/ directory removed (files moved to scripts/lib/)
- install.sh is now a wrapper that delegates to scripts/install.sh
- Old install.sh backed up as install-legacy.sh

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…I) (#33)

* feat: Complete Phase 8 (Additional Features) and Phase 9 (Testing & CI)

Phase 8: Additional Features
- Add uninstall script (scripts/uninstall.sh)
  - Safely removes symlinks via stow -D
  - Optional package removal with --remove-packages
  - Backup before removal
  - Dry-run mode support
- Add update script (scripts/update.sh)
  - Pulls latest changes from git
  - Re-applies symlinks with stow
  - Updates packages (optional with --no-packages)
  - Restarts services (optional with --no-restart)
  - Shows git diff before updating
- Root wrapper scripts (uninstall.sh, update.sh)
- Dry-run mode (implemented in Phase 7)
- Rollback on failure (implemented in Phase 2)

Phase 9: Testing & CI
- Add shellcheck integration
  - Created scripts/test-shellcheck.sh
  - Created .shellcheckrc configuration
  - All 27 scripts pass shellcheck
  - Fixed style issues (SC2126, SC2010, SC2086)
- Add integration tests
  - Created scripts/test-integration.sh
  - Tests symlinks, binaries, shell config, git, tmux, volta, neovim
  - 9 comprehensive test cases
- Add Docker test environments
  - Created test/Dockerfile.ubuntu (Ubuntu 22.04)
  - Created test/Dockerfile.fedora (Fedora 39)
  - Created test/Dockerfile.arch (Arch Linux)
  - Created test/test-docker.sh runner script
- Set up GitHub Actions CI
  - Created .github/workflows/test-install.yml
  - Tests on macOS and Ubuntu
  - Runs shellcheck, integration tests, package validation
  - Dry-run and full installation tests

Progress: 9/10 phases complete (90%)

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

* fix: Resolve CI failures - log file handling and shellcheckrc format

- Fix log file errors in common.sh by gracefully handling missing log directory
- Add fallback to echo if tee fails (fixes CI where DOTFILES may not exist yet)
- Update .shellcheckrc to use comma-separated format for older shellcheck versions
- Compatible with shellcheck 0.9.0 (used in CI) and 0.11.0 (local)

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

* fix: Show shellcheck errors in CI output

- Capture and display shellcheck errors immediately in CI logs
- Helps debug CI failures without needing to check artifacts

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

* fix: Remove -x flag from shellcheck for CI compatibility

- Older shellcheck versions (0.9.0 in CI) have issues with -x flag
- We already disable SC1091 so -x isn't necessary
- Fixes shellcheck failures on macos.sh in CI

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

* chore: Remove test artifacts and add to gitignore

- Remove shellcheck-report.txt (generated file)
- Remove cagent files (IDE artifacts)
- Add to .gitignore to prevent future commits

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

* fix: Remove set -e from shellcheck test to show all results

- set -e was causing script to exit early on first shellcheck failure
- Now all scripts are checked and summary is always shown
- Fixes issue where macos.sh failure caused early exit

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

* fix: Resolve macOS CI failure - DOTFILES path and log directory

Fixes the "Test on macOS" CI failure caused by incorrect DOTFILES path
resolution and missing log file directory.

Changes:
- Export DOTFILES in root install.sh so scripts/install.sh inherits it
- Calculate DOTFILES from script location in scripts/install.sh as fallback
- Auto-create log directory in common.sh to prevent write failures

The issue occurred because:
1. DOTFILES was set to $HOME/.dotfiles which doesn't exist in CI
2. The actual repo is at /Users/runner/work/dotfiles/dotfiles/
3. Log file writes failed when parent directory didn't exist

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

* fix: Auto-detect OS in non-interactive mode instead of hardcoding macOS

Fixes Ubuntu CI test failure where the script was hardcoded to use "mac"
in non-interactive mode, causing Ubuntu tests to run macOS installation.

Changes:
- Use detect_os() function to determine actual OS in non-interactive mode
- Map detected OS (macos/linux) to script OS variable (mac/linux)
- Log the detected OS for transparency

Now the --non-interactive flag will correctly detect and use the actual
operating system instead of always assuming macOS.

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

* fix: Prevent arithmetic exit status failure with set -e

Fixes Ubuntu CI failure caused by arithmetic increment operations
returning exit status 1 when evaluating to 0.

The issue:
- ((count++)) when count=0 increments to 1 but returns 0 (old value)
- In bash, arithmetic result of 0 has exit status 1
- With set -euo pipefail, this triggers immediate script exit

Solution:
- Replace ((count++)) with count=$((count + 1))
- Replace ((failed++)) with failed=$((failed + 1))
- These always return exit status 0 regardless of the result

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

* fix: Resolve shellcheck warning and add non-interactive shell handling

- Replace useless cat with input redirection in VS Code extension install
- Skip chsh in non-interactive mode (CI) to avoid authentication failures

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

* fix: Resolve Ubuntu CI hang with Neovim version check and timeout

- Add proper timeout for Linux (use 'timeout' instead of 'gtimeout')
- Increase timeout to 30s to allow LazyVim bootstrap time
- Auto-upgrade Neovim on Linux if version < 0.11 (LazyVim requirement)
- Add Neovim unstable PPA on Ubuntu for latest version
- Skip test if no timeout command available to prevent hanging

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

* fix: Allow shell test to pass in non-interactive/CI mode

The shell configuration test was failing in CI because chsh requires
authentication and is skipped in non-interactive mode. Updated test to
pass if zsh is available, even if not set as default shell in CI.

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

* fix: Address PR review feedback for shell safety and correctness

Fixes 6 issues identified in PR #33 review:

1. scripts/install.sh - Use safe parameter expansion ${DOTFILES:-} to prevent set -u failures
2. test/test-docker.sh - Fix unreachable error handling by wrapping docker run in if statement
3. scripts/update.sh - Replace $(command -v) with command -v >/dev/null 2>&1 for set -e safety
4. scripts/update.sh - Fix undefined $OS variable references to use $DETECTED_OS
5. scripts/uninstall.sh - Same command -v and $OS fixes as update.sh
6. scripts/components/neovim.sh - Fix version comparison to check patch version (0.11.2 requirement)
7. .github/workflows/test-install.yml - Use continue-on-error instead of || true for better CI visibility

All scripts pass shellcheck validation.

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

* fix: Address additional PR review feedback for shell safety

Fixes 4 more issues identified in second PR #33 review:

1. scripts/lib/common.sh - Use safe ${LOG_FILE:-} expansion in all log functions
   - Prevents set -u failures when LOG_FILE is unset
   - All log functions now check if LOG_FILE is set before attempting to write

2. scripts/update.sh - Remove hardcoded /usr/bin/stow path
   - Use 'stow' from PATH instead of hardcoded /usr/bin/stow
   - Works on systems where stow is installed elsewhere

3. scripts/uninstall.sh - Remove hardcoded /usr/bin/stow path
   - Same fix as update.sh for consistency

4. scripts/os/wsl.sh - Fix glob expansion issue in Windows username detection
   - Add [ -e "$dir" ] check to skip when glob doesn't match any files
   - Prevents setting username to literal "*" when directory is empty

All scripts continue to pass shellcheck validation.

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

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This completes Phase 10 of the dotfiles improvement plan with comprehensive
documentation for the new cross-platform, modular architecture.

**Updated Files:**
- CLAUDE.md: Comprehensive guide with cross-platform architecture, package system,
  component-based installation, OS detection, and troubleshooting (1,000+ lines)
- README.md: Modernized with platform support matrix, features, quick start,
  prerequisites, CLI options, and troubleshooting
- tasks.md: Updated to mark Phase 10 as complete (100% completion)

**New Files:**
- CONTRIBUTING.md: Development guidelines including package management, component
  creation, testing, code style, and PR process
- MIGRATION.md: Step-by-step guide for upgrading from v1.x to v2.0.0 with
  Brewfile migration, breaking changes, and rollback instructions
- docs/MACOS.md: macOS-specific features (yabai, skhd, Homebrew, Powerlevel10k)
- docs/LINUX.md: Linux-specific features (Ubuntu, Fedora, Arch, Starship)
- docs/WSL.md: WSL-specific setup (systemd, Windows interop, performance)

**Key Improvements:**
- Cross-platform documentation for macOS, Linux (Ubuntu/Fedora/Arch), and WSL
- Platform support matrix with tested versions
- Comprehensive troubleshooting sections for each platform
- Migration guide for users upgrading from old system
- Contribution guidelines with code style and testing requirements
- All documentation cross-referenced and internally consistent

All 10 phases now complete (100%). Repository is fully documented and ready
for contributors and future Claude Code sessions.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…url ...)` (#34)

* Initial plan

* Fix: reconnect stdin to /dev/tty when running via bash <(curl ...)

Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>
* Initial plan

* Fix: redirect UI prompts to stderr in bash fallbacks so command substitution captures only the selection

Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>
* Initial plan

* Fix FZF install script not found error in setup_fzf

Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>

* Update fzf setup to use modern shell integration per official docs

Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>
* Initial plan

* Fix: add ninja build tool to package lists for lua-language-server compilation

Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>
…#38)

* Initial plan

* Fix luaformatter install failing when cmake is not found

Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>

* Install cmake automatically if missing before luaformatter install

Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>
* Initial plan

* fix: handle unbound CI variable in stow.sh

Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jrock2004 <655716+jrock2004@users.noreply.github.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.

2 participants