Project estate

Projects

The current PHP Boy Scout project estate: tools, libraries, infrastructure modules and the sites they support.

96 public entries 11 groups

Toolkits and Frameworks

The foundations I build other things on.

go-tool-base

Framework

Go

The underpinnings for any Go command-line tool, and (as a few of my projects now prove) for comprehensive web services too. It standardises the boilerplate and wiring you end up writing in every Go project, and puts config, logging, self-update, a DI container and the rest straight at your fingertips. Highly opinionated, and it makes some calls people will disagree with, but it works, and it works really well. The CLI it ships with is a big part of that: keeping a Go app built, updated and maintained becomes almost trivial.

rust-tool-base

Framework

Rust

The Rust counterpart to go-tool-base, and deliberately not a straight port. Rather than copy the Go version wholesale, it reimagines the same idea through Rust idioms and off-the-shelf crates, while keeping a common signature and feature set so the two feel familiar if you switch between them. The same streamlined developer experience, done the Rust way.

Layered Configuration

The config module and the family of small adapters around it. Read and write configuration in any format, from any filesystem, and from dynamic backends like Consul, all as one layered store that can tell you where every value came from.

config

Configuration store

Go

A layered configuration store: read from files, the environment, flags and remote backends, ask where any value came from, and write a change back without wrecking the file. Rewritten off Viper to own config I/O end to end.

config backends

Dynamic backend adapters

Go

Remote systems as first-class layers, with the same precedence and provenance a file gets, and write-back wherever the system allows it safely.

config-aws-secrets

Go

Secret backend

Read secrets from AWS Secrets Manager as a config layer.

config-aws-ssm

Go

Backend

Read AWS SSM Parameter Store as a layer. Read-only: Parameter Store has no compare-and-swap write.

config-azure-appconfig

Go

Backend

Read and write Azure App Configuration, each write guarded by the setting's ETag.

config-azure-keyvault

Go

Secret backend

Read secrets from Azure Key Vault as a config layer.

config-consul

Go

Backend

Read and write HashiCorp Consul, with structure-preserving compare-and-swap writes.

config-gcp-parameter

Go

Backend

Read GCP Parameter Manager as a layer, read-only.

config-gcp-secret

Go

Secret backend

Read secrets from Google Cloud Secret Manager as a config layer.

config-keychain

Go

Secret backend

Read and write sensitive values in the OS keychain as a config layer, so a CLI's tokens never sit in a plain file on disk.

config-vault

Go

Secret backend

Read secrets from HashiCorp Vault as a config layer, with the client injected so you own how it authenticates.

config filesystems

Filesystem adapters

Go

Read and write config files from filesystems other than the local disk: compiled into the binary, on a remote host over SSH, or in a cloud object store. config.OS() and config.Dir ship in the core.

config-afero

Go

Filesystem

Bridge an afero filesystem a consumer already holds to config's own FS interface.

config-aws-s3

Go

Filesystem

Read and write a config file that lives in an AWS S3 bucket, staged and renamed over for an atomic commit.

config-azure-blob

Go

Filesystem

Read and write a config file in an Azure Blob container, through the same stage-and-rename machinery a local file uses.

config-billy

Go

Filesystem

Read and write config through a go-billy filesystem a tool already uses.

config-gcp-gcs

Go

Filesystem

Read and write a config file in a Google Cloud Storage bucket, atomic per object.

config-iofs

Go

Filesystem

Read config from any io/fs.FS, including an embed.FS compiled into the binary. Read-only, as io/fs is.

config-sftp

Go

Filesystem

Read and write config on a remote host over SFTP, staged and renamed over so a reader never sees a half-written file.

config formats

File format adapters

Go

One small module per file format, so you only compile the parsers you use. YAML is built into the core.

config-dotenv

Go

Codec

Read dotenv (.env) configuration, read-only with no added dependency.

config-hcl

Go

Codec

Read and write HCL, treating it as a configuration format in its own right, not Terraform.

config-ini

Go

Codec

Read INI configuration, read-only with no added dependency.

config-json

Go

Codec

