217 lines
11 KiB
Markdown
217 lines
11 KiB
Markdown
# AGENTS.md
|
|
|
|
Tibi CMS starter template — Svelte 5 SPA with esbuild, SSR via goja, and Playwright tests.
|
|
|
|
## Skill auto-improvement
|
|
|
|
Skills in `.agents/skills/` are **automatically updated** when the agent discovers patterns, gotchas, or workflows that are:
|
|
- Generic enough to apply across projects (not project-specific workarounds)
|
|
- Missing from the current skill documentation
|
|
- Important enough to prevent the same mistake in future projects
|
|
|
|
If you see an agent updating a skill file, it is capturing reusable knowledge. Review skill diffs to stay informed about evolving conventions.
|
|
|
|
## Token header distinction
|
|
|
|
- **System-level API** (raw tibi-server project CRUD, raw admin reload, server ops): use `X-Admin-Token` header
|
|
- **Collection-level API** (CRUD on content, navigation, etc.): use the header name defined by the collection permission key. In this starter that is typically `Token` via permission entries such as `token:${ADMIN_TOKEN}`.
|
|
- **User-level API** (JWT-authenticated requests): use `X-Auth-Token` header
|
|
|
|
## Medialib image URL pattern
|
|
|
|
In this starter, medialib URLs are derived from the entry ID plus the stored relative `file.src` value. If `file.src` is `file/example.jpg`, the project-local URL is `/api/medialib/{entryId}/file/example.jpg`.
|
|
Shared widgets such as `MedialibImage` append responsive filters as query params, for example `/api/medialib/{entryId}/file/example.jpg?filter=l-webp`.
|
|
These `/api/...` URLs are starter-local proxy URLs. Do not hardcode `file/file`.
|
|
|
|
## Project overview
|
|
|
|
- **Frontend**: Svelte 5 SPA in `frontend/src/`, esbuild, Tailwind CSS 4.
|
|
- **Backend**: tibi-server with hooks in `api/hooks/`, collections in `api/collections/`.
|
|
- **SSR**: goja (Go JS runtime) in `api/hooks/ssr/`.
|
|
- **Tests**: Playwright in `tests/` (API, E2E, mobile, visual).
|
|
- **Types**: `types/global.d.ts` (project), `tibi-types/` (read-only, from sibling repo).
|
|
|
|
## Key constraints
|
|
|
|
- **Dev servers always run in Docker** — never `yarn dev` or `yarn start` locally.
|
|
- `yarn` is for standalone tasks: `build`, `build:server`, `validate`.
|
|
- Bootstrap details (placeholder replacement, docker setup) → `tibi-project-setup` skill.
|
|
- Build checklist for full website projects → `.agents/BUILD_CHECKLIST.md`.
|
|
- Starter maintenance current state → `.agents/STARTER_ALIGNMENT_STATUS.md`.
|
|
- Starter maintenance and upstream/reference alignment workflow → `.agents/STARTER_ALIGNMENT_PLAN.md`.
|
|
|
|
## Project delivery workflow
|
|
|
|
When building a new website project from this starter, work through `.agents/BUILD_CHECKLIST.md` **phase by phase**. Do not skip phases, even when individual checklist items are already satisfied by the starter defaults.
|
|
|
|
For each phase:
|
|
|
|
1. Load the required skills listed in that phase.
|
|
2. Create or update the required project artifacts.
|
|
3. Work through every `[ ]` implementation check.
|
|
4. Run the listed validation commands. A phase is not done until all validations pass.
|
|
5. Mark each `[ ]` as `[x]` only when the concrete check is satisfied and its validation command passes cleanly.
|
|
6. Confirm all exit criteria before moving to the next phase.
|
|
|
|
The checklist covers the full delivery lifecycle: bootstrap → architecture → collections → types → frontend → SSR → hooks/actions → permissions → audit → media/SEO → optional branches → ops/deploy → tests → final verification.
|
|
|
|
## Quick reference
|
|
|
|
| Action | Command |
|
|
|--------|---------|
|
|
| Start dev stack | `make docker-up` or `make docker-start` |
|
|
| Restart frontend | `make docker-restart-frontend` |
|
|
| Logs | `make docker-logs` |
|
|
| Build frontend | `yarn build` |
|
|
| Build SSR | `yarn build:server` |
|
|
| Validate | `yarn validate` |
|
|
| Run all tests | `yarn test` |
|
|
| Run E2E tests | `yarn test:e2e` |
|
|
| Run API tests | `yarn test:api` |
|
|
|
|
## Testing notes
|
|
|
|
- Tests read `CODING_URL` from `.env`. Ensure it serves both `/` and `/api/...`.
|
|
- After changes, run only affected specs: `npx playwright test tests/e2e/filename.spec.ts`.
|
|
- CI runs `yarn validate` but not Playwright (needs MongoDB + tibi-server).
|
|
|
|
## API access
|
|
|
|
- `Token` header with `ADMIN_TOKEN` from `api/config.yml.env` when the collection permission key is `token:${ADMIN_TOKEN}`.
|
|
- Collection `user:` permissions apply to JWT auth (`X-Auth-Token`), not static `Token:`.
|
|
- For write access via `ADMIN_TOKEN`, add `"token:${ADMIN_TOKEN}": { methods: { post: true, put: true } }` to the collection permissions.
|
|
- The current deploy scripts call the reverse-proxied reload endpoint on `LIVE_URL` or `STAGING_URL` with `Authorization: Bearer ${ADMIN_TOKEN}`. Treat that as a separate project-local proxy surface from raw tibi-server project CRUD APIs.
|
|
|
|
## Required secrets
|
|
|
|
| Secret | Location | Purpose |
|
|
| --- | --- | --- |
|
|
| `ADMIN_TOKEN` | `api/config.yml.env` | API/admin access token |
|
|
| `ADMIN_ASSET_VERSION` | `api/config.yml.env` | Cache-busting for admin bundle (auto-generated) |
|
|
| `.basic-auth-web` | project root (git-ignored) | BrowserSync basic auth |
|
|
| `.basic-auth-code` | project root (git-ignored) | Code-Server basic auth |
|
|
|
|
Generated dev defaults in `api/config.yml.env` may be committed. Production values are overwritten in CI/CD via secrets.
|
|
|
|
## TypeScript
|
|
|
|
```json
|
|
"include": ["frontend/src/**/*", "types/**/*", "./../../cms/tibi-types", "api/**/*"]
|
|
```
|
|
|
|
- Domain types (entities, block props, API responses) be strict. `any`/`[key: string]: any` OK for inherently dynamic data (MongoDB filters, CMS fields, hook payloads).
|
|
- No `@ts-ignore` — use `/** @type {…} */` cast instead.
|
|
- **Zero warnings policy**: always run `yarn validate` after changes; fix all warnings.
|
|
- Svelte 5 with Runes: `$props()`, `$state()`, `$derived()`, `$effect()`.
|
|
|
|
## Svelte 5 patterns
|
|
|
|
- **Prop destructuring**: Destructuring `block` from `$props()` into local variables triggers `state_referenced_locally` warnings. The values capture initial state and lose reactivity. Either access through the parent object (`block.headline`) or use `$derived` for each value.
|
|
- **`$derived.by()`**: Use for multi-statement derived values: `let filtered = $derived.by(() => { if (x) return a; return b; })`
|
|
- **`class:` directive**: Invalid with `/` in class names like `class:text-white/85`. Use ternary in `class` attribute instead: `class={condition ? 'text-white/85' : ''}`.
|
|
|
|
## Reference repositories (sibling repos)
|
|
|
|
| Repo | Path | Key file |
|
|
|------|------|----------|
|
|
| **tibi-types** | `../tibi-types` | `index.d.ts` (context types), `schemas/config/collection.schema.json` |
|
|
| **tibi-server** | `../tibi-server` | `docs/` (20 files: collections, hooks, auth, actions, SSE, jobs, etc.) |
|
|
| **tibi-admin-nova** | `../tibi-admin-nova` | `types/admin.d.ts` (all admin config types) |
|
|
|
|
### When to consult which repo
|
|
|
|
- **Collection YAML** → `tibi-server/docs/04-collections.md` + `tibi-types/schemas/config/collection.schema.json`
|
|
- **Hooks** → `tibi-server/docs/06-hooks.md` + `tibi-types/index.d.ts`
|
|
- **Admin UI config** → `tibi-admin-nova/types/admin.d.ts` + `tibi-admin-nova/docs/collection-config.md`
|
|
- **Permissions** → `tibi-server/docs/05-authentication.md`
|
|
- **Actions/forms** → `tibi-server/docs/19-actions.md`
|
|
- **Realtime/SSE** → `tibi-server/docs/07-realtime.md`
|
|
- **Images/uploads** → `tibi-server/docs/08-file-upload-images.md`
|
|
- **LLM integration** → `tibi-server/docs/09-llm-integration.md`
|
|
- **Field-level permissions** → `tibi-server/docs/17-field-level-permissions.md`
|
|
|
|
## API lookup für aufgelöste Referenzen
|
|
|
|
Beim Laden von Collections können Fremdschlüssel via `lookup`-Parameter automatisch aufgelöst werden:
|
|
|
|
```ts
|
|
// entries mit aufgelösten medialib-Bildern laden
|
|
const entries = await getCachedEntries<"content">("content", {
|
|
filter: { active: true },
|
|
sort: "sort",
|
|
lookup: "blocks.heroImage.image:medialib"
|
|
})
|
|
// Ergebnis: entry._lookup enthält die aufgelösten Referenzen
|
|
```
|
|
|
|
Der `lookup`-Parameter wird im Optionen-Objekt an `getCachedEntries` übergeben. Ohne lookup bleiben Referenzfelder reine ID-Werte ohne `_lookup`.
|
|
|
|
## Tailwind CSS 4
|
|
|
|
Canonical v4 syntax — no v3 legacy classes:
|
|
|
|
| v3 | v4 |
|
|
|----|----|
|
|
| `bg-gradient-to-*` | `bg-linear-to-*` |
|
|
| `aspect-[4/3]` | `aspect-[4/3]` (v4 hat nur `aspect-square`/`aspect-video` als Built-in-Utilities; benutzerdefinierte Ratios bleiben arbitrary) |
|
|
| `!bg-brand-600` | `bg-brand-600!` |
|
|
| `hover:!bg-brand-700` | `hover:bg-brand-700!` |
|
|
|
|
## Architecture skills (loaded on demand)
|
|
|
|
Use these tables as the lookup index. Each skill is a deep-dive for its domain.
|
|
|
|
### 1. Project start and solution design
|
|
|
|
| Skill | When |
|
|
|-------|------|
|
|
| `tibi-project-setup` | Bootstrap a new project from scratch |
|
|
| `website-solution-architecture` | Translate requirements into collections, blocks, SSR, workflows |
|
|
| `security-hardening-and-token-strategy` | Token strategy, secrets, hook risk surfaces, CORS |
|
|
|
|
### 2. Content model and editor UX
|
|
|
|
| Skill | When |
|
|
|-------|------|
|
|
| `content-authoring` | Add pages, block types, collections, and required type/registry wiring |
|
|
| `nova-pagebuilder-modeling` | Block schemas, preview, drillDown, dependsOn |
|
|
| `nova-navigation-modeling` | Header/footer trees, viewHint.navigation, declaredTrees |
|
|
| `admin-ui-config` | Field widgets, sidebar, layout, choices, foreign refs |
|
|
| `media-seo-publishing` | Image fields, alt/caption, SEO, publication model |
|
|
| `permissions-and-editor-workflows` | Field-level readonly/hidden, 3-layer cascade, custom roles |
|
|
| `nova-ai-editor-features` | AI-assisted alt text, LLM actions, token budgets |
|
|
|
|
### 3. Backend behavior
|
|
|
|
| Skill | When |
|
|
|-------|------|
|
|
| `tibi-hook-authoring` | Write/debug server-side hooks (goja) |
|
|
| `tibi-actions-and-forms` | Contact forms, newsletter, webhooks, action endpoints |
|
|
| `scheduled-jobs-and-automation` | Cron tasks, cleanup, reports, sync |
|
|
| `realtime-and-live-workflows` | SSE channels, live notifications, preview refresh |
|
|
| `audit-and-compliance` | Audit logging, retention, audit.return filtering, source semantics |
|
|
|
|
### 4. Frontend and delivery
|
|
|
|
| Skill | When |
|
|
|-------|------|
|
|
| `frontend-architecture` | SPA router, stores, Svelte 5 patterns, API layer |
|
|
| `tibi-ssr-caching` | SSR rendering, cache invalidation, 404 signaling |
|
|
| `playwright-testing` | Deterministic seed data, API/E2E/admin/visual tests |
|
|
| `deployment` | Production deployment setup, Basispanel subdomains, CI, rsync, staging |
|
|
|
|
### 5. Operations and diagnostics
|
|
|
|
| Skill | When |
|
|
|-------|------|
|
|
| `mongodb-and-indexes` | Mongo prerequisites, replica set, indexes, persistence, backup assumptions |
|
|
| `monitoring-and-performance` | OpenAPI, metrics, Sentry, reachability and observability checks |
|
|
| `troubleshooting-and-debugging` | Common stack failures, hook/runtime debugging, config/auth diagnosis |
|
|
|
|
### 6. AI, search, and enterprise
|
|
|
|
| Skill | When |
|
|
|-------|------|
|
|
| `search-and-embeddings` | Search modes, embedding providers, regeneration, semantic retrieval |
|
|
| `multi-tenancy-and-orgs` | Org/team isolation, enterprise permissions, visibility vs working rights |
|