Rename project from SmartTools to CmdForge
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>
This commit is contained in:
parent
2939dd806b
commit
497fe87fc5
|
|
@ -21,7 +21,7 @@ What should have happened?
|
|||
## Environment
|
||||
|
||||
- OS:
|
||||
- SmartTools version:
|
||||
- CmdForge version:
|
||||
- Provider:
|
||||
- Docker or native install?
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
name: Question
|
||||
about: Ask a question about SmartTools
|
||||
about: Ask a question about CmdForge
|
||||
labels: question
|
||||
---
|
||||
|
||||
|
|
|
|||
12
AGENTS.md
12
AGENTS.md
|
|
@ -1,7 +1,7 @@
|
|||
# Repository Guidelines
|
||||
|
||||
## Project Structure & Module Organization
|
||||
- `src/smarttools/` contains the core Python package (CLI entry point, tool model, runner, providers, UI backends).
|
||||
- `src/cmdforge/` contains the core Python package (CLI entry point, tool model, runner, providers, UI backends).
|
||||
- `tests/` holds pytest suites.
|
||||
- `docs/` includes installation, provider setup, examples, and design notes.
|
||||
- `examples/` provides sample tools and an installer script.
|
||||
|
|
@ -15,11 +15,11 @@
|
|||
- `ui_urwid.py` and `ui_snack.py` provide the TUI implementations, selected by `ui.py`.
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
- `pip install -e ".[dev]"` installs SmartTools in editable mode with dev dependencies.
|
||||
- `pip install -e ".[dev]"` installs CmdForge in editable mode with dev dependencies.
|
||||
- `pytest` runs the full test suite.
|
||||
- `pytest tests/test.py::test_name` runs a focused test.
|
||||
- `python -m smarttools.cli` runs the CLI module directly.
|
||||
- `smarttools ui` launches the TUI (requires `urwid` or `python-newt`).
|
||||
- `python -m cmdforge.cli` runs the CLI module directly.
|
||||
- `cmdforge ui` launches the TUI (requires `urwid` or `python-newt`).
|
||||
- `docker-compose build` builds the dev container image.
|
||||
- `docker-compose run --rm test` runs tests inside Docker.
|
||||
|
||||
|
|
@ -38,5 +38,5 @@
|
|||
- PRs should include a clear summary, test results (or rationale if tests are skipped), and screenshots when UI behavior changes.
|
||||
|
||||
## Security & Configuration Tips
|
||||
- Provider credentials live in `~/.smarttools/providers.yaml`; avoid committing secrets.
|
||||
- User tool configs live in `~/.smarttools/<toolname>/config.yaml` and should not be added to the repo.
|
||||
- Provider credentials live in `~/.cmdforge/providers.yaml`; avoid committing secrets.
|
||||
- User tool configs live in `~/.cmdforge/<toolname>/config.yaml` and should not be added to the repo.
|
||||
|
|
|
|||
28
CLAUDE.md
28
CLAUDE.md
|
|
@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||
|
||||
## Project Overview
|
||||
|
||||
SmartTools is a lightweight personal tool builder for AI-powered CLI commands. It lets users create custom terminal commands that call AI providers, chain prompts with Python code steps, and use them like any Unix pipe command.
|
||||
CmdForge is a lightweight personal tool builder for AI-powered CLI commands. It lets users create custom terminal commands that call AI providers, chain prompts with Python code steps, and use them like any Unix pipe command.
|
||||
|
||||
## Development Commands
|
||||
|
||||
|
|
@ -19,29 +19,29 @@ pytest
|
|||
pytest tests/test.py::test_name
|
||||
|
||||
# Run the CLI
|
||||
python -m smarttools.cli
|
||||
python -m cmdforge.cli
|
||||
|
||||
# Launch the UI
|
||||
smarttools ui
|
||||
cmdforge ui
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Core Modules (`src/smarttools/`)
|
||||
### Core Modules (`src/cmdforge/`)
|
||||
|
||||
- **cli.py**: Entry point (`smarttools` command). Routes subcommands: list, create, edit, delete, test, run, ui, refresh
|
||||
- **cli.py**: Entry point (`cmdforge` command). Routes subcommands: list, create, edit, delete, test, run, ui, refresh
|
||||
- **tool.py**: Tool definition dataclasses (`Tool`, `ToolArgument`, `PromptStep`, `CodeStep`), YAML config loading/saving, wrapper script generation
|
||||
- **runner.py**: Execution engine. Runs tool steps sequentially, handles variable substitution (`{input}`, `{varname}`), executes Python code steps via `exec()`
|
||||
- **providers.py**: Provider abstraction. Calls AI CLI tools via subprocess, reads provider configs from `~/.smarttools/providers.yaml`
|
||||
- **providers.py**: Provider abstraction. Calls AI CLI tools via subprocess, reads provider configs from `~/.cmdforge/providers.yaml`
|
||||
- **ui.py**: UI dispatcher - selects between urwid and snack implementations
|
||||
- **ui_urwid.py**: Full TUI implementation using urwid library
|
||||
- **ui_snack.py**: Fallback TUI using python-newt/snack
|
||||
|
||||
### Key Paths
|
||||
|
||||
- **Tools storage**: `~/.smarttools/<toolname>/config.yaml`
|
||||
- **Tools storage**: `~/.cmdforge/<toolname>/config.yaml`
|
||||
- **Wrapper scripts**: `~/.local/bin/<toolname>` (auto-generated bash scripts)
|
||||
- **Provider config**: `~/.smarttools/providers.yaml`
|
||||
- **Provider config**: `~/.cmdforge/providers.yaml`
|
||||
|
||||
### Tool Structure
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ Variable substitution is simple string replacement in `runner.py:substitute_vari
|
|||
|
||||
## Provider System
|
||||
|
||||
Providers are CLI tools that accept prompts via stdin and output to stdout. Defined in `~/.smarttools/providers.yaml`:
|
||||
Providers are CLI tools that accept prompts via stdin and output to stdout. Defined in `~/.cmdforge/providers.yaml`:
|
||||
|
||||
```yaml
|
||||
providers:
|
||||
|
|
@ -81,9 +81,9 @@ The `mock` provider is built-in for testing without API calls.
|
|||
|
||||
## Web UI & Registry
|
||||
|
||||
SmartTools includes a web interface and tool registry:
|
||||
CmdForge includes a web interface and tool registry:
|
||||
|
||||
### Web Modules (`src/smarttools/web/`)
|
||||
### Web Modules (`src/cmdforge/web/`)
|
||||
|
||||
- **app.py**: Flask app factory, registers blueprints
|
||||
- **routes.py**: Main web routes (docs, tutorials, tools, etc.)
|
||||
|
|
@ -93,7 +93,7 @@ SmartTools includes a web interface and tool registry:
|
|||
- **filters.py**: Jinja2 filters (timeago, markdown, etc.)
|
||||
- **docs_content.py**: Documentation and tutorial content
|
||||
|
||||
### Registry Modules (`src/smarttools/registry/`)
|
||||
### Registry Modules (`src/cmdforge/registry/`)
|
||||
|
||||
- **app.py**: Registry API (tool publishing, search, downloads)
|
||||
- **db.py**: SQLite schema and queries
|
||||
|
|
@ -109,8 +109,8 @@ SmartTools includes a web interface and tool registry:
|
|||
|
||||
```bash
|
||||
# Development
|
||||
python -m smarttools.web.app
|
||||
python -m cmdforge.web.app
|
||||
|
||||
# Production (example)
|
||||
SMARTTOOLS_REGISTRY_DB=/path/to/db PORT=5050 python -m smarttools.web.app
|
||||
CMDFORGE_REGISTRY_DB=/path/to/db PORT=5050 python -m cmdforge.web.app
|
||||
```
|
||||
|
|
|
|||
22
Dockerfile
22
Dockerfile
|
|
@ -1,11 +1,11 @@
|
|||
# SmartTools - AI-powered CLI command builder
|
||||
# Build: docker build -t smarttools .
|
||||
# Run: docker run -it --rm -v ~/.smarttools:/root/.smarttools smarttools
|
||||
# CmdForge - AI-powered CLI command builder
|
||||
# Build: docker build -t cmdforge .
|
||||
# Run: docker run -it --rm -v ~/.cmdforge:/root/.cmdforge cmdforge
|
||||
|
||||
FROM python:3.12-slim
|
||||
|
||||
LABEL maintainer="rob"
|
||||
LABEL description="SmartTools - Personal AI-powered CLI command builder"
|
||||
LABEL description="CmdForge - Personal AI-powered CLI command builder"
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
|
|
@ -34,24 +34,24 @@ COPY examples/ ./examples/
|
|||
COPY docs/ ./docs/
|
||||
COPY tests/ ./tests/
|
||||
|
||||
# Install SmartTools and all dependencies (CLI, TUI, registry)
|
||||
# Install CmdForge and all dependencies (CLI, TUI, registry)
|
||||
RUN pip install --no-cache-dir -e ".[all,dev]"
|
||||
|
||||
# Create smarttools directory
|
||||
RUN mkdir -p /root/.smarttools /root/.local/bin
|
||||
# Create cmdforge directory
|
||||
RUN mkdir -p /root/.cmdforge /root/.local/bin
|
||||
|
||||
# Install example tools
|
||||
RUN python examples/install.py
|
||||
|
||||
# Generate CLI wrappers
|
||||
RUN smarttools refresh
|
||||
RUN cmdforge refresh
|
||||
|
||||
# Add local bin to PATH
|
||||
ENV PATH="/root/.local/bin:${PATH}"
|
||||
|
||||
# Default command - show help
|
||||
CMD ["smarttools", "--help"]
|
||||
CMD ["cmdforge", "--help"]
|
||||
|
||||
# For interactive use:
|
||||
# docker run -it --rm smarttools smarttools ui
|
||||
# docker run -it --rm smarttools bash
|
||||
# docker run -it --rm cmdforge cmdforge ui
|
||||
# docker run -it --rm cmdforge bash
|
||||
|
|
|
|||
96
README.md
96
README.md
|
|
@ -1,4 +1,4 @@
|
|||
# SmartTools
|
||||
# CmdForge
|
||||
|
||||
**A lightweight personal tool builder for AI-powered CLI commands.**
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ echo "Price $49.99, SKU ABC-123" | json-extract --fields "price, sku"
|
|||
# Output: {"price": 49.99, "sku": "ABC-123"}
|
||||
```
|
||||
|
||||
## Why SmartTools?
|
||||
## Why CmdForge?
|
||||
|
||||
- **Unix Philosophy** - Tools that do one thing well, composable with pipes
|
||||
- **Provider Agnostic** - Works with Claude, GPT, Gemini, DeepSeek, local models
|
||||
|
|
@ -30,17 +30,17 @@ echo "Price $49.99, SKU ABC-123" | json-extract --fields "price, sku"
|
|||
|
||||
## Try It Now (60 seconds)
|
||||
|
||||
See SmartTools in action without installing anything on your system:
|
||||
See CmdForge in action without installing anything on your system:
|
||||
|
||||
```bash
|
||||
# Pull the container
|
||||
docker pull gitea.brrd.tech/rob/smarttools:latest
|
||||
docker pull gitea.brrd.tech/rob/cmdforge:latest
|
||||
|
||||
# Run it
|
||||
docker run -it --rm gitea.brrd.tech/rob/smarttools bash
|
||||
docker run -it --rm gitea.brrd.tech/rob/cmdforge bash
|
||||
|
||||
# Inside the container - install OpenCode (includes free AI models)
|
||||
smarttools providers install # Select option 4, then 'y'
|
||||
cmdforge providers install # Select option 4, then 'y'
|
||||
source ~/.bashrc
|
||||
|
||||
# Try it! This explains the README using the free Big Pickle model
|
||||
|
|
@ -55,21 +55,21 @@ For regular use, install natively:
|
|||
|
||||
```bash
|
||||
# Clone and install
|
||||
git clone https://gitea.brrd.tech/rob/SmartTools.git
|
||||
cd SmartTools
|
||||
git clone https://gitea.brrd.tech/rob/CmdForge.git
|
||||
cd CmdForge
|
||||
pip install -e .
|
||||
|
||||
# Ensure ~/.local/bin is in PATH
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
# Install an AI provider (interactive guide)
|
||||
smarttools providers install
|
||||
cmdforge providers install
|
||||
|
||||
# Launch the UI
|
||||
smarttools ui
|
||||
cmdforge ui
|
||||
|
||||
# Or create your first tool
|
||||
smarttools create summarize
|
||||
cmdforge create summarize
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
|
@ -77,16 +77,16 @@ smarttools create summarize
|
|||
### Native Install
|
||||
|
||||
```bash
|
||||
git clone https://gitea.brrd.tech/rob/SmartTools.git
|
||||
cd SmartTools
|
||||
git clone https://gitea.brrd.tech/rob/CmdForge.git
|
||||
cd CmdForge
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
### With Development Dependencies
|
||||
|
||||
```bash
|
||||
git clone https://gitea.brrd.tech/rob/SmartTools.git
|
||||
cd SmartTools
|
||||
git clone https://gitea.brrd.tech/rob/CmdForge.git
|
||||
cd CmdForge
|
||||
pip install -e ".[dev]"
|
||||
```
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ export PATH="$HOME/.local/bin:$PATH"
|
|||
Then refresh wrapper scripts:
|
||||
|
||||
```bash
|
||||
smarttools refresh
|
||||
cmdforge refresh
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
|
@ -115,7 +115,7 @@ smarttools refresh
|
|||
### UI Mode (Recommended for Beginners)
|
||||
|
||||
```bash
|
||||
smarttools ui
|
||||
cmdforge ui
|
||||
```
|
||||
|
||||
Navigate with arrow keys, Tab, Enter, and mouse. Create tools visually with the built-in prompt editor.
|
||||
|
|
@ -123,13 +123,13 @@ Navigate with arrow keys, Tab, Enter, and mouse. Create tools visually with the
|
|||
### CLI Mode
|
||||
|
||||
```bash
|
||||
smarttools list # List all tools
|
||||
smarttools create mytool # Create new tool
|
||||
smarttools edit mytool # Edit in $EDITOR
|
||||
smarttools delete mytool # Delete tool
|
||||
smarttools run mytool # Run a tool
|
||||
smarttools test mytool # Test with mock provider
|
||||
smarttools refresh # Update executable wrappers
|
||||
cmdforge list # List all tools
|
||||
cmdforge create mytool # Create new tool
|
||||
cmdforge edit mytool # Edit in $EDITOR
|
||||
cmdforge delete mytool # Delete tool
|
||||
cmdforge run mytool # Run a tool
|
||||
cmdforge test mytool # Test with mock provider
|
||||
cmdforge refresh # Update executable wrappers
|
||||
```
|
||||
|
||||
### Running Tools
|
||||
|
|
@ -155,10 +155,10 @@ cat file.txt | mytool --provider mock
|
|||
|
||||
### Composing Tools
|
||||
|
||||
SmartTools follows Unix philosophy: each tool does one thing well, and tools chain together for complex workflows.
|
||||
CmdForge follows Unix philosophy: each tool does one thing well, and tools chain together for complex workflows.
|
||||
|
||||
```bash
|
||||
# Chain SmartTools together
|
||||
# Chain CmdForge together
|
||||
cat error.log | log-errors | summarize | translate --lang Spanish
|
||||
|
||||
# Code review pipeline: focus on changes, review, then summarize
|
||||
|
|
@ -208,7 +208,7 @@ translate-doc() {
|
|||
|
||||
## Example Tools
|
||||
|
||||
SmartTools comes with 28 pre-built examples you can install:
|
||||
CmdForge comes with 28 pre-built examples you can install:
|
||||
|
||||
### Text Processing
|
||||
|
||||
|
|
@ -259,14 +259,14 @@ SmartTools comes with 28 pre-built examples you can install:
|
|||
### Install Example Tools
|
||||
|
||||
```bash
|
||||
# Run the example installer (from the SmartTools directory)
|
||||
# Run the example installer (from the CmdForge directory)
|
||||
python examples/install.py
|
||||
smarttools refresh
|
||||
cmdforge refresh
|
||||
```
|
||||
|
||||
## Providers
|
||||
|
||||
SmartTools works with any AI CLI tool. We've profiled 12 providers:
|
||||
CmdForge works with any AI CLI tool. We've profiled 12 providers:
|
||||
|
||||
| Provider | Speed | Accuracy | Cost | Best For |
|
||||
|----------|-------|----------|------|----------|
|
||||
|
|
@ -281,7 +281,7 @@ See [docs/PROVIDERS.md](docs/PROVIDERS.md) for setup instructions.
|
|||
|
||||
## Tool Anatomy
|
||||
|
||||
A tool is a YAML config file in `~/.smarttools/<name>/config.yaml`:
|
||||
A tool is a YAML config file in `~/.cmdforge/<name>/config.yaml`:
|
||||
|
||||
```yaml
|
||||
name: summarize
|
||||
|
|
@ -429,7 +429,7 @@ This lets you generate or modify Python code using AI directly within the tool b
|
|||
|
||||
## Philosophy
|
||||
|
||||
SmartTools is built on **Unix philosophy**:
|
||||
CmdForge is built on **Unix philosophy**:
|
||||
|
||||
1. **Do one thing well** - Each tool solves one problem. `summarize` summarizes. `translate` translates. No bloated mega-tools.
|
||||
|
||||
|
|
@ -444,15 +444,15 @@ SmartTools is built on **Unix philosophy**:
|
|||
## Contributing
|
||||
|
||||
```bash
|
||||
git clone https://gitea.brrd.tech/rob/smarttools.git
|
||||
cd smarttools
|
||||
git clone https://gitea.brrd.tech/rob/cmdforge.git
|
||||
cd cmdforge
|
||||
pip install -e ".[dev]"
|
||||
pytest
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
If SmartTools saves you time, consider supporting the project:
|
||||
If CmdForge saves you time, consider supporting the project:
|
||||
|
||||
**Bitcoin:** `3KeLqGv2Xo8jGYkqA1i68a6nXwgQnuJoza`
|
||||
|
||||
|
|
@ -470,16 +470,16 @@ Pull and run the pre-built image directly:
|
|||
|
||||
```bash
|
||||
# Pull from registry
|
||||
docker pull gitea.brrd.tech/rob/smarttools:latest
|
||||
docker pull gitea.brrd.tech/rob/cmdforge:latest
|
||||
|
||||
# Run SmartTools
|
||||
docker run -it --rm gitea.brrd.tech/rob/smarttools smarttools --help
|
||||
# Run CmdForge
|
||||
docker run -it --rm gitea.brrd.tech/rob/cmdforge cmdforge --help
|
||||
|
||||
# List available tools
|
||||
docker run -it --rm gitea.brrd.tech/rob/smarttools smarttools list
|
||||
docker run -it --rm gitea.brrd.tech/rob/cmdforge cmdforge list
|
||||
|
||||
# Interactive shell
|
||||
docker run -it --rm gitea.brrd.tech/rob/smarttools bash
|
||||
docker run -it --rm gitea.brrd.tech/rob/cmdforge bash
|
||||
```
|
||||
|
||||
### Build from Source
|
||||
|
|
@ -488,8 +488,8 @@ Alternatively, build the container yourself:
|
|||
|
||||
```bash
|
||||
# Clone the repo
|
||||
git clone https://gitea.brrd.tech/rob/SmartTools.git
|
||||
cd SmartTools
|
||||
git clone https://gitea.brrd.tech/rob/CmdForge.git
|
||||
cd CmdForge
|
||||
|
||||
# Build the container
|
||||
docker-compose build
|
||||
|
|
@ -498,7 +498,7 @@ docker-compose build
|
|||
docker-compose run --rm test
|
||||
|
||||
# Use the CLI
|
||||
docker-compose run --rm cli smarttools list
|
||||
docker-compose run --rm cli cmdforge list
|
||||
|
||||
# Interactive shell
|
||||
docker-compose run --rm shell
|
||||
|
|
@ -518,12 +518,12 @@ xhost +local:docker
|
|||
docker run -it --rm \
|
||||
-e DISPLAY=$DISPLAY \
|
||||
-v /tmp/.X11-unix:/tmp/.X11-unix \
|
||||
-v smarttools-data:/root/.smarttools \
|
||||
-v cmdforge-data:/root/.cmdforge \
|
||||
--network host \
|
||||
gitea.brrd.tech/rob/smarttools bash
|
||||
gitea.brrd.tech/rob/cmdforge bash
|
||||
|
||||
# Inside the container:
|
||||
smarttools providers install
|
||||
cmdforge providers install
|
||||
```
|
||||
|
||||
**Using docker-compose (build from source):**
|
||||
|
|
@ -533,14 +533,14 @@ xhost +local:docker
|
|||
docker-compose run --rm setup
|
||||
|
||||
# Inside the container:
|
||||
smarttools providers install
|
||||
cmdforge providers install
|
||||
```
|
||||
|
||||
**After installing a provider:**
|
||||
|
||||
```bash
|
||||
# Test the provider works
|
||||
smarttools providers test claude
|
||||
cmdforge providers test claude
|
||||
```
|
||||
|
||||
**Available Providers:**
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# SmartTools - AI-powered CLI command builder
|
||||
# CmdForge - AI-powered CLI command builder
|
||||
#
|
||||
# Quick Start:
|
||||
# docker-compose build # Build the image
|
||||
# docker-compose run --rm test # Run tests
|
||||
# docker-compose run --rm cli smarttools list
|
||||
# docker-compose run --rm cli cmdforge list
|
||||
#
|
||||
# This is a standalone project with no external dependencies.
|
||||
|
||||
|
|
@ -17,10 +17,10 @@ services:
|
|||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: smarttools:latest
|
||||
image: cmdforge:latest
|
||||
volumes:
|
||||
- smarttools-data:/root/.smarttools
|
||||
command: ["smarttools", "--help"]
|
||||
- cmdforge-data:/root/.cmdforge
|
||||
command: ["cmdforge", "--help"]
|
||||
|
||||
# ============================================================================
|
||||
# Tests
|
||||
|
|
@ -29,9 +29,9 @@ services:
|
|||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: smarttools:latest
|
||||
image: cmdforge:latest
|
||||
volumes:
|
||||
- smarttools-data:/root/.smarttools
|
||||
- cmdforge-data:/root/.cmdforge
|
||||
command: ["pytest", "-v"]
|
||||
|
||||
# ============================================================================
|
||||
|
|
@ -41,9 +41,9 @@ services:
|
|||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: smarttools:latest
|
||||
image: cmdforge:latest
|
||||
volumes:
|
||||
- smarttools-data:/root/.smarttools
|
||||
- cmdforge-data:/root/.cmdforge
|
||||
command: ["/bin/bash"]
|
||||
stdin_open: true
|
||||
tty: true
|
||||
|
|
@ -57,11 +57,11 @@ services:
|
|||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: smarttools:latest
|
||||
image: cmdforge:latest
|
||||
environment:
|
||||
- DISPLAY=${DISPLAY:-:0}
|
||||
volumes:
|
||||
- smarttools-data:/root/.smarttools
|
||||
- cmdforge-data:/root/.cmdforge
|
||||
- /tmp/.X11-unix:/tmp/.X11-unix:ro
|
||||
command: ["/bin/bash"]
|
||||
stdin_open: true
|
||||
|
|
@ -69,8 +69,8 @@ services:
|
|||
network_mode: host
|
||||
|
||||
volumes:
|
||||
smarttools-data:
|
||||
# Persists ~/.smarttools between container runs
|
||||
cmdforge-data:
|
||||
# Persists ~/.cmdforge between container runs
|
||||
|
||||
# ==============================================================================
|
||||
# Usage Examples
|
||||
|
|
@ -83,8 +83,8 @@ volumes:
|
|||
# docker-compose run --rm test
|
||||
#
|
||||
# Use CLI:
|
||||
# docker-compose run --rm cli smarttools list
|
||||
# docker-compose run --rm cli smarttools run hello-world
|
||||
# docker-compose run --rm cli cmdforge list
|
||||
# docker-compose run --rm cli cmdforge run hello-world
|
||||
#
|
||||
# Interactive shell:
|
||||
# docker-compose run --rm shell
|
||||
|
|
@ -93,5 +93,5 @@ volumes:
|
|||
# xhost +local:docker
|
||||
# docker-compose run --rm setup
|
||||
# # Inside container:
|
||||
# smarttools providers install # Interactive guide
|
||||
# cmdforge providers install # Interactive guide
|
||||
# # Select a provider, it will install and open browser for auth
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
# SmartTools Deployment Guide
|
||||
# CmdForge Deployment Guide
|
||||
|
||||
This guide covers deploying the SmartTools Registry web application.
|
||||
This guide covers deploying the CmdForge Registry web application.
|
||||
|
||||
## Quick Start (Development)
|
||||
|
||||
```bash
|
||||
# Clone and install
|
||||
git clone https://gitea.brrd.tech/rob/SmartTools.git
|
||||
cd SmartTools
|
||||
git clone https://gitea.brrd.tech/rob/CmdForge.git
|
||||
cd CmdForge
|
||||
pip install -e ".[dev]"
|
||||
|
||||
# Initialize database
|
||||
cd src/smarttools/web
|
||||
cd src/cmdforge/web
|
||||
python -c "from app import create_app; create_app()"
|
||||
|
||||
# Run development server
|
||||
|
|
@ -33,12 +33,12 @@ Access at `http://localhost:5050`
|
|||
|
||||
```bash
|
||||
# Create application directory
|
||||
sudo mkdir -p /opt/smarttools
|
||||
sudo chown $USER:$USER /opt/smarttools
|
||||
cd /opt/smarttools
|
||||
sudo mkdir -p /opt/cmdforge
|
||||
sudo chown $USER:$USER /opt/cmdforge
|
||||
cd /opt/cmdforge
|
||||
|
||||
# Clone repository
|
||||
git clone https://gitea.brrd.tech/rob/SmartTools.git .
|
||||
git clone https://gitea.brrd.tech/rob/CmdForge.git .
|
||||
|
||||
# Create virtual environment
|
||||
python3 -m venv venv
|
||||
|
|
@ -51,7 +51,7 @@ pip install gunicorn
|
|||
|
||||
### 2. Configure Environment
|
||||
|
||||
Create `/opt/smarttools/.env`:
|
||||
Create `/opt/cmdforge/.env`:
|
||||
|
||||
```bash
|
||||
# Required
|
||||
|
|
@ -60,40 +60,40 @@ SECRET_KEY=your-secret-key-here # Generate with: python -c "import secrets; pri
|
|||
|
||||
# Optional
|
||||
SENTRY_DSN=https://xxx@sentry.io/xxx # Error monitoring
|
||||
SITE_URL=https://registry.smarttools.dev # For sitemap/SEO
|
||||
SITE_URL=https://cmdforge.brrd.tech # For sitemap/SEO
|
||||
```
|
||||
|
||||
### 3. Initialize Database
|
||||
|
||||
```bash
|
||||
cd /opt/smarttools/src/smarttools/web
|
||||
cd /opt/cmdforge/src/cmdforge/web
|
||||
python -c "from app import create_app; create_app()"
|
||||
```
|
||||
|
||||
Database will be created at `data/smarttools.db`.
|
||||
Database will be created at `data/cmdforge.db`.
|
||||
|
||||
### 4. systemd Service
|
||||
|
||||
Create `/etc/systemd/system/smarttools-web.service`:
|
||||
Create `/etc/systemd/system/cmdforge-web.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=SmartTools Registry Web Application
|
||||
Description=CmdForge Registry Web Application
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/opt/smarttools
|
||||
Environment="PATH=/opt/smarttools/venv/bin"
|
||||
EnvironmentFile=/opt/smarttools/.env
|
||||
ExecStart=/opt/smarttools/venv/bin/gunicorn \
|
||||
WorkingDirectory=/opt/cmdforge
|
||||
Environment="PATH=/opt/cmdforge/venv/bin"
|
||||
EnvironmentFile=/opt/cmdforge/.env
|
||||
ExecStart=/opt/cmdforge/venv/bin/gunicorn \
|
||||
--workers 4 \
|
||||
--bind 127.0.0.1:5050 \
|
||||
--access-logfile /var/log/smarttools/access.log \
|
||||
--error-logfile /var/log/smarttools/error.log \
|
||||
'smarttools.web.app:create_app()'
|
||||
--access-logfile /var/log/cmdforge/access.log \
|
||||
--error-logfile /var/log/cmdforge/error.log \
|
||||
'cmdforge.web.app:create_app()'
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
|
|
@ -105,26 +105,26 @@ Enable and start:
|
|||
|
||||
```bash
|
||||
# Create log directory
|
||||
sudo mkdir -p /var/log/smarttools
|
||||
sudo chown www-data:www-data /var/log/smarttools
|
||||
sudo mkdir -p /var/log/cmdforge
|
||||
sudo chown www-data:www-data /var/log/cmdforge
|
||||
|
||||
# Enable service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable smarttools-web
|
||||
sudo systemctl start smarttools-web
|
||||
sudo systemctl enable cmdforge-web
|
||||
sudo systemctl start cmdforge-web
|
||||
|
||||
# Check status
|
||||
sudo systemctl status smarttools-web
|
||||
sudo systemctl status cmdforge-web
|
||||
```
|
||||
|
||||
### 5. nginx Configuration
|
||||
|
||||
Create `/etc/nginx/sites-available/smarttools`:
|
||||
Create `/etc/nginx/sites-available/cmdforge`:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name registry.smarttools.dev;
|
||||
server_name cmdforge.brrd.tech;
|
||||
|
||||
# Redirect HTTP to HTTPS
|
||||
return 301 https://$server_name$request_uri;
|
||||
|
|
@ -132,11 +132,11 @@ server {
|
|||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name registry.smarttools.dev;
|
||||
server_name cmdforge.brrd.tech;
|
||||
|
||||
# SSL certificates (use certbot for Let's Encrypt)
|
||||
ssl_certificate /etc/letsencrypt/live/registry.smarttools.dev/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/registry.smarttools.dev/privkey.pem;
|
||||
ssl_certificate /etc/letsencrypt/live/cmdforge.brrd.tech/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/cmdforge.brrd.tech/privkey.pem;
|
||||
|
||||
# SSL settings
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
|
|
@ -145,7 +145,7 @@ server {
|
|||
|
||||
# Static files (optional - Flask can serve these)
|
||||
location /static/ {
|
||||
alias /opt/smarttools/src/smarttools/web/static/;
|
||||
alias /opt/cmdforge/src/cmdforge/web/static/;
|
||||
expires 1d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
|
@ -164,7 +164,7 @@ server {
|
|||
Enable site:
|
||||
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/smarttools /etc/nginx/sites-enabled/
|
||||
sudo ln -s /etc/nginx/sites-available/cmdforge /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
|
@ -173,7 +173,7 @@ sudo systemctl reload nginx
|
|||
|
||||
```bash
|
||||
sudo apt install certbot python3-certbot-nginx
|
||||
sudo certbot --nginx -d registry.smarttools.dev
|
||||
sudo certbot --nginx -d cmdforge.brrd.tech
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
|
@ -184,16 +184,16 @@ sudo certbot --nginx -d registry.smarttools.dev
|
|||
| `SECRET_KEY` | Yes | Secret key for sessions (32+ chars) |
|
||||
| `SENTRY_DSN` | No | Sentry error monitoring DSN |
|
||||
| `SITE_URL` | No | Public URL for sitemap generation |
|
||||
| `DATABASE_PATH` | No | Override database path (default: `data/smarttools.db`) |
|
||||
| `DATABASE_PATH` | No | Override database path (default: `data/cmdforge.db`) |
|
||||
|
||||
## Database Backup
|
||||
|
||||
```bash
|
||||
# Backup
|
||||
cp /opt/smarttools/data/smarttools.db /backup/smarttools-$(date +%Y%m%d).db
|
||||
cp /opt/cmdforge/data/cmdforge.db /backup/cmdforge-$(date +%Y%m%d).db
|
||||
|
||||
# Or use SQLite backup command for consistency
|
||||
sqlite3 /opt/smarttools/data/smarttools.db ".backup '/backup/smarttools.db'"
|
||||
sqlite3 /opt/cmdforge/data/cmdforge.db ".backup '/backup/cmdforge.db'"
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
|
@ -202,11 +202,11 @@ sqlite3 /opt/smarttools/data/smarttools.db ".backup '/backup/smarttools.db'"
|
|||
|
||||
```bash
|
||||
# Application logs
|
||||
tail -f /var/log/smarttools/error.log
|
||||
tail -f /var/log/smarttools/access.log
|
||||
tail -f /var/log/cmdforge/error.log
|
||||
tail -f /var/log/cmdforge/access.log
|
||||
|
||||
# systemd logs
|
||||
journalctl -u smarttools-web -f
|
||||
journalctl -u cmdforge-web -f
|
||||
```
|
||||
|
||||
### Sentry Integration
|
||||
|
|
@ -225,33 +225,33 @@ curl http://localhost:5050/api/v1/tools
|
|||
|
||||
```bash
|
||||
# Check logs
|
||||
journalctl -u smarttools-web -n 50
|
||||
journalctl -u cmdforge-web -n 50
|
||||
|
||||
# Verify Python path
|
||||
/opt/smarttools/venv/bin/python -c "import smarttools"
|
||||
/opt/cmdforge/venv/bin/python -c "import cmdforge"
|
||||
|
||||
# Test gunicorn manually
|
||||
cd /opt/smarttools
|
||||
cd /opt/cmdforge
|
||||
source venv/bin/activate
|
||||
gunicorn --bind 127.0.0.1:5050 'smarttools.web.app:create_app()'
|
||||
gunicorn --bind 127.0.0.1:5050 'cmdforge.web.app:create_app()'
|
||||
```
|
||||
|
||||
### Database errors
|
||||
|
||||
```bash
|
||||
# Check database exists and is readable
|
||||
ls -la /opt/smarttools/data/smarttools.db
|
||||
ls -la /opt/cmdforge/data/cmdforge.db
|
||||
|
||||
# Verify permissions
|
||||
chown www-data:www-data /opt/smarttools/data/
|
||||
chown www-data:www-data /opt/smarttools/data/smarttools.db
|
||||
chown www-data:www-data /opt/cmdforge/data/
|
||||
chown www-data:www-data /opt/cmdforge/data/cmdforge.db
|
||||
```
|
||||
|
||||
### Static files not loading
|
||||
|
||||
```bash
|
||||
# Rebuild Tailwind CSS
|
||||
cd /opt/smarttools
|
||||
cd /opt/cmdforge
|
||||
npm install
|
||||
npm run css:build
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# SmartTools - Design Document
|
||||
# CmdForge - Design Document
|
||||
|
||||
> A lightweight personal tool builder for AI-powered CLI commands
|
||||
|
||||
## Overview
|
||||
|
||||
SmartTools lets you create custom AI-powered terminal commands. You define a tool once (name, steps, provider), then use it like any Linux command.
|
||||
CmdForge lets you create custom AI-powered terminal commands. You define a tool once (name, steps, provider), then use it like any Linux command.
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
|
|
@ -17,7 +17,7 @@ sum -i text.txt -o summary.txt --max 512
|
|||
### Tool = Directory + Config
|
||||
|
||||
```
|
||||
~/.smarttools/
|
||||
~/.cmdforge/
|
||||
sum/
|
||||
config.yaml
|
||||
processed.py # Optional external code file
|
||||
|
|
@ -128,8 +128,8 @@ sum --stdin
|
|||
# No input (empty string) - useful for tools using only arguments
|
||||
sum --max 100
|
||||
|
||||
# Or via smarttools run
|
||||
smarttools run sum -i document.txt
|
||||
# Or via cmdforge run
|
||||
cmdforge run sum -i document.txt
|
||||
```
|
||||
|
||||
### Input Handling
|
||||
|
|
@ -158,17 +158,17 @@ smarttools run sum -i document.txt
|
|||
|
||||
```bash
|
||||
# Launch the UI to manage tools
|
||||
smarttools
|
||||
cmdforge
|
||||
|
||||
# Or use CLI directly:
|
||||
smarttools list # List all tools
|
||||
smarttools create sum # Create new tool (basic)
|
||||
smarttools edit sum # Edit tool config in $EDITOR
|
||||
smarttools delete sum # Delete tool
|
||||
smarttools test sum # Test with mock provider
|
||||
smarttools run sum # Run tool for real
|
||||
smarttools refresh # Refresh all wrapper scripts
|
||||
smarttools ui # Launch interactive UI
|
||||
cmdforge list # List all tools
|
||||
cmdforge create sum # Create new tool (basic)
|
||||
cmdforge edit sum # Edit tool config in $EDITOR
|
||||
cmdforge delete sum # Delete tool
|
||||
cmdforge test sum # Test with mock provider
|
||||
cmdforge run sum # Run tool for real
|
||||
cmdforge refresh # Refresh all wrapper scripts
|
||||
cmdforge ui # Launch interactive UI
|
||||
```
|
||||
|
||||
## Terminal UI
|
||||
|
|
@ -179,7 +179,7 @@ A BIOS-style terminal UI using `urwid` with full mouse support.
|
|||
|
||||
```
|
||||
┌──────────────────────────────────────┐
|
||||
│ SmartTools Manager │
|
||||
│ CmdForge Manager │
|
||||
├──────────────────────────────────────┤
|
||||
│ Tools: │
|
||||
│ ┌────────────────────────────────┐ │
|
||||
|
|
@ -256,7 +256,7 @@ The current section's title is highlighted with brackets: `[ Tool Info ]`
|
|||
|
||||
**Code Step Features:**
|
||||
- **Multiline editor** - Write multi-line Python code
|
||||
- **External file storage** - Code is auto-saved to `~/.smarttools/<toolname>/<filename>` on OK
|
||||
- **External file storage** - Code is auto-saved to `~/.cmdforge/<toolname>/<filename>` on OK
|
||||
- **Load button** - Load code from external file (with confirmation)
|
||||
- **Multiple output vars** - Capture multiple variables (comma-separated)
|
||||
|
||||
|
|
@ -265,7 +265,7 @@ The current section's title is highlighted with brackets: `[ Tool Info ]`
|
|||
### Directory Structure
|
||||
|
||||
```
|
||||
smarttools/
|
||||
cmdforge/
|
||||
__init__.py
|
||||
cli.py # Entry point, argument parsing
|
||||
ui.py # UI dispatcher (chooses urwid/snack/dialog)
|
||||
|
|
@ -278,7 +278,7 @@ smarttools/
|
|||
|
||||
### Provider System
|
||||
|
||||
Providers are defined in `~/.smarttools/providers.yaml`:
|
||||
Providers are defined in `~/.cmdforge/providers.yaml`:
|
||||
|
||||
```yaml
|
||||
providers:
|
||||
|
|
@ -297,18 +297,18 @@ The provider command receives the prompt via stdin and outputs to stdout.
|
|||
|
||||
### Wrapper Scripts
|
||||
|
||||
When you save a tool, SmartTools creates a wrapper script in `~/.local/bin/`:
|
||||
When you save a tool, CmdForge creates a wrapper script in `~/.local/bin/`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# SmartTools wrapper for 'sum'
|
||||
# CmdForge wrapper for 'sum'
|
||||
# Auto-generated - do not edit
|
||||
exec /path/to/python -m smarttools.runner sum "$@"
|
||||
exec /path/to/python -m cmdforge.runner sum "$@"
|
||||
```
|
||||
|
||||
The wrapper uses the full Python path to ensure the correct environment is used.
|
||||
|
||||
Use `smarttools refresh` to regenerate all wrapper scripts (e.g., after changing Python environments).
|
||||
Use `cmdforge refresh` to regenerate all wrapper scripts (e.g., after changing Python environments).
|
||||
|
||||
### Tool Name Validation
|
||||
|
||||
|
|
@ -319,12 +319,12 @@ Tool names must:
|
|||
|
||||
## Tool Composition
|
||||
|
||||
SmartTools are designed to chain together like any Unix command.
|
||||
CmdForge are designed to chain together like any Unix command.
|
||||
|
||||
### External Pipelines (Tool-to-Tool)
|
||||
|
||||
```bash
|
||||
# Chain multiple SmartTools
|
||||
# Chain multiple CmdForge
|
||||
cat logs.txt | log-errors | summarize | translate --lang Japanese
|
||||
|
||||
# Mix with standard Unix tools
|
||||
|
|
@ -389,7 +389,7 @@ Optional fallbacks:
|
|||
|
||||
## Example Workflow
|
||||
|
||||
1. Run `smarttools` to open UI
|
||||
1. Run `cmdforge` to open UI
|
||||
2. Select "Create" to create a new tool
|
||||
3. Fill in: name, description, output template
|
||||
4. Add arguments (e.g., `--max` with default `500`)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
# Example Tools
|
||||
|
||||
This document contains all 28 pre-built SmartTools with their full configurations.
|
||||
This document contains all 28 pre-built CmdForge with their full configurations.
|
||||
|
||||
## Quick Install
|
||||
|
||||
```bash
|
||||
# Install all example tools (from the SmartTools directory)
|
||||
# Install all example tools (from the CmdForge directory)
|
||||
python examples/install.py
|
||||
smarttools refresh
|
||||
cmdforge refresh
|
||||
```
|
||||
|
||||
## Text Processing Tools
|
||||
|
|
@ -17,7 +17,7 @@ smarttools refresh
|
|||
Condense long documents to key points.
|
||||
|
||||
```yaml
|
||||
# ~/.smarttools/summarize/config.yaml
|
||||
# ~/.cmdforge/summarize/config.yaml
|
||||
name: summarize
|
||||
description: Condense long documents to key points
|
||||
arguments:
|
||||
|
|
@ -963,7 +963,7 @@ output: "{result}"
|
|||
|
||||
## Pipeline Recipes
|
||||
|
||||
SmartTools chain together like Unix commands. Here are practical examples:
|
||||
CmdForge chain together like Unix commands. Here are practical examples:
|
||||
|
||||
### Development Workflows
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# Installation Guide
|
||||
|
||||
Complete installation instructions for SmartTools.
|
||||
Complete installation instructions for CmdForge.
|
||||
|
||||
## Quick Install
|
||||
|
||||
```bash
|
||||
git clone https://gitea.brrd.tech/rob/SmartTools.git
|
||||
cd SmartTools
|
||||
git clone https://gitea.brrd.tech/rob/CmdForge.git
|
||||
cd CmdForge
|
||||
pip install -e .
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
smarttools providers install
|
||||
cmdforge providers install
|
||||
```
|
||||
|
||||
## Detailed Installation
|
||||
|
|
@ -32,11 +32,11 @@ brew install python@3.11
|
|||
python3 --version # Should be 3.10 or higher
|
||||
```
|
||||
|
||||
### Step 2: Install SmartTools
|
||||
### Step 2: Install CmdForge
|
||||
|
||||
```bash
|
||||
git clone https://gitea.brrd.tech/rob/SmartTools.git
|
||||
cd SmartTools
|
||||
git clone https://gitea.brrd.tech/rob/CmdForge.git
|
||||
cd CmdForge
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ pip install -e ".[dev]"
|
|||
|
||||
### Step 3: Configure PATH
|
||||
|
||||
SmartTools creates executable wrappers in `~/.local/bin/`. Add this to your shell config:
|
||||
CmdForge creates executable wrappers in `~/.local/bin/`. Add this to your shell config:
|
||||
|
||||
**Bash (~/.bashrc):**
|
||||
```bash
|
||||
|
|
@ -74,7 +74,7 @@ source ~/.bashrc # or restart terminal
|
|||
You need at least one AI CLI tool. The easiest way is the interactive installer:
|
||||
|
||||
```bash
|
||||
smarttools providers install
|
||||
cmdforge providers install
|
||||
```
|
||||
|
||||
This guides you through installing and authenticating providers.
|
||||
|
|
@ -110,7 +110,7 @@ gemini # Opens browser for Google sign-in
|
|||
```bash
|
||||
curl -fsSL https://ollama.ai/install.sh | bash
|
||||
ollama pull llama3
|
||||
smarttools providers add ollama "ollama run llama3" -d "Local Llama 3"
|
||||
cmdforge providers add ollama "ollama run llama3" -d "Local Llama 3"
|
||||
```
|
||||
|
||||
See [PROVIDERS.md](PROVIDERS.md) for full provider setup instructions.
|
||||
|
|
@ -118,17 +118,17 @@ See [PROVIDERS.md](PROVIDERS.md) for full provider setup instructions.
|
|||
### Step 5: Verify Installation
|
||||
|
||||
```bash
|
||||
# Check SmartTools is installed
|
||||
smarttools --version
|
||||
# Check CmdForge is installed
|
||||
cmdforge --version
|
||||
|
||||
# List configured providers
|
||||
smarttools providers list
|
||||
cmdforge providers list
|
||||
|
||||
# Check which providers are available
|
||||
smarttools providers check
|
||||
cmdforge providers check
|
||||
|
||||
# Test with mock provider (no AI needed)
|
||||
echo "hello world" | smarttools run --provider mock
|
||||
echo "hello world" | cmdforge run --provider mock
|
||||
```
|
||||
|
||||
### Step 6: Create Wrapper Scripts
|
||||
|
|
@ -136,7 +136,7 @@ echo "hello world" | smarttools run --provider mock
|
|||
After installation or any Python environment change:
|
||||
|
||||
```bash
|
||||
smarttools refresh
|
||||
cmdforge refresh
|
||||
```
|
||||
|
||||
This creates executable scripts in `~/.local/bin/` for all your tools.
|
||||
|
|
@ -147,18 +147,18 @@ This creates executable scripts in `~/.local/bin/` for all your tools.
|
|||
|
||||
```bash
|
||||
python examples/install.py
|
||||
smarttools refresh
|
||||
cmdforge refresh
|
||||
```
|
||||
|
||||
### Manual Install
|
||||
|
||||
Copy individual tool configs to `~/.smarttools/<toolname>/config.yaml`.
|
||||
Copy individual tool configs to `~/.cmdforge/<toolname>/config.yaml`.
|
||||
|
||||
See [EXAMPLES.md](EXAMPLES.md) for all tool configurations.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "smarttools: command not found"
|
||||
### "cmdforge: command not found"
|
||||
|
||||
PATH is not configured. Add to your shell config:
|
||||
```bash
|
||||
|
|
@ -168,14 +168,14 @@ export PATH="$HOME/.local/bin:$PATH"
|
|||
### "Provider 'X' not found"
|
||||
|
||||
1. Check provider is installed: `which claude` or `which opencode`
|
||||
2. Check provider is configured: `smarttools providers`
|
||||
3. Add missing provider: `smarttools providers add`
|
||||
2. Check provider is configured: `cmdforge providers`
|
||||
3. Add missing provider: `cmdforge providers add`
|
||||
|
||||
### "Permission denied" on tool execution
|
||||
|
||||
Refresh wrapper scripts:
|
||||
```bash
|
||||
smarttools refresh
|
||||
cmdforge refresh
|
||||
```
|
||||
|
||||
### TUI doesn't start / looks broken
|
||||
|
|
@ -187,28 +187,28 @@ pip install urwid
|
|||
|
||||
Ensure your terminal supports mouse (most modern terminals do).
|
||||
|
||||
### Tools work with `smarttools run` but not directly
|
||||
### Tools work with `cmdforge run` but not directly
|
||||
|
||||
The wrapper scripts may be outdated. Refresh them:
|
||||
```bash
|
||||
smarttools refresh
|
||||
cmdforge refresh
|
||||
```
|
||||
|
||||
### Python version mismatch
|
||||
|
||||
If you have multiple Python versions, ensure SmartTools uses the right one:
|
||||
If you have multiple Python versions, ensure CmdForge uses the right one:
|
||||
```bash
|
||||
python3.11 -m pip install smarttools
|
||||
python3.11 -m pip install cmdforge
|
||||
```
|
||||
|
||||
## Uninstalling
|
||||
|
||||
```bash
|
||||
# Remove package
|
||||
pip uninstall smarttools
|
||||
pip uninstall cmdforge
|
||||
|
||||
# Remove config and tools (optional)
|
||||
rm -rf ~/.smarttools
|
||||
rm -rf ~/.cmdforge
|
||||
|
||||
# Remove wrapper scripts (optional)
|
||||
rm ~/.local/bin/{summarize,translate,fix-grammar,...}
|
||||
|
|
@ -217,8 +217,8 @@ rm ~/.local/bin/{summarize,translate,fix-grammar,...}
|
|||
## Upgrading
|
||||
|
||||
```bash
|
||||
pip install --upgrade smarttools
|
||||
smarttools refresh
|
||||
pip install --upgrade cmdforge
|
||||
cmdforge refresh
|
||||
```
|
||||
|
||||
## Directory Structure
|
||||
|
|
@ -226,7 +226,7 @@ smarttools refresh
|
|||
After installation:
|
||||
|
||||
```
|
||||
~/.smarttools/
|
||||
~/.cmdforge/
|
||||
├── providers.yaml # Provider configurations
|
||||
├── summarize/
|
||||
│ └── config.yaml # Tool config
|
||||
|
|
@ -236,7 +236,7 @@ After installation:
|
|||
└── ...
|
||||
|
||||
~/.local/bin/
|
||||
├── smarttools # Main command
|
||||
├── cmdforge # Main command
|
||||
├── summarize # Tool wrapper script
|
||||
├── translate # Tool wrapper script
|
||||
└── ...
|
||||
|
|
@ -246,4 +246,4 @@ After installation:
|
|||
|
||||
1. [Set up providers](PROVIDERS.md)
|
||||
2. [Browse example tools](EXAMPLES.md)
|
||||
3. Run `smarttools ui` to create your first tool
|
||||
3. Run `cmdforge ui` to create your first tool
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
# SmartTools Project Overview
|
||||
# CmdForge Project Overview
|
||||
|
||||
This document provides a comprehensive overview of the SmartTools project structure, components, and how everything fits together.
|
||||
This document provides a comprehensive overview of the CmdForge project structure, components, and how everything fits together.
|
||||
|
||||
## What is SmartTools?
|
||||
## What is CmdForge?
|
||||
|
||||
SmartTools is a personal tool builder for AI-powered CLI commands. It consists of three main components:
|
||||
CmdForge is a personal tool builder for AI-powered CLI commands. It consists of three main components:
|
||||
|
||||
1. **CLI Tool** (`smarttools`) - Create, manage, and run AI-powered command-line tools
|
||||
1. **CLI Tool** (`cmdforge`) - Create, manage, and run AI-powered command-line tools
|
||||
2. **Registry API** - REST API for publishing and discovering tools
|
||||
3. **Web UI** - Browser interface for the registry with docs, search, and user dashboard
|
||||
|
||||
|
|
@ -14,11 +14,11 @@ SmartTools is a personal tool builder for AI-powered CLI commands. It consists o
|
|||
|
||||
| Component | Location | Purpose |
|
||||
|-----------|----------|---------|
|
||||
| CLI | `src/smarttools/cli.py` | Main entry point for `smarttools` command |
|
||||
| Registry API | `src/smarttools/registry/` | REST API for tool registry |
|
||||
| Web UI | `src/smarttools/web/` | Flask web application |
|
||||
| Tool Storage | `~/.smarttools/` | User's installed tools |
|
||||
| Database | `data/smarttools.db` | SQLite with FTS5 search |
|
||||
| CLI | `src/cmdforge/cli.py` | Main entry point for `cmdforge` command |
|
||||
| Registry API | `src/cmdforge/registry/` | REST API for tool registry |
|
||||
| Web UI | `src/cmdforge/web/` | Flask web application |
|
||||
| Tool Storage | `~/.cmdforge/` | User's installed tools |
|
||||
| Database | `data/cmdforge.db` | SQLite with FTS5 search |
|
||||
|
||||
## Architecture Diagrams
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ See `docs/diagrams/` for visual representations:
|
|||
## Source Code Structure
|
||||
|
||||
```
|
||||
src/smarttools/
|
||||
src/cmdforge/
|
||||
├── cli.py # Entry point, subcommand routing
|
||||
├── tool.py # Tool dataclasses, YAML loading
|
||||
├── runner.py # Step execution engine
|
||||
|
|
@ -68,7 +68,7 @@ src/smarttools/
|
|||
|
||||
## Database Schema
|
||||
|
||||
SQLite database at `data/smarttools.db`:
|
||||
SQLite database at `data/cmdforge.db`:
|
||||
|
||||
| Table | Purpose |
|
||||
|-------|---------|
|
||||
|
|
@ -106,9 +106,9 @@ Base URL: `/api/v1/`
|
|||
## Key Files to Know
|
||||
|
||||
### Configuration
|
||||
- `~/.smarttools/providers.yaml` - AI provider configurations
|
||||
- `~/.smarttools/config.yaml` - Global settings
|
||||
- `~/.smarttools/<tool>/config.yaml` - Individual tool configs
|
||||
- `~/.cmdforge/providers.yaml` - AI provider configurations
|
||||
- `~/.cmdforge/config.yaml` - Global settings
|
||||
- `~/.cmdforge/<tool>/config.yaml` - Individual tool configs
|
||||
|
||||
### Development
|
||||
- `pyproject.toml` - Package configuration
|
||||
|
|
@ -130,10 +130,10 @@ Base URL: `/api/v1/`
|
|||
pip install -e ".[dev]"
|
||||
|
||||
# Run CLI
|
||||
python -m smarttools.cli
|
||||
python -m cmdforge.cli
|
||||
|
||||
# Run web server (development)
|
||||
cd src/smarttools/web
|
||||
cd src/cmdforge/web
|
||||
flask run --port 5050
|
||||
```
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ flask run --port 5050
|
|||
|
||||
```bash
|
||||
# Using gunicorn
|
||||
gunicorn -w 4 -b 0.0.0.0:5050 'smarttools.web.app:create_app()'
|
||||
gunicorn -w 4 -b 0.0.0.0:5050 'cmdforge.web.app:create_app()'
|
||||
|
||||
# Environment variables needed:
|
||||
# FLASK_ENV=production
|
||||
|
|
@ -164,7 +164,7 @@ pytest
|
|||
pytest tests/test_name.py::test_function
|
||||
|
||||
# Run with coverage
|
||||
pytest --cov=smarttools
|
||||
pytest --cov=cmdforge
|
||||
```
|
||||
|
||||
## Design Documents
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Provider Setup Guide
|
||||
|
||||
SmartTools works with any AI CLI tool that accepts input via stdin or arguments. This guide covers setup for the most popular providers.
|
||||
CmdForge works with any AI CLI tool that accepts input via stdin or arguments. This guide covers setup for the most popular providers.
|
||||
|
||||
## Provider Comparison
|
||||
|
||||
|
|
@ -139,7 +139,7 @@ echo "Hello" | gemini --model gemini-2.5-flash
|
|||
The easiest way to install providers:
|
||||
|
||||
```bash
|
||||
smarttools providers install
|
||||
cmdforge providers install
|
||||
```
|
||||
|
||||
This interactive guide:
|
||||
|
|
@ -151,22 +151,22 @@ This interactive guide:
|
|||
### List Providers
|
||||
|
||||
```bash
|
||||
smarttools providers list
|
||||
cmdforge providers list
|
||||
```
|
||||
|
||||
### Check Availability
|
||||
|
||||
```bash
|
||||
smarttools providers check
|
||||
cmdforge providers check
|
||||
```
|
||||
|
||||
### Add Custom Provider
|
||||
|
||||
```bash
|
||||
smarttools providers add myname "my-command --args" -d "Description"
|
||||
cmdforge providers add myname "my-command --args" -d "Description"
|
||||
```
|
||||
|
||||
Or edit `~/.smarttools/providers.yaml`:
|
||||
Or edit `~/.cmdforge/providers.yaml`:
|
||||
|
||||
```yaml
|
||||
providers:
|
||||
|
|
@ -242,9 +242,9 @@ cat file.txt | summarize --provider claude-opus
|
|||
|
||||
### "Provider 'X' not found"
|
||||
|
||||
1. Check it's in your providers list: `smarttools providers`
|
||||
1. Check it's in your providers list: `cmdforge providers`
|
||||
2. Verify the command works: `echo "test" | <command>`
|
||||
3. Add it: `smarttools providers add`
|
||||
3. Add it: `cmdforge providers add`
|
||||
|
||||
### "Command 'X' not found"
|
||||
|
||||
|
|
@ -273,8 +273,8 @@ echo "Say hello" | claude -p
|
|||
echo "Say hello" | ~/.opencode/bin/opencode run
|
||||
```
|
||||
|
||||
If it works directly but not in SmartTools, check:
|
||||
1. Provider command in `~/.smarttools/providers.yaml`
|
||||
If it works directly but not in CmdForge, check:
|
||||
1. Provider command in `~/.cmdforge/providers.yaml`
|
||||
2. Environment variables are expanded correctly
|
||||
|
||||
## Cost Optimization
|
||||
|
|
|
|||
170
docs/REGISTRY.md
170
docs/REGISTRY.md
|
|
@ -1,7 +1,7 @@
|
|||
# SmartTools Registry Design
|
||||
# CmdForge Registry Design
|
||||
|
||||
## Purpose
|
||||
Build a centralized registry for SmartTools to enable discovery, publishing, dependency management, and future curation at scale.
|
||||
Build a centralized registry for CmdForge to enable discovery, publishing, dependency management, and future curation at scale.
|
||||
|
||||
## Terminology
|
||||
|
||||
|
|
@ -9,20 +9,20 @@ Build a centralized registry for SmartTools to enable discovery, publishing, dep
|
|||
|------|------------|
|
||||
| **Tool definition** | The full YAML file in the registry (`config.yaml`) containing name, steps, arguments, etc. |
|
||||
| **Tool config** | The configuration within a tool definition (arguments, steps, provider settings) |
|
||||
| **smarttools.yaml** | Project manifest file declaring tool dependencies and overrides |
|
||||
| **cmdforge.yaml** | Project manifest file declaring tool dependencies and overrides |
|
||||
| **config.yaml** | The tool definition file, both in registry and when installed locally |
|
||||
| **Owner** | Immutable namespace slug identifying the publisher (e.g., `rob`, `alice`) |
|
||||
| **Publisher** | A registered user who can publish tools to the registry |
|
||||
| **Wrapper script** | Auto-generated bash script in `~/.local/bin/` that invokes a tool |
|
||||
|
||||
**Canonical naming:** Use `SmartTools-Registry` (capitalized, hyphenated) for the repository name.
|
||||
**Canonical naming:** Use `CmdForge-Registry` (capitalized, hyphenated) for the repository name.
|
||||
|
||||
## Diagram References
|
||||
- System overview: `discussions/diagrams/smarttools-registry_rob_1.puml`
|
||||
- Data flows: `discussions/diagrams/smarttools-registry_rob_5.puml`
|
||||
- System overview: `discussions/diagrams/cmdforge-registry_rob_1.puml`
|
||||
- Data flows: `discussions/diagrams/cmdforge-registry_rob_5.puml`
|
||||
|
||||
## System Overview
|
||||
Users interact via the CLI and a future Web UI. Both call a Registry API hosted at `https://gitea.brrd.tech/api/v1` (future alias: `registry.smarttools.dev/api/v1`). The API syncs from a Gitea-backed registry repo and maintains a SQLite cache/search index.
|
||||
Users interact via the CLI and a future Web UI. Both call a Registry API hosted at `https://gitea.brrd.tech/api/v1` (future alias: `cmdforge.brrd.tech/api/v1`). The API syncs from a Gitea-backed registry repo and maintains a SQLite cache/search index.
|
||||
|
||||
**Canonical API base path:** `https://gitea.brrd.tech/api/v1`
|
||||
|
||||
|
|
@ -166,7 +166,7 @@ tool = ToolSchema.parse(response['data']) # May fail on new fields
|
|||
|
||||
**Client version header:**
|
||||
```
|
||||
X-SmartTools-Client: cli/1.2.0
|
||||
X-CmdForge-Client: cli/1.2.0
|
||||
```
|
||||
Helps server track client versions for deprecation decisions.
|
||||
|
||||
|
|
@ -181,8 +181,8 @@ If the cache is stale, the API can fall back to repo reads; a warning header may
|
|||
Support owner/name from day one:
|
||||
- Registry path: `tools/{owner}/{name}/config.yaml`
|
||||
- API URL: `/tools/{owner}/{name}`
|
||||
- Install: `smarttools registry install rob/summarize`
|
||||
- Shorthand: `smarttools registry install summarize` resolves to the official namespace.
|
||||
- Install: `cmdforge registry install rob/summarize`
|
||||
- Shorthand: `cmdforge registry install summarize` resolves to the official namespace.
|
||||
|
||||
PR branches: `submit/{owner}/{name}/{version}`.
|
||||
|
||||
|
|
@ -227,7 +227,7 @@ tools/
|
|||
README.md
|
||||
```
|
||||
|
||||
Tool files match the existing SmartTools format. Registry-specific metadata is kept under `registry:`. Deprecation is tool-defined and top-level:
|
||||
Tool files match the existing CmdForge format. Registry-specific metadata is kept under `registry:`. Deprecation is tool-defined and top-level:
|
||||
```yaml
|
||||
name: summarize
|
||||
version: "1.2.0"
|
||||
|
|
@ -239,7 +239,7 @@ registry:
|
|||
downloads: 142
|
||||
```
|
||||
|
||||
**Schema compatibility note:** The current SmartTools config parser may reject unknown top-level keys like `deprecated`, `replacement`, and `registry`. Before implementing registry features:
|
||||
**Schema compatibility note:** The current CmdForge config parser may reject unknown top-level keys like `deprecated`, `replacement`, and `registry`. Before implementing registry features:
|
||||
1. Update the YAML parser to ignore unknown keys (permissive mode)
|
||||
2. Or explicitly define these fields in the Tool dataclass with defaults
|
||||
3. Validate registry-specific fields only when publishing, not when running locally
|
||||
|
|
@ -346,7 +346,7 @@ When resolving a version constraint:
|
|||
### Prerelease Handling
|
||||
|
||||
- Prereleases are **not** returned for `*` or range constraints by default
|
||||
- To install prerelease: `smarttools registry install rob/summarize@2.0.0-beta.1`
|
||||
- To install prerelease: `cmdforge registry install rob/summarize@2.0.0-beta.1`
|
||||
- To allow prereleases in manifest: `version: ">=2.0.0-0"` (the `-0` suffix includes prereleases)
|
||||
|
||||
### Download Endpoint Version Selection
|
||||
|
|
@ -401,14 +401,14 @@ Response (404):
|
|||
## Tool Resolution Order
|
||||
When a tool is invoked, the CLI searches in this order:
|
||||
|
||||
1. **Local project**: `./.smarttools/<owner>/<name>/config.yaml` (or `./.smarttools/<name>/` for unnamespaced)
|
||||
2. **Global user**: `~/.smarttools/<owner>/<name>/config.yaml`
|
||||
1. **Local project**: `./.cmdforge/<owner>/<name>/config.yaml` (or `./.cmdforge/<name>/` for unnamespaced)
|
||||
2. **Global user**: `~/.cmdforge/<owner>/<name>/config.yaml`
|
||||
3. **Registry**: Fetch from API, install to global, then run
|
||||
4. **Error**: `Tool '<toolname>' not found`
|
||||
|
||||
Step 3 only occurs if `auto_fetch_from_registry: true` in config (default: true).
|
||||
|
||||
**Path convention:** Use `.smarttools/` (with leading dot) for both local and global to maintain consistency.
|
||||
**Path convention:** Use `.cmdforge/` (with leading dot) for both local and global to maintain consistency.
|
||||
|
||||
Resolution also respects namespacing:
|
||||
- `summarize` → searches for any tool named `summarize`, prefers `official/summarize` if exists
|
||||
|
|
@ -422,7 +422,7 @@ The slug `official` is reserved for curated, high-quality tools maintained by th
|
|||
- If no `official/summarize`, falls back to most-downloaded tool named `summarize`
|
||||
- To avoid ambiguity, always use full `owner/name` in manifests
|
||||
|
||||
Reserved slugs that cannot be registered: `official`, `admin`, `system`, `api`, `registry`, `smarttools`
|
||||
Reserved slugs that cannot be registered: `official`, `admin`, `system`, `api`, `registry`, `cmdforge`
|
||||
|
||||
## Auto-Fetch Behavior
|
||||
When enabled (`auto_fetch_from_registry: true`), missing tools are automatically fetched:
|
||||
|
|
@ -436,14 +436,14 @@ $ summarize < file.txt
|
|||
```
|
||||
|
||||
Behavior details:
|
||||
- Fetches latest stable version unless pinned in `smarttools.yaml`
|
||||
- Installs to `~/.smarttools/<owner>/<name>/`
|
||||
- Fetches latest stable version unless pinned in `cmdforge.yaml`
|
||||
- Installs to `~/.cmdforge/<owner>/<name>/`
|
||||
- Generates wrapper script in `~/.local/bin/`
|
||||
- Subsequent runs use local copy (no re-fetch)
|
||||
|
||||
To disable (require explicit install):
|
||||
```yaml
|
||||
# ~/.smarttools/config.yaml
|
||||
# ~/.cmdforge/config.yaml
|
||||
auto_fetch_from_registry: false
|
||||
```
|
||||
|
||||
|
|
@ -467,11 +467,11 @@ summarize < file.txt
|
|||
# Explicit owner form (always works)
|
||||
rob-summarize < file.txt
|
||||
|
||||
# Or via smarttools run
|
||||
smarttools run rob/summarize < file.txt
|
||||
# Or via cmdforge run
|
||||
cmdforge run rob/summarize < file.txt
|
||||
```
|
||||
|
||||
## Project Manifest (smarttools.yaml)
|
||||
## Project Manifest (cmdforge.yaml)
|
||||
Defines tool dependencies with optional runtime overrides:
|
||||
```
|
||||
name: my-ai-project
|
||||
|
|
@ -487,7 +487,7 @@ overrides:
|
|||
Overrides are applied at runtime and do not mutate installed tool configs.
|
||||
|
||||
## CLI Config and Tokens
|
||||
Global config lives in `~/.smarttools/config.yaml`:
|
||||
Global config lives in `~/.cmdforge/config.yaml`:
|
||||
```yaml
|
||||
registry:
|
||||
url: https://gitea.brrd.tech/api/v1 # Must match canonical base path
|
||||
|
|
@ -540,7 +540,7 @@ Publishing uses registry accounts, not Gitea accounts:
|
|||
**Update flow (new version, not overwrite):**
|
||||
1. Developer modifies tool locally
|
||||
2. Bumps version in `config.yaml` (e.g., `1.2.0` → `1.3.0`)
|
||||
3. Runs `smarttools registry publish`
|
||||
3. Runs `cmdforge registry publish`
|
||||
4. New PR created for `1.3.0`
|
||||
5. Old version `1.2.0` remains available
|
||||
|
||||
|
|
@ -548,7 +548,7 @@ Publishing uses registry accounts, not Gitea accounts:
|
|||
Publishers register on the registry website, not Gitea:
|
||||
|
||||
**Registration flow:**
|
||||
1. User visits `https://gitea.brrd.tech/registry/register` (or future `registry.smarttools.dev`)
|
||||
1. User visits `https://gitea.brrd.tech/registry/register` (or future `cmdforge.brrd.tech`)
|
||||
2. Creates account with email + password + slug
|
||||
3. Receives verification email (optional in v1, but track `verified` status)
|
||||
4. Logs into dashboard at `/dashboard`
|
||||
|
|
@ -690,7 +690,7 @@ Dashboard login uses session cookies (not tokens) for browser auth:
|
|||
|
||||
**Cookie settings:**
|
||||
```python
|
||||
SESSION_COOKIE_NAME = 'smarttools_session'
|
||||
SESSION_COOKIE_NAME = 'cmdforge_session'
|
||||
SESSION_COOKIE_HTTPONLY = True # Prevent JS access
|
||||
SESSION_COOKIE_SECURE = True # HTTPS only in production
|
||||
SESSION_COOKIE_SAMESITE = 'Lax' # CSRF protection
|
||||
|
|
@ -844,7 +844,7 @@ CREATE TABLE tool_tags (
|
|||
|
||||
**CLI first-time publish flow:**
|
||||
```bash
|
||||
$ smarttools registry publish
|
||||
$ cmdforge registry publish
|
||||
|
||||
No registry account configured.
|
||||
|
||||
|
|
@ -853,7 +853,7 @@ No registry account configured.
|
|||
3. Enter your token below
|
||||
|
||||
Registry token: ********
|
||||
Token saved to ~/.smarttools/config.yaml
|
||||
Token saved to ~/.cmdforge/config.yaml
|
||||
|
||||
Validating tool...
|
||||
✓ config.yaml is valid
|
||||
|
|
@ -861,7 +861,7 @@ Validating tool...
|
|||
✓ Version 1.0.0 not yet published
|
||||
|
||||
Publishing rob/my-tool@1.0.0...
|
||||
✓ PR created: https://gitea.brrd.tech/rob/SmartTools-Registry/pulls/42
|
||||
✓ PR created: https://gitea.brrd.tech/rob/CmdForge-Registry/pulls/42
|
||||
|
||||
Your tool is pending review. You'll receive an email when it's approved.
|
||||
```
|
||||
|
|
@ -873,67 +873,67 @@ Full mapping of CLI commands to API calls:
|
|||
|
||||
```bash
|
||||
# Search for tools
|
||||
$ smarttools registry search <query> [--category=<cat>] [--limit=20]
|
||||
$ cmdforge registry search <query> [--category=<cat>] [--limit=20]
|
||||
→ GET /api/v1/tools/search?q=<query>&category=<cat>&limit=20
|
||||
|
||||
# Browse tools (TUI)
|
||||
$ smarttools registry browse [--category=<cat>]
|
||||
$ cmdforge registry browse [--category=<cat>]
|
||||
→ GET /api/v1/tools?category=<cat>&page=1
|
||||
→ GET /api/v1/categories
|
||||
|
||||
# View tool details
|
||||
$ smarttools registry info <owner/name>
|
||||
$ cmdforge registry info <owner/name>
|
||||
→ GET /api/v1/tools/<owner>/<name>
|
||||
|
||||
# Install a tool
|
||||
$ smarttools registry install <owner/name> [--version=<ver>]
|
||||
$ cmdforge registry install <owner/name> [--version=<ver>]
|
||||
→ GET /api/v1/tools/<owner>/<name>/download?version=<ver>&install=true
|
||||
→ Writes to ~/.smarttools/<owner>/<name>/config.yaml
|
||||
→ Writes to ~/.cmdforge/<owner>/<name>/config.yaml
|
||||
→ Generates ~/.local/bin/<name> wrapper (or <owner>-<name> if collision)
|
||||
|
||||
# Uninstall a tool
|
||||
$ smarttools registry uninstall <owner/name>
|
||||
→ Removes ~/.smarttools/<owner>/<name>/
|
||||
$ cmdforge registry uninstall <owner/name>
|
||||
→ Removes ~/.cmdforge/<owner>/<name>/
|
||||
→ Removes wrapper script
|
||||
|
||||
# Publish a tool
|
||||
$ smarttools registry publish [path] [--dry-run]
|
||||
$ cmdforge registry publish [path] [--dry-run]
|
||||
→ POST /api/v1/tools (with registry token)
|
||||
→ Returns PR URL
|
||||
|
||||
# List my published tools
|
||||
$ smarttools registry my-tools
|
||||
$ cmdforge registry my-tools
|
||||
→ GET /api/v1/me/tools (with registry token)
|
||||
|
||||
# Update index cache
|
||||
$ smarttools registry update
|
||||
$ cmdforge registry update
|
||||
→ GET /api/v1/index.json
|
||||
→ Writes to ~/.smarttools/registry/index.json
|
||||
→ Writes to ~/.cmdforge/registry/index.json
|
||||
```
|
||||
|
||||
### Project Commands
|
||||
|
||||
```bash
|
||||
# Install project dependencies from smarttools.yaml
|
||||
$ smarttools install
|
||||
→ Reads ./smarttools.yaml
|
||||
# Install project dependencies from cmdforge.yaml
|
||||
$ cmdforge install
|
||||
→ Reads ./cmdforge.yaml
|
||||
→ For each dependency:
|
||||
GET /api/v1/tools/<owner>/<name>/download?version=<constraint>&install=true
|
||||
→ Installs to ~/.smarttools/<owner>/<name>/
|
||||
→ Installs to ~/.cmdforge/<owner>/<name>/
|
||||
|
||||
# Add a dependency to smarttools.yaml
|
||||
$ smarttools add <owner/name> [--version=<constraint>]
|
||||
→ Adds to ./smarttools.yaml dependencies
|
||||
# Add a dependency to cmdforge.yaml
|
||||
$ cmdforge add <owner/name> [--version=<constraint>]
|
||||
→ Adds to ./cmdforge.yaml dependencies
|
||||
→ Runs install for that tool
|
||||
|
||||
# Show project dependencies status
|
||||
$ smarttools deps
|
||||
→ Reads ./smarttools.yaml
|
||||
$ cmdforge deps
|
||||
→ Reads ./cmdforge.yaml
|
||||
→ Shows installed status for each dependency
|
||||
→ Note: "smarttools list" is reserved for listing installed tools
|
||||
→ Note: "cmdforge list" is reserved for listing installed tools
|
||||
```
|
||||
|
||||
**Command naming note:** `smarttools list` already exists to list locally installed tools. Use `smarttools deps` to show project manifest dependencies.
|
||||
**Command naming note:** `cmdforge list` already exists to list locally installed tools. Use `cmdforge deps` to show project manifest dependencies.
|
||||
|
||||
### Flags available on most commands
|
||||
|
||||
|
|
@ -1081,7 +1081,7 @@ def sync_from_repo_atomic():
|
|||
| Lock timeout | Skip this sync, next webhook will retry |
|
||||
|
||||
## Automated CI Validation
|
||||
PRs are validated automatically using SmartTools (dogfooding):
|
||||
PRs are validated automatically using CmdForge (dogfooding):
|
||||
|
||||
```
|
||||
PR Submitted
|
||||
|
|
@ -1121,16 +1121,16 @@ jobs:
|
|||
- name: Validate schema
|
||||
run: python scripts/validate_tool.py ${{ github.event.pull_request.head.sha }}
|
||||
- name: Security scan
|
||||
run: smarttools run security-scanner < changed_files.txt
|
||||
run: cmdforge run security-scanner < changed_files.txt
|
||||
- name: Check duplicates
|
||||
run: smarttools run duplicate-detector < changed_files.txt
|
||||
run: cmdforge run duplicate-detector < changed_files.txt
|
||||
```
|
||||
|
||||
## Registry Repository Structure
|
||||
Full structure of the SmartTools-Registry repo:
|
||||
Full structure of the CmdForge-Registry repo:
|
||||
|
||||
```
|
||||
SmartTools-Registry/
|
||||
CmdForge-Registry/
|
||||
├── README.md # Registry overview
|
||||
├── CONTRIBUTING.md # How to submit tools
|
||||
├── LICENSE
|
||||
|
|
@ -1236,7 +1236,7 @@ CLI generates a persistent anonymous ID on first run:
|
|||
import uuid
|
||||
import os
|
||||
|
||||
CONFIG_PATH = os.path.expanduser("~/.smarttools/config.yaml")
|
||||
CONFIG_PATH = os.path.expanduser("~/.cmdforge/config.yaml")
|
||||
|
||||
def get_or_create_client_id():
|
||||
config = load_config()
|
||||
|
|
@ -1424,7 +1424,7 @@ def search_tools(q):
|
|||
"name": "bar",
|
||||
"suggestion": "Did you mean 'rob/bar'?"
|
||||
},
|
||||
"docs_url": "https://registry.smarttools.dev/docs/errors#TOOL_NOT_FOUND"
|
||||
"docs_url": "https://cmdforge.brrd.tech/docs/errors#TOOL_NOT_FOUND"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -1482,17 +1482,17 @@ When `VALIDATION_ERROR` occurs, provide specific field errors:
|
|||
}
|
||||
]
|
||||
},
|
||||
"docs_url": "https://registry.smarttools.dev/docs/tool-format"
|
||||
"docs_url": "https://cmdforge.brrd.tech/docs/tool-format"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Dependency Resolution Failures
|
||||
|
||||
When `smarttools install` fails on a manifest:
|
||||
When `cmdforge install` fails on a manifest:
|
||||
|
||||
```bash
|
||||
$ smarttools install
|
||||
$ cmdforge install
|
||||
|
||||
Error: Could not resolve all dependencies
|
||||
|
||||
|
|
@ -1511,7 +1511,7 @@ Suggestions:
|
|||
|
||||
| Component Down | Fallback Behavior |
|
||||
|----------------|-------------------|
|
||||
| API server | CLI uses `~/.smarttools/registry/index.json` for search |
|
||||
| API server | CLI uses `~/.cmdforge/registry/index.json` for search |
|
||||
| Gitea repo | API serves from DB cache (may be stale) |
|
||||
| FTS5 index | Fall back to LIKE queries (slower but works) |
|
||||
| Network | Use locally installed tools, skip registry features |
|
||||
|
|
@ -1520,9 +1520,9 @@ Suggestions:
|
|||
|
||||
### Publishing UX
|
||||
|
||||
- `smarttools registry publish --dry-run` validates locally and shows what would be submitted:
|
||||
- `cmdforge registry publish --dry-run` validates locally and shows what would be submitted:
|
||||
```bash
|
||||
$ smarttools registry publish --dry-run
|
||||
$ cmdforge registry publish --dry-run
|
||||
|
||||
Validating tool...
|
||||
✓ config.yaml is valid
|
||||
|
|
@ -1559,7 +1559,7 @@ Suggestions:
|
|||
Long-running operations show progress:
|
||||
|
||||
```bash
|
||||
$ smarttools install
|
||||
$ cmdforge install
|
||||
|
||||
Installing project dependencies...
|
||||
[1/3] rob/summarize@^1.0.0
|
||||
|
|
@ -1579,24 +1579,24 @@ Installing project dependencies...
|
|||
```
|
||||
|
||||
```bash
|
||||
$ smarttools registry publish
|
||||
$ cmdforge registry publish
|
||||
|
||||
Submitting rob/summarize@1.1.0...
|
||||
Validating... done ✓
|
||||
Uploading... done ✓
|
||||
Creating PR... done ✓
|
||||
|
||||
✓ PR created: https://gitea.brrd.tech/rob/SmartTools-Registry/pulls/42
|
||||
✓ PR created: https://gitea.brrd.tech/rob/CmdForge-Registry/pulls/42
|
||||
|
||||
Your tool is pending review. You'll receive an email when it's approved.
|
||||
```
|
||||
|
||||
### TUI Browse
|
||||
|
||||
`smarttools registry browse` opens a full-screen terminal UI:
|
||||
`cmdforge registry browse` opens a full-screen terminal UI:
|
||||
|
||||
```
|
||||
┌─ SmartTools Registry ───────────────────────────────────────┐
|
||||
┌─ CmdForge Registry ───────────────────────────────────────┐
|
||||
│ Search: [________________] [All Categories ▼] [Sort: Popular ▼] │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
|
|
@ -1634,9 +1634,9 @@ Your tool is pending review. You'll receive an email when it's approved.
|
|||
### Project Initialization
|
||||
|
||||
```bash
|
||||
$ smarttools init
|
||||
$ cmdforge init
|
||||
|
||||
Creating smarttools.yaml...
|
||||
Creating cmdforge.yaml...
|
||||
|
||||
Project name [my-project]: my-ai-project
|
||||
Version [1.0.0]:
|
||||
|
|
@ -1652,7 +1652,7 @@ Added rob/summarize@^1.2.0
|
|||
|
||||
Add tool (number, or Enter to finish):
|
||||
|
||||
✓ Created smarttools.yaml
|
||||
✓ Created cmdforge.yaml
|
||||
|
||||
name: my-ai-project
|
||||
version: "1.0.0"
|
||||
|
|
@ -1660,7 +1660,7 @@ dependencies:
|
|||
- name: rob/summarize
|
||||
version: "^1.2.0"
|
||||
|
||||
Run 'smarttools install' to install dependencies.
|
||||
Run 'cmdforge install' to install dependencies.
|
||||
```
|
||||
|
||||
### Accessibility
|
||||
|
|
@ -1676,7 +1676,7 @@ Run 'smarttools install' to install dependencies.
|
|||
## Offline Cache
|
||||
Cache registry index locally:
|
||||
```
|
||||
~/.smarttools/registry/index.json
|
||||
~/.cmdforge/registry/index.json
|
||||
```
|
||||
Refresh when older than 24 hours; support `--offline` and `--refresh` flags.
|
||||
|
||||
|
|
@ -1730,7 +1730,7 @@ The registry includes a full website, not just an API:
|
|||
|
||||
**Site structure:**
|
||||
```
|
||||
registry.smarttools.dev (or gitea.brrd.tech/registry)
|
||||
cmdforge.brrd.tech (or gitea.brrd.tech/registry)
|
||||
├── / # Landing page
|
||||
├── /tools # Browse all tools
|
||||
├── /tools/{owner}/{name} # Tool detail page
|
||||
|
|
@ -1843,9 +1843,9 @@ def render_readme_safe(readme_raw: str) -> str:
|
|||
## Implementation Phases
|
||||
|
||||
### Phase 1: Foundation
|
||||
- Define `smarttools.yaml` manifest format
|
||||
- Define `cmdforge.yaml` manifest format
|
||||
- Implement tool resolution order (local → global → registry)
|
||||
- Create SmartTools-Registry repo on Gitea (bootstrap)
|
||||
- Create CmdForge-Registry repo on Gitea (bootstrap)
|
||||
- Add 3-5 example tools to seed the registry
|
||||
|
||||
### Phase 2: Core Backend
|
||||
|
|
@ -1856,22 +1856,22 @@ def render_readme_safe(readme_raw: str) -> str:
|
|||
- Set up HMAC verification
|
||||
|
||||
### Phase 3: CLI Commands
|
||||
- `smarttools registry search`
|
||||
- `smarttools registry install`
|
||||
- `smarttools registry info`
|
||||
- `smarttools registry browse` (TUI)
|
||||
- `cmdforge registry search`
|
||||
- `cmdforge registry install`
|
||||
- `cmdforge registry info`
|
||||
- `cmdforge registry browse` (TUI)
|
||||
- Local index caching
|
||||
|
||||
### Phase 4: Publishing
|
||||
- Publisher registration (web UI)
|
||||
- Token management
|
||||
- `smarttools registry publish` command
|
||||
- `cmdforge registry publish` command
|
||||
- PR creation via Gitea API
|
||||
- CI validation workflows
|
||||
|
||||
### Phase 5: Project Dependencies
|
||||
- `smarttools install` (from manifest)
|
||||
- `smarttools add` command
|
||||
- `cmdforge install` (from manifest)
|
||||
- `cmdforge add` command
|
||||
- Runtime override application
|
||||
- Dependency resolution
|
||||
|
||||
|
|
|
|||
128
docs/WEB_UI.md
128
docs/WEB_UI.md
|
|
@ -1,10 +1,10 @@
|
|||
# SmartTools Web UI Design
|
||||
# CmdForge Web UI Design
|
||||
|
||||
## Purpose
|
||||
Deliver a professional web front-end that explains SmartTools, helps users discover tools, and supports a collaborative ecosystem. The site should drive sustainable revenue without undermining trust or usability.
|
||||
Deliver a professional web front-end that explains CmdForge, helps users discover tools, and supports a collaborative ecosystem. The site should drive sustainable revenue without undermining trust or usability.
|
||||
|
||||
## Mission Alignment
|
||||
This web UI serves the broader SmartTools mission: to provide a **universally accessible development ecosystem** that empowers regular people to collaborate and build upon each other's progress rather than compete. Revenue generated supports:
|
||||
This web UI serves the broader CmdForge mission: to provide a **universally accessible development ecosystem** that empowers regular people to collaborate and build upon each other's progress rather than compete. Revenue generated supports:
|
||||
- Maintaining and expanding the project
|
||||
- Future hosting of AI models for users with less access to paid services
|
||||
- Building a sustainable, community-first platform
|
||||
|
|
@ -131,14 +131,14 @@ Use an 8px base grid for consistent spacing:
|
|||
|
||||
### Landing Page (`/`)
|
||||
|
||||
**Purpose:** Convert visitors to users by clearly communicating SmartTools' value proposition and providing immediate paths to explore.
|
||||
**Purpose:** Convert visitors to users by clearly communicating CmdForge' value proposition and providing immediate paths to explore.
|
||||
|
||||
**Reference mockup:** `discussions/diagrams/smarttools-registry_rob_6.svg`
|
||||
**Reference mockup:** `discussions/diagrams/cmdforge-registry_rob_6.svg`
|
||||
|
||||
#### Section 1: Hero (Above the Fold)
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ [SmartTools] Docs Tutorials Registry Community About 🔍 │
|
||||
│ [CmdForge] Docs Tutorials Registry Community About 🔍 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Build Custom AI Commands in YAML │
|
||||
|
|
@ -147,7 +147,7 @@ Use an 8px base grid for consistent spacing:
|
|||
│ provider. Provider-agnostic and composable. │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────┐ │
|
||||
│ │ $ pip install smarttools && smarttools init │ [📋]│
|
||||
│ │ $ pip install cmdforge && cmdforge init │ [📋]│
|
||||
│ └──────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ [Get Started] [View Tutorials] │
|
||||
|
|
@ -158,7 +158,7 @@ Use an 8px base grid for consistent spacing:
|
|||
**Content:**
|
||||
- **Headline:** "Build Custom AI Commands in YAML" (benefit-focused, differentiating)
|
||||
- **Subheadline:** "Create Unix-style pipeable tools that work with any AI provider. Provider-agnostic and composable for ultimate flexibility."
|
||||
- **Install snippet:** `pip install smarttools && smarttools init` with copy button
|
||||
- **Install snippet:** `pip install cmdforge && cmdforge init` with copy button
|
||||
- **Primary CTA:** "Get Started" → links to `/docs/getting-started` (indigo background)
|
||||
- **Secondary CTA:** "View Tutorials" → links to `/tutorials` (outlined, cyan border)
|
||||
|
||||
|
|
@ -167,10 +167,10 @@ Use an 8px base grid for consistent spacing:
|
|||
- Maximum content width: 1100px centered
|
||||
- Install snippet: monospace font, light gray background (#E0E0E0), copy icon on right
|
||||
|
||||
#### Section 2: Three Pillars (Why SmartTools?)
|
||||
#### Section 2: Three Pillars (Why CmdForge?)
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Why SmartTools? │
|
||||
│ Why CmdForge? │
|
||||
├──────────────────┬──────────────────┬────────────────────────────┤
|
||||
│ [✓] Easy │ [⚡] Powerful │ [👥] Community │
|
||||
│ │ │ │
|
||||
|
|
@ -267,7 +267,7 @@ Use an 8px base grid for consistent spacing:
|
|||
#### Section 6: Footer Ad Zone (Optional)
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ [Advertisement: Support SmartTools Development] │
|
||||
│ [Advertisement: Support CmdForge Development] │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
|
|
@ -279,12 +279,12 @@ Use an 8px base grid for consistent spacing:
|
|||
#### Section 7: Footer
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SmartTools │
|
||||
│ CmdForge │
|
||||
│ ───────────────────────────────────────────────────────────── │
|
||||
│ Docs | Registry | Community | About | Donate │
|
||||
│ Privacy | Terms | GitHub | Twitter │
|
||||
│ │
|
||||
│ © 2025 SmartTools. Open source under MIT License. │
|
||||
│ © 2025 CmdForge. Open source under MIT License. │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
|
|
@ -511,7 +511,7 @@ Use an 8px base grid for consistent spacing:
|
|||
│ ⬇ 1,234 downloads │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ smarttools run owner/tool │ │
|
||||
│ │ cmdforge run owner/tool │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
└───────────────────────────────────────┘
|
||||
```
|
||||
|
|
@ -637,7 +637,7 @@ Registry > owner > tool-name > v1.2.0
|
|||
|
||||
**Inline Code:**
|
||||
```html
|
||||
<code>smarttools run foo</code>
|
||||
<code>cmdforge run foo</code>
|
||||
```
|
||||
- Background: Light gray (#F3F4F6)
|
||||
- Font: Monospace
|
||||
|
|
@ -1011,14 +1011,14 @@ Publisher dashboard uses auth endpoints:
|
|||
|
||||
Landing page:
|
||||
```html
|
||||
<title>SmartTools - Build Custom AI Commands in YAML</title>
|
||||
<title>CmdForge - Build Custom AI Commands in YAML</title>
|
||||
<meta name="description" content="Create Unix-style pipeable tools that work with any AI provider. Provider-agnostic, composable, and community-driven.">
|
||||
<meta name="keywords" content="ai cli tools, yaml automation, ai commands, smarttools">
|
||||
<meta name="keywords" content="ai cli tools, yaml automation, ai commands, cmdforge">
|
||||
```
|
||||
|
||||
Tool detail page:
|
||||
```html
|
||||
<title>{tool-name} by {owner} - SmartTools Registry</title>
|
||||
<title>{tool-name} by {owner} - CmdForge Registry</title>
|
||||
<meta name="description" content="{tool description, max 160 chars}">
|
||||
```
|
||||
|
||||
|
|
@ -1036,7 +1036,7 @@ Tool detail page:
|
|||
"@type": "Person",
|
||||
"name": "owner-name"
|
||||
},
|
||||
"downloadUrl": "https://registry.smarttools.dev/tools/owner/summarize",
|
||||
"downloadUrl": "https://cmdforge.brrd.tech/tools/owner/summarize",
|
||||
"softwareVersion": "1.2.0",
|
||||
"aggregateRating": {
|
||||
"@type": "AggregateRating",
|
||||
|
|
@ -1051,12 +1051,12 @@ Tool detail page:
|
|||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "SmartTools",
|
||||
"url": "https://smarttools.dev",
|
||||
"logo": "https://smarttools.dev/logo.png",
|
||||
"name": "CmdForge",
|
||||
"url": "https://cmdforge.dev",
|
||||
"logo": "https://cmdforge.dev/logo.png",
|
||||
"sameAs": [
|
||||
"https://github.com/your-org/smarttools",
|
||||
"https://twitter.com/smarttools"
|
||||
"https://github.com/your-org/cmdforge",
|
||||
"https://twitter.com/cmdforge"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
|
@ -1066,7 +1066,7 @@ Tool detail page:
|
|||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "TechArticle",
|
||||
"headline": "Getting Started with SmartTools",
|
||||
"headline": "Getting Started with CmdForge",
|
||||
"author": {"@type": "Person", "name": "Author Name"},
|
||||
"datePublished": "2025-01-15",
|
||||
"dateModified": "2025-01-20"
|
||||
|
|
@ -1077,18 +1077,18 @@ Tool detail page:
|
|||
|
||||
```html
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:title" content="SmartTools - AI CLI Tools">
|
||||
<meta property="og:title" content="CmdForge - AI CLI Tools">
|
||||
<meta property="og:description" content="Build custom AI commands...">
|
||||
<meta property="og:image" content="https://smarttools.dev/og-image.png">
|
||||
<meta property="og:url" content="https://smarttools.dev">
|
||||
<meta property="og:image" content="https://cmdforge.dev/og-image.png">
|
||||
<meta property="og:url" content="https://cmdforge.dev">
|
||||
<meta property="og:type" content="website">
|
||||
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:site" content="@smarttools">
|
||||
<meta name="twitter:title" content="SmartTools">
|
||||
<meta name="twitter:site" content="@cmdforge">
|
||||
<meta name="twitter:title" content="CmdForge">
|
||||
<meta name="twitter:description" content="Build custom AI commands...">
|
||||
<meta name="twitter:image" content="https://smarttools.dev/twitter-card.png">
|
||||
<meta name="twitter:image" content="https://cmdforge.dev/twitter-card.png">
|
||||
```
|
||||
|
||||
### Sitemap
|
||||
|
|
@ -1104,12 +1104,12 @@ Auto-generate `sitemap.xml`:
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://smarttools.dev/</loc>
|
||||
<loc>https://cmdforge.dev/</loc>
|
||||
<priority>1.0</priority>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://smarttools.dev/tools</loc>
|
||||
<loc>https://cmdforge.dev/tools</loc>
|
||||
<priority>0.9</priority>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
|
|
@ -1129,7 +1129,7 @@ Disallow: /register
|
|||
Disallow: /dashboard
|
||||
Disallow: /api/
|
||||
|
||||
Sitemap: https://smarttools.dev/sitemap.xml
|
||||
Sitemap: https://cmdforge.dev/sitemap.xml
|
||||
```
|
||||
|
||||
### Canonical URLs
|
||||
|
|
@ -1297,11 +1297,11 @@ The web UI consumes these existing API endpoints:
|
|||
|
||||
## Diagram References
|
||||
|
||||
- Landing page mockup: `discussions/diagrams/smarttools-registry_rob_6.svg`
|
||||
- System overview: `discussions/diagrams/smarttools-registry_rob_1.puml`
|
||||
- Data flows: `discussions/diagrams/smarttools-registry_rob_5.puml`
|
||||
- Web UI strategy: `discussions/diagrams/smarttools-web-ui-strategy.puml`
|
||||
- UI visual strategy: `discussions/diagrams/smarttools-web-ui-visual-strategy.puml`
|
||||
- Landing page mockup: `discussions/diagrams/cmdforge-registry_rob_6.svg`
|
||||
- System overview: `discussions/diagrams/cmdforge-registry_rob_1.puml`
|
||||
- Data flows: `discussions/diagrams/cmdforge-registry_rob_5.puml`
|
||||
- Web UI strategy: `discussions/diagrams/cmdforge-web-ui-strategy.puml`
|
||||
- UI visual strategy: `discussions/diagrams/cmdforge-web-ui-visual-strategy.puml`
|
||||
|
||||
## Deployment Guide
|
||||
|
||||
|
|
@ -1315,8 +1315,8 @@ The web UI consumes these existing API endpoints:
|
|||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://gitea.brrd.tech/rob/SmartTools.git
|
||||
cd SmartTools
|
||||
git clone https://gitea.brrd.tech/rob/CmdForge.git
|
||||
cd CmdForge
|
||||
|
||||
# Create virtual environment
|
||||
python3 -m venv venv
|
||||
|
|
@ -1326,7 +1326,7 @@ source venv/bin/activate
|
|||
pip install -e ".[registry]"
|
||||
|
||||
# Run the web server
|
||||
python -m smarttools.web.app
|
||||
python -m cmdforge.web.app
|
||||
```
|
||||
|
||||
The server will start on `http://localhost:5000`.
|
||||
|
|
@ -1337,47 +1337,47 @@ The server will start on `http://localhost:5000`.
|
|||
|
||||
```bash
|
||||
# Required
|
||||
export SMARTTOOLS_REGISTRY_DB=/path/to/registry.db
|
||||
export CMDFORGE_REGISTRY_DB=/path/to/registry.db
|
||||
export PORT=5050
|
||||
|
||||
# Optional
|
||||
export SMARTTOOLS_ENV=production # Enables secure cookies
|
||||
export SMARTTOOLS_SHOW_ADS=true # Enable ad placeholders
|
||||
export CMDFORGE_ENV=production # Enables secure cookies
|
||||
export CMDFORGE_SHOW_ADS=true # Enable ad placeholders
|
||||
```
|
||||
|
||||
#### 2. Database Location
|
||||
|
||||
By default, the registry uses `~/.smarttools/registry.db`. For production:
|
||||
By default, the registry uses `~/.cmdforge/registry.db`. For production:
|
||||
|
||||
```bash
|
||||
# Create dedicated directory
|
||||
mkdir -p /var/lib/smarttools
|
||||
export SMARTTOOLS_REGISTRY_DB=/var/lib/smarttools/registry.db
|
||||
mkdir -p /var/lib/cmdforge
|
||||
export CMDFORGE_REGISTRY_DB=/var/lib/cmdforge/registry.db
|
||||
```
|
||||
|
||||
**Note**: If using a merged filesystem (e.g., mergerfs), store the database on a single disk or in `/tmp` to avoid SQLite WAL mode issues:
|
||||
|
||||
```bash
|
||||
export SMARTTOOLS_REGISTRY_DB=/tmp/smarttools-registry/registry.db
|
||||
export CMDFORGE_REGISTRY_DB=/tmp/cmdforge-registry/registry.db
|
||||
```
|
||||
|
||||
#### 3. Running with systemd
|
||||
|
||||
Create `/etc/systemd/system/smarttools-registry.service`:
|
||||
Create `/etc/systemd/system/cmdforge-registry.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=SmartTools Registry Web Server
|
||||
Description=CmdForge Registry Web Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=smarttools
|
||||
WorkingDirectory=/opt/smarttools
|
||||
Environment=SMARTTOOLS_REGISTRY_DB=/var/lib/smarttools/registry.db
|
||||
User=cmdforge
|
||||
WorkingDirectory=/opt/cmdforge
|
||||
Environment=CMDFORGE_REGISTRY_DB=/var/lib/cmdforge/registry.db
|
||||
Environment=PORT=5050
|
||||
Environment=SMARTTOOLS_ENV=production
|
||||
ExecStart=/opt/smarttools/venv/bin/python -m smarttools.web.app
|
||||
Environment=CMDFORGE_ENV=production
|
||||
ExecStart=/opt/cmdforge/venv/bin/python -m cmdforge.web.app
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
|
|
@ -1387,8 +1387,8 @@ WantedBy=multi-user.target
|
|||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable smarttools-registry
|
||||
sudo systemctl start smarttools-registry
|
||||
sudo systemctl enable cmdforge-registry
|
||||
sudo systemctl start cmdforge-registry
|
||||
```
|
||||
|
||||
#### 4. Reverse Proxy (nginx)
|
||||
|
|
@ -1396,7 +1396,7 @@ sudo systemctl start smarttools-registry
|
|||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name registry.smarttools.dev;
|
||||
server_name cmdforge.brrd.tech;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5050;
|
||||
|
|
@ -1407,7 +1407,7 @@ server {
|
|||
}
|
||||
|
||||
location /static {
|
||||
alias /opt/smarttools/src/smarttools/web/static;
|
||||
alias /opt/cmdforge/src/cmdforge/web/static;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
|
@ -1417,7 +1417,7 @@ server {
|
|||
#### 5. SSL with Certbot
|
||||
|
||||
```bash
|
||||
sudo certbot --nginx -d registry.smarttools.dev
|
||||
sudo certbot --nginx -d cmdforge.brrd.tech
|
||||
```
|
||||
|
||||
### Tailwind CSS Build
|
||||
|
|
@ -1429,8 +1429,8 @@ The CSS is pre-built and committed. To rebuild after changes:
|
|||
npm install
|
||||
|
||||
# Build for production
|
||||
npx tailwindcss -i src/smarttools/web/static/css/input.css \
|
||||
-o src/smarttools/web/static/css/main.css \
|
||||
npx tailwindcss -i src/cmdforge/web/static/css/input.css \
|
||||
-o src/cmdforge/web/static/css/main.css \
|
||||
--minify
|
||||
```
|
||||
|
||||
|
|
@ -1447,7 +1447,7 @@ curl http://localhost:5050/api/v1/tools
|
|||
|-------|----------|
|
||||
| `disk I/O error` | Move database to non-merged filesystem |
|
||||
| Port already in use | Change PORT environment variable |
|
||||
| 500 errors | Check `/tmp/smarttools.log` for stack traces |
|
||||
| 500 errors | Check `/tmp/cmdforge.log` for stack traces |
|
||||
| Static files not loading | Verify static folder path in deployment |
|
||||
|
||||
## Future Considerations (Phase 8+)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Install all SmartTools example tools.
|
||||
Install all CmdForge example tools.
|
||||
|
||||
Usage:
|
||||
python3 install.py # Install all tools
|
||||
|
|
@ -9,7 +9,7 @@ Usage:
|
|||
python3 install.py --category dev # Install category
|
||||
|
||||
Run from anywhere:
|
||||
curl -sSL https://gitea.brrd.tech/rob/smarttools/raw/branch/main/examples/install.py | python3
|
||||
curl -sSL https://gitea.brrd.tech/rob/cmdforge/raw/branch/main/examples/install.py | python3
|
||||
"""
|
||||
|
||||
import argparse
|
||||
|
|
@ -22,7 +22,7 @@ except ImportError:
|
|||
print("PyYAML required. Install with: pip install pyyaml")
|
||||
sys.exit(1)
|
||||
|
||||
TOOLS_DIR = Path.home() / ".smarttools"
|
||||
TOOLS_DIR = Path.home() / ".cmdforge"
|
||||
|
||||
# All example tool configurations
|
||||
TOOLS = {
|
||||
|
|
@ -298,7 +298,7 @@ def list_tools():
|
|||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Install SmartTools example tools")
|
||||
parser = argparse.ArgumentParser(description="Install CmdForge example tools")
|
||||
parser.add_argument("tools", nargs="*", help="Specific tools to install (default: all)")
|
||||
parser.add_argument("--list", action="store_true", help="List available tools")
|
||||
parser.add_argument("--category", "-c", choices=list(CATEGORIES.keys()), help="Install tools from category")
|
||||
|
|
@ -335,7 +335,7 @@ def main():
|
|||
installed += 1
|
||||
|
||||
print(f"\nInstalled {installed} tools.")
|
||||
print("\nRun 'smarttools refresh' to create executable wrappers.")
|
||||
print("\nRun 'cmdforge refresh' to create executable wrappers.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"name": "smarttools-web",
|
||||
"name": "cmdforge-web",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"css:build": "tailwindcss -i src/smarttools/web/static/src/input.css -o src/smarttools/web/static/css/main.css --minify",
|
||||
"css:watch": "tailwindcss -i src/smarttools/web/static/src/input.css -o src/smarttools/web/static/css/main.css --watch"
|
||||
"css:build": "tailwindcss -i src/cmdforge/web/static/src/input.css -o src/cmdforge/web/static/css/main.css --minify",
|
||||
"css:watch": "tailwindcss -i src/cmdforge/web/static/src/input.css -o src/cmdforge/web/static/css/main.css --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tailwindcss": "^3.4.19"
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ requires = ["setuptools>=61.0", "wheel"]
|
|||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "smarttools"
|
||||
name = "cmdforge"
|
||||
version = "0.1.0"
|
||||
description = "A lightweight personal tool builder for AI-powered CLI commands"
|
||||
description = "Build custom AI-powered CLI commands in YAML"
|
||||
readme = "README.md"
|
||||
license = {text = "MIT"}
|
||||
requires-python = ">=3.10"
|
||||
|
|
@ -56,13 +56,13 @@ all = [
|
|||
]
|
||||
|
||||
[project.scripts]
|
||||
smarttools = "smarttools.cli:main"
|
||||
cmdforge = "cmdforge.cli:main"
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://gitea.brrd.tech/rob/smarttools"
|
||||
Documentation = "https://gitea.brrd.tech/rob/smarttools#readme"
|
||||
Repository = "https://gitea.brrd.tech/rob/smarttools.git"
|
||||
Issues = "https://gitea.brrd.tech/rob/smarttools/issues"
|
||||
Homepage = "https://cmdforge.brrd.tech"
|
||||
Documentation = "https://cmdforge.brrd.tech/docs"
|
||||
Repository = "https://gitea.brrd.tech/rob/CmdForge.git"
|
||||
Issues = "https://gitea.brrd.tech/rob/CmdForge/issues"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
"""Basic health check for the SmartTools Registry API and DB."""
|
||||
"""Basic health check for the CmdForge Registry API and DB."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -17,13 +17,13 @@ def _add_src_to_path() -> None:
|
|||
|
||||
|
||||
def _get_registry_url() -> str:
|
||||
from smarttools.config import get_registry_url
|
||||
from cmdforge.config import get_registry_url
|
||||
|
||||
return get_registry_url().rstrip("/")
|
||||
|
||||
|
||||
def _get_db_path() -> Path:
|
||||
from smarttools.registry.db import get_db_path
|
||||
from cmdforge.registry.db import get_db_path
|
||||
|
||||
return get_db_path()
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import yaml
|
|||
# Allow running from repo root
|
||||
sys.path.append(str(Path(__file__).resolve().parents[1] / "src"))
|
||||
|
||||
from smarttools.registry.db import connect_db, query_one
|
||||
from smarttools.registry.sync import ensure_publisher, normalize_tags
|
||||
from cmdforge.registry.db import connect_db, query_one
|
||||
from cmdforge.registry.sync import ensure_publisher, normalize_tags
|
||||
|
||||
|
||||
def load_yaml(path: Path) -> Dict[str, Any]:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
"""CmdForge - A lightweight personal tool builder for AI-powered CLI commands."""
|
||||
|
||||
__version__ = "0.1.0"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""CLI entry point for SmartTools.
|
||||
"""CLI entry point for CmdForge.
|
||||
|
||||
This module is a thin wrapper for backwards compatibility.
|
||||
The actual implementation is in the cli/ package.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""CLI entry point for SmartTools."""
|
||||
"""CLI entry point for CmdForge."""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
|
@ -18,7 +18,7 @@ from .config_commands import cmd_config
|
|||
def main():
|
||||
"""Main CLI entry point."""
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="smarttools",
|
||||
prog="cmdforge",
|
||||
description="A lightweight personal tool builder for AI-powered CLI commands"
|
||||
)
|
||||
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
|
||||
|
|
@ -179,7 +179,7 @@ def main():
|
|||
p_deps.set_defaults(func=cmd_deps)
|
||||
|
||||
# 'install' command (for dependencies)
|
||||
p_install = subparsers.add_parser("install", help="Install dependencies from smarttools.yaml")
|
||||
p_install = subparsers.add_parser("install", help="Install dependencies from cmdforge.yaml")
|
||||
p_install.set_defaults(func=cmd_install_deps)
|
||||
|
||||
# 'add' command
|
||||
|
|
@ -190,7 +190,7 @@ def main():
|
|||
p_add.set_defaults(func=cmd_add)
|
||||
|
||||
# 'init' command
|
||||
p_init = subparsers.add_parser("init", help="Initialize smarttools.yaml")
|
||||
p_init = subparsers.add_parser("init", help="Initialize cmdforge.yaml")
|
||||
p_init.add_argument("-n", "--name", help="Project name")
|
||||
p_init.add_argument("-v", "--version", help="Project version")
|
||||
p_init.add_argument("-f", "--force", action="store_true", help="Overwrite existing")
|
||||
|
|
@ -4,7 +4,7 @@ from ..config import load_config, save_config, set_registry_token
|
|||
|
||||
|
||||
def cmd_config(args):
|
||||
"""Manage SmartTools configuration."""
|
||||
"""Manage CmdForge configuration."""
|
||||
if args.config_cmd == "show":
|
||||
return _cmd_config_show(args)
|
||||
elif args.config_cmd == "set-token":
|
||||
|
|
@ -22,7 +22,7 @@ def cmd_config(args):
|
|||
def _cmd_config_show(args):
|
||||
"""Show current configuration."""
|
||||
config = load_config()
|
||||
print("SmartTools Configuration:")
|
||||
print("CmdForge Configuration:")
|
||||
print(f" Registry URL: {config.registry.url}")
|
||||
print(f" Token: {'***' if config.registry.token else '(not set)'}")
|
||||
print(f" Client ID: {config.client_id}")
|
||||
|
|
@ -13,12 +13,12 @@ from ..resolver import (
|
|||
|
||||
|
||||
def cmd_deps(args):
|
||||
"""Show project dependencies from smarttools.yaml."""
|
||||
"""Show project dependencies from cmdforge.yaml."""
|
||||
manifest = load_manifest()
|
||||
|
||||
if manifest is None:
|
||||
print("No smarttools.yaml found in current project.")
|
||||
print("Create one with: smarttools init")
|
||||
print("No cmdforge.yaml found in current project.")
|
||||
print("Create one with: cmdforge init")
|
||||
return 1
|
||||
|
||||
print(f"Project: {manifest.name} v{manifest.version}")
|
||||
|
|
@ -26,7 +26,7 @@ def cmd_deps(args):
|
|||
|
||||
if not manifest.dependencies:
|
||||
print("No dependencies defined.")
|
||||
print("Add one with: smarttools add <owner/name>")
|
||||
print("Add one with: cmdforge add <owner/name>")
|
||||
return 0
|
||||
|
||||
print(f"Dependencies ({len(manifest.dependencies)}):")
|
||||
|
|
@ -52,14 +52,14 @@ def cmd_deps(args):
|
|||
|
||||
|
||||
def cmd_install_deps(args):
|
||||
"""Install dependencies from smarttools.yaml."""
|
||||
"""Install dependencies from cmdforge.yaml."""
|
||||
from ..registry_client import RegistryError
|
||||
|
||||
manifest = load_manifest()
|
||||
|
||||
if manifest is None:
|
||||
print("No smarttools.yaml found in current project.")
|
||||
print("Create one with: smarttools init")
|
||||
print("No cmdforge.yaml found in current project.")
|
||||
print("Create one with: cmdforge init")
|
||||
return 1
|
||||
|
||||
if not manifest.dependencies:
|
||||
|
|
@ -150,19 +150,19 @@ def cmd_add(args):
|
|||
print(f"It's been added to your dependencies - you can install it manually later.", file=sys.stderr)
|
||||
elif e.code == "CONNECTION_ERROR":
|
||||
print(f"Could not connect to registry.", file=sys.stderr)
|
||||
print("Run 'smarttools install' to try again later.", file=sys.stderr)
|
||||
print("Run 'cmdforge install' to try again later.", file=sys.stderr)
|
||||
else:
|
||||
print(f"Install failed: {e.message}", file=sys.stderr)
|
||||
print("Run 'smarttools install' to try again.", file=sys.stderr)
|
||||
print("Run 'cmdforge install' to try again.", file=sys.stderr)
|
||||
except Exception as e:
|
||||
print(f"Install failed: {e}", file=sys.stderr)
|
||||
print("Run 'smarttools install' to try again.", file=sys.stderr)
|
||||
print("Run 'cmdforge install' to try again.", file=sys.stderr)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_init(args):
|
||||
"""Initialize a new smarttools.yaml."""
|
||||
"""Initialize a new cmdforge.yaml."""
|
||||
manifest_path = Path.cwd() / MANIFEST_FILENAME
|
||||
|
||||
if manifest_path.exists() and not args.force:
|
||||
|
|
@ -196,7 +196,7 @@ def cmd_init(args):
|
|||
|
||||
print(f"Created {MANIFEST_FILENAME}")
|
||||
print()
|
||||
print("Add dependencies with: smarttools add <owner/name>")
|
||||
print("Install them with: smarttools install")
|
||||
print("Add dependencies with: cmdforge add <owner/name>")
|
||||
print("Install them with: cmdforge install")
|
||||
|
||||
return 0
|
||||
|
|
@ -48,7 +48,7 @@ PROVIDER_INSTALL_INFO = {
|
|||
"cost": "FREE (runs entirely on your machine)",
|
||||
"variants": [],
|
||||
"custom": True,
|
||||
"post_install_note": "After installing, add the provider:\n smarttools providers add ollama 'ollama run llama3' -d 'Local Llama 3'",
|
||||
"post_install_note": "After installing, add the provider:\n cmdforge providers add ollama 'ollama run llama3' -d 'Local Llama 3'",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ def cmd_providers(args):
|
|||
def _cmd_providers_install(args):
|
||||
"""Interactive guide to install AI providers."""
|
||||
print("=" * 60)
|
||||
print("SmartTools Provider Installation Guide")
|
||||
print("CmdForge Provider Installation Guide")
|
||||
print("=" * 60)
|
||||
print()
|
||||
|
||||
|
|
@ -185,9 +185,9 @@ def _cmd_providers_install(args):
|
|||
print(f" 2. {info['setup']}")
|
||||
if info.get('post_install_note'):
|
||||
print(f" 3. {info['post_install_note']}")
|
||||
print(f" 4. Test with: smarttools providers test {selected}")
|
||||
print(f" 4. Test with: cmdforge providers test {selected}")
|
||||
else:
|
||||
print(f" 3. Test with: smarttools providers test {info['variants'][0] if info['variants'] else selected}")
|
||||
print(f" 3. Test with: cmdforge providers test {info['variants'][0] if info['variants'] else selected}")
|
||||
else:
|
||||
print()
|
||||
print(f"Installation failed (exit code {result.returncode})")
|
||||
|
|
@ -86,7 +86,7 @@ def _cmd_registry_search(args):
|
|||
return 1
|
||||
except Exception as e:
|
||||
print(f"Error searching registry: {e}", file=sys.stderr)
|
||||
print("If the problem persists, check: smarttools config show", file=sys.stderr)
|
||||
print("If the problem persists, check: cmdforge config show", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
|
@ -120,7 +120,7 @@ def _cmd_registry_install(args):
|
|||
except RegistryError as e:
|
||||
if e.code == "TOOL_NOT_FOUND":
|
||||
print(f"Tool '{tool_spec}' not found in the registry.", file=sys.stderr)
|
||||
print(f"Try: smarttools registry search {tool_spec.split('/')[-1]}", file=sys.stderr)
|
||||
print(f"Try: cmdforge registry search {tool_spec.split('/')[-1]}", file=sys.stderr)
|
||||
elif e.code == "VERSION_NOT_FOUND" or e.code == "CONSTRAINT_UNSATISFIABLE":
|
||||
print(f"Error: {e.message}", file=sys.stderr)
|
||||
if e.details and "available_versions" in e.details:
|
||||
|
|
@ -191,12 +191,12 @@ def _cmd_registry_info(args):
|
|||
if len(versions) > 5:
|
||||
print(f" ...and {len(versions) - 5} more")
|
||||
|
||||
print(f"\nInstall: smarttools registry install {tool_info.owner}/{tool_info.name}")
|
||||
print(f"\nInstall: cmdforge registry install {tool_info.owner}/{tool_info.name}")
|
||||
|
||||
except RegistryError as e:
|
||||
if e.code == "TOOL_NOT_FOUND":
|
||||
print(f"Tool '{tool_spec}' not found in the registry.", file=sys.stderr)
|
||||
print(f"Try: smarttools registry search {parsed.name}", file=sys.stderr)
|
||||
print(f"Try: cmdforge registry search {parsed.name}", file=sys.stderr)
|
||||
elif e.code == "CONNECTION_ERROR":
|
||||
print("Could not connect to the registry.", file=sys.stderr)
|
||||
print("Check your internet connection or try again later.", file=sys.stderr)
|
||||
|
|
@ -380,7 +380,7 @@ def _cmd_registry_my_tools(args):
|
|||
|
||||
if not tools:
|
||||
print("You haven't published any tools yet.")
|
||||
print("Publish your first tool with: smarttools registry publish")
|
||||
print("Publish your first tool with: cmdforge registry publish")
|
||||
return 0
|
||||
|
||||
print(f"Your published tools ({len(tools)}):\n")
|
||||
|
|
@ -393,7 +393,7 @@ def _cmd_registry_my_tools(args):
|
|||
except RegistryError as e:
|
||||
if e.code == "UNAUTHORIZED":
|
||||
print("Not logged in. Set your registry token first:", file=sys.stderr)
|
||||
print(" smarttools config set-token <token>", file=sys.stderr)
|
||||
print(" cmdforge config set-token <token>", file=sys.stderr)
|
||||
print()
|
||||
print("Don't have a token? Register at the registry website.", file=sys.stderr)
|
||||
elif e.code == "CONNECTION_ERROR":
|
||||
|
|
@ -418,8 +418,8 @@ def _cmd_registry_browse(args):
|
|||
return run_registry_browser()
|
||||
except ImportError:
|
||||
print("TUI browser requires urwid. Install with:", file=sys.stderr)
|
||||
print(" pip install 'smarttools[tui]'", file=sys.stderr)
|
||||
print(" pip install 'cmdforge[tui]'", file=sys.stderr)
|
||||
print()
|
||||
print("Or search from command line:", file=sys.stderr)
|
||||
print(" smarttools registry search <query>", file=sys.stderr)
|
||||
print(" cmdforge registry search <query>", file=sys.stderr)
|
||||
return 1
|
||||
|
|
@ -16,7 +16,7 @@ def cmd_list(args):
|
|||
|
||||
if not tools:
|
||||
print("No tools found.")
|
||||
print("Create your first tool with: smarttools ui")
|
||||
print("Create your first tool with: cmdforge ui")
|
||||
return 0
|
||||
|
||||
print(f"Available tools ({len(tools)}):\n")
|
||||
|
|
@ -76,7 +76,7 @@ def cmd_create(args):
|
|||
path = save_tool(tool)
|
||||
print(f"Created tool '{name}'")
|
||||
print(f"Config: {path}")
|
||||
print(f"\nUse 'smarttools ui' to add arguments, steps, and customize.")
|
||||
print(f"\nUse 'cmdforge ui' to add arguments, steps, and customize.")
|
||||
print(f"Or run: {name} < input.txt")
|
||||
|
||||
return 0
|
||||
|
|
@ -326,7 +326,7 @@ echo "input" | {args.name}
|
|||
# View README
|
||||
if not readme_path.exists():
|
||||
print(f"No documentation found for '{args.name}'.")
|
||||
print(f"Create it with: smarttools docs {args.name} --edit")
|
||||
print(f"Create it with: cmdforge docs {args.name} --edit")
|
||||
return 1
|
||||
|
||||
print(readme_path.read_text())
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
"""Global configuration handling for SmartTools.
|
||||
"""Global configuration handling for CmdForge.
|
||||
|
||||
Manages ~/.smarttools/config.yaml with registry settings, tokens, and preferences.
|
||||
Manages ~/.cmdforge/config.yaml with registry settings, tokens, and preferences.
|
||||
"""
|
||||
|
||||
import uuid
|
||||
|
|
@ -12,7 +12,7 @@ import yaml
|
|||
|
||||
|
||||
# Default configuration directory
|
||||
CONFIG_DIR = Path.home() / ".smarttools"
|
||||
CONFIG_DIR = Path.home() / ".cmdforge"
|
||||
CONFIG_FILE = CONFIG_DIR / "config.yaml"
|
||||
|
||||
# Default registry URL (canonical base path)
|
||||
|
|
@ -41,7 +41,7 @@ class RegistryConfig:
|
|||
|
||||
@dataclass
|
||||
class Config:
|
||||
"""Global SmartTools configuration."""
|
||||
"""Global CmdForge configuration."""
|
||||
registry: RegistryConfig = field(default_factory=RegistryConfig)
|
||||
client_id: str = ""
|
||||
auto_fetch_from_registry: bool = True
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Project manifest (smarttools.yaml) handling.
|
||||
"""Project manifest (cmdforge.yaml) handling.
|
||||
|
||||
Manages project-level tool dependencies and overrides.
|
||||
"""
|
||||
|
|
@ -11,7 +11,7 @@ from typing import Optional, List, Dict
|
|||
import yaml
|
||||
|
||||
|
||||
MANIFEST_FILENAME = "smarttools.yaml"
|
||||
MANIFEST_FILENAME = "cmdforge.yaml"
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -76,7 +76,7 @@ class ToolOverride:
|
|||
|
||||
@dataclass
|
||||
class Manifest:
|
||||
"""Project manifest (smarttools.yaml)."""
|
||||
"""Project manifest (cmdforge.yaml)."""
|
||||
name: str = "my-project"
|
||||
version: str = "1.0.0"
|
||||
dependencies: List[Dependency] = field(default_factory=list)
|
||||
|
|
@ -144,7 +144,7 @@ class Manifest:
|
|||
|
||||
def find_manifest(start_dir: Optional[Path] = None) -> Optional[Path]:
|
||||
"""
|
||||
Find smarttools.yaml by searching up from start_dir.
|
||||
Find cmdforge.yaml by searching up from start_dir.
|
||||
|
||||
Args:
|
||||
start_dir: Directory to start searching from (default: cwd)
|
||||
|
|
@ -201,7 +201,7 @@ def save_manifest(manifest: Manifest, path: Optional[Path] = None) -> Path:
|
|||
|
||||
Args:
|
||||
manifest: Manifest to save
|
||||
path: Path to save to (default: ./smarttools.yaml)
|
||||
path: Path to save to (default: ./cmdforge.yaml)
|
||||
|
||||
Returns:
|
||||
Path where manifest was saved
|
||||
|
|
@ -12,7 +12,7 @@ import yaml
|
|||
|
||||
|
||||
# Default providers config location
|
||||
PROVIDERS_FILE = Path.home() / ".smarttools" / "providers.yaml"
|
||||
PROVIDERS_FILE = Path.home() / ".cmdforge" / "providers.yaml"
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -161,7 +161,7 @@ def call_provider(provider_name: str, prompt: str, timeout: int = 300) -> Provid
|
|||
return ProviderResult(
|
||||
text="",
|
||||
success=False,
|
||||
error=f"Provider '{provider_name}' not found. Use 'smarttools providers' to manage providers."
|
||||
error=f"Provider '{provider_name}' not found. Use 'cmdforge providers' to manage providers."
|
||||
)
|
||||
|
||||
# Parse command (expand environment variables)
|
||||
|
|
@ -181,7 +181,7 @@ def call_provider(provider_name: str, prompt: str, timeout: int = 300) -> Provid
|
|||
return ProviderResult(
|
||||
text="",
|
||||
success=False,
|
||||
error=f"Command '{base_cmd}' not found. Is it installed and in PATH?\n\nTo install AI providers, run: smarttools providers install"
|
||||
error=f"Command '{base_cmd}' not found. Is it installed and in PATH?\n\nTo install AI providers, run: cmdforge providers install"
|
||||
)
|
||||
|
||||
try:
|
||||
|
|
@ -197,7 +197,7 @@ def call_provider(provider_name: str, prompt: str, timeout: int = 300) -> Provid
|
|||
if result.returncode != 0:
|
||||
error_msg = f"Provider exited with code {result.returncode}: {result.stderr}"
|
||||
if "not found" in result.stderr.lower() or "not installed" in result.stderr.lower():
|
||||
error_msg += "\n\nTo install AI providers, run: smarttools providers install"
|
||||
error_msg += "\n\nTo install AI providers, run: cmdforge providers install"
|
||||
return ProviderResult(
|
||||
text="",
|
||||
success=False,
|
||||
|
|
@ -224,14 +224,14 @@ def call_provider(provider_name: str, prompt: str, timeout: int = 300) -> Provid
|
|||
f"To fix this, either:\n"
|
||||
f" 1. Run 'opencode' to connect the {provider_id} provider\n"
|
||||
f" 2. Use --provider to pick a different model (e.g., --provider opencode-pickle)\n"
|
||||
f" 3. Run 'smarttools ui' to edit the tool's default provider"
|
||||
f" 3. Run 'cmdforge ui' to edit the tool's default provider"
|
||||
)
|
||||
|
||||
stderr_hint = f" (stderr: {stderr[:200]}...)" if len(stderr) > 200 else (f" (stderr: {stderr})" if stderr else "")
|
||||
return ProviderResult(
|
||||
text="",
|
||||
success=False,
|
||||
error=f"Provider returned empty output{stderr_hint}.\n\nThis may mean the model is not available. Try a different provider or run: smarttools providers install"
|
||||
error=f"Provider returned empty output{stderr_hint}.\n\nThis may mean the model is not available. Try a different provider or run: cmdforge providers install"
|
||||
)
|
||||
|
||||
return ProviderResult(text=result.stdout, success=True)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Flask app for SmartTools Registry API (Phase 2)."""
|
||||
"""Flask app for CmdForge Registry API (Phase 2)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ ALLOWED_SORT = {
|
|||
TOOL_NAME_RE = re.compile(r"^[A-Za-z0-9-]{1,64}$")
|
||||
OWNER_RE = re.compile(r"^[a-z0-9][a-z0-9-]{0,37}[a-z0-9]$")
|
||||
EMAIL_RE = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$")
|
||||
RESERVED_SLUGS = {"official", "admin", "system", "api", "registry", "smarttools"}
|
||||
RESERVED_SLUGS = {"official", "admin", "system", "api", "registry", "cmdforge"}
|
||||
|
||||
rate_limiter = RateLimiter()
|
||||
password_hasher = PasswordHasher(memory_cost=65536, time_cost=3, parallelism=4)
|
||||
|
|
@ -1517,7 +1517,7 @@ def create_app() -> Flask:
|
|||
status=413,
|
||||
details={"limit": MAX_BODY_BYTES},
|
||||
)
|
||||
secret = os.environ.get("SMARTTOOLS_REGISTRY_WEBHOOK_SECRET", "")
|
||||
secret = os.environ.get("CMDFORGE_REGISTRY_WEBHOOK_SECRET", "")
|
||||
if not secret:
|
||||
return error_response("UNAUTHORIZED", "Webhook secret not configured", 401)
|
||||
status, payload = process_webhook(request.data, dict(request.headers), secret)
|
||||
|
|
@ -232,8 +232,8 @@ CREATE INDEX IF NOT EXISTS idx_pageviews_date ON pageviews(date(viewed_at), path
|
|||
|
||||
|
||||
def get_db_path() -> Path:
|
||||
default_path = Path.home() / ".smarttools" / "registry" / "registry.db"
|
||||
return Path(os.environ.get("SMARTTOOLS_REGISTRY_DB", default_path))
|
||||
default_path = Path.home() / ".cmdforge" / "registry" / "registry.db"
|
||||
return Path(os.environ.get("CMDFORGE_REGISTRY_DB", default_path))
|
||||
|
||||
|
||||
def ensure_db_directory(path: Path) -> None:
|
||||
|
|
@ -19,22 +19,22 @@ from .db import connect_db, query_one
|
|||
|
||||
|
||||
def get_repo_dir() -> Path:
|
||||
default_dir = Path.home() / ".smarttools" / "registry" / "repo"
|
||||
return Path(os.environ.get("SMARTTOOLS_REGISTRY_REPO_DIR", default_dir))
|
||||
default_dir = Path.home() / ".cmdforge" / "registry" / "repo"
|
||||
return Path(os.environ.get("CMDFORGE_REGISTRY_REPO_DIR", default_dir))
|
||||
|
||||
|
||||
def get_repo_url() -> str:
|
||||
return os.environ.get("SMARTTOOLS_REGISTRY_REPO_URL", "https://gitea.brrd.tech/rob/SmartTools-Registry.git")
|
||||
return os.environ.get("CMDFORGE_REGISTRY_REPO_URL", "https://gitea.brrd.tech/rob/CmdForge-Registry.git")
|
||||
|
||||
|
||||
def get_repo_branch() -> str:
|
||||
return os.environ.get("SMARTTOOLS_REGISTRY_REPO_BRANCH", "main")
|
||||
return os.environ.get("CMDFORGE_REGISTRY_REPO_BRANCH", "main")
|
||||
|
||||
|
||||
def get_categories_cache_path() -> Path:
|
||||
return Path(os.environ.get(
|
||||
"SMARTTOOLS_REGISTRY_CATEGORIES_CACHE",
|
||||
Path.home() / ".smarttools" / "registry" / "categories_cache.json",
|
||||
"CMDFORGE_REGISTRY_CATEGORIES_CACHE",
|
||||
Path.home() / ".cmdforge" / "registry" / "categories_cache.json",
|
||||
))
|
||||
|
||||
|
||||
|
|
@ -249,7 +249,7 @@ def process_webhook(body: bytes, headers: Dict[str, str], secret: str, timeout:
|
|||
if is_delivery_processed(conn, delivery_id):
|
||||
return 200, {"data": {"status": "already_processed"}}
|
||||
|
||||
lock_path = Path.home() / ".smarttools" / "registry" / "locks" / "webhook.lock"
|
||||
lock_path = Path.home() / ".cmdforge" / "registry" / "locks" / "webhook.lock"
|
||||
if not acquire_lock(lock_path, timeout):
|
||||
return 200, {"data": {"status": "skipped", "reason": "sync_in_progress"}}
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Registry API client for SmartTools.
|
||||
"""Registry API client for CmdForge.
|
||||
|
||||
Handles all HTTP communication with the registry server.
|
||||
"""
|
||||
|
|
@ -114,7 +114,7 @@ class DownloadResult:
|
|||
|
||||
|
||||
class RegistryClient:
|
||||
"""Client for interacting with the SmartTools registry API."""
|
||||
"""Client for interacting with the CmdForge registry API."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
|
@ -141,8 +141,8 @@ class RegistryClient:
|
|||
# Session for connection pooling
|
||||
self._session = requests.Session()
|
||||
self._session.headers.update({
|
||||
"User-Agent": "SmartTools-CLI/1.0",
|
||||
"X-SmartTools-Client": "cli/1.0.0",
|
||||
"User-Agent": "CmdForge-CLI/1.0",
|
||||
"X-CmdForge-Client": "cli/1.0.0",
|
||||
"Accept": "application/json"
|
||||
})
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ class RegistryClient:
|
|||
if not self.token:
|
||||
raise RegistryError(
|
||||
code="UNAUTHORIZED",
|
||||
message="Authentication required. Set registry token with 'smarttools config set-token'",
|
||||
message="Authentication required. Set registry token with 'cmdforge config set-token'",
|
||||
http_status=401
|
||||
)
|
||||
headers.update(self._auth_headers())
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
"""Tool resolution with proper search order.
|
||||
|
||||
Implements the tool resolution order:
|
||||
1. Local project: ./.smarttools/<owner>/<name>/config.yaml
|
||||
2. Global user: ~/.smarttools/<owner>/<name>/config.yaml
|
||||
1. Local project: ./.cmdforge/<owner>/<name>/config.yaml
|
||||
2. Global user: ~/.cmdforge/<owner>/<name>/config.yaml
|
||||
3. Registry: Fetch from API, install to global, then run
|
||||
4. Error if not found
|
||||
"""
|
||||
|
|
@ -24,7 +24,7 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
# Local project tools directories (support both legacy and documented paths)
|
||||
LOCAL_TOOLS_DIRS = [Path(".smarttools"), Path("smarttools")]
|
||||
LOCAL_TOOLS_DIRS = [Path(".cmdforge"), Path("cmdforge")]
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -436,9 +436,9 @@ class ToolResolver:
|
|||
python_path = sys.executable
|
||||
|
||||
script = f"""#!/bin/bash
|
||||
# SmartTools wrapper for '{owner}/{name}'
|
||||
# CmdForge wrapper for '{owner}/{name}'
|
||||
# Auto-generated - do not edit
|
||||
exec {python_path} -m smarttools.runner {owner}/{name} "$@"
|
||||
exec {python_path} -m cmdforge.runner {owner}/{name} "$@"
|
||||
"""
|
||||
|
||||
wrapper_path.write_text(script)
|
||||
|
|
@ -450,9 +450,9 @@ exec {python_path} -m smarttools.runner {owner}/{name} "$@"
|
|||
"""Extract owner from existing wrapper script."""
|
||||
try:
|
||||
content = wrapper_path.read_text()
|
||||
# Look for pattern: smarttools.runner owner/name
|
||||
# Look for pattern: cmdforge.runner owner/name
|
||||
# Owner slugs can contain lowercase alphanumeric and hyphens
|
||||
match = re.search(r'smarttools\.runner\s+([a-z0-9][a-z0-9-]*)/([a-zA-Z0-9_-]+)', content)
|
||||
match = re.search(r'cmdforge\.runner\s+([a-z0-9][a-z0-9-]*)/([a-zA-Z0-9_-]+)', content)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
|
@ -210,7 +210,7 @@ def create_argument_parser(tool: Tool) -> argparse.ArgumentParser:
|
|||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
prog=tool.name,
|
||||
description=tool.description or f"SmartTools: {tool.name}"
|
||||
description=tool.description or f"CmdForge: {tool.name}"
|
||||
)
|
||||
|
||||
# Universal flags
|
||||
|
|
@ -244,7 +244,7 @@ def create_argument_parser(tool: Tool) -> argparse.ArgumentParser:
|
|||
def main():
|
||||
"""Entry point for tool execution via wrapper script."""
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python -m smarttools.runner <tool_name> [args...]", file=sys.stderr)
|
||||
print("Usage: python -m cmdforge.runner <tool_name> [args...]", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
tool_spec = sys.argv[1]
|
||||
|
|
@ -10,7 +10,7 @@ import yaml
|
|||
|
||||
|
||||
# Default tools directory
|
||||
TOOLS_DIR = Path.home() / ".smarttools"
|
||||
TOOLS_DIR = Path.home() / ".cmdforge"
|
||||
|
||||
# Default bin directory for wrapper scripts
|
||||
BIN_DIR = Path.home() / ".local" / "bin"
|
||||
|
|
@ -106,7 +106,7 @@ DEFAULT_CATEGORIES = ["Text", "Developer", "Data", "Other"]
|
|||
|
||||
@dataclass
|
||||
class Tool:
|
||||
"""A SmartTools tool definition."""
|
||||
"""A CmdForge tool definition."""
|
||||
name: str
|
||||
description: str = ""
|
||||
category: str = "Other" # Tool category for organization
|
||||
|
|
@ -275,13 +275,13 @@ def create_wrapper_script(name: str) -> Path:
|
|||
bin_dir = get_bin_dir()
|
||||
wrapper_path = bin_dir / name
|
||||
|
||||
# Use the current Python interpreter to ensure smarttools is available
|
||||
# Use the current Python interpreter to ensure cmdforge is available
|
||||
python_path = sys.executable
|
||||
|
||||
script = f"""#!/bin/bash
|
||||
# SmartTools wrapper for '{name}'
|
||||
# CmdForge wrapper for '{name}'
|
||||
# Auto-generated - do not edit
|
||||
exec {python_path} -m smarttools.runner {name} "$@"
|
||||
exec {python_path} -m cmdforge.runner {name} "$@"
|
||||
"""
|
||||
|
||||
wrapper_path.write_text(script)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Dialog-based UI for managing SmartTools."""
|
||||
"""Dialog-based UI for managing CmdForge."""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
|
|
@ -762,7 +762,7 @@ def main_menu(dialog_prog: str):
|
|||
"""Show the main menu."""
|
||||
while True:
|
||||
choice = show_menu(
|
||||
"SmartTools Manager",
|
||||
"CmdForge Manager",
|
||||
[
|
||||
("list", "List all tools"),
|
||||
("create", "Create new tool"),
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""TUI for browsing the SmartTools Registry using urwid.
|
||||
"""TUI for browsing the CmdForge Registry using urwid.
|
||||
|
||||
Uses threading for non-blocking network operations.
|
||||
"""
|
||||
|
|
@ -170,7 +170,7 @@ class AsyncOperation:
|
|||
|
||||
|
||||
class RegistryBrowser:
|
||||
"""TUI browser for the SmartTools Registry."""
|
||||
"""TUI browser for the CmdForge Registry."""
|
||||
|
||||
def __init__(self):
|
||||
self.client = get_client()
|
||||
|
|
@ -195,7 +195,7 @@ class RegistryBrowser:
|
|||
"""Build the main UI layout."""
|
||||
# Header
|
||||
self.header = urwid.AttrMap(
|
||||
urwid.Text(" SmartTools Registry Browser ", align='center'),
|
||||
urwid.Text(" CmdForge Registry Browser ", align='center'),
|
||||
'header'
|
||||
)
|
||||
|
||||
|
|
@ -344,7 +344,7 @@ Downloads: {downloads}
|
|||
Tags: {', '.join(tags) if tags else 'None'}
|
||||
|
||||
Install command:
|
||||
smarttools registry install {owner}/{name}
|
||||
cmdforge registry install {owner}/{name}
|
||||
|
||||
Press 'i' to install this tool
|
||||
"""
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""BIOS-style TUI for SmartTools using snack (python3-newt)."""
|
||||
"""BIOS-style TUI for CmdForge using snack (python3-newt)."""
|
||||
|
||||
import sys
|
||||
# Ensure system packages are accessible
|
||||
|
|
@ -15,8 +15,8 @@ from .tool import (
|
|||
from .providers import Provider, load_providers, add_provider, delete_provider, get_provider
|
||||
|
||||
|
||||
class SmartToolsUI:
|
||||
"""BIOS-style UI for SmartTools."""
|
||||
class CmdForgeUI:
|
||||
"""BIOS-style UI for CmdForge."""
|
||||
|
||||
def __init__(self):
|
||||
self.screen = None
|
||||
|
|
@ -51,7 +51,7 @@ class SmartToolsUI:
|
|||
for label, value in items:
|
||||
listbox.append(label, value)
|
||||
|
||||
grid = snack.GridForm(self.screen, "SmartTools Manager", 1, 1)
|
||||
grid = snack.GridForm(self.screen, "CmdForge Manager", 1, 1)
|
||||
grid.add(listbox, 0, 0)
|
||||
|
||||
result = grid.runOnce()
|
||||
|
|
@ -698,7 +698,7 @@ class SmartToolsUI:
|
|||
|
||||
def run_ui():
|
||||
"""Entry point for the snack UI."""
|
||||
ui = SmartToolsUI()
|
||||
ui = CmdForgeUI()
|
||||
ui.run()
|
||||
|
||||
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
"""BIOS-style TUI for SmartTools using urwid.
|
||||
"""BIOS-style TUI for CmdForge using urwid.
|
||||
|
||||
This module is a thin wrapper for backwards compatibility.
|
||||
The actual implementation is in the ui_urwid/ package.
|
||||
"""
|
||||
|
||||
from .ui_urwid import run_ui, SmartToolsUI
|
||||
from .ui_urwid import run_ui, CmdForgeUI
|
||||
from .ui_urwid.palette import PALETTE
|
||||
from .ui_urwid.widgets import (
|
||||
SelectableText, Button3D, Button3DCompact, ClickableButton,
|
||||
|
|
@ -13,7 +13,7 @@ from .ui_urwid.widgets import (
|
|||
)
|
||||
|
||||
__all__ = [
|
||||
'run_ui', 'SmartToolsUI', 'PALETTE',
|
||||
'run_ui', 'CmdForgeUI', 'PALETTE',
|
||||
'SelectableText', 'Button3D', 'Button3DCompact', 'ClickableButton',
|
||||
'SelectableToolItem', 'ToolListBox', 'TabCyclePile', 'TabPassEdit',
|
||||
'UndoableEdit', 'DOSScrollBar', 'ToolBuilderLayout', 'Dialog'
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""BIOS-style TUI for SmartTools using urwid (with mouse support)."""
|
||||
"""BIOS-style TUI for CmdForge using urwid (with mouse support)."""
|
||||
|
||||
import urwid
|
||||
from typing import Optional, Callable
|
||||
|
|
@ -18,8 +18,8 @@ from .widgets import (
|
|||
)
|
||||
|
||||
|
||||
class SmartToolsUI:
|
||||
"""Urwid-based UI for SmartTools with mouse support."""
|
||||
class CmdForgeUI:
|
||||
"""Urwid-based UI for CmdForge with mouse support."""
|
||||
|
||||
def __init__(self):
|
||||
self.loop = None
|
||||
|
|
@ -226,7 +226,7 @@ class SmartToolsUI:
|
|||
], tab_positions=[0, 1, 5]) # Tool list, buttons row, exit button
|
||||
|
||||
# Header
|
||||
header = urwid.Text(('header', ' SmartTools Manager '), align='center')
|
||||
header = urwid.Text(('header', ' CmdForge Manager '), align='center')
|
||||
|
||||
# Footer
|
||||
footer = urwid.Text(('footer', ' Arrow:Navigate list | Tab:Jump to buttons | Enter/Click:Select | Q:Quit '), align='center')
|
||||
|
|
@ -1566,5 +1566,5 @@ No explanations, no markdown fencing, just the code."""
|
|||
|
||||
def run_ui():
|
||||
"""Entry point for the urwid UI."""
|
||||
ui = SmartToolsUI()
|
||||
ui = CmdForgeUI()
|
||||
ui.run()
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Web UI blueprint for SmartTools."""
|
||||
"""Web UI blueprint for CmdForge."""
|
||||
|
||||
import os
|
||||
from flask import Blueprint
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Web app factory for SmartTools UI."""
|
||||
"""Web app factory for CmdForge UI."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -19,13 +19,13 @@ if _sentry_dsn:
|
|||
integrations=[FlaskIntegration()],
|
||||
traces_sample_rate=float(os.environ.get("SENTRY_TRACES_RATE", "0.1")),
|
||||
profiles_sample_rate=float(os.environ.get("SENTRY_PROFILES_RATE", "0.1")),
|
||||
environment=os.environ.get("SMARTTOOLS_ENV", "development"),
|
||||
environment=os.environ.get("CMDFORGE_ENV", "development"),
|
||||
send_default_pii=False, # Privacy: don't send user IPs, emails, etc.
|
||||
)
|
||||
except ImportError:
|
||||
pass # sentry-sdk not installed
|
||||
|
||||
from smarttools.registry import app as registry_app
|
||||
from cmdforge.registry import app as registry_app
|
||||
|
||||
from . import web_bp
|
||||
from .auth import login, register, logout
|
||||
|
|
@ -44,10 +44,10 @@ def create_web_app() -> Flask:
|
|||
app.register_blueprint(forum_bp)
|
||||
|
||||
# Session configuration
|
||||
app.session_interface = SQLiteSessionInterface(cookie_name="smarttools_session")
|
||||
app.config["SESSION_COOKIE_NAME"] = "smarttools_session"
|
||||
app.config["SESSION_COOKIE_SECURE"] = os.environ.get("SMARTTOOLS_ENV") == "production"
|
||||
app.config["SHOW_ADS"] = os.environ.get("SMARTTOOLS_SHOW_ADS", "").lower() == "true"
|
||||
app.session_interface = SQLiteSessionInterface(cookie_name="cmdforge_session")
|
||||
app.config["SESSION_COOKIE_NAME"] = "cmdforge_session"
|
||||
app.config["SESSION_COOKIE_SECURE"] = os.environ.get("CMDFORGE_ENV") == "production"
|
||||
app.config["SHOW_ADS"] = os.environ.get("CMDFORGE_SHOW_ADS", "").lower() == "true"
|
||||
|
||||
# CSRF token generator
|
||||
app.config["CSRF_GENERATOR"] = lambda: secrets.token_urlsafe(32)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Documentation content for SmartTools web UI.
|
||||
"""Documentation content for CmdForge web UI.
|
||||
|
||||
This module contains the actual documentation text that gets rendered
|
||||
on the /docs pages. Content is stored as markdown-ish HTML for simplicity.
|
||||
|
|
@ -7,13 +7,13 @@ on the /docs pages. Content is stored as markdown-ish HTML for simplicity.
|
|||
DOCS = {
|
||||
"getting-started": {
|
||||
"title": "Getting Started",
|
||||
"description": "Learn how to install SmartTools and create your first AI-powered CLI tool",
|
||||
"description": "Learn how to install CmdForge and create your first AI-powered CLI tool",
|
||||
"content": """
|
||||
<p class="lead">SmartTools lets you build custom AI-powered CLI commands using simple YAML configuration.
|
||||
<p class="lead">CmdForge lets you build custom AI-powered CLI commands using simple YAML configuration.
|
||||
Create tools that work with any AI provider and compose them like Unix pipes.</p>
|
||||
|
||||
<h2 id="what-is-smarttools">What is SmartTools?</h2>
|
||||
<p>SmartTools is a lightweight personal tool builder that lets you:</p>
|
||||
<h2 id="what-is-cmdforge">What is CmdForge?</h2>
|
||||
<p>CmdForge is a lightweight personal tool builder that lets you:</p>
|
||||
<ul>
|
||||
<li><strong>Create custom CLI commands</strong> that call AI providers</li>
|
||||
<li><strong>Chain prompts with Python code</strong> for complex workflows</li>
|
||||
|
|
@ -24,23 +24,23 @@ Create tools that work with any AI provider and compose them like Unix pipes.</p
|
|||
<h2 id="quick-start">Quick Start</h2>
|
||||
<p>Get up and running in under a minute:</p>
|
||||
|
||||
<pre><code class="language-bash"># Install SmartTools
|
||||
pip install smarttools
|
||||
<pre><code class="language-bash"># Install CmdForge
|
||||
pip install cmdforge
|
||||
|
||||
# Create your first tool (choose your style)
|
||||
smarttools ui # Visual builder with menus
|
||||
smarttools create # CLI wizard
|
||||
cmdforge ui # Visual builder with menus
|
||||
cmdforge create # CLI wizard
|
||||
|
||||
# Or install a tool from the registry
|
||||
smarttools registry install official/summarize
|
||||
cmdforge registry install official/summarize
|
||||
|
||||
# Use it!
|
||||
cat article.txt | summarize</code></pre>
|
||||
|
||||
<div class="bg-cyan-50 border-l-4 border-cyan-500 p-4 my-4">
|
||||
<p class="font-semibold text-cyan-800">Two Ways to Build</p>
|
||||
<p class="text-cyan-700"><code>smarttools ui</code> launches a visual builder with menus and forms.
|
||||
<code>smarttools create</code> uses a command-line wizard. Both create the same YAML config files.</p>
|
||||
<p class="text-cyan-700"><code>cmdforge ui</code> launches a visual builder with menus and forms.
|
||||
<code>cmdforge create</code> uses a command-line wizard. Both create the same YAML config files.</p>
|
||||
</div>
|
||||
|
||||
<h2 id="how-it-works">How It Works</h2>
|
||||
|
|
@ -87,11 +87,11 @@ output: "{summary}"</code></pre>
|
|||
<ul>
|
||||
<li><a href="/forum">Community Forum</a> - Ask questions, share projects, and connect with other users</li>
|
||||
<li><a href="/forum/c/help">Help & Support</a> - Get help with installation, configuration, or usage</li>
|
||||
<li><a href="https://gitea.brrd.tech/rob/SmartTools/issues" target="_blank">Report a Bug</a> - Found an issue? Let us know</li>
|
||||
<li><a href="https://gitea.brrd.tech/rob/CmdForge/issues" target="_blank">Report a Bug</a> - Found an issue? Let us know</li>
|
||||
</ul>
|
||||
""",
|
||||
"headings": [
|
||||
("what-is-smarttools", "What is SmartTools?"),
|
||||
("what-is-cmdforge", "What is CmdForge?"),
|
||||
("quick-start", "Quick Start"),
|
||||
("how-it-works", "How It Works"),
|
||||
("next-steps", "Next Steps"),
|
||||
|
|
@ -101,24 +101,24 @@ output: "{summary}"</code></pre>
|
|||
|
||||
"installation": {
|
||||
"title": "Installation",
|
||||
"description": "How to install SmartTools on your system",
|
||||
"description": "How to install CmdForge on your system",
|
||||
"parent": "getting-started",
|
||||
"content": """
|
||||
<p class="lead">SmartTools requires Python 3.8+ and works on Linux, macOS, and Windows.</p>
|
||||
<p class="lead">CmdForge requires Python 3.8+ and works on Linux, macOS, and Windows.</p>
|
||||
|
||||
<h2 id="pip-install">Install with pip</h2>
|
||||
<p>The simplest way to install SmartTools:</p>
|
||||
<pre><code class="language-bash">pip install smarttools</code></pre>
|
||||
<p>The simplest way to install CmdForge:</p>
|
||||
<pre><code class="language-bash">pip install cmdforge</code></pre>
|
||||
|
||||
<p>Or with pipx for isolated installation:</p>
|
||||
<pre><code class="language-bash">pipx install smarttools</code></pre>
|
||||
<pre><code class="language-bash">pipx install cmdforge</code></pre>
|
||||
|
||||
<h2 id="verify">Verify Installation</h2>
|
||||
<pre><code class="language-bash">smarttools --version
|
||||
smarttools --help</code></pre>
|
||||
<pre><code class="language-bash">cmdforge --version
|
||||
cmdforge --help</code></pre>
|
||||
|
||||
<h2 id="configure-provider">Configure a Provider</h2>
|
||||
<p>SmartTools needs at least one AI provider configured. The easiest is Claude CLI:</p>
|
||||
<p>CmdForge needs at least one AI provider configured. The easiest is Claude CLI:</p>
|
||||
|
||||
<pre><code class="language-bash"># Install Claude CLI (if you have an Anthropic API key)
|
||||
pip install claude-cli
|
||||
|
|
@ -127,17 +127,17 @@ pip install claude-cli
|
|||
pip install openai
|
||||
|
||||
# Configure your provider
|
||||
smarttools config</code></pre>
|
||||
cmdforge config</code></pre>
|
||||
|
||||
<h2 id="wrapper-scripts">Wrapper Scripts Location</h2>
|
||||
<p>SmartTools installs wrapper scripts to <code>~/.local/bin/</code>. Make sure this is in your PATH:</p>
|
||||
<p>CmdForge installs wrapper scripts to <code>~/.local/bin/</code>. Make sure this is in your PATH:</p>
|
||||
<pre><code class="language-bash"># Add to ~/.bashrc or ~/.zshrc
|
||||
export PATH="$HOME/.local/bin:$PATH"</code></pre>
|
||||
|
||||
<h2 id="development-install">Development Installation</h2>
|
||||
<p>To contribute or modify SmartTools:</p>
|
||||
<pre><code class="language-bash">git clone https://gitea.brrd.tech/rob/SmartTools.git
|
||||
cd SmartTools
|
||||
<p>To contribute or modify CmdForge:</p>
|
||||
<pre><code class="language-bash">git clone https://gitea.brrd.tech/rob/CmdForge.git
|
||||
cd CmdForge
|
||||
pip install -e ".[dev]"</code></pre>
|
||||
""",
|
||||
"headings": [
|
||||
|
|
@ -151,16 +151,16 @@ pip install -e ".[dev]"</code></pre>
|
|||
|
||||
"first-tool": {
|
||||
"title": "Your First Tool",
|
||||
"description": "Create your first SmartTools command step by step",
|
||||
"description": "Create your first CmdForge command step by step",
|
||||
"parent": "getting-started",
|
||||
"content": """
|
||||
<p class="lead">Let's create a simple tool that explains code. You'll learn the basics of tool configuration.</p>
|
||||
|
||||
<h2 id="create-tool">Create the Tool</h2>
|
||||
<p>Run the interactive creator:</p>
|
||||
<pre><code class="language-bash">smarttools create</code></pre>
|
||||
<pre><code class="language-bash">cmdforge create</code></pre>
|
||||
|
||||
<p>Or create the file manually at <code>~/.smarttools/explain/config.yaml</code>:</p>
|
||||
<p>Or create the file manually at <code>~/.cmdforge/explain/config.yaml</code>:</p>
|
||||
<pre><code class="language-yaml">name: explain
|
||||
version: "1.0.0"
|
||||
description: Explain code or concepts in simple terms
|
||||
|
|
@ -230,9 +230,9 @@ cat complex_algorithm.py | explain --level expert</code></pre>
|
|||
|
||||
"publishing": {
|
||||
"title": "Publishing Tools",
|
||||
"description": "Share your tools with the SmartTools community",
|
||||
"description": "Share your tools with the CmdForge community",
|
||||
"content": """
|
||||
<p class="lead">Share your tools with the community by publishing to the SmartTools Registry.</p>
|
||||
<p class="lead">Share your tools with the community by publishing to the CmdForge Registry.</p>
|
||||
|
||||
<h2 id="before-publishing">Before Publishing</h2>
|
||||
<p>Make sure your tool has:</p>
|
||||
|
|
@ -255,20 +255,20 @@ cat complex_algorithm.py | explain --level expert</code></pre>
|
|||
|
||||
<h2 id="publish">Publish Your Tool</h2>
|
||||
<pre><code class="language-bash"># Navigate to your tool directory
|
||||
cd ~/.smarttools/my-tool/
|
||||
cd ~/.cmdforge/my-tool/
|
||||
|
||||
# First time: enter your token when prompted
|
||||
smarttools registry publish
|
||||
cmdforge registry publish
|
||||
|
||||
# Dry run to validate without publishing
|
||||
smarttools registry publish --dry-run</code></pre>
|
||||
cmdforge registry publish --dry-run</code></pre>
|
||||
|
||||
<h2 id="versioning">Versioning</h2>
|
||||
<p>Published versions are <strong>immutable</strong>. To update a tool:</p>
|
||||
<ol>
|
||||
<li>Make your changes</li>
|
||||
<li>Bump the version in <code>config.yaml</code></li>
|
||||
<li>Run <code>smarttools registry publish</code></li>
|
||||
<li>Run <code>cmdforge registry publish</code></li>
|
||||
</ol>
|
||||
|
||||
<h2 id="best-practices">Best Practices</h2>
|
||||
|
|
@ -294,11 +294,11 @@ smarttools registry publish --dry-run</code></pre>
|
|||
"title": "AI Providers",
|
||||
"description": "Configure different AI providers for your tools",
|
||||
"content": """
|
||||
<p class="lead">SmartTools works with any AI provider that has a CLI interface. Configure providers in
|
||||
<code>~/.smarttools/providers.yaml</code>.</p>
|
||||
<p class="lead">CmdForge works with any AI provider that has a CLI interface. Configure providers in
|
||||
<code>~/.cmdforge/providers.yaml</code>.</p>
|
||||
|
||||
<h2 id="provider-config">Provider Configuration</h2>
|
||||
<p>Create or edit <code>~/.smarttools/providers.yaml</code>:</p>
|
||||
<p>Create or edit <code>~/.cmdforge/providers.yaml</code>:</p>
|
||||
|
||||
<pre><code class="language-yaml">providers:
|
||||
- name: claude
|
||||
|
|
@ -397,9 +397,9 @@ providers:
|
|||
|
||||
"parallel-orchestration": {
|
||||
"title": "Parallel Orchestration",
|
||||
"description": "Run multiple SmartTools concurrently for faster workflows",
|
||||
"description": "Run multiple CmdForge concurrently for faster workflows",
|
||||
"content": """
|
||||
<p class="lead">SmartTools executes steps sequentially within a tool, but you can run
|
||||
<p class="lead">CmdForge executes steps sequentially within a tool, but you can run
|
||||
<strong>multiple tools in parallel</strong> using Python's ThreadPoolExecutor. This pattern
|
||||
is ideal for multi-agent workflows, parallel analysis, or any task where you need responses
|
||||
from multiple AI providers simultaneously.</p>
|
||||
|
|
@ -412,7 +412,7 @@ from multiple AI providers simultaneously.</p>
|
|||
</ul>
|
||||
|
||||
<h2 id="basic-pattern">Basic Pattern</h2>
|
||||
<p>Use Python's <code>concurrent.futures</code> to run multiple SmartTools in parallel:</p>
|
||||
<p>Use Python's <code>concurrent.futures</code> to run multiple CmdForge in parallel:</p>
|
||||
|
||||
<pre><code class="language-python">import subprocess
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
|
@ -604,11 +604,11 @@ def run_with_progress(tools: list[str], input_text: str):
|
|||
</ul>
|
||||
|
||||
<h2 id="example-project">Full Example: orchestrated-discussions</h2>
|
||||
<p>For a complete implementation of parallel SmartTools orchestration, see the
|
||||
<p>For a complete implementation of parallel CmdForge orchestration, see the
|
||||
<a href="https://gitea.brrd.tech/rob/orchestrated-discussions" target="_blank">orchestrated-discussions</a>
|
||||
project. It implements:</p>
|
||||
<ul>
|
||||
<li>Multiple AI "participants" as SmartTools</li>
|
||||
<li>Multiple AI "participants" as CmdForge</li>
|
||||
<li>Parallel execution with live progress logging</li>
|
||||
<li>Shared log files for real-time monitoring</li>
|
||||
<li>Discussion workflows with voting and consensus</li>
|
||||
|
|
@ -656,7 +656,7 @@ steps:
|
|||
|
||||
output: "{result}"</code></pre>
|
||||
|
||||
<p>Save this to <code>~/.smarttools/shout/config.yaml</code> and you've got a working command:</p>
|
||||
<p>Save this to <code>~/.cmdforge/shout/config.yaml</code> and you've got a working command:</p>
|
||||
|
||||
<pre><code class="language-bash">$ echo "hello world" | shout
|
||||
HELLO WORLD!!!</code></pre>
|
||||
|
|
@ -1697,7 +1697,7 @@ loops, and more.</p>
|
|||
<li>Using different AI models for different tasks</li>
|
||||
<li>Building tools that adapt to their input</li>
|
||||
<li>Self-critiquing workflows that iterate to perfection</li>
|
||||
<li>Calling external tools from within your SmartTools</li>
|
||||
<li>Calling external tools from within your CmdForge</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
@ -1912,7 +1912,7 @@ output: "{result}"</code></pre>
|
|||
|
||||
<h2 id="external-tools">Calling External Tools</h2>
|
||||
|
||||
<p>SmartTools can wrap any command-line tool:</p>
|
||||
<p>CmdForge can wrap any command-line tool:</p>
|
||||
|
||||
<pre><code class="language-yaml">name: lint-explain
|
||||
version: "1.0.0"
|
||||
|
|
@ -2087,7 +2087,7 @@ output: "{formatted}"</code></pre>
|
|||
"title": "The Visual Builder",
|
||||
"description": "Build tools without touching YAML using the terminal UI",
|
||||
"content": """
|
||||
<p class="lead">Not everyone wants to write YAML by hand. SmartTools includes a full-featured
|
||||
<p class="lead">Not everyone wants to write YAML by hand. CmdForge includes a full-featured
|
||||
terminal UI that lets you create, edit, and test tools with menus and forms—no text editor required.</p>
|
||||
|
||||
<div class="bg-indigo-50 border-l-4 border-indigo-500 p-4 my-6">
|
||||
|
|
@ -2104,13 +2104,13 @@ terminal UI that lets you create, edit, and test tools with menus and forms—no
|
|||
|
||||
<p>Start the UI with a single command:</p>
|
||||
|
||||
<pre><code class="language-bash">smarttools ui</code></pre>
|
||||
<pre><code class="language-bash">cmdforge ui</code></pre>
|
||||
|
||||
<p>You'll see a menu-driven interface that works in any terminal:</p>
|
||||
|
||||
<div class="bg-gray-900 text-gray-100 rounded-lg p-4 my-6 font-mono text-sm">
|
||||
<pre>┌─────────────────────────────────────────────────────────┐
|
||||
│ SmartTools Manager │
|
||||
│ CmdForge Manager │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ [ List all tools ] │
|
||||
|
|
@ -2158,7 +2158,7 @@ terminal UI that lets you create, edit, and test tools with menus and forms—no
|
|||
<h3>Step-by-Step: Creating a Summarizer</h3>
|
||||
|
||||
<ol class="space-y-3">
|
||||
<li><strong>Launch:</strong> Run <code>smarttools ui</code></li>
|
||||
<li><strong>Launch:</strong> Run <code>cmdforge ui</code></li>
|
||||
<li><strong>Select:</strong> Choose "Create new tool"</li>
|
||||
<li><strong>Info:</strong> Go to "Info & Args", set name to <code>summarize</code></li>
|
||||
<li><strong>Add Argument:</strong> Click "Add Argument", set flag to <code>--length</code>, default to <code>100</code></li>
|
||||
|
|
@ -2243,7 +2243,7 @@ terminal UI that lets you create, edit, and test tools with menus and forms—no
|
|||
|
||||
<h2 id="ui-backends">UI Backends</h2>
|
||||
|
||||
<p>SmartTools automatically uses the best available terminal UI library:</p>
|
||||
<p>CmdForge automatically uses the best available terminal UI library:</p>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 my-6 text-sm">
|
||||
<div class="bg-green-50 border border-green-200 rounded-lg p-3">
|
||||
|
|
@ -2276,7 +2276,7 @@ terminal UI that lets you create, edit, and test tools with menus and forms—no
|
|||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b">
|
||||
<td class="px-4 py-2">You're new to SmartTools</td>
|
||||
<td class="px-4 py-2">You're new to CmdForge</td>
|
||||
<td class="px-4 py-2">You're comfortable with YAML</td>
|
||||
</tr>
|
||||
<tr class="border-b">
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
"""Forum blueprint for CmdForge community discussions."""
|
||||
|
||||
from .routes import forum_bp
|
||||
|
||||
__all__ = ["forum_bp"]
|
||||
|
|
@ -6,7 +6,7 @@ import re
|
|||
import sqlite3
|
||||
from typing import Any
|
||||
|
||||
from smarttools.registry.db import connect_db, query_one, query_all
|
||||
from cmdforge.registry.db import connect_db, query_one, query_all
|
||||
|
||||
|
||||
FORUM_SCHEMA = """
|
||||
|
|
@ -51,9 +51,9 @@ CREATE INDEX IF NOT EXISTS idx_forum_replies_topic ON forum_replies(topic_id);
|
|||
"""
|
||||
|
||||
DEFAULT_CATEGORIES = [
|
||||
("general", "General Discussion", "Chat about anything SmartTools related", "chat", 1),
|
||||
("general", "General Discussion", "Chat about anything CmdForge related", "chat", 1),
|
||||
("help", "Help & Support", "Get help with installation, configuration, or usage", "question", 2),
|
||||
("showcase", "Showcase", "Share tools and projects you've built with SmartTools", "star", 3),
|
||||
("showcase", "Showcase", "Share tools and projects you've built with CmdForge", "star", 3),
|
||||
("ideas", "Ideas & Feedback", "Suggest features and improvements", "lightbulb", 4),
|
||||
("tutorials", "Tutorials & Guides", "Community-written guides and how-tos", "book", 5),
|
||||
]
|
||||
|
|
@ -19,7 +19,7 @@ from flask import (
|
|||
url_for,
|
||||
)
|
||||
|
||||
from smarttools.registry.db import connect_db
|
||||
from cmdforge.registry.db import connect_db
|
||||
|
||||
from .models import (
|
||||
create_reply,
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Public web routes for the SmartTools UI."""
|
||||
"""Public web routes for the CmdForge UI."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
|||
from markupsafe import Markup, escape
|
||||
from flask import current_app, redirect, render_template, request, session, url_for
|
||||
|
||||
from smarttools.registry.db import connect_db, query_all, query_one
|
||||
from cmdforge.registry.db import connect_db, query_all, query_one
|
||||
|
||||
from . import web_bp
|
||||
|
||||
|
|
@ -499,7 +499,7 @@ def docs(path: str):
|
|||
else:
|
||||
page = SimpleNamespace(
|
||||
title=_title_case(current),
|
||||
description="SmartTools documentation",
|
||||
description="CmdForge documentation",
|
||||
content_html=Markup(f"<p>Documentation for <strong>{escape(current)}</strong> is coming soon.</p>"),
|
||||
headings=[],
|
||||
parent=None,
|
||||
|
|
@ -7,7 +7,7 @@ from typing import List
|
|||
|
||||
from flask import Response, current_app, url_for
|
||||
|
||||
from smarttools.registry.db import connect_db, query_all
|
||||
from cmdforge.registry.db import connect_db, query_all
|
||||
|
||||
SITEMAP_TTL = timedelta(hours=6)
|
||||
_sitemap_cache = {"generated_at": None, "xml": ""}
|
||||
|
|
@ -10,7 +10,7 @@ from typing import Optional
|
|||
from flask.sessions import SessionInterface, SessionMixin
|
||||
from werkzeug.datastructures import CallbackDict
|
||||
|
||||
from smarttools.registry.db import connect_db
|
||||
from cmdforge.registry.db import connect_db
|
||||
|
||||
SESSION_TTL = timedelta(days=7)
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ class SQLiteSession(CallbackDict, SessionMixin):
|
|||
|
||||
|
||||
class SQLiteSessionInterface(SessionInterface):
|
||||
def __init__(self, cookie_name: str = "smarttools_session"):
|
||||
def __init__(self, cookie_name: str = "cmdforge_session"):
|
||||
self.cookie_name = cookie_name
|
||||
|
||||
def open_session(self, app, request):
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* SmartTools Web UI - Main JavaScript
|
||||
* CmdForge Web UI - Main JavaScript
|
||||
*/
|
||||
|
||||
// Copy to clipboard utility
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# SmartTools Registry - robots.txt
|
||||
# CmdForge Registry - robots.txt
|
||||
# We welcome all crawlers! Index everything to help users find us
|
||||
# and enable AI assistants to help solve SmartTools issues.
|
||||
# and enable AI assistants to help solve CmdForge issues.
|
||||
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
|
@ -11,7 +11,7 @@ Allow: /tutorials/
|
|||
Allow: /tools/
|
||||
Allow: /categories/
|
||||
|
||||
# Allow AI crawlers explicitly (we want AI to learn about SmartTools)
|
||||
# Allow AI crawlers explicitly (we want AI to learn about CmdForge)
|
||||
User-agent: GPTBot
|
||||
Allow: /
|
||||
|
||||
|
|
@ -42,6 +42,6 @@ Disallow: /api/v1/tokens
|
|||
Allow: /api/
|
||||
|
||||
# Sitemap location
|
||||
Sitemap: https://registry.smarttools.dev/sitemap.xml
|
||||
Sitemap: https://cmdforge.brrd.tech/sitemap.xml
|
||||
|
||||
# Crawl-delay: none - crawl as fast as you want!
|
||||
|
|
@ -3,14 +3,14 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}SmartTools{% endblock %} - Build Custom AI Commands</title>
|
||||
<title>{% block title %}CmdForge{% endblock %} - Build Custom AI Commands</title>
|
||||
|
||||
<!-- Meta tags -->
|
||||
<meta name="description" content="{% block meta_description %}Create Unix-style pipeable tools that work with any AI provider. Provider-agnostic, composable, and community-driven.{% endblock %}">
|
||||
{% block meta_extra %}{% endblock %}
|
||||
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:title" content="{% block og_title %}SmartTools{% endblock %}">
|
||||
<meta property="og:title" content="{% block og_title %}CmdForge{% endblock %}">
|
||||
<meta property="og:description" content="{% block og_description %}Build custom AI commands in YAML{% endblock %}">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="{{ request.url }}">
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="{% block twitter_title %}SmartTools{% endblock %}">
|
||||
<meta name="twitter:title" content="{% block twitter_title %}CmdForge{% endblock %}">
|
||||
<meta name="twitter:description" content="{% block twitter_description %}Build custom AI commands in YAML{% endblock %}">
|
||||
{% block twitter_extra %}{% endblock %}
|
||||
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "SmartTools",
|
||||
"name": "CmdForge",
|
||||
"url": "{{ request.host_url }}",
|
||||
"description": "Build custom AI commands in YAML"
|
||||
}
|
||||
|
|
@ -3,19 +3,19 @@
|
|||
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
||||
<!-- Brand -->
|
||||
<div class="col-span-1 md:col-span-2">
|
||||
<a href="{{ url_for('web.index') }}" class="text-xl font-bold">SmartTools</a>
|
||||
<a href="{{ url_for('web.index') }}" class="text-xl font-bold">CmdForge</a>
|
||||
<p class="mt-2 text-gray-400 text-sm max-w-md">
|
||||
Build custom AI commands in YAML. Create Unix-style pipeable tools that work with any AI provider.
|
||||
Provider-agnostic, composable, and community-driven.
|
||||
</p>
|
||||
<div class="mt-4 flex space-x-4">
|
||||
<a href="https://github.com/rob/smarttools" target="_blank" rel="noopener noreferrer"
|
||||
<a href="https://github.com/rob/cmdforge" target="_blank" rel="noopener noreferrer"
|
||||
class="text-gray-400 hover:text-white transition-colors" aria-label="GitHub">
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="https://twitter.com/smarttools" target="_blank" rel="noopener noreferrer"
|
||||
<a href="https://twitter.com/cmdforge" target="_blank" rel="noopener noreferrer"
|
||||
class="text-gray-400 hover:text-white transition-colors" aria-label="Twitter">
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0022 5.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.072 4.072 0 012.8 9.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 012 18.407a11.616 11.616 0 006.29 1.84"/>
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
|
||||
<div class="mt-8 pt-8 border-t border-slate-700 flex flex-col sm:flex-row justify-between items-center">
|
||||
<p class="text-gray-400 text-sm">
|
||||
© {{ now().year }} SmartTools. Open source under MIT License.
|
||||
© {{ now().year }} CmdForge. Open source under MIT License.
|
||||
</p>
|
||||
<p class="text-gray-300 text-xs mt-2 sm:mt-0">
|
||||
Made with care for the developer community.
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<!-- Logo -->
|
||||
<div class="flex-shrink-0">
|
||||
<a href="{{ url_for('web.index') }}" class="text-xl font-bold hover:text-indigo-400 transition-colors">
|
||||
SmartTools
|
||||
CmdForge
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
|
@ -54,10 +54,10 @@
|
|||
<div class="mt-4">
|
||||
<div class="flex items-center bg-gray-100 rounded px-3 py-2 group">
|
||||
<code class="text-xs text-gray-700 flex-1 truncate font-mono">
|
||||
smarttools install {{ tool.owner }}/{{ tool.name }}
|
||||
cmdforge install {{ tool.owner }}/{{ tool.name }}
|
||||
</code>
|
||||
<button type="button"
|
||||
onclick="copyToClipboard('smarttools install {{ tool.owner }}/{{ tool.name }}')"
|
||||
onclick="copyToClipboard('cmdforge install {{ tool.owner }}/{{ tool.name }}')"
|
||||
class="ml-2 p-1 text-gray-400 hover:text-gray-600 opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
aria-label="Copy install command">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
</a>
|
||||
</h3>
|
||||
<p class="mt-2 text-sm text-gray-600 line-clamp-2">
|
||||
{{ tutorial.description or 'Learn how to use SmartTools effectively.' }}
|
||||
{{ tutorial.description or 'Learn how to use CmdForge effectively.' }}
|
||||
</p>
|
||||
<a href="{{ href or '#' }}"
|
||||
class="mt-4 inline-flex items-center text-sm font-medium text-indigo-600 hover:text-indigo-800 transition-colors">
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "dashboard/base.html" %}
|
||||
{% set active_page = 'overview' %}
|
||||
|
||||
{% block title %}Dashboard - SmartTools{% endblock %}
|
||||
{% block title %}Dashboard - CmdForge{% endblock %}
|
||||
|
||||
{% block dashboard_content %}
|
||||
<!-- Stats Cards -->
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
{% from "components/forms.html" import text_input, textarea, button_primary, form_errors, success_alert %}
|
||||
{% set active_page = 'settings' %}
|
||||
|
||||
{% block title %}Settings - SmartTools Dashboard{% endblock %}
|
||||
{% block title %}Settings - CmdForge Dashboard{% endblock %}
|
||||
|
||||
{% block dashboard_header %}
|
||||
<h1 class="text-2xl font-bold text-gray-900">Settings</h1>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "dashboard/base.html" %}
|
||||
{% set active_page = 'tokens' %}
|
||||
|
||||
{% block title %}API Tokens - SmartTools Dashboard{% endblock %}
|
||||
{% block title %}API Tokens - CmdForge Dashboard{% endblock %}
|
||||
|
||||
{% block dashboard_header %}
|
||||
<div class="flex items-center justify-between">
|
||||
|
|
@ -30,9 +30,9 @@
|
|||
<div class="ml-3">
|
||||
<h4 class="text-sm font-medium text-blue-800">About API Tokens</h4>
|
||||
<p class="mt-1 text-sm text-blue-700">
|
||||
API tokens are used to authenticate with the SmartTools registry from the CLI.
|
||||
Use <code class="px-1 bg-blue-100 rounded">smarttools auth login</code> to authenticate,
|
||||
or set the <code class="px-1 bg-blue-100 rounded">SMARTTOOLS_TOKEN</code> environment variable.
|
||||
API tokens are used to authenticate with the CmdForge registry from the CLI.
|
||||
Use <code class="px-1 bg-blue-100 rounded">cmdforge auth login</code> to authenticate,
|
||||
or set the <code class="px-1 bg-blue-100 rounded">CMDFORGE_TOKEN</code> environment variable.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -215,7 +215,7 @@
|
|||
<p class="mt-4 text-sm text-gray-600">
|
||||
To use this token, run:
|
||||
</p>
|
||||
<pre class="mt-2 bg-gray-900 text-gray-100 text-sm p-3 rounded-lg overflow-x-auto"><code>export SMARTTOOLS_TOKEN="<span id="token-in-export"></span>"</code></pre>
|
||||
<pre class="mt-2 bg-gray-900 text-gray-100 text-sm p-3 rounded-lg overflow-x-auto"><code>export CMDFORGE_TOKEN="<span id="token-in-export"></span>"</code></pre>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-50 px-6 py-4 rounded-b-lg flex justify-end">
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "dashboard/base.html" %}
|
||||
{% set active_page = 'tools' %}
|
||||
|
||||
{% block title %}My Tools - SmartTools Dashboard{% endblock %}
|
||||
{% block title %}My Tools - CmdForge Dashboard{% endblock %}
|
||||
|
||||
{% block dashboard_header %}
|
||||
<div class="flex items-center justify-between">
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Page Not Found - SmartTools{% endblock %}
|
||||
{% block title %}Page Not Found - CmdForge{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[60vh] flex items-center justify-center px-4">
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Server Error - SmartTools{% endblock %}
|
||||
{% block title %}Server Error - CmdForge{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[60vh] flex items-center justify-center px-4">
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
class="w-full sm:w-auto inline-flex justify-center items-center px-6 py-3 text-base font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700">
|
||||
Go Home
|
||||
</a>
|
||||
<a href="https://github.com/your-org/smarttools/issues"
|
||||
<a href="https://github.com/your-org/cmdforge/issues"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="w-full sm:w-auto inline-flex justify-center items-center px-6 py-3 text-base font-medium text-gray-700 border border-gray-300 rounded-md hover:bg-gray-50">
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{% block title %}Community Forum{% endblock %}
|
||||
|
||||
{% block meta_description %}Join the SmartTools community. Ask questions, share your projects, and connect with other users.{% endblock %}
|
||||
{% block meta_description %}Join the CmdForge community. Ask questions, share your projects, and connect with other users.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<h1 class="text-3xl font-bold text-gray-900">Community Forum</h1>
|
||||
<p class="mt-2 text-gray-600">
|
||||
Ask questions, share your projects, and connect with other SmartTools users.
|
||||
Ask questions, share your projects, and connect with other CmdForge users.
|
||||
</p>
|
||||
<div class="mt-4 flex items-center gap-6 text-sm text-gray-500">
|
||||
<span>{{ stats.topics }} topics</span>
|
||||
|
|
@ -119,7 +119,7 @@
|
|||
</svg>
|
||||
Browse Tools
|
||||
</a>
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools/issues"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge/issues"
|
||||
target="_blank" rel="noopener"
|
||||
class="flex items-center text-sm text-gray-600 hover:text-indigo-600">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}About - SmartTools{% endblock %}
|
||||
{% block title %}About - CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}Learn about SmartTools, the open-source platform for building custom AI-powered command-line tools.{% endblock %}
|
||||
{% block meta_description %}Learn about CmdForge, the open-source platform for building custom AI-powered command-line tools.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-white">
|
||||
<!-- Hero -->
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16 text-center">
|
||||
<h1 class="text-4xl font-bold text-gray-900">About SmartTools</h1>
|
||||
<h1 class="text-4xl font-bold text-gray-900">About CmdForge</h1>
|
||||
<p class="mt-6 text-xl text-gray-600">
|
||||
An open-source platform for building and sharing AI-powered command-line tools.
|
||||
</p>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Our Mission</h2>
|
||||
<div class="prose prose-lg prose-indigo max-w-none">
|
||||
<p>
|
||||
SmartTools was created with a simple belief: powerful AI tools should be accessible to everyone,
|
||||
CmdForge was created with a simple belief: powerful AI tools should be accessible to everyone,
|
||||
not just those with extensive programming knowledge or expensive API subscriptions.
|
||||
</p>
|
||||
<p>
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
</p>
|
||||
<p>
|
||||
Our platform follows the Unix philosophy: simple, composable tools that do one thing well.
|
||||
With SmartTools, you can create custom AI commands using simple YAML configuration,
|
||||
With CmdForge, you can create custom AI commands using simple YAML configuration,
|
||||
chain them together, and share them with the community.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
</div>
|
||||
<h3 class="text-lg font-semibold text-gray-900 mb-2">Open Source</h3>
|
||||
<p class="text-gray-600">
|
||||
SmartTools is MIT licensed and open source. We believe in transparency and community ownership.
|
||||
CmdForge is MIT licensed and open source. We believe in transparency and community ownership.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -98,7 +98,7 @@
|
|||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Sustainability</h2>
|
||||
<div class="prose prose-lg prose-indigo max-w-none">
|
||||
<p>
|
||||
SmartTools is committed to long-term sustainability. Revenue from optional ads
|
||||
CmdForge is committed to long-term sustainability. Revenue from optional ads
|
||||
and donations supports:
|
||||
</p>
|
||||
<ul>
|
||||
|
|
@ -121,9 +121,9 @@
|
|||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Contribute</h2>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
SmartTools is open source and welcomes contributions of all kinds.
|
||||
CmdForge is open source and welcomes contributions of all kinds.
|
||||
</p>
|
||||
<a href="https://github.com/your-org/smarttools"
|
||||
<a href="https://github.com/your-org/cmdforge"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center px-6 py-3 text-base font-medium text-white bg-gray-900 rounded-md hover:bg-gray-800">
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Community - SmartTools{% endblock %}
|
||||
{% block title %}Community - CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}Connect with SmartTools - report issues, request features, and contribute to the project.{% endblock %}
|
||||
{% block meta_description %}Connect with CmdForge - report issues, request features, and contribute to the project.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12 text-center">
|
||||
<h1 class="text-3xl font-bold text-gray-900">Community</h1>
|
||||
<p class="mt-4 text-lg text-gray-600">
|
||||
SmartTools is open source. Get help, report issues, and contribute.
|
||||
CmdForge is open source. Get help, report issues, and contribute.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
<p class="mt-2 text-sm text-gray-600">
|
||||
Browse the source, fork the project, and submit pull requests.
|
||||
</p>
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge"
|
||||
target="_blank" rel="noopener"
|
||||
class="mt-4 inline-flex items-center text-sm font-medium text-indigo-600 hover:text-indigo-800">
|
||||
View Repository
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
<p class="mt-2 text-sm text-gray-600">
|
||||
Found a bug? Have a feature request? Open an issue.
|
||||
</p>
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools/issues"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge/issues"
|
||||
target="_blank" rel="noopener"
|
||||
class="mt-4 inline-flex items-center text-sm font-medium text-indigo-600 hover:text-indigo-800">
|
||||
Open Issue
|
||||
|
|
@ -137,7 +137,7 @@
|
|||
<div>
|
||||
<h3 class="font-semibold text-gray-900">Report Bugs</h3>
|
||||
<p class="mt-1 text-sm text-gray-600">
|
||||
Help make SmartTools better by reporting issues with clear reproduction steps.
|
||||
Help make CmdForge better by reporting issues with clear reproduction steps.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -163,7 +163,7 @@
|
|||
class="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700">
|
||||
Visit Forum
|
||||
</a>
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools#installation"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge#installation"
|
||||
target="_blank" rel="noopener"
|
||||
class="inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50">
|
||||
Installation
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ title }} - SmartTools{% endblock %}
|
||||
{% block title %}{{ title }} - CmdForge{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="bg-white py-16">
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% from "components/callouts.html" import info, warning, tip %}
|
||||
|
||||
{% block title %}{{ page.title }} - SmartTools Docs{% endblock %}
|
||||
{% block title %}{{ page.title }} - CmdForge Docs{% endblock %}
|
||||
|
||||
{% block meta_description %}{{ page.description or page.title }}{% endblock %}
|
||||
|
||||
|
|
@ -124,7 +124,7 @@
|
|||
|
||||
<!-- Edit on GitHub -->
|
||||
<div class="mt-6 text-center">
|
||||
<a href="https://github.com/your-org/smarttools/edit/main/docs/{{ current_path }}.md"
|
||||
<a href="https://github.com/your-org/cmdforge/edit/main/docs/{{ current_path }}.md"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center text-sm text-gray-500 hover:text-gray-700">
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Support SmartTools{% endblock %}
|
||||
{% block title %}Support CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}Support SmartTools by contributing code, tools, or feedback.{% endblock %}
|
||||
{% block meta_description %}Support CmdForge by contributing code, tools, or feedback.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
<!-- Hero -->
|
||||
<div class="bg-white border-b border-gray-200">
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12 text-center">
|
||||
<h1 class="text-3xl font-bold text-gray-900">Support SmartTools</h1>
|
||||
<h1 class="text-3xl font-bold text-gray-900">Support CmdForge</h1>
|
||||
<p class="mt-4 text-lg text-gray-600">
|
||||
SmartTools is a passion project. The best way to support it is to use it and share what you build.
|
||||
CmdForge is a passion project. The best way to support it is to use it and share what you build.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
</div>
|
||||
<h2 class="text-lg font-semibold text-gray-900">Spread the Word</h2>
|
||||
<p class="mt-2 text-sm text-gray-600">
|
||||
Tell a friend or colleague who might find SmartTools useful.
|
||||
Tell a friend or colleague who might find CmdForge useful.
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-lg border border-gray-200 p-6">
|
||||
|
|
@ -58,10 +58,10 @@
|
|||
<section class="bg-white rounded-lg border border-gray-200 p-8 text-center">
|
||||
<h2 class="text-2xl font-bold text-gray-900">Get Involved</h2>
|
||||
<p class="mt-3 text-gray-600 max-w-2xl mx-auto">
|
||||
SmartTools is open source. The code, docs, and registry are all open for contributions.
|
||||
CmdForge is open source. The code, docs, and registry are all open for contributions.
|
||||
</p>
|
||||
<div class="mt-6 flex flex-col sm:flex-row items-center justify-center gap-4">
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge"
|
||||
target="_blank" rel="noopener"
|
||||
class="inline-flex items-center px-6 py-3 text-sm font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
|
||||
|
|
@ -79,7 +79,7 @@
|
|||
<!-- Thank you -->
|
||||
<section class="mt-12 text-center">
|
||||
<p class="text-gray-500">
|
||||
Thanks for using SmartTools!
|
||||
Thanks for using CmdForge!
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
{% from "components/tutorial_card.html" import tutorial_card %}
|
||||
{% from "components/contributor_card.html" import contributor_card %}
|
||||
|
||||
{% block title %}SmartTools - Build Custom AI Commands in YAML{% endblock %}
|
||||
{% block title %}CmdForge - Build Custom AI Commands in YAML{% endblock %}
|
||||
|
||||
{% block meta_description %}Create Unix-style pipeable AI tools with simple YAML configuration. Provider-agnostic, composable, and community-driven.{% endblock %}
|
||||
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<!-- Install Link -->
|
||||
<div class="mt-10">
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools#installation"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge#installation"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="inline-flex items-center gap-2 text-indigo-600 hover:text-indigo-800 font-medium transition-colors">
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
<section class="py-16 bg-gray-50">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<h2 class="text-3xl font-bold text-gray-900 text-center mb-12">
|
||||
Why SmartTools?
|
||||
Why CmdForge?
|
||||
</h2>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
|
|
@ -144,7 +144,7 @@
|
|||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{{ tutorial_card(
|
||||
title="Basic Setup",
|
||||
description="Learn how to install SmartTools and configure your first AI provider.",
|
||||
description="Learn how to install CmdForge and configure your first AI provider.",
|
||||
href=url_for('web.docs', path='getting-started'),
|
||||
step_number=1
|
||||
) }}
|
||||
|
|
@ -191,7 +191,7 @@
|
|||
<p class="text-xs text-gray-500 mb-2">Advertisement</p>
|
||||
<div id="footer-ad-zone" class="min-h-[90px] flex items-center justify-center">
|
||||
<!-- Ad content loaded dynamically -->
|
||||
<p class="text-gray-400 text-sm">Support SmartTools Development</p>
|
||||
<p class="text-gray-400 text-sm">Support CmdForge Development</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% from "components/forms.html" import text_input, button_primary, form_errors %}
|
||||
|
||||
{% block title %}Sign In - SmartTools{% endblock %}
|
||||
{% block title %}Sign In - CmdForge{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[70vh] flex items-center justify-center px-4 py-12">
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
<path d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<h1 class="mt-4 text-2xl font-bold text-gray-900">Sign in to SmartTools</h1>
|
||||
<h1 class="mt-4 text-2xl font-bold text-gray-900">Sign in to CmdForge</h1>
|
||||
<p class="mt-2 text-gray-600">
|
||||
Access your dashboard and manage your tools
|
||||
</p>
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Privacy Policy - SmartTools{% endblock %}
|
||||
{% block title %}Privacy Policy - CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}SmartTools privacy policy. Learn how we collect, use, and protect your data.{% endblock %}
|
||||
{% block meta_description %}CmdForge privacy policy. Learn how we collect, use, and protect your data.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-white py-16">
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
<div class="prose prose-lg prose-indigo max-w-none">
|
||||
<h2>Introduction</h2>
|
||||
<p>
|
||||
SmartTools ("we", "our", or "us") respects your privacy and is committed to protecting
|
||||
CmdForge ("we", "our", or "us") respects your privacy and is committed to protecting
|
||||
your personal data. This privacy policy explains how we collect, use, and safeguard
|
||||
your information when you use our website and services.
|
||||
</p>
|
||||
|
|
@ -121,8 +121,8 @@
|
|||
contact us at:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Email: privacy@smarttools.dev</li>
|
||||
<li>GitHub: <a href="https://github.com/your-org/smarttools/issues">Open an issue</a></li>
|
||||
<li>Email: privacy@cmdforge.dev</li>
|
||||
<li>GitHub: <a href="https://github.com/your-org/cmdforge/issues">Open an issue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
{% extends "base.html" %}
|
||||
{% from "components/tool_card.html" import tool_card %}
|
||||
|
||||
{% block title %}{{ publisher.display_name }} (@{{ publisher.slug }}) - SmartTools{% endblock %}
|
||||
{% block title %}{{ publisher.display_name }} (@{{ publisher.slug }}) - CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}{{ publisher.bio or 'SmartTools publisher profile for ' ~ publisher.display_name }}{% endblock %}
|
||||
{% block meta_description %}{{ publisher.bio or 'CmdForge publisher profile for ' ~ publisher.display_name }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% from "components/forms.html" import text_input, button_primary, form_errors, checkbox %}
|
||||
|
||||
{% block title %}Create Account - SmartTools{% endblock %}
|
||||
{% block title %}Create Account - CmdForge{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[70vh] flex items-center justify-center px-4 py-12">
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
{% extends "base.html" %}
|
||||
{% from "components/tool_card.html" import tool_card %}
|
||||
|
||||
{% block title %}Search: {{ query }} - SmartTools Registry{% endblock %}
|
||||
{% block title %}Search: {{ query }} - CmdForge Registry{% endblock %}
|
||||
|
||||
{% block meta_description %}Search results for "{{ query }}" in the SmartTools Registry.{% endblock %}
|
||||
{% block meta_description %}Search results for "{{ query }}" in the CmdForge Registry.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Terms of Service - SmartTools{% endblock %}
|
||||
{% block title %}Terms of Service - CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}SmartTools terms of service. Read our terms and conditions for using the platform.{% endblock %}
|
||||
{% block meta_description %}CmdForge terms of service. Read our terms and conditions for using the platform.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-white py-16">
|
||||
|
|
@ -13,19 +13,19 @@
|
|||
<div class="prose prose-lg prose-indigo max-w-none">
|
||||
<h2>1. Acceptance of Terms</h2>
|
||||
<p>
|
||||
By accessing or using SmartTools ("the Service"), you agree to be bound by these
|
||||
By accessing or using CmdForge ("the Service"), you agree to be bound by these
|
||||
Terms of Service ("Terms"). If you do not agree to these Terms, you may not use
|
||||
the Service.
|
||||
</p>
|
||||
|
||||
<h2>2. Description of Service</h2>
|
||||
<p>
|
||||
SmartTools is a platform for creating, publishing, and sharing AI-powered
|
||||
CmdForge is a platform for creating, publishing, and sharing AI-powered
|
||||
command-line tools. The Service includes:
|
||||
</p>
|
||||
<ul>
|
||||
<li>The SmartTools CLI application</li>
|
||||
<li>The SmartTools Registry (tool hosting and discovery)</li>
|
||||
<li>The CmdForge CLI application</li>
|
||||
<li>The CmdForge Registry (tool hosting and discovery)</li>
|
||||
<li>Documentation and tutorials</li>
|
||||
<li>Community features</li>
|
||||
</ul>
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
<h3>4.1 Your Content</h3>
|
||||
<p>
|
||||
You retain ownership of tools and content you publish ("User Content"). By publishing
|
||||
to the Registry, you grant SmartTools a non-exclusive, worldwide license to host,
|
||||
to the Registry, you grant CmdForge a non-exclusive, worldwide license to host,
|
||||
distribute, and display your User Content.
|
||||
</p>
|
||||
|
||||
|
|
@ -80,22 +80,22 @@
|
|||
|
||||
<h2>6. API and CLI Usage</h2>
|
||||
<p>
|
||||
Access to the SmartTools API and CLI is subject to rate limits. Excessive use
|
||||
Access to the CmdForge API and CLI is subject to rate limits. Excessive use
|
||||
that impacts service availability for others may result in temporary or permanent
|
||||
restrictions.
|
||||
</p>
|
||||
|
||||
<h2>7. Third-Party Services</h2>
|
||||
<p>
|
||||
SmartTools is designed to work with various AI providers and external services.
|
||||
CmdForge is designed to work with various AI providers and external services.
|
||||
Your use of these third-party services is subject to their respective terms and
|
||||
conditions. We are not responsible for third-party services.
|
||||
</p>
|
||||
|
||||
<h2>8. Intellectual Property</h2>
|
||||
<p>
|
||||
The SmartTools software is open source and licensed under the MIT License.
|
||||
The SmartTools name, logo, and branding are trademarks of SmartTools.
|
||||
The CmdForge software is open source and licensed under the MIT License.
|
||||
The CmdForge name, logo, and branding are trademarks of CmdForge.
|
||||
</p>
|
||||
|
||||
<h2>9. Disclaimer of Warranties</h2>
|
||||
|
|
@ -104,20 +104,20 @@
|
|||
WE DO NOT WARRANT THAT THE SERVICE WILL BE UNINTERRUPTED, ERROR-FREE, OR SECURE.
|
||||
</p>
|
||||
<p>
|
||||
Tools published by third parties are not endorsed by SmartTools. You use third-party
|
||||
Tools published by third parties are not endorsed by CmdForge. You use third-party
|
||||
tools at your own risk.
|
||||
</p>
|
||||
|
||||
<h2>10. Limitation of Liability</h2>
|
||||
<p>
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY LAW, SMARTTOOLS SHALL NOT BE LIABLE FOR ANY
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY LAW, CMDFORGE SHALL NOT BE LIABLE FOR ANY
|
||||
INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES ARISING FROM
|
||||
YOUR USE OF THE SERVICE.
|
||||
</p>
|
||||
|
||||
<h2>11. Indemnification</h2>
|
||||
<p>
|
||||
You agree to indemnify and hold harmless SmartTools and its contributors from
|
||||
You agree to indemnify and hold harmless CmdForge and its contributors from
|
||||
any claims, damages, or expenses arising from your use of the Service or
|
||||
violation of these Terms.
|
||||
</p>
|
||||
|
|
@ -140,7 +140,7 @@
|
|||
|
||||
<h2>14. Governing Law</h2>
|
||||
<p>
|
||||
These Terms are governed by the laws of the jurisdiction in which SmartTools
|
||||
These Terms are governed by the laws of the jurisdiction in which CmdForge
|
||||
operates, without regard to conflict of law principles.
|
||||
</p>
|
||||
|
||||
|
|
@ -149,8 +149,8 @@
|
|||
For questions about these Terms, please contact us at:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Email: legal@smarttools.dev</li>
|
||||
<li>GitHub: <a href="https://github.com/your-org/smarttools/issues">Open an issue</a></li>
|
||||
<li>Email: legal@cmdforge.dev</li>
|
||||
<li>GitHub: <a href="https://github.com/your-org/cmdforge/issues">Open an issue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue