# Send Mission Control Builder to your agent
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
## Fast path
- Download the package from Yavira.
- Extract it into a folder your agent can access.
- Paste one of the prompts below and point your agent at the extracted folder.
## Suggested prompts
### New install

```text
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
```
### Upgrade existing

```text
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
```
## Machine-readable fields
```json
{
  "schemaVersion": "1.0",
  "item": {
    "slug": "mission-control-builder",
    "name": "Mission Control Builder",
    "source": "tencent",
    "type": "skill",
    "category": "效率提升",
    "sourceUrl": "https://clawhub.ai/Shukiclaw/mission-control-builder",
    "canonicalUrl": "https://clawhub.ai/Shukiclaw/mission-control-builder",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadUrl": "/downloads/mission-control-builder",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=mission-control-builder",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "packageFormat": "ZIP package",
    "primaryDoc": "SKILL.md",
    "includedAssets": [
      "SKILL.md"
    ],
    "downloadMode": "redirect",
    "sourceHealth": {
      "source": "tencent",
      "slug": "mission-control-builder",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T09:30:57.347Z",
      "expiresAt": "2026-05-07T09:30:57.347Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=mission-control-builder",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=mission-control-builder",
        "contentDisposition": "attachment; filename=\"mission-control-builder-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "mission-control-builder"
      },
      "scope": "item",
      "summary": "Item download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this item.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/mission-control-builder"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    }
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/mission-control-builder",
    "downloadUrl": "https://openagent3.xyz/downloads/mission-control-builder",
    "agentUrl": "https://openagent3.xyz/skills/mission-control-builder/agent",
    "manifestUrl": "https://openagent3.xyz/skills/mission-control-builder/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/mission-control-builder/agent.md"
  }
}
```
## Documentation

### Mission Control Skill

Build your own personal dashboard for OpenClaw - a central command center for tasks, memories, calendar, and team management.

### What You'll Build

A Next.js web dashboard that connects to your OpenClaw instance and provides:

Task Board - Kanban-style task management
Memory Browser - Search and view your OpenClaw memories
Calendar View - See scheduled events and cron jobs
Team Status - Track who's working on what
GitHub Trends - Discover trending repositories

### Architecture Overview

┌─────────────────────────────────────┐
│         Next.js Frontend            │
│  ┌─────────┐ ┌─────────┐ ┌────────┐ │
│  │  Task   │ │ Memory  │ │Calendar│ │
│  │  Board  │ │  List   │ │  View  │ │
│  └────┬────┘ └────┬────┘ └───┬────┘ │
│       └───────────┴──────────┘       │
│              │                       │
│       ┌──────┴──────┐                │
│       │   API Routes │               │
│       └──────┬──────┘                │
└──────────────┼───────────────────────┘
               │
       ┌───────┴───────┐
       │               │
┌──────┴──────┐ ┌──────┴──────┐
│ Local JSON  │ │  OpenClaw   │
│   Files     │ │   Memory    │
└─────────────┘ └─────────────┘

### Prerequisites

Node.js 18+
OpenClaw installed and running
Basic knowledge of React/Next.js

### Step 1: Initialize Project

npx create-next-app@latest mission-control --typescript --tailwind

### Step 2: Install Dependencies

cd mission-control
npm install lucide-react

### Step 3: Create Data Layer

Create src/lib/data.ts for file-based storage:

import fs from "fs/promises";
import path from "path";

const DATA_DIR = path.join(process.cwd(), "src", "data");

// Types
export interface Task {
  id: string;
  title: string;
  description: string;
  status: "todo" | "in-progress" | "done";
  assignee: string;
  createdAt: string;
  updatedAt: string;
}

// Initialize data files
async function initDataFile(filename: string, defaultData: unknown) {
  const filepath = path.join(DATA_DIR, filename);
  try {
    await fs.access(filepath);
  } catch {
    await fs.mkdir(DATA_DIR, { recursive: true });
    await fs.writeFile(filepath, JSON.stringify(defaultData, null, 2));
  }
  return filepath;
}

// Tasks
export async function getTasks(): Promise<Task[]> {
  const filepath = await initDataFile("tasks.json", []);
  const data = await fs.readFile(filepath, "utf-8");
  return JSON.parse(data);
}

export async function addTask(task: Omit<Task, "id" | "createdAt" | "updatedAt">): Promise<Task> {
  const tasks = await getTasks();
  const newTask: Task = {
    ...task,
    id: Date.now().toString(),
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
  };
  tasks.push(newTask);
  await fs.writeFile(
    path.join(DATA_DIR, "tasks.json"),
    JSON.stringify(tasks, null, 2)
  );
  return newTask;
}

