- Add 'cmdforge providers for-tools <tool>...' to list providers used by tools
- Add --warm flag to pre-load local models (Ollama) for faster first inference
- Warm larger models first to claim contiguous GPU memory
- Skip cloud providers (claude, opencode, gemini) during warm-up
- Add max_tokens field to PromptStep for controlling output length
- Pass max_tokens to call_provider with provider-specific flags
- Add comprehensive tests for provider functionality
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add schema validation and retry logic for AI responses:
- Add output_schema, max_retries, plain_text fields to PromptStep
- Add DEFAULT_OUTPUT_SCHEMA with output/reasoning fields
- Implement append_schema_instructions() for prompt augmentation
- Implement validate_schema() using jsonschema library
- Add retry logic with error feedback on validation failure
- Enhance substitute_variables() for nested field access ({var.field})
- Add jsonschema to dependencies
- Update GUI dialog with plain_text checkbox and max_retries spinner
- Add comprehensive tests for structured output and nested access
Tools using plain_text=True bypass validation (current behavior).
Tools without plain_text get structured JSON output with schema enforcement.
Migration Phase 1 complete. Next: Apply plain_text=True to all 72 tools.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add strip_fences field to PromptStep for removing markdown code fences
- Fix exec() to use same dict for globals and locals, allowing nested
functions to access module-level imports
- Add GUI checkbox for strip_fences option
- Update CLAUDE.md with improved documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- save_tool() now preserves registry_hash, registry_status, registry_owner,
and registry_feedback from existing config when writing Tool.to_dict(),
preventing edits from erasing registry metadata.
- CLI publish (registry_commands.py) and collection publish
(collections_commands.py) now save registry_owner from the publish
response, matching the GUI publish dialog behavior.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Registry:
- Add admin owner override for publishing tools as "official"
- Add POST /api/v1/tools/status-by-hash batch endpoint for status lookup
scoped to publisher_id (works for tools published under any owner)
GUI:
- Add "Publish as" dropdown in publish dialog for admin users
- Add "installed" tool state (teal with arrow indicator) for registry-installed tools
- Fix tool editing for official/* qualified tool names (_get_qualified_name helper)
- Fix cancel navigation returning to wrong page (Welcome instead of Tools)
- Fix collections tab not refreshing after publish
- Refactor StatusSyncWorker to use batch hash lookup (1 request instead of N)
with chunking (100 max) and hash collision handling
CLI:
- Switch registry status sync to hash-based lookup
- Add collection dependency checking and unpublished dep detection
Publish dialog cleanup:
- Move yaml import to module level, remove duplicate _bump_patch_version
- Fix owner combo using currentText() for reliable selection
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tools can now declare system-level package dependencies (apt, brew, pacman, dnf)
that get checked and optionally installed when the tool is installed or run.
Features:
- SystemDependency dataclass with short form (string) and long form (dict)
- New system_deps.py module with platform detection and installation
- `cmdforge system-deps <tool>` command to check/install system packages
- `cmdforge check` now shows both CmdForge and system dependencies
- `cmdforge registry install` prompts for system dep installation
- GUI: System Dependencies section in Tool Builder with add/edit dialog
- Runner warns about missing system deps before execution
- Integration with project install (manifest and lock-based)
Also includes:
- Quote paths in wrapper scripts for spaces support
- Tests for value type preservation in code steps
- Unskip invalid tool name test
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tools can now ship with defaults.yaml containing configurable settings
that users can customize via settings.yaml (auto-created from defaults).
Features:
- ensure_settings() helper copies defaults to settings on first use
- Settings available as {settings.key} in templates (scalars only)
- Full dict access via settings['key'] in code steps
- CLI: cmdforge settings <tool> show/edit/reset/diff
- GUI: Defaults editor in Tool Builder, Configure button on Tools page
- Registry: defaults.yaml published with tools, included in downloads
- Secret detection warning on publish (api_key, password, token, etc.)
Fully backward compatible - tools without defaults work unchanged.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tools from the registry are installed to ~/.cmdforge/owner/name/ (e.g.,
~/.cmdforge/official/summarize/), but list_tools() only searched direct
children of ~/.cmdforge/.
Changes:
- list_tools() now searches both direct children and owner subdirectories
- Returns qualified names for nested tools (e.g., "official/summarize")
- load_tool() already handled qualified paths, added docstring clarification
Fixes tools installed via `cmdforge install` not appearing in `cmdforge list`.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Normalize dependencies in Tool.from_dict() to handle both string and dict formats
- Dict format: {name: "tts", version: "*"} → extracts just the name for Tool.dependencies
- Fixes "unhashable type: dict" error in check_dependencies()
This allows tools to declare dependencies with version constraints in config.yaml:
dependencies:
- name: tts
version: "*"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Tool dataclass now has a path field that points to the config.yaml
file it was loaded from. This is set by load_tool() and enables the
publish dialog to save the registry_hash back to the local config.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add name field to PromptStep, CodeStep, and ToolStep dataclasses
- Update step dialogs to allow editing step names
- Display custom step names in both list and flow views
- Fix F key shortcut by installing event filter on graph widget
- Steps without custom names show default "Prompt N" / "Code N"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Profiles allow users to inject system instructions into prompts,
customizing the AI's behavior and persona for tool execution.
Features:
- Profile dataclass with name, description, system_prompt
- 8 built-in profiles: None, Comedian, Technical Writer, Teacher,
Concise, Creative, Code Reviewer, Analyst
- Custom profile creation and storage in ~/.cmdforge/profiles/
- Profile selector in Prompt Step dialog
- Profile injection during tool execution
- Profiles page in GUI (Ctrl+4) for viewing and managing profiles
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code step errors:
- Show line numbers with context (line before/after)
- Display available variables for debugging
- Include step number in error message
YAML loading errors:
- Show line and column number for syntax errors
- Display the problematic line with arrow pointer
- Show the specific YAML problem description
Nested tool errors:
- Track call stack through tool chain
- Display full call path when nested tool fails
- Show step numbers at each level
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add ToolSource dataclass for attribution metadata (type, license, url, author, original_tool)
- Add source and version fields to Tool dataclass
- Update Tool.from_dict() and to_dict() to handle source field
- Display source attribution in TUI info panel
- Show [imported]/[forked] markers in cmdforge list
- Add import_fabric.py script to import Fabric patterns as CmdForge tools
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major rename operation:
- Rename Python package: smarttools -> cmdforge
- Update CLI entry point: smarttools -> cmdforge
- Update all imports and module references
- Update pyproject.toml with new name, URLs, entry point
- Update all HTML templates with new branding
- Update documentation (CLAUDE.md, README.md, docs/*, wiki/*)
- Update environment variables:
- SMARTTOOLS_ENV -> CMDFORGE_ENV
- SMARTTOOLS_REGISTRY_DB -> CMDFORGE_REGISTRY_DB
- SMARTTOOLS_TOKEN -> CMDFORGE_TOKEN
- SMARTTOOLS_REGISTRY_* -> CMDFORGE_REGISTRY_*
- Update Dockerfile and docker-compose.yml
- Update tests to use new package name
- Update scripts and examples
- Update package.json and tailwind.config.js
All 158 unit tests pass. The CLI is working correctly with the
new cmdforge command.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>