feat: Add new tools and configurations for Castle platform

- Introduced `uv.lock` for dependency management with various packages including `pytest`, `colorama`, and `pluggy`.
- Added `pyrightconfig.json` for Python type checking configuration.
- Expanded `recommendations.md` with detailed scaling recommendations and project management strategies.
- Created shared `ruff.toml` for consistent linting across projects.
- Developed `Castle Tools` with various utilities including Android backup, browser automation, document conversion, and search tools.
- Implemented `backup-collect` and `schedule` tools for system administration tasks.
- Enhanced `search` functionality with indexing and querying capabilities using Tantivy.
- Added comprehensive documentation for each tool, including usage examples and installation instructions.
This commit is contained in:
2026-02-20 16:41:19 -08:00
parent 0d35ac9ffd
commit f39a551aad
152 changed files with 21197 additions and 83 deletions

View File

@@ -0,0 +1,81 @@
"""castle list - show all registered components."""
from __future__ import annotations
import argparse
import json
from castle_cli.config import load_config
from castle_cli.manifest import Role
# Terminal colors
BOLD = "\033[1m"
RESET = "\033[0m"
DIM = "\033[2m"
ROLE_COLORS: dict[str, str] = {
Role.SERVICE: "\033[92m", # green
Role.TOOL: "\033[96m", # cyan
Role.WORKER: "\033[94m", # blue
Role.JOB: "\033[95m", # magenta
Role.FRONTEND: "\033[93m", # yellow
Role.REMOTE: "\033[90m", # dim
Role.CONTAINERIZED: "\033[33m", # orange
}
def run_list(args: argparse.Namespace) -> int:
"""List all components."""
config = load_config()
components = config.components
filter_role = getattr(args, "role", None)
if filter_role:
components = {
k: v for k, v in components.items() if filter_role in v.roles
}
if getattr(args, "json", False):
output = []
for name, manifest in components.items():
entry: dict = {
"name": name,
"roles": [r.value for r in manifest.roles],
}
if manifest.description:
entry["description"] = manifest.description
if manifest.expose and manifest.expose.http:
entry["port"] = manifest.expose.http.internal.port
output.append(entry)
print(json.dumps(output, indent=2))
return 0
if not components:
print("No components found.")
return 0
# Group by primary role (first in sorted list)
by_role: dict[str, list[tuple[str, object]]] = {}
for name, manifest in components.items():
primary_role = manifest.roles[0].value if manifest.roles else "other"
by_role.setdefault(primary_role, []).append((name, manifest))
# Display order
role_order = ["service", "tool", "worker", "job", "frontend", "remote", "containerized"]
for role_name in role_order:
items = by_role.get(role_name, [])
if not items:
continue
color = ROLE_COLORS.get(role_name, "")
print(f"\n{BOLD}{color}{role_name}s{RESET}")
print(f"{color}{'' * 40}{RESET}")
for name, manifest in items:
port_str = ""
if manifest.expose and manifest.expose.http:
port_str = f" :{manifest.expose.http.internal.port}"
desc = f" {DIM}{manifest.description}{RESET}" if manifest.description else ""
print(f" {BOLD}{name}{RESET}{port_str}{desc}")
print()
return 0