chore(hq): daily sync 2026-02-19

This commit is contained in:
2026-02-19 10:00:18 +00:00
parent 7eb3d11f02
commit 176b75328f
71 changed files with 5928 additions and 1660 deletions

View File

@@ -0,0 +1,69 @@
# Atomizer-HQ Mission-Dashboard Protocol
## Overview
The Mission-Dashboard at `http://100.68.144.33:8091` is the **single source of truth** for all Atomizer HQ tasks. All agents MUST use it.
## Dashboard Location
- **URL:** http://100.68.144.33:8091
- **Data file:** ~/atomizer/mission-control/data/tasks.json
- **CLI tool:** ~/atomizer/mission-control/scripts/mc-update.sh
## Task Lifecycle
```
backlog → in_progress → review → done
```
| Status | Meaning |
|--------|---------|
| `permanent` | Recurring/standing tasks |
| `backlog` | Waiting to be worked on |
| `in_progress` | Agent is actively working |
| `review` | Done, awaiting human review |
| `done` | Approved by Antoine |
## Agent Responsibilities
### Manager
- Creates new tasks (`mc-update.sh add`)
- Assigns tasks to agents (via comments)
- Moves approved work to `done`
- ALL new projects/orchestrations MUST get a dashboard task
### All Agents
- When starting work: `mc-update.sh start <task_id>`
- Progress updates: `mc-update.sh comment <task_id> "update"`
- Subtask completion: `mc-update.sh subtask <task_id> <sub_id> done`
- When finished: `mc-update.sh complete <task_id> "summary"`
### Secretary
- Reviews task board during reports
- Flags stale in_progress tasks (>24h no update)
### Auditor
- Verifies completed tasks meet DoD before review
## CLI Reference
```bash
MC=~/atomizer/mission-control/scripts/mc-update.sh
# Add new task
$MC add "Title" "Description" [status] [project] [priority]
# Update status
$MC status ATZ-xxx in_progress
# Add comment
$MC comment ATZ-xxx "Progress update: completed phase 1"
# Mark subtask done
$MC subtask ATZ-xxx sub_001 done
# Complete (→ review)
$MC complete ATZ-xxx "Summary of what was done"
```
## Rules
1. **No shadow work** — if it's not on the dashboard, it didn't happen
2. **Update before Slack** — update the task, THEN discuss in Slack
3. **Every orchestration = a task** — Manager creates the task BEFORE spawning agents
4. **Comments are the audit trail** — agents log progress as comments, not just Slack messages

View File

