Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ pnpm-debug.log*
.vitepress/dist/
docs/.vitepress/cache/
docs/.vitepress/dist/
docs/.vitepress/generated-course-data.mjs
docs/.vitepress/featured-course.json
courses/
docs/courses/
*.tsbuildinfo
artifacts/
dist/
95 changes: 36 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,59 @@
# course-builder

Whitelabel VitePress course builder with multi-course manifest support.
Reusable VitePress course builder. The repository contains the builder only; course source content can live outside the repo and is mirrored into `docs/courses/` during local dev and build.

This repository is no longer only the `Learn Harness Engineering` course. It now contains:
## How it works

- a reusable VitePress course platform
- one active course selected at build time
- multiple course manifests under `courses/`
- isolated course content under `courses/<slug>/docs`
- external course source directory: `../course-builder-courses` by default
- override source directory: `COURSE_SOURCE_DIR=/absolute/or/relative/path`
- manifest contract per course: `<course-dir>/course.manifest.mjs`
- markdown content per course: `<course-dir>/docs/<locale>/...`
- generated mirror used by VitePress: `docs/courses/<slug>/`
- generated runtime registry: `docs/.vitepress/generated-course-data.mjs`

## Current structure
The published site exposes:

- active course selector: [docs/.vitepress/active-course.mjs](/Users/matheuspuppe/Desktop/estudo/course-builder/docs/.vitepress/active-course.mjs:1)
- active-course wrapper: [docs/.vitepress/course.manifest.mjs](/Users/matheuspuppe/Desktop/estudo/course-builder/docs/.vitepress/course.manifest.mjs:1)
- builder shell: [docs/.vitepress/config.mts](/Users/matheuspuppe/Desktop/estudo/course-builder/docs/.vitepress/config.mts:1)
- course manifests:
- [courses/learn-harness-engineering/course.manifest.mjs](/Users/matheuspuppe/Desktop/estudo/course-builder/courses/learn-harness-engineering/course.manifest.mjs:1)
- [courses/agent-ops-bootcamp/course.manifest.mjs](/Users/matheuspuppe/Desktop/estudo/course-builder/courses/agent-ops-bootcamp/course.manifest.mjs:1)
- course content roots:
- [courses/learn-harness-engineering/docs](/Users/matheuspuppe/Desktop/estudo/course-builder/courses/learn-harness-engineering/docs:1)
- [courses/agent-ops-bootcamp/docs](/Users/matheuspuppe/Desktop/estudo/course-builder/courses/agent-ops-bootcamp/docs:1)
- root catalog at `/`
- one route tree per course at `/courses/<slug>/<locale>/...`

## Commands

```bash
npm install
npm run courses:sync
npm test
npm run docs:build
npm run docs:dev
npm run docs:build
```

To inspect and switch courses:
Useful course commands:

```bash
npm run course:list
npm run course:new -- my-new-course "My New Course"
npm run course:activate -- learn-harness-engineering
npm run course:activate -- agent-ops-bootcamp
npm run course:new -- my-course "My Course"
npm run course:activate -- my-course
```

## How it works

Each course manifest defines:

- `site`
- `brand`
- `theme`
- `locales`
- `curriculum`
- `homeByLocale`

The VitePress layer reads the active manifest and points `srcDir` at that course's own `docs` directory. Nav, sidebar, branding, homepage, and markdown content all come from the active course.

## Creating a new course

1. Create `courses/<slug>/course.manifest.mjs`.
2. Or scaffold both manifesto and docs with `npm run course:new -- <slug> "Course Title"`.
3. Create `courses/<slug>/docs/` if you did not use the scaffold command.
4. Define the course `site`, `brand`, `theme`, `locales`, `curriculum`, and `homeByLocale`.
5. Add markdown content under `courses/<slug>/docs/<locale>/...` to match the curriculum.
6. Switch to it with `npm run course:activate -- <slug>`.

## Current limitations

- only one course is active per build
- the current manifest format is code-first, not CMS-driven
- only one course is active per build

## Validation

The repo currently validates:

- manifest loading
- branding token generation
- locale-aware navigation generation
- alternate course manifest loading
- full VitePress production build
## External course layout

Each external course directory should look like:

```text
course-builder-courses/
my-course/
course.manifest.mjs
docs/
index.md
en/
index.md
lectures/
projects/
resources/
skills/
```

## Notes

