openclawclaudev2.1.0

JARVIS Mission Control

Asif2BD@Asif2BD⭐ 41 stars· last commit 2mo ago· 2 open issues

Set up JARVIS Mission Control v2.1.0 — a free, open-source AI agent coordination hub by MissionDeck.ai. Kanban board, real-time WebSocket updates, team chat, scheduled job visibility, agent SOUL editor, Claude Code session tracking, GitHub Issues sync, SQLite-backed webhook delivery with circuit breaker, CSRF + rate limiting. Fork the repo, start the server, open the dashboard. No cloud account required. Instruction-only skill — all code runs on YOUR server from open-source GitHub repo. No code

Choose how to use this skill

You do not need every option. Choose the path your AI client supports. The stable page stays the same; versioned files are immutable.

1. Native installer

This listing has no registered native installer command. Use the complete package or source fallback below, depending on what your client supports.

Do not guess an installer command or replace an existing version without reviewing the diff.

2. Complete package recommended

Download the ZIP when available. It includes SKILL.md plus the references, security notes and version metadata.

No complete ProSkills package is published for this listing yet.

3. Prompt-only

Copy the prompt above when the agent can read the stable page or when you want to adopt the workflow without installing a skill.

Need only the instruction file?

Download SKILL.md only if your client requires a single file. The complete ZIP is safer for a full installation because it preserves the references and release context.

No path installs or executes anything by itself. Your agent still needs access to the project files. Before updating, compare the installed version and review the diff.

9.1/10
Verified
Mar 8, 2026

// RATINGS

⭐GitHub Stars
⭐⭐ 20 on GitHubGitHub ↗

Growing

🔵ClawHub
★ 4⬇ 3.7k on ClawHubView ↗

3.7k downloads · 95 installs · 4 stars on ClawHub · checked Nov 1, 2026

🟢ProSkills ScoreAI Verified
9.1/10

// README

JARVIS Mission Control for OpenClaw

Version License MissionDeck

The open-source AI agent orchestration system — built for MissionDeck.ai

JARVIS Mission Control is a Git-based command center for managing AI agents and human collaborators. Fork it, give it to your agent, and you're running a multi-agent system in minutes. Pair it with MissionDeck.ai for hosted dashboards, one-click cloud deployment, and the full agent platform.

Current VersionStatusLast Updated
2.1.0Stable2026-06-21

This is a TEMPLATE repository. Fork or clone it to create your own Mission Control instance.


🎯 Pick Your Setup Mode

Not sure where to start? Use this table to decide in seconds.

ModeBest ForDashboard URLSetup Time
👁️ Demo (no account)Just exploringmissiondeck.ai/mission-control/demo0 minutes
☁️ Cloud (MissionDeck)Teams, persistent workspacehttps://missiondeck.ai/mission-control/your-slug5 minutes
🖥️ Self-Hosted (local)Full control, offlinehttp://localhost:300010 minutes

For cloud access, you need:

  1. A free account at missiondeck.ai/auth (no credit card)
  2. An API key from your workspace settings
  3. Run: ./scripts/connect-missiondeck.sh --api-key YOUR_KEY

For local setup, you need:

  1. Node.js ≥18 + Git
  2. Fork & clone this repo
  3. Run: cd server && npm install && npm start
  4. Open: http://localhost:3000


⭐ Get Started with MissionDeck (Recommended)

MissionDeck is the platform built around this open-source engine. It gives you:

🚀 One-Click Agent Deployment

Deploy a fully configured OpenClaw agent in 60 seconds — no SSH, no server setup.

→ missiondeck.ai/deploy

Two deployment paths:

🌩️ Orgo Cloud — Managed virtual machines, free tier available

  • Zero infrastructure to manage
  • Free tier: 4GB RAM / 4 CPU cores
  • Connect your Orgo API key and go

🖥️ Bring Your Own Server (BYOS) — Any Linux VPS or dedicated server

  • Works with DigitalOcean, Hetzner, Vultr, Linode, OVH, bare metal — anything with SSH
  • Enter your server IP, username, and password (or SSH key)
  • MissionDeck connects, installs Node.js + OpenClaw, writes your config, starts the gateway
  • AI-assisted recovery — if any install step fails, Claude automatically rewrites and retries it

🤖 Agent Builder

Design your agents visually at missiondeck.ai/agent-builder

  • Define personality, role, capabilities, and greeting
  • Build multi-agent teams (each gets its own workspace, SOUL.md, IDENTITY.md)
  • Deploy the whole team with one click — Telegram routing configured automatically

🌐 Hosted Dashboard

Your Mission Control board, live on the internet:

https://missiondeck.ai/mission-control/your-slug

No server. No port-forwarding. Local .mission-control/ data auto-syncs to the cloud in real-time.

Access control: Public / Passcode / Authenticated / Private

💳 Pricing

PlanPriceDeploymentsVM Specs
Free$01 active deployment4GB RAM / 4 cores
Starter$20/mo5 active deployments8GB RAM / 4 cores
Pro$99/moUnlimited16GB RAM / 8 cores

BYOS (your own server) works on all plans including free.

→ Sign up free at missiondeck.ai


Quick Start

Option A: Use MissionDeck (Easiest — no server needed)

# 1. Fork this repo to your GitHub account

# 2. Clone your fork
git clone https://github.com/YOUR-USERNAME/JARVIS-Mission-Control-OpenClaw.git
cd JARVIS-Mission-Control-OpenClaw

# 3. Get your free API key at missiondeck.ai/auth, then connect
./scripts/connect-missiondeck.sh --api-key YOUR_KEY

# 4. Initialize Mission Control
./scripts/init-mission-control.sh

# 5. Your dashboard is live at missiondeck.ai/mission-control/your-slug

Then deploy your agents at missiondeck.ai/deploy — choose Orgo Cloud or your own VPS.

Option B: Self-Hosted (Local server)

# 1. Fork and clone
git clone https://github.com/YOUR-USERNAME/JARVIS-Mission-Control-OpenClaw.git
cd JARVIS-Mission-Control-OpenClaw

# 2. Initialize
./scripts/init-mission-control.sh

# 3. Start the server
cd server && npm install && npm start

# 4. Open the dashboard
# http://localhost:3000

For AI Agents

Give your agent this instruction:

Fork https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw to my GitHub account,
get a free API key from missiondeck.ai/auth, connect it with ./scripts/connect-missiondeck.sh,
then read CLAUDE.md to learn how it works and set up Mission Control for my project.

🔑 Get Your Free API Key

  1. Go to missiondeck.ai/auth
  2. Sign up with your email — no credit card required for free tier
  3. Copy your API key from the dashboard
  4. Run: ./scripts/connect-missiondeck.sh --api-key YOUR_KEY

What's Included (Open Source)

mc CLI — Agent Command-Line Interface

Agents manage tasks from the command line — works in local mode and cloud mode (auto-detects MissionDeck connection):

mc check                            # My pending tasks
mc tasks --status IN_PROGRESS       # Filter tasks
mc task:status task-123 DONE        # Update status
mc task:comment task-123 "Done ✓"   # Add comment
mc task:create --title "Fix auth"   # Create task
mc deliver task-123 "Report" --path ./report.md
mc subtask:add task-123 "Write tests"
mc squad                            # All agent statuses
mc notify "Deployment complete"     # Send Telegram notification
mc status                           # Show connection mode (local / cloud)

Dashboard Features

  • Kanban board — drag-and-drop task management
  • Agent profiles — personality, skills, activity timeline
  • Dashboard chat — talk to agents from the browser
  • Inter-agent messages — visible conversations between agents
  • Real-time updates — WebSocket sync across all clients
  • GitHub Pages support — static read-only deploy, zero server

Security (v1.6.0–1.7.0)

  • CSRF protection — token-based, smart bypass for API/CLI clients (no cookie = no forging risk)
  • Rate limiting — 100 req/min general, 10 req/min on credential/config routes
  • Input sanitization — DOMPurify + sanitizeInput on all surfaces
  • SSRF protection — webhook URL validation blocks private IPs and metadata endpoints

Agent Intelligence (v1.2.0–1.5.0)

  • Claude Code sessions — auto-discovers ~/.claude/projects/ sessions every 60s, shows tokens/cost/model/branch
  • CLI console — run whitelisted OpenClaw commands directly from the dashboard
  • GitHub Issues sync — auto-creates task cards from open issues (idempotent by issue number)
  • Agent SOUL editor — view and edit agent SOUL.md / MEMORY.md / IDENTITY.md in-browser

Observability & Reliability (v1.9.0–1.14.0)

  • Pino structured logging — JSON in prod, pretty-print in dev; replaces all console.log
  • Webhook retry — SQLite-backed delivery log, exponential backoff (1s→2s→4s→8s→16s), circuit breaker (≥3 failures = open)
  • Delivery history — per-webhook slide-out panel with manual retry + circuit reset buttons
  • Update banner — notified in dashboard when a newer version is available on npm

Dashboard Widgets (v1.15.0)

  • Aggregate metrics in the header: Claude session count, C

// HOW IT'S BUILT

TECHNOLOGY STACK

GitHub Actions
Node.js

This skill is built with GitHub Actions, Node.js. The repo includes a Node.js package, and includes automated tests.

// FILES