@@ -0,0 +1,88 @@
{
"crons": [
{
"id": "d5e319ed",
"name": "Calendar Reminder",
"schedule": "*/15 * * * * (ET)",
"enabled": true,
"status": "ok",
"description": "Check Google Calendar for events in next 30 min, remind if imminent"
},
{
"id": "dd34f80a",
"name": "Nightly Restore",
"schedule": "0 0 * * * (ET)",
"enabled": true,
"status": "error",
"description": "RESTORE \u2192 SORT \u2192 DREAM \u2192 RESOLVE memory pipeline",
"lastError": "delivery target missing"
},
{
"id": "71be9066",
"name": "Git Auto-Commit",
"schedule": "0 3 * * * (ET)",
"enabled": true,
"status": "ok",
"description": "Daily commit+push for clawd, Atomizer, WEBtomaste, CODEtomaste"
},
{
"id": "1bb02334",
"name": "HQ Cluster \u2192 Gitea Sync",
"schedule": "0 5 * * * (ET)",
"enabled": true,
"status": "error",
"description": "Rsync ~/atomizer/ \u2192 Atomizer repo hq/ folder, commit+push",
"lastError": "Slack channel id format"
},
{
"id": "7d737126",
"name": "Morning Briefing",
"schedule": "0 12 * * 1-5 UTC (7 AM ET weekdays)",
"enabled": true,
"status": "error",
"description": "Daily briefing: calendar, weather, transcripts, priorities",
"lastError": "model not allowed: openai-codex/gpt-5.2"
},
{
"id": "8c25d356",
"name": "Credential Health Check",
"schedule": "0 13 * * * (ET)",
"enabled": true,
"status": "ok",
"description": "Check token expiry for Atomizer cluster credentials"
},
{
"id": "4ddc5f20",
"name": "Weekly Report",
"schedule": "0 21 * * 5 (ET, Friday 4 PM)",
"enabled": true,
"status": "error",
"description": "Weekly summary: tasks, decisions, blockers, carry-forwards",
"lastError": "model not allowed: openai-codex/gpt-5.2"
},
{
"id": "25015348",
"name": "Codex Token Renewal Reminder",
"schedule": "One-shot: Feb 22 9AM ET",
"enabled": true,
"status": "pending",
"description": "Remind Antoine to renew Codex OAuth tokens before Feb 24 expiry"
},
{
"id": "8889b659",
"name": "Codex Token Renewal Reminder (2)",
"schedule": "One-shot: Feb 22 2PM ET",
"enabled": true,
"status": "pending",
"description": "Second reminder for Codex token renewal"
},
{
"id": "92704624",
"name": "Codex Token Expiry Reminder",
"schedule": "One-shot: Feb 22 2PM ET",
"enabled": true,
"status": "pending",
"description": "Third reminder for Codex token renewal"
}
]
}

View File

