Jake Shore d5e86e050b MCP Pipeline + workspace sync — 2026-02-06
=== WHAT'S BEEN DONE (Recent) ===

MCP Pipeline Factory:
- 38 MCP servers tracked across 7 pipeline stages
- 31 servers at Stage 16 (Website Built) — ready to deploy
- All 30 production servers patched to 100/100 protocol compliance
- Built complete testing infra: mcp-jest, mcp-validator, mcp-add, MCP Inspector
- 702 auto-generated test cases ready for live API testing
- Autonomous pipeline operator system w/ 7 Discord channels + cron jobs
- Dashboard live at 192.168.0.25:8888 (drag-drop kanban)

CloseBot MCP:
- 119 tools, 4,656 lines TypeScript, compiles clean
- 14 modules (8 tool groups + 6 UI apps)

GHL MCP:
- Stage 11 (Edge Case Testing) — 42 failing tests identified

Sub-agent _meta Labels:
- All 643 tools across 5 MCPs tagged (GHL, Google Ads, Meta Ads, Google Console, Twilio)

OpenClaw Upwork Launch:
- 15 graphics, 6 mockups, 2 PDFs, 90-sec Remotion video
- 3-tier pricing: $2,499 / $7,499 / $24,999
- First $20k deal closed + $2k/mo retainer (hospice)

Other:
- Surya Blender animation scripts (7 tracks)
- Clawdbot architecture deep dive doc
- Pipeline state.json updates

=== TO-DO (Open Items) ===

BLOCKERS:
- [ ] GHL MCP: Fix 42 failing edge case tests (Stage 11)
- [ ] Expired Anthropic API key in localbosses-app .env.local
- [ ] Testing strategy decision: structural vs live API vs hybrid

