Releases: ttscoff/howzit
Releases · ttscoff/howzit
v2.1.40
2.1.40
2026-02-04 07:53
NEW
- Added a --test-search flag that exits 0 when a search term matches at least one topic and 1 otherwise, with no normal output, allowing shells and scripts to probe for howzit topics programmatically
IMPROVED
- Build note processing in test-search mode now short-circuits without auto-creating buildnotes and treats the absence of any note file as a clean non-match instead of an error
v2.1.39
2.1.39
2026-01-25 07:39
IMPROVED
- The --stack option is now negatable, allowing --no-stack to disable stacking even when :stack: true is set in the configuration file, giving users command-line control over stack mode behavior
- Howzit.buildnote now always creates a new instance when a specific file is requested, preventing cache-related issues when different files need to be loaded
FIXED
- Template topics now have their template name prefixed to their title (e.g., "github:Update GitHub README"), allowing them to be distinguished from local topics and enabling @include directives to reference them using the template prefix format
- Build note file selection now prioritizes buildnotes.md and howzit.md over other build note files, preventing test files or other build notes from being incorrectly selected when multiple build note files exist in the same directory
- Explicit file arguments to BuildNote.new are now properly handled, ensuring that when a specific file is provided it is used correctly instead of falling back to file discovery logic, and stack mode is disabled when an explicit file is provided
v2.1.38
2.1.38
2026-01-25 07:19
NEW
- Added --stack option to merge build notes from directory hierarchy up to root, with topics from closer directories taking precedence over parent directories
- Metadata from all stacked build note files is now merged, with closer directories overriding parent values but parent directories filling in missing keys
- Commands now execute from the directory where their build note file is located, automatically changing directory before execution and restoring original directory after completion
- Menu display for multiple topic matches now shows abbreviated directory
IMPROVED
- Topic and Task classes now track source_file to enable directory-aware execution and abbreviated path display
- Menu selection now handles both abbreviated and full path formats for backward compatibility when matching selected topics
- Template topics are now explicitly loaded from the main build note (closest file) in stack mode to ensure they are always included
- Source file paths are now always normalized to absolute paths for consistent directory handling
- Task execution directory logic now only changes directory in stack mode and correctly identifies template files to avoid changing directory for template-based tasks
FIXED
- Template topics are now correctly loaded in both normal and stack modes, fixing an issue where templates were not appearing when using --stack option
- Template topic filtering now checks against local topics array instead of instance @topics to prevent templates from being incorrectly filtered out when @topics already contains topics from parent directories
- Build note file selection now prioritizes buildnotes.md and howzit.md over other build note files, preventing test files or other build notes from being incorrectly selected when multiple build note files exist in the same directory
- Explicit file arguments to BuildNote.new are now properly handled, ensuring that when a specific file is provided it is used correctly instead of falling back to file discovery logic
- Template topics now have their template name prefixed to their title (e.g., "github:Update GitHub README"), allowing them to be distinguished from local topics and enabling @include directives to reference them using the template prefix format
v2.1.35
2.1.35
2026-01-14 04:37
CHANGED
- Variables are no longer rendered when displaying topics, showing the raw ${variable} syntax so users can see where variable substitution will occur
NEW
- Topic headers now display accepted variables with their defaults, e.g., "Deploy (increment:1, target:prod)"
- Variable placeholders (${VAR} and ${VAR:default}) are syntax highlighted in topic display with blue delimiters, bright white variable names, and yellow default values
v2.1.34
v2.1.33
2.1.33
2026-01-06 08:08
IMPROVED
- Variables set via set_var in run blocks are now properly substituted in all task types: fenced code blocks, @run directive actions, @copy directive actions, and @after block content, enabling dynamic script execution and messaging based on variables set in earlier tasks
- Directive#to_task now merges parent named_args with existing named_arguments instead of overwriting, preserving variables set by scripts via set_var helper functions across sequential task execution
FIXED
- Fix variables set via set_var in run blocks not being substituted in subsequent fenced code block (```run) actions by moving variable substitution to execution time instead of task creation time
- Fix @after blocks only displaying first two lines by wrapping each line individually to preserve multiline structure including empty lines and numbered lists
- Fix @after blocks not displaying when no tasks are executed in sequential processing mode by ensuring they display regardless of task execution results
v2.1.32
2.1.32
2026-01-06 05:22
IMPROVED
- Completion output for howzit -L and howzit -T now shows topic titles without parenthetical variable names, making completion lists cleaner and easier to read while still preserving variable information in verbose output (howzit -R).
v2.1.31
2.1.31
2026-01-06 04:57
CHANGED
- Updated Howzit to use XDG_CONFIG_HOME/howzit (or ~/.config/howzit if XDG_CONFIG_HOME is not set) for all configuration files, templates, themes, and script support files instead of ~/.local/share/howzit.
NEW
- Added automatic migration prompt that detects existing ~/.local/share/howzit directory and offers to migrate all files to the new config location, merging contents and overwriting existing files in the new location while preserving files that only exist in the new location.
- Added --migrate flag to explicitly trigger migration of legacy ~/.local/share/howzit directory to the new config location.
IMPROVED
- Migration prompt now appears during config initialization to catch legacy directories before creating new config files, preventing confusion about file locations.
FIXED
- Fixed ArgumentError when topic titles were longer than terminal width by ensuring horizontal rule width calculation never goes negative, clamping to zero when title exceeds available space.
v2.1.30
2.1.30
2026-01-06 03:55
CHANGED
- Updated rubocop from version 0.93.1 to 1.82.1 for Ruby 3.4.4 compatibility
- Updated .rubocop.yml to use plugins syntax instead of require for rubocop extensions
- Updated .rubocop.yml to inherit from .rubocop_todo.yml and removed Max settings that were overriding todo file limits
- Added Security/YAMLLoad exception to .rubocop.yml to allow YAML.load usage (intentionally not using safe_load)
- Added Layout/LineLength exceptions for files with intentionally long lines (bin/howzit, task.rb, util.rb, stringutils.rb, buildnote.rb)
- Run blocks now execute scripts using appropriate interpreter commands instead of always using /bin/sh
- Moved @log_level and @set_var directive processing before task check in sequential execution to ensure they are processed correctly.
NEW
- Scripts can now communicate back to Howzit by writing to a communication file specified in HOWZIT_COMM_FILE environment variable, allowing scripts to send log messages (LOG:level:message) and set variables (VAR:KEY=value) that are available for subsequent tasks and conditional logic
- Added ScriptComm module to handle bidirectional communication between scripts and Howzit
- Added @if and @unless conditional blocks that allow content and tasks to be conditionally included or excluded based on evaluated conditions, with support for nested blocks
- Conditional blocks support string comparisons (==, =~ /regex/, *= contains, ^= starts with, $= ends with) and numeric comparisons (==, !=, >, >=, <, <=)
- Conditions can test against metadata keys, environment variables, positional arguments ($1, $2, etc.), named arguments, and script-set variables
- Added special condition checks: git dirty/clean, file exists , dir exists , topic exists , and cwd/working directory
- Conditions support negation with 'not' or '!' prefix
- Added @elsif directive for alternative conditions in @if/@unless blocks, allowing multiple conditional branches
- Added @else directive for fallback branches in conditional blocks when all previous conditions are false
- Conditional blocks now support chaining multiple @elsif statements between @if/@unless and @else
- @elsif and @else work correctly with nested conditional blocks
- Added **= fuzzy match operator for string comparisons that matches if search string characters appear in order within the target string (e.g., "fluffy" **= "ffy" matches)
- Added file contents condition that reads file contents and performs string comparisons using any comparison operator (e.g., file contents VERSION.txt ^= 0.)
- File contents condition supports file paths as variables from metadata, named arguments, or environment variables
- ScriptSupport module provides helper functions (log_info, log_warn, log_error, log_debug, set_var) for bash, zsh, fish, ruby, python, perl, and node scripts in run blocks
- Automatic interpreter detection from hashbang lines in scripts
- Helper script injection into run blocks based on detected interpreter
- Support directory installation at ~/.local/share/howzit/support with language-specific helper scripts
- Add sequential conditional evaluation: @if/@unless blocks are now evaluated after each task runs, allowing variables set by scripts to affect subsequent conditional blocks in the same topic
- Add @log_level(LEVEL) directive to set log level for subsequent tasks in a topic
- Add log_level parameter to @run directives (e.g., @run(script.sh, log_level=debug))
- Add HOWZIT_LOG_LEVEL environment variable support for global log level configuration
- Add emoji and color indicators for log messages (debug, info, warn, error)
- Add comprehensive test coverage for sequential conditional evaluation including @if/@unless/@elsif/@else blocks with variables from run blocks
- Add comprehensive test coverage for log level configuration including @log_level directive, log_level parameter in @run directives, and HOWZIT_LOG_LEVEL environment variable
- Added @set_var directive to set variables in build notes. Takes two comma-separated arguments: variable name (alphanumeric, dashes, underscores only) and value. Variables are available as ${VAR} in subsequent @run directives, run blocks, and @if/@else conditional blocks.
- Added command substitution support to @set_var directive. Values can use backticks (
command) or $() syntax ($(command)) to execute commands and use their output as the variable value. Commands can reference other variables using ${VAR} syntax. - Added @set_var directive to set variables directly in build notes, making them available as ${VAR} in subsequent @run directives, run blocks, and @if/@else conditional blocks.
- Added command substitution support to @set_var so values can come from backtick commands (
command) or $() syntax ($(command)), with command output (whitespace stripped) used as the variable value and ${VAR} substitutions applied inside the command.
IMPROVED
- Auto-corrected rubocop style offenses including string literals, redundant self, parentheses, and other correctable issues
- Fixed Lint/Void issue in buildnote.rb by simplifying conditional logic
- Cwd and working directory can now be used with string comparison operators (==, =~, *=, ^=, $=) to check the current directory path
- Conditions now support ${var} syntax in addition to var for consistency with variable substitution syntax
- String comparison operators (*=, ^=, $=) now treat unquoted strings that aren't found as variables as literal strings, allowing simpler syntax like template *= gem instead of template *= "gem"
- Log messages from scripts now display with visual indicators: debug messages show with magnifying glass emoji and dark color, info with info emoji and cyan, warnings with warning emoji and yellow, errors with X emoji and red
- Log level filtering now properly applies to script-to-howzit communication messages, showing only messages at or above the configured level
- Conditional blocks (@if/@unless/@elsif/@else) now re-evaluate after each task execution, enabling dynamic conditional flow based on variables set by preceding tasks
- Improve task directive parsing by refactoring to use unless/next pattern for better code organization and fixing @log_level directive handling
- Improve Directive#to_task to properly handle title rendering with variable substitution, argument parsing for include tasks, and action escaping for copy tasks
- Processed @set_var directives before task creation in topics without conditionals so variable substitution in @run actions works as expected even in the non-sequential execution path.
FIXED
- Resolved NameError for 'white' color method by generating escape codes directly from configured_colors hash instead of calling dynamically generated methods
- Fixed infinite recursion in ConsoleLogger by using $stderr.puts directly instead of calling warn method recursively
- Color template method now properly respects coloring? setting and returns empty strings when coloring is disabled
- Resolved test failures caused by Howzit.buildnote caching stale instances by resetting @buildnote in spec_helper before each test
- Fixed bug where @EnD statements failed to close conditional blocks when conditions evaluated to false, preventing subsequent conditional blocks from working correctly
- Fixed issue where named arguments from topic titles were not available when evaluating conditions in conditional blocks
- Suppressed EPIPE errors that occur when writing to stdout/stderr after pipes are closed, preventing error messages from appearing in terminal output
- Fix @elsif and @else conditional blocks not executing tasks when parent @if condition is false by correctly tracking branch indices and skipping parent @if index in conditional path evaluation
- Fix clipboard copy test failing due to cached console logger instance not updating when log_level option changes
- Fixed variable persistence issue in sequential execution where Howzit.named_arguments was being reset on each iteration, causing @set_var variables to be lost.
- Ensured variables set by @set_var and helper scripts persist correctly across sequential conditional evaluation by merging topic named arguments into Howzit.named_arguments instead of overwriting them.
v2.1.29
2.1.29
2026-01-01 06:56
CHANGED
- Updated rubocop from version 0.93.1 to 1.82.1 for Ruby 3.4.4 compatibility
- Updated .rubocop.yml to use plugins syntax instead of require for rubocop extensions
- Updated .rubocop.yml to inherit from .rubocop_todo.yml and removed Max settings that were overriding todo file limits
- Added Security/YAMLLoad exception to .rubocop.yml to allow YAML.load usage (intentionally not using safe_load)
- Added Layout/LineLength exceptions for files with intentionally long lines (bin/howzit, task.rb, util.rb, stringutils.rb, buildnote.rb)
NEW
- Scripts can now communicate back to Howzit by writing to a communication file specified in HOWZIT_COMM_FILE environment variable, allowing scripts to send log messages (LOG:level:message) and set variables (VAR:KEY=value) that are available for subsequent tasks and conditional logic
- Added ScriptComm module to handle bidirectional communication between scripts and Howzit
- Added @if and @unless conditional blocks that allow content and tasks to be conditionally included or excluded based on evaluated conditions, with support for nested blocks
- Conditional blocks support string comparisons (==, =~ /regex/, *= contains, ^= starts with, $= ends with) and numeric comparisons (==, !=, >, >=, <, <=)
- Conditions can test against metadata keys, environment variables, positional arguments ($1, $2, etc.), named arguments, and script-set variables
- Added special condition checks: git dirty/clean, file exists , dir exists , topic exists , and cwd/working directory
- Conditions support negation with 'not' or '!' prefix
- Added @elsif directive for alternative conditions in @if/@unless blocks, allowing multiple conditional branches
- Added @else directive for fallback branches in conditional blocks when all previous conditions are false
- Conditional blocks now support chaining multiple @elsif statements between @if/@unless and @else
- @elsif and @else work correctly with nested conditional blocks
- Added **= fuzzy match operator for string comparisons that matches if search string characters appear in order within the target string (e.g., "fluffy" **= "ffy" matches)
- Added file contents condition that reads file contents and performs string comparisons using any comparison operator (e.g., file contents VERSION.txt ^= 0.)
- File contents condition supports file paths as variables from metadata, named arguments, or environment variables
IMPROVED
- Auto-corrected rubocop style offenses including string literals, redundant self, parentheses, and other correctable issues
- Fixed Lint/Void issue in buildnote.rb by simplifying conditional logic
- Cwd and working directory can now be used with string comparison operators (==, =~, *=, ^=, $=) to check the current directory path
- Conditions now support ${var} syntax in addition to var for consistency with variable substitution syntax
- String comparison operators (*=, ^=, $=) now treat unquoted strings that aren't found as variables as literal strings, allowing simpler syntax like template *= gem instead of template *= "gem"
FIXED
- Resolved NameError for 'white' color method by generating escape codes directly from configured_colors hash instead of calling dynamically generated methods
- Fixed infinite recursion in ConsoleLogger by using $stderr.puts directly instead of calling warn method recursively
- Color template method now properly respects coloring? setting and returns empty strings when coloring is disabled
- Resolved test failures caused by Howzit.buildnote caching stale instances by resetting @buildnote in spec_helper before each test
- Fixed bug where @EnD statements failed to close conditional blocks when conditions evaluated to false, preventing subsequent conditional blocks from working correctly
- Fixed issue where named arguments from topic titles were not available when evaluating conditions in conditional blocks
- Suppressed EPIPE errors that occur when writing to stdout/stderr after pipes are closed, preventing error messages from appearing in terminal output