@@ -0,0 +1,126 @@
{
"tasks": [
{
"id": "guide_onboarding",
"title": "\ud83c\udfed Atomizer HQ \u2014 Mission Control",
"description": "Self-hosted dashboard at http://100.68.144.33:8091\n\nAgents update tasks by writing to ~/atomizer/mission-control/data/tasks.json.\nNo GitHub tokens needed \u2014 everything is local.\n\nManaged by: Manager agent\nBacked up to: Gitea (Atomizer-HQ repo)",
"status": "permanent",
"project": "meta",
"tags": [
"guide",
"setup"
],
"subtasks": [
{
"id": "sub_001",
"title": "Dashboard is live and accessible \u2705",
"done": true
},
{
"id": "sub_002",
"title": "Systemd service running (atomizer-hq-dashboard)",
"done": true
},
{
"id": "sub_003",
"title": "Backed by Gitea repo",
"done": true
}
],
"priority": "high",
"dod": "Dashboard is live on GitHub Pages and connected"
},
{
"id": "ATZ-001",
"title": "\ud83e\uddea Test Orchestration: Material Trade Study Mini-Project",
"description": "End-to-end test of the Atomizer HQ orchestration pipeline.\n\n**Objective:** Compare two candidate materials for a hypothetical lightweight bracket:\n- 7075-T6 Aluminum\n- Ti-6Al-4V Titanium\n\n**Criteria:** Strength-to-weight, cost, machinability, fatigue life\n\n**Expected workflow:**\n1. Manager receives this task\n2. Manager spawns Webster \u2192 research material properties\n3. Manager spawns Tech Lead \u2192 evaluate trade-offs\n4. Manager spawns Auditor \u2192 review the evaluation\n5. Manager spawns Secretary \u2192 write summary to #reports\n\nThis is a TEST to validate the orchestration pipeline works end-to-end.",
"status": "backlog",
"project": "test",
"tags": [
"test",
"orchestration",
"materials"
],
"assignee": "manager",
"subtasks": [
{
"id": "s1",
"title": "Webster: Research material properties (density, yield, UTS, fatigue, cost/kg)",
"assignee": "webster",
"done": false
},
{
"id": "s2",
"title": "Tech Lead: Evaluate trade-offs with weighted scoring matrix",
"assignee": "tech-lead",
"done": false
},
{
"id": "s3",
"title": "Auditor: Review methodology and conclusions",
"assignee": "auditor",
"done": false
},
{
"id": "s4",
"title": "Secretary: Write summary and post to #reports",
"assignee": "secretary",
"done": false
}
],
"deliverables": [],
"comments": [],
"priority": "high",
"dod": "Complete trade study with recommendation, reviewed by auditor, summary in #reports"
},
{
"id": "ATZ-749aac",
"title": "\ud83d\udccb Standardization Review \u2014 Project Structure & Protocols",
"description": "Review and standardize all agent project structures, communication protocols, and deliverable formats.\\n\\nThis was discussed and reviewed but never tracked on the dashboard.\\n\\nScope:\\n- Agent workspace structure standards\\n- Task lifecycle protocol\\n- Deliverable schema enforcement\\n- Communication routing rules",
"status": "review",
"project": "standards",
"tags": [],
"subtasks": [],
"priority": "high",
"createdAt": "2026-02-19T01:26:27.796175+00:00",
"comments": []
},
{
"id": "ATZ-2f1634",
"title": "\ud83d\udd27 P-Adaptive-Isogrid \u2014 Plate Lightweighting Tool",
"description": "Automated plate lightweighting via isogrid pattern optimization.\\n\\nArchitecture: Python Brain + NX Hands + Atomizer Manager\\nRepo: Atomizer/tools/adaptive-isogrid/\\n15 optimization params (Optuna TPE), AFEM with superposed models\\n\\nPhases:\\n- Phase 0: Foundation \u2705\\n- Phase 1: Python Brain standalone (CURRENT)\\n- Phase 2: NX sandbox scripts\\n- Phase 3: Full integration",
"status": "in_progress",
"project": "engineering",
"tags": [],
"subtasks": [],
"priority": "high",
"createdAt": "2026-02-19T01:32:13.987900+00:00",
"comments": []
},
{
"id": "ATZ-74f02a",
"title": "\ud83e\udd16 Atomizer Overhaul \u2014 Framework Agentic",
"description": "Transform Atomizer into multi-agent FEA optimization company.\\n\\n8 agents deployed on Discord/Slack cluster.\\nPhase 0: LIVE since 2026-02-08.\\n\\nInfrastructure:\\n- 8 OpenClaw instances (systemd template)\\n- Dedicated Slack + Discord workspaces\\n- Orchestration via orchestrate.sh + workflow.py\\n\\nCurrent focus: Agent protocols, dashboard integration, task enforcement.",
"status": "in_progress",
"project": "infrastructure",
"tags": [],
"subtasks": [],
"priority": "high",
"createdAt": "2026-02-19T01:32:14.030119+00:00",
"comments": []
},
{
"id": "ATZ-c13dfc",
"title": "\u2699\ufe0f Atomizer Core \u2014 Foundation Development",
"description": "Core Atomizer framework development.\\n\\nRepo: /home/papa/repos/Atomizer/\\nKnowledge base: Atomizer/knowledge_base/\\n\\nOngoing work:\\n- Code architecture improvements\\n- Knowledge base maintenance (LAC session insights)\\n- Documentation and QUICK_REF updates\\n- Bridge doc: PROJECT_STATUS.md",
"status": "permanent",
"project": "engineering",
"tags": [],
"subtasks": [],
"priority": "medium",
"createdAt": "2026-02-19T01:32:14.115298+00:00",
"comments": []
}
],
"lastUpdated": "2026-02-19T01:37:05.917Z"
}

View File

