diff --git a/scripts/training/generate_certificates.py b/scripts/training/generate_certificates.py
new file mode 100644
index 00000000..85e4d756
--- /dev/null
+++ b/scripts/training/generate_certificates.py
@@ -0,0 +1,331 @@
+#!/usr/bin/env python3
+"""
+Certificate and Badge Generator for AITBC Training
+
+Generates:
+1. Markdown badges (shields.io style) for completed stages
+2. HTML certificates with proper formatting
+3. Summary certificate for completing all stages
+"""
+
+import json
+import os
+import sys
+from datetime import datetime, timezone
+from pathlib import Path
+
+CERT_DIR = Path(__file__).parent / ".training_state" / "certificates"
+BADGE_DIR = Path(__file__).parent / ".training_state" / "badges"
+HTML_DIR = Path(__file__).parent / ".training_state" / "html_certificates"
+
+
+def ensure_dirs():
+ """Ensure output directories exist."""
+ BADGE_DIR.mkdir(parents=True, exist_ok=True)
+ HTML_DIR.mkdir(parents=True, exist_ok=True)
+
+
+def load_certificate(stage_num: int) -> dict:
+ """Load certificate JSON for a stage."""
+ cert_file = CERT_DIR / f"stage{stage_num}_certificate.json"
+ if not cert_file.exists():
+ return None
+ with open(cert_file) as f:
+ return json.load(f)
+
+
+def generate_markdown_badge(stage_num: int, cert_data: dict) -> str:
+ """Generate shields.io markdown badge for a stage."""
+ badge_label = f"Stage {stage_num}"
+ badge_message = "Completed"
+ badge_color = "brightgreen"
+
+ # URL encode spaces
+ badge_url = f"https://img.shields.io/badge/{badge_label.replace(' ', '%20')}-{badge_message.replace(' ', '%20')}-{badge_color}?style=flat-square"
+ markdown = f"[]({CERT_DIR}/stage{stage_num}_certificate.json)"
+ return markdown
+
+
+def generate_html_certificate(stage_num: int, cert_data: dict) -> str:
+ """Generate HTML certificate for a stage."""
+ stage_name = cert_data.get("stage_name", f"Stage {stage_num}")
+ timestamp = cert_data.get("completion_timestamp", datetime.now(timezone.utc).isoformat())
+ wallet = cert_data.get("wallet_name", "Unknown")
+ cert_id = cert_data.get("certificate_id", "Unknown")
+
+ html = f"""
+
+
+ Certificate - Stage {stage_num}
+
+
+
+
+
+
AITBC Agent Training Program
+
+
Stage {stage_num}: {stage_name}
+
+
+
+ Certificate ID: {cert_id}
+
+
+ Completed: {timestamp}
+
+
+ Wallet: {wallet}
+
+
+ Training Program: hermes AITBC Mastery Training
+
+
+
+
+ ✓ Stage Completed
+ ✓ Hands-On Training
+ ✓ Blockchain Verified
+
+
+
+
+
+"""
+ return html
+
+
+def generate_summary_certificate(completed_stages: list) -> str:
+ """Generate summary HTML certificate for completing all stages."""
+ stages_html = ""
+ for stage in sorted(completed_stages):
+ cert = load_certificate(stage)
+ stage_name = cert.get("stage_name", f"Stage {stage}") if cert else f"Stage {stage}"
+ stages_html += f' Stage {stage}: {stage_name}
\n'
+
+ html = f"""
+
+
+ Mastery Certificate - AITBC Training
+
+
+
+
+
+
AITBC Agent Training Program
+
+
+ Congratulations! You have completed all {len(completed_stages)} training stages
+
+
+
+{stages_html}
+
+
+
+
+
+"""
+ return html
+
+
+def generate_markdown_summary(completed_stages: list) -> str:
+ """Generate Markdown summary with all badges."""
+ markdown = "# AITBC Training Certificates\n\n"
+ markdown += f"Completed {len(completed_stages)} / 11 stages\n\n"
+
+ markdown += "## Badges\n\n"
+ for stage in sorted(completed_stages):
+ cert = load_certificate(stage)
+ if cert:
+ badge = generate_markdown_badge(stage, cert)
+ markdown += f"{badge} "
+
+ markdown += "\n\n## Stages Completed\n\n"
+ for stage in sorted(completed_stages):
+ cert = load_certificate(stage)
+ if cert:
+ stage_name = cert.get("stage_name", f"Stage {stage}")
+ timestamp = cert.get("completion_timestamp", "Unknown")
+ markdown += f"- **Stage {stage}: {stage_name}** - Completed {timestamp}\n"
+
+ return markdown
+
+
+def main():
+ """Main function."""
+ ensure_dirs()
+
+ # Find all completed stages
+ completed_stages = []
+ for i in range(11): # Stages 0-10
+ cert = load_certificate(i)
+ if cert:
+ completed_stages.append(i)
+
+ # Generate markdown badge
+ badge_md = generate_markdown_badge(i, cert)
+ badge_file = BADGE_DIR / f"stage{i}_badge.md"
+ with open(badge_file, 'w') as f:
+ f.write(badge_md)
+
+ # Generate HTML certificate
+ html = generate_html_certificate(i, cert)
+ html_file = HTML_DIR / f"stage{i}_certificate.html"
+ with open(html_file, 'w') as f:
+ f.write(html)
+
+ print(f"✓ Generated badge and HTML certificate for Stage {i}")
+
+ # Generate summary certificate if all stages completed
+ if len(completed_stages) == 11:
+ summary_html = generate_summary_certificate(completed_stages)
+ summary_file = HTML_DIR / "mastery_certificate.html"
+ with open(summary_file, 'w') as f:
+ f.write(summary_html)
+ print(f"✓ Generated Mastery Certificate: {summary_file}")
+
+ # Generate Markdown summary
+ if completed_stages:
+ md_summary = generate_markdown_summary(completed_stages)
+ summary_md_file = BADGE_DIR / "training_summary.md"
+ with open(summary_md_file, 'w') as f:
+ f.write(md_summary)
+ print(f"✓ Generated Markdown summary: {summary_md_file}")
+
+ print(f"\nTotal completed stages: {len(completed_stages)} / 11")
+ print(f"Badges directory: {BADGE_DIR}")
+ print(f"HTML certificates: {HTML_DIR}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/training/master_training_launcher.sh b/scripts/training/master_training_launcher.sh
index 4bffd7d2..b7701aa9 100755
--- a/scripts/training/master_training_launcher.sh
+++ b/scripts/training/master_training_launcher.sh
@@ -34,6 +34,8 @@ START_TIME=$(date +%s)
PROGRESS_FILE="$SCRIPT_DIR/.training_progress"
STATE_DIR="$SCRIPT_DIR/.training_state"
CERT_DIR="$STATE_DIR/certificates"
+BADGE_DIR="$STATE_DIR/badges"
+HTML_CERT_DIR="$STATE_DIR/html_certificates"
# Skill update flag (default: disabled)
ENABLE_SKILL_UPDATE="${ENABLE_SKILL_UPDATE:-false}"
@@ -397,16 +399,16 @@ capture_learnings() {
# View certificates
view_certificates() {
print_header "Stage Completion Certificates"
-
- # Ensure CERT_DIR exists
+
+ # Ensure directories exist
if [ ! -d "$CERT_DIR" ]; then
mkdir -p "$CERT_DIR"
fi
-
+
# Collect certificate files into array
local cert_files=()
local cert_count=0
-
+
if [ -d "$CERT_DIR" ]; then
for cert_file in "$CERT_DIR"/stage*_certificate.json; do
if [ -f "$cert_file" ]; then
@@ -415,42 +417,81 @@ view_certificates() {
fi
done
fi
-
+
if [ $cert_count -eq 0 ]; then
print_warning "No certificates found yet"
echo "Complete stages to earn certificates"
return 0
fi
-
+
echo -e "${BOLD}📜 Certificates Earned:${NC}"
echo
-
+
# Display certificates with index
for i in "${!cert_files[@]}"; do
local cert_file="${cert_files[$i]}"
- local stage_num=$(echo "$cert_file" | grep -o 'stage[0-10]' | grep -o '[0-10]')
+ local stage_num=$(echo "$cert_file" | grep -o 'stage[0-9]*' | grep -o '[0-9]*')
local stage_name=$(get_stage_name $stage_num)
local timestamp=$(python3 -c "import json; print(json.load(open('$cert_file'))['completion_timestamp'])" 2>/dev/null || echo "Unknown")
-
+
echo -e " ${GREEN}$(($i+1))${NC}. Stage $stage_num: $stage_name"
echo " Completed: $timestamp"
echo " File: $cert_file"
+
+ # Show badge path if exists
+ local badge_file="$BADGE_DIR/stage${stage_num}_badge.md"
+ if [ -f "$badge_file" ]; then
+ echo " Badge: $badge_file"
+ fi
+
+ # Show HTML cert path if exists
+ local html_file="$HTML_CERT_DIR/stage${stage_num}_certificate.html"
+ if [ -f "$html_file" ]; then
+ echo " HTML: $html_file"
+ fi
+
echo
done
-
+
echo -e "${BOLD}Total certificates: $cert_count${NC}"
-
+
+ # Show badges summary if available
+ if [ -d "$BADGE_DIR" ] && [ -f "$BADGE_DIR/training_summary.md" ]; then
+ echo
+ echo -e "${BOLD}🏅 Badges Summary:${NC}"
+ cat "$BADGE_DIR/training_summary.md"
+ fi
+
echo
echo -n "View certificate details? Enter number [1-$cert_count] or N: "
read -r view_choice
-
- if [[ "$view_choice" =~ ^[0-10]+$ ]] && [ "$view_choice" -ge 1 ] && [ "$view_choice" -le "$cert_count" ]; then
+
+ if [[ "$view_choice" =~ ^[0-9]+$ ]] && [ "$view_choice" -ge 1 ] && [ "$view_choice" -le "$cert_count" ]; then
local idx=$(($view_choice - 1))
local cert_file="${cert_files[$idx]}"
if [ -f "$cert_file" ]; then
echo
echo -e "${BOLD}Certificate Details:${NC}"
cat "$cert_file" | python3 -m json.tool 2>/dev/null || cat "$cert_file"
+
+ # Offer to open HTML certificate
+ local stage_num=$(echo "$cert_file" | grep -o 'stage[0-9]*' | grep -o '[0-9]*')
+ local html_file="$HTML_CERT_DIR/stage${stage_num}_certificate.html"
+ if [ -f "$html_file" ]; then
+ echo
+ echo -n "Open HTML certificate in browser? [y/N]: "
+ read -r open_choice
+ if [[ "$open_choice" =~ ^[Yy]$ ]]; then
+ if command -v xdg-open &> /dev/null; then
+ xdg-open "$html_file" &> /dev/null &
+ elif command -v python3 &> /dev/null; then
+ echo "Starting HTTP server for certificates..."
+ cd "$HTML_CERT_DIR" && python3 -m http.server 8888 &
+ echo "View certificates at: http://localhost:8888"
+ echo "Press Ctrl+C to stop the server when done"
+ fi
+ fi
+ fi
fi
fi
}