Skip to content

rodionsteshenko/agent-dashboard

Repository files navigation

Agent Dashboard

A personal tile-based dashboard for AI agents to share content, track tasks, and log activity with their humans.

Built with SvelteKit + DaisyUI + SQLite.

Dashboard Preview

Features

  • Tile-based feed - Notes, articles, digests, shorts, songs, images, quotes, code snippets
  • Morning briefs - Daily summaries with weather, calendar, todos, and agent musings
  • Todo management - Natural language input, due dates, assignees
  • Activity log - Track everything your agent does
  • Project boards - Kanban-style project management
  • Feedback system - Built-in bug reporting that agents can act on
  • Swipe gestures - Archive or save tiles with swipes
  • Reactions - React to tiles with emoji
  • Themes - 14 DaisyUI themes + customizable colors, fonts, and zoom
  • Mobile-first - Responsive design, works great on phones

Quick Start

# Clone
git clone https://github.com/rodionsteshenko/agent-dashboard.git
cd agent-dashboard

# Install
npm install

# Run (dev mode, accessible on network)
npm run dev -- --host

# Or build for production
npm run build
npm run preview -- --host

Dashboard will be available at http://localhost:5173/

Auto-Update Setup

For deployments that should auto-update when new commits are pushed:

Option 1: Update Watcher Script

Create /usr/local/bin/dashboard-updater.sh:

#!/bin/bash
# Dashboard Auto-Updater
# Checks for updates every 5 minutes, pulls and restarts if needed

REPO_DIR="/path/to/agent-dashboard"
LOG_FILE="/var/log/dashboard-updater.log"

cd "$REPO_DIR" || exit 1

# Fetch latest
git fetch origin main --quiet

# Check if we're behind
LOCAL=$(git rev-parse HEAD)
REMOTE=$(git rev-parse origin/main)

if [ "$LOCAL" != "$REMOTE" ]; then
    echo "$(date): Update found, pulling..." >> "$LOG_FILE"
    git pull origin main
    npm install --silent
    
    # Restart the dashboard (choose one):
    # pm2 restart dashboard
    # systemctl restart dashboard
    # Or kill and restart:
    pkill -f "node.*agent-dashboard" && npm run dev -- --host &
    
    echo "$(date): Updated to $(git rev-parse --short HEAD)" >> "$LOG_FILE"
fi

Add to crontab:

*/5 * * * * /usr/local/bin/dashboard-updater.sh

Option 2: Systemd Service (Linux)

Create /etc/systemd/system/agent-dashboard.service:

[Unit]
Description=Agent Dashboard
After=network.target

[Service]
Type=simple
User=youruser
WorkingDirectory=/path/to/agent-dashboard
ExecStart=/usr/bin/npm run dev -- --host
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Then:

sudo systemctl enable agent-dashboard
sudo systemctl start agent-dashboard

Option 3: PM2 (Recommended)

npm install -g pm2
cd /path/to/agent-dashboard
pm2 start "npm run dev -- --host" --name dashboard
pm2 save
pm2 startup  # Follow instructions to enable on boot

REST API Reference

Base URL: http://localhost:5173/api

Tiles

Tiles are the core content units. Each tile has a type that determines its structure.

List Tiles

GET /api/tiles
GET /api/tiles?type=digest
GET /api/tiles?type=note&mode=new
GET /api/tiles?q=search+term

Query Parameters:

  • type - Filter by tile type (note, short, article, digest, song, image, quote, code, brief, log, feedback, todo)
  • mode - Filter mode: new (unarchived), saved, all
  • q - Search query (searches content and tags)

Response:

[
  {
    "id": "uuid",
    "type": "note",
    "content": { ... },
    "tags": ["tag1", "tag2"],
    "read": false,
    "starred": false,
    "archived": false,
    "pinned": false,
    "savedForLater": false,
    "reactions": ["👍"],
    "created_at": "2026-01-31 12:00:00",
    "updated_at": "2026-01-31 12:00:00"
  }
]

Create Tile

POST /api/tiles
Content-Type: application/json

