---
name: tibi-project-setup
description: Set up a new tibi project from the tibi-svelte-starter template. Covers placeholder replacement, env/config setup, Docker startup, optional shared-server registration, and build verification. Use when creating a new project or onboarding into this template.
---

# tibi-project-setup

## When to use this skill

Use this skill when:

- creating a new project from `tibi-svelte-starter`
- onboarding into a freshly cloned project where starter placeholders are still present
- fixing a project that was renamed but never fully registered/configured in the current tibi stack

Goal: end with a project that is not only renamed, but actually reachable as a working website, admin, and API project in the current Docker/tibi-server setup.

## Source of truth

Use these sources when bootstrapping or auditing setup:

- `.agents/BUILD_CHECKLIST.md` phase 0
- `AGENTS.md`
- `README.md`
- `Makefile`
- `docker-compose-local.yml`
- `.env`
- `api/config.yml`
- `api/config.yml.env`
- `api/hooks/config-client.js`
- `.gitea/workflows/deploy.yml`
- `scripts/ci-deploy.sh`
- `scripts/ci-staging.sh`
- tibi-server server-level config requirements from `tibi-server/docs/02-configuration.md` when the project does not run on the starter's local Docker stack

## Core setup rule

Do not stop after placeholder replacement.

A project is only set up when all of these are true:

- placeholders and visible starter identity leftovers are gone
- env and token values are present
- Docker stack comes up
- the intended operator path is explicit: local starter Docker stack or shared/external tibi-server stack
- website, admin, and API respond on the expected project URLs
- if the current stack requires server-level config and project registration, that operator flow is completed
- `yarn build`, `yarn build:server`, and `yarn validate` pass

## Prerequisites

- `git`, `yarn`, `make`, `docker compose`, `curl`
- current Code-Server / Docker environment for `*.code.testversion.online`
- reverse proxy/Traefik managed by the host environment

## Step 1 — Clone and prepare remotes

Skip if the project is already cloned.

```sh
git clone https://gitbase.de/cms/tibi-svelte-starter.git my-project
cd my-project
git remote rename origin template
git remote add origin https://gitbase.de/<org>/<repo>.git
```

## Step 2 — Replace starter placeholders and identity surfaces

Replace placeholders in all required files:

- `.env`
- `api/config.yml`
- `frontend/.htaccess` when the deployment path uses the shipped Apache rewrite/proxy file
- `api/hooks/config-client.js`
- `package.json`
- `README.md` or other visible starter naming surfaces when the repo is already project-facing
- any other file that still contains starter markers

Minimum placeholders to replace:

- `__PROJECT_NAME__`
- `__TIBI_NAMESPACE__`
- `__ORG__`
- `__PROJECT__`

Verify with:

```sh
rg '__[A-Z0-9_]+__' . --glob '*.{yml,js,env,htaccess,json,md,ts,svelte}'
```

If anything remains, the setup is not complete.

## Step 3 — Fill project env, token, and metadata files

Set the current project URLs in `.env`:

- `LIVE_URL`
- `CODING_URL`
- `STAGING_URL`
- `CODING_TIBIADMIN_URL`
- `CODING_TIBISERVER_URL` only when the current environment exposes a dedicated raw tibi-server host

Generate `api/config.yml.env` values:

```sh
token=$(openssl rand -hex 20)
cat > api/config.yml.env <<EOF
ADMIN_TOKEN=$token
ADMIN_ASSET_VERSION=$(node -e "process.stdout.write(require('crypto').randomBytes(6).toString('hex'))")-dirty-$(date +%s)
EOF
```

Important:

- `ADMIN_TOKEN` generated in `api/config.yml.env` is the project-local token used for collection-level writes through the header name declared by the collection permission key; in this starter that is typically `Token` via `token:${ADMIN_TOKEN}`
- the current deploy scripts also use the same secret as a bearer token on the project-local reload endpoint
- do not assume this generated project-local `ADMIN_TOKEN` automatically has raw system-level `project` or `project.read` permissions
- if `GET /api/v1/project` with `X-Admin-Token: $ADMIN_TOKEN` returns `permission denied: admin token lacks permission project.read`, that token is not valid for project registration
- create new projects by logging in with `admin` / `admin` in the default starter dev setup and using the returned JWT via `X-Auth-Token`
- `ADMIN_ASSET_VERSION` is required so Nova picks up the current admin bundle
- `PROJECT_NAME`, `TIBI_NAMESPACE`, `PRODUCTION_PATH`, and `STAGING_PATH` should be project-specific before the first deploy
- `package.json` should no longer advertise the starter repository or default package name once the project is bootstrapped

## Step 4 — Install and start the Docker stack

Use the Docker targets from the project. Do not try to start the frontend with local dev servers.

```sh
yarn install
make docker-up
```

Notes:

- `make docker-up` already depends on `init`; do not duplicate bootstrap steps unless debugging Make targets directly
- for foreground operation use `make docker-start`

## Step 5 — Choose the active bootstrap path

### Path A — Local starter Docker stack

This repo's default local path is the Docker stack in `docker-compose-local.yml` started via `make docker-up`.

Important characteristics:

- the project is mounted into `tibiserver` as `/data`
- `DB_DIAL`, `DB_PREFIX`, `MAIL_HOST`, and security overrides are injected via container environment
- the project is served from the repo's own `api/config.yml`
- the repo files alone do not guarantee that the project is already registered in the running tibi-server instance

Important exception:

- if the local stack returns `project not found` for `/_/<namespace>/...` routes, treat that as a real registration gap instead of assuming the proxy is broken
- new projects should be assumed to be unregistered until the current tibi-server instance proves otherwise
- if needed, perform the one-time project registration before debugging unrelated frontend or SSR layers

Use this path unless the operator environment clearly tells you otherwise.

### Path B — Shared or external tibi-server stack

Only use this path when the project is not started through the local starter compose stack and the operator environment requires explicit server-level config or project registration.

In that case, confirm all of these with the operator first:

- which admin token is valid for raw system-level APIs
- which base URL exposes `/api/v1/project`
- how the project path is mounted into the shared tibi-server instance

Do not invent Path B steps in the local starter Docker stack just because upstream tibi-server docs mention them.
But do not ignore an explicit `project not found` server response either; that is the discriminating signal that the project may still need registration in the current runtime.

## Step 6 — Treat new projects as unregistered first

Do not assume that a new project is already known to the running tibi-server instance just because the files exist on disk.

Use this mental model first:

- files on disk define the project config
- project registration makes that config available to the running tibi-server instance
- until registration exists, namespace routes can fail with `project not found`

## Step 7 — Verify website, admin, and API reachability

Run the project-local checks after startup:

```sh
curl -I "$CODING_URL"
curl -I "$CODING_TIBIADMIN_URL"
curl -I "$CODING_URL/api/content?limit=1"
```

If the current environment also exposes a raw tibi-server host, add:

```sh
curl -I "$CODING_TIBISERVER_URL/api/v1/version"
```

If `/api/...` returns HTML instead of JSON, the reverse-proxy/setup path is still wrong.
If `/api/...` fails with `project not found`, the project runtime is up but the namespace is not registered in the current tibi-server instance yet.

## Step 8 — Project registration when the current runtime requires it

Projects are not assumed to exist just because files are present on disk. Register and reload them explicitly when the current stack requires project registration.

This step is mandatory for Path B and should be the first check for new projects whenever the running instance responds with `project not found` for the project namespace.

Token source for this step:

- do not blindly reuse the generated `api/config.yml.env` `ADMIN_TOKEN`
- first verify whether that token can read `GET /api/v1/project`
- in the default local starter setup, log in via `POST /api/v1/login` with `admin` / `admin` and use the returned JWT via `X-Auth-Token`

Default local dev flow:

```sh
jwt=$(curl -s -X POST "$CODING_TIBIADMIN_URL/api/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin"}' | jq -r '.token')
```

```sh
curl -s -X POST "$CODING_TIBISERVER_URL/api/v1/project" \
  -H "Content-Type: application/json" \
  -H "X-Auth-Token: $jwt" \
  -d '{
    "name": "<PROJECT_NAME>",
    "description": "...",
    "configFile": "/data/api/config.yml",
    "enabled": true
  }'
```

Expected effect:

- the project appears in `GET /api/v1/project`
- the project namespace begins to resolve on `/_/<namespace>/...`
- project-local `/api/...` proxy calls can start returning JSON instead of `project not found`

Reload after creation or config changes:

```sh
curl -s -X POST "$CODING_TIBISERVER_URL/api/v1/_/<PROJECT_NAME>/_/admin/reload" \
  -H "X-Auth-Token: $jwt"
```

### Token header distinction

- project registration in the default starter dev setup: log in with `admin` / `admin` and use `X-Auth-Token`
- raw system-level API such as project CRUD or direct admin reload can also use `X-Admin-Token` when such a server-level admin token exists in the current runtime
- collection-level CRUD such as content/navigation writes: use the header name from the collection permission key, typically `Token` in this starter via `token:${ADMIN_TOKEN}`
- JWT-authenticated user requests: `X-Auth-Token`; for project/user endpoints this is checked as fallback when no admin token is provided

The current starter deploy scripts are a separate case: they call the reverse-proxied reload endpoint on `LIVE_URL` or `STAGING_URL` with `Authorization: Bearer ${ADMIN_TOKEN}`.

Do not mix these headers casually. A working collection token does not imply project-admin access.

## Step 9 — Build and validate

```sh
yarn build
yarn build:server
yarn validate
```

The project is not considered bootstrapped until all three succeed.

## Step 10 — Optional immediate follow-up work

Depending on the project state, continue with:

- seed or create initial content/navigation entries
- remove demo content and demo assets
- update project imagery/icons
- run the first targeted Playwright smoke checks

## Recommended verification sequence

Use this exact order when debugging a broken setup:

1. placeholder scan
2. env/token/metadata presence
3. Docker stack or target operator stack up
4. choose Path A or Path B explicitly
5. if Path B: server-level config and project registration/reload succeed
6. website/admin/API reachability
7. build/SSR build/validate

This prevents wasting time in frontend code when the real issue is project registration or server-level config.

## Common failure modes

### Placeholders still present

Symptom:

- URLs or namespace stay wrong even though the project name was changed manually

Fix:

- rerun the placeholder scan and replace every remaining marker

### Website works but API probes return HTML

Symptom:

- `curl "$CODING_URL/api/content?limit=1"` returns HTML

Fix:

- verify reverse-proxy routing and the configured API/admin URLs

### Files exist but the project is invisible to tibi-server

Symptom:

- project does not show in admin or reload endpoint fails

Fix:

- this is a Path B problem; verify the shared-stack server-level config and project registration flow instead of changing the local starter stack

### Admin bundle changes do not appear

Symptom:

- Nova still loads stale admin assets

Fix:

- regenerate or bump `ADMIN_ASSET_VERSION`

### Build passes locally but operational setup is still broken

Symptom:

- files compile, but website/admin/API are not all reachable

Fix:

- return to the reachability and registration checks instead of continuing with feature work

## What an LLM should inspect first

When asked to bootstrap or audit a starter-derived project, inspect in this order:

1. `README.md`
2. `.env`
3. `api/config.yml`
4. `api/config.yml.env`
5. `api/hooks/config-client.js`
6. `docker-compose-local.yml` and `Makefile`
7. whether the current stack is Path A (local starter Docker) or Path B (shared/external tibi-server)
8. whether website, admin, and API URLs all respond

This avoids the common mistake of treating setup as a naming exercise instead of a full stack-registration task.
