The Dashboard & Database Switcher

The Dashboard & Database Switcher

The dashboard/ directory is a single Next.js application that hosts every application’s dashboards at once. Its hub is where the multi-database model becomes navigation: a database switcher picks which application you are looking at, and the hub shows only the dashboards valid for the selected database.

The switch

The hub reads a database and renders the applications available in it.

  1. On load, the hub calls typedb-notebook scan-databases. That command lists every database on the TypeDB server and, for each (database, skill) pair, probes a representative entity type and reports:
    • data — the type exists and has rows (the application is live here)
    • schema — the type is defined but empty
    • absent — the type is not defined in this database
  2. Selecting a database stores the choice (localStorage key alh-db) and filters the dashboard tiles: any skill whose status is absent is hidden, data tiles rank ahead of schema tiles.
  3. Every dashboard page then reads from the selected database, so the entire UI is scoped to one application at a time.

The probe map (skill → representative type) lives in typedb_notebook.py as DASHBOARD_PROBES; a skill may list several probe types (the best status wins).

Select this database …and these dashboards appear
alh_core / alhazen_notebook Agentic Memory (and the other core tools)
alh_deep_research Scientific Literature, Tech Recon, DisMech Notebook
alh_personal Career, Analyst, Advisor, Scribe, Ops, Chief of Staff, Coach
alh_mythras Mythras GM

Because absent dashboards are hidden rather than greyed out, the hub only ever shows applications that actually exist on your server.

How one dashboard is built

Each skill contributes its dashboard from its own dashboard/ folder, wired into the Next.js app on build. Skills are isolated with route groups (a folder like (career) that groups files without appearing in the URL) and per-skill component and API subfolders.

dashboard/src/
├── app/
│   ├── layout.tsx                 ← minimal root (fonts, dark mode, hub)
│   ├── (career)/                  ← route group (not in URL)
│   │   ├── layout.tsx             ← per-dashboard metadata
│   │   ├── career/page.tsx        ← URL: /career
│   │   └── career/opportunity/[id]/page.tsx
│   └── api/
│       └── career/…               ← one route per CLI command
├── components/
│   ├── ui/                        ← shared shadcn/ui primitives
│   └── career/…                   ← skill-specific components
└── lib/
    └── career.ts                  ← CLI wrapper (uv run → JSON)

Every dashboard follows the same three-layer pattern:

Browser (React client pages)
  → API routes (thin try/catch wrappers)
    → lib/<skill>.ts (calls the Python CLI via uv run)
      → TypeDB (the selected database)

Adding a dashboard for a new skill

  1. CLI wrappersrc/lib/<skill>.ts calls uv run python .claude/skills/<skill>/<skill>.py via execFile and parses the JSON on stdout.
  2. API routessrc/app/api/<skill>/, one thin route per CLI command, returning NextResponse.json().
  3. Route group + pagessrc/app/(<skill>)/ with a layout.tsx for metadata, <skill>/page.tsx as the home page, and <entity>/[id]/page.tsx detail pages.
  4. Componentssrc/components/<skill>/.
  5. Register the probe — add the skill’s representative entity type to DASHBOARD_PROBES in typedb_notebook.py so the switcher can detect it.
  6. Verify./node_modules/.bin/next build.

Environment notes

  • Scripts resolve their database from a .standalone-db marker or the TYPEDB_DATABASE env var — a personal-assistant skill points at alh_personal, a deep-research skill at alh_deep_research — rather than assuming one global default.
  • Build with ./node_modules/.bin/next build (not npm run build, which may miss PATH).
  • Tech stack: Next.js, shadcn/ui, Tailwind CSS, React. Pages are 'use client' (client-side fetch via useState/useEffect).