"""Publish a built static web project as a live multi-file preview.""" from __future__ import annotations import json from pathlib import Path from typing import ClassVar from uuid import UUID from core.web_previews import WebPreviewError, create_web_preview from .base import Tool class PublishWebPreviewTool(Tool): name = "publish_web_preview" description = ( "Publish an existing static multi-file web build from the current task as an interactive " "preview. Use it after creating and testing a project and producing its final static output " "directory (for example dist or build). The directory must contain the HTML entry and all " "local CSS/JS/assets. This tool does not run a development server or backend. Re-publishing " "the same directory refreshes the existing preview." ) parameters: ClassVar[dict] = { "type": "object", "properties": { "directory": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Static output directory relative to the current task working directory.", }, "entry": { "type": "string", "minLength": 1, "maxLength": 500, "default": "index.html", "description": "HTML entry path relative to directory.", }, "name": { "type": "string", "maxLength": 120, "default": "网页项目预览", "description": "Short user-facing preview name.", }, "spa_fallback": { "type": "boolean", "default": True, "description": "Serve the HTML entry for extensionless missing routes used by client-side routers.", }, }, "required": ["directory"], "additionalProperties": False, } def __init__( self, user_id: UUID, task_id: UUID, *, working_dir: Path, **kwargs, ) -> None: super().__init__(**kwargs) self.user_id = user_id self.task_id = task_id self.working_dir = Path(working_dir) def execute( self, directory: str, entry: str = "index.html", name: str = "网页项目预览", spa_fallback: bool = True, ) -> str: if self.user_root is None: return "[Error] web preview publishing requires a user workspace" try: preview = create_web_preview( user_id=self.user_id, task_id=self.task_id, working_dir=self.working_dir, directory=directory, entry=entry, name=name, spa_fallback=spa_fallback, ) except WebPreviewError as exc: return f"[Error] cannot publish web preview: {exc}" return "[WebPreview] " + json.dumps(preview, ensure_ascii=False, separators=(",", ":"))