NEEDS API KEYS (can't progress without):
- [ ] Meta Ads MCP — needs META_ADS_API_KEY for Stage 8→9
- [ ] Twilio MCP — needs TWILIO_API_KEY for Stage 8→9
- [ ] CloseBot MCP — needs CLOSEBOT_API_KEY for live testing
- [ ] 702 test cases across all servers need live API credentials

PIPELINE ADVANCEMENT:
- [ ] Stage 7→8: CloseBot + Google Console need design approval
- [ ] Stage 6→7: 22 servers need UI apps built
- [ ] Stage 5→6: 5 servers need core tools built (FreshBooks, Gusto, Jobber, Keap, Lightspeed)
- [ ] Stage 1→5: 3 new MCPs need scaffolding (Compliance GRC, HR People Ops, Product Analytics)

PENDING REVIEW:
- [ ] Jake review OpenClaw video + gallery → finalize Upwork listing
- [ ] LocalBosses UI redesign (Steve Jobs critique delivered, recs available)

QUEUED PROJECTS:
- [ ] SongSense AI music analysis product (architecture done, build not started)
- [ ] 8-Week Agent Study Plan execution (curriculum posted, Week 1 not started)
2026-02-06 06:22:26 -05:00

175 lines
5.2 KiB
Python

"""
SURYA - Master Generation Script
Creates all track animations in a single Blender file with separate scenes,
then exports each scene as GLTF and Alembic.
Usage:
/Applications/Blender.app/Contents/MacOS/Blender --background --python generate_all.py
"""
import bpy
import os
import sys
# Get the directory of this script
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, SCRIPT_DIR)
sys.path.insert(0, os.path.join(SCRIPT_DIR, "tracks"))
from utils import *
# Import track modules
from tracks import track01_skin
from tracks import track02_u_saved_me
from tracks import track03_nothing
from tracks import track06_natures_call
from tracks import track08_idk
from tracks import track09_with_u
from tracks import track14_hollow
# Track configurations
TRACKS = [
("Track01_Skin", track01_skin.create_skin_animation),
("Track02_USavedMe", track02_u_saved_me.create_sacred_geometry_animation),
("Track03_Nothing", track03_nothing.create_nothing_animation),
("Track06_NaturesCall", track06_natures_call.create_natures_call_animation),
("Track08_IDK", track08_idk.create_idk_animation),
("Track09_WithU", track09_with_u.create_with_u_animation),
("Track14_Hollow", track14_hollow.create_hollow_animation),
]
def generate_all_scenes():
"""Generate all track scenes in a single Blender file."""
print("=" * 60)
print("SURYA - Blender Animation Generator")
print("=" * 60)
# Delete the default scene
if "Scene" in bpy.data.scenes:
default_scene = bpy.data.scenes["Scene"]
if len(bpy.data.scenes) > 1:
bpy.data.scenes.remove(default_scene)
# Create each track scene
for track_name, create_func in TRACKS:
print(f"\nGenerating: {track_name}...")
# Create new scene
scene = bpy.data.scenes.new(track_name)
bpy.context.window.scene = scene
# Setup scene defaults
scene.frame_start = 1
scene.frame_end = TOTAL_FRAMES
scene.render.fps = FPS
scene.render.resolution_x = 1920
scene.render.resolution_y = 1080
# Create world for this scene
world = bpy.data.worlds.new(f"{track_name}_World")
scene.world = world
world.use_nodes = True
# Run the track creation function
try:
create_func()
print(f"{track_name} created successfully")
except Exception as e:
print(f" ✗ Error creating {track_name}: {e}")
import traceback
traceback.print_exc()
# Save the master blend file
output_path = os.path.join(SCRIPT_DIR, "surya_all.blend")
bpy.ops.wm.save_as_mainfile(filepath=output_path)
print(f"\n✓ Saved master file: {output_path}")
return output_path
def export_all_scenes():
"""Export each scene as GLTF and Alembic."""
exports_dir = os.path.join(SCRIPT_DIR, "exports")
os.makedirs(exports_dir, exist_ok=True)
print("\n" + "=" * 60)
print("Exporting scenes...")
print("=" * 60)
for scene in bpy.data.scenes:
scene_name = scene.name
print(f"\nExporting: {scene_name}...")
# Set as active scene
bpy.context.window.scene = scene
# Select all objects in scene
for obj in scene.objects:
obj.select_set(True)
# Export GLTF
gltf_path = os.path.join(exports_dir, f"{scene_name}.gltf")
try:
bpy.ops.export_scene.gltf(
filepath=gltf_path,
export_format='GLTF_SEPARATE',
export_animations=True,
export_apply=False,
export_texcoords=True,
export_normals=True,
export_materials='EXPORT',
use_selection=False,
export_extras=False,
export_yup=True,
)
print(f" ✓ GLTF: {gltf_path}")
except Exception as e:
print(f" ✗ GLTF export failed: {e}")
# Export Alembic
abc_path = os.path.join(exports_dir, f"{scene_name}.abc")
try:
bpy.ops.wm.alembic_export(
filepath=abc_path,
start=scene.frame_start,
end=scene.frame_end,
export_hair=False,
export_particles=False,
flatten=False,
selected=False,
export_normals=True,
export_uvs=True,
)
print(f" ✓ Alembic: {abc_path}")
except Exception as e:
print(f" ✗ Alembic export failed: {e}")
print("\n" + "=" * 60)
print("Export complete!")
print("=" * 60)
def main():
"""Main entry point."""
# Generate all scenes
blend_path = generate_all_scenes()
# Export all scenes
export_all_scenes()
# Print summary
print("\n" + "=" * 60)
print("SURYA GENERATION COMPLETE")
print("=" * 60)
print(f"\nBlend file: {blend_path}")
print(f"Exports: {os.path.join(SCRIPT_DIR, 'exports')}/")
print("\nGenerated tracks:")
for track_name, _ in TRACKS:
print(f" - {track_name}")
if __name__ == "__main__":
main()