@@ -0,0 +1,77 @@
{
"tasks": [
{
"id": "guide_onboarding",
"title": "\ud83c\udfed Atomizer HQ \u2014 Mission Control",
"description": "Self-hosted dashboard at http://100.68.144.33:8091\n\nAgents update tasks by writing to ~/atomizer/mission-control/data/tasks.json.\nNo GitHub tokens needed \u2014 everything is local.\n\nManaged by: Manager agent\nBacked up to: Gitea (Atomizer-HQ repo)",
"status": "permanent",
"project": "meta",
"tags": [
"guide",
"setup"
],
"subtasks": [
{
"id": "sub_001",
"title": "Dashboard is live and accessible \u2705",
"done": true
},
{
"id": "sub_002",
"title": "Systemd service running (atomizer-hq-dashboard)",
"done": true
},
{
"id": "sub_003",
"title": "Backed by Gitea repo",
"done": true
}
],
"priority": "high",
"dod": "Dashboard is live on GitHub Pages and connected"
},
{
"id": "ATZ-001",
"title": "\ud83e\uddea Test Orchestration: Material Trade Study Mini-Project",
"description": "End-to-end test of the Atomizer HQ orchestration pipeline.\n\n**Objective:** Compare two candidate materials for a hypothetical lightweight bracket:\n- 7075-T6 Aluminum\n- Ti-6Al-4V Titanium\n\n**Criteria:** Strength-to-weight, cost, machinability, fatigue life\n\n**Expected workflow:**\n1. Manager receives this task\n2. Manager spawns Webster \u2192 research material properties\n3. Manager spawns Tech Lead \u2192 evaluate trade-offs\n4. Manager spawns Auditor \u2192 review the evaluation\n5. Manager spawns Secretary \u2192 write summary to #reports\n\nThis is a TEST to validate the orchestration pipeline works end-to-end.",
"status": "backlog",
"project": "test",
"tags": [
"test",
"orchestration",
"materials"
],
"assignee": "manager",
"subtasks": [
{
"id": "s1",
"title": "Webster: Research material properties (density, yield, UTS, fatigue, cost/kg)",
"assignee": "webster",
"done": false
},
{
"id": "s2",
"title": "Tech Lead: Evaluate trade-offs with weighted scoring matrix",
"assignee": "tech-lead",
"done": false
},
{
"id": "s3",
"title": "Auditor: Review methodology and conclusions",
"assignee": "auditor",
"done": false
},
{
"id": "s4",
"title": "Secretary: Write summary and post to #reports",
"assignee": "secretary",
"done": false
}
],
"deliverables": [],
"comments": [],
"priority": "high",
"dod": "Complete trade study with recommendation, reviewed by auditor, summary in #reports"
}
]
}

View File

@@ -0,0 +1,89 @@
{
"tasks": [
{
"id": "guide_onboarding",
"title": "\ud83c\udfed Atomizer HQ \u2014 Mission Control",
"description": "Self-hosted dashboard at http://100.68.144.33:8091\n\nAgents update tasks by writing to ~/atomizer/mission-control/data/tasks.json.\nNo GitHub tokens needed \u2014 everything is local.\n\nManaged by: Manager agent\nBacked up to: Gitea (Atomizer-HQ repo)",
"status": "permanent",
"project": "meta",
"tags": [
"guide",
"setup"
],
"subtasks": [
{
"id": "sub_001",
"title": "Dashboard is live and accessible \u2705",
"done": true
},
{
"id": "sub_002",
"title": "Systemd service running (atomizer-hq-dashboard)",
"done": true
},
{
"id": "sub_003",
"title": "Backed by Gitea repo",
"done": true
}
],
"priority": "high",
"dod": "Dashboard is live on GitHub Pages and connected"
},
{
"id": "ATZ-001",
"title": "\ud83e\uddea Test Orchestration: Material Trade Study Mini-Project",
"description": "End-to-end test of the Atomizer HQ orchestration pipeline.\n\n**Objective:** Compare two candidate materials for a hypothetical lightweight bracket:\n- 7075-T6 Aluminum\n- Ti-6Al-4V Titanium\n\n**Criteria:** Strength-to-weight, cost, machinability, fatigue life\n\n**Expected workflow:**\n1. Manager receives this task\n2. Manager spawns Webster \u2192 research material properties\n3. Manager spawns Tech Lead \u2192 evaluate trade-offs\n4. Manager spawns Auditor \u2192 review the evaluation\n5. Manager spawns Secretary \u2192 write summary to #reports\n\nThis is a TEST to validate the orchestration pipeline works end-to-end.",
"status": "backlog",
"project": "test",
"tags": [
"test",
"orchestration",
"materials"
],
"assignee": "manager",
"subtasks": [
{
"id": "s1",
"title": "Webster: Research material properties (density, yield, UTS, fatigue, cost/kg)",
"assignee": "webster",
"done": false
},
{
"id": "s2",
"title": "Tech Lead: Evaluate trade-offs with weighted scoring matrix",
"assignee": "tech-lead",
"done": false
},
{
"id": "s3",
"title": "Auditor: Review methodology and conclusions",
"assignee": "auditor",
"done": false
},
{
"id": "s4",
"title": "Secretary: Write summary and post to #reports",
"assignee": "secretary",
"done": false
}
],
"deliverables": [],
"comments": [],
"priority": "high",
"dod": "Complete trade study with recommendation, reviewed by auditor, summary in #reports"
},
{
"id": "ATZ-749aac",
"title": "\ud83d\udccb Standardization Review \u2014 Project Structure & Protocols",
"description": "Review and standardize all agent project structures, communication protocols, and deliverable formats.\\n\\nThis was discussed and reviewed but never tracked on the dashboard.\\n\\nScope:\\n- Agent workspace structure standards\\n- Task lifecycle protocol\\n- Deliverable schema enforcement\\n- Communication routing rules",
"status": "review",
"project": "standards",
"tags": [],
"subtasks": [],
"priority": "high",
"createdAt": "2026-02-19T01:26:27.796175+00:00",
"comments": []
}
]
}

