PTENES
5.4 Track 5 ~50 min Real Case

🖥️ Case Study: ClaudeOS (Hermes)

Dissect a real long-term project: a personal AI dashboard with Bun + TanStack/React + Vite + Tailwind, deployed on Cloudflare. V2.3 — May/2026.

1 🗺️ Project Overview

ClaudeOS (codename Hermes) is a personal dashboard read-only for anyone running a local AI stack. It consolidates data from multiple sources into a single interface—without modifying any of them.

🍞

Bun 1.1

Runtime

⚛️

React 19

TanStack Query

⚡

Vite 6

+ Tailwind 4

☁️

Cloudflare

Pages + wrangler

🤖 Claude Code 📓 Obsidian 🔗 OpenRouter 🌲 Pinecone ⚙️ aggregate.ts scanner + pipeline 📄 live-data .json artifact 🖥️ UI Data sources scripts/aggregate.ts src/data/

ClaudeOS architecture: sources → pipeline → JSON → React dashboard

Why this project is a good case study

Applies 5.1

Layered architecture with scripts/src separation. Each folder has a single responsibility.

Applies 5.2

CLAUDE.md with explicit security and privacy restrictions. Onboarding greeting.

Applies 5.3

Structured CHANGELOG since V1. Semver tags for each release. V2.3 in May/2026.

2 ⚙️ scripts/aggregate.ts — the heart of the system

The most important file in ClaudeOS isn't a React component — it's a TypeScript script that runs outside the browser. It reads heterogeneous sources and produces a single JSON file consumed by the dashboard.

scripts/aggregate.ts — simplified structure
// scripts/aggregate.ts
// Lê todas as fontes de dados e gera src/data/live-data.json
// NUNCA modifica as fontes — read-only

import { readdir, readFile, writeFile } from 'fs/promises'
import { join } from 'path'

async function aggregateClaudeHistory() {
  const historyDir = join(process.env.HOME!, '.claude', 'history')
  // Lê arquivos de sessão dos últimos 30 dias
  // Extrai: tokens usados, projetos, modelos
  return { sessions: [...], tokenTotal: 0 }
}

async function aggregateObsidian() {
  const vaultPath = process.env.OBSIDIAN_VAULT_PATH!
  // Percorre .md recursivamente, lê frontmatter
  return { notes: [...], recentlyModified: [...] }
}

async function main() {
  const [claude, obsidian, openrouter, pinecone] = await Promise.all([
    aggregateClaudeHistory(),
    aggregateObsidian(),
    fetchOpenRouterStats(),
    fetchPineconeStats(),
  ])

  const liveData = { claude, obsidian, openrouter, pinecone,
                      generatedAt: new Date().toISOString() }

  await writeFile('src/data/live-data.json',
                  JSON.stringify(liveData, null, 2))
  console.log('✅ live-data.json gerado')
}

main()

✓ Elegant pattern

  • • Script separate from src/ (single responsibility)
  • • Promise.all for parallel I/O
  • • Structured, versionable JSON output
  • • Generation timestamp included
  • • Never modifies the source files (read-only)

🔁 Reusable for

  • • Any metrics dashboard
  • • Automated reports
  • • Consolidating distributed logs
  • • Local data pipelines
  • • Static feed generation
💡

The “script → JSON → UI” pattern

Separating data collection from presentation is one of the most resilient architectures for personal projects. You can rebuild the dashboard from scratch without losing data. The pipeline can run on cron without the UI existing.

3 💤 The /dream skill — 24-hour audit

The /dream skill is an example of a skill with structured output. It doesn’t respond in prose—it writes a JSON file that the dashboard renders as action cards.

~/.claude/skills/dream/SKILL.md — structure
# Skill /dream

## Propósito
Auditar as últimas 24h do stack de IA em 8 buckets de sinal.
Gerar as 4 prescrições de maior impacto em JSON.

## Buckets de sinal
1. Tokens consumidos vs budget diário
2. Projetos mais ativos (por sessão)
3. Skills mais invocadas
4. Notas Obsidian criadas/modificadas
5. Queries Pinecone (tópicos consultados)
6. Modelos OpenRouter usados
7. Dívidas técnicas registradas hoje
8. Commits e PRs abertos

## Output obrigatório
Ao terminar análise, escrever em src/data/dream-output.json:
{
  "generatedAt": "ISO-8601",
  "buckets": [ { "id": 1, "signal": "...", "value": "..." } ],
  "prescriptions": [
    { "rank": 1, "impact": "high", "action": "...", "rationale": "..." }
  ]
}

## Regras
- NUNCA exibir dados privados em texto livre
- Máximo 4 prescrições, ordenadas por impacto
- Basear APENAS em dados do live-data.json

The 8 signal buckets

💰

1. Tokens

vs budget

📁

2. Projects

most active

🧰

3. Skills

most invoked

📓

4. Obsidian

created/mod

🌲

5. Pinecone

topics

🤖

6. Models

OpenRouter

💳

7. Debt

registered today

📝

8. Commits

and PRs

4 📜 ClaudeOS CLAUDE.md — real example

