docs: clean up pre-existing staleness across the guides

Sweep of accumulated drift unrelated to the CLI reorg:
- Source paths: ~/.castle/code/<name> → /data/repos/<name> (REPOS_DIR), and
  source: code/X → absolute /data/repos/X. registry.md source-resolution table
  and 'how programs get in' section rewritten for the /data/repos layout.
- Old field name component: → program: in all YAML examples.
- Old term 'component' → 'program' throughout design.md and the stack guides.
- Frontend serving: corrected the copy-to-artifacts/content model to serve-in-
  place from the repo (<source>/<dist>), matching Phase 2b; dropped the dead
  _copy_app_static reference and the 'runtime never references the source tree'
  claim (frontends are the deliberate exception).
- Stale endpoints/commands: /components → /deployments; castle create/add →
  castle program create/add in the create.py/add.py docstrings.

CLAUDE.md was already current. cli 24 green; ruff clean.
This commit is contained in:
2026-06-14 16:32:13 -07:00
parent 5c6d8ec6f1
commit fd562f7468
7 changed files with 98 additions and 101 deletions

View File

@@ -31,10 +31,10 @@ How to build CLI tools following Unix philosophy.
## Project layout
Each tool is an independent project under `~/.castle/code/` with its own `pyproject.toml`:
Each tool is an independent project under `/data/repos/` with its own `pyproject.toml`:
```
~/.castle/code/my-tool/
/data/repos/my-tool/
├── src/my_tool/
│ ├── __init__.py
│ └── main.py # Entry point
@@ -50,7 +50,7 @@ Examples: `code/pdf2md/`, `code/gpt/`, `code/protonmail/`
```bash
castle program create my-tool --stack python-cli --description "Does something"
cd ~/.castle/code/my-tool && uv sync
cd /data/repos/my-tool && uv sync
```
This scaffolds the project and registers it in `castle.yaml`.
@@ -324,7 +324,7 @@ uv run ruff format . # Format
programs:
my-tool:
description: Does something useful
source: code/my-tool
source: /data/repos/my-tool
stack: python-cli
behavior: tool
```
@@ -335,13 +335,13 @@ Tools with system dependencies declare them directly on the program:
programs:
pdf2md:
description: Convert PDF files to Markdown
source: code/pdf2md
source: /data/repos/pdf2md
stack: python-cli
behavior: tool
system_dependencies: [pandoc, poppler-utils]
```
Tools live in the `programs:` section. If a tool also runs on a schedule,
add a separate entry in the `jobs:` section referencing the component.
add a separate entry in the `jobs:` section referencing the program.
See @docs/registry.md for the full registry reference.

View File

@@ -109,13 +109,13 @@ Castle passes config via env vars in castle.yaml:
programs:
my-service:
description: Does something useful
source: code/my-service
source: /data/repos/my-service
stack: python-fastapi
behavior: daemon
services:
my-service:
component: my-service
program: my-service
run:
runner: python
program: my-service

View File

@@ -7,7 +7,7 @@
> 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 components.
How to build, serve, and manage web frontends as castle programs.
## Stack
@@ -27,7 +27,7 @@ How to build, serve, and manage web frontends as castle components.
```bash
# Create the project
mkdir ~/.castle/code/my-frontend && cd ~/.castle/code/my-frontend
mkdir /data/repos/my-frontend && cd /data/repos/my-frontend
pnpm create vite . --template react-ts
# Core dependencies
@@ -122,9 +122,9 @@ pnpm run check # lint + type-check + test
The `build` output is a static SPA in `dist/` — just HTML, JS, and CSS files.
## Registering as a castle component
## Registering as a program
A frontend component has a `build` spec (produces static output). Register it
A frontend program has a `build` spec (produces static output). Register it
in the `programs:` section of `castle.yaml`. No `run` block needed if Caddy
handles serving directly from the build output.
@@ -133,7 +133,7 @@ handles serving directly from the build output.
programs:
my-frontend:
description: Web dashboard
source: code/my-frontend
source: /data/repos/my-frontend
build:
commands:
- ["pnpm", "build"]
@@ -141,16 +141,16 @@ programs:
- dist/
```
For production, `castle deploy` copies the build output to
`~/.castle/artifacts/content/<name>/` and Caddy serves it from there — no
Node process needed. See [Serving with Caddy](#serving-with-caddy) below.
For production, Caddy serves the build output **in place** from the program's
repo (`<source>/<build.outputs[0]>`) — no Node process and no copy into a
central directory. See [Serving with Caddy](#serving-with-caddy) below.
For development with Vite's dev server, add a service entry:
```yaml
services:
my-frontend:
component: my-frontend
program: my-frontend
run:
runner: node
script: dev
@@ -170,19 +170,19 @@ For production, the static build output is served by Caddy rather than a Node
process. You do **not** write this block by hand — `castle deploy` generates it.
The flow:
1. `castle deploy` runs the program's `build.commands`, then copies each
`build.outputs` directory from `~/.castle/code/<name>/` into
`~/.castle/artifacts/content/<name>/` (`core/src/castle_core/deploy.py`,
`_copy_app_static`).
2. The Caddyfile generator scans `~/.castle/artifacts/content/`; any directory
containing an `index.html` is served as a SPA at a path prefix matching its
name. `castle-app` is special-cased to serve at the root `/`.
1. `castle deploy` runs the program's `build.commands` (so `dist/` is current).
2. The Caddyfile generator emits a route per `behavior: frontend` program that
has `build.outputs`, rooted **in place** at `<source>/<build.outputs[0]>`
no copy. A static frontend mounts at `/<name>/`; `castle-app` is
special-cased to serve at the root `/`.
The generated block looks like this (written to `~/.castle/artifacts/specs/Caddyfile`):
The build is run with `VITE_BASE` set to that serve prefix, so a `vite.config`
that reads it (see [Vite config](#vite-config)) emits asset URLs that resolve at
the subpath. The generated block (in `~/.castle/artifacts/specs/Caddyfile`):
```caddyfile
handle_path /my-frontend/* {
root * /home/payne/.castle/artifacts/content/my-frontend
root * /data/repos/my-frontend/dist
try_files {path} /index.html
file_server
}