Add apps modules and improve captain_claude logging

- Add apps/ directory with modular components:
  - captain.py: Main orchestrator
  - corp/, deck/, devops/, docker/, hst/: Domain-specific apps
- Fix duplicate logger handlers in long sessions
- Add flush=True to print statements for real-time output

Note: flow-ui, mindlink, tzzr-cli are separate repos (not included)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
ARCHITECT
2026-01-02 01:13:30 +00:00
parent acffd2a2a7
commit d35f11e2f7
7 changed files with 1796 additions and 38 deletions

View File

@@ -98,6 +98,11 @@ class CaptainClaude:
self.cost_tracker = CostTracker()
logger = logging.getLogger("captain-claude")
logger.setLevel(logging.INFO)
# Evitar handlers duplicados en sesiones largas
if not logger.handlers:
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(message)s'))
logger.addHandler(handler)
self.logger = StructuredLogger(logger)
self.output_dir = Path(output_dir) if output_dir else Path.cwd() / "captain_output"
self.output_dir.mkdir(exist_ok=True)
@@ -244,33 +249,33 @@ Continue and complete this work."""
"""Execute a task using intelligent agent orchestration."""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
print(f"\n{'='*60}")
print("CAPTAIN CLAUDE by dadiaar")
print(f"{'='*60}")
print(f"Task: {task[:100]}...")
print(f"{'='*60}\n")
print(f"\n{'='*60}", flush=True)
print("CAPTAIN CLAUDE by dadiaar", flush=True)
print(f"{'='*60}", flush=True)
print(f"Task: {task[:100]}...", flush=True)
print(f"{'='*60}\n", flush=True)
# Phase 1: Analyze task
print("[Captain] Analyzing task...")
print("[Captain] Analyzing task...", flush=True)
plan = await self.analyze_task(task)
print(f"[Captain] Plan created: {len(plan.get('steps', []))} steps")
print(f"[Captain] Plan created: {len(plan.get('steps', []))} steps", flush=True)
# Phase 2: Execute plan
results = []
if plan.get("parallel_possible") and len(plan.get("agents_needed", [])) > 1:
print("[Captain] Executing agents in parallel...")
print("[Captain] Executing agents in parallel...", flush=True)
parallel_result = await self.run_parallel(
task,
plan.get("agents_needed", ["coder"])
)
results.append(parallel_result)
else:
print("[Captain] Executing agents sequentially...")
print("[Captain] Executing agents sequentially...", flush=True)
sequential_results = await self.run_sequential(plan.get("steps", []))
results.extend(sequential_results)
# Phase 3: Synthesize results
print("[Captain] Synthesizing results...")
print("[Captain] Synthesizing results...", flush=True)
synthesis_prompt = f"""Synthesize these results into a coherent final output:
Original task: {task}
@@ -298,12 +303,12 @@ Provide a clear, actionable final result."""
with open(output_file, "w") as f:
json.dump(final_result, f, indent=2, default=str)
print(f"\n{'='*60}")
print("EXECUTION COMPLETE")
print(f"{'='*60}")
print(f"Output saved: {output_file}")
print(f"Cost: {self.cost_tracker.summary()}")
print(f"{'='*60}\n")
print(f"\n{'='*60}", flush=True)
print("EXECUTION COMPLETE", flush=True)
print(f"{'='*60}", flush=True)
print(f"Output saved: {output_file}", flush=True)
print(f"Cost: {self.cost_tracker.summary()}", flush=True)
print(f"{'='*60}\n", flush=True)
return final_result
@@ -322,18 +327,18 @@ async def main():
"""Interactive Captain Claude session."""
captain = CaptainClaude()
print("\n" + "="*60)
print("CAPTAIN CLAUDE by dadiaar")
print("Multi-Agent Orchestration System")
print("="*60)
print("\nCommands:")
print(" /execute <task> - Full multi-agent execution")
print(" /chat <message> - Chat with Captain")
print(" /agent <name> <message> - Chat with specific agent")
print(" /parallel <task> - Run all agents in parallel")
print(" /cost - Show cost summary")
print(" /quit - Exit")
print("="*60 + "\n")
print("\n" + "="*60, flush=True)
print("CAPTAIN CLAUDE by dadiaar", flush=True)
print("Multi-Agent Orchestration System", flush=True)
print("="*60, flush=True)
print("\nCommands:", flush=True)
print(" /execute <task> - Full multi-agent execution", flush=True)
print(" /chat <message> - Chat with Captain", flush=True)
print(" /agent <name> <message> - Chat with specific agent", flush=True)
print(" /parallel <task> - Run all agents in parallel", flush=True)
print(" /cost - Show cost summary", flush=True)
print(" /quit - Exit", flush=True)
print("="*60 + "\n", flush=True)
while True:
try:
@@ -343,24 +348,24 @@ async def main():
continue
if user_input.lower() == "/quit":
print("Goodbye!")
print("Goodbye!", flush=True)
break
if user_input.lower() == "/cost":
print(f"Cost: {captain.cost_tracker.summary()}")
print(f"Cost: {captain.cost_tracker.summary()}", flush=True)
continue
if user_input.startswith("/execute "):
task = user_input[9:]
result = await captain.execute(task)
print(f"\nFinal Output:\n{result['final_output']}\n")
print(f"\nFinal Output:\n{result['final_output']}\n", flush=True)
continue
if user_input.startswith("/parallel "):
task = user_input[10:]
agents = ["coder", "reviewer", "researcher"]
result = await captain.run_parallel(task, agents)
print(f"\nParallel Results:\n{result}\n")
print(f"\nParallel Results:\n{result}\n", flush=True)
continue
if user_input.startswith("/agent "):
@@ -368,24 +373,24 @@ async def main():
if len(parts) == 2:
agent, message = parts
response = await captain.chat(message, agent)
print(f"\n[{agent}]: {response}\n")
print(f"\n[{agent}]: {response}\n", flush=True)
else:
print("Usage: /agent <name> <message>")
print("Usage: /agent <name> <message>", flush=True)
continue
if user_input.startswith("/chat ") or not user_input.startswith("/"):
message = user_input[6:] if user_input.startswith("/chat ") else user_input
response = await captain.chat(message)
print(f"\n[Captain]: {response}\n")
print(f"\n[Captain]: {response}\n", flush=True)
continue
print("Unknown command. Use /quit to exit.")
print("Unknown command. Use /quit to exit.", flush=True)
except KeyboardInterrupt:
print("\nGoodbye!")
print("\nGoodbye!", flush=True)
break
except Exception as e:
print(f"Error: {e}")
print(f"Error: {e}", flush=True)
if __name__ == "__main__":