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