All notable changes to this project will be documented in this file.
The format roughly follows Keep a Changelog and the project aims to follow Semantic Versioning.
- macOS / Bash 3: Installer no longer fails with "declare: -A: invalid option" on systems where Bash is 3.x (e.g. macOS default). Replaced associative array with a portable
case-based color lookup.
- CRITICAL: Installer MOTD color step no longer fails with "Cello: unbound variable" when using
set -u. Resolved by assigning associative array (COLOR_MAP) elements individually instead of compound assignment. install.sh --colorandbootstrap.sh --dir/--refnow validate that a value is provided and exit with a clear error instead of referencing unbound$2.test/ui-demo.shnow correctly sources the shared UI library (lib/ui.sh) instead of a non-existent section ininstall.sh.
- Removed machine-specific PATH entries (Antigravity, Windsurf) from the zshrc template; user-specific paths should go in
~/.franklin.local.zsh. /etc/os-releaseparsing now uses${ID:-}to guard against edge-case distros whereIDmay be unset.- macOS zshrc now sets
LS_COLORS(GNU format) alongsideLSCOLORSso completion coloring works on Darwin.
- BREAKING: Removed NVM lazy loading in favor of traditional eager initialization for reliability in non-interactive shells and agent/CLI tool contexts.
- Node.js and npm now work correctly in non-interactive shells, subprocesses, and when invoked by AI agents or automation tools.
- Commands like
bash -c "npm install"no longer fail due to undefined wrapper functions. - Debian/Ubuntu installation: Fixed incorrect package name
batcat→batin apt-get command. The package is namedbat(executable isbatcatfor conflict avoidance, which the zshrc template already handles via aliases). - CRITICAL: Fixed misleading MOTD services documentation that caused user confusion:
- Corrected variable name:
MOTD_SERVICES→MONITORED_SERVICESthroughout README and CHANGELOG - Updated
.franklin.local.zshtemplate to clearly explain services MUST be in~/.config/franklin/config.env, NOT in the local overrides file - Added explicit instructions:
MONITORED_SERVICES="nginx,postgresql,meshtasticd"(comma-separated) in config.env - Clarified that services only appear when running (
systemctl is-activereturns "active")
- Corrected variable name:
- Removed outdated Debian/NVM PATH warning from installer (issue was fixed in 2.0.1/2.0.2 with NVM PATH fallback logic and eager loading).
This patch prioritizes reliability over the ~200-400ms shell startup time penalty from loading NVM. The lazy loading pattern (introduced in v2.0) was causing failures when:
- Agents spawned non-interactive subshells
- Scripts used absolute paths to node/npm
- Commands were invoked via
bash -cor similar
Users who need sub-100ms startup can re-enable lazy loading via ~/.franklin.local.zsh.
.franklin.local.zshstub now includes commented examples for common options (MOTD flags, update defaults, backup directory, NVM/Node PATH, and custom aliases) so you can customize by uncommenting lines instead of consulting the docs.- Shared Bash UI library (
franklin/src/lib/ui.sh) for consistent Campfire styling across shell scripts. - Comprehensive test suite (
test/test_cli.py) with 20 pytest smoke tests covering CLI commands, OS detection, UI, constants, and MOTD modules.
- Zsh template now respects
FRANKLIN_LOCAL_CONFIGwhen loading local overrides, allowing you to relocate the overrides file. - Installer (
install.sh) refactored to use shared UI library and added--non-interactiveand--colorflags for automation. - Bootstrap script (
bootstrap.sh) streamlined with minimal UI functions (full library loads after installation). - OS family detection now returns
fedorainstead ofrhelfor consistency with install script naming conventions (affects all RHEL-family distros: Fedora, RHEL, CentOS, Rocky, Alma).
- Debian/Linux installs that use NVM no longer drop the active Node version from
PATHwhen nodefaultalias is configured; Franklin now falls back to the only installed NVM Node version when appropriate.
- Installer prints a Debian/NVM note describing how to restore NVM Node and global
npmtools onPATHif needed.
- First-run color prompt (interactive) with numeric selection;
franklin config --colorsupports numbers or hex. - CI smokes for macOS/Ubuntu with stubbed core tools to validate CLI commands in CI.
- GitHub Actions workflow for CLI smokes; installer now enforces core deps (Sheldon, bat) with exit-on-missing.
- Bootstrap invokes
install.shwith bash for broader Linux (dash/Pi) compatibility; Linux package manager detection now prefers available commands (apt/dnf/yum) for wider distro support. - Starship prompt: git branch glyph restored (), Node version shows reliably via broader detection.
- Campfire CLI: color controls honor NO_COLOR/
--no-color;update/update-allgain dry-run, OS package handlers, and stricter exit codes. - README updated: correct bootstrap URL, clearer macOS/Linux wording, simplified release workflow for v2 tags.
- Cleaned up color selection to ignore ANSI/arrow key input; prompts remain keyboard-friendly.
- Addressed POSIX/dash failures (
pipefail) on Raspberry Pi/Bookworm by using bash handoff.
- UV (Python package installer) now installed on all platforms (macOS via Homebrew, Linux via official installer)
- Brewfile-based package management on macOS for declarative dependency installation
- TTY detection for color output - respects
NO_COLORenvironment variable and disables ANSI codes when output is redirected - Signal handling (Ctrl+C) in install/update scripts - properly cleans up temp files and restores terminal state
- Comprehensive cleanup traps in spinner UI - prevents corrupted terminal on interrupts
FRANKLIN_FORCE_COLORSandFRANKLIN_DISABLE_COLORSenvironment variables for color override- Python virtual environment support (
python3-venv) on Debian/Ubuntu - Better error messages when installations are interrupted by user
- Core dependencies now required (not optional) - Antigen, Starship, NVM, and UV must be installed successfully
- macOS: Uses
brew bundlewith Brewfile instead of individual package installs - Debian/Ubuntu: Added bat to core packages (was optional), improved Starship fallback installer
- Fedora/RHEL: Added bat to core packages, improved Starship fallback installer
- Exit codes: Improved consistency - missing files/commands now use exit code 2 (user error) instead of 1
- Stream handling: Status messages in
franklin reloadnow output to stderr instead of stdout - Enhanced documentation in
versions.shwith update instructions and release dates
- Color codes no longer pollute pipes and redirects - fixes CI/CD integration and scriptability
- Terminal state properly restored on Ctrl+C - no more hidden cursor or corrupted display
- Temp files cleaned up on interrupt - prevents orphaned files in
/tmp franklin reloadnow starts a login shell (exec zsh -l), preserving login shell status sologoutcommand works correctlyfranklin reloadzsh not found error now uses exit code 2 instead of 1 (correct for user error)
- Added
INSTALL_WORKFLOW_DESIGN.md- architectural design for v2.0 migration to Sheldon plugin manager - Added
src/Brewfile- declarative macOS dependency specification - Updated
versions.shwith inline update instructions and version comments
This release completes Phase 0 critical fixes identified in architectural review, preparing Franklin for v2.0 development:
- CLI now follows Unix Philosophy (stdout for data, stderr for logs)
- Respects no-color.org standard for accessibility
- Proper signal handling prevents resource leaks
- Exit codes follow standard conventions
- Scriptability improved:
franklin version | grep "1.5"now works correctly
- MOTD banner now uses dual-color design (middle row background uses main background color, creating visual contrast with half-block borders)
- UI section banners (install/update) now use consistent color (middle row background matches half-block character color)
installwrapper function for unified package installation across platforms (automatically uses brew/apt/dnf based on OS)franklin reloadcommand to reload shell configuration (replaces standalonereload()function)update-all.shnow accepts--franklin-onlyto run just the Franklin core update step.franklin updateuses the new flag so it only updates Franklin, whilefranklin update-allretains the full workflow entry point.
- Moved
reloadfunctionality from standalone function tofranklin reloadsubcommand, avoiding namespace conflicts with plugin aliases - MOTD service status indicators now use colored ANSI dots (●) instead of emoji circles for better terminal compatibility
- MOTD service icons now include trailing space for better visual separation from service names
- MOTD memory calculation now uses floating-point arithmetic instead of integer division, fixing "0M" display when RAM usage is less than 1GB
- MOTD services grid now uses correct 1-indexed array access for zsh (was accessing empty cells[0] instead of cells[1])
- MOTD services grid now renders correctly by calculating visible length instead of including ANSI escape codes in length calculations
- MOTD service status icons now render properly (was outputting literal escape sequences instead of colored dots)
- MOTD now displays memory and disk usage in MB when values are less than 1GB (e.g., "512M/3G" instead of "0G/3G")
.zshrcnow unaliasesreloadbefore defining the function, preventing "defining function based on alias" parse errors when Antigen plugins define areloadalias.update-all.shnow updates git-based Franklin installs even when the GitHub API is unreachable, falling back to directgit pullbefore checking release tarballs.- Release status now falls back to the repo
VERSIONfile when the GitHub API is unavailable, eliminating spurious "unable to check latest" warnings. _motd_get_servicesno longer assigns to zsh's read-onlystatusparameter, fixing the "read-only variable: status" warning on Debian-based installs.- Debian updates now revalidate
sudocredentials before wrapping apt commands in the spinner, preventing hidden password prompts and apparent hangs. - Version audit skips git-based Antigen upgrades when local modifications are present, logging a warning instead of failing the entire step.
- Debian installers fall back to the official Starship install script if
snap install starshipfails or snapd is unavailable, ensuring the prompt can be installed non-interactively. - Antigen installs now clone the full upstream repository (respecting
FRANKLIN_ANTIGEN_VERSION), ensuringbin/antigen.zshexists and preventing "command not found: antigen" errors. _motd_render_servicesuses a non-reserved variable name so zsh no longer warns aboutstatuswhen printing services.- Antigen downloads now use the official single-file endpoint (
https://git.io/antigen), avoiding broken references to non-existentbin/scripts. _motd_service_iconno longer declares the reservedstatusvariable, fixing residual "read-only variable: status" warnings on Debian systems.- Existing Antigen installs referencing the deprecated
/bin/antigen.zshshim are automatically backed up and refreshed to the official single-file script, preventing "command not found: antigen" errors while preserving the legacy copy. _motd_service_iconnow lowercases viatr, avoiding the "unrecognized modifier" error seen on older Debian zsh builds._motd_render_servicestruncates long cells using portable arithmetic, eliminating "unrecognized modifier" crashes when drawing the services grid.step_nvmskips deleting active Node versions when pruning old releases, removing spurious "Failed to remove vXX.Y.Z" warnings on Debian hosts.- Color helpers now auto-detect terminal capabilities, falling back to 256-color or basic ANSI palettes when truecolor isn't supported so Debian installers render cleanly.
- Truecolor detection now also checks
tput colors(>= 16777216) so capable Debian terminals get 24-bit badges without needingCOLORTERM=truecolor. - UI color bindings now degrade gracefully: if primary Campfire colors aren't available (basic ANSI mode), badges fall back to secondary/neutral palettes instead of purple/gray blocks.
- Fixed a typo in the version audit so
fzf --versionoutput redirects to/dev/null(not/divnull), eliminating the Debian warning. - Version audit now detects uv installs from
~/.local/bin/uv, so Debian installs see uv as "system" once the official installer runs. - System packages managed by apt/snap are now labeled as "lagging" instead of "update_available", acknowledging that Debian repos often trail upstream releases.
update-all.shno longer complains about a blank option when run with no arguments (including viafranklin update); the CLI loop now uses numeric comparison for argument parsing.
- Introduced the
franklinhelper CLI sofranklin -v,franklin update, andfranklin checkwork from any shell without spelunking through the install directory. update-all.shnow self-updates Franklin (git pull or release tarball) so the core files stay in sync before other maintenance steps run.- Added Python runtime and uv maintenance steps to
update-all.shso Homebrew/apt/dnf installs stay current alongside Node/npm. .zshrcnow sources~/.franklin.local.zsh(orFRANKLIN_LOCAL_CONFIG) so you can keep private aliases outside the repo; the installer creates the stub automatically.- MOTD automatically shows a Docker/services grid when containers are present or
MONITORED_SERVICESdefines custom daemons to monitor.
- Simplified distribution architecture: Franklin now ships as a single universal tarball instead of three OS-specific bundles, reducing build complexity while keeping runtime OS detection. The 18KB size difference is negligible compared to eliminated maintenance overhead.
- Improved project structure: Source files moved to
src/directory for cleaner separation between code, tests, documentation, and project metadata. Follows standard conventions for modern projects. - Completion caching now refreshes once every 24 hours via
FRANKLIN_ZCOMP_CACHE, speeding up shell startup while keeping completions fresh. - Spinner frames now reuse the padded badge formatter so the second column stays aligned with other log lines.
- OS-specific build bundles (
franklin-macos.tar.gz,franklin-debian.tar.gz,franklin-fedora.tar.gz) in favor of singlefranklin.tar.gzcontaining all platform scripts. scripts/render_os_specific.pyand manifest generation logic—runtime detection handles OS differences cleanly.
- Spinner logging now emits ANSI escapes via
%bso Apple Terminal, Hyper, and other 24-bit terminals render animations correctly instead of printing literal\033[...]text.
- Shared
franklin_ui_run_with_spinnerhelper provides Campfire-themed animations, stdout-safe logging, and environment overrides for every Bash CLI.
update-all.sh,install.sh’s version audit, and the release pipeline now consume the centralized spinner helper so long-running steps stay modern without bespoke TTY logic.- CLI style guide documents the spinner API plus
FRANKLIN_FORCE_SPINNER/FRANKLIN_DISABLE_SPINNER/FRANKLIN_UI_SPINNER_VERBOSEfor contributors. - Spinner animation now automatically disables itself when running under CI/dumb terminals/
NO_COLOR, andscripts/release.shopts out by default so captured logs don’t show raw ANSI control codes.
- Captured the Franklin CLI logging vision in
docs/CLI-UX-Improvement-Plan.md, keeping the stream separation, badge catalog, and rollout checklist in one place. - Published a comprehensive UI deep dive plus a CLI style guide so contributors can mirror the Campfire look across every script.
install.sh,update-all.sh, and all build/release tooling now route diagnostics throughlib/ui.sh, respect a common--quietflag, and render consistent badges/sections without polluting stdout.- Release archives now ship the refreshed documentation set (CLI UX plan, UI deep dive, CLI style) so downstream bundles include the latest guidance by default.
- Introduced the Campfire UI palette (Cello/Terracotta/Black Rock + status colors) for installer/update badges, ensuring every non-banner surface shares the same Franklin visual language.
- Franklin signature palettes (Ember/Ash) now power the MOTD banner and installer color picker (use
ember:clay,ash:cello, or any#hex).
.zshrcreintroduces OS-specific sections (keybindings,lsaliases) so Debian/Fedora bundles no longer inherit macOS defaults.- Section banners in
install.shandupdate-all.shnow mirror the Campfire MOTD style exactly: top/bottom glyphs render without background color, and the middle fill uses the lighter Cello shade with base text color for improved contrast. update-all.shandinstall.shnow consume the shared Campfire UI helper (lib/ui.sh) so badges, section dividers, and colors match the MOTD banner everywhere.scripts/build_release.shbundles the new UI helper, skips stray files (e.g.,CHANGELOG.md), and continues to generate per-OS manifests from a clean staging tree.- Darkened the Franklin palette via HSL tweaks so prompts and dashboards have better contrast.
- Rebuilt the macOS, Debian, Fedora, and unified release bundles plus manifests to capture the latest assets.
- MOTD banner now uses truecolor sequences when the terminal supports them, falls back to tuned 256-color values otherwise, and expands to the detected terminal width (capped at 80 columns) so headers stay flush edge-to-edge.
update-all.shand the MOTD now display a 🐢 Franklin release status (current vs. latest) for quick diagnostics.- MOTD banner regained its Campfire frame and now adds a dedicated "Disk | Memory | Franklin" status row beneath the hostname, with the columns aligned left/center/right as requested.
- Disk usage now derives from the filesystem that backs
$HOME(configurable viaMOTD_DISK_PATH) so the numbers match Finder/Disk Utility instead of the tiny system volume slice. - MOTD version badge falls back to
git describewhen no VERSION file/script exists, so unreleased/dev builds still show a build identifier. - Status row now uses Nerd Font icons (
disk,memory, turtle for Franklin) and assumes a Nerd Font–patched terminal; document this requirement in README.
- MOTD color picker accepts shorthand/custom hex values (
eee,abc,123456) with or without a leading#, both when using--motd-colorand during the interactive installer prompt. - Spinner logging in
update-allis now TTY-aware, preventing log flooding when stdout is captured. - MOTD color prompts now restore
$PATHcorrectly and stop clobbering Franklin palette environment variables. - PATH cleanup during installation removes duplicates without stripping required segments.
lsaliases avoid recursive definitions when Antigen reloads them.- MOTD helper tests can set
FRANKLIN_TEST_MODE=1to strip ANSI sequences from bar charts, keeping assertions stable in CI. - Disk usage readings in the MOTD are now derived from raw
df -kvalues, so the used/total numbers match macOS Finder exactly (no more 11 GB when you really have 395 GB on disk).
.zshrcreintroduces OS-specific sections (keybindings,lsaliases) so Debian/Fedora bundles no longer inherit macOS defaults.
- MOTD color picker accepts shorthand/custom hex values (
eee,abc,123456) with or without a leading#, both when using--motd-colorand during the interactive installer prompt.
- Section banners in
install.shandupdate-all.shnow mirror the Campfire MOTD style exactly: top/bottom glyphs render without background color, and the middle fill uses the lighter Cello shade with base text color for improved contrast.
- New
scripts/release.shautomates stampingVERSION, buildingdist/, committing, tagging, and uploading GitHub releases (with--dry-run/--no-uploadsafety switches).
update-all.shandinstall.shnow consume the shared Campfire UI helper (lib/ui.sh) so badges, section dividers, and colors match the MOTD banner everywhere.scripts/build_release.shbundles the new UI helper, skips stray files (e.g.,CHANGELOG.md), and continues to generate per-OS manifests from a clean staging tree.
scripts/check_versions.shno longer aborts whennpmisn't on the PATH, soupdate-allcompletes cleanly even if NPM hasn't been initialized yet.
- Show Franklin palette swatches in the installer to make color selection easier.
- Truecolor detection helper (
franklin_use_truecolor) plusFRANKLIN_FORCE_TRUECOLOR/FRANKLIN_DISABLE_TRUECOLORoverrides so shells can force or skip 24-bit colors consistently. - Automatic environment flagging (e.g.,
FRANKLIN_FORCE_TRUECOLOR=1) ensures the MOTD picks up truecolor palettes just like the installer preview. MOTD_DEBUG_COLORS=1prints the resolved banner hex, ANSI sequences, and text color so you can see exactly what the MOTD is emitting.- Added VERSION file generation and helper scripts (
scripts/write_version_file.sh,scripts/current_franklin_version.sh) so releases embed and expose the Franklin build identifier. - Interactive MOTD color picker now uses a numbered menu (plus custom hex option) so invalid text entries can't accidentally reset the banner color.
- Darkened the Franklin palette via HSL tweaks so prompts and dashboards have better contrast.
- Rebuilt the macOS, Debian, Fedora, and unified release bundles plus manifests to capture the latest assets.
- MOTD banner now uses truecolor sequences when the terminal supports them, falls back to tuned 256-color values otherwise, and expands to the detected terminal width (capped at 80 columns) so headers stay flush edge-to-edge.
update-all.shand the MOTD now display a 🐢 Franklin release status (current vs. latest) for quick diagnostics.- MOTD banner regained its Campfire frame and now adds a dedicated "Disk | Memory | Franklin" status row beneath the hostname, with the columns aligned left/center/right as requested.
- Disk usage now derives from the filesystem that backs
$HOME(configurable viaMOTD_DISK_PATH) so the numbers match Finder/Disk Utility instead of the tiny system volume slice. - MOTD version badge falls back to
git describewhen no VERSION file/script exists, so unreleased/dev builds still show a build identifier. - Status row now uses Nerd Font icons (
disk,memory, turtle for Franklin) and assumes a Nerd Font–patched terminal; document this requirement in README.
- Spinner logging in
update-allis now TTY-aware, preventing log flooding when stdout is captured. - MOTD color prompts now restore
$PATHcorrectly and stop clobbering Franklin palette environment variables. - PATH cleanup during installation removes duplicates without stripping required segments.
lsaliases avoid recursive definitions when Antigen reloads them.- MOTD helper tests can set
FRANKLIN_TEST_MODE=1to strip ANSI sequences from bar charts, keeping assertions stable in CI. - Disk usage readings in the MOTD are now derived from raw
df -kvalues, so the used/total numbers match macOS Finder exactly (no more 11 GB when you really have 395 GB on disk).
- Initial public release of Franklin with macOS, Debian, and Fedora support, bundling Antigen, Starship, NVM, and a signature Campfire MOTD dashboard.