Files
blackroad/scripts/memory-task-marketplace.sh
Alexa Amundson 78fbe80f2a Initial monorepo — everything BlackRoad in one place
bin/       230 CLI tools (ask-*, br-*, agent-*, roadid, carpool)
scripts/   99 automation scripts
fleet/     Node configs and deployment
workers/   Cloudflare Worker sources (roadpay, road-search, squad webhooks)
roadc/     RoadC programming language
roadnet/   Mesh network (5 APs, WireGuard)
operator/  Memory system scripts
config/    System configs
dotfiles/  Shell configs
docs/      Documentation

BlackRoad OS — Pave Tomorrow.

RoadChain-SHA2048: d1a24f55318d338b
RoadChain-Identity: alexa@sovereign
RoadChain-Full: d1a24f55318d338b24b60bad7be39286379c76ae5470817482100cb0ddbbcb97e147d07ac7243da0a9f0363e4e5c833d612b9c0df3a3cd20802465420278ef74875a5b77f55af6fe42a931b8b635b3d0d0b6bde9abf33dc42eea52bc03c951406d8cbe49f1a3d29b26a94dade05e9477f34a7d4d4c6ec4005c3c2ac54e73a68440c512c8e83fd9b1fe234750b898ef8f4032c23db173961fe225e67a0432b5293a9714f76c5c57ed5fdf35b9fb40fd73c03ebf88b7253c6a0575f5afb6a6b49b3bda310602fb1ef676859962dad2aebbb2875814b30eee0a8ba195e482d4cbc91d8819e7f38f6db53e8063401649c77bb994371473cabfb917fb53e8cbe73d60
2026-03-14 17:08:41 -05:00

424 lines
15 KiB
Bash
Executable File

