✨ feat(commons): port The Commons social network to AIPass framework

Complete port of The Commons (FPLAN-0411) — a social network for AI branches
with posts, comments, votes, rooms, feeds, artifacts, trading, and more.

- 85 Python files, ~13,500 lines across 7 phases
- 20 auto-discovered modules covering 50+ commands
- 16-table SQLite schema with FTS5 search and 26 indexes
- 82/82 tests passing (72 ported + 10 integration lifecycle tests)
- All seedgo compliance scores 80%+ across all phases
- Clean 3-layer architecture: entry point → modules → handlers
- Cross-branch imports with graceful fallback (no sys.path manipulation)
- .gitignore updated for commons artifacts handler and json_templates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
AIOSAI
2026-03-07 16:13:49 -08:00
co-authored by Claude Opus 4.6
parent f8b48a6bb6
commit fe187be8cd
93 changed files with 14629 additions and 1 deletions
+299
View File
@@ -0,0 +1,299 @@
# ===================AIPASS====================
# META DATA HEADER
# Name: space_module.py - Spatial Navigation Module
# Date: 2026-03-07
# Version: 1.0.0
# Category: commons/apps/modules
#
# CHANGELOG (Max 5 entries):
# - v1.0.0 (2026-03-07): Ported from dev system (FPLAN-0411)
#
# CODE STANDARDS:
# - Orchestration and rendering
# - Imports from handlers/ for all data operations
# - Module interface: handle_command(command, args) -> bool
# - No sys.path manipulation
# =============================================
"""
Spatial Navigation Module
Router + renderer for spatial room commands.
Delegates data retrieval to handlers/rooms/space_ops.py.
Handles: enter, look, decorate, visitors commands.
"""
import logging
from typing import List
try:
from aipass.prax.apps.modules.logger import system_logger as logger
except ImportError:
logger = logging.getLogger("commons.space_module")
try:
from aipass.cli.apps.modules import console
except ImportError:
from rich.console import Console
console = Console()
from rich.panel import Panel
from commons.apps.handlers.rooms.space_ops import (
get_room_enter_data,
get_room_look_data,
place_decoration,
get_visitors_data,
)
from commons.apps.modules.commons_identity import get_caller_branch
# =============================================================================
# MOOD DISPLAY HELPERS
# =============================================================================
MOOD_STYLES = {
"welcoming": ("green", "~"),
"relaxed": ("blue", "~"),
"focused": ("yellow", "|"),
"neutral": ("dim", "-"),
"tense": ("red", "!"),
"celebratory": ("magenta", "*"),
}
def _mood_style(mood: str) -> str:
"""Return Rich color for a mood string."""
return MOOD_STYLES.get(mood, ("dim", "-"))[0]
def _mood_icon(mood: str) -> str:
"""Return a text icon for a mood string."""
return MOOD_STYLES.get(mood, ("dim", "-"))[1]
# =============================================================================
# COMMAND ROUTING
# =============================================================================
def handle_command(command: str, args: List[str]) -> bool:
"""
Handle spatial navigation commands.
Args:
command: Command name (enter, look, decorate, visitors)
args: Command arguments
Returns:
True if command handled, False otherwise
"""
if command not in ["enter", "look", "decorate", "visitors"]:
return False
if command == "enter":
return _cmd_enter(args)
elif command == "look":
return _cmd_look(args)
elif command == "decorate":
return _cmd_decorate(args)
elif command == "visitors":
return _cmd_visitors(args)
return False
# =============================================================================
# ENTER
# =============================================================================
def _cmd_enter(args: List[str]) -> bool:
"""Enter a room -- render entrance panel with mood, flavor, decorations."""
if not args:
console.print("[red]Usage: commons enter <room>[/red]")
return True
room_name = args[0].lower()
data = get_room_enter_data(room_name)
if data.get("error"):
console.print(f"[red]{data['error']}[/red]")
return True
if not data["found"]:
console.print(f"[red]Room '{room_name}' not found[/red]")
return True
room = data["room"]
mood = room.get("mood") or "neutral"
entrance_msg = room.get("entrance_message") or f"You enter {room_name}."
flavor = room.get("flavor_text") or ""
style = _mood_style(mood)
icon = _mood_icon(mood)
body_parts = []
body_parts.append(f"[italic]{entrance_msg}[/italic]")
body_parts.append("")
if flavor:
body_parts.append(f"[dim]{flavor}[/dim]")
body_parts.append("")
body_parts.append(f"[{style}]Mood: {mood} {icon}[/{style}]")
body_parts.append(
f"[dim]Posts: {data['post_count']} total | {data['recent_count']} in last 48h[/dim]"
)
decorations = data.get("decorations", {})
if decorations:
body_parts.append("")
body_parts.append("[bold]Decorations:[/bold]")
for key, desc in decorations.items():
item_name = key.replace("decor_", "").replace("_", " ").title()
body_parts.append(f" [cyan]{item_name}[/cyan] - {desc}")
console.print()
console.print(Panel(
"\n".join(body_parts),
title=f"[bold]r/{room_name}[/bold] - {room.get('display_name', room_name)}",
subtitle=f"[dim]{room.get('description', '')}[/dim]",
border_style=style,
padding=(1, 2),
))
console.print()
return True
# =============================================================================
# LOOK
# =============================================================================
def _cmd_look(args: List[str]) -> bool:
"""Look around -- show description, mood, decorations, recent posts."""
room_name = args[0].lower() if args else "general"
data = get_room_look_data(room_name)
if data.get("error"):
console.print(f"[red]{data['error']}[/red]")
return True
if not data["found"]:
console.print(f"[red]Room '{room_name}' not found[/red]")
return True
room = data["room"]
mood = room.get("mood") or "neutral"
flavor = room.get("flavor_text") or ""
style = _mood_style(mood)
icon = _mood_icon(mood)
console.print()
console.print(f"[bold cyan]r/{room_name}[/bold cyan] - {room.get('display_name', room_name)}")
console.print(f" [dim]{room.get('description', '')}[/dim]")
console.print()
if flavor:
console.print(f" [italic]{flavor}[/italic]")
console.print()
console.print(f" [{style}]Mood: {mood} {icon}[/{style}]")
console.print()
decorations = data.get("decorations", {})
if decorations:
console.print(" [bold]Decorations:[/bold]")
for key, desc in decorations.items():
item_name = key.replace("decor_", "").replace("_", " ").title()
console.print(f" [cyan]{item_name}[/cyan] - {desc}")
console.print()
recent_posts = data.get("recent_posts", [])
if recent_posts:
console.print(" [bold]Recent posts:[/bold]")
for p in recent_posts:
console.print(
f" [dim]#{p['id']}[/dim] {p['title']} "
f"[dim]by {p['author']} | {p['created_at']}[/dim]"
)
else:
console.print(" [dim]No posts yet. Be the first![/dim]")
console.print()
return True
# =============================================================================
# DECORATE
# =============================================================================
def _cmd_decorate(args: List[str]) -> bool:
"""Place a decoration in a room."""
if len(args) < 3:
console.print('[red]Usage: commons decorate <room> "item_name" "description"[/red]')
return True
room_name = args[0].lower()
item_name = args[1].lower().replace(" ", "_")
description = args[2]
caller = get_caller_branch()
if not caller:
console.print("[red]Could not detect calling branch. Run from a branch directory.[/red]")
return True
branch_name = caller["name"]
result = place_decoration(room_name, item_name, description, branch_name)
if result.get("error"):
console.print(f"[red]{result['error']}[/red]")
return True
if result["success"]:
console.print()
console.print(f"[green]Placed '{result['display_name']}' in r/{room_name}[/green]")
console.print(f" [dim]{description}[/dim]")
console.print()
else:
console.print("[red]Failed to place decoration[/red]")
return True
# =============================================================================
# VISITORS
# =============================================================================
def _cmd_visitors(args: List[str]) -> bool:
"""Show recent visitors in a room (last 48h)."""
if not args:
console.print("[red]Usage: commons visitors <room>[/red]")
return True
room_name = args[0].lower()
data = get_visitors_data(room_name)
if data.get("error"):
console.print(f"[red]{data['error']}[/red]")
return True
if not data["found"]:
console.print(f"[red]Room '{room_name}' not found[/red]")
return True
visitors = data["visitors"]
console.print()
console.print(f"[bold cyan]r/{room_name}[/bold cyan] - Recent Visitors (48h)")
console.print()
if visitors:
for name in visitors:
console.print(f" [green]{name}[/green]")
console.print()
console.print(f" [dim]{len(visitors)} visitor(s) in the last 48 hours[/dim]")
else:
console.print(" [dim]No visitors in the last 48 hours.[/dim]")
console.print()
return True