Read and write JSON and JSON Lines, preserving the document's structure on write.

config-properties

Go

Codec

Read Java .properties configuration, read-only with no added dependency.

config-toml

Go

Codec

Read and write TOML, structure-preserving.

config-xml

Go

Codec

Read XML over the standard library alone, with no added dependency.

Framework-Independent Go Modules

Go packages that stand on their own, without needing the full go-tool-base framework around them. Many were extracted from the framework once they proved reusable.

aferobilly

FS adapter

Go

Use a go-billy filesystem anywhere an afero one is expected: a complete billy-to-afero adapter with optional locking that makes a live handle concurrency-safe.

browser

Utility module

Go

A safe entry point for opening URLs: scheme allowlist, length bound and control-character rejection.

controls

Service lifecycle

Go

Startup ordering, health probes, graceful shutdown and self-healing restarts for Go services.

credentials

Secrets

Go

A storage-mode abstraction for user-supplied secrets: env-var reference, OS keychain or literal value, with a pluggable backend and an auditable keychain opt-out.

errorhandling

CLI errors

Go

Structured, user-friendly error reporting for CLIs: actionable hints, exit codes carried on the error, debug-gated stack traces and a pluggable support channel.

errors

Error package

Go

The error package the estate owns: stack traces, user-facing hints, structured attributes for logging, and an aggregate that behaves like the standard library's, so nothing goes missing below a Join. It imports nothing outside the standard library, and a test enforces that.

observability

Telemetry

Go

Hardened OpenTelemetry setup for Go services: OTLP logs, metrics and traces, wired up once and correctly.

output

CLI output

Go

Structured, themeable output for CLI tools: one Renderer facade for text, JSON, YAML, CSV, TSV and Markdown, plus tables, spinners, progress bars and status lines. Framework-free core, with an opt-in cobra subpackage.

redact

Safety utility

Go

Strips credential-like content from free-form strings before they reach logs or telemetry.

regexutil

Safety utility

Go

Bounded, DoS-safe regex compilation for patterns that might come from untrusted sources.

workspace

Utility module

Go

Find a project's root by walking up to a marker file, over an injected afero filesystem so it stays testable.

yamldoc

YAML editing

Go

Edit a YAML document without destroying it: comments, key order, quoting and block styles survive a targeted change. Built for config, useful on its own.

Networking and Transport

The framework-free networking layer: servers, clients, the middleware they share, and the TLS and auth that hold them together.

authn

Authentication

Go

Transport-agnostic request authentication: API key, JWT/OIDC and mTLS, usable from either transport.

grpcclient

gRPC client

Go

A light gRPC client dial factory: a decoupled target, go/tls credentials and the transit client interceptors.

httpclient

HTTP client

Go

A hardened *http.Client factory: secure TLS defaults, downgrade-proof redirects and the transit middleware.

localca

Local CA

Go

A framework-free, mkcert-style local development CA: a per-machine root, cross-OS trust-store install and browser-trusted HTTPS on localhost and LAN IPs with zero manual setup.

tls

TLS plumbing

Go

Hardened, framework-free TLS plumbing for Go: sensible defaults and the pieces the transports and clients build on.

transit

Client middleware

Go

The shared HTTP and gRPC client middleware both factories use: retry, circuit-breaker and auth.

transport

Server stack

Go

A framework-free HTTP + gRPC + gateway server stack: hardened server constructors, health endpoints, authentication and security headers.

transport-metrics

Metrics

Go

Cardinality-safe Prometheus instrumentation: a scrapeable /metrics endpoint (Go runtime, process and build-info collectors), optional pprof, mounted on your server or standalone. The pull/scrape counterpart to the OTel observability module; go/transport, gRPC and OTel isolated in opt-in subpackages.

transport-openapi

API docs

Go

Serve an OpenAPI spec and an interactive Stoplight Elements docs site from one Register call, mounted on your transport mux. Keeps the ~2.4 MB embedded docs UI out of servers that don't need it.

AI Building Blocks

Provider-neutral AI modules and the adapters that make them useful without tying the rest of the toolchain to one vendor.