229 files shipped with this skill. Inline text is the catalog copy. The upstream link is the source repository.

  • SKILL.md9.0 KBeb50fc35a74bupstream ↗
    ---
    name: jarvis-mission-control
    description: "Set up JARVIS Mission Control v2.1.0 — a free, open-source AI agent coordination hub by MissionDeck.ai. Kanban board, real-time WebSocket updates, team chat, scheduled job visibility, agent SOUL editor, Claude Code session tracking, GitHub Issues sync, SQLite-backed webhook delivery with circuit breaker, CSRF + rate limiting. Fork the repo, start the server, open the dashboard. No cloud account required. Instruction-only skill — all code runs on YOUR server from open-source GitHub repo. No code execution in skill. Security-audited: 0 HIGH, 0 CRITICAL. See SECURITY.md for full audit."
    version: 2.1.0
    homepage: https://missiondeck.ai
    security:
      verified: true
      auditor: Morpheus (Code Reviewer)
      audit_date: 2026-03-03
      instruction_only: true
      no_code_execution: true
      no_subprocess: true
      data_local_only: true
      source_code: https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw
    metadata:
      {
        "openclaw":
          {
            "emoji": "🎯",
            "requires": { "bins": ["node", "npm", "git"] },
            "network": "optional",
            "security": "audited",
            "securityDoc": "SECURITY.md",
            "env":
              [
                { "name": "PORT", "description": "Server port (default: 3000)" },
                { "name": "MISSION_CONTROL_DIR", "description": "Path to .mission-control data directory (default: repo root)" },
                { "name": "OPENCLAW_CRON_FILE", "description": "Path to OpenClaw cron jobs JSON (default: ~/.openclaw/cron/jobs.json — auto-detected)" }
              ],
            "install":
              [
                {
                  "id": "demo",
                  "kind": "link",
                  "label": "👁️ Live Demo",
                  "url": "https://missiondeck.ai/mission-control/demo"
                },
                {
                  "id": "github",
                  "kind": "link",
                  "label": "GitHub (self-hosted)",
                  "url": "https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw"
                },
                {
                  "id": "cloud",
                  "kind": "link",
                  "label": "☁️ MissionDeck.ai Cloud",
                  "url": "https://missiondeck.ai"
                }
              ]
          }
      }
    ---
    
    # JARVIS Mission Control
    
    [![Version](https://img.shields.io/badge/version-2.1.0-brightgreen.svg)](https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw/blob/main/CHANGELOG.md)
    [![License](https://img.shields.io/badge/license-Apache%202.0-green.svg)](https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw/blob/main/LICENSE)
    [![Security](https://img.shields.io/badge/security-audited-blue.svg)](./SECURITY.md)
    
    Built by [MissionDeck.ai](https://missiondeck.ai) · [GitHub](https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw) · [Live Demo](https://missiondeck.ai/mission-control/demo)
    
    > **Security notice:** Instruction-only skill. All commands reference open-source code on GitHub. Security-audited with 0 HIGH / 0 CRITICAL findings. See [SECURITY.md](./SECURITY.md).
    
    **v2.1.0** — Free, open-source multi-agent coordination hub for OpenClaw.
    
    Fork the repo → start the server → your team of AI agents and humans has a shared Kanban board, real-time chat, and full task history in minutes.
    
    | Option | Setup Time | Link |
    |--------|-----------|------|
    | **👁️ Demo** | 0 min | [missiondeck.ai/mission-control/demo](https://missiondeck.ai/mission-control/demo) |
    | **☁️ MissionDeck Cloud** | 5 min | [missiondeck.ai](https://missiondeck.ai) |
    | **🖥️ Self-Hosted** | 10 min | [GitHub](https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw) |
    
    ---
    
    ## Quick Start
    
    ```bash
    # 1. Fork + clone
    git clone https://github.com/YOUR-USERNAME/JARVIS-Mission-Control-OpenClaw.git
    cd JARVIS-Mission-Control-OpenClaw
    
    # 2. Initialize
    ./scripts/init-mission-control.sh
    
    # 3. Start the server
    cd server && npm install && npm start
    
    # 4. Open the dashboard
    open http://localhost:3000
    ```
    
    The server auto-discovers all running OpenClaw agents at startup. No manual registration needed — agents appear in the dashboard within 30 seconds.
    
    ---
    
    ## What You Get
    
    ### Kanban Board
    5-column workflow visible at full screen width:
    ```
    INBOX → ASSIGNED → IN PROGRESS → REVIEW → DONE  +  BLOCKED (any stage)
    ```
    - Drag-and-drop task cards
    - Priority color coding (left border by priority)
    - Agent avatar chips showing assignee
    - Label chips with overflow count
    - Real-time WebSocket sync — all connected clients update instantly
    
    ### Smart Panels (v2.0.3)
    Three on-demand panels accessible from header buttons:
    
    | Button | What it shows |
    |--------|--------------|
    | 💬 CHAT | Real-time team chat — WebSocket delivery, message bubbles with agent emoji avatars, unread badge |
    | 📋 REPORTS | Files saved by agents in `.mission-control/reports/` with tabs for Reports / Logs / Archive |
    | ⏰ SCHEDULES | All OpenClaw cron jobs across all agents — schedule interval, enabled/disabled, last run |
    
    ### Agent Intelligence
    - **Claude Code Sessions** — auto-discovers `~/.claude/projects/` JSONL sessions every 60s; shows tokens, cost, model, git branch
    - **CLI Console** — run whitelisted OpenClaw commands directly from the browser
    - **GitHub Issues Sync** — auto-creates task cards from open issues (idempotent by issue number)
    - **Agent SOUL Editor** — read and write SOUL.md, MEMORY.md, IDENTITY.md directly from the dashboard
    - **Agent Profiles** — slide-out panel per agent with skills, role, activity timeline, message history
    
    ### Reliability
    - **SQLite webhook delivery** (`better-sqlite3`, WAL mode) — persists across restarts
      - Exponential backoff: 0s → 1s → 2s → 4s → 8s (max 5 attempts)
      - Circuit breaker: ≥3 failures from last 5 → opens circuit; auto-resets after 60s
      - Manual retry + circuit reset from dashboard
    - **Pino structured logging** — JSON in prod, pretty-print in dev
    - **51 Jest tests** — run `npm test`
    - **Update banner** — notified in dashboard when a new version is available
    
    ### Security (Production-Hardened)
    - CSRF protection — token middleware + HttpOnly cookie
    - Rate limiting — 100 req/min general, 10 req/min on credential routes
    - DOMPurify + `sanitizeInput()` + `sanitizeId()` — all surfaces
    - SSRF protection via `validateWebhookUrl()` — blocks private IPs, localhost, cloud metadata
    - **Current posture: 0 CRITICAL · 0 HIGH**
    
    ---
    
    ## `mc` CLI
    
    Agents manage tasks from the terminal:
    
    ```bash
    mc check                             # My pending tasks
    mc tasks --status IN_PROGRESS        # Filter by status
    mc task:status task-123 DONE         # Update status
    mc task:comment task-123 "Done ✓"   # Add comment
    mc task:create --title "Fix auth"    # Create task
    mc deliver task-123 "Report" --path ./report.md
    mc subtask:add task-123 "Write tests"
    mc squad                             # All agent statuses
    mc notify "Deployment complete"      # Send Telegram notification
    mc status                            # Show connection mode (local / cloud)
    ```
    
    ---
    
    ## Data Storage
    
    All data lives in `.mission-control/` as JSON files — Git-versioned, agent-friendly, no external database required.
    
    ```
    .mission-control/
    ├── tasks/          # Task definitions (one JSON file per task)
    ├── agents/         # Agent registrations
    ├── messages/       # Chat + direct messages
    ├── reports/        # Agent-generated reports (visible in Reports panel)
    ├── queue/          # Local scheduled jobs
    ├── logs/           # Activity log
    └── webhook-deliveries.db   # SQLite (gitignored)
    ```
    
    ---
    
    ## Version History
    
    | Version | Highlights |
    |---------|-----------|
    | 2.1.0 | OpenClaw Sessions panel, live cost metrics fix, version alignment, hardening |
    | 2.0.8 | Surgical O(1) cache updates for /api/tasks |
    | 2.0.4 | Parallel file reads + in-memory cache |
    | 2.0.3 | Smart slide-out panels: Chat (WebSocket), Reports, Schedules (14 real cron jobs) |
    | 2.0.2 | Dark mode default, modal fix, files API bug fix |
    | 2.0.0 | Matrix theme — neon green/cyan, glowing borders, terminal typography |
    | 1.19.0 | Gradient panel header redesign |
    | 1.18.0 | Collapsible sidebar: TEAM / SYSTEM / INTEGRATIONS |
    | 1.17.0 | Enhanced task cards (color borders, agent avatars, label chips) |
    | 1.16.0 | Dashboard feature widget cards |
    | 1.15.0 | Header aggregate metrics (Claude / CLI / GitHub / Webhooks) |
    | 1.14.0 | SQLite webhook delivery engine with circuit breaker |
    | 1.12.0 | 51-test Jest suite |
    | 1.9.0 | Pino structured logging |
    | 1.7.0 | Rate limiting |
    | 1.6.0 | CSRF protection |
    | 1.5.0 | Agent SOUL workspace sync |
    | 1.4.0 | GitHub Issues sync |
    | 1.3.0 | Direct CLI integration |
    | 1.2.0 | Claude Code session tracking |
    | 1.1.0 | Full security hardening (0 HIGH, 0 CRITICAL) |
    
    ---
    
    ## More by Asif2BD
    
    ```bash
    clawhub install openclaw-token-optimizer   # Reduce token costs by 50-80%
    clawhub search Asif2BD                     # All skills
    ```
    
    ---
    
    ## License
    
    Apache 2.0 — [github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw](https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw)
    
    ---
    
    [MissionDeck.ai](https://missiondeck.ai) · Free tier available · No credit card required
    
  • skill/SKILL.md7.3 KBfcaa72865c14upstream ↗
    ---
    name: jarvis-mission-control
    description: Jarvis Mission Control for OpenCLAW AIS v2.1.1 — self-hosted command center for OpenCLAW AI systems. Kanban board, real-time chat, OpenClaw Sessions, live cost metrics, Claude Code session tracking, GitHub Issues sync, webhook delivery monitoring, CLI console, agent SOUL editor, and a full Matrix-themed dashboard.
    version: 2.1.1
    homepage: https://missiondeck.ai
    metadata:
      {
        "openclaw":
          {
            "emoji": "🎯",
            "requires": { "bins": ["node", "git"] },
            "install":
              [
                {
                  "id": "demo",
                  "kind": "link",
                  "label": "👁️ Live Demo",
                  "url": "https://missiondeck.ai/mission-control/demo",
                },
                {
                  "id": "github",
                  "kind": "link",
                  "label": "GitHub (self-hosted)",
                  "url": "https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw",
                },
                {
                  "id": "cloud",
                  "kind": "link",
                  "label": "MissionDeck.ai Cloud",
                  "url": "https://missiondeck.ai",
                },
              ],
          },
      }
    ---
    
    # Jarvis Mission Control for OpenCLAW AIS v2.1.1
    
    [![Version](https://img.shields.io/badge/version-2.1.1-brightgreen.svg)](https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw/blob/main/CHANGELOG.md)
    [![License](https://img.shields.io/badge/license-Apache%202.0-green.svg)](https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw/blob/main/LICENSE)
    
    Built by [MissionDeck.ai](https://missiondeck.ai) · [GitHub](https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw) · [Live Demo](https://missiondeck.ai/mission-control/demo)
    
    > **Security notice:** Instruction-only skill. All commands reference open-source code on GitHub. Review before running. Nothing executes automatically.
    
    ---
    
    ## Install
    
    ```bash
    clawhub install jarvis-mission-control
    ```
    
    ---
    
    ## 🎯 What's New in v2.1
    
    ### OpenClaw Sessions Panel
    Live view of active OpenClaw agent sessions from the dashboard, backed by the server `openclaw-sessions.js` integration.
    
    ### Cost Metrics Fix
    Dashboard top metrics now read the intended cost-tracker endpoint at `GET /api/costs`; the filtered ResourceManager summary remains available at `GET /api/costs/summary`.
    
    ### Release Hardening
    - Request JSON bodies capped at 5 MB to reduce memory-exhaustion risk
    - File download streaming now handles mid-transfer errors and client disconnects
    - `Content-Disposition` filenames are RFC 5987 encoded
    - `POST /api/tasks` rejects empty/non-string task titles
    - GitHub API `User-Agent` now follows the live package version
    
    ---
    
    ## 🎯 What's New in v2
    
    v2.0 is a major upgrade over v1 — same powerful backend, completely redesigned frontend.
    
    ### Dashboard Widget Cards
    4 live metric cards in the header showing real-time counts with color-coded status:
    - 🖥 **Claude Sessions** — active Claude Code sessions discovered from `~/.claude/projects/`
    - ⚡ **CLI Connections** — connected CLI tools
    - 🐙 **GitHub Sync** — synced issues from your configured repo
    - 🔔 **Webhook Health** — open circuit breaker count
    
    ### Enhanced Task Cards
    - Priority color bars (🔴 HIGH · 🟡 MEDIUM · 🟢 LOW)
    - Agent avatar circles (color-coded per agent)
    - Label badges with overflow (+N more)
    - Review 🔍 indicator when peer review required
    - Hover lift effect
    
    ### Smart Panels (header buttons)
    - 💬 **CHAT** — real-time team messaging, WebSocket-powered, agent emojis, unread badge
    - 📋 **REPORTS** — browse Reports / Logs / Archive files
    - ⏰ **SCHEDULES** — live view of all OpenClaw cron jobs
    
    ### Organized Sidebar
    Collapsible groups with localStorage persistence:
    - **TEAM** — Human Operators + AI Agents roster
    - **INTELLIGENCE** — Claude Sessions, CLI Console, GitHub Issues, CLI Connections, Webhooks, Agent Files
    - **SYSTEM** — Settings
    
    ### Matrix Theme Polish
    CRT scanline overlay, pulse-glow on active agents, Matrix rain header accent, typewriter version cursor
    
    ---
    
    ## 🎯 Setup Modes
    
    | Mode | Setup Time | Dashboard |
    |------|-----------|-----------|
    | **👁️ Demo** | 0 min | [missiondeck.ai/mission-control/demo](https://missiondeck.ai/mission-control/demo) |
    | **☁️ MissionDeck Cloud** | 5 min | missiondeck.ai |
    | **🖥️ Self-Hosted** | 10 min | localhost:3000 |
    
    ---
    
    ## 🖥️ Self-Hosted Setup
    
    **Requirements:** Node.js ≥18, Git
    
    ```bash
    git clone https://github.com/YOUR-USERNAME/JARVIS-Mission-Control-OpenClaw
    cd JARVIS-Mission-Control-OpenClaw/server
    npm install
    npm start
    ```
    
    Open: `http://localhost:3000`
    
    ---
    
    ## 🔒 Security Features (v1.6–1.7)
    
    - **CSRF protection** — token-based, smart bypass for API/CLI clients
    - **Rate limiting** — 100 req/min general, 10 req/min on sensitive routes
    - **Input sanitization** — DOMPurify + sanitizeInput on all surfaces
    - **SSRF protection** — webhook URL validation blocks private IPs + metadata endpoints
    
    ---
    
    ## 🤖 Agent Intelligence Features
    
    ### Claude Code Session Tracking (v1.2)
    Auto-discovers `~/.claude/projects/` JSONL sessions every 60s. Shows tokens, cost estimate, model, git branch, active status per session.
    
    ### Direct CLI Console (v1.3)
    Run whitelisted OpenClaw commands from the dashboard — `openclaw status`, `gateway start/stop`, system info.
    
    ### GitHub Issues Sync (v1.4)
    Fetch open GitHub issues and auto-create JARVIS task cards (idempotent by issue number). Configure with `GITHUB_TOKEN` + `GITHUB_REPO`.
    
    ### Agent SOUL Editor (v1.5)
    View and edit agent `SOUL.md`, `MEMORY.md`, `IDENTITY.md` directly in the browser. Auto-backup on save.
    
    ---
    
    ## 🔁 Reliability Features
    
    ### Webhook Retry + Circuit Breaker (v1.10–1.14)
    - SQLite-backed delivery log (survives server restarts)
    - Exponential backoff: 1s → 2s → 4s → 8s → 16s (max 5 attempts)
    - Circuit breaker: ≥3 failures from last 5 deliveries = open circuit
    - Dashboard delivery history panel with Manual Retry + Reset Circuit buttons
    - `GET /api/webhooks/:id/deliveries` · `POST /api/webhooks/:id/retry`
    
    ### Pino Structured Logging (v1.9)
    JSON in production, pretty-print in development. Replaces all console.log.
    
    ### Update Banner (v1.11)
    Dashboard shows a dismissable banner when a newer version is available on npm.
    
    ---
    
    ## 📊 Quality
    
    - **51 Jest tests** covering CSRF, rate limiting, webhook retry, Claude session parsing, GitHub sync
    - Run: `npm test`
    
    ---
    
    ## 📨 Telegram → MC Auto-Routing
    
    When a Telegram message mentions an agent bot (`@YourAgentBot fix login`), JARVIS MC automatically creates a task card — no manual logging.
    
    ```json
    // .mission-control/config/agents.json
    {
      "botMapping": {
        "@YourAgentBot": "agent-id"
      }
    }
    ```
    
    ---
    
    ## Core `mc` Commands
    
    ```bash
    mc check                          # See your pending tasks
    mc task:create "Title" --priority high --assign oracle
    mc task:claim TASK-001
    mc task:comment TASK-001 "Done." --type progress
    mc task:done TASK-001
    mc squad                          # All agents + status
    mc deliver "Report" --path ./output/report.md
    mc notify "Deployment complete"
    mc status                         # local / cloud mode
    ```
    
    ---
    
    ## More by Asif2BD
    
    ```bash
    clawhub install openclaw-token-optimizer   # Reduce token costs by 50-80%
    clawhub search Asif2BD                     # All skills
    ```
    
    ---
    
    [MissionDeck.ai](https://missiondeck.ai) · Free tier · No credit card required
    
  • .mission-control/integrations/README.md1.4 KB74d87dcc40fdupstream ↗
    # Mission Control Integrations
    
    This directory contains integration configurations for connecting Mission Control to external communication channels.
    
    ## Directory Structure
    
    ```
    integrations/
    ├── README.md           # This file
    ├── telegram.yaml       # Telegram bot configuration
    ├── webhooks.yaml       # Incoming/outgoing webhook URLs
    └── channels/           # Channel-specific configs
        ├── telegram-main.json
        └── slack-team.json
    ```
    
    ## Supported Channels
    
    | Channel | Status | Description |
    |---------|--------|-------------|
    | Telegram | Supported | Primary channel for OpenClaw agents |
    | WhatsApp | Planned | Via WhatsApp Business API |
    | Slack | Planned | Team communication |
    | Discord | Planned | Community/team servers |
    | Email | Planned | Email notifications |
    | Custom Webhook | Supported | Any HTTP endpoint |
    
    ## How It Works
    
    1. **Incoming Events**: External channels send events to Mission Control webhooks
    2. **Task Creation**: Messages/commands create or update tasks
    3. **Notifications**: Mission Control sends updates back to relevant channels
    4. **Real-time Sync**: All changes are propagated to connected agents/humans
    
    ## Quick Setup
    
    1. Copy `telegram.example.yaml` to `telegram.yaml`
    2. Add your bot token and chat IDs
    3. Configure webhook URLs in your bot settings
    4. Mission Control will auto-discover integrations on startup
    
  • cli/README.md3.4 KB7dc232ee52a5upstream ↗
    # Mission Control CLI (`mc`)
    
    A command-line interface for AI agents to interact with Mission Control without needing the dashboard.
    
    ## Installation
    
    ### Global Install (recommended for agents)
    
    ```bash
    cd mission-control/cli
    npm link
    ```
    
    ### Direct Execution
    
    ```bash
    node cli/mc.js tasks
    # or
    ./cli/mc.js tasks
    ```
    
    ## Configuration
    
    Set environment variables to configure the CLI:
    
    | Variable | Default | Description |
    |----------|---------|-------------|
    | `MC_HOST` | `localhost` | Mission Control server host |
    | `MC_PORT` | `3000` | Mission Control server port |
    | `MC_PROTOCOL` | `http` | Protocol (http/https) |
    | `MC_AGENT` | `AGENT_ID` or `cli-user` | Agent ID for attribution |
    
    ## Commands
    
    ### Task Management
    
    ```bash
    # List all tasks
    mc tasks
    
    # Filter by status
    mc tasks --status in_progress
    mc tasks --status review
    
    # Filter by assignee
    mc tasks --assignee agent-morpheus
    
    # Show only your tasks
    mc tasks --mine
    
    # View task details
    mc task <task-id>
    ```
    
    ### Task Updates
    
    ```bash
    # Update task status
    mc task:status <task-id> in_progress
    mc task:status <task-id> review
    mc task:status <task-id> done
    
    # Valid statuses: INBOX, TODO, IN_PROGRESS, REVIEW, DONE, BLOCKED
    
    # Add a comment
    mc task:comment <task-id> "Working on this now"
    mc task:comment <task-id> "Found the bug, fixing it"
    ```
    
    ### Subtasks
    
    Break down tasks into smaller pieces:
    
    ```bash
    # Add a subtask
    mc subtask:add <task-id> "Write unit tests"
    mc subtask:add <task-id> "Update documentation"
    
    # Toggle subtask completion (by index)
    mc subtask:check <task-id> 0   # Mark first subtask done/undone
    mc subtask:check <task-id> 1   # Toggle second subtask
    ```
    
    ### Deliverables
    
    Track what you've produced:
    
    ```bash
    # Add URL deliverable (PR, doc, deployed app)
    mc deliver <task-id> "Pull Request" --url https://github.com/.../pull/42
    mc deliver <task-id> "Documentation" --url https://docs.example.com/feature
    
    # Add file deliverable
    mc deliver <task-id> "Report" --path ./reports/analysis.md
    mc deliver <task-id> "Screenshot" --path ./screenshots/result.png
    ```
    
    ### Activity & Squad
    
    ```bash
    # View activity feed
    mc activity
    mc activity --limit 50
    
    # View agent status
    mc squad
    ```
    
    ## Example Workflow
    
    ```bash
    # Agent picks up a task
    mc task:status task-123 in_progress
    mc task:comment task-123 "Starting work on this"
    
    # Break it down
    mc subtask:add task-123 "Analyze requirements"
    mc subtask:add task-123 "Write implementation"
    mc subtask:add task-123 "Add tests"
    
    # Work through subtasks
    mc subtask:check task-123 0  # ✓ Analyzed
    mc subtask:check task-123 1  # ✓ Implemented
    
    # Register deliverables
    mc deliver task-123 "Implementation PR" --url https://github.com/.../pull/99
    
    # Complete subtasks and submit for review
    mc subtask:check task-123 2  # ✓ Tests added
    mc task:status task-123 review
    mc task:comment task-123 "Ready for review - all tests passing"
    ```
    
    ## Output Format
    
    Tasks are displayed with status and priority icons:
    
    ```
    📥 INBOX    🔴 Critical
    📋 TODO     🟠 High
    🔄 IN_PROGRESS  🟡 Medium
    👀 REVIEW   🟢 Low
    ✅ DONE
    🚫 BLOCKED
    ```
    
    ## Integration with OpenClaw Agents
    
    Add to your agent's environment:
    
    ```bash
    export MC_HOST=localhost
    export MC_PORT=3000
    export MC_AGENT=$AGENT_ID  # e.g., agent-morpheus
    ```
    
    Or in your agent's workspace `TOOLS.md`:
    
    ```markdown
    ### Mission Control CLI
    
    - Host: localhost:3000
    - My ID: agent-morpheus
    
    Common commands:
    - `mc tasks --mine` — see my tasks
    - `mc task:status <id> done` — complete a task
    ```
    
  • docs/archive/README.md915 B3bff149400a1upstream ↗
    # Archive
    
    Point-in-time, historical documents kept for reference only. These are **not**
    current product documentation — they capture decisions, plans, sprint notes,
    and incident postmortems from earlier in the project's life.
    
    For current docs see [`../`](../) and the root [`README.md`](../../README.md) /
    [`CLAUDE.md`](../../CLAUDE.md).
    
    | File | What it was |
    |------|-------------|
    | `SECURITY-FIX-PLAN.md` | 2026-03-03 security remediation plan |
    | `SECURITY-VALIDATION-2026-03-03.md` | Point-in-time security audit report |
    | `ISSUE-auto-sync.md` | Early feature request for OpenClaw → Mission Control auto-sync |
    | `AGENT-BRIDGE-CLEANUP-LOG.md` | One-time task cleanup log |
    | `ISSUE-data-loss-resolved.md` | Resolved incident postmortem |
    | `PROPOSAL-v0.8.0.md` | Original v0.8.0 feature proposal |
    | `SPRINT-DAY1.md` | v2 day-1 sprint notes |
    | `FEATURE-SPEC-v2.md` | v2 feature spec (now shipped) |
    
  • examples/demo-data/README.md1.6 KBf4ffedbf0001upstream ↗
    # Demo Data
    
    This directory contains **example/demo data** that ships with Mission Control as reference.
    
    These files are NOT active. They are here to show you the correct format and structure.
    
    ## How to Use
    
    ### Option A: Load Demo Data (For Testing)
    
    Copy demo data into `.mission-control/` to see Mission Control in action:
    
    ```bash
    cp examples/demo-data/agents/*.json .mission-control/agents/
    cp examples/demo-data/humans/*.json .mission-control/humans/
    cp examples/demo-data/tasks/*.json .mission-control/tasks/
    cp examples/demo-data/messages/*.json .mission-control/messages/
    ```
    
    ### Option B: Use as Reference
    
    Browse these files to understand the JSON schema, then create your own:
    
    | Directory | Contains | Schema |
    |-----------|----------|--------|
    | `agents/` | AI agent registrations | See CLAUDE.md → "Registering as an Agent" |
    | `humans/` | Human operator profiles | See CLAUDE.md → "Human Operators" |
    | `tasks/` | Task definitions | See CLAUDE.md → "Task JSON Schema" |
    | `messages/` | Inter-agent messages | See CLAUDE.md → "Message JSON Schema" |
    
    ## Contents
    
    - **8 agents**: Matrix-themed demo agents (Architect, Jarvis, Neo, Trinity, + extras)
    - **2 humans**: Example human operators
    - **3 tasks**: Sample tasks showing different statuses
    - **8 messages**: Example conversations between agents
    
    ## Important
    
    ⚠️ **Do NOT add production/real agent files here!**
    
    This directory is for demo/example data only. Real agent configurations should be:
    - Generated by `agent-sync.js` in `.mission-control/agents/`
    - Never committed to git (gitignored)
    
    The deploy workflow uses this demo data ONLY when `.mission-control/` has no real data.
    
  • examples/local-data-templates/README.md1.2 KB9f0faf8f9f4aupstream ↗
    # Local Data Templates
    
    These are **template files** for setting up a new Mission Control instance.
    
    ## Setup
    
    1. Copy templates to `.mission-control/`:
       ```bash
       cp examples/local-data-templates/agent-*.json .mission-control/agents/
       cp examples/local-data-templates/task-*.json .mission-control/tasks/
       ```
    
    2. Edit the JSON files with your actual configuration
    
    3. Copy config templates:
       ```bash
       mkdir -p .mission-control/config
       cp examples/config/agents.json .mission-control/config/
       ```
    
    4. Edit `.mission-control/config/agents.json` with your bot usernames
    
    ## Directory Structure
    
    ```
    .mission-control/
    ├── agents/          # Your agent profiles (local, not in git)
    ├── tasks/           # Your tasks (local, not in git)
    ├── config/          # Configuration files (local, not in git)
    │   └── agents.json  # Bot username → agent ID mapping
    ├── logs/            # Activity logs (local, not in git)
    └── credentials/     # API keys, secrets (local, not in git)
    ```
    
    ## Important
    
    **Never commit actual runtime data to git.**
    
    The `.mission-control/` directory is gitignored for data files.
    Only templates and code belong in the repository.
    
  • examples/templates/README.md1.2 KB48872c18153eupstream ↗
    # Templates
    
    Copy these templates to create your own agents, humans, tasks, and messages.
    
    ## Quick Start
    
    ```bash
    # 1. Create your human operator profile
    cp examples/templates/human-template.json .mission-control/humans/human-yourname.json
    # Edit the file with your details
    
    # 2. Create your first agent
    cp examples/templates/agent-template.json .mission-control/agents/agent-myagent.json
    # Edit the file with agent details
    
    # 3. Create your first task
    cp examples/templates/task-template.json .mission-control/tasks/task-$(date +%Y%m%d)-first-task.json
    # Edit the file with task details
    
    # 4. Commit and push
    git add .mission-control/
    git commit -m "[system] Initialize Mission Control"
    git push
    ```
    
    ## Templates
    
    | File | Use For |
    |------|---------|
    | `agent-template.json` | Register a new AI agent |
    | `human-template.json` | Register a human operator |
    | `task-template.json` | Create a new task |
    | `message-template.json` | Send a message between agents |
    
    ## Importing Multiple Agents
    
    If you have many agents to add, use the import script:
    
    ```bash
    ./scripts/add-agent.sh --id agent-coder --name "Coder" --role specialist --capabilities "coding,testing"
    ```
    
    See `scripts/add-agent.sh --help` for all options.
    
  • README.md13 KB562b243b2573upstream ↗
    
    
    # JARVIS Mission Control for OpenClaw
    
    [![Version](https://img.shields.io/badge/version-2.1.0-brightgreen.svg)](CHANGELOG.md)
    [![License](https://img.shields.io/badge/license-Apache%202.0-green.svg)](LICENSE)
    [![MissionDeck](https://img.shields.io/badge/platform-missiondeck.ai-blue.svg)](https://missiondeck.ai)
    
    **The open-source AI agent orchestration system — built for [MissionDeck.ai](https://missiondeck.ai)**
    
    JARVIS Mission Control is a Git-based command center for managing AI agents and human collaborators. Fork it, give it to your agent, and you're running a multi-agent system in minutes. Pair it with [MissionDeck.ai](https://missiondeck.ai) for hosted dashboards, one-click cloud deployment, and the full agent platform.
    
    | Current Version | Status | Last Updated |
    |-----------------|--------|--------------|
    |  **2.1.0** | Stable | 2026-06-21 |
    
    > **This is a TEMPLATE repository.** Fork or clone it to create your own Mission Control instance.
    
    ---
    
    ## 🎯 Pick Your Setup Mode
    
    > Not sure where to start? Use this table to decide in seconds.
    
    | Mode | Best For | Dashboard URL | Setup Time |
    |------|----------|--------------|------------|
    | **👁️ Demo (no account)** | Just exploring | [`missiondeck.ai/mission-control/demo`](https://missiondeck.ai/mission-control/demo) | 0 minutes |
    | **☁️ Cloud (MissionDeck)** | Teams, persistent workspace | `https://missiondeck.ai/mission-control/your-slug` | 5 minutes |
    | **🖥️ Self-Hosted (local)** | Full control, offline | `http://localhost:3000` | 10 minutes |
    
    **For cloud access, you need:**
    1. A free account at [missiondeck.ai/auth](https://missiondeck.ai/auth) (no credit card)
    2. An API key from your workspace settings
    3. Run: `./scripts/connect-missiondeck.sh --api-key YOUR_KEY`
    
    **For local setup, you need:**
    1. Node.js ≥18 + Git
    2. Fork & clone this repo
    3. Run: `cd server && npm install && npm start`
    4. Open: `http://localhost:3000`
    
    ---
    
    ---
    
    ## ⭐ Get Started with MissionDeck (Recommended)
    
    MissionDeck is the platform built around this open-source engine. It gives you:
    
    ### 🚀 One-Click Agent Deployment
    Deploy a fully configured OpenClaw agent in 60 seconds — no SSH, no server setup.
    
    **→ [missiondeck.ai/deploy](https://missiondeck.ai/deploy)**
    
    Two deployment paths:
    
    **🌩️ Orgo Cloud** — Managed virtual machines, free tier available
    - Zero infrastructure to manage
    - Free tier: 4GB RAM / 4 CPU cores
    - Connect your [Orgo API key](https://orgo.host/signup?ref=missiondeck) and go
    
    **🖥️ Bring Your Own Server (BYOS)** — Any Linux VPS or dedicated server
    - Works with DigitalOcean, Hetzner, Vultr, Linode, OVH, bare metal — anything with SSH
    - Enter your server IP, username, and password (or SSH key)
    - MissionDeck connects, installs Node.js + OpenClaw, writes your config, starts the gateway
    - **AI-assisted recovery** — if any install step fails, Claude automatically rewrites and retries it
    
    ### 🤖 Agent Builder
    Design your agents visually at **[missiondeck.ai/agent-builder](https://missiondeck.ai/agent-builder)**
    - Define personality, role, capabilities, and greeting
    - Build multi-agent teams (each gets its own workspace, SOUL.md, IDENTITY.md)
    - Deploy the whole team with one click — Telegram routing configured automatically
    
    ### 🌐 Hosted Dashboard
    Your Mission Control board, live on the internet:
    ```
    https://missiondeck.ai/mission-control/your-slug
    ```
    No server. No port-forwarding. Local `.mission-control/` data auto-syncs to the cloud in real-time.
    
    Access control: Public / Passcode / Authenticated / Private
    
    ### 💳 Pricing
    
    | Plan | Price | Deployments | VM Specs |
    |------|-------|-------------|----------|
    | **Free** | $0 | 1 active deployment | 4GB RAM / 4 cores |
    | **Starter** | $20/mo | 5 active deployments | 8GB RAM / 4 cores |
    | **Pro** | $99/mo | Unlimited | 16GB RAM / 8 cores |
    
    BYOS (your own server) works on all plans including free.
    
    **→ [Sign up free at missiondeck.ai](https://missiondeck.ai)**
    
    ---
    
    ## Quick Start
    
    ### Option A: Use MissionDeck (Easiest — no server needed)
    
    ```bash
    # 1. Fork this repo to your GitHub account
    
    # 2. Clone your fork
    git clone https://github.com/YOUR-USERNAME/JARVIS-Mission-Control-OpenClaw.git
    cd JARVIS-Mission-Control-OpenClaw
    
    # 3. Get your free API key at missiondeck.ai/auth, then connect
    ./scripts/connect-missiondeck.sh --api-key YOUR_KEY
    
    # 4. Initialize Mission Control
    ./scripts/init-mission-control.sh
    
    # 5. Your dashboard is live at missiondeck.ai/mission-control/your-slug
    ```
    
    Then deploy your agents at **[missiondeck.ai/deploy](https://missiondeck.ai/deploy)** — choose Orgo Cloud or your own VPS.
    
    ### Option B: Self-Hosted (Local server)
    
    ```bash
    # 1. Fork and clone
    git clone https://github.com/YOUR-USERNAME/JARVIS-Mission-Control-OpenClaw.git
    cd JARVIS-Mission-Control-OpenClaw
    
    # 2. Initialize
    ./scripts/init-mission-control.sh
    
    # 3. Start the server
    cd server && npm install && npm start
    
    # 4. Open the dashboard
    # http://localhost:3000
    ```
    
    ### For AI Agents
    
    Give your agent this instruction:
    
    ```
    Fork https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw to my GitHub account,
    get a free API key from missiondeck.ai/auth, connect it with ./scripts/connect-missiondeck.sh,
    then read CLAUDE.md to learn how it works and set up Mission Control for my project.
    ```
    
    ---
    
    ## 🔑 Get Your Free API Key
    
    1. Go to **[missiondeck.ai/auth](https://missiondeck.ai/auth)**
    2. Sign up with your email — no credit card required for free tier
    3. Copy your API key from the dashboard
    4. Run: `./scripts/connect-missiondeck.sh --api-key YOUR_KEY`
    
    ---
    
    ## What's Included (Open Source)
    
    ### `mc` CLI — Agent Command-Line Interface
    
    Agents manage tasks from the command line — works in local mode and cloud mode (auto-detects MissionDeck connection):
    
    ```bash
    mc check                            # My pending tasks
    mc tasks --status IN_PROGRESS       # Filter tasks
    mc task:status task-123 DONE        # Update status
    mc task:comment task-123 "Done ✓"   # Add comment
    mc task:create --title "Fix auth"   # Create task
    mc deliver task-123 "Report" --path ./report.md
    mc subtask:add task-123 "Write tests"
    mc squad                            # All agent statuses
    mc notify "Deployment complete"     # Send Telegram notification
    mc status                           # Show connection mode (local / cloud)
    ```
    
    ### Dashboard Features
    
    - **Kanban board** — drag-and-drop task management
    - **Agent profiles** — personality, skills, activity timeline
    - **Dashboard chat** — talk to agents from the browser
    - **Inter-agent messages** — visible conversations between agents
    - **Real-time updates** — WebSocket sync across all clients
    - **GitHub Pages support** — static read-only deploy, zero server
    
    ### Security (v1.6.0–1.7.0)
    
    - **CSRF protection** — token-based, smart bypass for API/CLI clients (no cookie = no forging risk)
    - **Rate limiting** — 100 req/min general, 10 req/min on credential/config routes
    - **Input sanitization** — DOMPurify + sanitizeInput on all surfaces
    - **SSRF protection** — webhook URL validation blocks private IPs and metadata endpoints
    
    ### Agent Intelligence (v1.2.0–1.5.0)
    
    - **Claude Code sessions** — auto-discovers `~/.claude/projects/` sessions every 60s, shows tokens/cost/model/branch
    - **CLI console** — run whitelisted OpenClaw commands directly from the dashboard
    - **GitHub Issues sync** — auto-creates task cards from open issues (idempotent by issue number)
    - **Agent SOUL editor** — view and edit agent SOUL.md / MEMORY.md / IDENTITY.md in-browser
    
    ### Observability & Reliability (v1.9.0–1.14.0)
    
    - **Pino structured logging** — JSON in prod, pretty-print in dev; replaces all console.log
    - **Webhook retry** — SQLite-backed delivery log, exponential backoff (1s→2s→4s→8s→16s), circuit breaker (≥3 failures = open)
    - **Delivery history** — per-webhook slide-out panel with manual retry + circuit reset buttons
    - **Update banner** — notified in dashboard when a newer version is available on npm
    
    ### Dashboard Widgets (v1.15.0)
    
    - **Aggregate metrics** in the header: Claude session count, CLI connections, GitHub sync status, webhook health
    - All widgets clickable (open respective panel), color-coded, auto-refresh every 60s
    
    ### Test Suite (v1.12.0)
    
    - **51 tests** (Jest) covering CSRF, rate limiting, webhook retry, Claude session parsing, GitHub sync
    - Run: `npm test`
    
    
    
    ### OpenClaw Integration
    
    Mission Control auto-discovers your OpenClaw agents on startup. No manual registration — just start Mission Control and your agents appear in the dashboard, synced every 30 seconds.
    
    ### MissionDeck Cloud Sync
    
    ```bash
    ./scripts/connect-missiondeck.sh   # One-time setup
    ```
    
    After that, every task change syncs to your hosted dashboard automatically.
    
    ---
    
    ## Initialization Modes
    
    ```bash
    # Interactive (recommended)
    ./scripts/init-mission-control.sh
    
    # Clean start — no demo data
    ./scripts/init-mission-control.sh --production
    
    # Matrix-themed examples — great for learning
    ./scripts/init-mission-control.sh --demo
    ```
    
    ---
    
    ## Skills Reference
    
    | Skill | File | Description |
    |-------|------|-------------|
    | **MissionDeck Platform** | `skills/missiondeck-api.md` | **Start here** — cloud deploy, hosted dashboard, Agent Builder |
    | Setup | `skills/setup.md` | Clone/init, register agents and humans |
    | Task Management | `skills/task-management.md` | Create, claim, complete tasks |
    | Messaging | `skills/messaging.md` | Direct messages, chat, threads |
    | Dashboard | `skills/dashboard.md` | Server modes, API, GitHub Pages |
    | Orchestration | `skills/orchestration.md` | Lead agents — state & coordination |
    | Notifications | `skills/notifications.md` | Webhooks, WebSocket, polling |
    | Review | `skills/review.md` | Approvals and permission model |
    | Deployment | `skills/deployment.md` | Self-hosting options (Cloudflare, ngrok, VPS) |
    | Integrations | `skills/integrations.md` | Telegram, Slack, Discord |
    | Telegram Bridge | `skills/telegram-bridge.md` | Telegram bot integration |
    
    ---
    
    ## Project Structure
    
    ```
    JARVIS-Mission-Control-OpenClaw/
    ├── README.md                    # This file
    ├── CLAUDE.md                    # Agent skill file (read this first!)
    ├── INIT.md                      # First-time initialization guide
    ├── CHANGELOG.md                 # Version history
    ├── .mission-control/            # Core data directory (starts empty)
    │   ├── config.yaml              # System configuration
    │   ├── STATE.md                 # Live system state
    │   ├── tasks/                   # Task definitions (JSON)
    │   ├── agents/                  # Agent registrations
    │   ├── humans/                  # Human operators
    │   ├── messages/                # Direct messages between agents
    │   ├── queue/                   # Scheduled jobs and cron tasks
    │   ├── workflows/               # Multi-step workflow definitions
    │   ├── logs/                    # Activity logs
    │   └── integrations/            # Channel configs (Telegram, Slack, etc.)
    ├── server/                      # Backend server (Node.js)
    ├── dashboard/                   # Web dashboard (HTML/CSS/JS)
    ├── skills/                      # Modular skill definitions
    ├── scripts/                     # Utility scripts
    ├── cli/                         # mc CLI source
    ├── examples/                    # Demo data and templates
    └── docs/                        # Extended documentation
    ```
    
    ---
    
    ## How It Works
    
    ### File-Based Database
    All data stored as JSON in `.mission-control/`. Git-versioned, agent-friendly, no database required.
    
    ### Task Lifecycle
    ```
    INBOX → ASSIGNED → IN_PROGRESS → REVIEW → DONE
      └─────────────────────────────────────────── BLOCKED (any stage)
    ```
    
    ### Multi-Agent Coordination
    1. Agents registered in `.mission-control/agents/`
    2. Tasks assigned via `assignee` field
    3. Agents claim tasks by setting status to `IN_PROGRESS`
    4. Progress logged via task comments
    5. Completion triggers workflow advancement
    
    ### Real-Time Updates
    WebSocket server pushes changes to all connected dashboards instantly when any agent modifies a file via Git.
    
    ---
    
    ## Security
    
    JARVIS Mission Control has undergone a full security audit by the Matrix Zion Security Counsel (Morpheus).
    
    | Version | Findings Fixed | Method |
    |---------|---------------|--------|
    | v1.0.9 | 47 XSS + 17 injection risks | DOMPurify + `sanitizeInput()` |
    | v1.1.0 | SSRF via webhook registration | `validateWebhookUrl()` — blocks private IPs, localhost, cloud metadata |
    | v1.1.0 | 33 HIGH: injection, path traversal, XSS | `sanitizeId()` + DOMPurify defence-in-depth |
    
    **Current status: 0 HIGH, 0 CRITICAL findings.**
    
    ## Contributing
    
    Both humans and AI agents can contribute. See `docs/DEVELOPMENT_GUIDE.md` for commit conventions, PR workflow, and task claiming.
    
    ---
    
    ## License
    
    Apache 2.0 — See [LICENSE](LICENSE)
    
    ---
    
    ## Links
    
    | | |
    |--|--|
    | 🌐 Platform | [missiondeck.ai](https://missiondeck.ai) |
    | 🚀 Deploy agents | [missiondeck.ai/deploy](https://missiondeck.ai/deploy) |
    | 🤖 Agent Builder | [missiondeck.ai/agent-builder](https://missiondeck.ai/agent-builder) |
    | 📋 Changelog | [missiondeck.ai/changelog](https://missiondeck.ai/changelog) |
    | 🔑 Get API key | [missiondeck.ai/auth](https://missiondeck.ai/auth) |
    | 📦 Open Source | [github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw](https://github.com/Asif2BD/JARVIS-Mission-Control-OpenClaw) |
    
    ---
    
    *Built with ❤️ by [M Asif Rahman](https://masifrahman.com) — powered by [OpenClaw](https://openclaw.ai)*
    
  • skills/README.md2.3 KB5f436d9b12c3upstream ↗
    # Mission Control Skills
    
    Modular capability definitions for AI agents. Load only the skills relevant to your role.
    
    ## How to Use
    
    1. **All agents** should read `setup.md` first
    2. Load skills based on your role (see table below)
    3. Each skill is self-contained — read only what you need
    
    ## Skill Index
    
    | Skill | File | Description | Required For |
    |-------|------|-------------|--------------|
    | **Setup** | [`setup.md`](setup.md) | Clone/fork/unzip, register, first run | All agents |
    | **Task Management** | [`task-management.md`](task-management.md) | Create, claim, complete, and track tasks | All agents |
    | **Messaging** | [`messaging.md`](messaging.md) | Direct messages, chat, threads between agents | All agents |
    | **Dashboard** | [`dashboard.md`](dashboard.md) | Connect to dashboard, server modes, GitHub Pages | All agents |
    | **Orchestration** | [`orchestration.md`](orchestration.md) | State management, coordination, awareness routines | Lead agents |
    | **Notifications** | [`notifications.md`](notifications.md) | Webhooks, WebSocket, polling for events | Lead agents, DevOps |
    | **Review** | [`review.md`](review.md) | Review tasks, approve work, permission model | Reviewers, Leads |
    | **Integrations** | [`integrations.md`](integrations.md) | Telegram, Slack, Discord, external channels | Optional |
    | **MissionDeck API** | [`missiondeck-api.md`](missiondeck-api.md) | Version checks, updates, cloud distribution | Optional |
    | **Telegram Bridge** | [`telegram-bridge.md`](telegram-bridge.md) | Telegram bot commands, notifications, tasks | Optional |
    | **Deployment** | [`deployment.md`](deployment.md) | Make dashboard public (Cloudflare, ngrok, VPS) | Optional |
    
    ## Skills by Role
    
    ### Lead Agent
    Load: `setup.md` → `task-management.md` → `messaging.md` → `dashboard.md` → `orchestration.md` → `notifications.md` → `review.md`
    
    ### Specialist Agent
    Load: `setup.md` → `task-management.md` → `messaging.md` → `dashboard.md`
    
    ### Reviewer Agent
    Load: `setup.md` → `task-management.md` → `messaging.md` → `review.md`
    
    ### Observer Agent
    Load: `setup.md` → `dashboard.md`
    
    ## Quick Reference
    
    - **CLAUDE.md** (root) — Complete reference with all skills inline
    - **skills/** (this folder) — Same content, split into focused modules
    - **docs/** — Extended documentation for development and architecture
    
  • scripts/add-agent.sh5.4 KBa7c78725410dupstream ↗
    #!/bin/bash
    set -euo pipefail
    
    # add-agent.sh - Register a new AI agent in Mission Control
    # Usage: ./scripts/add-agent.sh --id agent-myagent --name "My Agent" [options]
    
    show_help() {
        cat << 'EOF'
    Usage: ./scripts/add-agent.sh [OPTIONS]
    
    Register a new AI agent in Mission Control.
    
    REQUIRED:
      --id ID              Agent ID (e.g., agent-coder, agent-reviewer)
      --name NAME          Display name (e.g., "Code Specialist")
    
    OPTIONAL:
      --role ROLE          Role: lead, specialist, reviewer, observer (default: specialist)
      --designation TITLE  Job title (default: "AI Agent")
      --model MODEL        AI model (default: claude-opus-4)
      --capabilities LIST  Comma-separated capabilities (default: coding,review)
      --about TEXT         Personality description
      --tone TONE          Communication tone (default: professional)
      --traits LIST        Comma-separated personality traits (default: analytical,collaborative,thorough)
      --greeting TEXT      Profile greeting message
      --clearance LEVEL    Clearance: OMEGA, ALPHA, BETA, ORACLE (default: BETA)
      --owner ID           Human owner ID (default: none)
      --help               Show this help
    
    EXAMPLES:
      # Basic agent
      ./scripts/add-agent.sh --id agent-coder --name "Code Specialist"
    
      # Full agent with personality
      ./scripts/add-agent.sh \
        --id agent-security \
        --name "Security Sentinel" \
        --role specialist \
        --designation "Security Operations" \
        --capabilities "security,audit,monitoring" \
        --about "I focus on security audits and threat detection." \
        --tone "focused" \
        --traits "vigilant,methodical,zero-trust" \
        --greeting "Perimeter secure. Report any anomalies." \
        --clearance ALPHA \
        --owner human-admin
    
      # Batch import multiple agents
      ./scripts/add-agent.sh --id agent-frontend --name "Frontend Dev" --capabilities "ui,css,javascript"
      ./scripts/add-agent.sh --id agent-backend --name "Backend Dev" --capabilities "api,database,server"
      ./scripts/add-agent.sh --id agent-tester --name "QA Tester" --role reviewer --capabilities "testing,qa,automation"
    EOF
        exit 0
    }
    
    # Defaults
    AGENT_ID=""
    AGENT_NAME=""
    ROLE="specialist"
    DESIGNATION="AI Agent"
    MODEL="claude-opus-4"
    CAPABILITIES="coding,review"
    ABOUT=""
    TONE="professional"
    TRAITS="analytical,collaborative,thorough"
    GREETING=""
    CLEARANCE="BETA"
    OWNER=""
    
    # Parse arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            --id) AGENT_ID="$2"; shift 2 ;;
            --name) AGENT_NAME="$2"; shift 2 ;;
            --role) ROLE="$2"; shift 2 ;;
            --designation) DESIGNATION="$2"; shift 2 ;;
            --model) MODEL="$2"; shift 2 ;;
            --capabilities) CAPABILITIES="$2"; shift 2 ;;
            --about) ABOUT="$2"; shift 2 ;;
            --tone) TONE="$2"; shift 2 ;;
            --traits) TRAITS="$2"; shift 2 ;;
            --greeting) GREETING="$2"; shift 2 ;;
            --clearance) CLEARANCE="$2"; shift 2 ;;
            --owner) OWNER="$2"; shift 2 ;;
            --help) show_help ;;
            *) echo "Unknown option: $1"; echo "Use --help for usage"; exit 1 ;;
        esac
    done
    
    # Validate required fields
    if [[ -z "$AGENT_ID" ]]; then
        echo "Error: --id is required"
        echo "Use --help for usage"
        exit 1
    fi
    
    if [[ -z "$AGENT_NAME" ]]; then
        echo "Error: --name is required"
        echo "Use --help for usage"
        exit 1
    fi
    
    # Ensure ID starts with agent-
    if [[ ! "$AGENT_ID" =~ ^agent- ]]; then
        AGENT_ID="agent-${AGENT_ID}"
    fi
    
    # Build capabilities JSON array
    IFS=',' read -ra CAP_ARRAY <<< "$CAPABILITIES"
    CAP_JSON=$(printf '"%s",' "${CAP_ARRAY[@]}")
    CAP_JSON="[${CAP_JSON%,}]"
    
    # Build traits JSON array
    IFS=',' read -ra TRAIT_ARRAY <<< "$TRAITS"
    TRAIT_JSON=$(printf '"%s",' "${TRAIT_ARRAY[@]}")
    TRAIT_JSON="[${TRAIT_JSON%,}]"
    
    # Set defaults for personality
    if [[ -z "$ABOUT" ]]; then
        ABOUT="$AGENT_NAME - a $ROLE agent specializing in ${CAPABILITIES//,/, }."
    fi
    if [[ -z "$GREETING" ]]; then
        GREETING="$AGENT_NAME online and ready."
    fi
    
    TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
    SEED=$(echo "$AGENT_ID" | sed 's/agent-//')
    AVATAR="https://api.dicebear.com/7.x/bottts-neutral/svg?seed=${SEED}"
    
    # Find repo root
    REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo ".")
    OUTPUT_FILE="${REPO_ROOT}/.mission-control/agents/${AGENT_ID}.json"
    
    # Check if agent already exists
    if [[ -f "$OUTPUT_FILE" ]]; then
        echo "Error: Agent ${AGENT_ID} already exists at ${OUTPUT_FILE}"
        echo "Delete it first if you want to re-register."
        exit 1
    fi
    
    # Build owner metadata
    OWNER_LINE=""
    if [[ -n "$OWNER" ]]; then
        OWNER_LINE="\"owner\": \"${OWNER}\","
    fi
    
    # Write agent file
    cat > "$OUTPUT_FILE" << EOF
    {
      "id": "${AGENT_ID}",
      "name": "${AGENT_NAME}",
      "type": "ai",
      "role": "${ROLE}",
      "designation": "${DESIGNATION}",
      "model": "${MODEL}",
      "avatar": "${AVATAR}",
      "status": "active",
      "parent_agent": null,
      "sub_agents": [],
      "capabilities": ${CAP_JSON},
      "personality": {
        "about": "${ABOUT}",
        "tone": "${TONE}",
        "traits": ${TRAIT_JSON},
        "greeting": "${GREETING}"
      },
      "channels": [],
      "registered_at": "${TIMESTAMP}",
      "last_active": "${TIMESTAMP}",
      "current_tasks": [],
      "completed_tasks": 0,
      "metadata": {
        "description": "${DESIGNATION}",
        ${OWNER_LINE}
        "clearance": "${CLEARANCE}"
      }
    }
    EOF
    
    echo "Agent registered: ${AGENT_ID}"
    echo "  Name: ${AGENT_NAME}"
    echo "  Role: ${ROLE}"
    echo "  File: ${OUTPUT_FILE}"
    echo ""
    echo "Next steps:"
    echo "  git add ${OUTPUT_FILE}"
    echo "  git commit -m \"[system] Registered agent: ${AGENT_NAME}\""
    echo "  git push"
    
  • scripts/add-human.sh2.7 KB47fe479754d4upstream ↗
    #!/bin/bash
    set -euo pipefail
    
    # add-human.sh - Register a human operator in Mission Control
    # Usage: ./scripts/add-human.sh --id human-name --name "Full Name" [options]
    
    show_help() {
        cat << 'EOF'
    Usage: ./scripts/add-human.sh [OPTIONS]
    
    Register a human operator in Mission Control.
    
    REQUIRED:
      --id ID              Human ID (e.g., human-john, human-admin)
      --name NAME          Display name (e.g., "John Doe")
    
    OPTIONAL:
      --role ROLE          Role: admin, reviewer, observer (default: admin)
      --designation TITLE  Title (default: "Project Owner")
      --email EMAIL        Email address
      --clearance LEVEL    Clearance: OMEGA, ALPHA, BETA (default: OMEGA)
      --help               Show this help
    
    EXAMPLES:
      ./scripts/add-human.sh --id human-john --name "John Doe" --email "[email protected]"
      ./scripts/add-human.sh --id human-reviewer --name "Jane Smith" --role reviewer
    EOF
        exit 0
    }
    
    # Defaults
    HUMAN_ID=""
    HUMAN_NAME=""
    ROLE="admin"
    DESIGNATION="Project Owner"
    EMAIL=""
    CLEARANCE="OMEGA"
    
    # Parse arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            --id) HUMAN_ID="$2"; shift 2 ;;
            --name) HUMAN_NAME="$2"; shift 2 ;;
            --role) ROLE="$2"; shift 2 ;;
            --designation) DESIGNATION="$2"; shift 2 ;;
            --email) EMAIL="$2"; shift 2 ;;
            --clearance) CLEARANCE="$2"; shift 2 ;;
            --help) show_help ;;
            *) echo "Unknown option: $1"; exit 1 ;;
        esac
    done
    
    if [[ -z "$HUMAN_ID" || -z "$HUMAN_NAME" ]]; then
        echo "Error: --id and --name are required"
        echo "Use --help for usage"
        exit 1
    fi
    
    # Ensure ID starts with human-
    if [[ ! "$HUMAN_ID" =~ ^human- ]]; then
        HUMAN_ID="human-${HUMAN_ID}"
    fi
    
    REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo ".")
    OUTPUT_FILE="${REPO_ROOT}/.mission-control/humans/${HUMAN_ID}.json"
    
    if [[ -f "$OUTPUT_FILE" ]]; then
        echo "Error: Human ${HUMAN_ID} already exists at ${OUTPUT_FILE}"
        exit 1
    fi
    
    SEED=$(echo "$HUMAN_ID" | sed 's/human-//')
    AVATAR="https://api.dicebear.com/7.x/avataaars/svg?seed=${SEED}"
    
    EMAIL_LINE=""
    if [[ -n "$EMAIL" ]]; then
        EMAIL_LINE="\"email\": \"${EMAIL}\","
    fi
    
    cat > "$OUTPUT_FILE" << EOF
    {
      "id": "${HUMAN_ID}",
      "name": "${HUMAN_NAME}",
      "type": "human",
      "role": "${ROLE}",
      "designation": "${DESIGNATION}",
      ${EMAIL_LINE}
      "avatar": "${AVATAR}",
      "status": "online",
      "capabilities": ["all", "override", "approve"],
      "channels": [],
      "metadata": {
        "clearance": "${CLEARANCE}",
        "timezone": "UTC"
      }
    }
    EOF
    
    echo "Human registered: ${HUMAN_ID}"
    echo "  Name: ${HUMAN_NAME}"
    echo "  Role: ${ROLE}"
    echo "  File: ${OUTPUT_FILE}"
    echo ""
    echo "Next steps:"
    echo "  git add ${OUTPUT_FILE}"
    echo "  git commit -m \"[system] Registered human: ${HUMAN_NAME}\""
    echo "  git push"
    
  • scripts/check-updates.sh2.0 KBa87de633f264upstream ↗
    #!/bin/bash
    # check-updates.sh - Check for Mission Control updates via MissionDeck API
    #
    # Usage: ./scripts/check-updates.sh
    #
    # Requires: MISSIONDECK_API_KEY environment variable or config.json
    
    set -e
    
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    MC_ROOT="$(dirname "$SCRIPT_DIR")"
    
    # Get API key from env or config
    API_KEY="${MISSIONDECK_API_KEY:-}"
    if [ -z "$API_KEY" ] && [ -f "$MC_ROOT/.mission-control/config.json" ]; then
      API_KEY=$(grep -o '"apiKey"[[:space:]]*:[[:space:]]*"[^"]*"' "$MC_ROOT/.mission-control/config.json" 2>/dev/null | head -1 | cut -d'"' -f4)
    fi
    
    if [ -z "$API_KEY" ]; then
      echo "ℹ️  No MissionDeck API key configured"
      echo "   Set MISSIONDECK_API_KEY or add to .mission-control/config.json"
      exit 0
    fi
    
    # Get current version
    CURRENT_VERSION="0.0.0"
    if [ -f "$MC_ROOT/VERSION" ]; then
      CURRENT_VERSION=$(cat "$MC_ROOT/VERSION")
    elif [ -f "$MC_ROOT/CHANGELOG.md" ]; then
      CURRENT_VERSION=$(grep -o '\*\*[0-9]*\.[0-9]*\.[0-9]*\*\*' "$MC_ROOT/CHANGELOG.md" | head -1 | tr -d '*')
    fi
    
    # Check latest version
    API_URL="${MISSIONDECK_API_BASE:-https://missiondeck.ai/api/distribution}/version"
    
    echo "🔍 Checking for updates..."
    echo "   Current version: $CURRENT_VERSION"
    
    RESPONSE=$(curl -s -H "x-api-key: $API_KEY" "$API_URL" 2>/dev/null || echo '{"error":"failed"}')
    
    if echo "$RESPONSE" | grep -q '"error"'; then
      echo "❌ Failed to check for updates"
      echo "   Response: $RESPONSE"
      exit 1
    fi
    
    LATEST=$(echo "$RESPONSE" | grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4)
    
    if [ -z "$LATEST" ]; then
      echo "❌ Could not parse version from response"
      exit 1
    fi
    
    echo "   Latest version:  $LATEST"
    
    if [ "$LATEST" != "$CURRENT_VERSION" ]; then
      echo ""
      echo "🚀 New version available: $LATEST"
      echo ""
      echo "To update, run:"
      echo "  ./scripts/update-mission-control.sh"
      echo ""
      echo "Or download manually:"
      echo "  curl -H \"x-api-key: \$MISSIONDECK_API_KEY\" \\"
      echo "    $API_URL/../download/latest -o mission-control.zip"
    else
      echo ""
      echo "✅ Mission Control is up to date!"
    fi
    
  • scripts/connect-missiondeck.sh8.5 KBdbe238eb8476upstream ↗
    #!/usr/bin/env bash
    # =============================================================
    # MissionDeck Cloud Connect
    # Connects your local JARVIS Mission Control to MissionDeck.ai
    # so your dashboard is live at missiondeck.ai/mission-control/[slug]
    # =============================================================
    
    set -euo pipefail
    
    GREEN='\033[0;32m'
    CYAN='\033[0;36m'
    YELLOW='\033[1;33m'
    RED='\033[0;31m'
    BOLD='\033[1m'
    NC='\033[0m'
    
    MISSIONDECK_URL="${MISSIONDECK_URL:-https://missiondeck.ai}"
    # API base: Supabase direct URL (works now). Override once missiondeck.ai proxy is configured.
    MISSIONDECK_API_URL="${MISSIONDECK_API_URL:-https://sqykgceibcmnmgfuioso.supabase.co/functions/v1}"
    MC_DIR="$(cd "$(dirname "$0")/.." && pwd)"
    CONFIG_FILE="$MC_DIR/.mission-control/config.yaml"
    
    echo ""
    echo -e "${CYAN}${BOLD}☁️  MissionDeck Cloud Connect${NC}"
    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo ""
    
    # ── Cloud API status check ─────────────────────────────────────────
    echo -e "${YELLOW}Checking cloud API availability...${NC}"
    STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
      --max-time 8 \
      "$MISSIONDECK_API_URL/mc-api/verify" 2>/dev/null || echo "000")
    
    CLOUD_AVAILABLE=false
    if [ "$STATUS_CODE" = "200" ] || [ "$STATUS_CODE" = "401" ]; then
      CLOUD_AVAILABLE=true
      echo -e "  ${GREEN}✅ Cloud API is available${NC}"
    elif [ "$STATUS_CODE" = "405" ] || [ "$STATUS_CODE" = "404" ] || [ "$STATUS_CODE" = "000" ]; then
      echo -e "  ${YELLOW}⚠️  Cloud sync API not yet deployed (HTTP $STATUS_CODE)${NC}"
      echo ""
      echo -e "  ${BOLD}What this means:${NC}"
      echo -e "  • Your local Mission Control works perfectly (http://localhost:3000)"
      echo -e "  • Cloud sync to missiondeck.ai is not yet available"
      echo -e "  • Your config will be saved — sync will activate when the API goes live"
      echo ""
      echo -e "  ${BOLD}What to do now:${NC}"
      echo -e "  • Re-run this script when cloud sync is announced at missiondeck.ai"
      echo -e "  • For remote access today, see: skills/deployment.md"
      echo -e "  • Your local board at http://localhost:3000 is fully functional"
      echo ""
      read -rp "  Save local config anyway and continue? [y/N]: " CONTINUE
      if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then
        echo -e "${YELLOW}Exiting. Local setup is fully functional without this step.${NC}"
        exit 0
      fi
    else
      echo -e "  ${YELLOW}⚠️  Unexpected HTTP $STATUS_CODE — proceeding anyway${NC}"
    fi
    
    echo ""
    echo "Your cloud dashboard URL (once API is live):"
    echo -e "  ${BOLD}missiondeck.ai/mission-control/your-slug${NC}"
    echo ""
    
    # ── Step 1: Get API key ────────────────────────────────────────────
    echo -e "${YELLOW}Step 1${NC} — Enter your API key"
    echo ""
    echo "  Get a free key at: ${BOLD}${MISSIONDECK_URL}/settings/api-keys${NC}"
    echo ""
    if [ -t 0 ]; then
      read -rsp "  Paste API key (or press Enter to skip): " API_KEY
      echo ""
    else
      API_KEY="${MISSIONDECK_API_KEY:-}"
    fi
    
    if [ -z "$API_KEY" ]; then
      echo -e "  ${YELLOW}ℹ️  No key provided — saving placeholder config${NC}"
      API_KEY="REPLACE_WITH_YOUR_KEY"
    fi
    
    # ── Step 2: Workspace slug ─────────────────────────────────────────
    WORKSPACE_SLUG=""
    
    if [ "$CLOUD_AVAILABLE" = true ] && [ "$API_KEY" != "REPLACE_WITH_YOUR_KEY" ]; then
      echo ""
      echo -e "${YELLOW}Step 2${NC} — Verifying key..."
    
      HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 8 \
        -H "Authorization: Bearer $API_KEY" \
        "$MISSIONDECK_API_URL/mc-api/verify" 2>/dev/null || echo "000")
    
      if [ "$HTTP_CODE" = "200" ]; then
        VERIFY_BODY=$(curl -s --max-time 8 \
          -H "Authorization: Bearer $API_KEY" \
          "$MISSIONDECK_API_URL/mc-api/verify" 2>/dev/null || echo "{}")
        WORKSPACE_SLUG=$(echo "$VERIFY_BODY" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('slug',''))" 2>/dev/null || echo "")
        [ -n "$WORKSPACE_SLUG" ] && echo -e "  ${GREEN}✅ Verified — workspace: ${BOLD}$WORKSPACE_SLUG${NC}"
      fi
    fi
    
    if [ -z "$WORKSPACE_SLUG" ]; then
      echo ""
      echo -e "${YELLOW}Step 2${NC} — Workspace slug"
      read -rp "  Enter your username/slug (default: my-workspace): " WORKSPACE_SLUG
      WORKSPACE_SLUG="${WORKSPACE_SLUG:-my-workspace}"
    fi
    
    DASHBOARD_URL="$MISSIONDECK_URL/mission-control/$WORKSPACE_SLUG"
    
    # ── Step 3: Save config ────────────────────────────────────────────
    echo ""
    echo -e "${YELLOW}Step 3${NC} — Saving configuration..."
    
    mkdir -p "$MC_DIR/.mission-control"
    
    if [ -f "$CONFIG_FILE" ]; then
      grep -v "^missiondeck_" "$CONFIG_FILE" > "${CONFIG_FILE}.tmp" 2>/dev/null || true
      mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
    fi
    
    printf '\n# MissionDeck Cloud (added by connect-missiondeck.sh)\nmissiondeck_enabled: true\nmissiondeck_slug: %s\nmissiondeck_url: %s\n' \
      "$WORKSPACE_SLUG" "$MISSIONDECK_URL" >> "$CONFIG_FILE"
    
    printf 'MISSIONDECK_API_KEY=%s\nMISSIONDECK_URL=%s\nMISSIONDECK_SLUG=%s\nMISSIONDECK_API_URL=%s\n' \
      "$API_KEY" "$MISSIONDECK_URL" "$WORKSPACE_SLUG" "$MISSIONDECK_API_URL" > "$MC_DIR/.missiondeck"
    chmod 600 "$MC_DIR/.missiondeck"
    
    echo -e "  ${GREEN}✅ Config saved to .missiondeck${NC}"
    
    # ── Step 4: Sync (only if cloud available) ────────────────────────
    if [ "$CLOUD_AVAILABLE" = true ] && [ "$API_KEY" != "REPLACE_WITH_YOUR_KEY" ]; then
      echo ""
      echo -e "${YELLOW}Step 4${NC} — Syncing tasks to cloud..."
    
      TASKS_DIR="$MC_DIR/.mission-control/tasks"
      TASK_COUNT=0
      [ -d "$TASKS_DIR" ] && TASK_COUNT=$(ls "$TASKS_DIR"/*.json 2>/dev/null | wc -l | tr -d ' ') || true
    
      if [ "$TASK_COUNT" -gt 0 ]; then
        PAYLOAD=$(python3 -c "
    import json, os, glob
    tasks = []
    for f in glob.glob('$TASKS_DIR/*.json'):
        try:
            tasks.append(json.load(open(f)))
        except: pass
    print(json.dumps({'tasks': tasks, 'agents': [], 'deleted_ids': [], 'client_version': '2.1.0'}))
    ")
    
        SYNC_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 15 \
          -X POST \
          -H "Authorization: Bearer $API_KEY" \
          -H "Content-Type: application/json" \
          -d "$PAYLOAD" \
          "$MISSIONDECK_API_URL/mc-sync" 2>/dev/null || echo "000")
    
        if [ "$SYNC_CODE" = "200" ]; then
          echo -e "  ${GREEN}✅ $TASK_COUNT tasks synced${NC}"
        else
          echo -e "  ${YELLOW}⚠️  Sync returned HTTP $SYNC_CODE — will retry on server start${NC}"
        fi
      else
        echo -e "  ${YELLOW}ℹ️  No tasks yet — will sync automatically when you create tasks${NC}"
      fi
    else
      echo ""
      echo -e "  ${YELLOW}ℹ️  Skipping sync — cloud API not available${NC}"
      echo -e "  Tasks are safe locally. Sync activates when the API goes live."
    fi
    
    # ── Step 5: Restart server ─────────────────────────────────────────
    echo ""
    echo -e "${YELLOW}Step 5${NC} — Server restart..."
    
    if pm2 list 2>/dev/null | grep -q "mission-control-server"; then
      pm2 restart mission-control-server --update-env 2>/dev/null && \
        echo -e "  ${GREEN}✅ Server restarted${NC}" || \
        echo -e "  ${YELLOW}⚠️  Restart manually: pm2 restart mission-control-server --update-env${NC}"
    else
      echo -e "  ${YELLOW}ℹ️  Restart server to pick up new config:${NC}"
      echo -e "  source .missiondeck && node server/index.js"
    fi
    
    # ── Done ────────────────────────────────────────────────────────────
    echo ""
    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo ""
    if [ "$CLOUD_AVAILABLE" = true ]; then
      echo -e "${GREEN}${BOLD}✅ MissionDeck Cloud connected!${NC}"
      echo -e "  🌐 Dashboard: ${BOLD}$DASHBOARD_URL${NC}"
      echo -e "  🔄 Auto-sync: Active"
    else
      echo -e "${YELLOW}${BOLD}Config saved — cloud sync coming soon${NC}"
      echo -e "  🖥️  Local dashboard: ${BOLD}http://localhost:3000${NC}  ← Works now"
      echo -e "  ☁️  Cloud dashboard: ${BOLD}$DASHBOARD_URL${NC}  ← Available when API goes live"
      echo -e ""
      echo -e "  Re-run this script when MissionDeck cloud sync is announced."
      echo -e "  For remote access now: see skills/deployment.md"
    fi
    echo ""
    
  • scripts/create-github-issue.sh3.8 KBc93443c19570upstream ↗
    #!/bin/bash
    # Create GitHub Issue for Auto-Task Spam Bug
    # Usage: GITHUB_TOKEN=ghp_xxx ./scripts/create-github-issue.sh
    
    set -e
    
    REPO="Asif2BD/JARVIS-Mission-Control-OpenClaw"
    TITLE="[BUG] Agent Bridge auto-creates junk tasks for every spawn"
    LABELS="bug,agent-bridge,cleanup"
    ASSIGNEES="morpheus"
    
    BODY=$(cat <<'EOF'
    ## Problem Description
    
    The Agent Bridge is configured to automatically create a Mission Control task for **every agent spawn** via `sessions_spawn`, resulting in dashboard clutter with meaningless tasks like:
    
    - "Agent session started" (24+ duplicate instances)
    - Generic session tasks with no context
    - Real work buried under auto-generated noise
    
    ## Root Cause
    
    **File:** `server/agent-bridge.js`  
    **Function:** `processNewSession()`
    
    The bridge creates a task whenever it detects a spawned subagent session.
    
    **Config:** `.mission-control/config.yaml`
    ```yaml
    openclaw:
      hooks:
        on_agent_start:
          - action: create_task
            template: "agent_session"
    ```
    
    This creates noise for casual agent conversations, quick questions, and internal coordination.
    
    ## Current Workaround
    
    **Environment variable override:**
    ```bash
    AUTO_CREATE_TASKS=false node start-all.js
    ```
    
    **Changes applied:**
    - Added `AUTO_CREATE_TASKS` check in `agent-bridge.js`
    - Archived 24 junk tasks to `archived-tasks/`
    - Updated `config.yaml` with policy documentation
    
    ## Proposed Solution
    
    **Option 1: Make Auto-Create Configurable (Recommended)**
    
    Add to `config.yaml`:
    ```yaml
    openclaw:
      auto_create_tasks:
        enabled: false  # Default off
        rules:
          - spawn_label_contains: "task:"
          - prompt_starts_with: "Task ID:"
    ```
    
    **Option 2: Require Explicit Task Linking**
    
    - Spawns with `Task ID: task-xyz` → link to existing task
    - Spawns without reference → no task created
    - Forces deliberate task management
    
    ## Expected Behavior
    
    **For meaningful work:**
    1. Create task JSON explicitly
    2. Spawn with reference: `sessions_spawn("tank", "Task ID: task-xyz...")`
    3. Bridge links session → updates task status
    4. No duplicate created
    
    **For casual work:**
    1. Spawn without reference
    2. Bridge logs session only (no task)
    3. Dashboard stays clean
    
    ## Impact
    
    - UX: Dashboard cluttered
    - Maintenance: Manual cleanup needed
    - Trust: Users lose confidence in tracking
    
    ## Acceptance Criteria
    
    - [ ] `config.yaml` controls auto-task behavior
    - [ ] Default: `auto_create_tasks: false`
    - [ ] Bridge respects config
    - [ ] Docs updated (`AGENT-BRIDGE.md`, `CLAUDE.md`)
    - [ ] Tests for both modes
    - [ ] Migration guide
    
    **Related:**
    - `docs/AGENT-BRIDGE-CLEANUP-LOG.md` (previous cleanup 2026-02-05)
    - `MISSION_CONTROL_PROTOCOL.md` (workflow documentation)
    
    **Discovered:** 2026-02-06 by Tank (user report)  
    **Affected versions:** v0.8.0+
    
    **Assignee recommendation:** Morpheus (code review specialist)
    EOF
    )
    
    if [ -z "$GITHUB_TOKEN" ]; then
        echo "Error: GITHUB_TOKEN environment variable not set"
        echo ""
        echo "To create the issue, run:"
        echo "  export GITHUB_TOKEN=ghp_your_token_here"
        echo "  ./scripts/create-github-issue.sh"
        echo ""
        echo "Or create manually at:"
        echo "  https://github.com/$REPO/issues/new"
        echo ""
        echo "Title: $TITLE"
        echo "Labels: $LABELS"
        echo "Body: (see below)"
        echo ""
        echo "$BODY"
        exit 1
    fi
    
    echo "Creating GitHub issue..."
    
    RESPONSE=$(curl -s -X POST \
        -H "Authorization: token $GITHUB_TOKEN" \
        -H "Accept: application/vnd.github.v3+json" \
        "https://api.github.com/repos/$REPO/issues" \
        -d @- <<JSON_PAYLOAD
    {
      "title": "$TITLE",
      "body": $(echo "$BODY" | jq -Rs .),
      "labels": ["bug", "agent-bridge", "cleanup"],
      "assignees": []
    }
    JSON_PAYLOAD
    )
    
    ISSUE_URL=$(echo "$RESPONSE" | grep -o '"html_url": "[^"]*' | cut -d'"' -f4)
    
    if [ -n "$ISSUE_URL" ]; then
        echo "✅ Issue created: $ISSUE_URL"
    else
        echo "❌ Failed to create issue"
        echo "$RESPONSE"
        exit 1
    fi
    
  • scripts/create-task.js4.4 KBb3e85552869eupstream ↗
    #!/usr/bin/env node
    /**
     * Create Task CLI - Mission Control
     * 
     * Creates meaningful tasks from command line or programmatically.
     * Usage:
     *   node create-task.js "Task Title" "Description" --assignee oracle --priority high --labels "feature,important"
     *   
     * Or via API:
     *   curl -X POST http://localhost:3000/api/tasks -H "Content-Type: application/json" \
     *     -d '{"title":"Task Title","description":"Description","assignee":"oracle"}'
     */
    
    const fs = require('fs').promises;
    const path = require('path');
    
    const MISSION_CONTROL_DIR = path.join(__dirname, '..', '.mission-control');
    const TASKS_DIR = path.join(MISSION_CONTROL_DIR, 'tasks');
    
    /**
     * Generate a task ID
     */
    function generateTaskId() {
        const date = new Date().toISOString().split('T')[0].replace(/-/g, '');
        const rand = Math.random().toString(36).substring(2, 8);
        return `task-${date}-${rand}`;
    }
    
    /**
     * Create a new task
     */
    async function createTask(options) {
        const {
            title,
            description,
            assignee = null,
            priority = 'medium',
            labels = [],
            status = 'INBOX',
            created_by = 'system'
        } = options;
    
        if (!title) {
            throw new Error('Task title is required');
        }
    
        const task = {
            id: generateTaskId(),
            title,
            description: description || '',
            status,
            priority,
            assignee,
            created_by,
            labels: Array.isArray(labels) ? labels : labels.split(',').map(l => l.trim()).filter(Boolean),
            comments: [],
            attachments: [],
            created_at: new Date().toISOString(),
            updated_at: new Date().toISOString()
        };
    
        // Ensure directory exists
        await fs.mkdir(TASKS_DIR, { recursive: true });
    
        // Write task file
        const filePath = path.join(TASKS_DIR, `${task.id}.json`);
        await fs.writeFile(filePath, JSON.stringify(task, null, 2));
    
        console.log(`✅ Task created: ${task.id}`);
        console.log(`   Title: ${task.title}`);
        console.log(`   Priority: ${task.priority}`);
        console.log(`   Assignee: ${task.assignee || 'Unassigned'}`);
        console.log(`   File: ${filePath}`);
    
        return task;
    }
    
    /**
     * Parse command line arguments
     */
    function parseArgs(args) {
        const options = {
            title: null,
            description: null,
            assignee: null,
            priority: 'medium',
            labels: [],
            status: 'INBOX',
            created_by: 'cli'
        };
    
        let i = 0;
        while (i < args.length) {
            const arg = args[i];
    
            if (arg === '--assignee' || arg === '-a') {
                options.assignee = args[++i];
            } else if (arg === '--priority' || arg === '-p') {
                options.priority = args[++i];
            } else if (arg === '--labels' || arg === '-l') {
                options.labels = args[++i].split(',').map(l => l.trim());
            } else if (arg === '--status' || arg === '-s') {
                options.status = args[++i];
            } else if (arg === '--created-by' || arg === '-c') {
                options.created_by = args[++i];
            } else if (arg === '--help' || arg === '-h') {
                console.log(`
    Usage: node create-task.js "Title" "Description" [options]
    
    Options:
      -a, --assignee    Agent ID to assign (e.g., oracle, tank, morpheus)
      -p, --priority    Priority level (low, medium, high, critical)
      -l, --labels      Comma-separated labels
      -s, --status      Initial status (INBOX, ASSIGNED, IN_PROGRESS, REVIEW, DONE)
      -c, --created-by  Creator identifier
      -h, --help        Show this help
    
    Examples:
      node create-task.js "Setup Piper TTS" "Install and configure local TTS system" -a oracle -p high
      node create-task.js "Review PR #42" "Review dashboard fixes" -a tank -l "review,code" -p medium
    `);
                process.exit(0);
            } else if (!options.title) {
                options.title = arg;
            } else if (!options.description) {
                options.description = arg;
            }
            i++;
        }
    
        return options;
    }
    
    // Run if called directly
    if (require.main === module) {
        const args = process.argv.slice(2);
        
        if (args.length === 0) {
            console.error('Error: Task title required. Use --help for usage.');
            process.exit(1);
        }
    
        const options = parseArgs(args);
        
        createTask(options)
            .then(() => process.exit(0))
            .catch(err => {
                console.error('Error:', err.message);
                process.exit(1);
            });
    }
    
    module.exports = { createTask, generateTaskId };
    
  • scripts/create-task.sh5.6 KB71b9b0b1d2f3upstream ↗
    #!/bin/bash
    #
    # JARVIS Mission Control - Create Task Script
    # Creates a new task file in .mission-control/tasks/
    #
    # Usage: ./scripts/create-task.sh "Task Title" [options]
    #
    # Options:
    #   --priority <level>    Set priority (critical, high, medium, low)
    #   --labels <labels>     Comma-separated labels
    #   --assignee <id>       Assign to agent/human
    #   --description <text>  Task description (or read from stdin)
    #   --dry-run            Show task JSON without creating file
    #
    
    set -euo pipefail
    
    # Configuration
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
    TASKS_DIR="$PROJECT_ROOT/.mission-control/tasks"
    
    # Defaults
    PRIORITY="medium"
    LABELS=""
    ASSIGNEE=""
    DESCRIPTION=""
    DRY_RUN=false
    CREATED_BY="${MC_AGENT_ID:-human-user}"
    
    # Colors
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    NC='\033[0m' # No Color
    
    # Functions
    usage() {
        cat << EOF
    Usage: $(basename "$0") "Task Title" [options]
    
    Options:
      --priority <level>     Set priority (critical, high, medium, low)
      --labels <labels>      Comma-separated labels
      --assignee <id>        Assign to agent/human (e.g., agent-jarvis)
      --description <text>   Task description
      --dry-run              Show task JSON without creating file
      -h, --help             Show this help message
    
    Examples:
      $(basename "$0") "Implement login feature" --priority high --labels feature,backend
      $(basename "$0") "Fix bug #123" --assignee agent-backend-specialist
      echo "Detailed description" | $(basename "$0") "Task Title" --description -
    EOF
    }
    
    error() {
        echo -e "${RED}Error: $1${NC}" >&2
        exit 1
    }
    
    info() {
        echo -e "${GREEN}$1${NC}"
    }
    
    warn() {
        echo -e "${YELLOW}$1${NC}"
    }
    
    # Generate task ID
    generate_id() {
        local date_part=$(date +%Y%m%d)
        local title_slug=$(echo "$1" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | tr -cd 'a-z0-9-' | head -c 30)
        echo "task-${date_part}-${title_slug}"
    }
    
    # Parse labels into JSON array
    parse_labels() {
        local labels="$1"
        if [ -z "$labels" ]; then
            echo "[]"
            return
        fi
    
        local json="["
        local first=true
        IFS=',' read -ra LABEL_ARRAY <<< "$labels"
        for label in "${LABEL_ARRAY[@]}"; do
            label=$(echo "$label" | xargs)  # trim whitespace
            if [ "$first" = true ]; then
                first=false
            else
                json+=","
            fi
            json+="\"$label\""
        done
        json+="]"
        echo "$json"
    }
    
    # Generate task JSON
    generate_task_json() {
        local id="$1"
        local title="$2"
        local description="$3"
        local priority="$4"
        local labels_json="$5"
        local assignee="$6"
        local created_by="$7"
        local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    
        local assignee_json="null"
        if [ -n "$assignee" ]; then
            assignee_json="\"$assignee\""
        fi
    
        local status="INBOX"
        if [ -n "$assignee" ]; then
            status="ASSIGNED"
        fi
    
        cat << EOF
    {
      "id": "$id",
      "title": "$title",
      "description": "$description",
      "status": "$status",
      "priority": "$priority",
      "assignee": $assignee_json,
      "created_by": "$created_by",
      "created_at": "$timestamp",
      "updated_at": "$timestamp",
      "due_date": null,
      "labels": $labels_json,
      "estimated_hours": null,
      "actual_hours": null,
      "comments": [
        {
          "id": "comment-001",
          "author": "$created_by",
          "content": "Task created via create-task.sh",
          "timestamp": "$timestamp",
          "type": "system"
        }
      ],
      "deliverables": [],
      "dependencies": [],
      "blocked_by": [],
      "workflow_id": null,
      "metadata": {}
    }
    EOF
    }
    
    # Parse arguments
    if [ $# -lt 1 ]; then
        usage
        exit 1
    fi
    
    TITLE=""
    
    while [ $# -gt 0 ]; do
        case "$1" in
            -h|--help)
                usage
                exit 0
                ;;
            --priority)
                shift
                PRIORITY="$1"
                if [[ ! "$PRIORITY" =~ ^(critical|high|medium|low)$ ]]; then
                    error "Invalid priority: $PRIORITY (must be critical, high, medium, or low)"
                fi
                ;;
            --labels)
                shift
                LABELS="$1"
                ;;
            --assignee)
                shift
                ASSIGNEE="$1"
                ;;
            --description)
                shift
                if [ "$1" = "-" ]; then
                    DESCRIPTION=$(cat)
                else
                    DESCRIPTION="$1"
                fi
                ;;
            --dry-run)
                DRY_RUN=true
                ;;
            -*)
                error "Unknown option: $1"
                ;;
            *)
                if [ -z "$TITLE" ]; then
                    TITLE="$1"
                else
                    error "Unexpected argument: $1"
                fi
                ;;
        esac
        shift
    done
    
    # Validate
    if [ -z "$TITLE" ]; then
        error "Task title is required"
    fi
    
    # Use title as description if not provided
    if [ -z "$DESCRIPTION" ]; then
        DESCRIPTION="$TITLE"
    fi
    
    # Generate task
    TASK_ID=$(generate_id "$TITLE")
    LABELS_JSON=$(parse_labels "$LABELS")
    TASK_JSON=$(generate_task_json "$TASK_ID" "$TITLE" "$DESCRIPTION" "$PRIORITY" "$LABELS_JSON" "$ASSIGNEE" "$CREATED_BY")
    
    # Output
    if [ "$DRY_RUN" = true ]; then
        warn "Dry run - task not created"
        echo ""
        echo "Task ID: $TASK_ID"
        echo "File: $TASKS_DIR/$TASK_ID.json"
        echo ""
        echo "$TASK_JSON"
        exit 0
    fi
    
    # Ensure tasks directory exists
    mkdir -p "$TASKS_DIR"
    
    # Write task file
    TASK_FILE="$TASKS_DIR/$TASK_ID.json"
    echo "$TASK_JSON" > "$TASK_FILE"
    
    info "Task created successfully!"
    echo ""
    echo "ID:   $TASK_ID"
    echo "File: $TASK_FILE"
    echo ""
    echo "Next steps:"
    echo "  1. Review the task: cat $TASK_FILE"
    echo "  2. Commit: git add $TASK_FILE && git commit -m '[$CREATED_BY] Created task: $TITLE'"
    echo "  3. Push: git push"
    
  • scripts/init-mission-control.sh9.6 KB8a78c517ab8bupstream ↗
    #!/bin/bash
    #
    # init-mission-control.sh - Initialize Mission Control for production or demo mode
    #
    # Usage:
    #   ./scripts/init-mission-control.sh              # Interactive mode
    #   ./scripts/init-mission-control.sh --production # Skip demo, clean setup
    #   ./scripts/init-mission-control.sh --demo       # Load demo data
    #   ./scripts/init-mission-control.sh --help       # Show help
    #
    # This script properly separates demo data from production deployments.
    #
    
    set -e
    
    # Colors for output
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    BLUE='\033[0;34m'
    CYAN='\033[0;36m'
    NC='\033[0m' # No Color
    BOLD='\033[1m'
    
    # Get script directory and repo root
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    REPO_ROOT="$(dirname "$SCRIPT_DIR")"
    MC_DIR="$REPO_ROOT/.mission-control"
    DEMO_DATA_DIR="$REPO_ROOT/examples/demo-data"
    DEMO_FLAG="$MC_DIR/.demo-loaded"
    INIT_FLAG="$MC_DIR/.initialized"
    
    # Print banner
    print_banner() {
        echo -e "${CYAN}"
        echo "╔═══════════════════════════════════════════════════════════════╗"
        echo "║           JARVIS Mission Control - Initialization             ║"
        echo "╚═══════════════════════════════════════════════════════════════╝"
        echo -e "${NC}"
    }
    
    # Print help
    print_help() {
        echo "Usage: $0 [OPTIONS]"
        echo ""
        echo "Options:"
        echo "  --production    Initialize for production (no demo data)"
        echo "  --demo          Initialize with demo data (Matrix-themed examples)"
        echo "  --force         Force re-initialization (overwrite existing)"
        echo "  --help          Show this help message"
        echo ""
        echo "Without options, runs in interactive mode."
        echo ""
        echo "Examples:"
        echo "  $0                  # Interactive mode"
        echo "  $0 --production     # Clean production setup"
        echo "  $0 --demo           # Load demo data for testing"
        echo "  $0 --production --force  # Re-initialize (destructive)"
    }
    
    # Check if already initialized
    check_existing() {
        if [[ -f "$INIT_FLAG" ]]; then
            echo -e "${YELLOW}⚠️  Mission Control is already initialized.${NC}"
            
            if [[ -f "$DEMO_FLAG" ]]; then
                echo -e "   Mode: ${CYAN}Demo${NC} (Matrix-themed examples loaded)"
            else
                echo -e "   Mode: ${GREEN}Production${NC}"
            fi
            
            echo ""
            
            if [[ "$FORCE" != "true" ]]; then
                echo -e "${YELLOW}To re-initialize, run with --force flag.${NC}"
                echo -e "${RED}WARNING: --force will DELETE all existing tasks, agents, and messages!${NC}"
                exit 0
            else
                echo -e "${RED}--force flag detected. Proceeding with re-initialization...${NC}"
                echo ""
            fi
        fi
    }
    
    # Count existing data
    count_existing_data() {
        local tasks=$(find "$MC_DIR/tasks" -name "*.json" 2>/dev/null | wc -l)
        local agents=$(find "$MC_DIR/agents" -name "*.json" 2>/dev/null | wc -l)
        local messages=$(find "$MC_DIR/messages" -name "*.json" 2>/dev/null | wc -l)
        local humans=$(find "$MC_DIR/humans" -name "*.json" 2>/dev/null | wc -l)
        
        echo "$tasks tasks, $agents agents, $humans humans, $messages messages"
    }
    
    # Clear all data directories (for production or re-init)
    clear_data() {
        echo -e "${YELLOW}Clearing existing data...${NC}"
        
        # Remove JSON files from data directories
        rm -f "$MC_DIR/tasks/"*.json 2>/dev/null || true
        rm -f "$MC_DIR/agents/"*.json 2>/dev/null || true
        rm -f "$MC_DIR/messages/"*.json 2>/dev/null || true
        rm -f "$MC_DIR/humans/"*.json 2>/dev/null || true
        rm -f "$MC_DIR/queue/"*.json 2>/dev/null || true
        rm -f "$MC_DIR/workflows/"*.json 2>/dev/null || true
        
        # Clear logs
        rm -f "$MC_DIR/logs/"*.log 2>/dev/null || true
        
        # Remove flags
        rm -f "$DEMO_FLAG" 2>/dev/null || true
        rm -f "$INIT_FLAG" 2>/dev/null || true
        
        echo -e "${GREEN}✓ Data cleared${NC}"
    }
    
    # Load demo data
    load_demo_data() {
        echo -e "${CYAN}Loading demo data (Matrix-themed examples)...${NC}"
        
        # Copy demo data to .mission-control
        if [[ -d "$DEMO_DATA_DIR/agents" ]]; then
            cp "$DEMO_DATA_DIR/agents/"*.json "$MC_DIR/agents/" 2>/dev/null || true
            echo -e "  ${GREEN}✓${NC} Agents loaded"
        fi
        
        if [[ -d "$DEMO_DATA_DIR/humans" ]]; then
            cp "$DEMO_DATA_DIR/humans/"*.json "$MC_DIR/humans/" 2>/dev/null || true
            echo -e "  ${GREEN}✓${NC} Humans loaded"
        fi
        
        if [[ -d "$DEMO_DATA_DIR/tasks" ]]; then
            cp "$DEMO_DATA_DIR/tasks/"*.json "$MC_DIR/tasks/" 2>/dev/null || true
            echo -e "  ${GREEN}✓${NC} Tasks loaded"
        fi
        
        if [[ -d "$DEMO_DATA_DIR/messages" ]]; then
            cp "$DEMO_DATA_DIR/messages/"*.json "$MC_DIR/messages/" 2>/dev/null || true
            echo -e "  ${GREEN}✓${NC} Messages loaded"
        fi
        
        # Create demo flag
        echo "Loaded: $(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$DEMO_FLAG"
        
        echo -e "${GREEN}✓ Demo data loaded successfully${NC}"
    }
    
    # Initialize for production (clean state)
    init_production() {
        echo -e "${GREEN}Initializing for production (clean state)...${NC}"
        
        # Create welcome task
        local timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
        local date_prefix=$(date +%Y%m%d)
        
        cat > "$MC_DIR/tasks/task-${date_prefix}-welcome.json" << EOF
    {
      "id": "task-${date_prefix}-welcome",
      "title": "Welcome to Mission Control",
      "description": "Your Mission Control is ready for production use!\\n\\nNext steps:\\n1. Register your human operator: ./scripts/add-human.sh\\n2. Register your agent: ./scripts/add-agent.sh\\n3. Create your first task: ./scripts/create-task.sh\\n\\nSee CLAUDE.md for complete documentation.",
      "status": "INBOX",
      "priority": "high",
      "assignee": null,
      "created_by": "system",
      "created_at": "${timestamp}",
      "updated_at": "${timestamp}",
      "labels": ["setup", "getting-started"],
      "comments": [],
      "deliverables": [],
      "dependencies": [],
      "blocked_by": []
    }
    EOF
        
        echo -e "  ${GREEN}✓${NC} Welcome task created"
        echo -e "${GREEN}✓ Production initialization complete${NC}"
    }
    
    # Create initialization flag
    mark_initialized() {
        local mode=$1
        local timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
        
        cat > "$INIT_FLAG" << EOF
    # Mission Control Initialized
    mode: ${mode}
    initialized_at: ${timestamp}
    initialized_by: init-mission-control.sh
    EOF
        
        echo -e "${GREEN}✓ Initialization complete (${mode} mode)${NC}"
    }
    
    # Print summary
    print_summary() {
        local mode=$1
        
        echo ""
        echo -e "${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
        echo -e "${CYAN}║                    Initialization Complete                     ║${NC}"
        echo -e "${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
        echo ""
        
        if [[ "$mode" == "demo" ]]; then
            echo -e "Mode: ${CYAN}Demo${NC}"
            echo -e "Data: Matrix-themed agents, tasks, and messages loaded"
            echo ""
            echo -e "${YELLOW}Note: This is demo data. For production, re-run with --production --force${NC}"
        else
            echo -e "Mode: ${GREEN}Production${NC}"
            echo -e "Data: Clean state with welcome task"
            echo ""
            echo -e "Next steps:"
            echo -e "  1. Register yourself: ${CYAN}./scripts/add-agent.sh --id agent-primary --name 'Your Name' --role lead${NC}"
            echo -e "  2. Register human:    ${CYAN}./scripts/add-human.sh --id human-admin --name 'Admin Name'${NC}"
            echo -e "  3. Start dashboard:   ${CYAN}cd server && npm install && npm start${NC}"
        fi
        
        echo ""
        echo -e "Current data: $(count_existing_data)"
        echo ""
    }
    
    # Interactive mode
    interactive_mode() {
        echo ""
        echo -e "${BOLD}How would you like to initialize Mission Control?${NC}"
        echo ""
        echo -e "  ${GREEN}1)${NC} ${BOLD}Production${NC} - Clean setup, no demo data"
        echo -e "     Best for: Real projects, deployments, your own agents"
        echo ""
        echo -e "  ${CYAN}2)${NC} ${BOLD}Demo${NC} - Load Matrix-themed examples"
        echo -e "     Best for: Learning, testing, exploring features"
        echo ""
        
        read -p "Enter choice (1 or 2): " choice
        
        case $choice in
            1)
                MODE="production"
                ;;
            2)
                MODE="demo"
                ;;
            *)
                echo -e "${RED}Invalid choice. Exiting.${NC}"
                exit 1
                ;;
        esac
    }
    
    # Parse arguments
    MODE=""
    FORCE="false"
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --production)
                MODE="production"
                shift
                ;;
            --demo)
                MODE="demo"
                shift
                ;;
            --force)
                FORCE="true"
                shift
                ;;
            --help|-h)
                print_help
                exit 0
                ;;
            *)
                echo -e "${RED}Unknown option: $1${NC}"
                print_help
                exit 1
                ;;
        esac
    done
    
    # Main execution
    print_banner
    
    # Check if already initialized
    check_existing
    
    # If no mode specified, run interactive
    if [[ -z "$MODE" ]]; then
        interactive_mode
    fi
    
    # Clear existing data
    clear_data
    
    # Initialize based on mode
    if [[ "$MODE" == "demo" ]]; then
        load_demo_data
        mark_initialized "demo"
    else
        init_production
        mark_initialized "production"
    fi
    
    # Print summary
    print_summary "$MODE"
    
  • scripts/jarvis-install.sh935 Bf519feb1e913upstream ↗
    #!/usr/bin/env bash
    # DEPRECATED — Use scripts/mc-install.sh instead. Superseded by v1.0.0 mc CLI.
    # jarvis-install.sh — Install jarvis CLI globally via symlink
    # Run from any directory: bash /path/to/scripts/jarvis-install.sh
    
    set -e
    
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    JARVIS_JS="$SCRIPT_DIR/jarvis.js"
    TARGET="/usr/local/bin/jarvis"
    
    if [ ! -f "$JARVIS_JS" ]; then
      echo "❌ Error: $JARVIS_JS not found." >&2
      exit 1
    fi
    
    # Ensure executable
    chmod +x "$JARVIS_JS"
    
    # Symlink
    if [ -L "$TARGET" ] || [ -f "$TARGET" ]; then
      echo "→ Removing existing: $TARGET"
      rm -f "$TARGET"
    fi
    
    ln -s "$JARVIS_JS" "$TARGET"
    echo "✔ jarvis installed → $TARGET"
    echo ""
    echo "Configure your environment:"
    echo "  export AGENT_ID=tank"
    echo "  export MC_API_URL=http://localhost:3000   # optional, this is the default"
    echo ""
    echo "Quick test:"
    echo "  jarvis --help"
    echo "  jarvis tasks"
    echo "  jarvis squad"
    
  • scripts/jarvis.js20 KB73847fc52155upstream ↗
    #!/usr/bin/env node
    /**
     * DEPRECATED — Use `mc` instead (scripts/mc). This file is superseded by v1.0.0.
     * JARVIS CLI — Agent command-line interface for JARVIS Mission Control
     * Inspired by clawe (https://github.com/getclawe/clawe)
     *
     * Usage: jarvis <command> [args...]
     *
     * Config env vars:
     *   MC_API_URL  — Mission Control API base URL (default: http://localhost:3000)
     *   AGENT_ID    — Your agent identity (e.g. tank, oracle, morpheus)
     */
    
    'use strict';
    
    const http   = require('http');
    const https  = require('https');
    const fs     = require('fs');
    const path   = require('path');
    const crypto = require('crypto');
    
    // ─────────────────────────────────────────────
    // CONFIG
    // ─────────────────────────────────────────────
    const MC_API_URL = process.env.MC_API_URL || 'http://localhost:3000';
    const AGENT_ID   = process.env.AGENT_ID   || 'tank';
    
    // Resolve .mission-control dir (repo-root/.mission-control)
    const MC_DIR = path.join(__dirname, '..', '.mission-control');
    
    // ─────────────────────────────────────────────
    // COLORS
    // ─────────────────────────────────────────────
    const C = {
      reset:   '\x1b[0m',
      bold:    '\x1b[1m',
      dim:     '\x1b[2m',
      red:     '\x1b[31m',
      green:   '\x1b[32m',
      yellow:  '\x1b[33m',
      blue:    '\x1b[34m',
      magenta: '\x1b[35m',
      cyan:    '\x1b[36m',
      white:   '\x1b[37m',
    };
    
    const STATUS_COLOR = {
      INBOX:       C.white,
      TODO:        C.cyan,
      IN_PROGRESS: C.yellow,
      REVIEW:      C.magenta,
      DONE:        C.green,
      BLOCKED:     C.red,
      CANCELLED:   C.dim,
    };
    
    const PRIORITY_COLOR = {
      critical: C.red,
      high:     C.yellow,
      medium:   C.cyan,
      low:      C.dim,
    };
    
    const colorStatus   = s => (STATUS_COLOR[s]   || '') + s + C.reset;
    const colorPriority = p => (PRIORITY_COLOR[p] || '') + p + C.reset;
    const bold          = s => C.bold    + s + C.reset;
    const dim           = s => C.dim     + s + C.reset;
    const green         = s => C.green   + s + C.reset;
    const red           = s => C.red     + s + C.reset;
    const cyan          = s => C.cyan    + s + C.reset;
    const yellow        = s => C.yellow  + s + C.reset;
    const magenta       = s => C.magenta + s + C.reset;
    
    // ─────────────────────────────────────────────
    // HTTP HELPERS
    // ─────────────────────────────────────────────
    function apiRequest(method, urlPath, body) {
      return new Promise((resolve, reject) => {
        const fullUrl  = new URL(urlPath, MC_API_URL);
        const transport = fullUrl.protocol === 'https:' ? https : http;
        const bodyStr  = body ? JSON.stringify(body) : null;
    
        const options = {
          hostname: fullUrl.hostname,
          port:     fullUrl.port || (fullUrl.protocol === 'https:' ? 443 : 80),
          path:     fullUrl.pathname + fullUrl.search,
          method,
          headers: {
            'Content-Type': 'application/json',
            'X-Agent-Id': AGENT_ID,
            ...(bodyStr ? { 'Content-Length': Buffer.byteLength(bodyStr) } : {}),
          },
        };
    
        const req = transport.request(options, (res) => {
          let data = '';
          res.on('data', chunk => { data += chunk; });
          res.on('end', () => {
            try { resolve({ status: res.statusCode, body: JSON.parse(data) }); }
            catch { resolve({ status: res.statusCode, body: data }); }
          });
        });
    
        req.setTimeout(5000, () => { req.destroy(); reject(new Error('Request timeout')); });
        req.on('error', reject);
        if (bodyStr) req.write(bodyStr);
        req.end();
      });
    }
    
    // ─────────────────────────────────────────────
    // TASK FILE HELPERS  (direct file I/O fallback)
    // ─────────────────────────────────────────────
    function readTaskFile(id) {
      const p = path.join(MC_DIR, 'tasks', `${id}.json`);
      if (!fs.existsSync(p)) throw new Error(`Task file not found: ${p}`);
      return JSON.parse(fs.readFileSync(p, 'utf-8'));
    }
    
    function writeTaskFile(task) {
      const p = path.join(MC_DIR, 'tasks', `${task.id}.json`);
      fs.mkdirSync(path.dirname(p), { recursive: true });
      fs.writeFileSync(p, JSON.stringify(task, null, 2));
    }
    
    async function fetchTask(id) {
      try {
        const r = await apiRequest('GET', `/api/tasks/${id}`);
        if (r.status === 200) return r.body;
      } catch { /* server down — fall through */ }
      return readTaskFile(id);
    }
    
    async function persistTask(task) {
      task.updated_at = new Date().toISOString();
      try {
        const r = await apiRequest('PUT', `/api/tasks/${task.id}`, task);
        if (r.status === 200 || r.status === 201) return r.body;
      } catch { /* server down */ }
      writeTaskFile(task);
      return task;
    }
    
    // ─────────────────────────────────────────────
    // DISPLAY HELPERS
    // ─────────────────────────────────────────────
    const SEP = dim('─'.repeat(60));
    
    function printTask(task) {
      console.log(SEP);
      console.log(`${bold(task.id)}  ${colorStatus(task.status)}  ${colorPriority(task.priority || 'medium')}`);
      console.log(`${bold('Title:')}     ${task.title}`);
      if (task.assignee)   console.log(`${bold('Assignee:')}  ${cyan(task.assignee)}`);
      if (task.description) {
        const firstLine = task.description.split('\n')[0];
        console.log(`${bold('Desc:')}      ${firstLine}${task.description.includes('\n') ? ' …' : ''}`);
      }
      if (task.labels && task.labels.length)
        console.log(`${bold('Labels:')}    ${task.labels.map(l => magenta('#' + l)).join(' ')}`);
      console.log(`${bold('Created:')}   ${dim(task.created_at || '—')}`);
      console.log(`${bold('Updated:')}   ${dim(task.updated_at || '—')}`);
    
      // Subtasks
      if (task.subtasks && task.subtasks.length) {
        console.log(`\n${bold('Subtasks:')}`);
        task.subtasks.forEach((st, i) => {
          const check = st.done ? green('✔') : dim('○');
          console.log(`  ${check}  [${i}] ${st.done ? dim(st.text) : st.text}`);
        });
        const done = task.subtasks.filter(s => s.done).length;
        console.log(dim(`       ${done}/${task.subtasks.length} complete`));
      }
    
      // Deliverables (stored as attachments with type=deliverable)
      const deliverables = (task.attachments || []).filter(a => a.type === 'deliverable');
      if (deliverables.length) {
        console.log(`\n${bold('Deliverables:')}`);
        deliverables.forEach(d => {
          console.log(`  ${green('📦')} ${bold(d.name)}  ${dim(d.url || d.path || '—')}`);
        });
      }
    
      // Comments (last 3)
      if (task.comments && task.comments.length) {
        console.log(`\n${bold('Comments:')} ${dim('(' + task.comments.length + ')')}`);
        task.comments.slice(-3).forEach(c => {
          console.log(`  ${cyan(c.author)}  ${dim((c.timestamp || '').slice(0, 16))}`);
          console.log(`    ${c.content}`);
        });
      }
      console.log(SEP);
    }
    
    // ─────────────────────────────────────────────
    // COMMANDS
    // ─────────────────────────────────────────────
    
    /** task:status <id> <status> */
    async function cmdTaskStatus(id, status) {
      if (!id || !status) {
        console.error(red('Usage: jarvis task:status <task_id> <status>'));
        console.error(dim('  Statuses: INBOX TODO IN_PROGRESS REVIEW DONE BLOCKED CANCELLED'));
        process.exit(1);
      }
      const task = await fetchTask(id);
      const old  = task.status;
      task.status = status.toUpperCase();
      await persistTask(task);
      console.log(`${green('✔')} ${bold(id)} status: ${colorStatus(old)} → ${colorStatus(task.status)}`);
    }
    
    /** task:comment <id> "message" */
    async function cmdTaskComment(id, message) {
      if (!id || !message) {
        console.error(red('Usage: jarvis task:comment <task_id> "message"'));
        process.exit(1);
      }
      const task = await fetchTask(id);
      if (!task.comments) task.comments = [];
      const comment = {
        id:        `comment-${crypto.randomBytes(4).toString('hex')}`,
        author:    AGENT_ID,
        content:   message,
        timestamp: new Date().toISOString(),
        type:      'agent',
      };
      task.comments.push(comment);
      await persistTask(task);
      console.log(`${green('✔')} Comment added to ${bold(id)} by ${cyan(AGENT_ID)}`);
      console.log(`  ${dim(comment.id)}  ${comment.content}`);
    }
    
    /** task:view <id> */
    async function cmdTaskView(id) {
      if (!id) { console.error(red('Usage: jarvis task:view <task_id>')); process.exit(1); }
      const task = await fetchTask(id);
      printTask(task);
    }
    
    /** subtask:add <id> "description" */
    async function cmdSubtaskAdd(id, desc) {
      if (!id || !desc) {
        console.error(red('Usage: jarvis subtask:add <task_id> "description"'));
        process.exit(1);
      }
      const task = await fetchTask(id);
      if (!task.subtasks) task.subtasks = [];
      const idx = task.subtasks.length;
      task.subtasks.push({ text: desc, done: false, added_by: AGENT_ID, added_at: new Date().toISOString() });
      await persistTask(task);
      console.log(`${green('✔')} Subtask [${idx}] added to ${bold(id)}: ${desc}`);
    }
    
    /** subtask:check <id> <index> */
    async function cmdSubtaskCheck(id, indexStr) {
      if (!id || indexStr === undefined) {
        console.error(red('Usage: jarvis subtask:check <task_id> <index>'));
        process.exit(1);
      }
      const idx  = parseInt(indexStr, 10);
      const task = await fetchTask(id);
      if (!task.subtasks || !task.subtasks[idx]) {
        console.error(red(`Subtask [${idx}] not found on task ${id}`));
        process.exit(1);
      }
      task.subtasks[idx].done = !task.subtasks[idx].done;
      const state = task.subtasks[idx].done ? green('✔ done') : yellow('○ undone');
      await persistTask(task);
      console.log(`${green('✔')} Subtask [${idx}] toggled → ${state}: ${task.subtasks[idx].text}`);
    }
    
    /** subtask:list <id> */
    async function cmdSubtaskList(id) {
      if (!id) { console.error(red('Usage: jarvis subtask:list <task_id>')); process.exit(1); }
      const task = await fetchTask(id);
      if (!task.subtasks || task.subtasks.length === 0) {
        console.log(dim(`No subtasks on ${id}`));
        return;
      }
      console.log(`${bold('Subtasks for')} ${cyan(id)}:`);
      console.log(SEP);
      task.subtasks.forEach((st, i) => {
        const check = st.done ? green('✔') : dim('○');
        console.log(`  ${check}  [${i}]  ${st.done ? dim(st.text) : st.text}`);
      });
      const done  = task.subtasks.filter(s => s.done).length;
      const total = task.subtasks.length;
      console.log(dim(`\n  ${done}/${total} complete`));
      console.log(SEP);
    }
    
    /** deliver <id> "name" --path ./file | --url https://... */
    async function cmdDeliver(id, name, flags) {
      if (!id || !name) {
        console.error(red('Usage: jarvis deliver <task_id> "name" --path ./file.md'));
        console.error(red('       jarvis deliver <task_id> "name" --url https://...'));
        process.exit(1);
      }
      if (!flags.path && !flags.url) {
        console.error(red('Must provide --path or --url'));
        process.exit(1);
      }
      const task = await fetchTask(id);
      if (!task.attachments) task.attachments = [];
      const deliverable = {
        name,
        type:        'deliverable',
        description: flags.desc || '',
        added_by:    AGENT_ID,
        added_at:    new Date().toISOString(),
        ...(flags.path ? { path: flags.path } : {}),
        ...(flags.url  ? { url:  flags.url  } : {}),
      };
      task.attachments.push(deliverable);
      await persistTask(task);
      console.log(`${green('✔')} Deliverable "${bold(name)}" registered on ${bold(id)}`);
      console.log(`  ${dim(flags.url || flags.path)}`);
    }
    
    /** tasks [--status X] [--assignee Y] */
    async function cmdTasks(flags) {
      let tasks = [];
      try {
        const r = await apiRequest('GET', '/api/tasks');
        if (r.status === 200 && Array.isArray(r.body)) tasks = r.body;
        else throw new Error('API error');
      } catch {
        // fallback: read files directly
        const dir = path.join(MC_DIR, 'tasks');
        if (!fs.existsSync(dir)) { console.log(dim('No tasks found.')); return; }
        tasks = fs.readdirSync(dir)
          .filter(f => f.endsWith('.json'))
          .map(f => { try { return JSON.parse(fs.readFileSync(path.join(dir, f), 'utf-8')); } catch { return null; } })
          .filter(Boolean);
      }
    
      if (flags.status)   tasks = tasks.filter(t => t.status && t.status.toUpperCase() === flags.status.toUpperCase());
      if (flags.assignee) tasks = tasks.filter(t => t.assignee && t.assignee.includes(flags.assignee));
    
      if (tasks.length === 0) { console.log(dim('No tasks match.')); return; }
    
      console.log(`\n${bold('JARVIS Tasks')}  ${dim('(' + tasks.length + ')')}\n`);
      console.log(
        bold(padR('ID', 34)) +
        bold(padR('STATUS', 14)) +
        bold(padR('PRI', 10)) +
        bold(padR('ASSIGNEE', 18)) +
        bold('TITLE')
      );
      console.log(SEP);
      tasks.forEach(t => {
        console.log(
          padR(t.id, 34) +
          padR(t.status || '—', 14) +
          padR(t.priority || '—', 10) +
          padR(t.assignee || '—', 18) +
          (t.title || '').slice(0, 38)
        );
      });
      console.log(SEP + '\n');
    }
    
    /** notify "message" --to <agent> */
    async function cmdNotify(message, flags) {
      if (!message) {
        console.error(red('Usage: jarvis notify "message" --to <agent>'));
        process.exit(1);
      }
      const to = flags.to || 'all';
      const body = {
        id:        `msg-${crypto.randomBytes(4).toString('hex')}`,
        from:      AGENT_ID,
        to,
        content:   message,
        timestamp: new Date().toISOString(),
        type:      'notification',
        read:      false,
      };
    
      let sent = false;
      try {
        const r = await apiRequest('POST', '/api/messages', body);
        if (r.status === 200 || r.status === 201) sent = true;
      } catch { /* server down */ }
    
      if (!sent) {
        const dir = path.join(MC_DIR, 'messages');
        fs.mkdirSync(dir, { recursive: true });
        fs.writeFileSync(path.join(dir, `${body.id}.json`), JSON.stringify(body, null, 2));
      }
    
      console.log(`${green('✔')} Notification sent ${cyan(AGENT_ID)} → ${cyan(to)}`);
      console.log(`  "${message}"`);
    }
    
    /** squad — show all agents + their active task */
    async function cmdSquad() {
      let agents = [];
      let tasks  = [];
    
      try {
        const r = await apiRequest('GET', '/api/agents');
        if (r.status === 200 && Array.isArray(r.body)) agents = r.body;
      } catch {}
    
      if (!agents.length) {
        const dir = path.join(MC_DIR, 'agents');
        if (fs.existsSync(dir)) {
          agents = fs.readdirSync(dir)
            .filter(f => f.endsWith('.json'))
            .map(f => { try { return JSON.parse(fs.readFileSync(path.join(dir, f), 'utf-8')); } catch { return null; } })
            .filter(Boolean);
        }
      }
    
      try {
        const r = await apiRequest('GET', '/api/tasks');
        if (r.status === 200 && Array.isArray(r.body)) tasks = r.body;
      } catch {}
    
      if (!tasks.length) {
        const dir = path.join(MC_DIR, 'tasks');
        if (fs.existsSync(dir)) {
          tasks = fs.readdirSync(dir)
            .filter(f => f.endsWith('.json'))
            .map(f => { try { return JSON.parse(fs.readFileSync(path.join(dir, f), 'utf-8')); } catch { return null; } })
            .filter(Boolean);
        }
      }
    
      const activeTasks = tasks.filter(t => t.status === 'IN_PROGRESS');
      const taskByAssignee = {};
      activeTasks.forEach(t => { if (t.assignee) taskByAssignee[t.assignee] = t; });
    
      console.log(`\n${bold('⚡ JARVIS Squad Status')}\n`);
      console.log(SEP);
    
      if (!agents.length) {
        console.log(dim('  No agents found.'));
      } else {
        agents.forEach(a => {
          const status  = a.status || 'unknown';
          const dot     = status === 'online'  ? green('●') :
                          status === 'offline' ? red('●')   : yellow('●');
          const agentId = a.id || a.name || '?';
          const task    = taskByAssignee[agentId];
          const taskStr = task
            ? `${yellow(task.id)}  ${dim((task.title || '').slice(0, 35))}`
            : dim('— idle');
          console.log(`  ${dot}  ${bold(padR(agentId, 22))}  ${taskStr}`);
        });
      }
    
      console.log(SEP + '\n');
    }
    
    // ─────────────────────────────────────────────
    // ARG PARSING
    // ─────────────────────────────────────────────
    function padR(str, len) {
      str = String(str);
      return str.length >= len ? str.slice(0, len - 1) + ' ' : str + ' '.repeat(len - str.length);
    }
    
    function parseArgs(args) {
      const flags      = {};
      const positional = [];
      for (let i = 0; i < args.length; i++) {
        if (args[i].startsWith('--')) {
          const key = args[i].slice(2);
          flags[key] = (args[i + 1] && !args[i + 1].startsWith('--')) ? args[++i] : true;
        } else {
          positional.push(args[i]);
        }
      }
      return { flags, positional };
    }
    
    // ─────────────────────────────────────────────
    // HELP
    // ─────────────────────────────────────────────
    function printHelp() {
      console.log(`
    ${bold(cyan('JARVIS CLI'))} — Mission Control Command Interface
    ${dim('Agent: ' + AGENT_ID + '  |  API: ' + MC_API_URL)}
    
    ${bold('Task Management')}
      ${yellow('jarvis task:status')} <id> <status>        Update task status
      ${yellow('jarvis task:comment')} <id> "msg"           Add a comment
      ${yellow('jarvis task:view')} <id>                   View full task details
    
    ${bold('Subtasks')}
      ${yellow('jarvis subtask:add')} <id> "desc"           Add a subtask
      ${yellow('jarvis subtask:check')} <id> <idx>          Toggle subtask done/undone
      ${yellow('jarvis subtask:list')} <id>                List all subtasks
    
    ${bold('Deliverables')}
      ${yellow('jarvis deliver')} <id> "name" --path ./f    Register a file deliverable
      ${yellow('jarvis deliver')} <id> "name" --url https   Register a URL deliverable
    
    ${bold('Listing')}
      ${yellow('jarvis tasks')}                             List all tasks
      ${yellow('jarvis tasks')} --status IN_PROGRESS        Filter by status
      ${yellow('jarvis tasks')} --assignee oracle            Filter by agent
    
    ${bold('Notifications & Squad')}
      ${yellow('jarvis notify')} "msg" --to oracle           Notify an agent
      ${yellow('jarvis squad')}                             Show all agents + active task
    
    ${bold('Valid Statuses:')}
      INBOX  TODO  IN_PROGRESS  REVIEW  DONE  BLOCKED  CANCELLED
    
    ${bold('Env Vars:')}
      MC_API_URL   API base URL  (default: http://localhost:3000)
      AGENT_ID     Your agent ID (default: tank)
      DEBUG        Set to 1 for stack traces on errors
    `);
    }
    
    // ─────────────────────────────────────────────
    // MAIN
    // ─────────────────────────────────────────────
    async function main() {
      const argv = process.argv.slice(2);
      if (!argv.length || argv[0] === '--help' || argv[0] === '-h') {
        printHelp();
        return;
      }
    
      const cmd                 = argv[0];
      const { flags, positional } = parseArgs(argv.slice(1));
    
      try {
        switch (cmd) {
          case 'task:status':  await cmdTaskStatus(positional[0], positional[1]);           break;
          case 'task:comment': await cmdTaskComment(positional[0], positional[1]);          break;
          case 'task:view':    await cmdTaskView(positional[0]);                            break;
          case 'subtask:add':  await cmdSubtaskAdd(positional[0], positional[1]);           break;
          case 'subtask:check':await cmdSubtaskCheck(positional[0], positional[1]);         break;
          case 'subtask:list': await cmdSubtaskList(positional[0]);                         break;
          case 'deliver':      await cmdDeliver(positional[0], positional[1], flags);       break;
          case 'tasks':        await cmdTasks(flags);                                       break;
          case 'notify':       await cmdNotify(positional[0], flags);                      break;
          case 'squad':        await cmdSquad();                                            break;
          default:
            console.error(red(`Unknown command: ${cmd}`));
            printHelp();
            process.exit(1);
        }
      } catch (err) {
        console.error(red(`Error: ${err.message}`));
        if (process.env.DEBUG) console.error(err.stack);
        process.exit(1);
      }
    }
    
    main();
    
  • scripts/list-tasks.sh5.4 KBebc10a4ef4d4upstream ↗
    #!/bin/bash
    #
    # JARVIS Mission Control - List Tasks Script
    # Lists all tasks with optional filtering
    #
    # Usage: ./scripts/list-tasks.sh [options]
    #
    # Options:
    #   --status <status>     Filter by status
    #   --assignee <id>       Filter by assignee
    #   --priority <level>    Filter by priority
    #   --label <label>       Filter by label
    #   --format <format>     Output format (table, json, simple)
    #
    
    set -euo pipefail
    
    # Configuration
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
    TASKS_DIR="$PROJECT_ROOT/.mission-control/tasks"
    
    # Defaults
    STATUS_FILTER=""
    ASSIGNEE_FILTER=""
    PRIORITY_FILTER=""
    LABEL_FILTER=""
    FORMAT="table"
    
    # Colors
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    BLUE='\033[0;34m'
    PURPLE='\033[0;35m'
    CYAN='\033[0;36m'
    NC='\033[0m'
    
    # Usage
    usage() {
        cat << EOF
    Usage: $(basename "$0") [options]
    
    Options:
      --status <status>     Filter by status (INBOX, ASSIGNED, IN_PROGRESS, REVIEW, DONE, BLOCKED)
      --assignee <id>       Filter by assignee
      --priority <level>    Filter by priority (critical, high, medium, low)
      --label <label>       Filter by label
      --format <format>     Output format: table (default), json, simple
      -h, --help            Show this help message
    
    Examples:
      $(basename "$0")
      $(basename "$0") --status IN_PROGRESS
      $(basename "$0") --assignee agent-jarvis --format json
    EOF
    }
    
    # Status color
    status_color() {
        case "$1" in
            INBOX) echo -e "${CYAN}$1${NC}" ;;
            ASSIGNED) echo -e "${BLUE}$1${NC}" ;;
            IN_PROGRESS) echo -e "${YELLOW}$1${NC}" ;;
            REVIEW) echo -e "${PURPLE}$1${NC}" ;;
            DONE) echo -e "${GREEN}$1${NC}" ;;
            BLOCKED) echo -e "${RED}$1${NC}" ;;
            *) echo "$1" ;;
        esac
    }
    
    # Priority color
    priority_color() {
        case "$1" in
            critical) echo -e "${RED}$1${NC}" ;;
            high) echo -e "${YELLOW}$1${NC}" ;;
            medium) echo -e "${CYAN}$1${NC}" ;;
            low) echo -e "${GREEN}$1${NC}" ;;
            *) echo "$1" ;;
        esac
    }
    
    # Parse arguments
    while [ $# -gt 0 ]; do
        case "$1" in
            -h|--help)
                usage
                exit 0
                ;;
            --status)
                shift
                STATUS_FILTER="$1"
                ;;
            --assignee)
                shift
                ASSIGNEE_FILTER="$1"
                ;;
            --priority)
                shift
                PRIORITY_FILTER="$1"
                ;;
            --label)
                shift
                LABEL_FILTER="$1"
                ;;
            --format)
                shift
                FORMAT="$1"
                ;;
            *)
                echo "Unknown option: $1"
                usage
                exit 1
                ;;
        esac
        shift
    done
    
    # Check if jq is available
    if ! command -v jq &> /dev/null; then
        echo "Error: jq is required but not installed"
        echo "Install with: apt-get install jq (Linux) or brew install jq (macOS)"
        exit 1
    fi
    
    # Check tasks directory
    if [ ! -d "$TASKS_DIR" ]; then
        echo "No tasks found (directory does not exist)"
        exit 0
    fi
    
    # Collect tasks
    TASKS=()
    for file in "$TASKS_DIR"/*.json 2>/dev/null; do
        [ -e "$file" ] || continue
    
        # Read task data
        id=$(jq -r '.id' "$file")
        title=$(jq -r '.title' "$file")
        status=$(jq -r '.status' "$file")
        priority=$(jq -r '.priority' "$file")
        assignee=$(jq -r '.assignee // "unassigned"' "$file")
        labels=$(jq -r '.labels | join(",")' "$file")
    
        # Apply filters
        if [ -n "$STATUS_FILTER" ] && [ "$status" != "$STATUS_FILTER" ]; then
            continue
        fi
    
        if [ -n "$ASSIGNEE_FILTER" ] && [ "$assignee" != "$ASSIGNEE_FILTER" ]; then
            continue
        fi
    
        if [ -n "$PRIORITY_FILTER" ] && [ "$priority" != "$PRIORITY_FILTER" ]; then
            continue
        fi
    
        if [ -n "$LABEL_FILTER" ] && [[ ! "$labels" == *"$LABEL_FILTER"* ]]; then
            continue
        fi
    
        TASKS+=("$id|$title|$status|$priority|$assignee|$labels|$file")
    done
    
    # No tasks found
    if [ ${#TASKS[@]} -eq 0 ]; then
        echo "No tasks found"
        exit 0
    fi
    
    # Output based on format
    case "$FORMAT" in
        json)
            echo "["
            first=true
            for task in "${TASKS[@]}"; do
                IFS='|' read -r id title status priority assignee labels file <<< "$task"
                if [ "$first" = true ]; then
                    first=false
                else
                    echo ","
                fi
                cat "$file"
            done
            echo ""
            echo "]"
            ;;
    
        simple)
            for task in "${TASKS[@]}"; do
                IFS='|' read -r id title status priority assignee labels file <<< "$task"
                echo "$id: $title [$status]"
            done
            ;;
    
        table|*)
            # Print header
            printf "%-35s %-40s %-12s %-10s %-25s\n" "ID" "TITLE" "STATUS" "PRIORITY" "ASSIGNEE"
            printf "%s\n" "$(printf '=%.0s' {1..130})"
    
            # Print tasks
            for task in "${TASKS[@]}"; do
                IFS='|' read -r id title status priority assignee labels file <<< "$task"
    
                # Truncate title if too long
                if [ ${#title} -gt 38 ]; then
                    title="${title:0:35}..."
                fi
    
                # Truncate assignee if too long
                if [ ${#assignee} -gt 23 ]; then
                    assignee="${assignee:0:20}..."
                fi
    
                # Print with colors
                printf "%-35s %-40s " "$id" "$title"
                printf "%-12b " "$(status_color "$status")"
                printf "%-10b " "$(priority_color "$priority")"
                printf "%-25s\n" "$assignee"
            done
    
            echo ""
            echo "Total: ${#TASKS[@]} task(s)"
            ;;
    esac
    
  • scripts/mc25 KB224a8fe78f3bupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • scripts/mc-install.sh197 B3ecea62d7bfcupstream ↗
    #!/usr/bin/env bash
    set -euo pipefail
    MC_DIR="$(cd "$(dirname "$0")/.." && pwd)"
    ln -sf "$MC_DIR/scripts/mc" /usr/local/bin/mc
    echo "✅ mc installed to /usr/local/bin/mc"
    echo "   Run: mc --help"
    
  • scripts/mc-task.sh1.6 KB26ccb4342b34upstream ↗
    #!/bin/bash
    # mc-task.sh - Create/update Mission Control tasks from CLI
    # Usage: ./mc-task.sh create "Task title" "Description" [assignee]
    # Usage: ./mc-task.sh update <task-id> <status> [result]
    
    MC_URL="${MC_SERVER_URL:-http://localhost:3000}"
    MC_DIR="${MISSION_CONTROL_DIR:-/root/.openclaw/workspace/agents/tank/mission-control/.mission-control}"
    
    create_task() {
        local title="$1"
        local description="$2"
        local assignee="${3:-unassigned}"
        local task_id="task-$(date +%Y%m%d)-$(date +%s)"
        
        cat > "$MC_DIR/tasks/$task_id.json" << EOF
    {
      "id": "$task_id",
      "title": "$title",
      "description": "$description",
      "status": "pending",
      "priority": "normal",
      "assignee": "$assignee",
      "createdAt": "$(date -Iseconds)",
      "createdBy": "agent",
      "mentions": ["$assignee"],
      "progress": 0
    }
    EOF
        echo "Created: $task_id"
    }
    
    update_task() {
        local task_id="$1"
        local status="$2"
        local result="${3:-}"
        local task_file="$MC_DIR/tasks/$task_id.json"
        
        if [ ! -f "$task_file" ]; then
            echo "Task not found: $task_id"
            exit 1
        fi
        
        # Update status using jq if available, else sed
        if command -v jq &> /dev/null; then
            jq ".status = \"$status\" | .updatedAt = \"$(date -Iseconds)\"" "$task_file" > "$task_file.tmp" && mv "$task_file.tmp" "$task_file"
        else
            sed -i "s/\"status\": \"[^\"]*\"/\"status\": \"$status\"/" "$task_file"
        fi
        echo "Updated: $task_id -> $status"
    }
    
    case "$1" in
        create) create_task "$2" "$3" "$4" ;;
        update) update_task "$2" "$3" "$4" ;;
        *) echo "Usage: $0 {create|update} ..." ;;
    esac
    
  • scripts/mc-telegram-task.sh793 B1dff302020eaupstream ↗
    #!/bin/bash
    # mc-telegram-task.sh - Create Mission Control task from Telegram message
    # Called by agents when they receive a task assignment
    #
    # Usage: ./mc-telegram-task.sh "from_user" "message_text" [chat_id] [message_id]
    #
    # Examples:
    #   ./mc-telegram-task.sh "User" "@MyAgentBot fix the bug"
    #   ./mc-telegram-task.sh "User" "@AgentBot review" "-123456789" "456"
    
    MC_URL="${MC_SERVER_URL:-http://localhost:3000}"
    
    FROM="${1:-User}"
    MESSAGE="${2:?Message required}"
    CHAT_ID="${3:-0}"
    MESSAGE_ID="${4:-0}"
    
    curl -s -X POST "${MC_URL}/api/telegram/task" \
      -H "Content-Type: application/json" \
      -d "{
        \"from\": \"${FROM}\",
        \"message\": \"${MESSAGE}\",
        \"chat_id\": \"${CHAT_ID}\",
        \"message_id\": \"${MESSAGE_ID}\",
        \"timestamp\": \"$(date -Iseconds)\"
      }"
    
    echo ""
    
  • scripts/report-context.sh947 B4b6ecc772df3upstream ↗
    #!/bin/bash
    # report-context.sh — agent reports context window usage to local Mission Control
    # Called from OpenClaw heartbeat or cron.
    #
    # Usage: ./scripts/report-context.sh <agent_id> <tokens_used> <tokens_total> [model]
    #
    # Example (from OpenClaw heartbeat via exec tool):
    #   ./scripts/report-context.sh oracle 45000 200000 claude-sonnet-4-6
    #
    # Or use environment variables:
    #   export MC_AGENT_ID=oracle
    #   export MC_CONTEXT_USED=45000
    #   export MC_CONTEXT_TOTAL=200000
    #   ./scripts/report-context.sh
    
    AGENT_ID="${1:-${MC_AGENT_ID:-agent}}"
    USED="${2:-${MC_CONTEXT_USED:-0}}"
    TOTAL="${3:-${MC_CONTEXT_TOTAL:-200000}}"
    MODEL="${4:-${MC_MODEL:-unknown}}"
    MC_PORT="${MC_PORT:-3001}"
    MC_SERVER="${MC_SERVER_URL:-http://localhost:$MC_PORT}"
    
    curl -s -X POST "$MC_SERVER/api/agents/$AGENT_ID/context" \
      -H "Content-Type: application/json" \
      -d "{\"used\":$USED,\"total\":$TOTAL,\"model\":\"$MODEL\"}" \
      --max-time 5 > /dev/null
    
    exit 0
    
  • scripts/safe-deploy.sh8.8 KB3b22e1f3b17eupstream ↗
    #!/bin/bash
    #
    # safe-deploy.sh - Deploy Mission Control with data protection
    #
    # Usage:
    #   ./scripts/safe-deploy.sh                    # Deploy current state (preserves data)
    #   ./scripts/safe-deploy.sh --backup           # Create backup only
    #   ./scripts/safe-deploy.sh --restore BACKUP   # Restore from backup
    #   ./scripts/safe-deploy.sh --demo             # Deploy with demo data (WARNING: destructive)
    #   ./scripts/safe-deploy.sh --pull             # Safe git pull (backs up first)
    #
    # RULE: User data is NEVER overwritten without explicit --demo flag
    #
    
    set -e
    
    # Colors
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    CYAN='\033[0;36m'
    NC='\033[0m'
    
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    REPO_ROOT="$(dirname "$SCRIPT_DIR")"
    MC_DIR="$REPO_ROOT/.mission-control"
    BACKUP_DIR="$REPO_ROOT/.backups"
    TIMESTAMP=$(date +%Y%m%d-%H%M%S)
    
    # Ensure backup directory exists
    mkdir -p "$BACKUP_DIR"
    
    print_banner() {
        echo -e "${CYAN}"
        echo "╔═══════════════════════════════════════════════════════════════╗"
        echo "║         Mission Control - Safe Deployment Tool                ║"
        echo "╚═══════════════════════════════════════════════════════════════╝"
        echo -e "${NC}"
    }
    
    # Create backup of all user data
    create_backup() {
        local backup_name="${1:-data-backup-$TIMESTAMP}"
        local backup_path="$BACKUP_DIR/$backup_name.tar.gz"
        
        echo -e "${CYAN}📦 Creating backup: $backup_name${NC}"
        
        # Count what we're backing up
        local agent_count=$(find "$MC_DIR/agents" -name "*.json" 2>/dev/null | wc -l)
        local task_count=$(find "$MC_DIR/tasks" -name "*.json" 2>/dev/null | wc -l)
        local human_count=$(find "$MC_DIR/humans" -name "*.json" 2>/dev/null | wc -l)
        local msg_count=$(find "$MC_DIR/messages" -name "*.json" 2>/dev/null | wc -l)
        
        echo "   Agents: $agent_count | Tasks: $task_count | Humans: $human_count | Messages: $msg_count"
        
        # Create tarball of user data directories
        tar -czf "$backup_path" \
            -C "$REPO_ROOT" \
            .mission-control/agents \
            .mission-control/tasks \
            .mission-control/humans \
            .mission-control/messages \
            .mission-control/config.yaml \
            .mission-control/config \
            2>/dev/null || true
        
        echo -e "${GREEN}✅ Backup created: $backup_path${NC}"
        echo "$backup_path"
    }
    
    # Restore from backup
    restore_backup() {
        local backup_path="$1"
        
        if [ ! -f "$backup_path" ]; then
            # Try finding in backup dir
            if [ -f "$BACKUP_DIR/$backup_path" ]; then
                backup_path="$BACKUP_DIR/$backup_path"
            elif [ -f "$BACKUP_DIR/$backup_path.tar.gz" ]; then
                backup_path="$BACKUP_DIR/$backup_path.tar.gz"
            else
                echo -e "${RED}❌ Backup not found: $backup_path${NC}"
                echo "Available backups:"
                ls -la "$BACKUP_DIR"/*.tar.gz 2>/dev/null || echo "  (none)"
                exit 1
            fi
        fi
        
        echo -e "${YELLOW}⚠️  Restoring from: $backup_path${NC}"
        echo -e "${YELLOW}   This will REPLACE current data with backup contents.${NC}"
        read -p "Continue? (y/N) " -n 1 -r
        echo
        
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            echo "Cancelled."
            exit 0
        fi
        
        # Backup current state first
        echo -e "${CYAN}Creating pre-restore backup...${NC}"
        create_backup "pre-restore-backup-$TIMESTAMP"
        
        # Extract backup
        echo -e "${CYAN}Restoring data...${NC}"
        tar -xzf "$backup_path" -C "$REPO_ROOT"
        
        echo -e "${GREEN}✅ Data restored from backup${NC}"
    }
    
    # Safe git pull (backs up data first)
    safe_pull() {
        echo -e "${CYAN}🔄 Safe Git Pull${NC}"
        
        # Check for uncommitted changes
        if ! git -C "$REPO_ROOT" diff --quiet; then
            echo -e "${YELLOW}⚠️  You have uncommitted changes:${NC}"
            git -C "$REPO_ROOT" status --short
            echo ""
            read -p "Stash changes and continue? (y/N) " -n 1 -r
            echo
            if [[ ! $REPLY =~ ^[Yy]$ ]]; then
                exit 0
            fi
            git -C "$REPO_ROOT" stash
        fi
        
        # Create backup
        local backup_path=$(create_backup "pre-pull-backup-$TIMESTAMP")
        
        # Pull
        echo -e "${CYAN}Pulling latest changes...${NC}"
        git -C "$REPO_ROOT" pull
        
        echo ""
        echo -e "${GREEN}✅ Pull complete. Your data is preserved.${NC}"
        echo -e "   Backup: $backup_path"
        echo ""
        echo -e "${YELLOW}NOTE: If anything looks wrong, restore with:${NC}"
        echo "   ./scripts/safe-deploy.sh --restore pre-pull-backup-$TIMESTAMP"
    }
    
    # Deploy with demo data (DESTRUCTIVE)
    deploy_demo() {
        echo -e "${RED}"
        echo "╔═══════════════════════════════════════════════════════════════╗"
        echo "║  ⚠️  WARNING: DESTRUCTIVE OPERATION                            ║"
        echo "║                                                               ║"
        echo "║  This will REPLACE all your data with demo data!             ║"
        echo "╚═══════════════════════════════════════════════════════════════╝"
        echo -e "${NC}"
        
        # Count existing data
        local agent_count=$(find "$MC_DIR/agents" -name "*.json" 2>/dev/null | wc -l)
        local task_count=$(find "$MC_DIR/tasks" -name "*.json" 2>/dev/null | wc -l)
        
        if [ "$agent_count" -gt 0 ] || [ "$task_count" -gt 0 ]; then
            echo -e "${YELLOW}You have existing data:${NC}"
            echo "   Agents: $agent_count"
            echo "   Tasks: $task_count"
            echo ""
            echo "Type 'DEMO' to confirm replacement: "
            read -r confirm
            
            if [ "$confirm" != "DEMO" ]; then
                echo "Cancelled."
                exit 0
            fi
            
            # Backup first
            create_backup "pre-demo-backup-$TIMESTAMP"
        fi
        
        # Clear existing data
        echo -e "${CYAN}Clearing existing data...${NC}"
        rm -f "$MC_DIR/agents/"*.json 2>/dev/null || true
        rm -f "$MC_DIR/tasks/"*.json 2>/dev/null || true
        rm -f "$MC_DIR/humans/"*.json 2>/dev/null || true
        rm -f "$MC_DIR/messages/"*.json 2>/dev/null || true
        
        # Copy demo data
        echo -e "${CYAN}Loading demo data...${NC}"
        cp "$REPO_ROOT/examples/demo-data/agents/"*.json "$MC_DIR/agents/" 2>/dev/null || true
        cp "$REPO_ROOT/examples/demo-data/tasks/"*.json "$MC_DIR/tasks/" 2>/dev/null || true
        cp "$REPO_ROOT/examples/demo-data/humans/"*.json "$MC_DIR/humans/" 2>/dev/null || true
        cp "$REPO_ROOT/examples/demo-data/messages/"*.json "$MC_DIR/messages/" 2>/dev/null || true
        
        # Mark as demo
        touch "$MC_DIR/.demo-loaded"
        
        echo -e "${GREEN}✅ Demo data loaded${NC}"
    }
    
    # Show usage
    show_help() {
        echo "Usage: $0 [OPTIONS]"
        echo ""
        echo "Options:"
        echo "  --backup           Create backup of current data"
        echo "  --restore BACKUP   Restore from a backup file"
        echo "  --pull             Safe git pull (backs up first)"
        echo "  --demo             Load demo data (DESTRUCTIVE - requires confirmation)"
        echo "  --list             List available backups"
        echo "  --help             Show this help"
        echo ""
        echo "Default behavior: Creates a backup (safe operation)"
        echo ""
        echo "Examples:"
        echo "  $0 --pull                              # Update code safely"
        echo "  $0 --restore data-backup-20260210      # Restore specific backup"
        echo "  $0 --list                              # See all backups"
    }
    
    # List backups
    list_backups() {
        echo -e "${CYAN}Available backups:${NC}"
        echo ""
        if ls "$BACKUP_DIR"/*.tar.gz 1>/dev/null 2>&1; then
            for f in "$BACKUP_DIR"/*.tar.gz; do
                local size=$(du -h "$f" | cut -f1)
                local name=$(basename "$f")
                echo "  $name ($size)"
            done
        else
            echo "  (no backups found)"
        fi
    }
    
    # Main
    print_banner
    
    case "${1:-}" in
        --backup)
            create_backup
            ;;
        --restore)
            if [ -z "${2:-}" ]; then
                echo -e "${RED}❌ Please specify a backup to restore${NC}"
                list_backups
                exit 1
            fi
            restore_backup "$2"
            ;;
        --pull)
            safe_pull
            ;;
        --demo)
            deploy_demo
            ;;
        --list)
            list_backups
            ;;
        --help|-h)
            show_help
            ;;
        "")
            # Default: just create a backup
            create_backup
            echo ""
            echo "Run with --help for more options"
            ;;
        *)
            echo -e "${RED}Unknown option: $1${NC}"
            show_help
            exit 1
            ;;
    esac
    
  • scripts/update-mission-control.sh2.5 KBdec14b67066aupstream ↗
    #!/bin/bash
    # update-mission-control.sh - Download and apply Mission Control updates
    #
    # Usage: ./scripts/update-mission-control.sh [--force]
    #
    # Options:
    #   --force    Skip confirmation prompt
    #
    # Requires: MISSIONDECK_API_KEY environment variable or config.json
    
    set -e
    
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    MC_ROOT="$(dirname "$SCRIPT_DIR")"
    
    FORCE=false
    if [ "$1" = "--force" ]; then
      FORCE=true
    fi
    
    # Get API key
    API_KEY="${MISSIONDECK_API_KEY:-}"
    if [ -z "$API_KEY" ] && [ -f "$MC_ROOT/.mission-control/config.json" ]; then
      API_KEY=$(grep -o '"apiKey"[[:space:]]*:[[:space:]]*"[^"]*"' "$MC_ROOT/.mission-control/config.json" 2>/dev/null | head -1 | cut -d'"' -f4)
    fi
    
    if [ -z "$API_KEY" ]; then
      echo "❌ No MissionDeck API key configured"
      echo "   Set MISSIONDECK_API_KEY or add to .mission-control/config.json"
      exit 1
    fi
    
    API_BASE="${MISSIONDECK_API_BASE:-https://missiondeck.ai/api/distribution}"
    
    # Get latest version info
    echo "🔍 Checking latest version..."
    VERSION_INFO=$(curl -s -H "x-api-key: $API_KEY" "$API_BASE/version")
    LATEST=$(echo "$VERSION_INFO" | grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4)
    
    if [ -z "$LATEST" ]; then
      echo "❌ Could not get version info"
      exit 1
    fi
    
    echo "   Latest version: $LATEST"
    
    # Confirm update
    if [ "$FORCE" != "true" ]; then
      echo ""
      read -p "📦 Download and apply update? (y/N) " -n 1 -r
      echo ""
      if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo "Cancelled."
        exit 0
      fi
    fi
    
    # Create backup
    BACKUP_DIR="$MC_ROOT/../mission-control-backup-$(date +%Y%m%d-%H%M%S)"
    echo ""
    echo "💾 Creating backup at: $BACKUP_DIR"
    cp -r "$MC_ROOT" "$BACKUP_DIR"
    
    # Download update
    TEMP_ZIP="/tmp/mission-control-$LATEST.zip"
    echo "⬇️  Downloading Mission Control $LATEST..."
    curl -s -H "x-api-key: $API_KEY" "$API_BASE/download/latest" -o "$TEMP_ZIP"
    
    if [ ! -f "$TEMP_ZIP" ] || [ ! -s "$TEMP_ZIP" ]; then
      echo "❌ Download failed"
      exit 1
    fi
    
    # Extract (preserve local data)
    echo "📂 Extracting update..."
    cd "$MC_ROOT"
    
    # Extract everything except local data
    unzip -o "$TEMP_ZIP" -x ".mission-control/agents/*" ".mission-control/tasks/*" ".mission-control/humans/*" ".mission-control/messages/*" ".mission-control/config.json" ".mission-control/logs/*" 2>/dev/null || true
    
    # Update VERSION file
    echo "$LATEST" > VERSION
    
    # Cleanup
    rm -f "$TEMP_ZIP"
    
    echo ""
    echo "✅ Updated to Mission Control $LATEST!"
    echo ""
    echo "📋 What's new: Check CHANGELOG.md"
    echo "🔙 Backup at: $BACKUP_DIR"
    echo ""
    echo "Note: Your local data (.mission-control/agents, tasks, etc.) was preserved."
    
  • scripts/validate.sh9.0 KBfb45c2ae10d6upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .claude/rules.md6.4 KBdcc44386d9ceupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .claude/skills/architecture.md3.4 KBd2aa6d9a5a59upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .claude/skills/coding-patterns.md4.4 KB49775765f77fupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .claude/skills/deploy.md2.8 KBe4f637e0febdupstream ↗
    # Deploy Guide — JARVIS Mission Control
    
    ## Production Environment
    
    - **Server:** zion.asif.dev (this IS the local machine — no SSH needed)
    - **Local URL:** http://localhost:3000
    - **External URL:** https://zion.asif.dev (nginx proxy, basic auth protected)
    - **Process:** PM2 (`mission-control-server`)
    - **Repo path:** `/root/.openclaw/workspace/agents/tank/mission-control/`
    
    ⚠️ **zion.asif.dev is PRIVATE** — never share it publicly, never put it in docs/READMEs.
    **Public demo:** https://missiondeck.ai/mission-control/demo
    
    ## Standard Deploy (after merge to main)
    
    ```bash
    cd /root/.openclaw/workspace/agents/tank/mission-control
    
    # Safe pull (backs up .mission-control/ first, then pulls)
    ./scripts/safe-deploy.sh --pull
    
    # Restart PM2
    pm2 restart mission-control-server
    
    # Verify
    pm2 status mission-control-server
    curl http://localhost:3000/api/metrics
    ```
    
    ## Deploy Checklist
    
    - [ ] PR merged to `main` by Oracle
    - [ ] `./scripts/safe-deploy.sh --pull` (NOT raw `git pull`)
    - [ ] `pm2 restart mission-control-server`
    - [ ] Check `pm2 logs mission-control-server` for errors
    - [ ] Verify `http://localhost:3000` responds
    - [ ] Update CHANGELOG.md if version bump
    
    ## Backup & Restore
    
    ```bash
    # Create named backup before risky changes
    ./scripts/safe-deploy.sh --backup pre-v2.1.0
    
    # List backups
    ls .mission-control-backups/
    
    # Restore
    ./scripts/safe-deploy.sh --restore pre-v2.1.0
    ```
    
    ## PM2 Commands
    
    ```bash
    pm2 status                           # All processes
    pm2 status mission-control-server    # This process only
    pm2 restart mission-control-server   # Restart (preserves env)
    pm2 logs mission-control-server      # View logs
    pm2 logs mission-control-server --lines 50  # Last 50 lines
    pm2 delete mission-control-server    # Kill it
    pm2 start ecosystem.config.cjs       # Start from ecosystem config (full env reload)
    ```
    
    ## Environment Variables
    
    Stored in `ecosystem.config.cjs` — do not hardcode in source files.
    
    Key vars:
    - `PORT` — server port (default 3000)
    - `TELEGRAM_BOT_TOKEN` — Telegram bridge token
    - `MISSIONDECK_API_KEY` — MissionDeck sync key
    - `BASIC_AUTH_USER` / `BASIC_AUTH_PASS` — external access credentials (see credentials file)
    
    ## nginx Config
    
    nginx proxies `zion.asif.dev` → `localhost:3000`. Do not touch the nginx config unless explicitly asked. If the server needs a restart:
    
    ```bash
    systemctl reload nginx
    ```
    
    ## Version Bump Process
    
    1. Update `VERSION` file with new semver
    2. Update `CHANGELOG.md` with changes
    3. Update version in `package.json`
    4. Commit: `[agent:tank] chore: bump version to X.Y.Z`
    5. Open PR → tag Oracle → wait for merge
    6. After merge: deploy as above
    
    ## Rollback
    
    If deploy breaks production:
    
    ```bash
    # Immediate rollback
    ./scripts/safe-deploy.sh --restore BACKUP_NAME
    pm2 restart mission-control-server
    ```
    
    Then report to Oracle with what happened.
    
  • .claude/skills/git-rules.md1.8 KBba13e207dfa7upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .claude/testing-rules.md5.7 KB59980323beafupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .clawhubignore401 Be6ceb5f38c05upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .clawhubsafe382 B5e8c09a9494dupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .context/DECISIONS.md7.5 KB4eb74ab1e907upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .context/PROJECT_CONTEXT.md12 KB153264cf4721upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .env.example1007 B6a5e3903bcc5upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .github/ISSUE_TEMPLATE/bug_report_auto_task_spam.md5.0 KB8da96456db66upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .github/workflows/deploy.yml2.4 KBeab157b5896cupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .gitignore1.1 KBd276052dc3dbupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/.gitignore967 Beb10e7d238a9upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/agents/.gitkeep0 Be69de29bb2d1upstream ↗
  • .mission-control/checklists/.gitkeep0 Be69de29bb2d1upstream ↗
  • .mission-control/config.yaml6.1 KBbbb8d115202fupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/hooks/on-agent-complete.sh2.3 KB2d0d4923b265upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/hooks/on-agent-error.sh2.2 KB145696d74059upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/hooks/on-agent-start.sh2.8 KB5d3d8a17e4a5upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/hooks/on-tool-use.sh2.7 KB117cdbfb0f37upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/humans/.gitkeep0 Be69de29bb2d1upstream ↗
  • .mission-control/integrations/events.schema.json3.0 KBd0318ecec243upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/integrations/telegram.example.yaml2.3 KB1a78ceb73b9dupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/integrations/webhooks.yaml2.0 KB63ae9d1b97c8upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/messages/.gitkeep0 Be69de29bb2d1upstream ↗
  • .mission-control/queue/.gitkeep0 Be69de29bb2d1upstream ↗
  • .mission-control/quotas/.gitkeep0 Be69de29bb2d1upstream ↗
  • .mission-control/resources/.gitkeep0 Be69de29bb2d1upstream ↗
  • .mission-control/schema/agent.schema.json3.6 KB16a901efb9a3upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/schema/task.schema.json4.4 KB507fc4b84180upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/schema/workflow.schema.json3.4 KBf11d127c9530upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/STATE.md3.3 KBb1e3f3dab046upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-control/tasks/.gitkeep0 Be69de29bb2d1upstream ↗
  • .mission-control/workflows/.gitkeep70 B7e8b22b30edeupstream ↗
    # Workflows directory
    # Store workflow definitions here as JSON files
    
  • .nojekyll0 Be69de29bb2d1upstream ↗
  • CHANGELOG.md16 KB2273b88e6319upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • CLAUDE.md48 KB16f275b212c0upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • cli/mc.js15 KB4a8f2bdbd18cupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • cli/package.json357 Baab68e672909upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/css/events-feed.css5.7 KBf0da032dd5f9upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/css/jarvis-hud.css11 KB1802341c59ccupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/css/mobile.css18 KB47cc1c407858upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/css/styles.css126 KB6615036df053upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/css/themes.css15 KBbced51104b53upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/index.html95 KB856215667285upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/api.js16 KB565ef0c39320upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/app.js118 KBf1443a3234cfupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/claude-sessions.js8.8 KBc2c0fa980fe5upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/cli-connections.js7.6 KB5a47b5ec777eupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/cli.js4.2 KBe9d0a8c5a5f4upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/dashboard-widgets.js6.4 KBb7cd6d0e6bf5upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/data.js51 KB68a8ea44f5d5upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/events-feed.js9.7 KB3d2b7489289dupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/github-issues.js6.0 KBc63ef25cded1upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/jarvis-hud.js14 KB2b14ad49ff9cupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/jarvis-voice.js5.2 KB214cef8edf40upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/openclaw-sessions.js8.5 KB7d3f69d52e55upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/smart-panels.js18 KBa348d5d66ce9upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/soul-files.js6.0 KBaddeb42a2577upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/update-banner.js2.1 KB10db0f99f081upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/js/webhooks.js10 KB21277959a971upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboard/robots.txt26 B1f53798bb4feupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • DEPLOYMENT-RULES.md3.5 KB14ec52f1bef1upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/AGENT-BRIDGE.md5.9 KB4329ef059159upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/AGENT_ADOPTION.md8.4 KB04738d6a7da3upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/api-reference.md10 KB788c7fa7fb89upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/architecture.md15 KB5affc85fcd73upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/archive/AGENT-BRIDGE-CLEANUP-LOG.md2.5 KB6ad92f24f31eupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/archive/FEATURE-SPEC-v2.md9.3 KB264323469dfbupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/archive/ISSUE-auto-sync.md3.3 KB08643d9413e9upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/archive/ISSUE-data-loss-resolved.md2.2 KB764e3110ec32upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/archive/PROPOSAL-v0.8.0.md20 KB508e6ea7bfbdupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/archive/SECURITY-FIX-PLAN.md2.4 KBcf221ca93c20upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/archive/SECURITY-VALIDATION-2026-03-03.md5.8 KB0946474df695upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/archive/SPRINT-DAY1.md6.3 KB9ec9bb695effupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/DEVELOPMENT_GUIDE.md15 KB9eb567d01e11upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/examples/example-agent-specialist.json964 Bd60aa2a56cb9upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/examples/example-workflow.json2.0 KB640959df2dccupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/openclaw-integration.md8.6 KB97b9f8f143fbupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/RESOURCE-MANAGEMENT.md6.4 KB75b6f9a21540upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/SECURITY.md8.8 KBf026eb4a8b94upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docs/TELEGRAM-INTEGRATION.md3.9 KB260db2f35b8dupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • ecosystem.config.cjs490 B85ba9046ace5upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/config/agents.json258 Bc35ffebf6b22upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/agents/agent-architect.json1.4 KBec349768d457upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/agents/agent-casey-feb.json864 B2c87eb1107aaupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/agents/agent-jarvis.json1.6 KB13680f12bfe4upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/agents/agent-jordan-feb.json847 B7177ead51e8dupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/agents/agent-morgan-feb.json876 B73f81c0f11beupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/agents/agent-neo.json1.3 KB16e42c8acf40upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/agents/agent-sam-feb.json873 B3547b330714bupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/agents/agent-trinity.json1.3 KB1cbae51aa76cupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/humans/architect.json629 B9034e6a41a57upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/humans/human-alex-feb.json361 Bdb8b2c7c855aupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/humans/human-nobin.json749 B98f2e3752802upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/messages/msg-20260205-001.json324 Bcc1d4e1c689cupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/messages/msg-20260205-002.json279 B23523cb1b5d0upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/messages/msg-20260205-003.json322 B16904bc95fa7upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/messages/msg-20260205-004.json336 B9a08183fdbccupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/messages/msg-20260205-010.json252 B2f4498ec8e82upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/messages/msg-20260205-011.json342 Be20aa926f4acupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/messages/msg-20260205-012.json248 B74e58bd96d2cupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/messages/msg-20260205-013.json287 Bb017782fd37dupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/tasks/task-20260205-example-feature.json1.6 KB1d034c006285upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/tasks/task-20260205-security-audit.json1.3 KBe6b68377d103upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/demo-data/tasks/task-20260205-setup-project.json2.1 KB4661e51a1c3dupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/local-data-templates/agent-example.json287 Be9419c6f7407upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/local-data-templates/task-example.json352 B6d665d7bb461upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/agent-template.json898 Be957475ffb6fupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/checklists/checklist-code-review.json1001 B22d4d6202d0fupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/checklists/checklist-deployment.json871 B9334a13af760upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/human-template.json379 Be9c827e6d208upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/message-template.json242 Bae3f26968748upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/queue/job-agent-sync.json580 B3120ca44fcc2upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/queue/job-backup.json556 B2c395938e9a7upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/queue/job-daily-report.json570 B79e6bfe568f8upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/queue/job-heartbeat-oracle.json535 B1da4caee8932upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/queue/queue-data-sync.json637 B04dfe20be711upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/queue/queue-health-check.json646 Bdec8f06bd590upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/quotas/quota-global-tokens.json310 B9056532a63a1upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/quotas/quota-sam-feb-api-calls.json309 Bf694358ae146upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/quotas/quotas.json745 B86b82042272eupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/resources/res-anthropic-api.json710 B2f290158eb73upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/resources/res-brave-search.json896 B42bd56ef7faaupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/resources/res-compute-cluster.json740 B260d543aed60upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/resources/res-elevenlabs-tts.json842 B5fea4b85868aupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/resources/res-github-api.json810 Bb3f90904d03fupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/resources/res-github-enterprise.json669 B1fd774c80ff6upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/resources/res-matrix-server.json863 Beeff96be79feupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/resources/res-openai-api.json677 B02c695d3263fupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/resources/res-telegram-bot.json888 Bba189c571c3cupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/task-template.json406 B868b30d5615bupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/workflows/workflow-default.json328 B0e49c63d5fb7upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examples/templates/workflows/workflow-multi-level.json506 B94c9e27b4e9dupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • index.html280 B4681cbef8d26upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • INIT.md4.4 KB60fa07c3f3d5upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • LICENSE11 KBaa406a27b09eupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • package-lock.json159 KB32857899853eupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • package.json656 B7ee2623166c1upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • SECURITY.md6.5 KBd010ee8d4b9bupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/agent-bridge.js34 KBf600e9c71b59upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/agent-sync.js14 KB1bcc8d8ad893upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/claude-sessions.js9.4 KBcdd1f251539aupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/cli-connections.js3.7 KB9d7d4b403f33upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/index.js110 KB4836068def4eupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/lib/cost-tracker.js5.5 KB2d369a67ec54upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/lib/event-logger.js4.8 KBf467afc650e4upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/logger.js1.0 KBdc32cba5916fupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/middleware/basic-auth.js1.9 KBc06ee584d64dupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/missiondeck-sync.js8.8 KB7d624990d936upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/openclaw-sessions.js6.8 KB8139425ea78eupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/package-lock.json65 KB1be955b08393upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/package.json722 B9d0b32376bfcupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/resource-manager.js19 KB3b8ea042d581upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/review-manager.js21 KBfedd95626495upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/start-all.js1.6 KB5b05e0570c13upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/telegram-bridge.js5.5 KB7232193cff33upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • server/webhook-delivery.js13 KB7a4a09c689d9upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skill/.clawhubsafe1.7 KB5f35ee576133upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skill/_meta.json1.9 KB65638b1b2236upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skill/references/1-setup.md1.8 KBfe35b176c866upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skill/references/2-missiondeck-connect.md3.0 KB3a887d33a871upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skill/references/3-mc-cli.md2.8 KBfd7fcfd212ddupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skill/references/4-data-population.md3.1 KB78976451b22fupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skill/SECURITY.md3.9 KBc0bba08bbcf0upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skills/dashboard.md4.6 KBbf16ac3a1c82upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skills/deployment.md8.7 KBc5efdbe74d29upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skills/integrations.md2.5 KB6ff931a17b55upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skills/messaging.md3.6 KB5ccac570f2d7upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skills/missiondeck-api.md7.4 KB52a8d625740bupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skills/notifications.md3.4 KBf87188d0ca32upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skills/orchestration.md3.6 KB7a1d0b7b8aedupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skills/review.md3.5 KB3de53ee6e820upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skills/setup.md4.9 KB6711669c9217upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skills/task-management.md3.9 KB6a61b5054684upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skills/telegram-bridge.md4.9 KB3e7c266a62f4upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • tests/basic-auth.test.js2.4 KBf9f72d6b16f0upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • tests/claude-sessions.test.js6.5 KB1985f0ebc2cbupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • tests/csrf.test.js2.4 KBc63df899e9a9upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • tests/github-issues.test.js5.2 KB3d76126389fbupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • tests/rate-limiter.test.js1.8 KB9b0eed1cf72cupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • tests/webhook-retry.test.js7.0 KB908f5b846b57upstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • VERSION6 B7ec1d6db4087upstream ↗
    2.1.0
    
  • .contextupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .githubupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • .mission-controlupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • ISSUE-auto-sync.mdupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • SECURITY-FIX-PLAN.mdupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • SECURITY-VALIDATION-2026-03-03.mdupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • cliupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • dashboardupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • docsupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • examplesupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • scriptsupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • serverupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skillupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • skillsupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

  • testsupstream ↗

    Contents are not inlined in the catalog. Open the upstream file.

Plain-text copy, no login: /skill-bundles/jarvis-mission-control.md

// REPO STATS

41 stars
2 open issues
Last commit: 2mo ago

// MORE FROM ASIF2BD