#!/bin/bash
# BlackRoad Task Marketplace - Where Claudes find work!
# A revolutionary system for multi-Claude coordination at scale
MEMORY_DIR="$HOME/.blackroad/memory"
TASKS_DIR="$MEMORY_DIR/tasks"
CLAIMED_DIR="$TASKS_DIR/claimed"
AVAILABLE_DIR="$TASKS_DIR/available"
COMPLETED_DIR="$TASKS_DIR/completed"
# 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'
# Initialize marketplace
init_marketplace() {
mkdir -p "$TASKS_DIR" "$CLAIMED_DIR" "$AVAILABLE_DIR" "$COMPLETED_DIR"
echo -e "${GREEN}✅ Task Marketplace initialized!${NC}"
}
# Post a new task
post_task() {
local task_id="$1"
local title="$2"
local description="$3"
local priority="${4:-medium}"
local tags="${5:-general}"
local skills="${6:-any}"
if [[ -z "$task_id" || -z "$title" ]]; then
echo -e "${RED}Usage: post <task-id> <title> <description> [priority] [tags] [skills]${NC}"
return 1
fi
local task_file="$AVAILABLE_DIR/${task_id}.json"
local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")
cat > "$task_file" << EOF
{
"task_id": "$task_id",
"title": "$title",
"description": "$description",
"priority": "$priority",
"tags": "$tags",
"skills": "$skills",
"status": "available",
"posted_at": "$timestamp",
"posted_by": "${MY_CLAUDE:-unknown}"
}
EOF
# Log to memory system
~/memory-system.sh log task-posted "$task_id" "📋 New task: $title (Priority: $priority, Skills: $skills, Tags: $tags)"
echo -e "${GREEN}✅ Task posted: ${CYAN}$task_id${NC}"
echo -e " ${BLUE}Title:${NC} $title"
echo -e " ${BLUE}Priority:${NC} $priority"
echo -e " ${BLUE}Skills:${NC} $skills"
}
# List available tasks
list_tasks() {
local filter_priority="$1"
local filter_tags="$2"
echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ 📋 BLACKROAD TASK MARKETPLACE 📋 ║${NC}"
echo -e "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
local available_count=$(find "$AVAILABLE_DIR" -maxdepth 1 -name "*.json" 2>/dev/null | wc -l | tr -d ' ')
local claimed_count=$(find "$CLAIMED_DIR" -maxdepth 1 -name "*.json" 2>/dev/null | wc -l | tr -d ' ')
local completed_count=$(find "$COMPLETED_DIR" -maxdepth 1 -name "*.json" 2>/dev/null | wc -l | tr -d ' ')
echo -e "${GREEN}Available:${NC} $available_count ${YELLOW}In Progress:${NC} $claimed_count ${BLUE}Completed:${NC} $completed_count"
echo ""
if [[ $available_count -eq 0 ]]; then
echo -e "${YELLOW}No tasks available. Post one with: ./memory-task-marketplace.sh post <task-id> <title> <description>${NC}"
return
fi
echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
for task_file in "$AVAILABLE_DIR"/*.json; do
[[ ! -f "$task_file" ]] && continue
local task_id=$(jq -r '.task_id' "$task_file")
local title=$(jq -r '.title' "$task_file")
local priority=$(jq -r '.priority' "$task_file")
local tags=$(jq -r '.tags' "$task_file")
local skills=$(jq -r '.skills' "$task_file")
local posted_at=$(jq -r '.posted_at' "$task_file")
# Filter by priority if specified
if [[ -n "$filter_priority" && "$priority" != "$filter_priority" ]]; then
continue
fi
# Filter by tags if specified
if [[ -n "$filter_tags" && "$tags" != *"$filter_tags"* ]]; then
continue
fi
# Priority color
local priority_color="$NC"
case "$priority" in
high|urgent) priority_color="$RED" ;;
medium) priority_color="$YELLOW" ;;
low) priority_color="$GREEN" ;;
esac
echo -e "${CYAN}📌 $task_id${NC}"
echo -e " ${BLUE}Title:${NC} $title"
echo -e " ${BLUE}Priority:${NC} ${priority_color}$priority${NC}"
echo -e " ${BLUE}Skills:${NC} $skills"
echo -e " ${BLUE}Tags:${NC} $tags"
echo -e " ${BLUE}Posted:${NC} $posted_at"
echo -e " ${GREEN}Claim with:${NC} ./memory-task-marketplace.sh claim $task_id"
echo ""
done
echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}
# Claim a task
claim_task() {
local task_id="$1"
local claude_id="${2:-${MY_CLAUDE:-unknown}}"
local timeout_minutes="${3:-30}"
if [[ -z "$task_id" ]]; then
echo -e "${RED}Usage: claim <task-id> [claude-id] [timeout-minutes]${NC}"
return 1
fi
local task_file="$AVAILABLE_DIR/${task_id}.json"
if [[ ! -f "$task_file" ]]; then
echo -e "${RED}❌ Task not found: $task_id${NC}"
echo -e "${YELLOW}Available tasks:${NC}"
ls -1 "$AVAILABLE_DIR"/*.json 2>/dev/null | xargs -n1 basename | sed 's/.json//' | sed 's/^/ - /'
return 1
fi
# Move to claimed
local claimed_file="$CLAIMED_DIR/${task_id}.json"
local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")
local timeout_at=$(date -u -v+${timeout_minutes}M +"%Y-%m-%dT%H:%M:%S.%3NZ" 2>/dev/null || date -u -d "+${timeout_minutes} minutes" +"%Y-%m-%dT%H:%M:%S.%3NZ")
# Update task with claim info
jq --arg claude "$claude_id" \
--arg timestamp "$timestamp" \
--arg timeout "$timeout_at" \
'.status = "claimed" | .claimed_by = $claude | .claimed_at = $timestamp | .timeout_at = $timeout' \
"$task_file" > "$claimed_file"
rm "$task_file"
# Log to memory
~/memory-system.sh log task-claimed "$task_id" "🎯 Claimed by $claude_id (timeout: ${timeout_minutes}m)"
echo -e "${GREEN}✅ Task claimed: ${CYAN}$task_id${NC}"
echo -e " ${BLUE}Claimed by:${NC} $claude_id"
echo -e " ${BLUE}Timeout:${NC} ${timeout_minutes} minutes ($timeout_at)"
echo -e " ${YELLOW}💡 Complete with:${NC} ./memory-task-marketplace.sh complete $task_id"
}
# Complete a task
complete_task() {
local task_id="$1"
local result="${2:-Success}"
if [[ -z "$task_id" ]]; then
echo -e "${RED}Usage: complete <task-id> [result]${NC}"
return 1
fi
local claimed_file="$CLAIMED_DIR/${task_id}.json"
if [[ ! -f "$claimed_file" ]]; then
echo -e "${RED}❌ Claimed task not found: $task_id${NC}"
return 1
fi
# Move to completed
local completed_file="$COMPLETED_DIR/${task_id}.json"
local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")
jq --arg timestamp "$timestamp" \
--arg result "$result" \
'.status = "completed" | .completed_at = $timestamp | .result = $result' \
"$claimed_file" > "$completed_file"
rm "$claimed_file"
# Log to memory
~/memory-system.sh log task-completed "$task_id" "✅ Completed: $result"
echo -e "${GREEN}🎉 Task completed: ${CYAN}$task_id${NC}"
echo -e " ${BLUE}Result:${NC} $result"
}
# Release a task (if can't complete)
release_task() {
local task_id="$1"
local reason="${2:-No reason given}"
if [[ -z "$task_id" ]]; then
echo -e "${RED}Usage: release <task-id> [reason]${NC}"
return 1
fi
local claimed_file="$CLAIMED_DIR/${task_id}.json"
if [[ ! -f "$claimed_file" ]]; then
echo -e "${RED}❌ Claimed task not found: $task_id${NC}"
return 1
fi
# Move back to available
local available_file="$AVAILABLE_DIR/${task_id}.json"
jq 'del(.claimed_by, .claimed_at, .timeout_at) | .status = "available"' \
"$claimed_file" > "$available_file"
rm "$claimed_file"
# Log to memory
~/memory-system.sh log task-released "$task_id" "🔄 Released: $reason"
echo -e "${YELLOW}🔄 Task released: ${CYAN}$task_id${NC}"
echo -e " ${BLUE}Reason:${NC} $reason"
}
# Show help
show_help() {
cat << EOF
${CYAN}╔════════════════════════════════════════════════════════════╗${NC}
${CYAN}║ 🎯 BlackRoad Task Marketplace - Help 🎯 ║${NC}
${CYAN}╚════════════════════════════════════════════════════════════╝${NC}
${GREEN}USAGE:${NC}
$0 <command> [options]
${GREEN}COMMANDS:${NC}
${BLUE}init${NC}
Initialize the task marketplace
${BLUE}post${NC} <task-id> <title> <description> [priority] [tags] [skills]
Post a new task
Priority: high|medium|low (default: medium)
Example: post auth-impl "Implement OAuth2" "Add OAuth2 auth" high backend backend-auth
${BLUE}list${NC} [priority] [tags]
List available tasks (optionally filtered)
Example: list high backend
${BLUE}claim${NC} <task-id> [claude-id] [timeout-minutes]
Claim a task to work on it (default timeout: 30 minutes)
Example: claim auth-impl claude-auth-specialist 60
${BLUE}complete${NC} <task-id> [result]
Mark a claimed task as completed
Example: complete auth-impl "OAuth2 implemented, tested, deployed"
${BLUE}release${NC} <task-id> [reason]
Release a claimed task back to available
Example: release auth-impl "Blocked on API deployment"
${BLUE}my-tasks${NC}
Show tasks claimed by you
${BLUE}stats${NC}
Show marketplace statistics
${GREEN}EXAMPLES:${NC}
# Initialize
$0 init
# Post a high-priority backend task
$0 post api-deploy "Deploy FastAPI backend" "Deploy to api.blackroad.io with PostgreSQL" high backend backend-api
# List all high-priority tasks
$0 list high
# Claim a task
MY_CLAUDE=claude-api-specialist $0 claim api-deploy
# Complete the task
$0 complete api-deploy "Deployed successfully to api.blackroad.io"
${GREEN}WORKFLOW:${NC}
1. Someone posts tasks to the marketplace
2. Claudes browse available tasks (list)
3. Claude claims a task to work on it
4. Claude completes the task (or releases if blocked)
5. Task moves to completed! 🎉
EOF
}
# Show tasks claimed by current Claude
my_tasks() {
local claude_id="${MY_CLAUDE:-unknown}"
echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ 📋 My Tasks ($claude_id) ║${NC}"
echo -e "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
local my_task_count=0
for task_file in "$CLAIMED_DIR"/*.json; do
[[ ! -f "$task_file" ]] && continue
local claimed_by=$(jq -r '.claimed_by' "$task_file")
if [[ "$claimed_by" == "$claude_id" ]]; then
local task_id=$(jq -r '.task_id' "$task_file")
local title=$(jq -r '.title' "$task_file")
local claimed_at=$(jq -r '.claimed_at' "$task_file")
local timeout_at=$(jq -r '.timeout_at' "$task_file")
echo -e "${CYAN}📌 $task_id${NC}"
echo -e " ${BLUE}Title:${NC} $title"
echo -e " ${BLUE}Claimed:${NC} $claimed_at"
echo -e " ${BLUE}Timeout:${NC} $timeout_at"
echo -e " ${GREEN}Complete:${NC} ./memory-task-marketplace.sh complete $task_id"
echo ""
((my_task_count++))
fi
done
if [[ $my_task_count -eq 0 ]]; then
echo -e "${YELLOW}No tasks claimed by you. Browse available tasks with: ./memory-task-marketplace.sh list${NC}"
fi
}
# Show statistics
show_stats() {
echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ 📊 Task Marketplace Statistics 📊 ║${NC}"
echo -e "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
local available_count=$(find "$AVAILABLE_DIR" -maxdepth 1 -name "*.json" 2>/dev/null | wc -l | tr -d ' ')
local claimed_count=$(find "$CLAIMED_DIR" -maxdepth 1 -name "*.json" 2>/dev/null | wc -l | tr -d ' ')
local completed_count=$(find "$COMPLETED_DIR" -maxdepth 1 -name "*.json" 2>/dev/null | wc -l | tr -d ' ')
local total=$((available_count + claimed_count + completed_count))
echo -e "${GREEN}📋 Total Tasks:${NC} $total"
echo -e "${YELLOW}⏳ Available:${NC} $available_count"
echo -e "${BLUE}🎯 Claimed:${NC} $claimed_count"
echo -e "${PURPLE}✅ Completed:${NC} $completed_count"
echo ""
if [[ $total -gt 0 ]]; then
local completion_rate=$((completed_count * 100 / total))
echo -e "${GREEN}📈 Completion Rate:${NC} ${completion_rate}%"
fi
echo ""
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
# Show who's working on what
if [[ $claimed_count -gt 0 ]]; then
echo -e "${BLUE}Active Workers:${NC}"
for task_file in "$CLAIMED_DIR"/*.json; do
[[ ! -f "$task_file" ]] && continue
local task_id=$(jq -r '.task_id' "$task_file")
local claimed_by=$(jq -r '.claimed_by' "$task_file")
local title=$(jq -r '.title' "$task_file")
echo -e " ${CYAN}$claimed_by${NC}$task_id: $title"
done
fi
}
# Main command router
case "$1" in
init)
init_marketplace
;;
post)
post_task "$2" "$3" "$4" "$5" "$6" "$7"
;;
list)
list_tasks "$2" "$3"
;;
claim)
claim_task "$2" "$3" "$4"
;;
complete)
complete_task "$2" "$3"
;;
release)
release_task "$2" "$3"
;;
my-tasks)
my_tasks
;;
stats)
show_stats
;;
help|--help|-h)
show_help
;;
*)
echo -e "${RED}Unknown command: $1${NC}"
echo -e "Run ${CYAN}$0 help${NC} for usage information"
exit 1
;;
esac