chat

AI client

Go

A light, framework-free multi-provider AI chat client with provider support kept opt-in.

chat-anthropic

Go

Provider

Anthropic Claude provider for the Go chat client.

chat-gemini

Go

Provider

Google Gemini provider for the Go chat client.

chat-openai

Go

Provider

OpenAI and OpenAI-compatible provider for the Go chat client.

chat-platform

Chat platform contract

Go

Receive, reply and moderate across chat platforms with no vendor SDK in the core. The other side of the chat modules: those talk to models, this one talks to the people.

chat-platform-discord

Go

Provider

The Discord provider: read channels, reply in threads, moderate and run slash commands.

Rust Toolkit

The Rust sibling of the go-tool-base module set: small, independently-versioned crates extracted from rust-tool-base, each usable on its own.

app

Application core

Rust

The application context and command contract for RTB-based CLI tools: App<C>, ToolMetadata, typed config and cancellation.

assets

Embedded assets

Rust

Embedded-asset overlay filesystem: ship defaults in the binary, override on disk.

chat

AI client

Rust

A unified AI chat client: Claude, OpenAI, Gemini, Ollama and compatibles behind one interface.

cli

CLI runtime

Rust

The CLI runtime family: a four-crate workspace on one version line. rtb-cli builds the application; the others each register a built-in command into the same link-time registry.

config

Configuration

Rust

Strongly-typed layered configuration with hot reload.

credentials

Secrets

Rust

User-secret storage behind one seam: env-var reference, OS keychain or literal config.

error

Error handling

Rust

Error types and the miette diagnostic report pipeline for CLI tools.

forge

Release ops

Rust

Forge release providers (GitHub, GitLab, Gitea, Codeberg, Bitbucket), plus git operations over gix.

redact

Safety utility

Rust

Strips credential-like content from strings before they reach logs or telemetry.

telemetry

Telemetry

Rust

Opt-in, consent-gated anonymous usage telemetry with pluggable sinks.

tui

Terminal UI

Rust

Reusable terminal-UI widgets: wizards, tables and spinners.

Media and Creative Tools

Tools for publishing, reels, photography and media processing.

afmpeg

Media library

Go

FFmpeg in pure Go with no install, no CGO and no disk: a WASM build of FFmpeg running over a virtualised, in-memory filesystem, so media processing ships as a single binary and stays sandboxed. That virtual FS layer is a big part of the appeal, and the whole thing sits behind one clean Go interface, no dropping to a shell, no wrangling CGO bindings. A native FFmpeg backend is on the way too, for the performance edge cases where you can trade the security posture for speed, and it speaks the very same interface.

ffmpeg-wasi

C / WASI

Media engine

Current FFmpeg as a sandboxed WASI module, runnable from Go through wazero without CGO or a host FFmpeg install.

keryx

Publishing studio

Go / Svelte

Keryx is ancient Greek for 'the herald', which is precisely the job. A little utility I built for myself because I'm dreadfully bad at social media: point it at the page bundle for one of these blog posts and it turns that into a sharp piece of short-form media, ready to post to the platforms I want to be on.

krites

Photography tool

Go / Svelte

Krites is ancient Greek for 'the judge', and judging photographs is the whole job. I built it for an audience of one, my wife: a simple, UI-driven tool (not a command line in sight) that helps her rip through culling 4,000-plus wedding images to her own standards. It leans on local ML rather than a cloud-AI subscription, so it works wherever she is, signal or not. It's since grown an optional AI critic as well, expert feedback on composition, colour and technique, there to help her learn rather than to do the judging for her.

krites-models

Python / ONNX

Model provisioning

The signed, checksum-pinned, provenance-tracked ONNX models krites downloads: fetched from upstream, converted, parity-verified, then signed as one release with a record of each model's source, version and licence.

Release Trust and Delivery

The plumbing that signs, verifies, builds and ships the rest.

changelog

Release notes

Go

Turn a repository's Conventional-Commits history, or a release-notes archive, into a structured, categorised changelog.

CI images

Build images

