---
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` is 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
- `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`
- no extra root `config.yml` or `/api/v1/project` registration step is required for basic local startup

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:

- where the server-level `config.yml` lives
- 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.

## Step 6 — Optional server-level config and project registration for Path B

Shared or external tibi-server setups may require a server-level `config.yml` outside the project config. That file defines database connection, JWT secret, and admin tokens used for project CRUD and reload.

Create a root-level `config.yml` such as:

```yaml
db:
    dial: mongodb://mongo
    prefix: tibi

api:
    port: 8080
    jwtSecret: <random-secret>
    adminTokens:
        - token: "<ADMIN_TOKEN>"
          label: "admin"
          permissions:
              - project
              - project.reload
              - user
              - namespace.<PROJECT_NAME>
              - server.shutdown

mail:
    host: localhost:25

security:
    allowAbsolutePaths: false
    allowUpperPaths: true
```

Then copy it into the tibi-server container and restart that container if the current environment requires this manual step.

## 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.

## Step 8 — Optional project registration for Path B

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.

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

Reload after creation or config changes:

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

### Token header distinction

- raw system-level API such as project CRUD or direct admin reload: `X-Admin-Token`
- 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`

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.