View File

@@ -0,0 +1,161 @@
{
"tasks": [
{
"id": "guide_onboarding",
"title": "\ud83c\udfed Atomizer HQ \u2014 Mission Control",
"description": "Self-hosted dashboard at http://100.68.144.33:8091\n\nAgents update tasks by writing to ~/atomizer/mission-control/data/tasks.json.\nNo GitHub tokens needed \u2014 everything is local.\n\nManaged by: Manager agent\nBacked up to: Gitea (Atomizer-HQ repo)",
"status": "permanent",
"project": "meta",
"tags": [
"guide",
"setup"
],
"subtasks": [
{
"id": "sub_001",
"title": "Dashboard is live and accessible \u2705",
"done": true
},
{
"id": "sub_002",
"title": "Systemd service running (atomizer-hq-dashboard)",
"done": true
},
{
"id": "sub_003",
"title": "Backed by Gitea repo",
"done": true
}
],
"priority": "high",
"dod": "Dashboard is live on GitHub Pages and connected"
},
{
"id": "ATZ-001",
"title": "\ud83e\uddea Test Orchestration: Material Trade Study Mini-Project",
"description": "End-to-end test of the Atomizer HQ orchestration pipeline.\n\n**Objective:** Compare two candidate materials for a hypothetical lightweight bracket:\n- 7075-T6 Aluminum\n- Ti-6Al-4V Titanium\n\n**Criteria:** Strength-to-weight, cost, machinability, fatigue life\n\n**Expected workflow:**\n1. Manager receives this task\n2. Manager spawns Webster \u2192 research material properties\n3. Manager spawns Tech Lead \u2192 evaluate trade-offs\n4. Manager spawns Auditor \u2192 review the evaluation\n5. Manager spawns Secretary \u2192 write summary to #reports\n\nThis is a TEST to validate the orchestration pipeline works end-to-end.",
"status": "backlog",
"project": "test",
"tags": [
"test",
"orchestration",
"materials"
],
"assignee": "manager",
"subtasks": [
{
"id": "s1",
"title": "Webster: Research material properties (density, yield, UTS, fatigue, cost/kg)",
"assignee": "webster",
"done": false
},
{
"id": "s2",
"title": "Tech Lead: Evaluate trade-offs with weighted scoring matrix",
"assignee": "tech-lead",
"done": false
},
{
"id": "s3",
"title": "Auditor: Review methodology and conclusions",
"assignee": "auditor",
"done": false
},
{
"id": "s4",
"title": "Secretary: Write summary and post to #reports",
"assignee": "secretary",
"done": false
}
],
"deliverables": [],
"comments": [],
"priority": "high",
"dod": "Complete trade study with recommendation, reviewed by auditor, summary in #reports"
},
{
"id": "ATZ-749aac",
"title": "\ud83d\udccb Standardization Review \u2014 Project Structure & Protocols",
"description": "Review and standardize all agent project structures, communication protocols, and deliverable formats.\\n\\nThis was discussed and reviewed but never tracked on the dashboard.\\n\\nScope:\\n- Agent workspace structure standards\\n- Task lifecycle protocol\\n- Deliverable schema enforcement\\n- Communication routing rules",
"status": "review",
"project": "standards",
"tags": [],
"subtasks": [],
"priority": "high",
"createdAt": "2026-02-19T01:26:27.796175+00:00",
"comments": []
},
{
"id": "ATZ-2f1634",
"title": "\ud83d\udd27 P-Adaptive-Isogrid \u2014 Plate Lightweighting Tool",
"description": "Automated plate lightweighting via isogrid pattern optimization.\\n\\nArchitecture: Python Brain + NX Hands + Atomizer Manager\\nRepo: Atomizer/tools/adaptive-isogrid/\\n15 optimization params (Optuna TPE), AFEM with superposed models\\n\\nPhases:\\n- Phase 0: Foundation \u2705\\n- Phase 1: Python Brain standalone (CURRENT)\\n- Phase 2: NX sandbox scripts\\n- Phase 3: Full integration",
"status": "in_progress",
"project": "engineering",
"tags": [],
"subtasks": [],
"priority": "high",
"createdAt": "2026-02-19T01:32:13.987900+00:00",
"comments": []
},
{
"id": "ATZ-74f02a",
"title": "\ud83e\udd16 Atomizer Overhaul \u2014 Framework Agentic",
"description": "Transform Atomizer into multi-agent FEA optimization company.\\n\\n8 agents deployed on Discord/Slack cluster.\\nPhase 0: LIVE since 2026-02-08.\\n\\nInfrastructure:\\n- 8 OpenClaw instances (systemd template)\\n- Dedicated Slack + Discord workspaces\\n- Orchestration via orchestrate.sh + workflow.py\\n\\nCurrent focus: Agent protocols, dashboard integration, task enforcement.",
"status": "in_progress",
"project": "infrastructure",
"tags": [],
"subtasks": [],
"priority": "high",
"createdAt": "2026-02-19T01:32:14.030119+00:00",
"comments": []
},
{
"id": "ATZ-afd82a",
"title": "\u2b50 P04 \u2014 GigaBIT M1 (StarSpec)",
"description": "StarSpec client project \u2014 HIGH priority.\\n\\nStatus: CDR approved, procurement phase.\\nSelected: Option B (Conical V14)\\nCDR documentation delivered, two reviews done.\\n\\nActive work:\\n- Lateral shoe CBUSH interface (GF-PTFE 25%)\\n- M2/M3 material evaluation (Ohara Clearceram-Z HS vs Zerodur)\\n- INO collaboration for interferometer (contacts: Topart, Doucet, Denoyer)\\n- Collaboration definition report in progress",
"status": "in_progress",
"project": "client",
"tags": [],
"subtasks": [],
"priority": "high",
"createdAt": "2026-02-19T01:32:14.072849+00:00",
"comments": []
},
{
"id": "ATZ-c13dfc",
"title": "\u2699\ufe0f Atomizer Core \u2014 Foundation Development",
"description": "Core Atomizer framework development.\\n\\nRepo: /home/papa/repos/Atomizer/\\nKnowledge base: Atomizer/knowledge_base/\\n\\nOngoing work:\\n- Code architecture improvements\\n- Knowledge base maintenance (LAC session insights)\\n- Documentation and QUICK_REF updates\\n- Bridge doc: PROJECT_STATUS.md",
"status": "permanent",
"project": "engineering",
"tags": [],
"subtasks": [],
"priority": "medium",
"createdAt": "2026-02-19T01:32:14.115298+00:00",
"comments": []
},
{
"id": "ATZ-672077",
"title": "\ud83d\udcf9 P-CAD-Documenter \u2014 Video \u2192 Engineering Docs",
"description": "Major new skill: video walkthrough \u2192 complete engineering documentation.\\n\\nIntegrates: Atomizer, Part Manager, Atomaste Reports.\\nProject doc: 2-Projects/P-CAD-Documenter/\\n\\nStatus: Planning phase.",
"status": "backlog",
"project": "engineering",
"tags": [],
"subtasks": [],
"priority": "medium",
"createdAt": "2026-02-19T01:32:14.158364+00:00",
"comments": []
},
{
"id": "ATZ-5138af",
"title": "\ud83d\udcb0 P-ALSOFinance \u2014 Portfolio Tracker",
"description": "Portfolio tracker application.\\n\\nRepo: http://100.80.199.40:3000/Antoine/ALSOFinance\\nStack: React + FastAPI + PostgreSQL + Redis\\n\\nStatus: Needs deployment on dalidou.",
"status": "backlog",
"project": "tools",
"tags": [],
"subtasks": [],
"priority": "low",
"createdAt": "2026-02-19T01:32:14.199513+00:00",
"comments": []
}
]
}