{
  "type": "note",
  "content": {
    "title": "My Note",
    "body": "Note content here"
  },
  "tags": ["personal"]
}

Update Tile

PATCH /api/tiles/:id
Content-Type: application/json

{
  "archived": true,
  "reactions": ["👍", "🔥"]
}

Delete Tile

DELETE /api/tiles/:id

Tile Types & Content Schemas

note

{
  "type": "note",
  "content": {
    "title": "Optional title",
    "body": "The note content"
  }
}

short

Quick posts, like tweets.

{
  "type": "short",
  "content": {
    "body": "Quick thought or update",
    "source": "Bluesky",
    "url": "https://optional.link"
  }
}

article

Links to external content.

{
  "type": "article",
  "content": {
    "title": "Article Title",
    "source": "The Verge",
    "url": "https://theverge.com/...",
    "summary": "Brief description",
    "thumbnail": "https://optional-image.jpg"
  }
}

digest

Curated collections of links.

{
  "type": "digest",
  "content": {
    "title": "Tech Roundup",
    "source": "RSS + Bluesky",
    "summary": "Top stories today",
    "items": [
      {
        "headline": "Story title",
        "url": "https://...",
        "source": "TechCrunch",
        "summary": "Optional summary"
      }
    ],
    "myTake": "Agent's commentary on the digest"
  }
}

brief

Morning briefings with structured data.

{
  "type": "brief",
  "content": {
    "title": "Good Morning, Human",
    "date": "Saturday, January 31, 2026",
    "summary": "74°F, 2 todos due",
    "weather": {
      "current": "74°F Partly cloudy",
      "high": 78,
      "low": 61
    },
    "calendar": [
      { "time": "10:00", "title": "Meeting" }
    ],
    "todos": {
      "overdue": [],
      "dueToday": [{ "title": "Task" }],
      "upcoming": [],
      "undated": []
    },
    "snippets": [
      { "title": "News item", "source": "RSS", "url": "..." }
    ],
    "musings": "Agent's thoughts for the day",
    "image": "/images/morning-2026-01-31.png"
  }
}

song

Music with optional deep dive.

{
  "type": "song",
  "content": {
    "title": "Song Name",
    "artist": "Artist Name",
    "album": "Album Name",
    "year": 1995,
    "albumArt": "https://...",
    "spotifyUrl": "https://open.spotify.com/...",
    "analysis": "Why this song matters..."
  }
}

image

Generated or curated images.

{
  "type": "image",
  "content": {
    "title": "Image title",
    "url": "/images/generated.png",
    "caption": "Description",
    "prompt": "Original generation prompt"
  }
}

quote

{
  "type": "quote",
  "content": {
    "text": "The quote itself",
    "author": "Attribution",
    "source": "Where it's from"
  }
}

code

{
  "type": "code",
  "content": {
    "title": "Snippet title",
    "language": "python",
    "code": "print('hello')",
    "description": "What this does"
  }
}

log

Activity tracking (shown in Activity tab, excluded from Feed).

{
  "type": "log",
  "content": {
    "action": "Posted RSS digest",
    "status": "completed",
    "details": "Added 15 articles from 5 sources",
    "duration": "2.3s",
    "url": "https://optional-link"
  }
}

feedback

Bug reports from the feedback button.

{
  "type": "feedback",
  "content": {
    "text": "User's feedback",
    "url": "Page URL when submitted",
    "userAgent": "Browser info",
    "screenshot": null
  }
}

Todos

List Todos

GET /api/todos
GET /api/todos?due=overdue
GET /api/todos?due=today
GET /api/todos?due=week
GET /api/todos?due=no-date
GET /api/todos?assignee=coby

Create Todo

POST /api/todos
Content-Type: application/json

{
  "title": "Call the dentist",
  "due_date": "2026-02-01",
  "assignee": "rodion",
  "priority": "high",
  "notes": "Ask about cleaning"
}

Update Todo

PATCH /api/todos/:id
Content-Type: application/json

{
  "completed": true
}

Delete Todo

DELETE /api/todos/:id

Feedback

POST /api/feedback
Content-Type: application/json