ClaudeOS's CLAUDE.md is an example of production-level instructions. Each rule has a clear reason for existing.

CLAUDE.md — ClaudeOS (Hermes)
# ClaudeOS (Hermes) — Instruções do agente

## Saudação de onboarding
Bem-vindo ao ClaudeOS! Você está trabalhando no dashboard
pessoal de IA. Antes de qualquer task, leia este arquivo.

## O que é este projeto
Dashboard read-only que consolida dados de Claude Code,
Obsidian, OpenRouter e Pinecone para visualização pessoal.
Stack: Bun + React 19 + TanStack Query + Vite + Tailwind 4
Deploy: Cloudflare Pages (wrangler)

## Regras OBRIGATÓRIAS

### Privacidade
- NUNCA ler ou escrever diretamente em ~/.claude/
  → Dados chegam via scripts/aggregate.ts e src/data/live-data.json
- NUNCA enviar dados do usuário para serviços externos
- Anonimização LIGADA — remove PII de outputs
- Sem telemetria — sem analytics, sem tracking

### Arquitetura
- Dashboard é READ-ONLY — NUNCA modificar fontes de dados
- Código novo vai em src/ — scripts de dados vão em scripts/
- Não criar arquivos na raiz do projeto

### Segurança
- API keys SEMPRE via variáveis de ambiente (.env)
- .env está no .gitignore — nunca commit

## Estrutura do projeto
src/
  components/   → UI React
  data/         → live-data.json (gerado, não editado)
scripts/
  aggregate.ts  → coleta dados das fontes
  setup.ts      → setup inicial (roda uma vez)

🔍 Why Each Rule Exists

Never read ~/.claude directly: prevents inadvertent access to private conversations
Read-only enforcement: prevents bugs that corrupt data sources
No telemetry: personal project — no data leaves the device

🧩 Reusable pattern

• Onboarding greeting = immediate context

• Rules by category (privacy, architecture, security)

• Inline justification for each critical constraint

• Folder map with an explicit purpose

5 📦 CHANGELOG V2.3 — history as a mirror

The ClaudeOS CHANGELOG tells the story of a project that evolved from a simple script into a complete dashboard. Each version is a milestone.

V2.3

Documents Gallery

May 31, 2026

Added: Obsidian docs viewer in the dashboard. Filter by vault. aggregate.ts 3x faster (parallel processing).

V2.2

Skill /personas

Apr 15, 2026

Added: local YAML persona pantheon. Persona panel in the dashboard. Changed: Vercel → Cloudflare Pages migration.

V2.1

Skill /dream

Mar 1, 2026

Added: /dream skill with 8 signal buckets. Prescriptions panel in the dashboard.

V1.0

MVP — Walking Skeleton

Jan 10, 2026

Basic aggregate.ts script + minimal React dashboard. Claude Code data only.

💡

What the CHANGELOG reveals

Reading the CHANGELOG, you can see that the project started small (V1.0 was Claude Code only), grew incrementally, moved platforms when it made sense, and each version added one thing at a time. That's healthy growth.

6 🔗 Dashboard Mockup and Lessons for Your Project

ClaudeOS — Dashboard (ILLUSTRATIVE MOCKUP — not a real screenshot)
V2.3
🖥️ Hermes ClaudeOS
v2.3.0

Tokens today

84.2k

Obsidian notes

1.847

Pinecone queries

23

Invoked skills

7

💤 /dream prescriptions

#1 High priority

Consolidate 3 inactive projects to reduce context overhead

#2 Medium priority

62% of the budget consumed — consider caching repeated prompts

Generated on 2026-06-01T08:00:00Z · READ-ONLY

⚠️ Illustrative HTML mockup — does not represent real data or a screenshot of the system

✓ Repeatable patterns

  • • Generator script + JSON artifact + UI
  • • CLAUDE.md with restrictions by category
  • • Skills with JSON output (not prose)
  • • CHANGELOG since V1
  • • Walking skeleton growing incrementally

🚀 Apply It to Your Project

  • • Identify what your "aggregate.ts" is
  • • Define constraints in CLAUDE.md before coding
  • • Start the CHANGELOG at V0.1
  • • Separate scripts from src/ from the start
  • • Read-only where possible — fewer bugs
🏗️

Download the project ClaudeOS (Hermes) V2.3 · ~88 MB

The complete source code for this case study: the scanner aggregate.ts, o setup.ts, the skills /dream e /personas, o CLAUDE.md e o CHANGELOG. A real, long-term project to study from start to finish.

⬇ Download ClaudeOS-Hermes-V2.3.zip

📋 Track 5 summary

You completed Track 5. Here's what you've mastered:

✅ Completed modules
  • 🏗️ 5.1 Project architecture
  • 🧠 5.2 CLAUDE.md and memory
  • 📦 5.3 Versioning and CHANGELOG
  • 🖥️ 5.4 ClaudeOS case study
🚀 Next Track

Track 6 covers Deploy — how to put your project into production with Cloudflare, GitHub Actions, custom domains, and monitoring.

🚀 Go to Track 6: Deploy →