docs: 更新 HTTP 错误码、用户积分、占卜运行及用户资料协议文档
This commit is contained in:
Executable
+236
@@ -0,0 +1,236 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Multi-Agent Pipeline: Plan Agent Launcher.
|
||||
|
||||
Usage: python3 plan.py --name <task-name> --type <dev-type> --requirement "<requirement>"
|
||||
|
||||
This script:
|
||||
1. Creates task directory
|
||||
2. Starts Plan Agent in background
|
||||
3. Plan Agent produces fully configured task directory
|
||||
|
||||
After completion, use start.py to launch the Dispatch Agent.
|
||||
|
||||
Prerequisites:
|
||||
- agents/plan.md must exist (in .claude/, .cursor/, .iflow/, or .opencode/)
|
||||
- Developer must be initialized
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add parent directory to path for imports
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from common.cli_adapter import get_cli_adapter
|
||||
from common.paths import get_repo_root
|
||||
from common.developer import ensure_developer
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Colors
|
||||
# =============================================================================
|
||||
|
||||
class Colors:
|
||||
RED = "\033[0;31m"
|
||||
GREEN = "\033[0;32m"
|
||||
YELLOW = "\033[1;33m"
|
||||
BLUE = "\033[0;34m"
|
||||
NC = "\033[0m"
|
||||
|
||||
|
||||
def log_info(msg: str) -> None:
|
||||
print(f"{Colors.BLUE}[INFO]{Colors.NC} {msg}")
|
||||
|
||||
|
||||
def log_success(msg: str) -> None:
|
||||
print(f"{Colors.GREEN}[SUCCESS]{Colors.NC} {msg}")
|
||||
|
||||
|
||||
def log_error(msg: str) -> None:
|
||||
print(f"{Colors.RED}[ERROR]{Colors.NC} {msg}")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Constants
|
||||
# =============================================================================
|
||||
|
||||
DEFAULT_PLATFORM = "claude"
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Main
|
||||
# =============================================================================
|
||||
|
||||
def main() -> int:
|
||||
"""Main entry point."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Multi-Agent Pipeline: Plan Agent Launcher"
|
||||
)
|
||||
parser.add_argument("--name", "-n", required=True, help="Task name (e.g., user-auth)")
|
||||
parser.add_argument("--type", "-t", required=True, help="Dev type: backend|frontend|fullstack")
|
||||
parser.add_argument("--requirement", "-r", required=True, help="Requirement description")
|
||||
parser.add_argument(
|
||||
"--platform", "-p",
|
||||
choices=["claude", "cursor", "iflow", "opencode", "qoder"],
|
||||
default=DEFAULT_PLATFORM,
|
||||
help="Platform to use (default: claude)"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
task_name = args.name
|
||||
dev_type = args.type
|
||||
requirement = args.requirement
|
||||
platform = args.platform
|
||||
|
||||
# Initialize CLI adapter
|
||||
adapter = get_cli_adapter(platform)
|
||||
|
||||
# Validate dev type
|
||||
if dev_type not in ("backend", "frontend", "fullstack"):
|
||||
log_error(f"Invalid dev type: {dev_type} (must be: backend, frontend, fullstack)")
|
||||
return 1
|
||||
|
||||
project_root = get_repo_root()
|
||||
|
||||
# Check plan agent exists (path varies by platform)
|
||||
plan_md = adapter.get_agent_path("plan", project_root)
|
||||
if not plan_md.is_file():
|
||||
log_error(f"plan agent not found at {plan_md}")
|
||||
log_info(f"Platform: {platform}")
|
||||
return 1
|
||||
|
||||
ensure_developer(project_root)
|
||||
|
||||
# =============================================================================
|
||||
# Step 1: Create Task Directory
|
||||
# =============================================================================
|
||||
print()
|
||||
print(f"{Colors.BLUE}=== Multi-Agent Pipeline: Plan ==={Colors.NC}")
|
||||
log_info(f"Task: {task_name}")
|
||||
log_info(f"Type: {dev_type}")
|
||||
log_info(f"Requirement: {requirement}")
|
||||
print()
|
||||
|
||||
log_info("Step 1: Creating task directory...")
|
||||
|
||||
# Import task module to create task
|
||||
from task import cmd_create
|
||||
import argparse as ap
|
||||
|
||||
# Create task using task.py's create command
|
||||
create_args = ap.Namespace(
|
||||
title=requirement,
|
||||
slug=task_name,
|
||||
assignee=None,
|
||||
priority="P2",
|
||||
description=""
|
||||
)
|
||||
|
||||
# Capture stdout to get task dir
|
||||
import io
|
||||
from contextlib import redirect_stdout
|
||||
|
||||
stdout_capture = io.StringIO()
|
||||
with redirect_stdout(stdout_capture):
|
||||
ret = cmd_create(create_args)
|
||||
|
||||
if ret != 0:
|
||||
log_error("Failed to create task directory")
|
||||
return 1
|
||||
|
||||
task_dir = stdout_capture.getvalue().strip().split("\n")[-1]
|
||||
task_dir_abs = project_root / task_dir
|
||||
|
||||
log_success(f"Task directory: {task_dir}")
|
||||
|
||||
# =============================================================================
|
||||
# Step 2: Prepare and Start Plan Agent
|
||||
# =============================================================================
|
||||
log_info("Step 2: Starting Plan Agent in background...")
|
||||
|
||||
log_file = task_dir_abs / ".plan-log"
|
||||
log_file.touch()
|
||||
|
||||
# Get proxy environment variables
|
||||
https_proxy = os.environ.get("https_proxy", "")
|
||||
http_proxy = os.environ.get("http_proxy", "")
|
||||
all_proxy = os.environ.get("all_proxy", "")
|
||||
|
||||
# Start agent in background (cross-platform, no shell script needed)
|
||||
env = os.environ.copy()
|
||||
env["PLAN_TASK_NAME"] = task_name
|
||||
env["PLAN_DEV_TYPE"] = dev_type
|
||||
env["PLAN_TASK_DIR"] = task_dir
|
||||
env["PLAN_REQUIREMENT"] = requirement
|
||||
env["https_proxy"] = https_proxy
|
||||
env["http_proxy"] = http_proxy
|
||||
env["all_proxy"] = all_proxy
|
||||
|
||||
# Clear nested-session detection so the new CLI process can start
|
||||
env.pop("CLAUDECODE", None)
|
||||
|
||||
# Set non-interactive env var based on platform
|
||||
env.update(adapter.get_non_interactive_env())
|
||||
|
||||
# Build CLI command using adapter
|
||||
cli_cmd = adapter.build_run_command(
|
||||
agent="plan", # Will be mapped to "trellis-plan" for OpenCode
|
||||
prompt=f"Start planning for task: {task_name}",
|
||||
skip_permissions=True,
|
||||
verbose=True,
|
||||
json_output=True,
|
||||
)
|
||||
|
||||
with log_file.open("w") as log_f:
|
||||
# Use shell=False for cross-platform compatibility
|
||||
# creationflags for Windows, start_new_session for Unix
|
||||
popen_kwargs = {
|
||||
"stdout": log_f,
|
||||
"stderr": subprocess.STDOUT,
|
||||
"cwd": str(project_root),
|
||||
"env": env,
|
||||
}
|
||||
if sys.platform == "win32":
|
||||
popen_kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP
|
||||
else:
|
||||
popen_kwargs["start_new_session"] = True
|
||||
|
||||
process = subprocess.Popen(cli_cmd, **popen_kwargs)
|
||||
agent_pid = process.pid
|
||||
|
||||
log_success(f"Plan Agent started (PID: {agent_pid})")
|
||||
|
||||
# =============================================================================
|
||||
# Summary
|
||||
# =============================================================================
|
||||
print()
|
||||
print(f"{Colors.GREEN}=== Plan Agent Running ==={Colors.NC}")
|
||||
print()
|
||||
print(f" Task: {task_name}")
|
||||
print(f" Type: {dev_type}")
|
||||
print(f" Dir: {task_dir}")
|
||||
print(f" Log: {log_file}")
|
||||
print(f" PID: {agent_pid}")
|
||||
print()
|
||||
print(f"{Colors.YELLOW}To monitor:{Colors.NC}")
|
||||
print(f" tail -f {log_file}")
|
||||
print()
|
||||
print(f"{Colors.YELLOW}To check status:{Colors.NC}")
|
||||
print(f" ps -p {agent_pid}")
|
||||
print(f" ls -la {task_dir}")
|
||||
print()
|
||||
print(f"{Colors.YELLOW}After completion, run:{Colors.NC}")
|
||||
print(f" python3 ./.trellis/scripts/multi_agent/start.py {task_dir}")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user