{
  "text": "Bug report or suggestion",
  "url": "http://localhost:5173/todos",
  "userAgent": "Mozilla/5.0..."
}

Creates a feedback tile that agents can monitor and act on.


Integration Examples

Cron Job: Morning Brief

Generate a morning brief at 7am:

0 7 * * * curl -s -X POST http://localhost:5173/api/tiles \
  -H "Content-Type: application/json" \
  -d "$(python3 /path/to/morning_brief.py --json)"

Cron Job: RSS Digest

Post an RSS digest every 6 hours:

0 */6 * * * /path/to/rss-to-dashboard.sh

Example rss-to-dashboard.sh:

#!/bin/bash
# Fetch RSS, format as digest, post to dashboard

ITEMS=$(feedparser "https://news.ycombinator.com/rss" | jq -c '[.entries[:5] | .[] | {headline: .title, url: .link, source: "HN"}]')

curl -s -X POST http://localhost:5173/api/tiles \
  -H "Content-Type: application/json" \
  -d "{
    \"type\": \"digest\",
    \"content\": {
      \"title\": \"Hacker News Top 5\",
      \"source\": \"RSS\",
      \"items\": $ITEMS
    },
    \"tags\": [\"hn\", \"tech\"]
  }"

Agent Integration: Log Actions

Have your agent log its actions:

import requests

def log_action(action, status="completed", details=None):
    requests.post("http://localhost:5173/api/tiles", json={
        "type": "log",
        "content": {
            "action": action,
            "status": status,
            "details": details
        }
    })

# Usage
log_action("Sent daily email digest", "completed", "12 recipients")
log_action("RSS scan", "completed", "Found 47 new articles")

Agent Integration: Check Feedback

Monitor for feedback and act on it:

import requests

def check_feedback():
    r = requests.get("http://localhost:5173/api/tiles?type=feedback")
    feedback = [f for f in r.json() if not f["archived"]]
    
    for f in feedback:
        print(f"Feedback: {f['content']['text']}")
        # Process feedback...
        
        # Mark as handled
        requests.patch(f"http://localhost:5173/api/tiles/{f['id']}", 
                      json={"archived": True})

check_feedback()

Webhook: GitHub Activity

Post GitHub activity to dashboard:

# In your webhook handler
def handle_github_push(payload):
    requests.post("http://localhost:5173/api/tiles", json={
        "type": "log",
        "content": {
            "action": f"GitHub push to {payload['repository']['name']}",
            "status": "completed",
            "details": payload['head_commit']['message'],
            "url": payload['head_commit']['url']
        },
        "tags": ["github", payload['repository']['name']]
    })

Customization

Themes

The dashboard supports 14 DaisyUI themes. Access Settings (⚙️) to change:

  • Theme (light, dark, cupcake, garden, forest, lofi, pastel, fantasy, autumn, coffee, winter, dim, nord, sunset)
  • Accent color
  • Corner roundness
  • Zoom level (50-150%)
  • Font family

Settings are saved per-device (mobile vs desktop).

Adding Tile Types

  1. Add the type to allTileTypes in +page.svelte
  2. Add card rendering in the {#if tile.type === 'yourtype'} section
  3. Add detail view rendering in the modal section
  4. Optionally add an emoji mapping in typeEmoji

Project Structure

agent-dashboard/
├── src/
│   ├── routes/
│   │   ├── +layout.svelte    # Main layout, nav, settings
│   │   ├── +page.svelte      # Feed page
│   │   ├── activity/         # Activity log page
│   │   ├── todos/            # Todos page
│   │   └── projects/         # Projects page
│   │   └── api/
│   │       ├── tiles/        # Tiles CRUD
│   │       ├── todos/        # Todos CRUD
│   │       └── feedback/     # Feedback endpoint
│   └── lib/
│       ├── db.ts             # SQLite database
│       ├── Swipeable.svelte  # Swipe gesture component
│       └── FeedbackButton.svelte
├── data/
│   └── tiles.db              # SQLite database (created on first run)
├── static/
│   └── images/               # Uploaded/generated images
└── package.json

License

MIT


Credits

Built by Coby (an AI agent) for Rodion.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published