mission-control/scripts/mc.sh
OpenClaw Bot 95060930b1 feat: Add machine token auth for Mission Control CLI
- Add mc_api_call_machine() function for MC_MACHINE_TOKEN auth
- Update mc_api_call() to use machine token when available
- Allows cron jobs to authenticate without cookie-based login
- No breaking changes - cookie auth still works for interactive use
- Also updates default API URL to production (was localhost)
2026-02-26 08:31:14 -06:00

344 lines
8.5 KiB
Bash
Executable File

#!/bin/bash
# Mission Control CLI - Main Entry Point
# Usage: ./mc.sh <command> [args]
#
# Commands:
# auth Authentication (login, logout, session)
# task Task operations (delegates to gantt-board)
# project Project operations (delegates to gantt-board)
# sprint Sprint operations (delegates to gantt-board)
# search Search across tasks, projects, documents
# document Document management
# due-dates Tasks with due dates
# dashboard Dashboard data
#
# Environment:
# MC_API_URL Mission Control API URL (default: http://localhost:3001/api)
# GANTT_BOARD_DIR Path to gantt-board directory (auto-detected)
# MC_COOKIE_FILE Path to cookie file (default: ~/.config/mission-control/cookies.txt)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export SCRIPT_DIR
# Source API client library
source "$SCRIPT_DIR/lib/api_client.sh"
# Auto-detect gantt-board directory
if [[ -z "${GANTT_BOARD_DIR:-}" ]]; then
# Try common locations
if [[ -d "$SCRIPT_DIR/../../../gantt-board" ]]; then
GANTT_BOARD_DIR="$SCRIPT_DIR/../../../gantt-board"
elif [[ -d "$HOME/Documents/Projects/OpenClaw/Web/gantt-board" ]]; then
GANTT_BOARD_DIR="$HOME/Documents/Projects/OpenClaw/Web/gantt-board"
elif [[ -d "/Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board" ]]; then
GANTT_BOARD_DIR="/Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board"
fi
fi
# Show usage
usage() {
cat << 'EOF'
Mission Control CLI
Usage: ./mc.sh <command> [args]
Commands:
auth <subcommand> Authentication operations
login <email> <password> Login to Mission Control
logout Logout
session Show current session
task <args> Task operations (delegates to gantt-board)
See: ./task.sh --help
project <args> Project operations (delegates to gantt-board)
See: ./project.sh --help
sprint <args> Sprint operations (delegates to gantt-board)
See: ./sprint.sh --help
search <query> Search across tasks, projects, documents
due-dates List tasks with due dates
documents Document management
list List all documents
get <id> Get document by ID
dashboard Get dashboard data
Examples:
./mc.sh auth login user@example.com password
./mc.sh search "api design"
./mc.sh due-dates
./mc.sh task list --status open
./mc.sh project list
Environment Variables:
MC_API_URL Mission Control API URL (default: http://localhost:3001/api)
GANTT_BOARD_DIR Path to gantt-board directory
MC_COOKIE_FILE Path to cookie file
EOF
}
# Auth commands
handle_auth() {
local subcmd="${1:-}"
case "$subcmd" in
login)
local email="${2:-}"
local password="${3:-}"
if [[ -z "$email" || -z "$password" ]]; then
echo "Usage: ./mc.sh auth login <email> <password>" >&2
exit 1
fi
mc_login "$email" "$password"
;;
logout)
mc_logout
;;
session)
mc_get "/auth/session" | jq .
;;
*)
echo "Unknown auth subcommand: $subcmd" >&2
echo "Usage: ./mc.sh auth {login|logout|session}" >&2
exit 1
;;
esac
}
# Search command
handle_search() {
local query="${1:-}"
if [[ -z "$query" ]]; then
echo "Usage: ./mc.sh search <query>" >&2
exit 1
fi
local encoded_query
encoded_query=$(url_encode "$query")
mc_get "/search?q=$encoded_query" | jq .
}
# Due dates command
handle_due_dates() {
mc_get "/tasks/with-due-dates" | jq .
}
# Documents command
handle_documents() {
local subcmd="${1:-list}"
case "$subcmd" in
list)
mc_get "/documents" | jq .
;;
get)
local id="${2:-}"
if [[ -z "$id" ]]; then
echo "Usage: ./mc.sh documents get <id>" >&2
exit 1
fi
mc_get "/documents?id=$id" | jq .
;;
create)
shift # Remove 'create' from args
local title=""
local content=""
local folder="Research/"
local tags='["saved", "article"]'
local description=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--title)
title="$2"
shift 2
;;
--content)
content="$2"
shift 2
;;
--folder)
folder="$2"
shift 2
;;
--tags)
tags="$2"
shift 2
;;
--description)
description="$2"
shift 2
;;
*)
echo "Unknown option: $1" >&2
shift
;;
esac
done
# Validate required fields
if [[ -z "$title" ]]; then
echo "Usage: ./mc.sh documents create --title <title> --content <content> [--folder <folder>] [--tags <tags>] [--description <description>]" >&2
exit 1
fi
if [[ -z "$content" ]]; then
echo "Error: --content is required" >&2
exit 1
fi
# Get absolute path to mc.sh for API URL resolution
local SCRIPT_DIR
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export SCRIPT_DIR
source "$SCRIPT_DIR/lib/api_client.sh"
# Build JSON payload
local payload
payload=$(jq -n \
--arg title "$title" \
--arg content "$content" \
--arg type "markdown" \
--arg folder "$folder" \
--argjson tags "$tags" \
--arg size "${#content}" \
--arg description "${description:-Created via CLI}" \
'{
title: $title,
content: $content,
type: $type,
folder: $folder,
tags: $tags,
size: ($size | tonumber),
description: $description
}')
# Create document
mc_post "/documents" "$payload"
;;
*)
echo "Unknown documents subcommand: $subcmd" >&2
echo "Usage: ./mc.sh documents {list|get <id>|create <args>}" >&2
exit 1
;;
esac
}
# Task command - delegate to gantt-board
handle_task() {
if [[ -z "${GANTT_BOARD_DIR:-}" ]]; then
echo "Error: GANTT_BOARD_DIR not set and gantt-board not found" >&2
echo "Please set GANTT_BOARD_DIR to the path of your gantt-board installation" >&2
exit 1
fi
if [[ ! -f "$GANTT_BOARD_DIR/scripts/task.sh" ]]; then
echo "Error: gantt-board task.sh not found at $GANTT_BOARD_DIR/scripts/task.sh" >&2
exit 1
fi
# Delegate to gantt-board task.sh
exec "$GANTT_BOARD_DIR/scripts/task.sh" "$@"
}
# Project command - delegate to gantt-board
handle_project() {
if [[ -z "${GANTT_BOARD_DIR:-}" ]]; then
echo "Error: GANTT_BOARD_DIR not set and gantt-board not found" >&2
exit 1
fi
if [[ ! -f "$GANTT_BOARD_DIR/scripts/project.sh" ]]; then
echo "Error: gantt-board project.sh not found at $GANTT_BOARD_DIR/scripts/project.sh" >&2
exit 1
fi
exec "$GANTT_BOARD_DIR/scripts/project.sh" "$@"
}
# Sprint command - delegate to gantt-board
handle_sprint() {
if [[ -z "${GANTT_BOARD_DIR:-}" ]]; then
echo "Error: GANTT_BOARD_DIR not set and gantt-board not found" >&2
exit 1
fi
if [[ ! -f "$GANTT_BOARD_DIR/scripts/sprint.sh" ]]; then
echo "Error: gantt-board sprint.sh not found at $GANTT_BOARD_DIR/scripts/sprint.sh" >&2
exit 1
fi
exec "$GANTT_BOARD_DIR/scripts/sprint.sh" "$@"
}
# Dashboard command
handle_dashboard() {
# For now, combine multiple API calls to build dashboard view
echo "Fetching dashboard data..."
echo ""
echo "=== Tasks with Due Dates ==="
handle_due_dates | jq -r '.[] | "\(.due_date) | \(.priority) | \(.title)"' 2>/dev/null || echo "No tasks with due dates"
echo ""
echo "=== Recent Activity ==="
# This would need a dedicated API endpoint
echo "(Recent activity endpoint not yet implemented)"
}
# Main command dispatcher
main() {
local cmd="${1:-}"
shift || true
case "$cmd" in
auth)
handle_auth "$@"
;;
search)
handle_search "$@"
;;
due-dates)
handle_due_dates
;;
documents|document)
handle_documents "$@"
;;
task)
handle_task "$@"
;;
project)
handle_project "$@"
;;
sprint)
handle_sprint "$@"
;;
dashboard)
handle_dashboard
;;
help|--help|-h)
usage
;;
*)
if [[ -z "$cmd" ]]; then
usage
exit 1
fi
echo "Unknown command: $cmd" >&2
usage
exit 1
;;
esac
}
main "$@"