diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..570ac0e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,88 @@ +# AGENTS.md + +## Project: Roux + +A personal/family recipe management site. See [README.org](./README.org) for full project description. + +### Key facts + +- **Backend**: Haskell + SQLite +- **Frontend**: Static HTML + Pico CSS +- **Recipe format**: Cooklang (https://cooklang.org/) +- **Development**: Docker-based; nothing required locally except Docker +- **Subprojects**: + - `cooklang-hs/` — Cooklang parser in Haskell + - `roux-server/` — Web server, file indexing, HTML rendering + +### Development environment + +All Haskell tooling runs via the `hs` wrapper script, which runs inside the +[flipstone/haskell-tools](https://github.com/flipstone/haskell-tools) Docker +image. Adopted from the pattern in the Atlas project. + +#### Setup + +1. Create the `hs` wrapper script in the project root: + +```bash +cat > hs << 'SCRIPT' +#!/usr/bin/env bash +# Thin wrapper to run Haskell tooling (stack, hpack, fourmolu, hlint, ...) +# inside the flipstone/haskell-tools Docker image. Usage: ./hs [args] +# e.g. ./hs stack build, ./hs stack test, ./hs hpack, ./hs fourmolu +set -euo pipefail + +IMAGE="${HAWAT_HASKELL_TOOLS_IMAGE:-ghcr.io/flipstone/haskell-tools:debian-ghc-9.10.3-5d6640d}" +PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +STACK_ROOT_HOST="${PROJECT_DIR}/.stack-root" + +mkdir -p "${STACK_ROOT_HOST}" + +exec docker run --rm -i $([ -t 0 ] && printf -- -t) \ + -v "${PROJECT_DIR}:/work" \ + -v "${STACK_ROOT_HOST}:/stack-root" \ + -e STACK_ROOT=/stack-root \ + -w /work \ + "${IMAGE}" \ + "$@" +SCRIPT +chmod +x hs +``` + +2. Create `.stack-root/` in the project root to persist GHC/cache across runs: + +```bash +mkdir -p .stack-root +``` + +3. Initialize a Haskell project with `stack` or `hpack`: + +```bash +./hs stack new cooklang-hs simple --dir cooklang-hs +# or for an existing project: +./hs stack build +``` + +#### Usage examples + +```bash +./hs stack build # Build all subprojects +./hs stack test # Run tests +./hs stack ghci # REPL +./hs hpack # Regenerate .cabal from package.yaml +./hs fourmolu -i **/*.hs # Format Haskell sources +./hs hlint src/ # Lint sources +``` + +#### Environment variables + +- `HAWAT_HASKELL_TOOLS_IMAGE` — override the Docker image tag (defaults to + `ghcr.io/flipstone/haskell-tools:debian-ghc-9.10.3-5d6640d`) + +### Agent conventions + +- Prefer the `hs` wrapper over local tooling — match the Docker-first dev environment. +- Run `./hs stack build` and `./hs stack test` before marking work as complete. +- When adding a new subproject (e.g. `roux-server`), initialize it with `./hs stack new`. +- Use `hpack` (via `./hs hpack`) for package metadata in `package.yaml` format. +- When agent-created files are owned by root, fix ownership with `sudo chown -R $(id -u):$(id -g) .`. diff --git a/hs b/hs new file mode 100755 index 0000000..70bd544 --- /dev/null +++ b/hs @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# Thin wrapper to run Haskell tooling (stack, hpack, fourmolu, hlint, ...) +# inside the flipstone/haskell-tools Docker image. Usage: ./hs [args] +# e.g. ./hs stack build, ./hs stack test, ./hs hpack, ./hs fourmolu +set -euo pipefail + +IMAGE="${HAWAT_HASKELL_TOOLS_IMAGE:-ghcr.io/flipstone/haskell-tools:debian-ghc-9.10.3-5d6640d}" +PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +STACK_ROOT_HOST="${PROJECT_DIR}/.stack-root" + +mkdir -p "${STACK_ROOT_HOST}" + +exec docker run --rm -i $([ -t 0 ] && printf -- -t) \ + -v "${PROJECT_DIR}:/work" \ + -v "${STACK_ROOT_HOST}:/stack-root" \ + -e STACK_ROOT=/stack-root \ + -w /work \ + "${IMAGE}" \ + "$@"