Adds a new `--readpattern <name>` CLI flag that prints the raw contents
of a named pattern's system.md file to stdout. This makes it easy to
inspect what instructions a pattern sends to the model without having
to navigate the filesystem manually.
The implementation respects custom patterns directories: it checks the
user's custom patterns directory first before falling back to the main
patterns directory, consistent with how all other pattern lookups work.
xAI's Responses API accepts web_search and x_search tool types, but
fabric hardcoded OpenAI's web_search_preview tool name in
buildResponseParams, causing GrokAI plus --search to fail with HTTP 422.
This adds two new fields to openai_compatible.ProviderConfig:
- WebSearchToolName: override the default web_search tool name string
- EnableXSearch: append xAI's x_search tool when search is enabled
Both fields are empty/false by default, preserving backwards
compatibility for all existing providers. GrokAI now sets
WebSearchToolName to "web_search" and EnableXSearch to true.
Tests added in openai_test.go cover the new override paths and
confirm the default provider behavior is unchanged.
Verified with live xAI API key: fabric -V GrokAI --search "query"
now returns grounded results with real source URLs.
- Move visual flag descriptions to i18n locale system
- Add visual extraction strings to all 11 locale files
- Replace hardcoded English error messages with i18n lookups
- Register visual flags in `flagDescriptionMap` for help system
- Remove inline `description` tags from visual CLI flag structs
- Localize FFmpeg, Tesseract, and yt-dlp error messages
- Add `youtube_visual_frame_cue` translation key across locales
- Add `context.Context` parameter to `ListModels` interface method
- Add `context.Context` parameter to `SendStream` interface method
- Thread caller context through `Chatter.Send` instead of using `context.Background()`
- Update all vendor implementations to accept context parameter
- Introduce `publicError` type wrapping Codex provider errors
- Normalize Codex error messages to lowercase for consistency
- Add context-aware `sendStreamUpdate` helper in Codex client
- Remove stale `context.Background()` calls from Anthropic and Azure AI Gateway
- Update all vendor test mocks and stubs with new signatures
- Pass HTTP request context from server handler into `chatter.Send`
Adds a lightweight pattern composition feature that lets users chain
multiple patterns together via a simple YAML/JSON workflow file,
piping each step's output into the next step's input.
* New --workflow flag parses YAML/JSON with steps: [{pattern, input?,
variables?, model?, vendor?}]
* Each step reuses the existing Chatter.Send path, so --stream,
--dry-run, -m/-V, -v, --context, --strategy, --language all continue
to work unchanged
* Pre-flight validation: empty steps, missing pattern, repeated
patterns, and unknown pattern names all fail before any LLM call
* Per-step input override: an optional `input:` field lets a step
ignore the carried output; whitespace-only values are treated as no
override
* Progress + errors use a consistent "[step N/TOTAL pattern]" prefix
on stderr so stdout stays pipe-clean
* Single-pattern -p path is untouched – workflow only activates when
--workflow is set
Tests cover loading, validation, input-override chaining, empty-output
handling, and bad/malformed workflow files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
## Bug: Streaming Deadlock in Chatter.Send
When a streaming error occurs, two goroutines can race to write to the
same buffered(1) error channel:
1. The SendStream goroutine returns an error and writes to errChan
2. The stream-update loop receives a StreamTypeError update and also
writes to errChan
Since errChan has a buffer of 1, the second write blocks forever,
causing a goroutine leak and a deadlock — the caller never returns.
### Fix
Introduce `recordFirstStreamError()` which uses a non-blocking
select/default to safely send only the first error, discarding
subsequent ones. This prevents the deadlock while preserving the
original error for the caller.
### Scenario that triggers the deadlock (before this fix):
1. Vendor stream emits a StreamTypeError update (e.g., rate limit)
2. The update loop writes the error to errChan (buffer fills)
3. SendStream also returns an error
4. SendStream goroutine tries to write to errChan → BLOCKS FOREVER
5. Chatter.Send never returns → user sees a hang
## Refactor: Unify Strategy Handling (Server + CLI)
The REST API server (chat.go) was loading strategy prompts inline by
reading JSON files directly with os.ReadFile, bypassing the core
Chatter layer entirely. This caused:
- Strategy prompts were prepended to UserInput instead of the system
message, breaking the prompt architecture
- The StrategyName was not passed to GetChatter(), so the core layer
had no knowledge of the strategy
- Duplicate strategy-loading logic between CLI and server paths
### Fix
- Pass StrategyName through to GetChatter() and ChatRequest so the
core Chatter.BuildSession() handles strategy loading uniformly
- Extract `buildPromptChatRequest()` helper for clean request
construction
- Remove inline os.ReadFile strategy loading from the server handler
## Refactor: Clean System Message Assembly
Replace raw string concatenation of context + pattern + strategy
prompts with `joinPromptSections()` which:
- Trims whitespace from each section
- Skips empty sections (no double newlines from missing context)
- Joins with a single newline separator
## Tests Added
- `TestChatter_BuildSession_SeparatesSystemSections`: Verifies
strategy, context, and pattern are joined with newline separators
in the correct order
- `TestChatter_Send_StreamingErrorUpdateAndReturnDoesNotDeadlock`:
Regression test with 2-second timeout that catches the deadlock
when both error paths fire simultaneously
- `TestBuildPromptChatRequest_PreservesStrategyAndUserInput`: Verifies
the extracted helper preserves all fields including StrategyName
## CHANGES
- Add `Wire` log level constant to debug level enum
- Expose `GetLevel()` function for safe concurrent level reads
- Log outbound message roles and content at wire debug level
- Log inbound stream updates and token usage at wire level
- Log non-streaming LLM responses at wire debug level
- Update `--debug` flag description to include new level 4
- Update `set_debug_level` locale strings across all 10 languages
- Replace `fmt.Errorf("%s", ...)` with `errors.New()` across all packages
- Add `errors` import where needed, remove unused `fmt` imports
- Lowercase error message strings in i18n locale files for Go conventions
- Add `plugin_registry_run_setup_select_defaults` i18n key for setup prompt
- Add `plugin_registry_could_not_find_vendor` i18n key for vendor errors
- Internationalize hardcoded English strings in `plugin_registry.go`
- Update `db_error_loading_env_file` format verb from `%s` to `%w` for wrapping
- Normalize error casing in en, de, es, fr, it, ja, pt-BR, pt-PT, zh, fa locales
- Remove `NoSessionPatternUserMessages` constant from `chatter.go`
- Replace direct constant reference with `i18n.T()` translation call
- Update test import from `core` package to `i18n` package
- Update test assertion to use localized error message lookup
Changed from using only the last positional argument (args[len(args)-1])
to joining all positional arguments with spaces. This allows commands like:
fabric -p pattern_name How do I use fabric to list available models
to consume the entire phrase instead of just "models".
Fixes#1958
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
## CHANGES
- Add Spotify plugin with OAuth token handling and metadata
- Wire --spotify flag into CLI processing and output
- Register Spotify in plugin setup, env, and registry
- Update shell completions to include --spotify option
- Add i18n strings for Spotify configuration errors
- Add unit and integration tests for Spotify API
- Set gopls integration build tags for workspace
## CHANGES
- Add warning to stderr when using incompatible models with image generation
- Add GPT-5, GPT-5-nano, and GPT-5.2 to supported image generation models
- Create `checkImageGenerationCompatibility` function in OpenAI plugin
- Add comprehensive tests for image generation compatibility warnings
- Add integration test scenarios for CLI image generation workflows
- Suggest gpt-4o as alternative in incompatibility warning messages
### CHANGES
- Simplify error wrapping by removing redundant Sprintf calls in CLI
- Pass HTTP client to FetchModelsDirectly to enable connection reuse
- Store persistent HTTP client instance inside the OpenAI provider struct
- Update compatible AI providers to match the new function signature
- Add error handling for pattern loading from absolute file paths
### CHANGES
- Remove redundant fmt.Sprintf calls from error formatting logic
- Simplify model assignment to always use normalized model names
- Remove unused variadic parameter from the VendorsManager Clear method
### CHANGES
- Add automated first-time setup for patterns and strategies.
- Implement configuration validation to warn about missing required components.
- Update setup menu to group plugins into required and optional.
- Provide helpful guidance when no patterns are found in listing.
- Expand localization support for setup and error messaging across languages.
- Enhance strategy manager to reload and count installed strategies.
- Improve pattern error handling with specific guidance for empty directories.
## CHANGES
- Upgrade GitHub Actions to latest versions (v6, v21)
- Add modernization check step in CI workflow
- Replace strings manipulation with `strings.CutPrefix` and `strings.CutSuffix`
- Replace manual loops with `slices.Contains` for validation
- Use `strings.SplitSeq` for iterator-based string splitting
- Replace `bytes.TrimPrefix` with `bytes.CutPrefix` for clarity
- Use `strings.Builder` instead of string concatenation
- Replace `fmt.Sprintf` with `fmt.Appendf` for efficiency
- Simplify padding calculation with `max` builtin
- Replace reflect.TypeOf with TypeFor generic syntax
- Convert traditional for loops to range-based iterations
- Simplify reflection usage in CLI flag handling
- Update test loops to use range over integers
- Refactor string processing loops in template plugin
## CHANGES
- Add case-insensitive vendor lookup in VendorsManager
- Implement model name normalization in GetChatter method
- Add FilterByVendor method with case-insensitive matching
- Add FindModelNameCaseInsensitive helper for model queries
- Update group/item comparison to use case-insensitive checks
- Store vendors with lowercase keys internally
- Add comprehensive tests for case-insensitive functionality
- Fix vendor filtering for model listing command
- Update `--raw` flag description across all documentation files
- Clarify flag only affects OpenAI-compatible providers behavior
- Document Anthropic models use smart parameter selection
- Remove outdated reference to system/user role changes
- Update help text in CLI flags definition
- Translate updated description to all supported locales
- Update shell completion descriptions for zsh and fish
- chore: incoming 1836 changelog entry
- Add newline to `CreateOutputFile` if missing
- Use `t.Cleanup` for file removal in tests
- Add test for message with trailing newline
- Introduce `printedStream` flag in `Chatter.Send`
- Print newline if stream printed without trailing newline
- Add runtime OS detection for Windows platform
- Support `/flag` syntax for Windows command line
- Handle Windows colon delimiter `/flag:value` format
- Maintain backward compatibility with Unix-style flags
- Add comprehensive test coverage for flag extraction
- Support both `:` and `=` delimiters on Windows
- Preserve existing dash-based flag parsing logic
- Replace hardcoded strings with i18n.T translations
- Add en and es JSON locale files
- Implement custom translated help system
- Enable language detection from CLI args
- Add locale download capability
- Localize error messages throughout codebase
- Support TTS and notification translations
- Add internationalization system with Spanish support
- Create contexts and sessions tutorial documentation
- Fix broken Warp sponsorship image URL
- Add locale detection from environment variables
- Update VSCode settings with new dictionary words
- Exclude VSCode settings from version workflows
- Update pattern descriptions and explanations
- Add comprehensive i18n test coverage
- Replace fmt.Fprintf/os.Stderr with centralized debuglog.Log across CLI
- Add unconditional Log function to debuglog for important messages
- Improve OAuth flow messaging and token refresh diagnostics
- Update tests to capture debuglog output via SetOutput
- Convert Perplexity streaming errors to unified debug logging
- Emit file write notifications through debuglog instead of stderr
- Warn on ambiguous model selection using centralized logger
- Announce large audio processing steps via debuglog progress messages
- Standardize extension registry and patterns warnings through debuglog
CHANGES
- Update PrintWithVendor signature to accept default vendor and model
- Mark default vendor/model with asterisk in non-shell output
- Compare vendor and model case-insensitively when marking
- Pass registry defaults to PrintWithVendor from CLI
- Add test ensuring default selection appears with asterisk
- Keep shell completion output unchanged without default markers
CHANGES
- Add --transcribe-file flag to transcribe audio or video
- Add --transcribe-model flag with model listing and completion
- Add --split-media-file flag to chunk files over 25MB
- Implement OpenAI transcription using Whisper and GPT-4o Transcribe
- Integrate transcription pipeline into CLI before readability processing
- Provide zsh, bash, fish completions for new transcription flags
- Validate media extensions and enforce 25MB upload limits
- Update README with release and corrected pattern link path
• Add per-pattern model mapping documentation section
• Implement environment variable lookup for pattern-specific models
• Support vendor|model format in environment variable specification
• Check pattern-specific model when no model explicitly set
• Transform pattern names to uppercase environment variable format
• Add table of contents entry for new feature
• Enable shell startup file configuration for patterns
- Introduce CLI flag to skip pattern variable replacement.
- Wire flag into domain request and session builder.
- Avoid applying input variables when replacement is disabled.
- Provide PatternsEntity.GetWithoutVariables for input-only pattern processing support.
- Refactor patterns code into reusable load and apply helpers.
- Update bash, zsh, fish completions with new flag.
- Document flag in README and CLI help output.
- Add unit tests covering GetWithoutVariables path and behavior.
- Ensure {{input}} placeholder appends when missing in patterns.
- Add comprehensive "Recent Major Features" section to README
- Introduce new readme_updates Python script for automation
- Enable Gemini thinking configuration with token budgets
- Update CLI help text for Gemini thinking support
- Add comprehensive test coverage for Gemini thinking
- Create documentation for README update automation
- Reorganize README navigation structure with changelog section
CHANGES
- Add -V/--vendor flag to specify model vendor
- Implement vendor-aware model resolution and availability validation
- Warn on ambiguous models; suggest --vendor to disambiguate
- Update bash, zsh, fish completions with vendor suggestions
- Extend --listmodels to print vendor|model when interactive
- Add VendorsModels.PrintWithVendor; sort vendors and models alphabetically
- Pass vendor through API; update server chat handler
- Standardize docs and errors to --yt-dlp-args="..." syntax
- Add test covering ambiguous model warning across multiple vendors
- Promote go-shellquote to direct dependency in go.mod
CHANGES
- Enable Gemini models to use web search tool
- Validate search-location timezone or language code formats
- Normalize language codes from underscores to hyphenated form
- Inject Google Search tool when --search flag enabled
- Append deduplicated web citations under standardized Sources section
- Improve robustness for nil candidates and content parts
- Factor generation config builder for reuse in streaming
- Update CLI help and completions to include Gemini
### CHANGES
- Introduce `--yt-dlp-args` flag for advanced control
- Allow passing browser cookies for authentication
- Improve error handling for YouTube rate limits
- Add comprehensive documentation for YouTube processing
- Refactor YouTube methods to accept additional arguments
- Update shell completions to include new flag
CHANGES
- Integrate notification sending into chat processing workflow
- Add --notification and --notification-command CLI flags and help
- Provide cross-platform providers: macOS, Linux, Windows with fallbacks
- Escape shell metacharacters to prevent injection vulnerabilities
- Truncate Unicode output safely for notification message previews
- Update bash, zsh, fish completions with new notification options
- Add docs and YAML examples for configuration and customization
- Add unit tests for providers and notification integration paths
## CHANGES
- Add file existence check before creating output file
- Return error if target file already exists
- Change success message to write to stderr
- Update message format with brackets for clarity
- Prevent accidental file overwrites during output creation
## CHANGES
- Remove redundant byte conversion from audio data extraction
- Extract audio data as string before converting once
- Simplify audio data processing in chat handler
- Fix potential data corruption in audio output