Skip to content

Template questions

The application template's questions are in copier.yml at the repository's root, and its files in template/ (The application template). Answer them interactively, or with --defaults and --data NAME=VALUE.

Questions

Question Type Default Choices Asked when Help
project_name str My App always The application's name, as people read it
project_slug str {{ project_name.strip().lower() | regex_replace('[^a-z0-9]+', '-') | trim('-') }} always Its slug: the Python distribution, the OpenTelemetry service and the Compose project
description str An application on stackr. always One line about what it does
libraries str both artifactr, reflexr, both always The libraries it uses
evals bool yes always Include evaluation with evalr (an evals/ directory and a starter experiment)?
python_version str 3.12 3.12, 3.13, 3.14 always The Python version it runs on
app_port int 8800 always The port it is published on, on this machine

Copier checks each answer: the name can't be empty; the slug is lowercase letters, digits and single dashes, starting with a letter, at most 30 characters, and not one of the libraries' names (artifactr, artifactr-ai, reflexr, evalr), which its package would shadow; and the port is from 1024 to 65535.

Derived values

These are computed from the answers, or fixed by the template, as the libraries' revisions are (ADR-0013). They are never asked, and not recorded in .copier-answers.yml, so copier update moves them with the template.

Value Type Derived as
artifactr_rev str 1a635ecb9800c2e414221e7293e8a2de2fdb600c
reflexr_rev str dc2d05916cd6d1bf36b7c2b26e29663dfdddc338
package_name str {{ project_slug | replace('-', '_') }}
use_artifactr bool {{ libraries in ['artifactr', 'both'] }}
use_reflexr bool {{ libraries in ['reflexr', 'both'] }}
Copier setting Value
_subdirectory template
_min_copier_version 9.4
_answers_file .copier-answers.yml

The files it generates

A file whose name ends in .jinja in template/ is rendered with the answers; any other is copied as it is. A name with {% if ... %} in it is generated only when its condition holds, and <package> is the package's name.

File in the application Generated when How
.copier-answers.yml always rendered
.devcontainer/compose.yaml always rendered
.devcontainer/devcontainer.json always rendered
.devcontainer/initialize.sh always copied
.devcontainer/post-create.sh always copied
.dockerignore always copied
.editorconfig always copied
.env.example always rendered
.github/dependabot.yml always copied
.github/workflows/ci.yml always rendered
.gitignore always copied
.pre-commit-config.yaml always copied
.python-version always rendered
Dockerfile always rendered
Makefile always rendered
README.md always rendered
compose.yaml always rendered
pyproject.toml always rendered
src/<package>/__init__.py always rendered
src/<package>/app.py always rendered
src/<package>/auth.py always rendered
src/<package>/database.py always rendered
src/<package>/gateway.py always rendered
src/<package>/py.typed always copied
src/<package>/scores.py always rendered
src/<package>/settings.py always rendered
src/<package>/telemetry.py always rendered
src/<package>/collaboration.py use_artifactr rendered
src/<package>/notes.py use_artifactr rendered
src/<package>/automation.py use_reflexr rendered
src/<package>/tickets.py use_reflexr rendered
stackr.env always copied
tests/conftest.py always rendered
tests/test_app.py always rendered
tests/test_auth.py always rendered
tests/test_scores.py always rendered
tests/test_settings.py always rendered
tests/test_evals.py evals rendered
tests/test_collaboration.py use_artifactr rendered
tests/test_automation.py use_reflexr rendered
evals/__init__.py evals copied
evals/__main__.py evals copied
evals/experiments.py evals rendered

The file

The whole file: copier.yml
# The application template (RFC-0001 phase 5, ADR-0011): a new application on artifactr,
# reflexr or both, wired to the stack's ports.
#
#   uvx copier copy gh:alexnodeland/lattice my-app    # from GitHub
#   uvx copier copy path/to/lattice my-app            # from a clone
#   uvx copier update                                 # later, in the application
#
# Copier takes the latest tag that parses as a version. lattice's tags carry their package's
# name (stackr-v0.1.0), and none parses, so Copier warns that it found no release and takes
# HEAD instead: main's, from GitHub. `--vcs-ref` names another revision.
#
# The template's files are in template/. Copier takes a repository, not a directory of one,
# so lattice's root copier.yml includes these questions and points Copier at template/.

_subdirectory: template
_min_copier_version: "9.4"
_answers_file: .copier-answers.yml

project_name:
  type: str
  help: The application's name, as people read it
  default: My App
  validator: >-
    {% if not project_name.strip() %}The name can't be empty{% endif %}

project_slug:
  type: str
  help: >-
    Its slug: the Python distribution, the OpenTelemetry service and the Compose project
  default: >-
    {{ project_name.strip().lower() | regex_replace('[^a-z0-9]+', '-') | trim('-') }}
  validator: >-
    {% if not (project_slug | regex_search('^[a-z][a-z0-9]*(-[a-z0-9]+)*$')) %}
    Lowercase letters, digits and single dashes, starting with a letter
    {% elif project_slug | length > 30 %}
    At most 30 characters
    {% elif project_slug in ['artifactr', 'artifactr-ai', 'reflexr', 'evalr'] %}
    One of the libraries' names
    {% endif %}

description:
  type: str
  help: One line about what it does
  default: An application on stackr.

libraries:
  type: str
  help: The libraries it uses
  choices:
    artifactr (people and agents edit shared artifacts): artifactr
    reflexr (rules over event streams run agents): reflexr
    both, mounted side by side on one database: both
  default: both

evals:
  type: bool
  help: Include evaluation with evalr (an evals/ directory and a starter experiment)?
  default: true

python_version:
  type: str
  help: The Python version it runs on
  choices: ["3.12", "3.13", "3.14"]
  default: "3.12"

app_port:
  type: int
  help: The port it is published on, on this machine
  default: 8800
  validator: >-
    {% if app_port < 1024 or app_port > 65535 %}Choose a port from 1024 to 65535{% endif %}

# Never asked, and not recorded in the answers. The libraries' commits are the template's, so
# `copier update` moves them with its code; `make bump-libraries` moves them to each library's
# main, and evalr comes with them (ADR-0013). The rest are derived from the answers.
artifactr_rev:
  type: str
  default: 1a635ecb9800c2e414221e7293e8a2de2fdb600c
  when: false

reflexr_rev:
  type: str
  default: dc2d05916cd6d1bf36b7c2b26e29663dfdddc338
  when: false

package_name:
  type: str
  default: "{{ project_slug | replace('-', '_') }}"
  when: false

use_artifactr:
  type: bool
  default: "{{ libraries in ['artifactr', 'both'] }}"
  when: false

use_reflexr:
  type: bool
  default: "{{ libraries in ['reflexr', 'both'] }}"
  when: false