export async function updateTask(id: string, updates: Partial<Task>): Promise<Task | null> {
  const tasks = await getTasks();
  const index = tasks.findIndex((t) => t.id === id);
  if (index === -1) return null;
  
  tasks[index] = { 
    ...tasks[index], 
    ...updates, 
    updatedAt: new Date().toISOString() 
  };
  await fs.writeFile(
    path.join(DATA_DIR, "tasks.json"),
    JSON.stringify(tasks, null, 2)
  );
  return tasks[index];
}

### Step 4: Create API Routes

Create src/app/api/tasks/route.ts:

import { NextRequest, NextResponse } from "next/server";
import { getTasks, addTask, updateTask } from "@/lib/data";

export async function GET() {
  const tasks = await getTasks();
  return NextResponse.json(tasks);
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const task = await addTask(body);
    return NextResponse.json(task, { status: 201 });
  } catch (error) {
    return NextResponse.json(
      { error: "Failed to create task" },
      { status: 500 }
    );
  }
}

export async function PUT(request: NextRequest) {
  try {
    const { id, ...updates } = await request.json();
    const task = await updateTask(id, updates);
    if (!task) {
      return NextResponse.json({ error: "Task not found" }, { status: 404 });
    }
    return NextResponse.json(task);
  } catch (error) {
    return NextResponse.json(
      { error: "Failed to update task" },
      { status: 500 }
    );
  }
}

### Step 5: Create Components

Navigation Component (src/components/Navigation.tsx):

"use client";

import Link from "next/link";
import { usePathname } from "next/navigation";
import { useState } from "react";
import { LayoutDashboard, ClipboardList, Menu, X } from "lucide-react";

const navItems = [
  { href: "/", label: "Dashboard", icon: LayoutDashboard },
  { href: "/tasks", label: "Tasks", icon: ClipboardList },
];

