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>
- Add category field to Tool dataclass (Text, Developer, Data, Other)
- Display tools grouped by category in main UI with section headers
- Add category dropdown selector in tool builder dialog
- Update example tools with appropriate categories
- Document category feature in README
Categories help organize tools in the UI for easier navigation.
Tools without a category default to "Other".
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added Alt+U/Alt+R for undo/redo in key bindings table
- Added tips about undo/redo (50 states) and $EDITOR button
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed undo/redo keys to Alt+U and Alt+R (meta keys work in urwid)
- Fixed undo logic: now saves state BEFORE edit happens, not after
- Added duplicate state prevention
- Simplified the tracking logic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Ctrl+Z is the Unix suspend signal (SIGTSTP) which suspends the process
before urwid can intercept it. Changed to:
- Ctrl+U for undo
- Ctrl+R for redo
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add UndoableEdit class with undo/redo support:
- Ctrl+Z to undo (up to 50 states)
- Ctrl+Y or Ctrl+Shift+Z to redo
- Automatically tracks edit history and cursor position
- Tab passes through for focus cycling
- Remove syntax highlighting attempt (incompatible with urwid Edit widget's
text layout engine which requires raw text strings, not markup)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When editing a code step, users can now click the "$EDITOR" button
to open the current code in their preferred external editor:
- Uses $EDITOR environment variable (falls back to $VISUAL, then nano)
- Creates a temp .py file with current code
- Suspends urwid UI while editor runs
- Imports edited code back when editor closes
- Shows success/error status in the dialog
This allows using vim, nano, VS Code, or any editor for complex
code editing while still using the SmartTools UI for workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Wrap the AI prompt ListBox in DOSScrollBar for consistent
scrolling experience in the auto-adjust panel.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>