- Add tests/ to Docker image for in-container testing
- Install [all,dev] dependencies (includes Flask, registry, TUI)
- Make integration tests configurable via REGISTRY_URL env var
- Add error handling to publish test fixture for rate limiting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major refactoring:
- Split cli.py (1465 lines) into cli/ package with 6 modules
- Split ui_urwid.py (2313 lines) into ui_urwid/ package with 4 modules
- Maintain backwards compatibility via thin wrapper modules
New features:
- Add tool scrutiny system for registry publishing (honesty, transparency, scope, efficiency checks)
- Add optimization suggestions for AI calls that could be pure code
Bug fixes:
- Fix variable substitution escaping ({{literal}} now works)
- Fix provider command parsing with shlex for quoted paths
- Add error logging even without --verbose flag
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add proper label associations with for/id attributes to all select
elements on the tools page for screen reader compatibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add submit button to search forms for keyboard accessibility
- Fix category count text contrast (text-gray-400 → text-gray-600)
- Add aria-label to search inputs
- Add visible Search button on mobile filters
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Convert (id, title) tuples to SimpleNamespace objects with id, text,
and level attributes to match template expectations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove sitemap.xml and robots.txt route registrations from app.py
since they're already defined in routes.py. This was causing an
AssertionError on startup.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add permissive robots.txt welcoming all crawlers including AI
- Add dynamic sitemap.xml with all pages and tools
- Add real documentation content (Getting Started, Installation, First Tool, Publishing, Providers)
- Update docs route to use content from docs_content.py
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The main Flask app and web blueprint both used /static, causing
conflicts. Changed web blueprint to use /web-static instead.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use absolute paths for templates and static folders to ensure
they resolve correctly regardless of the working directory.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Register Flask error handlers to render the error templates.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added node_modules/, package-lock.json, discussions/, diagrams/
and temporary files to .gitignore
- Removed accidentally committed files from git tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The auth.py was passing csrf_token as a string variable which
collided with the global csrf_token function in Jinja2. Removed
the redundant passing since csrf_token() is already available
as a Jinja global.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The footer template uses now().year for the copyright date.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Detect ProviderModelNotFoundError and show clean message
- Extract provider and model IDs from error
- Suggest: connect provider in opencode, use --provider flag, or edit in UI
- Truncate other stderr to 200 chars to avoid code dumps
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add "smarttools providers install" suggestion when command not found
- Add suggestion when provider exits with error containing "not found"
- Detect empty output and warn about unavailable model
- Show stderr hint when provider returns nothing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
60-second demo using Docker container:
- Pull container, install OpenCode, run eli5 on README
- Uses free Big Pickle model by default, no sign-up required
- Demonstrates the tool while explaining itself
Keep native install as 'Quick Start (Native Install)' for regular use.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Mention 4 free models: Big Pickle, GLM-4.7, Grok Code Fast 1, MiniMax M2.1
- Note that 75+ providers are available through OpenCode
- Change setup to "opens browser to connect more providers"
- Put opencode-pickle first in variants so test uses a free provider
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Always show the IMPORTANT message about refreshing PATH, with clear
step numbering that makes source ~/.bashrc step 1.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add separate instructions for:
- Pre-built container: docker run with display/volume flags
- Build from source: docker-compose run setup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Users can now pull the image directly from the Gitea registry:
docker pull gitea.brrd.tech/rob/smarttools:latest
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Docker changes:
- Install Node.js and npm (for Claude CLI)
- Install Firefox ESR for browser-based OAuth
- Install X11 libraries for display forwarding
- Add 'setup' service with display access
Usage:
xhost +local:docker
docker-compose run --rm setup
smarttools providers install
The 'setup' service has DISPLAY and X11 socket access, so browser-based
OAuth flows (Claude, Codex, Gemini, OpenCode) can work inside Docker.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All major providers (Claude, Codex, Gemini, OpenCode) use browser-based
OAuth authentication, not manual API keys:
- Run the CLI command
- Browser opens for sign-in
- Auth tokens saved automatically
Also added post_install_note for Ollama to show how to add the provider
after installing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New commands:
- smarttools providers list - List all providers with status
- smarttools providers check - Check which providers are available
- smarttools providers add <name> <command> - Add/update provider
- smarttools providers remove <name> - Remove provider
- smarttools providers test <name> - Test a provider
Features:
- Shows [+] for available, [-] for missing providers
- Mock provider always shows as available (built-in)
- Helpful installation hints when no providers found
- Can add custom providers (Ollama, local scripts, etc.)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Friends can now clone and test without installing anything locally.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Self-contained Docker setup for SmartTools with no external dependencies.
Includes cli, test, and shell services.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Dockerfile for containerized builds
- Add .dockerignore for cleaner builds
- Add CLAUDE.md for development guidance
- Update README and docs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The AI prompt now explicitly shows:
1. Assign Available Variables to standard Python variables first
2. Then use those variables in the code
3. Multi-line example with file writing pattern
This prevents the AI from trying to use {variable} directly in
expressions without proper assignment.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The AI follows the pattern better when the available variables are
shown in the exact format they should be used:
"""{input}""", """{response}""", etc.
This helps the AI generate code that properly uses triple quotes
for variable substitution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated the default prompt template to explain how to use variables:
- Variables must be wrapped in curly braces: {variable}
- Use triple quotes since content may contain quotes/newlines
- Added example: my_var = """{response}"""
This helps the AI generate code that works correctly with the
variable substitution system.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Code steps were executing with literal {variable} placeholders instead
of substituted values. Now substitute_variables() is called on the code
before execution, matching the behavior of prompt steps.
This fixes issues like {outputfile} being treated as a Python set literal
or written as a literal filename.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The AI was generating function definitions instead of inline code.
Updated the default prompt template to explicitly:
- Request inline executable code, NOT function definitions
- Clarify that variables are already available
- Emphasize no wrapping in functions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>