feat(registry): index cpp/apps/* + e2e test infrastructure

registry/indexer.go ahora escanea <lang>/apps/*/app.md ademas de apps/ y
projects/*/apps/. cpp/apps/chart_demo y cpp/apps/shaders_lab pasan a estar
en registry.db con sus manifests.

Infraestructura de tests e2e (opt-in con -DFN_BUILD_TESTS=ON):
- vendor de Dear ImGui Test Engine (personal/open-source license).
- chart_demo_tests target con tests/chart_demo_tests.cpp.
- /e2e-cpp slash command para crear y ejecutar tests e2e.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-04 11:51:38 +02:00
parent bf94893032
commit ab6ce8f822
37 changed files with 18370 additions and 8 deletions
+19 -5
View File
@@ -84,13 +84,27 @@ func Index(db *DB, root string) (*IndexResult, error) {
})
}
// Parse apps from apps/*/app.md (standalone apps, no project)
// Parse apps from apps/*/app.md (standalone apps, no project) and from
// <lang>/apps/*/app.md (language-specific standalone apps, e.g. cpp/apps/).
var apps []*App
localAppIDs := make(map[string]bool)
appsDir := filepath.Join(root, "apps")
if fi, err := os.Stat(appsDir); err == nil && fi.IsDir() {
entries, _ := os.ReadDir(appsDir)
for _, e := range entries {
appsDirs := []string{filepath.Join(root, "apps")}
for _, e := range entries {
if !e.IsDir() {
continue
}
langApps := filepath.Join(root, e.Name(), "apps")
if fi, err := os.Stat(langApps); err == nil && fi.IsDir() {
appsDirs = append(appsDirs, langApps)
}
}
for _, appsDir := range appsDirs {
fi, err := os.Stat(appsDir)
if err != nil || !fi.IsDir() {
continue
}
appEntries, _ := os.ReadDir(appsDir)
for _, e := range appEntries {
if !e.IsDir() {
continue
}