Update PROJECT.md to reflect actual state, active session indicator
This commit is contained in:
+43
-173
@@ -1,199 +1,69 @@
|
|||||||
# PROJECT.md — Hermes OS
|
# PROJECT.md — Hermes OS
|
||||||
|
|
||||||
Mobile-first dashboard for Hermes Agent. Visibility into state, control over behavior, and a self-improvement loop — all from your phone.
|
Mobile-first dashboard for Hermes Agent. Visibility into state, control over behavior, and self-improvement — all from your phone.
|
||||||
|
|
||||||
## What This Is
|
|
||||||
|
|
||||||
Hermes is a single AI agent that lives across platforms (CLI, Telegram, Discord, WhatsApp). It has persistent memory, procedural skills, scheduled cron jobs, and searchable session history. Today, all of that is managed through the CLI or by talking to the agent itself.
|
|
||||||
|
|
||||||
Hermes OS gives you a visual interface to see what Hermes knows, what it's doing, and how it's performing — without opening a terminal.
|
|
||||||
|
|
||||||
## Design Principles
|
|
||||||
|
|
||||||
1. **Mobile-first.** Thumb-friendly. Works on a phone in portrait mode. No hover states, no tiny click targets, no horizontal scrolling. Desktop is a stretched mobile layout, not the other way around.
|
|
||||||
|
|
||||||
2. **Read-heavy, write-light.** You're mostly checking on things — glancing at memory, reviewing a cron output, scanning session history. Edits are occasional and should feel deliberate.
|
|
||||||
|
|
||||||
3. **Native Hermes data.** No separate database. Reads directly from `~/.hermes/` — state.db (SQLite), memory files, session JSONs, cron jobs, skills on disk. The existing webapi (FastAPI on the gateway) is the data layer.
|
|
||||||
|
|
||||||
4. **PWA.** Installable on phone home screen. Offline shell with online data. Push notifications for cron completions and platform messages.
|
|
||||||
|
|
||||||
5. **Single agent, not an org.** No roster, no org chart. The "team" is skills. The "backlog" is cron jobs and todos. The "standup" is session history.
|
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
┌─────────────────────────────────┐
|
Phone/Browser → Next.js (port 3100) → proxy routes → Hermes WebAPI (8643) + Gateway (8642)
|
||||||
│ Hermes OS (Next.js PWA) │
|
|
||||||
│ Mobile-first SPA │
|
|
||||||
│ Port 3100 │
|
|
||||||
└──────────┬──────────────────────┘
|
|
||||||
│ HTTP/SSE
|
|
||||||
┌──────────▼──────────────────────┐
|
|
||||||
│ Hermes WebAPI (FastAPI) │
|
|
||||||
│ Already exists in gateway │
|
|
||||||
│ /api/sessions, /api/memory, │
|
|
||||||
│ /api/skills, /api/config, │
|
|
||||||
│ /api/chat │
|
|
||||||
└──────────┬──────────────────────┘
|
|
||||||
│ SQLite + filesystem
|
|
||||||
┌──────────▼──────────────────────┐
|
|
||||||
│ ~/.hermes/ │
|
|
||||||
│ state.db, memories/, sessions/ │
|
|
||||||
│ skills/, cron/, config.yaml │
|
|
||||||
└─────────────────────────────────┘
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The frontend talks exclusively to the existing Hermes WebAPI. New endpoints are added to the WebAPI as needed — the frontend never reads the filesystem directly.
|
All API calls proxy through Next.js server-side route handlers. No CORS, no cross-origin issues. The frontend makes same-origin requests only.
|
||||||
|
|
||||||
## Modules
|
## Modules
|
||||||
|
|
||||||
Three modules, inspired by Satyr OS but rethought for a single-agent mobile experience.
|
### Pulse (/)
|
||||||
|
Home screen. Status card (model, online/offline), stats (sessions, tokens, platforms), memory usage bars, platform breakdown, quick links to Skills/Cron/Soul/Config, recent sessions list. Pull-to-refresh.
|
||||||
|
|
||||||
### 🟠 Pulse (Home)
|
### Memory (/memory)
|
||||||
|
Agent + User memory tabs. View entries, inline edit, delete with confirm, add new. Usage bar with char limit. All mutations go through WebAPI.
|
||||||
|
|
||||||
The landing screen. A single scrollable feed showing what matters right now.
|
### History (/history)
|
||||||
|
Session list with platform filter (All/CLI/Telegram/Discord/Web) and full-text search. New session creation (/history/new). Session replay with:
|
||||||
|
- Newest-first message order
|
||||||
|
- Verbosity toggle: Compact (text only) / Normal (+ tool calls) / Full (+ reasoning + expanded results)
|
||||||
|
- Message input to continue sessions
|
||||||
|
- Thinking indicator while agent runs
|
||||||
|
- Session delete with confirm
|
||||||
|
- Refresh button
|
||||||
|
|
||||||
- **Status card** — model, provider, platform connections (which platforms are active), uptime
|
### Skills (/skills)
|
||||||
- **Recent sessions** — last 5-10 sessions with title, platform badge (CLI/Telegram/Discord), message count, timestamp. Tap to open session replay.
|
Categorized skill browser with search/filter. Skill detail renders SKILL.md as proper markdown (headings, code blocks, tables, blockquotes). Shows linked files.
|
||||||
- **Active cron jobs** — next scheduled runs, last output preview. Tap to see full output.
|
|
||||||
- **Memory snapshot** — current char usage (memory + user), last modified. Tap to open memory editor.
|
|
||||||
- **Quick actions** — floating action button: new chat, trigger cron job, search sessions
|
|
||||||
|
|
||||||
### 🔵 Memory
|
### Cron (/cron)
|
||||||
|
Job list grouped by status (active/paused/other). Manual trigger button. Detail page (/cron/[id]) with job metadata, prompt, and output history read from filesystem.
|
||||||
|
|
||||||
Full visibility and control over what Hermes remembers.
|
### Soul (/soul)
|
||||||
|
SOUL.md editor. Direct filesystem read/write. Save/revert with dirty detection.
|
||||||
|
|
||||||
- **Memory tab** — agent memory entries, each as a card. Tap to edit inline. Swipe to delete. Add new entry button.
|
### Config (/config)
|
||||||
- **User tab** — user profile entries, same interaction pattern.
|
Read-only config viewer. Model, terminal, memory, display sections.
|
||||||
- **Usage bars** — visual char limit indicators (e.g., "847/1,375 chars" for user profile).
|
|
||||||
- **Skills browser** — categorized skill list. Tap to view SKILL.md rendered as markdown. Shows linked files (references, templates, scripts). Search/filter by category.
|
|
||||||
- **SOUL.md** — view and edit the persona file.
|
|
||||||
|
|
||||||
### 🟢 History
|
## Stack
|
||||||
|
|
||||||
Session search and replay.
|
- Next.js 15, TypeScript, Tailwind CSS v4
|
||||||
|
- TanStack Query for server state
|
||||||
|
- Lucide icons, react-markdown + remark-gfm
|
||||||
|
- PWA manifest + service worker
|
||||||
|
- systemd user services for persistence
|
||||||
|
|
||||||
- **Session list** — reverse chronological, filterable by platform (CLI, Telegram, Discord, etc.). Shows title, message count, token usage, cost estimate, timestamp.
|
## Services
|
||||||
- **Session detail** — full message replay. User messages, assistant responses, tool calls (collapsible), tool results. Rendered markdown. Scroll through the conversation like a chat transcript.
|
|
||||||
- **Search** — full-text search across all sessions (uses FTS5 in state.db). Results show matching snippets with session context.
|
|
||||||
- **Cron output** — dedicated view for cron job history. Each job shows schedule, last N outputs, delivery target.
|
|
||||||
|
|
||||||
## Navigation
|
```bash
|
||||||
|
# Deploy (build + install services + restart)
|
||||||
|
bash deploy/deploy.sh 3100
|
||||||
|
|
||||||
Bottom tab bar with 3 tabs: Pulse, Memory, History. Active tab has a colored indicator. The tab bar is fixed at the bottom with safe-area padding for notched phones.
|
# Manual control
|
||||||
|
systemctl --user status hermes-os
|
||||||
No hamburger menus. No nested navigation deeper than 2 levels (list → detail). Back button or swipe-back to return.
|
systemctl --user status hermes-webapi
|
||||||
|
systemctl --user restart hermes-os
|
||||||
## Phase 2: Self-Improvement (Lab)
|
|
||||||
|
|
||||||
After the core three modules are solid, add a Lab module:
|
|
||||||
|
|
||||||
- **Session analytics** — tokens per session over time, tool call frequency, most-used tools, cost tracking (state.db already has billing columns)
|
|
||||||
- **Memory timeline** — when entries were added/modified (requires adding timestamps to memory, currently not tracked)
|
|
||||||
- **Skill usage tracking** — which skills get loaded, how often, success rate
|
|
||||||
- **Cron health** — success/failure rates, output quality scoring
|
|
||||||
- **Prompt experiments** — A/B test different SOUL.md personas, compare session quality
|
|
||||||
|
|
||||||
## Tech Stack
|
|
||||||
|
|
||||||
- **Frontend:** Next.js 15 (App Router), TypeScript, Tailwind CSS v4, Lucide icons
|
|
||||||
- **UI:** Mobile-first responsive. Dark theme (matches terminal aesthetic). Glass morphism cards like Satyr OS but optimized for touch.
|
|
||||||
- **State:** React Query (TanStack Query) for server state. No client-side database.
|
|
||||||
- **PWA:** next-pwa or manual service worker. Web app manifest for home screen install.
|
|
||||||
- **Backend:** Hermes WebAPI (FastAPI) — extend existing routes as needed. No separate backend.
|
|
||||||
- **Data:** SQLite state.db (sessions, messages, FTS5 search), filesystem (memories, skills, cron, config)
|
|
||||||
|
|
||||||
## WebAPI Extensions Needed
|
|
||||||
|
|
||||||
The existing webapi covers sessions, chat, memory, skills, and config. Additional endpoints needed:
|
|
||||||
|
|
||||||
```
|
|
||||||
GET /api/status — gateway state, platform connections, model info
|
|
||||||
GET /api/cron — list cron jobs with schedule, status, last run
|
|
||||||
GET /api/cron/{id} — job detail with recent outputs
|
|
||||||
POST /api/cron/{id}/run — trigger a job manually
|
|
||||||
GET /api/cron/{id}/output — paginated output history
|
|
||||||
GET /api/stats — aggregate session stats (tokens, costs, tool usage)
|
|
||||||
GET /api/soul — read SOUL.md
|
|
||||||
PUT /api/soul — update SOUL.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## File Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
hermes-os/
|
|
||||||
├── src/
|
|
||||||
│ ├── app/
|
|
||||||
│ │ ├── layout.tsx
|
|
||||||
│ │ ├── page.tsx # Pulse (home)
|
|
||||||
│ │ ├── memory/
|
|
||||||
│ │ │ └── page.tsx
|
|
||||||
│ │ ├── history/
|
|
||||||
│ │ │ ├── page.tsx # Session list
|
|
||||||
│ │ │ └── [id]/
|
|
||||||
│ │ │ └── page.tsx # Session replay
|
|
||||||
│ │ ├── skills/
|
|
||||||
│ │ │ ├── page.tsx
|
|
||||||
│ │ │ └── [name]/
|
|
||||||
│ │ │ └── page.tsx
|
|
||||||
│ │ └── cron/
|
|
||||||
│ │ ├── page.tsx
|
|
||||||
│ │ └── [id]/
|
|
||||||
│ │ └── page.tsx
|
|
||||||
│ ├── components/
|
|
||||||
│ │ ├── BottomNav.tsx
|
|
||||||
│ │ ├── StatusCard.tsx
|
|
||||||
│ │ ├── SessionCard.tsx
|
|
||||||
│ │ ├── MemoryEditor.tsx
|
|
||||||
│ │ ├── SkillCard.tsx
|
|
||||||
│ │ ├── CronCard.tsx
|
|
||||||
│ │ ├── MessageBubble.tsx
|
|
||||||
│ │ ├── ToolCallBlock.tsx
|
|
||||||
│ │ └── SearchBar.tsx
|
|
||||||
│ └── lib/
|
|
||||||
│ ├── api.ts # Typed fetch wrappers for WebAPI
|
|
||||||
│ ├── types.ts
|
|
||||||
│ └── hooks.ts # TanStack Query hooks
|
|
||||||
├── public/
|
|
||||||
│ ├── manifest.json
|
|
||||||
│ ├── sw.js
|
|
||||||
│ └── icon-*.png
|
|
||||||
├── .env.example
|
|
||||||
├── PROJECT.md
|
|
||||||
├── package.json
|
|
||||||
├── tailwind.config.ts
|
|
||||||
├── tsconfig.json
|
|
||||||
└── next.config.mjs
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Environment
|
## Environment
|
||||||
|
|
||||||
```
|
| Variable | Default | Description |
|
||||||
HERMES_API_URL=http://localhost:8787 # Hermes WebAPI base URL
|
|---|---|---|
|
||||||
```
|
| `HERMES_BACKEND_URL` | `http://127.0.0.1:8643` | WebAPI (FastAPI) |
|
||||||
|
| `HERMES_GATEWAY_URL` | `http://127.0.0.1:8642` | Gateway (aiohttp, cron jobs) |
|
||||||
The WebAPI port is whatever the gateway exposes. The frontend is a separate Next.js process.
|
| `HERMES_SOUL_PATH` | `~/.hermes/SOUL.md` | Persona file |
|
||||||
|
| `HERMES_CRON_OUTPUT` | `~/.hermes/cron/output` | Cron output directory |
|
||||||
## MVP Scope
|
|
||||||
|
|
||||||
Phase 1 — ship these first:
|
|
||||||
|
|
||||||
1. **Pulse** — status card + recent sessions + cron summary
|
|
||||||
2. **Memory** — view/edit memory and user entries
|
|
||||||
3. **History** — session list with search, session replay
|
|
||||||
4. **PWA** — installable, works on phone
|
|
||||||
|
|
||||||
Phase 2 — after MVP is stable:
|
|
||||||
|
|
||||||
5. **Skills browser** — view skills and their files
|
|
||||||
6. **Cron management** — full cron UI with output history
|
|
||||||
7. **Lab** — analytics and self-improvement features
|
|
||||||
8. **Push notifications** — cron completions, platform activity
|
|
||||||
|
|
||||||
## What This Is NOT
|
|
||||||
|
|
||||||
- Not a chat interface. Hermes already has CLI, Telegram, Discord for that. (Though a minimal "quick message" input on Pulse could be useful later.)
|
|
||||||
- Not a replacement for the CLI. Power users will always prefer the terminal for complex work.
|
|
||||||
- Not multi-agent. One Hermes instance, one dashboard.
|
|
||||||
- Not a config editor for everything. Config changes that could break the agent (toolsets, providers, terminal backend) stay in config.yaml via CLI.
|
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useHealth, useConfig } from "@/lib/hooks";
|
import { useHealth, useConfig, useSessions } from "@/lib/hooks";
|
||||||
|
|
||||||
export function StatusCard() {
|
export function StatusCard() {
|
||||||
const { data: health } = useHealth();
|
const { data: health } = useHealth();
|
||||||
const { data: config } = useConfig();
|
const { data: config } = useConfig();
|
||||||
|
const { data: sessions } = useSessions(10);
|
||||||
|
|
||||||
const online = health?.status === "ok";
|
const online = health?.status === "ok";
|
||||||
const model = config?.model || "—";
|
const model = config?.model || "—";
|
||||||
|
const activeSessions = sessions?.items?.filter((s) => !s.ended_at).length || 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card p-4 flex items-center justify-between">
|
<div className="card p-4 flex items-center justify-between">
|
||||||
@@ -15,6 +17,11 @@ export function StatusCard() {
|
|||||||
<div className="text-[13px] font-mono" style={{ color: "var(--text-2)" }}>
|
<div className="text-[13px] font-mono" style={{ color: "var(--text-2)" }}>
|
||||||
{model}
|
{model}
|
||||||
</div>
|
</div>
|
||||||
|
{activeSessions > 0 && (
|
||||||
|
<div className="text-[11px] mt-0.5" style={{ color: "var(--accent)" }}>
|
||||||
|
{activeSessions} active session{activeSessions !== 1 ? "s" : ""}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div
|
<div
|
||||||
|
|||||||
Reference in New Issue
Block a user