2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-21 02:01:45 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00
2026-02-22 21:31:21 -08:00

Castle

A personal software platform. Castle manages independent services, tools, and frontends from a single CLI, with a unified gateway, systemd integration, and a web dashboard.

Quick Start

# Install the castle CLI
cd cli && uv tool install --editable . && cd ..

# Sync all projects (git submodules + dependencies)
castle sync

# See what's here
castle list

# Start everything (all services + Caddy gateway)
castle services start

# Visit the dashboard
open http://localhost:9000

Creating Components

# Service — FastAPI app with health endpoint, systemd unit, gateway route
castle create my-api --type service --description "Does something useful"
cd my-api && uv sync
castle test my-api
castle service enable my-api
castle gateway reload

# Standalone tool — CLI tool with argparse, stdin/stdout, Unix pipes
castle create my-tool --type tool --description "Does something"

CLI Reference

castle list [--role ROLE] [--json]    List all components
castle info NAME [--json]             Show component details
castle create NAME --type TYPE        Scaffold a new component
castle run NAME                       Run component in foreground
castle test [NAME]                    Run tests (one or all)
castle lint [NAME]                    Run linter (one or all)
castle sync                           Update submodules + install deps
castle logs NAME [-f] [-n 50]         View component logs
castle gateway start|stop|reload      Manage Caddy reverse proxy
castle service enable|disable NAME    Manage a systemd service
castle service status                 Show all service statuses
castle services start|stop            Start/stop everything
castle tool list                      List all tools
castle tool info NAME                 Show tool details

Registry

castle.yaml is the single source of truth. Components declare what they do (run, expose, manage, install, build, triggers) and roles are derived from those declarations.

gateway:
  port: 9000

components:
  central-context:
    description: Content storage API
    run:
      runner: python_uv_tool
      tool: central-context
      working_dir: central-context
      env:
        CENTRAL_CONTEXT_DATA_DIR: /data/castle/central-context
        CENTRAL_CONTEXT_PORT: "9001"
    expose:
      http:
        internal: { port: 9001 }
        health_path: /health
    proxy:
      caddy: { path_prefix: /central-context }
    manage:
      systemd: {}

Architecture

castle.yaml          <- component registry (single source of truth)
cli/                 <- castle CLI
castle-api/          <- Castle API (dashboard backend)
app/                 <- Castle web app (React/Vite frontend)
central-context/     <- content storage API (git submodule)
notification-bridge/ <- desktop notification forwarder (git submodule)
protonmail/          <- email sync tool/job
devbox-connect/      <- SSH tunnel manager
pdf2md/              <- standalone tool (each tool is its own project)
ruff.toml            <- shared lint config
pyrightconfig.json   <- shared type checking config

Independence principle: Services never depend on castle. They accept configuration (data dir, port, URLs) via environment variables. Only castle components (CLI, API, gateway) know about castle internals.

Gateway: Caddy reverse proxy at port 9000. Services are proxied under one address (localhost:9000/central-context/* -> localhost:9001/*). The web app is served at the root.

Systemd: The CLI generates user units under ~/.config/systemd/user/castle-*.service. Scheduled jobs get .timer files alongside.

Data: Service data lives in /data/castle/<service-name>/, outside the repo. Secrets live in ~/.castle/secrets/.

Components

Services

Component Port Description
castle-gateway 9000 Caddy reverse proxy gateway
central-context 9001 Content storage API
notification-bridge 9002 Desktop notification forwarder
castle-api 9020 Castle API (dashboard backend)

Jobs

Component Schedule Description
protonmail Every 5 min ProtonMail email sync
backup-collect 2:00 AM Collect files into backup directory
backup-data 3:30 AM Restic backup of /data to /storage

Tools

Tool Description
android-backup Backup Android devices via ADB
browser Browse the web via browser-use
devbox-connect SSH tunnel manager
docx-extractor Extract content from Word files
docx2md Convert Word .docx to Markdown
gpt OpenAI text generation
html2text Convert HTML to plain text
mbox2eml Convert MBOX mailboxes to .eml files
md2pdf Convert Markdown to PDF
mdscraper Combine text files into markdown
pdf-extractor Extract content from PDF files
pdf2md Convert PDF to Markdown
schedule Manage systemd user timers
search Manage searchable file collections
text-extractor Extract content from text files

Frontends

Component Description
castle-app Castle web dashboard (React/Vite/TypeScript)
Description
Personal software environment.
Readme 2.3 MiB
Languages
Python 69.3%
TypeScript 28.5%
Shell 2%