export function Navigation() {
  const pathname = usePathname();
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);

  return (
    <>
      {/* Desktop Sidebar */}
      <aside className="hidden lg:flex w-64 bg-gray-800 border-r border-gray-700 flex-col h-screen">
        <div className="p-6 border-b border-gray-700">
          <h1 className="text-xl font-bold text-blue-400">Mission Control</h1>
        </div>
        <nav className="flex-1 p-4">
          <ul className="space-y-2">
            {navItems.map((item) => {
              const Icon = item.icon;
              const isActive = pathname === item.href;
              return (
                <li key={item.href}>
                  <Link
                    href={item.href}
                    className={\`flex items-center gap-3 px-4 py-3 rounded-lg transition-colors ${
                      isActive
                        ? "bg-blue-600 text-white"
                        : "text-gray-300 hover:bg-gray-700"
                    }\`}
                  >
                    <Icon size={20} />
                    <span>{item.label}</span>
                  </Link>
                </li>
              );
            })}
          </ul>
        </nav>
      </aside>

      {/* Mobile Header */}
      <div className="lg:hidden fixed top-0 left-0 right-0 z-40 bg-gray-800 border-b border-gray-700">
        <div className="flex items-center justify-between px-4 py-3">
          <h1 className="text-lg font-bold text-blue-400">Mission Control</h1>
          <button
            onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
            className="p-2 rounded-lg bg-gray-700"
          >
            {mobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
          </button>
        </div>
      </div>

      {/* Mobile Drawer */}
      {mobileMenuOpen && (
        <aside className="lg:hidden fixed top-[60px] left-0 bottom-0 w-64 bg-gray-800 z-40">
          {/* Same nav as desktop */}
        </aside>
      )}
    </>
  );
}

### Step 6: Create Task Board

"use client";

import { useState, useEffect } from "react";

interface Task {
  id: string;
  title: string;
  description: string;
  status: "todo" | "in-progress" | "done";
  assignee: string;
}

export function TaskBoard() {
  const [tasks, setTasks] = useState<Task[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchTasks();
  }, []);

  const fetchTasks = async () => {
    try {
      const response = await fetch("/api/tasks");
      const data = await response.json();
      setTasks(data);
    } finally {
      setLoading(false);
    }
  };

  const handleUpdateStatus = async (taskId: string, newStatus: Task["status"]) => {
    await fetch("/api/tasks", {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ id: taskId, status: newStatus }),
    });
    fetchTasks();
  };

  const tasksByStatus = {
    todo: tasks.filter((t) => t.status === "todo"),
    "in-progress": tasks.filter((t) => t.status === "in-progress"),
    done: tasks.filter((t) => t.status === "done"),
  };

  if (loading) return <div>Loading...</div>;

  return (
    <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
      {Object.entries(tasksByStatus).map(([status, statusTasks]) => (
        <div key={status} className="bg-gray-800/50 rounded-xl p-4">
          <h3 className="font-semibold text-gray-300 mb-4 capitalize">{status}</h3>
          <div className="space-y-3">
            {statusTasks.map((task) => (
              <div key={task.id} className="bg-gray-800 p-4 rounded-lg">
                <h4 className="font-medium">{task.title}</h4>
                <select
                  value={task.status}
                  onChange={(e) => handleUpdateStatus(task.id, e.target.value as Task["status"])}
                  className="mt-2 text-sm bg-gray-700 border border-gray-600 rounded px-2 py-1"
                >
                  <option value="todo">To Do</option>
                  <option value="in-progress">In Progress</option>
                  <option value="done">Done</option>
                </select>
              </div>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

### Step 7: OpenClaw Memory Sync

Create src/app/api/sync/route.ts:

import { NextResponse } from "next/server";
import fs from "fs/promises";
import path from "path";

export async function GET() {
  try {
    // Read OpenClaw memory files
    const memoryDir = path.join(process.env.HOME || "", "clawd", "memory");
    const files = await fs.readdir(memoryDir);
    
    const memories = [];
    for (const file of files.filter(f => f.endsWith('.md'))) {
      const content = await fs.readFile(path.join(memoryDir, file), 'utf-8');
      memories.push({
        id: file,
        title: file.replace('.md', ''),
        content: content.slice(0, 500) + '...',
        createdAt: new Date().toISOString(),
      });
    }
    
    return NextResponse.json(memories);
  } catch (error) {
    return NextResponse.json([]);
  }
}

### Step 8: Create Layout

import type { Metadata } from "next";
import "./globals.css";
import { Navigation } from "@/components/Navigation";

export const metadata: Metadata = {
  title: "Mission Control",
  description: "Personal dashboard for OpenClaw",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className="bg-gray-900 text-white">
        <div className="flex flex-col lg:flex-row min-h-screen">
          <Navigation />
          <main className="flex-1 overflow-auto pt-[60px] lg:pt-0 p-6">
            {children}
          </main>
        </div>
      </body>
    </html>
  );
}

### Step 9: Start Script

Create start.sh:

#!/bin/bash
cd "$(dirname "$0")"
npm run dev

Make it executable:

chmod +x start.sh

### Step 10: Run

./start.sh

Open http://localhost:3000

### Add GitHub Trends

// src/app/api/github-trends/route.ts
export async function GET() {
  const response = await fetch(
    "https://api.github.com/search/repositories?q=stars:>1000&sort=stars&per_page=10"
  );
  const data = await response.json();
  return NextResponse.json(data.items);
}

### Add Calendar Events

Store events in src/data/calendar.json and create similar API routes.

### Add Team Members

Create src/data/team.json with member info and current tasks.

### Mobile Responsiveness Tips

Use Tailwind breakpoints: lg: for desktop, default for mobile
Touch targets: Minimum 40px for buttons
Horizontal scroll: For Kanban board on mobile
Drawer navigation: Slide-in menu for mobile

### Security Considerations

Store personal data in src/data/ (gitignored)
Keep template data in the skill
No authentication included - add your own if needed
Run locally or behind a VPN

### Troubleshooting

Port already in use?

PORT=3001 ./start.sh

Data not saving?
Ensure src/data/ directory exists and is writable.

OpenClaw sync not working?
Check that OpenClaw memory path is correct in your environment.

### Resources

Next.js docs: https://nextjs.org/docs
Tailwind CSS: https://tailwindcss.com
Lucide icons: https://lucide.dev

### License

MIT - Built for the OpenClaw community 🦞
## Trust
- Source: tencent
- Verification: Indexed source record
- Publisher: Shukiclaw
- Version: 1.0.0
## Source health
- Status: healthy
- Item download looks usable.
- Yavira can redirect you to the upstream package for this item.
- Health scope: item
- Reason: direct_download_ok
- Checked at: 2026-04-30T09:30:57.347Z
- Expires at: 2026-05-07T09:30:57.347Z
- Recommended action: Download for OpenClaw
## Links
- [Detail page](https://openagent3.xyz/skills/mission-control-builder)
- [Send to Agent page](https://openagent3.xyz/skills/mission-control-builder/agent)
- [JSON manifest](https://openagent3.xyz/skills/mission-control-builder/agent.json)
- [Markdown brief](https://openagent3.xyz/skills/mission-control-builder/agent.md)
- [Download page](https://openagent3.xyz/downloads/mission-control-builder)