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 <[email protected]>
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
"""CmdForge - A lightweight personal tool builder for AI-powered CLI commands."""
|
||||
|
||||
__version__ = "0.1.0"
|
||||
@@ -1,4 +1,4 @@
|
||||
"""CLI entry point for SmartTools.
|
||||
"""CLI entry point for CmdForge.
|
||||
|
||||
This module is a thin wrapper for backwards compatibility.
|
||||
The actual implementation is in the cli/ package.
|
||||
@@ -1,4 +1,4 @@
|
||||
"""CLI entry point for SmartTools."""
|
||||
"""CLI entry point for CmdForge."""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
@@ -18,7 +18,7 @@ from .config_commands import cmd_config
|
||||
def main():
|
||||
"""Main CLI entry point."""
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="smarttools",
|
||||
prog="cmdforge",
|
||||
description="A lightweight personal tool builder for AI-powered CLI commands"
|
||||
)
|
||||
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
|
||||
@@ -179,7 +179,7 @@ def main():
|
||||
p_deps.set_defaults(func=cmd_deps)
|
||||
|
||||
# 'install' command (for dependencies)
|
||||
p_install = subparsers.add_parser("install", help="Install dependencies from smarttools.yaml")
|
||||
p_install = subparsers.add_parser("install", help="Install dependencies from cmdforge.yaml")
|
||||
p_install.set_defaults(func=cmd_install_deps)
|
||||
|
||||
# 'add' command
|
||||
@@ -190,7 +190,7 @@ def main():
|
||||
p_add.set_defaults(func=cmd_add)
|
||||
|
||||
# 'init' command
|
||||
p_init = subparsers.add_parser("init", help="Initialize smarttools.yaml")
|
||||
p_init = subparsers.add_parser("init", help="Initialize cmdforge.yaml")
|
||||
p_init.add_argument("-n", "--name", help="Project name")
|
||||
p_init.add_argument("-v", "--version", help="Project version")
|
||||
p_init.add_argument("-f", "--force", action="store_true", help="Overwrite existing")
|
||||
@@ -4,7 +4,7 @@ from ..config import load_config, save_config, set_registry_token
|
||||
|
||||
|
||||
def cmd_config(args):
|
||||
"""Manage SmartTools configuration."""
|
||||
"""Manage CmdForge configuration."""
|
||||
if args.config_cmd == "show":
|
||||
return _cmd_config_show(args)
|
||||
elif args.config_cmd == "set-token":
|
||||
@@ -22,7 +22,7 @@ def cmd_config(args):
|
||||
def _cmd_config_show(args):
|
||||
"""Show current configuration."""
|
||||
config = load_config()
|
||||
print("SmartTools Configuration:")
|
||||
print("CmdForge Configuration:")
|
||||
print(f" Registry URL: {config.registry.url}")
|
||||
print(f" Token: {'***' if config.registry.token else '(not set)'}")
|
||||
print(f" Client ID: {config.client_id}")
|
||||
@@ -13,12 +13,12 @@ from ..resolver import (
|
||||
|
||||
|
||||
def cmd_deps(args):
|
||||
"""Show project dependencies from smarttools.yaml."""
|
||||
"""Show project dependencies from cmdforge.yaml."""
|
||||
manifest = load_manifest()
|
||||
|
||||
if manifest is None:
|
||||
print("No smarttools.yaml found in current project.")
|
||||
print("Create one with: smarttools init")
|
||||
print("No cmdforge.yaml found in current project.")
|
||||
print("Create one with: cmdforge init")
|
||||
return 1
|
||||
|
||||
print(f"Project: {manifest.name} v{manifest.version}")
|
||||
@@ -26,7 +26,7 @@ def cmd_deps(args):
|
||||
|
||||
if not manifest.dependencies:
|
||||
print("No dependencies defined.")
|
||||
print("Add one with: smarttools add <owner/name>")
|
||||
print("Add one with: cmdforge add <owner/name>")
|
||||
return 0
|
||||
|
||||
print(f"Dependencies ({len(manifest.dependencies)}):")
|
||||
@@ -52,14 +52,14 @@ def cmd_deps(args):
|
||||
|
||||
|
||||
def cmd_install_deps(args):
|
||||
"""Install dependencies from smarttools.yaml."""
|
||||
"""Install dependencies from cmdforge.yaml."""
|
||||
from ..registry_client import RegistryError
|
||||
|
||||
manifest = load_manifest()
|
||||
|
||||
if manifest is None:
|
||||
print("No smarttools.yaml found in current project.")
|
||||
print("Create one with: smarttools init")
|
||||
print("No cmdforge.yaml found in current project.")
|
||||
print("Create one with: cmdforge init")
|
||||
return 1
|
||||
|
||||
if not manifest.dependencies:
|
||||
@@ -150,19 +150,19 @@ def cmd_add(args):
|
||||
print(f"It's been added to your dependencies - you can install it manually later.", file=sys.stderr)
|
||||
elif e.code == "CONNECTION_ERROR":
|
||||
print(f"Could not connect to registry.", file=sys.stderr)
|
||||
print("Run 'smarttools install' to try again later.", file=sys.stderr)
|
||||
print("Run 'cmdforge install' to try again later.", file=sys.stderr)
|
||||
else:
|
||||
print(f"Install failed: {e.message}", file=sys.stderr)
|
||||
print("Run 'smarttools install' to try again.", file=sys.stderr)
|
||||
print("Run 'cmdforge install' to try again.", file=sys.stderr)
|
||||
except Exception as e:
|
||||
print(f"Install failed: {e}", file=sys.stderr)
|
||||
print("Run 'smarttools install' to try again.", file=sys.stderr)
|
||||
print("Run 'cmdforge install' to try again.", file=sys.stderr)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_init(args):
|
||||
"""Initialize a new smarttools.yaml."""
|
||||
"""Initialize a new cmdforge.yaml."""
|
||||
manifest_path = Path.cwd() / MANIFEST_FILENAME
|
||||
|
||||
if manifest_path.exists() and not args.force:
|
||||
@@ -196,7 +196,7 @@ def cmd_init(args):
|
||||
|
||||
print(f"Created {MANIFEST_FILENAME}")
|
||||
print()
|
||||
print("Add dependencies with: smarttools add <owner/name>")
|
||||
print("Install them with: smarttools install")
|
||||
print("Add dependencies with: cmdforge add <owner/name>")
|
||||
print("Install them with: cmdforge install")
|
||||
|
||||
return 0
|
||||
@@ -48,7 +48,7 @@ PROVIDER_INSTALL_INFO = {
|
||||
"cost": "FREE (runs entirely on your machine)",
|
||||
"variants": [],
|
||||
"custom": True,
|
||||
"post_install_note": "After installing, add the provider:\n smarttools providers add ollama 'ollama run llama3' -d 'Local Llama 3'",
|
||||
"post_install_note": "After installing, add the provider:\n cmdforge providers add ollama 'ollama run llama3' -d 'Local Llama 3'",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ def cmd_providers(args):
|
||||
def _cmd_providers_install(args):
|
||||
"""Interactive guide to install AI providers."""
|
||||
print("=" * 60)
|
||||
print("SmartTools Provider Installation Guide")
|
||||
print("CmdForge Provider Installation Guide")
|
||||
print("=" * 60)
|
||||
print()
|
||||
|
||||
@@ -185,9 +185,9 @@ def _cmd_providers_install(args):
|
||||
print(f" 2. {info['setup']}")
|
||||
if info.get('post_install_note'):
|
||||
print(f" 3. {info['post_install_note']}")
|
||||
print(f" 4. Test with: smarttools providers test {selected}")
|
||||
print(f" 4. Test with: cmdforge providers test {selected}")
|
||||
else:
|
||||
print(f" 3. Test with: smarttools providers test {info['variants'][0] if info['variants'] else selected}")
|
||||
print(f" 3. Test with: cmdforge providers test {info['variants'][0] if info['variants'] else selected}")
|
||||
else:
|
||||
print()
|
||||
print(f"Installation failed (exit code {result.returncode})")
|
||||
@@ -86,7 +86,7 @@ def _cmd_registry_search(args):
|
||||
return 1
|
||||
except Exception as e:
|
||||
print(f"Error searching registry: {e}", file=sys.stderr)
|
||||
print("If the problem persists, check: smarttools config show", file=sys.stderr)
|
||||
print("If the problem persists, check: cmdforge config show", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
@@ -120,7 +120,7 @@ def _cmd_registry_install(args):
|
||||
except RegistryError as e:
|
||||
if e.code == "TOOL_NOT_FOUND":
|
||||
print(f"Tool '{tool_spec}' not found in the registry.", file=sys.stderr)
|
||||
print(f"Try: smarttools registry search {tool_spec.split('/')[-1]}", file=sys.stderr)
|
||||
print(f"Try: cmdforge registry search {tool_spec.split('/')[-1]}", file=sys.stderr)
|
||||
elif e.code == "VERSION_NOT_FOUND" or e.code == "CONSTRAINT_UNSATISFIABLE":
|
||||
print(f"Error: {e.message}", file=sys.stderr)
|
||||
if e.details and "available_versions" in e.details:
|
||||
@@ -191,12 +191,12 @@ def _cmd_registry_info(args):
|
||||
if len(versions) > 5:
|
||||
print(f" ...and {len(versions) - 5} more")
|
||||
|
||||
print(f"\nInstall: smarttools registry install {tool_info.owner}/{tool_info.name}")
|
||||
print(f"\nInstall: cmdforge registry install {tool_info.owner}/{tool_info.name}")
|
||||
|
||||
except RegistryError as e:
|
||||
if e.code == "TOOL_NOT_FOUND":
|
||||
print(f"Tool '{tool_spec}' not found in the registry.", file=sys.stderr)
|
||||
print(f"Try: smarttools registry search {parsed.name}", file=sys.stderr)
|
||||
print(f"Try: cmdforge registry search {parsed.name}", file=sys.stderr)
|
||||
elif e.code == "CONNECTION_ERROR":
|
||||
print("Could not connect to the registry.", file=sys.stderr)
|
||||
print("Check your internet connection or try again later.", file=sys.stderr)
|
||||
@@ -380,7 +380,7 @@ def _cmd_registry_my_tools(args):
|
||||
|
||||
if not tools:
|
||||
print("You haven't published any tools yet.")
|
||||
print("Publish your first tool with: smarttools registry publish")
|
||||
print("Publish your first tool with: cmdforge registry publish")
|
||||
return 0
|
||||
|
||||
print(f"Your published tools ({len(tools)}):\n")
|
||||
@@ -393,7 +393,7 @@ def _cmd_registry_my_tools(args):
|
||||
except RegistryError as e:
|
||||
if e.code == "UNAUTHORIZED":
|
||||
print("Not logged in. Set your registry token first:", file=sys.stderr)
|
||||
print(" smarttools config set-token <token>", file=sys.stderr)
|
||||
print(" cmdforge config set-token <token>", file=sys.stderr)
|
||||
print()
|
||||
print("Don't have a token? Register at the registry website.", file=sys.stderr)
|
||||
elif e.code == "CONNECTION_ERROR":
|
||||
@@ -418,8 +418,8 @@ def _cmd_registry_browse(args):
|
||||
return run_registry_browser()
|
||||
except ImportError:
|
||||
print("TUI browser requires urwid. Install with:", file=sys.stderr)
|
||||
print(" pip install 'smarttools[tui]'", file=sys.stderr)
|
||||
print(" pip install 'cmdforge[tui]'", file=sys.stderr)
|
||||
print()
|
||||
print("Or search from command line:", file=sys.stderr)
|
||||
print(" smarttools registry search <query>", file=sys.stderr)
|
||||
print(" cmdforge registry search <query>", file=sys.stderr)
|
||||
return 1
|
||||
@@ -16,7 +16,7 @@ def cmd_list(args):
|
||||
|
||||
if not tools:
|
||||
print("No tools found.")
|
||||
print("Create your first tool with: smarttools ui")
|
||||
print("Create your first tool with: cmdforge ui")
|
||||
return 0
|
||||
|
||||
print(f"Available tools ({len(tools)}):\n")
|
||||
@@ -76,7 +76,7 @@ def cmd_create(args):
|
||||
path = save_tool(tool)
|
||||
print(f"Created tool '{name}'")
|
||||
print(f"Config: {path}")
|
||||
print(f"\nUse 'smarttools ui' to add arguments, steps, and customize.")
|
||||
print(f"\nUse 'cmdforge ui' to add arguments, steps, and customize.")
|
||||
print(f"Or run: {name} < input.txt")
|
||||
|
||||
return 0
|
||||
@@ -326,7 +326,7 @@ echo "input" | {args.name}
|
||||
# View README
|
||||
if not readme_path.exists():
|
||||
print(f"No documentation found for '{args.name}'.")
|
||||
print(f"Create it with: smarttools docs {args.name} --edit")
|
||||
print(f"Create it with: cmdforge docs {args.name} --edit")
|
||||
return 1
|
||||
|
||||
print(readme_path.read_text())
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Global configuration handling for SmartTools.
|
||||
"""Global configuration handling for CmdForge.
|
||||
|
||||
Manages ~/.smarttools/config.yaml with registry settings, tokens, and preferences.
|
||||
Manages ~/.cmdforge/config.yaml with registry settings, tokens, and preferences.
|
||||
"""
|
||||
|
||||
import uuid
|
||||
@@ -12,7 +12,7 @@ import yaml
|
||||
|
||||
|
||||
# Default configuration directory
|
||||
CONFIG_DIR = Path.home() / ".smarttools"
|
||||
CONFIG_DIR = Path.home() / ".cmdforge"
|
||||
CONFIG_FILE = CONFIG_DIR / "config.yaml"
|
||||
|
||||
# Default registry URL (canonical base path)
|
||||
@@ -41,7 +41,7 @@ class RegistryConfig:
|
||||
|
||||
@dataclass
|
||||
class Config:
|
||||
"""Global SmartTools configuration."""
|
||||
"""Global CmdForge configuration."""
|
||||
registry: RegistryConfig = field(default_factory=RegistryConfig)
|
||||
client_id: str = ""
|
||||
auto_fetch_from_registry: bool = True
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Project manifest (smarttools.yaml) handling.
|
||||
"""Project manifest (cmdforge.yaml) handling.
|
||||
|
||||
Manages project-level tool dependencies and overrides.
|
||||
"""
|
||||
@@ -11,7 +11,7 @@ from typing import Optional, List, Dict
|
||||
import yaml
|
||||
|
||||
|
||||
MANIFEST_FILENAME = "smarttools.yaml"
|
||||
MANIFEST_FILENAME = "cmdforge.yaml"
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -76,7 +76,7 @@ class ToolOverride:
|
||||
|
||||
@dataclass
|
||||
class Manifest:
|
||||
"""Project manifest (smarttools.yaml)."""
|
||||
"""Project manifest (cmdforge.yaml)."""
|
||||
name: str = "my-project"
|
||||
version: str = "1.0.0"
|
||||
dependencies: List[Dependency] = field(default_factory=list)
|
||||
@@ -144,7 +144,7 @@ class Manifest:
|
||||
|
||||
def find_manifest(start_dir: Optional[Path] = None) -> Optional[Path]:
|
||||
"""
|
||||
Find smarttools.yaml by searching up from start_dir.
|
||||
Find cmdforge.yaml by searching up from start_dir.
|
||||
|
||||
Args:
|
||||
start_dir: Directory to start searching from (default: cwd)
|
||||
@@ -201,7 +201,7 @@ def save_manifest(manifest: Manifest, path: Optional[Path] = None) -> Path:
|
||||
|
||||
Args:
|
||||
manifest: Manifest to save
|
||||
path: Path to save to (default: ./smarttools.yaml)
|
||||
path: Path to save to (default: ./cmdforge.yaml)
|
||||
|
||||
Returns:
|
||||
Path where manifest was saved
|
||||
@@ -12,7 +12,7 @@ import yaml
|
||||
|
||||
|
||||
# Default providers config location
|
||||
PROVIDERS_FILE = Path.home() / ".smarttools" / "providers.yaml"
|
||||
PROVIDERS_FILE = Path.home() / ".cmdforge" / "providers.yaml"
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -161,7 +161,7 @@ def call_provider(provider_name: str, prompt: str, timeout: int = 300) -> Provid
|
||||
return ProviderResult(
|
||||
text="",
|
||||
success=False,
|
||||
error=f"Provider '{provider_name}' not found. Use 'smarttools providers' to manage providers."
|
||||
error=f"Provider '{provider_name}' not found. Use 'cmdforge providers' to manage providers."
|
||||
)
|
||||
|
||||
# Parse command (expand environment variables)
|
||||
@@ -181,7 +181,7 @@ def call_provider(provider_name: str, prompt: str, timeout: int = 300) -> Provid
|
||||
return ProviderResult(
|
||||
text="",
|
||||
success=False,
|
||||
error=f"Command '{base_cmd}' not found. Is it installed and in PATH?\n\nTo install AI providers, run: smarttools providers install"
|
||||
error=f"Command '{base_cmd}' not found. Is it installed and in PATH?\n\nTo install AI providers, run: cmdforge providers install"
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -197,7 +197,7 @@ def call_provider(provider_name: str, prompt: str, timeout: int = 300) -> Provid
|
||||
if result.returncode != 0:
|
||||
error_msg = f"Provider exited with code {result.returncode}: {result.stderr}"
|
||||
if "not found" in result.stderr.lower() or "not installed" in result.stderr.lower():
|
||||
error_msg += "\n\nTo install AI providers, run: smarttools providers install"
|
||||
error_msg += "\n\nTo install AI providers, run: cmdforge providers install"
|
||||
return ProviderResult(
|
||||
text="",
|
||||
success=False,
|
||||
@@ -224,14 +224,14 @@ def call_provider(provider_name: str, prompt: str, timeout: int = 300) -> Provid
|
||||
f"To fix this, either:\n"
|
||||
f" 1. Run 'opencode' to connect the {provider_id} provider\n"
|
||||
f" 2. Use --provider to pick a different model (e.g., --provider opencode-pickle)\n"
|
||||
f" 3. Run 'smarttools ui' to edit the tool's default provider"
|
||||
f" 3. Run 'cmdforge ui' to edit the tool's default provider"
|
||||
)
|
||||
|
||||
stderr_hint = f" (stderr: {stderr[:200]}...)" if len(stderr) > 200 else (f" (stderr: {stderr})" if stderr else "")
|
||||
return ProviderResult(
|
||||
text="",
|
||||
success=False,
|
||||
error=f"Provider returned empty output{stderr_hint}.\n\nThis may mean the model is not available. Try a different provider or run: smarttools providers install"
|
||||
error=f"Provider returned empty output{stderr_hint}.\n\nThis may mean the model is not available. Try a different provider or run: cmdforge providers install"
|
||||
)
|
||||
|
||||
return ProviderResult(text=result.stdout, success=True)
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Flask app for SmartTools Registry API (Phase 2)."""
|
||||
"""Flask app for CmdForge Registry API (Phase 2)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -51,7 +51,7 @@ ALLOWED_SORT = {
|
||||
TOOL_NAME_RE = re.compile(r"^[A-Za-z0-9-]{1,64}$")
|
||||
OWNER_RE = re.compile(r"^[a-z0-9][a-z0-9-]{0,37}[a-z0-9]$")
|
||||
EMAIL_RE = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$")
|
||||
RESERVED_SLUGS = {"official", "admin", "system", "api", "registry", "smarttools"}
|
||||
RESERVED_SLUGS = {"official", "admin", "system", "api", "registry", "cmdforge"}
|
||||
|
||||
rate_limiter = RateLimiter()
|
||||
password_hasher = PasswordHasher(memory_cost=65536, time_cost=3, parallelism=4)
|
||||
@@ -1517,7 +1517,7 @@ def create_app() -> Flask:
|
||||
status=413,
|
||||
details={"limit": MAX_BODY_BYTES},
|
||||
)
|
||||
secret = os.environ.get("SMARTTOOLS_REGISTRY_WEBHOOK_SECRET", "")
|
||||
secret = os.environ.get("CMDFORGE_REGISTRY_WEBHOOK_SECRET", "")
|
||||
if not secret:
|
||||
return error_response("UNAUTHORIZED", "Webhook secret not configured", 401)
|
||||
status, payload = process_webhook(request.data, dict(request.headers), secret)
|
||||
@@ -232,8 +232,8 @@ CREATE INDEX IF NOT EXISTS idx_pageviews_date ON pageviews(date(viewed_at), path
|
||||
|
||||
|
||||
def get_db_path() -> Path:
|
||||
default_path = Path.home() / ".smarttools" / "registry" / "registry.db"
|
||||
return Path(os.environ.get("SMARTTOOLS_REGISTRY_DB", default_path))
|
||||
default_path = Path.home() / ".cmdforge" / "registry" / "registry.db"
|
||||
return Path(os.environ.get("CMDFORGE_REGISTRY_DB", default_path))
|
||||
|
||||
|
||||
def ensure_db_directory(path: Path) -> None:
|
||||
@@ -19,22 +19,22 @@ from .db import connect_db, query_one
|
||||
|
||||
|
||||
def get_repo_dir() -> Path:
|
||||
default_dir = Path.home() / ".smarttools" / "registry" / "repo"
|
||||
return Path(os.environ.get("SMARTTOOLS_REGISTRY_REPO_DIR", default_dir))
|
||||
default_dir = Path.home() / ".cmdforge" / "registry" / "repo"
|
||||
return Path(os.environ.get("CMDFORGE_REGISTRY_REPO_DIR", default_dir))
|
||||
|
||||
|
||||
def get_repo_url() -> str:
|
||||
return os.environ.get("SMARTTOOLS_REGISTRY_REPO_URL", "https://gitea.brrd.tech/rob/SmartTools-Registry.git")
|
||||
return os.environ.get("CMDFORGE_REGISTRY_REPO_URL", "https://gitea.brrd.tech/rob/CmdForge-Registry.git")
|
||||
|
||||
|
||||
def get_repo_branch() -> str:
|
||||
return os.environ.get("SMARTTOOLS_REGISTRY_REPO_BRANCH", "main")
|
||||
return os.environ.get("CMDFORGE_REGISTRY_REPO_BRANCH", "main")
|
||||
|
||||
|
||||
def get_categories_cache_path() -> Path:
|
||||
return Path(os.environ.get(
|
||||
"SMARTTOOLS_REGISTRY_CATEGORIES_CACHE",
|
||||
Path.home() / ".smarttools" / "registry" / "categories_cache.json",
|
||||
"CMDFORGE_REGISTRY_CATEGORIES_CACHE",
|
||||
Path.home() / ".cmdforge" / "registry" / "categories_cache.json",
|
||||
))
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ def process_webhook(body: bytes, headers: Dict[str, str], secret: str, timeout:
|
||||
if is_delivery_processed(conn, delivery_id):
|
||||
return 200, {"data": {"status": "already_processed"}}
|
||||
|
||||
lock_path = Path.home() / ".smarttools" / "registry" / "locks" / "webhook.lock"
|
||||
lock_path = Path.home() / ".cmdforge" / "registry" / "locks" / "webhook.lock"
|
||||
if not acquire_lock(lock_path, timeout):
|
||||
return 200, {"data": {"status": "skipped", "reason": "sync_in_progress"}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Registry API client for SmartTools.
|
||||
"""Registry API client for CmdForge.
|
||||
|
||||
Handles all HTTP communication with the registry server.
|
||||
"""
|
||||
@@ -114,7 +114,7 @@ class DownloadResult:
|
||||
|
||||
|
||||
class RegistryClient:
|
||||
"""Client for interacting with the SmartTools registry API."""
|
||||
"""Client for interacting with the CmdForge registry API."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -141,8 +141,8 @@ class RegistryClient:
|
||||
# Session for connection pooling
|
||||
self._session = requests.Session()
|
||||
self._session.headers.update({
|
||||
"User-Agent": "SmartTools-CLI/1.0",
|
||||
"X-SmartTools-Client": "cli/1.0.0",
|
||||
"User-Agent": "CmdForge-CLI/1.0",
|
||||
"X-CmdForge-Client": "cli/1.0.0",
|
||||
"Accept": "application/json"
|
||||
})
|
||||
|
||||
@@ -198,7 +198,7 @@ class RegistryClient:
|
||||
if not self.token:
|
||||
raise RegistryError(
|
||||
code="UNAUTHORIZED",
|
||||
message="Authentication required. Set registry token with 'smarttools config set-token'",
|
||||
message="Authentication required. Set registry token with 'cmdforge config set-token'",
|
||||
http_status=401
|
||||
)
|
||||
headers.update(self._auth_headers())
|
||||
@@ -1,8 +1,8 @@
|
||||
"""Tool resolution with proper search order.
|
||||
|
||||
Implements the tool resolution order:
|
||||
1. Local project: ./.smarttools/<owner>/<name>/config.yaml
|
||||
2. Global user: ~/.smarttools/<owner>/<name>/config.yaml
|
||||
1. Local project: ./.cmdforge/<owner>/<name>/config.yaml
|
||||
2. Global user: ~/.cmdforge/<owner>/<name>/config.yaml
|
||||
3. Registry: Fetch from API, install to global, then run
|
||||
4. Error if not found
|
||||
"""
|
||||
@@ -24,7 +24,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Local project tools directories (support both legacy and documented paths)
|
||||
LOCAL_TOOLS_DIRS = [Path(".smarttools"), Path("smarttools")]
|
||||
LOCAL_TOOLS_DIRS = [Path(".cmdforge"), Path("cmdforge")]
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -436,9 +436,9 @@ class ToolResolver:
|
||||
python_path = sys.executable
|
||||
|
||||
script = f"""#!/bin/bash
|
||||
# SmartTools wrapper for '{owner}/{name}'
|
||||
# CmdForge wrapper for '{owner}/{name}'
|
||||
# Auto-generated - do not edit
|
||||
exec {python_path} -m smarttools.runner {owner}/{name} "$@"
|
||||
exec {python_path} -m cmdforge.runner {owner}/{name} "$@"
|
||||
"""
|
||||
|
||||
wrapper_path.write_text(script)
|
||||
@@ -450,9 +450,9 @@ exec {python_path} -m smarttools.runner {owner}/{name} "$@"
|
||||
"""Extract owner from existing wrapper script."""
|
||||
try:
|
||||
content = wrapper_path.read_text()
|
||||
# Look for pattern: smarttools.runner owner/name
|
||||
# Look for pattern: cmdforge.runner owner/name
|
||||
# Owner slugs can contain lowercase alphanumeric and hyphens
|
||||
match = re.search(r'smarttools\.runner\s+([a-z0-9][a-z0-9-]*)/([a-zA-Z0-9_-]+)', content)
|
||||
match = re.search(r'cmdforge\.runner\s+([a-z0-9][a-z0-9-]*)/([a-zA-Z0-9_-]+)', content)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
@@ -210,7 +210,7 @@ def create_argument_parser(tool: Tool) -> argparse.ArgumentParser:
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
prog=tool.name,
|
||||
description=tool.description or f"SmartTools: {tool.name}"
|
||||
description=tool.description or f"CmdForge: {tool.name}"
|
||||
)
|
||||
|
||||
# Universal flags
|
||||
@@ -244,7 +244,7 @@ def create_argument_parser(tool: Tool) -> argparse.ArgumentParser:
|
||||
def main():
|
||||
"""Entry point for tool execution via wrapper script."""
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python -m smarttools.runner <tool_name> [args...]", file=sys.stderr)
|
||||
print("Usage: python -m cmdforge.runner <tool_name> [args...]", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
tool_spec = sys.argv[1]
|
||||
@@ -10,7 +10,7 @@ import yaml
|
||||
|
||||
|
||||
# Default tools directory
|
||||
TOOLS_DIR = Path.home() / ".smarttools"
|
||||
TOOLS_DIR = Path.home() / ".cmdforge"
|
||||
|
||||
# Default bin directory for wrapper scripts
|
||||
BIN_DIR = Path.home() / ".local" / "bin"
|
||||
@@ -106,7 +106,7 @@ DEFAULT_CATEGORIES = ["Text", "Developer", "Data", "Other"]
|
||||
|
||||
@dataclass
|
||||
class Tool:
|
||||
"""A SmartTools tool definition."""
|
||||
"""A CmdForge tool definition."""
|
||||
name: str
|
||||
description: str = ""
|
||||
category: str = "Other" # Tool category for organization
|
||||
@@ -275,13 +275,13 @@ def create_wrapper_script(name: str) -> Path:
|
||||
bin_dir = get_bin_dir()
|
||||
wrapper_path = bin_dir / name
|
||||
|
||||
# Use the current Python interpreter to ensure smarttools is available
|
||||
# Use the current Python interpreter to ensure cmdforge is available
|
||||
python_path = sys.executable
|
||||
|
||||
script = f"""#!/bin/bash
|
||||
# SmartTools wrapper for '{name}'
|
||||
# CmdForge wrapper for '{name}'
|
||||
# Auto-generated - do not edit
|
||||
exec {python_path} -m smarttools.runner {name} "$@"
|
||||
exec {python_path} -m cmdforge.runner {name} "$@"
|
||||
"""
|
||||
|
||||
wrapper_path.write_text(script)
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Dialog-based UI for managing SmartTools."""
|
||||
"""Dialog-based UI for managing CmdForge."""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -762,7 +762,7 @@ def main_menu(dialog_prog: str):
|
||||
"""Show the main menu."""
|
||||
while True:
|
||||
choice = show_menu(
|
||||
"SmartTools Manager",
|
||||
"CmdForge Manager",
|
||||
[
|
||||
("list", "List all tools"),
|
||||
("create", "Create new tool"),
|
||||
@@ -1,4 +1,4 @@
|
||||
"""TUI for browsing the SmartTools Registry using urwid.
|
||||
"""TUI for browsing the CmdForge Registry using urwid.
|
||||
|
||||
Uses threading for non-blocking network operations.
|
||||
"""
|
||||
@@ -170,7 +170,7 @@ class AsyncOperation:
|
||||
|
||||
|
||||
class RegistryBrowser:
|
||||
"""TUI browser for the SmartTools Registry."""
|
||||
"""TUI browser for the CmdForge Registry."""
|
||||
|
||||
def __init__(self):
|
||||
self.client = get_client()
|
||||
@@ -195,7 +195,7 @@ class RegistryBrowser:
|
||||
"""Build the main UI layout."""
|
||||
# Header
|
||||
self.header = urwid.AttrMap(
|
||||
urwid.Text(" SmartTools Registry Browser ", align='center'),
|
||||
urwid.Text(" CmdForge Registry Browser ", align='center'),
|
||||
'header'
|
||||
)
|
||||
|
||||
@@ -344,7 +344,7 @@ Downloads: {downloads}
|
||||
Tags: {', '.join(tags) if tags else 'None'}
|
||||
|
||||
Install command:
|
||||
smarttools registry install {owner}/{name}
|
||||
cmdforge registry install {owner}/{name}
|
||||
|
||||
Press 'i' to install this tool
|
||||
"""
|
||||
@@ -1,4 +1,4 @@
|
||||
"""BIOS-style TUI for SmartTools using snack (python3-newt)."""
|
||||
"""BIOS-style TUI for CmdForge using snack (python3-newt)."""
|
||||
|
||||
import sys
|
||||
# Ensure system packages are accessible
|
||||
@@ -15,8 +15,8 @@ from .tool import (
|
||||
from .providers import Provider, load_providers, add_provider, delete_provider, get_provider
|
||||
|
||||
|
||||
class SmartToolsUI:
|
||||
"""BIOS-style UI for SmartTools."""
|
||||
class CmdForgeUI:
|
||||
"""BIOS-style UI for CmdForge."""
|
||||
|
||||
def __init__(self):
|
||||
self.screen = None
|
||||
@@ -51,7 +51,7 @@ class SmartToolsUI:
|
||||
for label, value in items:
|
||||
listbox.append(label, value)
|
||||
|
||||
grid = snack.GridForm(self.screen, "SmartTools Manager", 1, 1)
|
||||
grid = snack.GridForm(self.screen, "CmdForge Manager", 1, 1)
|
||||
grid.add(listbox, 0, 0)
|
||||
|
||||
result = grid.runOnce()
|
||||
@@ -698,7 +698,7 @@ class SmartToolsUI:
|
||||
|
||||
def run_ui():
|
||||
"""Entry point for the snack UI."""
|
||||
ui = SmartToolsUI()
|
||||
ui = CmdForgeUI()
|
||||
ui.run()
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"""BIOS-style TUI for SmartTools using urwid.
|
||||
"""BIOS-style TUI for CmdForge using urwid.
|
||||
|
||||
This module is a thin wrapper for backwards compatibility.
|
||||
The actual implementation is in the ui_urwid/ package.
|
||||
"""
|
||||
|
||||
from .ui_urwid import run_ui, SmartToolsUI
|
||||
from .ui_urwid import run_ui, CmdForgeUI
|
||||
from .ui_urwid.palette import PALETTE
|
||||
from .ui_urwid.widgets import (
|
||||
SelectableText, Button3D, Button3DCompact, ClickableButton,
|
||||
@@ -13,7 +13,7 @@ from .ui_urwid.widgets import (
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
'run_ui', 'SmartToolsUI', 'PALETTE',
|
||||
'run_ui', 'CmdForgeUI', 'PALETTE',
|
||||
'SelectableText', 'Button3D', 'Button3DCompact', 'ClickableButton',
|
||||
'SelectableToolItem', 'ToolListBox', 'TabCyclePile', 'TabPassEdit',
|
||||
'UndoableEdit', 'DOSScrollBar', 'ToolBuilderLayout', 'Dialog'
|
||||
@@ -1,4 +1,4 @@
|
||||
"""BIOS-style TUI for SmartTools using urwid (with mouse support)."""
|
||||
"""BIOS-style TUI for CmdForge using urwid (with mouse support)."""
|
||||
|
||||
import urwid
|
||||
from typing import Optional, Callable
|
||||
@@ -18,8 +18,8 @@ from .widgets import (
|
||||
)
|
||||
|
||||
|
||||
class SmartToolsUI:
|
||||
"""Urwid-based UI for SmartTools with mouse support."""
|
||||
class CmdForgeUI:
|
||||
"""Urwid-based UI for CmdForge with mouse support."""
|
||||
|
||||
def __init__(self):
|
||||
self.loop = None
|
||||
@@ -226,7 +226,7 @@ class SmartToolsUI:
|
||||
], tab_positions=[0, 1, 5]) # Tool list, buttons row, exit button
|
||||
|
||||
# Header
|
||||
header = urwid.Text(('header', ' SmartTools Manager '), align='center')
|
||||
header = urwid.Text(('header', ' CmdForge Manager '), align='center')
|
||||
|
||||
# Footer
|
||||
footer = urwid.Text(('footer', ' Arrow:Navigate list | Tab:Jump to buttons | Enter/Click:Select | Q:Quit '), align='center')
|
||||
@@ -1566,5 +1566,5 @@ No explanations, no markdown fencing, just the code."""
|
||||
|
||||
def run_ui():
|
||||
"""Entry point for the urwid UI."""
|
||||
ui = SmartToolsUI()
|
||||
ui = CmdForgeUI()
|
||||
ui.run()
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Web UI blueprint for SmartTools."""
|
||||
"""Web UI blueprint for CmdForge."""
|
||||
|
||||
import os
|
||||
from flask import Blueprint
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Web app factory for SmartTools UI."""
|
||||
"""Web app factory for CmdForge UI."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -19,13 +19,13 @@ if _sentry_dsn:
|
||||
integrations=[FlaskIntegration()],
|
||||
traces_sample_rate=float(os.environ.get("SENTRY_TRACES_RATE", "0.1")),
|
||||
profiles_sample_rate=float(os.environ.get("SENTRY_PROFILES_RATE", "0.1")),
|
||||
environment=os.environ.get("SMARTTOOLS_ENV", "development"),
|
||||
environment=os.environ.get("CMDFORGE_ENV", "development"),
|
||||
send_default_pii=False, # Privacy: don't send user IPs, emails, etc.
|
||||
)
|
||||
except ImportError:
|
||||
pass # sentry-sdk not installed
|
||||
|
||||
from smarttools.registry import app as registry_app
|
||||
from cmdforge.registry import app as registry_app
|
||||
|
||||
from . import web_bp
|
||||
from .auth import login, register, logout
|
||||
@@ -44,10 +44,10 @@ def create_web_app() -> Flask:
|
||||
app.register_blueprint(forum_bp)
|
||||
|
||||
# Session configuration
|
||||
app.session_interface = SQLiteSessionInterface(cookie_name="smarttools_session")
|
||||
app.config["SESSION_COOKIE_NAME"] = "smarttools_session"
|
||||
app.config["SESSION_COOKIE_SECURE"] = os.environ.get("SMARTTOOLS_ENV") == "production"
|
||||
app.config["SHOW_ADS"] = os.environ.get("SMARTTOOLS_SHOW_ADS", "").lower() == "true"
|
||||
app.session_interface = SQLiteSessionInterface(cookie_name="cmdforge_session")
|
||||
app.config["SESSION_COOKIE_NAME"] = "cmdforge_session"
|
||||
app.config["SESSION_COOKIE_SECURE"] = os.environ.get("CMDFORGE_ENV") == "production"
|
||||
app.config["SHOW_ADS"] = os.environ.get("CMDFORGE_SHOW_ADS", "").lower() == "true"
|
||||
|
||||
# CSRF token generator
|
||||
app.config["CSRF_GENERATOR"] = lambda: secrets.token_urlsafe(32)
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Documentation content for SmartTools web UI.
|
||||
"""Documentation content for CmdForge web UI.
|
||||
|
||||
This module contains the actual documentation text that gets rendered
|
||||
on the /docs pages. Content is stored as markdown-ish HTML for simplicity.
|
||||
@@ -7,13 +7,13 @@ on the /docs pages. Content is stored as markdown-ish HTML for simplicity.
|
||||
DOCS = {
|
||||
"getting-started": {
|
||||
"title": "Getting Started",
|
||||
"description": "Learn how to install SmartTools and create your first AI-powered CLI tool",
|
||||
"description": "Learn how to install CmdForge and create your first AI-powered CLI tool",
|
||||
"content": """
|
||||
<p class="lead">SmartTools lets you build custom AI-powered CLI commands using simple YAML configuration.
|
||||
<p class="lead">CmdForge lets you build custom AI-powered CLI commands using simple YAML configuration.
|
||||
Create tools that work with any AI provider and compose them like Unix pipes.</p>
|
||||
|
||||
<h2 id="what-is-smarttools">What is SmartTools?</h2>
|
||||
<p>SmartTools is a lightweight personal tool builder that lets you:</p>
|
||||
<h2 id="what-is-cmdforge">What is CmdForge?</h2>
|
||||
<p>CmdForge is a lightweight personal tool builder that lets you:</p>
|
||||
<ul>
|
||||
<li><strong>Create custom CLI commands</strong> that call AI providers</li>
|
||||
<li><strong>Chain prompts with Python code</strong> for complex workflows</li>
|
||||
@@ -24,23 +24,23 @@ Create tools that work with any AI provider and compose them like Unix pipes.</p
|
||||
<h2 id="quick-start">Quick Start</h2>
|
||||
<p>Get up and running in under a minute:</p>
|
||||
|
||||
<pre><code class="language-bash"># Install SmartTools
|
||||
pip install smarttools
|
||||
<pre><code class="language-bash"># Install CmdForge
|
||||
pip install cmdforge
|
||||
|
||||
# Create your first tool (choose your style)
|
||||
smarttools ui # Visual builder with menus
|
||||
smarttools create # CLI wizard
|
||||
cmdforge ui # Visual builder with menus
|
||||
cmdforge create # CLI wizard
|
||||
|
||||
# Or install a tool from the registry
|
||||
smarttools registry install official/summarize
|
||||
cmdforge registry install official/summarize
|
||||
|
||||
# Use it!
|
||||
cat article.txt | summarize</code></pre>
|
||||
|
||||
<div class="bg-cyan-50 border-l-4 border-cyan-500 p-4 my-4">
|
||||
<p class="font-semibold text-cyan-800">Two Ways to Build</p>
|
||||
<p class="text-cyan-700"><code>smarttools ui</code> launches a visual builder with menus and forms.
|
||||
<code>smarttools create</code> uses a command-line wizard. Both create the same YAML config files.</p>
|
||||
<p class="text-cyan-700"><code>cmdforge ui</code> launches a visual builder with menus and forms.
|
||||
<code>cmdforge create</code> uses a command-line wizard. Both create the same YAML config files.</p>
|
||||
</div>
|
||||
|
||||
<h2 id="how-it-works">How It Works</h2>
|
||||
@@ -87,11 +87,11 @@ output: "{summary}"</code></pre>
|
||||
<ul>
|
||||
<li><a href="/forum">Community Forum</a> - Ask questions, share projects, and connect with other users</li>
|
||||
<li><a href="/forum/c/help">Help & Support</a> - Get help with installation, configuration, or usage</li>
|
||||
<li><a href="https://gitea.brrd.tech/rob/SmartTools/issues" target="_blank">Report a Bug</a> - Found an issue? Let us know</li>
|
||||
<li><a href="https://gitea.brrd.tech/rob/CmdForge/issues" target="_blank">Report a Bug</a> - Found an issue? Let us know</li>
|
||||
</ul>
|
||||
""",
|
||||
"headings": [
|
||||
("what-is-smarttools", "What is SmartTools?"),
|
||||
("what-is-cmdforge", "What is CmdForge?"),
|
||||
("quick-start", "Quick Start"),
|
||||
("how-it-works", "How It Works"),
|
||||
("next-steps", "Next Steps"),
|
||||
@@ -101,24 +101,24 @@ output: "{summary}"</code></pre>
|
||||
|
||||
"installation": {
|
||||
"title": "Installation",
|
||||
"description": "How to install SmartTools on your system",
|
||||
"description": "How to install CmdForge on your system",
|
||||
"parent": "getting-started",
|
||||
"content": """
|
||||
<p class="lead">SmartTools requires Python 3.8+ and works on Linux, macOS, and Windows.</p>
|
||||
<p class="lead">CmdForge requires Python 3.8+ and works on Linux, macOS, and Windows.</p>
|
||||
|
||||
<h2 id="pip-install">Install with pip</h2>
|
||||
<p>The simplest way to install SmartTools:</p>
|
||||
<pre><code class="language-bash">pip install smarttools</code></pre>
|
||||
<p>The simplest way to install CmdForge:</p>
|
||||
<pre><code class="language-bash">pip install cmdforge</code></pre>
|
||||
|
||||
<p>Or with pipx for isolated installation:</p>
|
||||
<pre><code class="language-bash">pipx install smarttools</code></pre>
|
||||
<pre><code class="language-bash">pipx install cmdforge</code></pre>
|
||||
|
||||
<h2 id="verify">Verify Installation</h2>
|
||||
<pre><code class="language-bash">smarttools --version
|
||||
smarttools --help</code></pre>
|
||||
<pre><code class="language-bash">cmdforge --version
|
||||
cmdforge --help</code></pre>
|
||||
|
||||
<h2 id="configure-provider">Configure a Provider</h2>
|
||||
<p>SmartTools needs at least one AI provider configured. The easiest is Claude CLI:</p>
|
||||
<p>CmdForge needs at least one AI provider configured. The easiest is Claude CLI:</p>
|
||||
|
||||
<pre><code class="language-bash"># Install Claude CLI (if you have an Anthropic API key)
|
||||
pip install claude-cli
|
||||
@@ -127,17 +127,17 @@ pip install claude-cli
|
||||
pip install openai
|
||||
|
||||
# Configure your provider
|
||||
smarttools config</code></pre>
|
||||
cmdforge config</code></pre>
|
||||
|
||||
<h2 id="wrapper-scripts">Wrapper Scripts Location</h2>
|
||||
<p>SmartTools installs wrapper scripts to <code>~/.local/bin/</code>. Make sure this is in your PATH:</p>
|
||||
<p>CmdForge installs wrapper scripts to <code>~/.local/bin/</code>. Make sure this is in your PATH:</p>
|
||||
<pre><code class="language-bash"># Add to ~/.bashrc or ~/.zshrc
|
||||
export PATH="$HOME/.local/bin:$PATH"</code></pre>
|
||||
|
||||
<h2 id="development-install">Development Installation</h2>
|
||||
<p>To contribute or modify SmartTools:</p>
|
||||
<pre><code class="language-bash">git clone https://gitea.brrd.tech/rob/SmartTools.git
|
||||
cd SmartTools
|
||||
<p>To contribute or modify CmdForge:</p>
|
||||
<pre><code class="language-bash">git clone https://gitea.brrd.tech/rob/CmdForge.git
|
||||
cd CmdForge
|
||||
pip install -e ".[dev]"</code></pre>
|
||||
""",
|
||||
"headings": [
|
||||
@@ -151,16 +151,16 @@ pip install -e ".[dev]"</code></pre>
|
||||
|
||||
"first-tool": {
|
||||
"title": "Your First Tool",
|
||||
"description": "Create your first SmartTools command step by step",
|
||||
"description": "Create your first CmdForge command step by step",
|
||||
"parent": "getting-started",
|
||||
"content": """
|
||||
<p class="lead">Let's create a simple tool that explains code. You'll learn the basics of tool configuration.</p>
|
||||
|
||||
<h2 id="create-tool">Create the Tool</h2>
|
||||
<p>Run the interactive creator:</p>
|
||||
<pre><code class="language-bash">smarttools create</code></pre>
|
||||
<pre><code class="language-bash">cmdforge create</code></pre>
|
||||
|
||||
<p>Or create the file manually at <code>~/.smarttools/explain/config.yaml</code>:</p>
|
||||
<p>Or create the file manually at <code>~/.cmdforge/explain/config.yaml</code>:</p>
|
||||
<pre><code class="language-yaml">name: explain
|
||||
version: "1.0.0"
|
||||
description: Explain code or concepts in simple terms
|
||||
@@ -230,9 +230,9 @@ cat complex_algorithm.py | explain --level expert</code></pre>
|
||||
|
||||
"publishing": {
|
||||
"title": "Publishing Tools",
|
||||
"description": "Share your tools with the SmartTools community",
|
||||
"description": "Share your tools with the CmdForge community",
|
||||
"content": """
|
||||
<p class="lead">Share your tools with the community by publishing to the SmartTools Registry.</p>
|
||||
<p class="lead">Share your tools with the community by publishing to the CmdForge Registry.</p>
|
||||
|
||||
<h2 id="before-publishing">Before Publishing</h2>
|
||||
<p>Make sure your tool has:</p>
|
||||
@@ -255,20 +255,20 @@ cat complex_algorithm.py | explain --level expert</code></pre>
|
||||
|
||||
<h2 id="publish">Publish Your Tool</h2>
|
||||
<pre><code class="language-bash"># Navigate to your tool directory
|
||||
cd ~/.smarttools/my-tool/
|
||||
cd ~/.cmdforge/my-tool/
|
||||
|
||||
# First time: enter your token when prompted
|
||||
smarttools registry publish
|
||||
cmdforge registry publish
|
||||
|
||||
# Dry run to validate without publishing
|
||||
smarttools registry publish --dry-run</code></pre>
|
||||
cmdforge registry publish --dry-run</code></pre>
|
||||
|
||||
<h2 id="versioning">Versioning</h2>
|
||||
<p>Published versions are <strong>immutable</strong>. To update a tool:</p>
|
||||
<ol>
|
||||
<li>Make your changes</li>
|
||||
<li>Bump the version in <code>config.yaml</code></li>
|
||||
<li>Run <code>smarttools registry publish</code></li>
|
||||
<li>Run <code>cmdforge registry publish</code></li>
|
||||
</ol>
|
||||
|
||||
<h2 id="best-practices">Best Practices</h2>
|
||||
@@ -294,11 +294,11 @@ smarttools registry publish --dry-run</code></pre>
|
||||
"title": "AI Providers",
|
||||
"description": "Configure different AI providers for your tools",
|
||||
"content": """
|
||||
<p class="lead">SmartTools works with any AI provider that has a CLI interface. Configure providers in
|
||||
<code>~/.smarttools/providers.yaml</code>.</p>
|
||||
<p class="lead">CmdForge works with any AI provider that has a CLI interface. Configure providers in
|
||||
<code>~/.cmdforge/providers.yaml</code>.</p>
|
||||
|
||||
<h2 id="provider-config">Provider Configuration</h2>
|
||||
<p>Create or edit <code>~/.smarttools/providers.yaml</code>:</p>
|
||||
<p>Create or edit <code>~/.cmdforge/providers.yaml</code>:</p>
|
||||
|
||||
<pre><code class="language-yaml">providers:
|
||||
- name: claude
|
||||
@@ -397,9 +397,9 @@ providers:
|
||||
|
||||
"parallel-orchestration": {
|
||||
"title": "Parallel Orchestration",
|
||||
"description": "Run multiple SmartTools concurrently for faster workflows",
|
||||
"description": "Run multiple CmdForge concurrently for faster workflows",
|
||||
"content": """
|
||||
<p class="lead">SmartTools executes steps sequentially within a tool, but you can run
|
||||
<p class="lead">CmdForge executes steps sequentially within a tool, but you can run
|
||||
<strong>multiple tools in parallel</strong> using Python's ThreadPoolExecutor. This pattern
|
||||
is ideal for multi-agent workflows, parallel analysis, or any task where you need responses
|
||||
from multiple AI providers simultaneously.</p>
|
||||
@@ -412,7 +412,7 @@ from multiple AI providers simultaneously.</p>
|
||||
</ul>
|
||||
|
||||
<h2 id="basic-pattern">Basic Pattern</h2>
|
||||
<p>Use Python's <code>concurrent.futures</code> to run multiple SmartTools in parallel:</p>
|
||||
<p>Use Python's <code>concurrent.futures</code> to run multiple CmdForge in parallel:</p>
|
||||
|
||||
<pre><code class="language-python">import subprocess
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
@@ -604,11 +604,11 @@ def run_with_progress(tools: list[str], input_text: str):
|
||||
</ul>
|
||||
|
||||
<h2 id="example-project">Full Example: orchestrated-discussions</h2>
|
||||
<p>For a complete implementation of parallel SmartTools orchestration, see the
|
||||
<p>For a complete implementation of parallel CmdForge orchestration, see the
|
||||
<a href="https://gitea.brrd.tech/rob/orchestrated-discussions" target="_blank">orchestrated-discussions</a>
|
||||
project. It implements:</p>
|
||||
<ul>
|
||||
<li>Multiple AI "participants" as SmartTools</li>
|
||||
<li>Multiple AI "participants" as CmdForge</li>
|
||||
<li>Parallel execution with live progress logging</li>
|
||||
<li>Shared log files for real-time monitoring</li>
|
||||
<li>Discussion workflows with voting and consensus</li>
|
||||
@@ -656,7 +656,7 @@ steps:
|
||||
|
||||
output: "{result}"</code></pre>
|
||||
|
||||
<p>Save this to <code>~/.smarttools/shout/config.yaml</code> and you've got a working command:</p>
|
||||
<p>Save this to <code>~/.cmdforge/shout/config.yaml</code> and you've got a working command:</p>
|
||||
|
||||
<pre><code class="language-bash">$ echo "hello world" | shout
|
||||
HELLO WORLD!!!</code></pre>
|
||||
@@ -1697,7 +1697,7 @@ loops, and more.</p>
|
||||
<li>Using different AI models for different tasks</li>
|
||||
<li>Building tools that adapt to their input</li>
|
||||
<li>Self-critiquing workflows that iterate to perfection</li>
|
||||
<li>Calling external tools from within your SmartTools</li>
|
||||
<li>Calling external tools from within your CmdForge</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -1912,7 +1912,7 @@ output: "{result}"</code></pre>
|
||||
|
||||
<h2 id="external-tools">Calling External Tools</h2>
|
||||
|
||||
<p>SmartTools can wrap any command-line tool:</p>
|
||||
<p>CmdForge can wrap any command-line tool:</p>
|
||||
|
||||
<pre><code class="language-yaml">name: lint-explain
|
||||
version: "1.0.0"
|
||||
@@ -2087,7 +2087,7 @@ output: "{formatted}"</code></pre>
|
||||
"title": "The Visual Builder",
|
||||
"description": "Build tools without touching YAML using the terminal UI",
|
||||
"content": """
|
||||
<p class="lead">Not everyone wants to write YAML by hand. SmartTools includes a full-featured
|
||||
<p class="lead">Not everyone wants to write YAML by hand. CmdForge includes a full-featured
|
||||
terminal UI that lets you create, edit, and test tools with menus and forms—no text editor required.</p>
|
||||
|
||||
<div class="bg-indigo-50 border-l-4 border-indigo-500 p-4 my-6">
|
||||
@@ -2104,13 +2104,13 @@ terminal UI that lets you create, edit, and test tools with menus and forms—no
|
||||
|
||||
<p>Start the UI with a single command:</p>
|
||||
|
||||
<pre><code class="language-bash">smarttools ui</code></pre>
|
||||
<pre><code class="language-bash">cmdforge ui</code></pre>
|
||||
|
||||
<p>You'll see a menu-driven interface that works in any terminal:</p>
|
||||
|
||||
<div class="bg-gray-900 text-gray-100 rounded-lg p-4 my-6 font-mono text-sm">
|
||||
<pre>┌─────────────────────────────────────────────────────────┐
|
||||
│ SmartTools Manager │
|
||||
│ CmdForge Manager │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ [ List all tools ] │
|
||||
@@ -2158,7 +2158,7 @@ terminal UI that lets you create, edit, and test tools with menus and forms—no
|
||||
<h3>Step-by-Step: Creating a Summarizer</h3>
|
||||
|
||||
<ol class="space-y-3">
|
||||
<li><strong>Launch:</strong> Run <code>smarttools ui</code></li>
|
||||
<li><strong>Launch:</strong> Run <code>cmdforge ui</code></li>
|
||||
<li><strong>Select:</strong> Choose "Create new tool"</li>
|
||||
<li><strong>Info:</strong> Go to "Info & Args", set name to <code>summarize</code></li>
|
||||
<li><strong>Add Argument:</strong> Click "Add Argument", set flag to <code>--length</code>, default to <code>100</code></li>
|
||||
@@ -2243,7 +2243,7 @@ terminal UI that lets you create, edit, and test tools with menus and forms—no
|
||||
|
||||
<h2 id="ui-backends">UI Backends</h2>
|
||||
|
||||
<p>SmartTools automatically uses the best available terminal UI library:</p>
|
||||
<p>CmdForge automatically uses the best available terminal UI library:</p>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 my-6 text-sm">
|
||||
<div class="bg-green-50 border border-green-200 rounded-lg p-3">
|
||||
@@ -2276,7 +2276,7 @@ terminal UI that lets you create, edit, and test tools with menus and forms—no
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b">
|
||||
<td class="px-4 py-2">You're new to SmartTools</td>
|
||||
<td class="px-4 py-2">You're new to CmdForge</td>
|
||||
<td class="px-4 py-2">You're comfortable with YAML</td>
|
||||
</tr>
|
||||
<tr class="border-b">
|
||||
@@ -0,0 +1,5 @@
|
||||
"""Forum blueprint for CmdForge community discussions."""
|
||||
|
||||
from .routes import forum_bp
|
||||
|
||||
__all__ = ["forum_bp"]
|
||||
@@ -6,7 +6,7 @@ import re
|
||||
import sqlite3
|
||||
from typing import Any
|
||||
|
||||
from smarttools.registry.db import connect_db, query_one, query_all
|
||||
from cmdforge.registry.db import connect_db, query_one, query_all
|
||||
|
||||
|
||||
FORUM_SCHEMA = """
|
||||
@@ -51,9 +51,9 @@ CREATE INDEX IF NOT EXISTS idx_forum_replies_topic ON forum_replies(topic_id);
|
||||
"""
|
||||
|
||||
DEFAULT_CATEGORIES = [
|
||||
("general", "General Discussion", "Chat about anything SmartTools related", "chat", 1),
|
||||
("general", "General Discussion", "Chat about anything CmdForge related", "chat", 1),
|
||||
("help", "Help & Support", "Get help with installation, configuration, or usage", "question", 2),
|
||||
("showcase", "Showcase", "Share tools and projects you've built with SmartTools", "star", 3),
|
||||
("showcase", "Showcase", "Share tools and projects you've built with CmdForge", "star", 3),
|
||||
("ideas", "Ideas & Feedback", "Suggest features and improvements", "lightbulb", 4),
|
||||
("tutorials", "Tutorials & Guides", "Community-written guides and how-tos", "book", 5),
|
||||
]
|
||||
@@ -19,7 +19,7 @@ from flask import (
|
||||
url_for,
|
||||
)
|
||||
|
||||
from smarttools.registry.db import connect_db
|
||||
from cmdforge.registry.db import connect_db
|
||||
|
||||
from .models import (
|
||||
create_reply,
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Public web routes for the SmartTools UI."""
|
||||
"""Public web routes for the CmdForge UI."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -8,7 +8,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||
from markupsafe import Markup, escape
|
||||
from flask import current_app, redirect, render_template, request, session, url_for
|
||||
|
||||
from smarttools.registry.db import connect_db, query_all, query_one
|
||||
from cmdforge.registry.db import connect_db, query_all, query_one
|
||||
|
||||
from . import web_bp
|
||||
|
||||
@@ -499,7 +499,7 @@ def docs(path: str):
|
||||
else:
|
||||
page = SimpleNamespace(
|
||||
title=_title_case(current),
|
||||
description="SmartTools documentation",
|
||||
description="CmdForge documentation",
|
||||
content_html=Markup(f"<p>Documentation for <strong>{escape(current)}</strong> is coming soon.</p>"),
|
||||
headings=[],
|
||||
parent=None,
|
||||
@@ -7,7 +7,7 @@ from typing import List
|
||||
|
||||
from flask import Response, current_app, url_for
|
||||
|
||||
from smarttools.registry.db import connect_db, query_all
|
||||
from cmdforge.registry.db import connect_db, query_all
|
||||
|
||||
SITEMAP_TTL = timedelta(hours=6)
|
||||
_sitemap_cache = {"generated_at": None, "xml": ""}
|
||||
@@ -10,7 +10,7 @@ from typing import Optional
|
||||
from flask.sessions import SessionInterface, SessionMixin
|
||||
from werkzeug.datastructures import CallbackDict
|
||||
|
||||
from smarttools.registry.db import connect_db
|
||||
from cmdforge.registry.db import connect_db
|
||||
|
||||
SESSION_TTL = timedelta(days=7)
|
||||
|
||||
@@ -22,7 +22,7 @@ class SQLiteSession(CallbackDict, SessionMixin):
|
||||
|
||||
|
||||
class SQLiteSessionInterface(SessionInterface):
|
||||
def __init__(self, cookie_name: str = "smarttools_session"):
|
||||
def __init__(self, cookie_name: str = "cmdforge_session"):
|
||||
self.cookie_name = cookie_name
|
||||
|
||||
def open_session(self, app, request):
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* SmartTools Web UI - Main JavaScript
|
||||
* CmdForge Web UI - Main JavaScript
|
||||
*/
|
||||
|
||||
// Copy to clipboard utility
|
||||
@@ -1,6 +1,6 @@
|
||||
# SmartTools Registry - robots.txt
|
||||
# CmdForge Registry - robots.txt
|
||||
# We welcome all crawlers! Index everything to help users find us
|
||||
# and enable AI assistants to help solve SmartTools issues.
|
||||
# and enable AI assistants to help solve CmdForge issues.
|
||||
|
||||
User-agent: *
|
||||
Allow: /
|
||||
@@ -11,7 +11,7 @@ Allow: /tutorials/
|
||||
Allow: /tools/
|
||||
Allow: /categories/
|
||||
|
||||
# Allow AI crawlers explicitly (we want AI to learn about SmartTools)
|
||||
# Allow AI crawlers explicitly (we want AI to learn about CmdForge)
|
||||
User-agent: GPTBot
|
||||
Allow: /
|
||||
|
||||
@@ -42,6 +42,6 @@ Disallow: /api/v1/tokens
|
||||
Allow: /api/
|
||||
|
||||
# Sitemap location
|
||||
Sitemap: https://registry.smarttools.dev/sitemap.xml
|
||||
Sitemap: https://cmdforge.brrd.tech/sitemap.xml
|
||||
|
||||
# Crawl-delay: none - crawl as fast as you want!
|
||||
@@ -3,14 +3,14 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}SmartTools{% endblock %} - Build Custom AI Commands</title>
|
||||
<title>{% block title %}CmdForge{% endblock %} - Build Custom AI Commands</title>
|
||||
|
||||
<!-- Meta tags -->
|
||||
<meta name="description" content="{% block meta_description %}Create Unix-style pipeable tools that work with any AI provider. Provider-agnostic, composable, and community-driven.{% endblock %}">
|
||||
{% block meta_extra %}{% endblock %}
|
||||
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:title" content="{% block og_title %}SmartTools{% endblock %}">
|
||||
<meta property="og:title" content="{% block og_title %}CmdForge{% endblock %}">
|
||||
<meta property="og:description" content="{% block og_description %}Build custom AI commands in YAML{% endblock %}">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="{{ request.url }}">
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="{% block twitter_title %}SmartTools{% endblock %}">
|
||||
<meta name="twitter:title" content="{% block twitter_title %}CmdForge{% endblock %}">
|
||||
<meta name="twitter:description" content="{% block twitter_description %}Build custom AI commands in YAML{% endblock %}">
|
||||
{% block twitter_extra %}{% endblock %}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "SmartTools",
|
||||
"name": "CmdForge",
|
||||
"url": "{{ request.host_url }}",
|
||||
"description": "Build custom AI commands in YAML"
|
||||
}
|
||||
+4
-4
@@ -3,19 +3,19 @@
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
||||
<!-- Brand -->
|
||||
<div class="col-span-1 md:col-span-2">
|
||||
<a href="{{ url_for('web.index') }}" class="text-xl font-bold">SmartTools</a>
|
||||
<a href="{{ url_for('web.index') }}" class="text-xl font-bold">CmdForge</a>
|
||||
<p class="mt-2 text-gray-400 text-sm max-w-md">
|
||||
Build custom AI commands in YAML. Create Unix-style pipeable tools that work with any AI provider.
|
||||
Provider-agnostic, composable, and community-driven.
|
||||
</p>
|
||||
<div class="mt-4 flex space-x-4">
|
||||
<a href="https://github.com/rob/smarttools" target="_blank" rel="noopener noreferrer"
|
||||
<a href="https://github.com/rob/cmdforge" target="_blank" rel="noopener noreferrer"
|
||||
class="text-gray-400 hover:text-white transition-colors" aria-label="GitHub">
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="https://twitter.com/smarttools" target="_blank" rel="noopener noreferrer"
|
||||
<a href="https://twitter.com/cmdforge" target="_blank" rel="noopener noreferrer"
|
||||
class="text-gray-400 hover:text-white transition-colors" aria-label="Twitter">
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0022 5.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.072 4.072 0 012.8 9.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 012 18.407a11.616 11.616 0 006.29 1.84"/>
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
<div class="mt-8 pt-8 border-t border-slate-700 flex flex-col sm:flex-row justify-between items-center">
|
||||
<p class="text-gray-400 text-sm">
|
||||
© {{ now().year }} SmartTools. Open source under MIT License.
|
||||
© {{ now().year }} CmdForge. Open source under MIT License.
|
||||
</p>
|
||||
<p class="text-gray-300 text-xs mt-2 sm:mt-0">
|
||||
Made with care for the developer community.
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<!-- Logo -->
|
||||
<div class="flex-shrink-0">
|
||||
<a href="{{ url_for('web.index') }}" class="text-xl font-bold hover:text-indigo-400 transition-colors">
|
||||
SmartTools
|
||||
CmdForge
|
||||
</a>
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -54,10 +54,10 @@
|
||||
<div class="mt-4">
|
||||
<div class="flex items-center bg-gray-100 rounded px-3 py-2 group">
|
||||
<code class="text-xs text-gray-700 flex-1 truncate font-mono">
|
||||
smarttools install {{ tool.owner }}/{{ tool.name }}
|
||||
cmdforge install {{ tool.owner }}/{{ tool.name }}
|
||||
</code>
|
||||
<button type="button"
|
||||
onclick="copyToClipboard('smarttools install {{ tool.owner }}/{{ tool.name }}')"
|
||||
onclick="copyToClipboard('cmdforge install {{ tool.owner }}/{{ tool.name }}')"
|
||||
class="ml-2 p-1 text-gray-400 hover:text-gray-600 opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
aria-label="Copy install command">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
+1
-1
@@ -39,7 +39,7 @@
|
||||
</a>
|
||||
</h3>
|
||||
<p class="mt-2 text-sm text-gray-600 line-clamp-2">
|
||||
{{ tutorial.description or 'Learn how to use SmartTools effectively.' }}
|
||||
{{ tutorial.description or 'Learn how to use CmdForge effectively.' }}
|
||||
</p>
|
||||
<a href="{{ href or '#' }}"
|
||||
class="mt-4 inline-flex items-center text-sm font-medium text-indigo-600 hover:text-indigo-800 transition-colors">
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{% extends "dashboard/base.html" %}
|
||||
{% set active_page = 'overview' %}
|
||||
|
||||
{% block title %}Dashboard - SmartTools{% endblock %}
|
||||
{% block title %}Dashboard - CmdForge{% endblock %}
|
||||
|
||||
{% block dashboard_content %}
|
||||
<!-- Stats Cards -->
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
{% from "components/forms.html" import text_input, textarea, button_primary, form_errors, success_alert %}
|
||||
{% set active_page = 'settings' %}
|
||||
|
||||
{% block title %}Settings - SmartTools Dashboard{% endblock %}
|
||||
{% block title %}Settings - CmdForge Dashboard{% endblock %}
|
||||
|
||||
{% block dashboard_header %}
|
||||
<h1 class="text-2xl font-bold text-gray-900">Settings</h1>
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
{% extends "dashboard/base.html" %}
|
||||
{% set active_page = 'tokens' %}
|
||||
|
||||
{% block title %}API Tokens - SmartTools Dashboard{% endblock %}
|
||||
{% block title %}API Tokens - CmdForge Dashboard{% endblock %}
|
||||
|
||||
{% block dashboard_header %}
|
||||
<div class="flex items-center justify-between">
|
||||
@@ -30,9 +30,9 @@
|
||||
<div class="ml-3">
|
||||
<h4 class="text-sm font-medium text-blue-800">About API Tokens</h4>
|
||||
<p class="mt-1 text-sm text-blue-700">
|
||||
API tokens are used to authenticate with the SmartTools registry from the CLI.
|
||||
Use <code class="px-1 bg-blue-100 rounded">smarttools auth login</code> to authenticate,
|
||||
or set the <code class="px-1 bg-blue-100 rounded">SMARTTOOLS_TOKEN</code> environment variable.
|
||||
API tokens are used to authenticate with the CmdForge registry from the CLI.
|
||||
Use <code class="px-1 bg-blue-100 rounded">cmdforge auth login</code> to authenticate,
|
||||
or set the <code class="px-1 bg-blue-100 rounded">CMDFORGE_TOKEN</code> environment variable.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -215,7 +215,7 @@
|
||||
<p class="mt-4 text-sm text-gray-600">
|
||||
To use this token, run:
|
||||
</p>
|
||||
<pre class="mt-2 bg-gray-900 text-gray-100 text-sm p-3 rounded-lg overflow-x-auto"><code>export SMARTTOOLS_TOKEN="<span id="token-in-export"></span>"</code></pre>
|
||||
<pre class="mt-2 bg-gray-900 text-gray-100 text-sm p-3 rounded-lg overflow-x-auto"><code>export CMDFORGE_TOKEN="<span id="token-in-export"></span>"</code></pre>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-50 px-6 py-4 rounded-b-lg flex justify-end">
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{% extends "dashboard/base.html" %}
|
||||
{% set active_page = 'tools' %}
|
||||
|
||||
{% block title %}My Tools - SmartTools Dashboard{% endblock %}
|
||||
{% block title %}My Tools - CmdForge Dashboard{% endblock %}
|
||||
|
||||
{% block dashboard_header %}
|
||||
<div class="flex items-center justify-between">
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Page Not Found - SmartTools{% endblock %}
|
||||
{% block title %}Page Not Found - CmdForge{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[60vh] flex items-center justify-center px-4">
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Server Error - SmartTools{% endblock %}
|
||||
{% block title %}Server Error - CmdForge{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[60vh] flex items-center justify-center px-4">
|
||||
@@ -15,7 +15,7 @@
|
||||
class="w-full sm:w-auto inline-flex justify-center items-center px-6 py-3 text-base font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700">
|
||||
Go Home
|
||||
</a>
|
||||
<a href="https://github.com/your-org/smarttools/issues"
|
||||
<a href="https://github.com/your-org/cmdforge/issues"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="w-full sm:w-auto inline-flex justify-center items-center px-6 py-3 text-base font-medium text-gray-700 border border-gray-300 rounded-md hover:bg-gray-50">
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
|
||||
{% block title %}Community Forum{% endblock %}
|
||||
|
||||
{% block meta_description %}Join the SmartTools community. Ask questions, share your projects, and connect with other users.{% endblock %}
|
||||
{% block meta_description %}Join the CmdForge community. Ask questions, share your projects, and connect with other users.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<h1 class="text-3xl font-bold text-gray-900">Community Forum</h1>
|
||||
<p class="mt-2 text-gray-600">
|
||||
Ask questions, share your projects, and connect with other SmartTools users.
|
||||
Ask questions, share your projects, and connect with other CmdForge users.
|
||||
</p>
|
||||
<div class="mt-4 flex items-center gap-6 text-sm text-gray-500">
|
||||
<span>{{ stats.topics }} topics</span>
|
||||
@@ -119,7 +119,7 @@
|
||||
</svg>
|
||||
Browse Tools
|
||||
</a>
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools/issues"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge/issues"
|
||||
target="_blank" rel="noopener"
|
||||
class="flex items-center text-sm text-gray-600 hover:text-indigo-600">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
+9
-9
@@ -1,14 +1,14 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}About - SmartTools{% endblock %}
|
||||
{% block title %}About - CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}Learn about SmartTools, the open-source platform for building custom AI-powered command-line tools.{% endblock %}
|
||||
{% block meta_description %}Learn about CmdForge, the open-source platform for building custom AI-powered command-line tools.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-white">
|
||||
<!-- Hero -->
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16 text-center">
|
||||
<h1 class="text-4xl font-bold text-gray-900">About SmartTools</h1>
|
||||
<h1 class="text-4xl font-bold text-gray-900">About CmdForge</h1>
|
||||
<p class="mt-6 text-xl text-gray-600">
|
||||
An open-source platform for building and sharing AI-powered command-line tools.
|
||||
</p>
|
||||
@@ -20,7 +20,7 @@
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Our Mission</h2>
|
||||
<div class="prose prose-lg prose-indigo max-w-none">
|
||||
<p>
|
||||
SmartTools was created with a simple belief: powerful AI tools should be accessible to everyone,
|
||||
CmdForge was created with a simple belief: powerful AI tools should be accessible to everyone,
|
||||
not just those with extensive programming knowledge or expensive API subscriptions.
|
||||
</p>
|
||||
<p>
|
||||
@@ -29,7 +29,7 @@
|
||||
</p>
|
||||
<p>
|
||||
Our platform follows the Unix philosophy: simple, composable tools that do one thing well.
|
||||
With SmartTools, you can create custom AI commands using simple YAML configuration,
|
||||
With CmdForge, you can create custom AI commands using simple YAML configuration,
|
||||
chain them together, and share them with the community.
|
||||
</p>
|
||||
</div>
|
||||
@@ -49,7 +49,7 @@
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold text-gray-900 mb-2">Open Source</h3>
|
||||
<p class="text-gray-600">
|
||||
SmartTools is MIT licensed and open source. We believe in transparency and community ownership.
|
||||
CmdForge is MIT licensed and open source. We believe in transparency and community ownership.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Sustainability</h2>
|
||||
<div class="prose prose-lg prose-indigo max-w-none">
|
||||
<p>
|
||||
SmartTools is committed to long-term sustainability. Revenue from optional ads
|
||||
CmdForge is committed to long-term sustainability. Revenue from optional ads
|
||||
and donations supports:
|
||||
</p>
|
||||
<ul>
|
||||
@@ -121,9 +121,9 @@
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Contribute</h2>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
SmartTools is open source and welcomes contributions of all kinds.
|
||||
CmdForge is open source and welcomes contributions of all kinds.
|
||||
</p>
|
||||
<a href="https://github.com/your-org/smarttools"
|
||||
<a href="https://github.com/your-org/cmdforge"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center px-6 py-3 text-base font-medium text-white bg-gray-900 rounded-md hover:bg-gray-800">
|
||||
+7
-7
@@ -1,8 +1,8 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Community - SmartTools{% endblock %}
|
||||
{% block title %}Community - CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}Connect with SmartTools - report issues, request features, and contribute to the project.{% endblock %}
|
||||
{% block meta_description %}Connect with CmdForge - report issues, request features, and contribute to the project.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12 text-center">
|
||||
<h1 class="text-3xl font-bold text-gray-900">Community</h1>
|
||||
<p class="mt-4 text-lg text-gray-600">
|
||||
SmartTools is open source. Get help, report issues, and contribute.
|
||||
CmdForge is open source. Get help, report issues, and contribute.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -52,7 +52,7 @@
|
||||
<p class="mt-2 text-sm text-gray-600">
|
||||
Browse the source, fork the project, and submit pull requests.
|
||||
</p>
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge"
|
||||
target="_blank" rel="noopener"
|
||||
class="mt-4 inline-flex items-center text-sm font-medium text-indigo-600 hover:text-indigo-800">
|
||||
View Repository
|
||||
@@ -72,7 +72,7 @@
|
||||
<p class="mt-2 text-sm text-gray-600">
|
||||
Found a bug? Have a feature request? Open an issue.
|
||||
</p>
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools/issues"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge/issues"
|
||||
target="_blank" rel="noopener"
|
||||
class="mt-4 inline-flex items-center text-sm font-medium text-indigo-600 hover:text-indigo-800">
|
||||
Open Issue
|
||||
@@ -137,7 +137,7 @@
|
||||
<div>
|
||||
<h3 class="font-semibold text-gray-900">Report Bugs</h3>
|
||||
<p class="mt-1 text-sm text-gray-600">
|
||||
Help make SmartTools better by reporting issues with clear reproduction steps.
|
||||
Help make CmdForge better by reporting issues with clear reproduction steps.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -163,7 +163,7 @@
|
||||
class="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700">
|
||||
Visit Forum
|
||||
</a>
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools#installation"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge#installation"
|
||||
target="_blank" rel="noopener"
|
||||
class="inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50">
|
||||
Installation
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ title }} - SmartTools{% endblock %}
|
||||
{% block title %}{{ title }} - CmdForge{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="bg-white py-16">
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "components/callouts.html" import info, warning, tip %}
|
||||
|
||||
{% block title %}{{ page.title }} - SmartTools Docs{% endblock %}
|
||||
{% block title %}{{ page.title }} - CmdForge Docs{% endblock %}
|
||||
|
||||
{% block meta_description %}{{ page.description or page.title }}{% endblock %}
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
|
||||
<!-- Edit on GitHub -->
|
||||
<div class="mt-6 text-center">
|
||||
<a href="https://github.com/your-org/smarttools/edit/main/docs/{{ current_path }}.md"
|
||||
<a href="https://github.com/your-org/cmdforge/edit/main/docs/{{ current_path }}.md"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center text-sm text-gray-500 hover:text-gray-700">
|
||||
+8
-8
@@ -1,17 +1,17 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Support SmartTools{% endblock %}
|
||||
{% block title %}Support CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}Support SmartTools by contributing code, tools, or feedback.{% endblock %}
|
||||
{% block meta_description %}Support CmdForge by contributing code, tools, or feedback.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
<!-- Hero -->
|
||||
<div class="bg-white border-b border-gray-200">
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12 text-center">
|
||||
<h1 class="text-3xl font-bold text-gray-900">Support SmartTools</h1>
|
||||
<h1 class="text-3xl font-bold text-gray-900">Support CmdForge</h1>
|
||||
<p class="mt-4 text-lg text-gray-600">
|
||||
SmartTools is a passion project. The best way to support it is to use it and share what you build.
|
||||
CmdForge is a passion project. The best way to support it is to use it and share what you build.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,7 +38,7 @@
|
||||
</div>
|
||||
<h2 class="text-lg font-semibold text-gray-900">Spread the Word</h2>
|
||||
<p class="mt-2 text-sm text-gray-600">
|
||||
Tell a friend or colleague who might find SmartTools useful.
|
||||
Tell a friend or colleague who might find CmdForge useful.
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-lg border border-gray-200 p-6">
|
||||
@@ -58,10 +58,10 @@
|
||||
<section class="bg-white rounded-lg border border-gray-200 p-8 text-center">
|
||||
<h2 class="text-2xl font-bold text-gray-900">Get Involved</h2>
|
||||
<p class="mt-3 text-gray-600 max-w-2xl mx-auto">
|
||||
SmartTools is open source. The code, docs, and registry are all open for contributions.
|
||||
CmdForge is open source. The code, docs, and registry are all open for contributions.
|
||||
</p>
|
||||
<div class="mt-6 flex flex-col sm:flex-row items-center justify-center gap-4">
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge"
|
||||
target="_blank" rel="noopener"
|
||||
class="inline-flex items-center px-6 py-3 text-sm font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
|
||||
@@ -79,7 +79,7 @@
|
||||
<!-- Thank you -->
|
||||
<section class="mt-12 text-center">
|
||||
<p class="text-gray-500">
|
||||
Thanks for using SmartTools!
|
||||
Thanks for using CmdForge!
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
+5
-5
@@ -3,7 +3,7 @@
|
||||
{% from "components/tutorial_card.html" import tutorial_card %}
|
||||
{% from "components/contributor_card.html" import contributor_card %}
|
||||
|
||||
{% block title %}SmartTools - Build Custom AI Commands in YAML{% endblock %}
|
||||
{% block title %}CmdForge - Build Custom AI Commands in YAML{% endblock %}
|
||||
|
||||
{% block meta_description %}Create Unix-style pipeable AI tools with simple YAML configuration. Provider-agnostic, composable, and community-driven.{% endblock %}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<!-- Install Link -->
|
||||
<div class="mt-10">
|
||||
<a href="https://gitea.brrd.tech/rob/SmartTools#installation"
|
||||
<a href="https://gitea.brrd.tech/rob/CmdForge#installation"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="inline-flex items-center gap-2 text-indigo-600 hover:text-indigo-800 font-medium transition-colors">
|
||||
@@ -50,7 +50,7 @@
|
||||
<section class="py-16 bg-gray-50">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<h2 class="text-3xl font-bold text-gray-900 text-center mb-12">
|
||||
Why SmartTools?
|
||||
Why CmdForge?
|
||||
</h2>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
@@ -144,7 +144,7 @@
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{{ tutorial_card(
|
||||
title="Basic Setup",
|
||||
description="Learn how to install SmartTools and configure your first AI provider.",
|
||||
description="Learn how to install CmdForge and configure your first AI provider.",
|
||||
href=url_for('web.docs', path='getting-started'),
|
||||
step_number=1
|
||||
) }}
|
||||
@@ -191,7 +191,7 @@
|
||||
<p class="text-xs text-gray-500 mb-2">Advertisement</p>
|
||||
<div id="footer-ad-zone" class="min-h-[90px] flex items-center justify-center">
|
||||
<!-- Ad content loaded dynamically -->
|
||||
<p class="text-gray-400 text-sm">Support SmartTools Development</p>
|
||||
<p class="text-gray-400 text-sm">Support CmdForge Development</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "components/forms.html" import text_input, button_primary, form_errors %}
|
||||
|
||||
{% block title %}Sign In - SmartTools{% endblock %}
|
||||
{% block title %}Sign In - CmdForge{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[70vh] flex items-center justify-center px-4 py-12">
|
||||
@@ -12,7 +12,7 @@
|
||||
<path d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<h1 class="mt-4 text-2xl font-bold text-gray-900">Sign in to SmartTools</h1>
|
||||
<h1 class="mt-4 text-2xl font-bold text-gray-900">Sign in to CmdForge</h1>
|
||||
<p class="mt-2 text-gray-600">
|
||||
Access your dashboard and manage your tools
|
||||
</p>
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Privacy Policy - SmartTools{% endblock %}
|
||||
{% block title %}Privacy Policy - CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}SmartTools privacy policy. Learn how we collect, use, and protect your data.{% endblock %}
|
||||
{% block meta_description %}CmdForge privacy policy. Learn how we collect, use, and protect your data.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-white py-16">
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="prose prose-lg prose-indigo max-w-none">
|
||||
<h2>Introduction</h2>
|
||||
<p>
|
||||
SmartTools ("we", "our", or "us") respects your privacy and is committed to protecting
|
||||
CmdForge ("we", "our", or "us") respects your privacy and is committed to protecting
|
||||
your personal data. This privacy policy explains how we collect, use, and safeguard
|
||||
your information when you use our website and services.
|
||||
</p>
|
||||
@@ -121,8 +121,8 @@
|
||||
contact us at:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Email: privacy@smarttools.dev</li>
|
||||
<li>GitHub: <a href="https://github.com/your-org/smarttools/issues">Open an issue</a></li>
|
||||
<li>Email: privacy@cmdforge.dev</li>
|
||||
<li>GitHub: <a href="https://github.com/your-org/cmdforge/issues">Open an issue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "components/tool_card.html" import tool_card %}
|
||||
|
||||
{% block title %}{{ publisher.display_name }} (@{{ publisher.slug }}) - SmartTools{% endblock %}
|
||||
{% block title %}{{ publisher.display_name }} (@{{ publisher.slug }}) - CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}{{ publisher.bio or 'SmartTools publisher profile for ' ~ publisher.display_name }}{% endblock %}
|
||||
{% block meta_description %}{{ publisher.bio or 'CmdForge publisher profile for ' ~ publisher.display_name }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "components/forms.html" import text_input, button_primary, form_errors, checkbox %}
|
||||
|
||||
{% block title %}Create Account - SmartTools{% endblock %}
|
||||
{% block title %}Create Account - CmdForge{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-[70vh] flex items-center justify-center px-4 py-12">
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "components/tool_card.html" import tool_card %}
|
||||
|
||||
{% block title %}Search: {{ query }} - SmartTools Registry{% endblock %}
|
||||
{% block title %}Search: {{ query }} - CmdForge Registry{% endblock %}
|
||||
|
||||
{% block meta_description %}Search results for "{{ query }}" in the SmartTools Registry.{% endblock %}
|
||||
{% block meta_description %}Search results for "{{ query }}" in the CmdForge Registry.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
+17
-17
@@ -1,8 +1,8 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Terms of Service - SmartTools{% endblock %}
|
||||
{% block title %}Terms of Service - CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}SmartTools terms of service. Read our terms and conditions for using the platform.{% endblock %}
|
||||
{% block meta_description %}CmdForge terms of service. Read our terms and conditions for using the platform.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-white py-16">
|
||||
@@ -13,19 +13,19 @@
|
||||
<div class="prose prose-lg prose-indigo max-w-none">
|
||||
<h2>1. Acceptance of Terms</h2>
|
||||
<p>
|
||||
By accessing or using SmartTools ("the Service"), you agree to be bound by these
|
||||
By accessing or using CmdForge ("the Service"), you agree to be bound by these
|
||||
Terms of Service ("Terms"). If you do not agree to these Terms, you may not use
|
||||
the Service.
|
||||
</p>
|
||||
|
||||
<h2>2. Description of Service</h2>
|
||||
<p>
|
||||
SmartTools is a platform for creating, publishing, and sharing AI-powered
|
||||
CmdForge is a platform for creating, publishing, and sharing AI-powered
|
||||
command-line tools. The Service includes:
|
||||
</p>
|
||||
<ul>
|
||||
<li>The SmartTools CLI application</li>
|
||||
<li>The SmartTools Registry (tool hosting and discovery)</li>
|
||||
<li>The CmdForge CLI application</li>
|
||||
<li>The CmdForge Registry (tool hosting and discovery)</li>
|
||||
<li>Documentation and tutorials</li>
|
||||
<li>Community features</li>
|
||||
</ul>
|
||||
@@ -46,7 +46,7 @@
|
||||
<h3>4.1 Your Content</h3>
|
||||
<p>
|
||||
You retain ownership of tools and content you publish ("User Content"). By publishing
|
||||
to the Registry, you grant SmartTools a non-exclusive, worldwide license to host,
|
||||
to the Registry, you grant CmdForge a non-exclusive, worldwide license to host,
|
||||
distribute, and display your User Content.
|
||||
</p>
|
||||
|
||||
@@ -80,22 +80,22 @@
|
||||
|
||||
<h2>6. API and CLI Usage</h2>
|
||||
<p>
|
||||
Access to the SmartTools API and CLI is subject to rate limits. Excessive use
|
||||
Access to the CmdForge API and CLI is subject to rate limits. Excessive use
|
||||
that impacts service availability for others may result in temporary or permanent
|
||||
restrictions.
|
||||
</p>
|
||||
|
||||
<h2>7. Third-Party Services</h2>
|
||||
<p>
|
||||
SmartTools is designed to work with various AI providers and external services.
|
||||
CmdForge is designed to work with various AI providers and external services.
|
||||
Your use of these third-party services is subject to their respective terms and
|
||||
conditions. We are not responsible for third-party services.
|
||||
</p>
|
||||
|
||||
<h2>8. Intellectual Property</h2>
|
||||
<p>
|
||||
The SmartTools software is open source and licensed under the MIT License.
|
||||
The SmartTools name, logo, and branding are trademarks of SmartTools.
|
||||
The CmdForge software is open source and licensed under the MIT License.
|
||||
The CmdForge name, logo, and branding are trademarks of CmdForge.
|
||||
</p>
|
||||
|
||||
<h2>9. Disclaimer of Warranties</h2>
|
||||
@@ -104,20 +104,20 @@
|
||||
WE DO NOT WARRANT THAT THE SERVICE WILL BE UNINTERRUPTED, ERROR-FREE, OR SECURE.
|
||||
</p>
|
||||
<p>
|
||||
Tools published by third parties are not endorsed by SmartTools. You use third-party
|
||||
Tools published by third parties are not endorsed by CmdForge. You use third-party
|
||||
tools at your own risk.
|
||||
</p>
|
||||
|
||||
<h2>10. Limitation of Liability</h2>
|
||||
<p>
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY LAW, SMARTTOOLS SHALL NOT BE LIABLE FOR ANY
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY LAW, CMDFORGE SHALL NOT BE LIABLE FOR ANY
|
||||
INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES ARISING FROM
|
||||
YOUR USE OF THE SERVICE.
|
||||
</p>
|
||||
|
||||
<h2>11. Indemnification</h2>
|
||||
<p>
|
||||
You agree to indemnify and hold harmless SmartTools and its contributors from
|
||||
You agree to indemnify and hold harmless CmdForge and its contributors from
|
||||
any claims, damages, or expenses arising from your use of the Service or
|
||||
violation of these Terms.
|
||||
</p>
|
||||
@@ -140,7 +140,7 @@
|
||||
|
||||
<h2>14. Governing Law</h2>
|
||||
<p>
|
||||
These Terms are governed by the laws of the jurisdiction in which SmartTools
|
||||
These Terms are governed by the laws of the jurisdiction in which CmdForge
|
||||
operates, without regard to conflict of law principles.
|
||||
</p>
|
||||
|
||||
@@ -149,8 +149,8 @@
|
||||
For questions about these Terms, please contact us at:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Email: legal@smarttools.dev</li>
|
||||
<li>GitHub: <a href="https://github.com/your-org/smarttools/issues">Open an issue</a></li>
|
||||
<li>Email: legal@cmdforge.dev</li>
|
||||
<li>GitHub: <a href="https://github.com/your-org/cmdforge/issues">Open an issue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
+6
-6
@@ -1,12 +1,12 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "components/callouts.html" import warning, info %}
|
||||
|
||||
{% block title %}{{ tool.owner }}/{{ tool.name }} - SmartTools Registry{% endblock %}
|
||||
{% block title %}{{ tool.owner }}/{{ tool.name }} - CmdForge Registry{% endblock %}
|
||||
|
||||
{% block meta_description %}{{ tool.description or 'A SmartTools command-line tool' }}{% endblock %}
|
||||
{% block meta_description %}{{ tool.description or 'A CmdForge command-line tool' }}{% endblock %}
|
||||
|
||||
{% block og_title %}{{ tool.owner }}/{{ tool.name }}{% endblock %}
|
||||
{% block og_description %}{{ tool.description or 'A SmartTools command-line tool' }}{% endblock %}
|
||||
{% block og_description %}{{ tool.description or 'A CmdForge command-line tool' }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
@@ -91,7 +91,7 @@
|
||||
<p>{{ tool.description or 'No additional documentation available.' }}</p>
|
||||
|
||||
<h2>Installation</h2>
|
||||
<pre><code>smarttools install {{ tool.owner }}/{{ tool.name }}</code></pre>
|
||||
<pre><code>cmdforge install {{ tool.owner }}/{{ tool.name }}</code></pre>
|
||||
|
||||
<h2>Usage</h2>
|
||||
<pre><code>{{ tool.name }} --help</code></pre>
|
||||
@@ -108,7 +108,7 @@
|
||||
<h3 class="text-lg font-semibold text-gray-900 mb-4">Install</h3>
|
||||
<div class="flex items-center bg-gray-100 rounded-lg p-3 group">
|
||||
<span class="text-gray-400 mr-2 select-none">$</span>
|
||||
<code id="install-cmd" class="flex-1 text-sm text-gray-800 font-mono overflow-x-auto">smarttools install {{ tool.owner }}/{{ tool.name }}</code>
|
||||
<code id="install-cmd" class="flex-1 text-sm text-gray-800 font-mono overflow-x-auto">cmdforge install {{ tool.owner }}/{{ tool.name }}</code>
|
||||
<button type="button"
|
||||
onclick="copyInstall()"
|
||||
class="ml-2 p-1.5 text-gray-400 hover:text-gray-600"
|
||||
@@ -267,7 +267,7 @@
|
||||
|
||||
<script>
|
||||
function copyInstall() {
|
||||
const cmd = 'smarttools install {{ tool.owner }}/{{ tool.name }}';
|
||||
const cmd = 'cmdforge install {{ tool.owner }}/{{ tool.name }}';
|
||||
navigator.clipboard.writeText(cmd).then(() => {
|
||||
const copyIcon = document.getElementById('copy-icon');
|
||||
const checkIcon = document.getElementById('check-icon');
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "components/tool_card.html" import tool_card %}
|
||||
|
||||
{% block title %}Browse Tools - SmartTools Registry{% endblock %}
|
||||
{% block title %}Browse Tools - CmdForge Registry{% endblock %}
|
||||
|
||||
{% block meta_description %}Discover and install community-built AI tools. Browse by category, search by name, or explore the most popular tools.{% endblock %}
|
||||
|
||||
+7
-7
@@ -1,9 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "components/tutorial_card.html" import tutorial_card %}
|
||||
|
||||
{% block title %}Tutorials - SmartTools{% endblock %}
|
||||
{% block title %}Tutorials - CmdForge{% endblock %}
|
||||
|
||||
{% block meta_description %}Learn how to use SmartTools with step-by-step tutorials. From basic setup to advanced workflows.{% endblock %}
|
||||
{% block meta_description %}Learn how to use CmdForge with step-by-step tutorials. From basic setup to advanced workflows.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="bg-gray-50 min-h-screen">
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12 text-center">
|
||||
<h1 class="text-3xl font-bold text-gray-900">Tutorials</h1>
|
||||
<p class="mt-4 text-lg text-gray-600">
|
||||
Learn SmartTools from the ground up with step-by-step guides.
|
||||
Learn CmdForge from the ground up with step-by-step guides.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -22,13 +22,13 @@
|
||||
<section class="mb-16">
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Getting Started</h2>
|
||||
<p class="text-gray-600 mb-8">
|
||||
New to SmartTools? Start here with the fundamentals.
|
||||
New to CmdForge? Start here with the fundamentals.
|
||||
</p>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{{ tutorial_card(
|
||||
title="Installation & Setup",
|
||||
description="Install SmartTools and configure your first AI provider.",
|
||||
description="Install CmdForge and configure your first AI provider.",
|
||||
href=url_for('web.tutorials_path', path='installation'),
|
||||
step_number=1
|
||||
) }}
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
{{ tutorial_card(
|
||||
title="Understanding YAML Config",
|
||||
description="Learn the structure of SmartTools configuration files.",
|
||||
description="Learn the structure of CmdForge configuration files.",
|
||||
href=url_for('web.tutorials_path', path='yaml-config'),
|
||||
step_number=3
|
||||
) }}
|
||||
@@ -53,7 +53,7 @@
|
||||
<section class="mb-16">
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Core Concepts</h2>
|
||||
<p class="text-gray-600 mb-8">
|
||||
Understand the key concepts that power SmartTools.
|
||||
Understand the key concepts that power CmdForge.
|
||||
</p>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
@@ -1,3 +0,0 @@
|
||||
"""SmartTools - A lightweight personal tool builder for AI-powered CLI commands."""
|
||||
|
||||
__version__ = "0.1.0"
|
||||
@@ -1,5 +0,0 @@
|
||||
"""Forum blueprint for SmartTools community discussions."""
|
||||
|
||||
from .routes import forum_bp
|
||||
|
||||
__all__ = ["forum_bp"]
|
||||
Reference in New Issue
Block a user