The second course, `agent-ops-bootcamp`, exists mainly as an architectural proof that the platform can host distinct branding and curriculum in the same repo.
- `courses/` inside this repo is ignored and should not be used as the source of truth.
- `docs/courses/` and generated registry files are local build artifacts and are ignored.
- `npm test`, `npm run docs:dev`, and `npm run docs:build` sync external courses before running.
94 changes: 42 additions & 52 deletions WHITELABEL.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,44 @@
# Whitelabel Guide

O projeto agora está estruturado para suportar múltiplos cursos com um curso ativo definido pela camada VitePress.

## Estrutura atual

- curso ativo: [docs/.vitepress/active-course.mjs](/Users/matheuspuppe/Desktop/estudo/course-builder/docs/.vitepress/active-course.mjs:1)
- manifesto do curso atual: [courses/learn-harness-engineering/course.manifest.mjs](/Users/matheuspuppe/Desktop/estudo/course-builder/courses/learn-harness-engineering/course.manifest.mjs:1)
- conteúdo do curso atual: [courses/learn-harness-engineering/docs](/Users/matheuspuppe/Desktop/estudo/course-builder/courses/learn-harness-engineering/docs:1)
- wrappers compatíveis com a camada antiga:
- [docs/.vitepress/course.config.mjs](/Users/matheuspuppe/Desktop/estudo/course-builder/docs/.vitepress/course.config.mjs:1)
- [docs/.vitepress/course-content.mjs](/Users/matheuspuppe/Desktop/estudo/course-builder/docs/.vitepress/course-content.mjs:1)
- [docs/.vitepress/course-curriculum.mjs](/Users/matheuspuppe/Desktop/estudo/course-builder/docs/.vitepress/course-curriculum.mjs:1)
- [docs/.vitepress/course-locales.mjs](/Users/matheuspuppe/Desktop/estudo/course-builder/docs/.vitepress/course-locales.mjs:1)

## O que já está desacoplado

- branding visual do site
- config base do VitePress
- manifesto de locales e labels de UI
- currículo por locale
- conteúdo da homepage por locale
- conteúdo markdown por curso
- seleção do curso ativo

## Como criar outro curso

1. Crie uma pasta `courses/<slug>/`.
2. Crie `courses/<slug>/docs/`.
3. Copie [courses/learn-harness-engineering/course.manifest.mjs](/Users/matheuspuppe/Desktop/estudo/course-builder/courses/learn-harness-engineering/course.manifest.mjs:1) para o novo slug.
4. Edite no manifesto:
- `site.title`
- `site.description`
- `site.base`
- `site.repoTreeUrl`
- `brand.logo`
- `theme.*`
- `locales`
- `curriculum`
- `homeByLocale`
5. Adicione o conteúdo real em `courses/<slug>/docs/<locale>/` para bater com o currículo do novo curso.
6. Ative o curso.

Ou use os comandos:

- `npm run course:list`
- `npm run course:new -- <slug> "Course Title"`
- `npm run course:activate -- <slug>`

## Limitações atuais

- o manifesto do curso atual ainda concentra muito conteúdo inline
- ainda existe apenas um curso ativo por build
- o builder ainda depende de manifests em código, não de uma camada editorial
O repositório agora é apenas o builder. Os cursos devem ficar fora dele e entrar no site por sincronização.

## Estrutura

- builder VitePress: `docs/.vitepress/`
- catálogo inicial: `docs/index.md`
- espelho gerado dos cursos: `docs/courses/`
- configuração da fonte externa: `scripts/course-source-config.mjs`
- sincronização: `scripts/sync-course-docs.mjs`

## Fonte dos cursos

Por padrão, o builder procura cursos em:

```bash
../course-builder-courses
```

Você pode trocar isso com:

```bash
COURSE_SOURCE_DIR=../outro-diretorio npm run docs:dev
```

Cada curso externo precisa ter:

1. `course.manifest.mjs`
2. `docs/`
3. conteúdo por locale compatível com o currículo definido no manifest

## Fluxo

1. Crie ou edite o curso fora deste repo.
2. Rode `npm run courses:sync`.
3. Rode `npm run docs:dev` ou `npm run docs:build`.
4. Se quiser mudar o destaque do catálogo, rode `npm run course:activate -- <slug>`.

## Observações

- `courses/` neste repo está no `.gitignore`.
- `docs/courses/` e `docs/.vitepress/generated-course-data.mjs` são artefatos gerados.
- O site continua servindo múltiplos cursos em `/courses/<slug>/<locale>/...`.
Loading