Files
AIPass/src/commons/apps/modules/post_module.py
T
AIOSAIandClaude Opus 4.6 babedd9c64 feat(system): seedgo v2 operational, full system audit, 14/15 branches at 99%
Three days of intensive work bringing seedgo to full operational status
and driving all branches through comprehensive standards compliance.

Seedgo v2.0.0:
- 22 checkers active (up from 20), standards pack fully operational
- New introspection standard researched from Dev-Pass, FPLAN-0017 open
- Bypass system for false positives (.seedgo config)
- Standards query and audit commands fully functional

System-wide audit (FPLAN-0016):
- All 14 auditable branches at 99%+ compliance
- CLI imports standardized across all branches (console from cli.apps.modules)
- handle_command(command, args) → bool contract added to all modules
- print_help() function naming fixed for checker pattern matching
- Handler extraction: large modules split, file I/O moved to handler layer
- New handlers created across ai_mail, backup, daemon, flow, skills, spawn, seedgo

Branch-specific highlights:
- ai_mail: email.py split 840→420 lines, 4 new handlers
- flow: dplan_flow.py 688→591 lines, 4 new handlers
- seedgo: massive restructure — standards moved to handlers/aipass_standards/,
  old standards/ tree removed, bypass system added, diagnostics module
- commons: database module added, CLI imports fixed
- skills: 5 handle_commands added, help function renamed
- trigger: error reporter handler, handle_command routing
- All branches: consistent architecture, clean drone routing

Culture doc (CLAUDE.md) added — documents AIPass philosophy, identity,
memory system, and collaboration principles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 01:26:42 -07:00

184 lines
5.7 KiB
Python

# =================== AIPass ====================
# Name: post_module.py
# Description: Post orchestration module
# Version: 1.0.0
# Created: 2026-03-07
# Modified: 2026-03-07
# =============================================
"""
Post Orchestration Module
Thin router for post workflows. Delegates all implementation
to handlers/posts/post_ops.py and renders the results.
Handles: post, thread, delete commands.
"""
from typing import List
from aipass.prax.apps.modules.logger import system_logger as logger
try:
from aipass.cli.apps.modules import console
except ImportError:
from rich.console import Console
console = Console()
from rich.panel import Panel
from rich.text import Text
from commons.apps.handlers.posts.post_ops import create_post, view_thread, delete_post
from commons.apps.handlers.identity.identity_ops import resolve_display_name
def print_introspection():
"""Display module introspection info."""
console.print()
console.print("post_module Module")
console.print("Thin router for post workflows. Handles creating posts, viewing threads, and deleting posts.")
console.print()
console.print("Connected Handlers:")
console.print(" handlers/posts/")
console.print(" - post_ops.py (create_post — create a new post in a room)")
console.print(" - post_ops.py (view_thread — view a post with its threaded comments)")
console.print(" - post_ops.py (delete_post — delete a post by ID)")
console.print(" handlers/identity/")
console.print(" - identity_ops.py (resolve_display_name — resolve branch agent to display name)")
console.print()
# =============================================================================
# COMMAND ROUTING
# =============================================================================
def handle_command(command: str, args: List[str]) -> bool:
"""
Handle post-related commands.
Args:
command: Command name (post, thread, delete).
args: Command arguments.
Returns:
True if command handled, False otherwise.
"""
if command == "post":
return _handle_create_post(args)
elif command == "thread":
return _handle_view_thread(args)
elif command == "delete":
return _handle_delete_post(args)
return False
# =============================================================================
# DISPLAY HANDLERS
# =============================================================================
def _handle_create_post(args: List[str]) -> bool:
"""Create a post and display the result."""
result = create_post(args)
if not result["success"]:
console.print(f"[red]{result['error']}[/red]")
return True
console.print()
console.print(f"[green]Post created in r/{result['room']}[/green]")
console.print(f" [dim]ID:[/dim] {result['post_id']}")
console.print(f" [dim]Title:[/dim] {result['title']}")
console.print(f" [dim]Type:[/dim] {result['post_type']}")
console.print(f" [dim]Author:[/dim] {resolve_display_name(result['author'])}")
if result.get("mentions"):
console.print(f" [dim]Mentions:[/dim] {', '.join(f'@{m}' for m in result['mentions'])}")
console.print()
return True
def _handle_view_thread(args: List[str]) -> bool:
"""View a thread and display post with comments."""
result = view_thread(args)
if not result["success"]:
console.print(f"[red]{result['error']}[/red]")
return True
post = result["post"]
comments = result["comments"]
# Display the post
console.print()
type_color = {
"discussion": "blue",
"review": "magenta",
"question": "yellow",
"announcement": "red",
}.get(post["post_type"], "white")
header_text = Text()
header_text.append(f"[{post['post_type']}] ", style=type_color)
header_text.append(post["title"], style="bold")
console.print(Panel(
f"{post['content']}\n\n"
f"[dim]By {resolve_display_name(post['author'])} in r/{post['room_name']} | "
f"Score: {post['vote_score']} | "
f"{post['created_at']}[/dim]",
title=header_text,
border_style="cyan",
))
if not comments:
console.print("[dim] No comments yet.[/dim]")
console.print()
return True
# Build threaded display
console.print(f"\n[bold]Comments ({len(comments)}):[/bold]")
console.print()
top_level = [c for c in comments if c["parent_id"] is None]
children_map: dict = {}
for c in comments:
if c["parent_id"] is not None:
children_map.setdefault(c["parent_id"], []).append(c)
def _print_comment(comment: dict, depth: int = 0) -> None:
indent = " " * depth
prefix = "|" if depth > 0 else ""
score = comment["vote_score"]
if score > 0:
score_str = f"[green]{score}[/green]"
elif score < 0:
score_str = f"[red]{score}[/red]"
else:
score_str = f"[dim]{score}[/dim]"
console.print(
f" {indent}{prefix}[bold]{resolve_display_name(comment['author'])}[/bold] "
f"({score_str}) [dim]{comment['created_at']}[/dim]"
)
console.print(f" {indent}{prefix} {comment['content']}")
console.print()
for child in children_map.get(comment["id"], []):
_print_comment(child, depth + 1)
for comment in top_level:
_print_comment(comment)
return True
def _handle_delete_post(args: List[str]) -> bool:
"""Delete a post and display the result."""
result = delete_post(args)
if not result["success"]:
console.print(f"[red]{result['error']}[/red]")
return True
console.print(f"[green]Post {result['post_id']} deleted.[/green]")
return True