Rename Castle -> Wild PC across the repo

Repo-side rename only (Phases 1-3 of the migration plan); the live box
(~/.castle, systemd units, /data/castle, domains) is a separate cutover.

- Slug `castle` -> `wildpc`: CLI command, module names (wildpc_core/cli/api),
  dist names, entry point `wildpc = wildpc_cli.main:main`.
- Identifiers: CastleConfig/NATSClient/DirError/MDNS -> Wildpc*.
- Env/constants: CASTLE_* -> WILDPC_*; ~/.castle -> ~/.wildpc, castle.yaml ->
  wildpc.yaml, /data/castle -> /data/wildpc.
- Systemd UNIT_PREFIX castle- -> wildpc-; own programs castle-api/gateway/etc.
- Display prose "Castle" -> "Wild PC" in docs, agent-guide files, README, frontend.
- Package dirs and bootstrap yaml renamed via git mv; lockfiles regenerated;
  redundant nested uv.lock files dropped (workspace root lock is authoritative).

Tests: core 273, cli 47, wildpc-api 120 all pass. Frontend type-checks + builds.
Fixed a stale test fixture (secret_env_path kind arg) broken pre-rename.
This commit is contained in:
2026-07-18 22:55:08 -07:00
parent 25d7a522cc
commit 05b28cb584
190 changed files with 2428 additions and 3337 deletions

View File

@@ -1,13 +1,13 @@
# Web Frontends in Castle
# Web Frontends in Wild PC
> **This is a stack — creation-time guidance for writing _new_ frontends.**
> A stack is a template + conventions, not a runtime requirement. `castle program create
> A stack is a template + conventions, not a runtime requirement. `wildpc program create
> --stack react-vite` scaffolds from it and seeds the program's default dev-verb
> commands. An existing frontend adopted with `castle program add` doesn't need this
> commands. An existing frontend adopted with `wildpc program add` doesn't need this
> stack — it declares its own `commands:`. See @docs/registry.md for
> `commands:`, `stack:` (optional), and `repo:`.
How to build, serve, and manage web frontends as castle programs.
How to build, serve, and manage web frontends as wildpc programs.
## Stack
@@ -56,7 +56,7 @@ import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
export default defineConfig({
// Castle sets VITE_BASE=/ at build time (every frontend serves at its
// Wild PC sets VITE_BASE=/ at build time (every frontend serves at its
// subdomain root). Reading it here keeps the bundle.s absolute asset
// URLs resolving at the root — no hand-tuning.
base: process.env.VITE_BASE ?? "/",
@@ -70,7 +70,7 @@ export default defineConfig({
```
> **Serving behind the gateway.** A static frontend is served at its own subdomain
> — `<name>.<gateway.domain>` — rooted at `/`, so `VITE_BASE` is always `/`. Castle's
> — `<name>.<gateway.domain>` — rooted at `/`, so `VITE_BASE` is always `/`. Wild PC's
> `react-vite` build passes `VITE_BASE=/`, and a `vite.config` that reads it (above)
> works unchanged. (Frontends are no longer mounted under a `/<name>/` path.)
@@ -130,19 +130,19 @@ project root:
24.14.1
```
Castle reads this pin and puts the matching node on PATH whenever it runs the
program's node — at build time (`castle program build`, incl. builds triggered from
the castle web app, which run inside the `castle-api` service) and at run time (a
Wild PC reads this pin and puts the matching node on PATH whenever it runs the
program's node — at build time (`wildpc program build`, incl. builds triggered from
the wildpc web app, which run inside the `wildpc-api` service) and at run time (a
`launcher: node` service's systemd unit). This is why a build works from the web app
even though the service's default PATH deliberately omits nvm's versioned dirs.
The pin is standard, tool-agnostic config — the program stays castle-independent; nvm
(and editors/CI) honor the same file. Castle resolves it against
`~/.nvm/versions/node` (override with `CASTLE_NODE_VERSIONS_DIR`), newest match wins.
The pin is standard, tool-agnostic config — the program stays wildpc-independent; nvm
(and editors/CI) honor the same file. Wild PC resolves it against
`~/.nvm/versions/node` (override with `WILDPC_NODE_VERSIONS_DIR`), newest match wins.
An exact pin (`24.14.1`) matches exactly; a partial (`24`) or a range (`>=24`) matches
the newest installed major. If the pinned version isn't installed, the verb fails loud
with a `nvm install <version>` hint instead of a cryptic `node: not found`. Unpinned →
Castle injects no node (it uses whatever ambient node is on PATH, and does not guess).
Wild PC injects no node (it uses whatever ambient node is on PATH, and does not guess).
## Registering as a program
@@ -194,19 +194,19 @@ See @docs/registry.md for the full registry reference.
## Serving with Caddy
For production, the static build output is served by Caddy rather than a Node
process. You do **not** write this block by hand — `castle apply` generates it.
process. You do **not** write this block by hand — `wildpc apply` generates it.
The flow:
1. You build the frontend with `castle program build <name>` (deploy does **not**
1. You build the frontend with `wildpc program build <name>` (deploy does **not**
build — it only points Caddy at `dist/`).
2. The Caddyfile generator emits a route per `manager: caddy` deployment (kind
**static**), rooted **in place** at `<source>/<root>` — no copy. Each static
frontend is served at its own subdomain `<name>.<gateway.domain>` (the
dashboard, `castle`, is also the target of the `:9000` redirect).
dashboard, `wildpc`, is also the target of the `:9000` redirect).
The build is run with `VITE_BASE=/`, so a `vite.config` that reads it (see
[Vite config](#vite-config)) emits root-relative asset URLs. The generated block
(in `~/.castle/artifacts/specs/Caddyfile`) is a host matcher inside the
(in `~/.wildpc/artifacts/specs/Caddyfile`) is a host matcher inside the
`*.<domain>` site:
```caddyfile
@@ -225,7 +225,7 @@ not hand-configured.
## API integration
Frontends talk to castle services via environment variables injected at build
Frontends talk to wildpc services via environment variables injected at build
time. Vite exposes variables prefixed with `VITE_`:
```bash
@@ -256,7 +256,7 @@ class ApiClient {
export const apiClient = new ApiClient()
```
When served behind the castle gateway, the API base URL can use the gateway's
When served behind the wildpc gateway, the API base URL can use the gateway's
proxy paths (e.g., `/central-context/`) instead of direct ports, avoiding CORS.
## React Query setup