View File

@@ -0,0 +1,187 @@
#!/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

View File

@@ -0,0 +1,73 @@
#!/usr/bin/env python3
"""Simple HTTP server with save API for Mission Control."""
import http.server
import json
import os
import shutil
from datetime import datetime
PORT = 8091
os.chdir(os.path.dirname(os.path.abspath(__file__)))
class MissionControlHandler(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
self.send_header('Pragma', 'no-cache')
self.send_header('Expires', '0')
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, PUT, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Content-Type')
super().end_headers()
def do_OPTIONS(self):
self.send_response(200)
self.end_headers()
def do_PUT(self):
path = self.path.lstrip('/')
if not path.startswith('data/') or not path.endswith('.json'):
self.send_response(403)
self.end_headers()
self.wfile.write(b'{"error":"Only data/*.json writes allowed"}')
return
content_length = int(self.headers.get('Content-Length', 0))
body = self.rfile.read(content_length)
try:
data = json.loads(body)
except json.JSONDecodeError as e:
self.send_response(400)
self.end_headers()
self.wfile.write(json.dumps({"error": f"Invalid JSON: {e}"}).encode())
return
filepath = os.path.join(os.getcwd(), path)
os.makedirs(os.path.dirname(filepath), exist_ok=True)
if os.path.exists(filepath):
backup = filepath + f'.bak-{datetime.now().strftime("%Y%m%d-%H%M%S")}'
shutil.copy2(filepath, backup)
bak_dir = os.path.dirname(filepath)
bak_base = os.path.basename(filepath)
baks = sorted([f for f in os.listdir(bak_dir) if f.startswith(bak_base + '.bak-')])
for old in baks[:-10]:
os.remove(os.path.join(bak_dir, old))
with open(filepath, 'w') as f:
json.dump(data, f, indent=2)
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({"ok": True, "saved": path}).encode())
def log_message(self, format, *args):
pass
if __name__ == '__main__':
class ThreadedServer(http.server.ThreadingHTTPServer):
allow_reuse_address = True
server = ThreadedServer(('0.0.0.0', PORT), MissionControlHandler)
print(f'Atomizer HQ Mission Control serving on port {PORT}')
server.serve_forever()