Docker

Public container images that keep the toolchain repeatable across software and infrastructure projects.

dev-tools

Docker

Software CI image

Rust, Go, Node, Python and the language CI tooling used by the software projects.

infra-tools

Docker

Infrastructure CI image

OpenTofu, tflint, trivy, checkov, gitleaks, terraform-docs and aws-cli for infrastructure pipelines.

cicd

Components

GitLab CI

Reusable GitLab CI/CD components I include rather than copy across my projects, so the pipeline lives in one place instead of drifting copy-paste in every repo.

claude-code-plugins

Plugin marketplace

Markdown / JSON

A Claude Code plugin marketplace for the reusable skills, guardrails and workflow habits I use across my projects.

forge

Release ops

Go

Forge release operations: a provider contract, registry and credential chain, with no vendor SDK in the core. Each forge is a swappable provider module.

forge-bitbucket

Go

Provider

Bitbucket release provider, over the Downloads API.

forge-gitea

Go

Provider

Gitea and Codeberg release provider, over the gitea SDK.

forge-github

Go

Provider

GitHub release provider (github.com and Enterprise), over go-github.

forge-gitlab

Go

Provider

GitLab release provider, over the official client-go.

homebrew

Package tap

Ruby

The Homebrew tap for phpboyscout tools, used to distribute the binaries that come out of the release pipeline.

repo

Git operations

Go

Git repository operations for Go: clone, commit, worktrees and tree inspection over go-git, behind focused role interfaces.

sigillum

Signing CLI

Go

A standalone command-line tool for signing and verifying release artefacts with OpenPGP. The private key never leaves your KMS, HSM or PEM file, and nothing about it cares what language your project is written in.

signing

Library

Go

A small, standalone module for creating and verifying signatures on files. I pulled it out of go-tool-base so it stays lightweight and anything can use it, not just go-tool-base projects: it's what signs the CLI binaries and the ffmpeg-wasm bundle I distribute. It works through pluggable backends, so the key can live somewhere like AWS KMS rather than on disk, with Google Cloud, Azure and HashiCorp Vault to follow.

signing-aws-kms

Go

Backend

The AWS KMS backend for the signing module, keeping private release-signing keys inside KMS while the public API stays framework-free.

Community and Support

Tools that sit between the projects and the people using them.

phpbotscout

Support bot

Go

A support and moderation bot bridging Discord and GitLab: it answers what the docs already cover, with citations, and offers to raise an issue with the thread attached when it can't. Every question it can't answer is a documentation gap with a timestamp on it.

Infrastructure Modules

Public OpenTofu modules. The private repos that consume them stay private and are deliberately not listed here.

terraform-aws-bootstrap

Terraform module

OpenTofu

The small first stack for a new AWS account: remote state, CI OIDC identity and an aws-nuke config. It deliberately stops there.

terraform-aws-gitlab-runner-fleet

CI runner fleet

OpenTofu

A GitLab Runner fleeting fleet on AWS: one always-on manager plus scale-to-zero spot workers on the docker-autoscaler executor. Built to replace cattle-ops/gitlab-runner and expose the levers it hid, including worker disk size and a shared cache layer.

terraform-aws-security-baseline

Terraform module

OpenTofu

The downstream account baseline: audit logging, threat detection, account hardening, operator access and the alerts wiring I keep reusing.

terraform-aws-signing-kms

Terraform module

OpenTofu

The KMS-backed release signing module: asymmetric keys, CI signer role and the policy shape needed to sign without ever exporting the key.

Sites

Static sites with their own audiences and visual identities. Public site links only; private source repositories are intentionally not linked.

PHP Boy Scout blog

Blog

Hugo

This site: the home for the project write-ups, leadership pieces, tutorials and the occasional personal essay.

Shutter & Stove

Photography / recipes

Hugo

Hailey's vanlife photography and galley-kitchen cooking site, built ahead of the 2027 trip so the shape exists before the content does.

The Dusthole

Business site

Hugo

A bespoke site for my dad's 15th-century coaching inn and bed and breakfast in Shepton Mallet.