Files
Atomizer/hq/mission-control/scripts/mc-update.sh

188 lines
5.9 KiB
Bash
Executable File

#!/bin/bash
# Atomizer HQ Mission Control Task Update Script
# Wraps the skill's mc-update.sh but points to HQ's tasks.json
#
# Usage: mc-update.sh <command> <task_id> [args...]
#
# Commands:
# status <task_id> <new_status> - Update task status
# subtask <task_id> <subtask_id> done - Mark subtask done
# comment <task_id> "comment text" - Add comment
# add-subtask <task_id> "title" - Add new subtask
# complete <task_id> "summary" - Move to review + comment
# start <task_id> - Mark as being processed
# add "title" "description" [status] [project] [priority] - Add new task
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_DIR="$(dirname "$SCRIPT_DIR")"
export TASKS_FILE="$REPO_DIR/data/tasks.json"
sanitize_input() {
local val="$1"
local name="$2"
if [[ "$val" =~ [\`\$] ]]; then
echo "✗ Invalid characters in $name" >&2
exit 1
fi
}
case "$1" in
status)
TASK_ID="$2"; NEW_STATUS="$3"
[[ -z "$TASK_ID" || -z "$NEW_STATUS" ]] && { echo "Usage: mc-update.sh status <task_id> <new_status>"; exit 1; }
sanitize_input "$TASK_ID" "task_id"
sanitize_input "$NEW_STATUS" "status"
MC_TASK_ID="$TASK_ID" MC_NEW_STATUS="$NEW_STATUS" python3 -c "
import json, os
tf = os.environ['TASKS_FILE']
tid = os.environ['MC_TASK_ID']
ns = os.environ['MC_NEW_STATUS']
with open(tf) as f: d = json.load(f)
for t in d['tasks']:
if t['id'] == tid:
t['status'] = ns
break
else:
print(f'Task {tid} not found'); exit(1)
with open(tf, 'w') as f: json.dump(d, f, indent=2)
print(f'✓ {tid} → {ns}')
"
;;
comment)
TASK_ID="$2"; COMMENT="$3"
[[ -z "$TASK_ID" || -z "$COMMENT" ]] && { echo "Usage: mc-update.sh comment <task_id> \"text\""; exit 1; }
sanitize_input "$TASK_ID" "task_id"
MC_TASK_ID="$TASK_ID" MC_COMMENT="$COMMENT" python3 -c "
import json, os
from datetime import datetime, timezone
tf = os.environ['TASKS_FILE']
tid = os.environ['MC_TASK_ID']
cmt = os.environ['MC_COMMENT']
with open(tf) as f: d = json.load(f)
for t in d['tasks']:
if t['id'] == tid:
if 'comments' not in t: t['comments'] = []
t['comments'].append({'text': cmt, 'timestamp': datetime.now(timezone.utc).isoformat(), 'author': 'agent'})
break
else:
print(f'Task {tid} not found'); exit(1)
with open(tf, 'w') as f: json.dump(d, f, indent=2)
print(f'✓ Comment added to {tid}')
"
;;
subtask)
TASK_ID="$2"; SUB_ID="$3"; ACTION="$4"
MC_TASK_ID="$TASK_ID" MC_SUB_ID="$SUB_ID" python3 -c "
import json, os
tf = os.environ['TASKS_FILE']
tid = os.environ['MC_TASK_ID']
sid = os.environ['MC_SUB_ID']
with open(tf) as f: d = json.load(f)
for t in d['tasks']:
if t['id'] == tid:
for s in t.get('subtasks', []):
if s['id'] == sid:
s['done'] = True
break
break
with open(tf, 'w') as f: json.dump(d, f, indent=2)
print(f'✓ {tid}/{sid} marked done')
"
;;
add-subtask)
TASK_ID="$2"; TITLE="$3"
MC_TASK_ID="$TASK_ID" MC_TITLE="$TITLE" python3 -c "
import json, os
tf = os.environ['TASKS_FILE']
tid = os.environ['MC_TASK_ID']
title = os.environ['MC_TITLE']
with open(tf) as f: d = json.load(f)
for t in d['tasks']:
if t['id'] == tid:
subs = t.get('subtasks', [])
new_id = f'sub_{len(subs)+1:03d}'
subs.append({'id': new_id, 'title': title, 'done': False})
t['subtasks'] = subs
break
with open(tf, 'w') as f: json.dump(d, f, indent=2)
print(f'✓ Added subtask to {tid}')
"
;;
complete)
TASK_ID="$2"; SUMMARY="$3"
MC_TASK_ID="$TASK_ID" MC_SUMMARY="$SUMMARY" python3 -c "
import json, os
from datetime import datetime, timezone
tf = os.environ['TASKS_FILE']
tid = os.environ['MC_TASK_ID']
summary = os.environ['MC_SUMMARY']
with open(tf) as f: d = json.load(f)
for t in d['tasks']:
if t['id'] == tid:
t['status'] = 'review'
if 'comments' not in t: t['comments'] = []
t['comments'].append({'text': f'✅ Completed: {summary}', 'timestamp': datetime.now(timezone.utc).isoformat(), 'author': 'agent'})
break
with open(tf, 'w') as f: json.dump(d, f, indent=2)
print(f'✓ {tid} → review')
"
;;
start)
TASK_ID="$2"
MC_TASK_ID="$TASK_ID" python3 -c "
import json, os
from datetime import datetime, timezone
tf = os.environ['TASKS_FILE']
tid = os.environ['MC_TASK_ID']
with open(tf) as f: d = json.load(f)
for t in d['tasks']:
if t['id'] == tid:
t['status'] = 'in_progress'
t['processingStartedAt'] = datetime.now(timezone.utc).isoformat()
break
with open(tf, 'w') as f: json.dump(d, f, indent=2)
print(f'✓ {tid} started')
"
;;
add)
TITLE="$2"; DESC="$3"; STATUS="${4:-backlog}"; PROJECT="${5:-general}"; PRIORITY="${6:-medium}"
[[ -z "$TITLE" ]] && { echo "Usage: mc-update.sh add \"title\" \"description\" [status] [project] [priority]"; exit 1; }
MC_TITLE="$TITLE" MC_DESC="$DESC" MC_STATUS="$STATUS" MC_PROJECT="$PROJECT" MC_PRIORITY="$PRIORITY" python3 -c "
import json, os, hashlib
from datetime import datetime, timezone
tf = os.environ['TASKS_FILE']
with open(tf) as f: d = json.load(f)
now = datetime.now(timezone.utc)
task_id = 'ATZ-' + hashlib.md5(now.isoformat().encode()).hexdigest()[:6]
task = {
'id': task_id,
'title': os.environ['MC_TITLE'],
'description': os.environ['MC_DESC'],
'status': os.environ['MC_STATUS'],
'project': os.environ['MC_PROJECT'],
'tags': [],
'subtasks': [],
'priority': os.environ['MC_PRIORITY'],
'createdAt': now.isoformat(),
'comments': []
}
d['tasks'].append(task)
with open(tf, 'w') as f: json.dump(d, f, indent=2)
print(f'✓ Created {task_id}: {os.environ[\"MC_TITLE\"]}')
"
;;
*)
echo "Commands: status, comment, subtask, add-subtask, complete, start, add"
exit 1
;;
esac