gemdesign-skill

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GemDesign Prototyping

GemDesign 原型设计

Use the
gemdesign
CLI to create, save, and modify high-fidelity prototype pages on the GemDesign platform. You generate HTML following the GemDesign Page Spec, validate it, then save via CLI.
使用
gemdesign
CLI在GemDesign平台上创建、保存和修改高保真原型页面。你需要遵循GemDesign页面规范生成HTML,进行验证,然后通过CLI保存。

When to Invoke

调用时机

  • User wants to create a UI prototype or design a page
  • User has a requirements document and wants batch page generation
  • User wants to modify an existing GemDesign page
  • User wants to view existing GemDesign pages
  • 用户想要创建UI原型或设计页面
  • 用户有需求文档,想要批量生成页面
  • 用户想要修改现有GemDesign页面
  • 用户想要查看现有GemDesign页面

Prerequisites

前置条件

CRITICAL: Step 1, Step 2, and Step 2.5 MUST be executed strictly in order BEFORE starting any Workflow. Each step MUST fully complete before proceeding to the next. Do NOT skip, parallelize, or advance until the current step is confirmed successful.
IMPORTANT — Step 3 timing: Step 3 (Start the Local Server) is NOT executed immediately after login. It MUST be executed INSIDE a Workflow, AFTER the app is created or reused (i.e., after
gemdesign app create
/
gemdesign app use
+
gemdesign app info
), and BEFORE any page generation. Starting the server before the app exists is a violation — the server serves pages from the project subdirectory derived from the app, so the app must exist first.
关键:步骤1、步骤2和步骤2.5必须严格按顺序执行,且在开始任何工作流之前完成。每一步必须完全完成后才能进行下一步。请勿跳过、并行执行或提前推进,直到当前步骤确认成功。
重要 — 步骤3的时机:步骤3(启动本地服务器)无需在登录后立即执行。它必须在工作流内部执行,即创建或复用应用之后(也就是执行
gemdesign app create
/
gemdesign app use
+
gemdesign app info
之后),且在任何页面生成之前执行。在应用存在之前启动服务器是违规的 — 服务器从应用对应的项目子目录提供页面服务,因此应用必须先存在。

Step 1: Verify & Install GemDesign CLI (MUST complete before Step 2)

步骤1:验证并安装GemDesign CLI(必须在步骤2之前完成)

ALWAYS verify CLI installation and version first before doing any other work. This step is a hard gate — no other operations (
auth
,
app
,
page
,
style
, etc.) may run until this step is confirmed complete.
  1. Check if CLI is installed:
    bash
    npm list -g @gemdesign-ai/cli
    • If the command returns version info (e.g.,
      @gemdesign-ai/cli@1.2.3
      ), CLI is installed - proceed to step 2.
    • If the command returns empty or error (e.g.,
      (empty)
      or
      ERR!
      ), CLI is NOT installed. Run:
      bash
      npm install -g @gemdesign-ai/cli
      Wait for the installation to finish, then re-verify with
      npm list -g @gemdesign-ai/cli
      . Do NOT proceed until re-verification confirms the installed version.
  2. Check if CLI is latest version (only after step 1 confirms CLI is installed):
    bash
    npm outdated -g @gemdesign-ai/cli
    • If the command returns empty or shows
      Current=Latest
      , CLI is up-to-date - this step is complete, proceed to Step 2.
    • If the command shows version info with different
      Current
      and
      Latest
      values, CLI is outdated. Update to latest:
      bash
      npm update -g @gemdesign-ai/cli
      Wait for the update to finish, then re-verify with
      npm outdated -g @gemdesign-ai/cli
      . Do NOT proceed until re-verification confirms the CLI is up-to-date.
After this step is confirmed complete, the
gemdesign-ai
command is available globally at the latest version. Only then may you advance to Step 2.
在进行任何其他工作之前,务必先验证CLI的安装情况和版本。这一步是硬性要求 — 在确认完成此步骤之前,不得运行任何其他操作(
auth
app
page
style
等)。
  1. 检查CLI是否已安装
    bash
    npm list -g @gemdesign-ai/cli
    • 如果命令返回版本信息(例如
      @gemdesign-ai/cli@1.2.3
      ),说明CLI已安装 — 进入步骤2。
    • 如果命令返回空或错误(例如
      (empty)
      ERR!
      ),说明CLI未安装。运行:
      bash
      npm install -g @gemdesign-ai/cli
      等待安装完成,然后再次用
      npm list -g @gemdesign-ai/cli
      验证。在重新验证确认已安装版本之前,请勿继续。
  2. 检查CLI是否为最新版本(仅在步骤1确认CLI已安装后执行):
    bash
    npm outdated -g @gemdesign-ai/cli
    • 如果命令返回空或显示
      Current=Latest
      ,说明CLI已更新到最新版本 — 此步骤完成,进入步骤2。
    • 如果命令显示
      Current
      Latest
      版本不同,说明CLI已过时。更新到最新版本:
      bash
      npm update -g @gemdesign-ai/cli
      等待更新完成,然后再次用
      npm outdated -g @gemdesign-ai/cli
      验证。在重新验证确认CLI已更新到最新版本之前,请勿继续。
确认此步骤完成后,
gemdesign-ai
命令将以最新版本全局可用。只有此时,你才能进入步骤2。

Step 2: Verify Login (MUST complete after Step 1, before any Workflow)

步骤2:验证登录状态(必须在步骤1之后、任何工作流之前完成)

ALWAYS verify login status after Step 1 is complete. Run this command:
bash
gemdesign auth whoami
  • If it succeeds (returns user info), the user is logged in — proceed to a Workflow (A/B/C). Step 3 (local server) will be executed INSIDE the workflow, after the app is created/reused.
  • If it fails (returns an error like "token 无效" or "未提供 token"), the user is NOT authenticated. You MUST:
    1. Tell the user: if they don't have an account or token yet, go to https://design.gemcoder.com to register an account and get an API token. The token retrieval path is: log in to the platform -> click 个人中心 (Personal Center) -> get the MCP 令牌 (MCP token).
    2. Ask the user for their API token (use
      AskUserQuestion
      tool to prompt the user to input their token).
    3. Once the user provides their token, automatically run the login command for them:
      bash
      gemdesign auth login --token <user_provided_token>
    4. Re-verify with
      gemdesign auth whoami
      to confirm login succeeded.
    5. If login still fails, repeat from step 2 (ask the user to provide their token again).
    6. Only proceed to a Workflow after login is confirmed.
HARD GATE: Until login is confirmed via
gemdesign auth whoami
, you MUST NOT perform ANY page-generation work — this includes CLI commands (
app
,
page
,
style
,
validate
) AND local file operations (writing
.html
, streaming write, creating the
./output/
directory). Local HTML generation is NOT a workaround for the login gate; a page can only be saved to the platform by an authenticated user, so generating it before login is wasted work. If login fails, stop and resolve authentication first — do not start writing any HTML.
步骤1完成后,务必验证登录状态。运行以下命令:
bash
gemdesign auth whoami
  • 如果命令成功执行(返回用户信息),说明用户已登录 — 进入工作流(A/B/C)。步骤3(本地服务器)将在工作流内部执行,即创建或复用应用之后。
  • 如果命令执行失败(返回类似"token 无效"或"未提供 token"的错误),说明用户未认证。你必须:
    1. 告知用户:如果他们还没有账户或令牌,请访问https://design.gemcoder.com**注册账户并获取API令牌。令牌获取路径为:登录平台 -> 点击个人中心** -> 获取MCP令牌
    2. 请求用户提供API令牌(使用
      AskUserQuestion
      工具提示用户输入令牌)。
    3. 用户提供令牌后,自动为他们运行登录命令:
      bash
      gemdesign auth login --token <user_provided_token>
    4. 再次用
      gemdesign auth whoami
      验证登录是否成功。
    5. 如果登录仍然失败,从步骤2重复(再次请求用户提供令牌)。
    6. 只有确认登录成功后,才能进入工作流。
硬性要求:在通过
gemdesign auth whoami
确认登录之前,不得执行任何页面生成工作 — 包括CLI命令(
app
page
style
validate
)和本地文件操作(写入
.html
、流式写入、创建
./output/
目录)。本地HTML生成不能绕过登录限制;只有已认证用户才能将页面保存到平台,因此登录前生成页面是无效工作。如果登录失败,请停止操作并先解决认证问题 — 不要开始写入任何HTML。

Step 2.5: Configure htmlWorkdir and Clean Up (MUST complete after Step 2, before any Workflow)

步骤2.5:配置htmlWorkdir并清理(必须在步骤2之后、任何工作流之前完成)

After login is confirmed, configure the HTML working directory (
htmlWorkdir
) and then clean up stale empty project directories left over from previous interrupted sessions. Both operations MUST complete before starting any Workflow (in particular, before
app create
), because
cleanup
needs
htmlWorkdir
to be configured first in order to scan it.
  1. Configure htmlWorkdir (run once, persists across sessions):
    CRITICAL -
    app create
    sync-creates the local project folder under
    htmlWorkdir
    , and
    server start
    validates
    htmlWorkdir
    before launching.
    If
    htmlWorkdir
    is not configured,
    app create
    skips local folder creation (returns a
    warning
    ), and
    server start
    returns
    {"success":false,"error":"未配置 htmlWorkdir,请先执行 gemdesign server workdir --path <path> 设置 HTML 工作目录"}
    and refuses to start. This prevents the background process's cwd from mismatching the actual HTML generation directory, which would cause fileWatcher to miss
    .html
    changes and the canvas to stay blank ("page generated but canvas not showing").
    bash
    gemdesign server workdir --path ./output
    • Relative paths are resolved against the current working directory to an absolute path.
    • Verify with
      gemdesign server workdir
      (no flags) - returns
      {"success":true,"htmlWorkdir":"<absolute path>"}
      .
    • If htmlWorkdir is already configured (returns a non-empty
      htmlWorkdir
      ), skip this step.
  2. Clean up empty project directories (MUST run AFTER step 1, because
    cleanup
    scans
    htmlWorkdir
    which must be configured first):
    bash
    gemdesign server cleanup
    • The command scans the configured
      htmlWorkdir
      (the
      ./output
      directory) for project subdirectories (named
      {projectName}__{appuuid}
      ).
    • It deletes:
      • Empty project directories: project subdirectories that contain zero
        .html
        files (created by
        app create
        but never had a page saved — e.g., the session was interrupted).
      • Orphaned streaming files: files left over from streaming write that was started but never completed.
    • Returns JSON:
      {"success":true,"message":"清理完成:删除 N 个空项目目录,清理 M 个遗留文件","removedDirs":[...],"removedLocks":[...]}
    • This step is non-blocking: cleanup failures do not prevent proceeding to a Workflow. The command always returns
      success: true
      unless an unexpected error occurs.
确认登录后,配置HTML工作目录(
htmlWorkdir
),然后清理之前中断会话留下的陈旧空项目目录。这两项操作必须在开始任何工作流之前完成(尤其是
app create
之前),因为
cleanup
需要先配置
htmlWorkdir
才能扫描它。
  1. 配置htmlWorkdir(运行一次,会话间持久化):
    关键 -
    app create
    会在
    htmlWorkdir
    下同步创建本地项目文件夹,
    server start
    在启动前会验证
    htmlWorkdir
    。如果未配置
    htmlWorkdir
    app create
    会跳过本地文件夹创建(返回
    warning
    ),
    server start
    会返回
    {"success":false,"error":"未配置 htmlWorkdir,请先执行 gemdesign server workdir --path <path> 设置 HTML 工作目录"}
    并拒绝启动。这会防止后台进程的工作目录与实际HTML生成目录不匹配,导致fileWatcher无法检测到
    .html
    文件变化,画布保持空白("页面已生成但画布不显示")。
    bash
    gemdesign server workdir --path ./output
    • 相对路径会解析为相对于当前工作目录的绝对路径。
    • gemdesign server workdir
      (不带参数)验证 — 返回
      {"success":true,"htmlWorkdir":"<absolute path>"}
    • 如果
      htmlWorkdir
      已配置(返回非空的
      htmlWorkdir
      ),跳过此步骤。
  2. 清理空项目目录(必须在步骤1之后执行,因为
    cleanup
    会扫描已配置的
    htmlWorkdir
    ):
    bash
    gemdesign server cleanup
    • 该命令会扫描已配置的
      htmlWorkdir
      (即
      ./output
      目录)中的项目子目录(命名格式为
      {projectName}__{appuuid}
      )。
    • 它会删除:
      • 空项目目录:包含0个
        .html
        文件的项目子目录(由
        app create
        创建但从未保存过页面 — 例如会话被中断)。
      • 孤立流式文件:流式写入已启动但未完成留下的文件。
    • 返回JSON:
      {"success":true,"message":"清理完成:删除 N 个空项目目录,清理 M 个遗留文件","removedDirs":[...],"removedLocks":[...]}
    • 此步骤为非阻塞:清理失败不会阻止进入工作流。除非发生意外错误,否则命令始终返回
      success: true

Step 3: Start the Local Server (MUST complete after app is created/reused, before any page generation)

步骤3:启动本地服务器(必须在创建或复用应用之后、任何页面生成之前完成)

CRITICAL - HARD GATE: You MUST open the browser in this step. This is NON-NEGOTIABLE and MUST NOT be skipped, deferred, or treated as optional. Generating any page before the browser is open is a SERIOUS VIOLATION - the user needs the real-time preview surface to see pages as they are generated. You MUST actively open the browser yourself using your platform's built-in browser/preview tool (see step 3 below for the fallback strategy). Do NOT just output a URL in chat text and wait for the user to click it — you MUST programmatically open the browser.
TIMING — Execute INSIDE a Workflow, NOT immediately after login. Step 3 is invoked from within Workflow A/B/C (see each workflow's "Start the local server" step), AFTER the app has been created or reused via
gemdesign app create
/
gemdesign app use
and confirmed via
gemdesign app info
. Do NOT start the server right after Step 2 (login) — the server serves pages from the project subdirectory derived from the app (
<projectDir> = {projectName}__{appuuid}
), so the app must exist first. Starting the server before the app exists is a violation.
After Step 1 (CLI installed), Step 2 (Login verified), AND the app is created/reused (inside a Workflow) are all confirmed complete, start the local server for real-time streaming preview.
The local server provides real-time streaming preview of HTML pages as they are being generated. The server is built into the CLI and managed via the
gemdesign server
commands. The server runs on port
4056
by default; if that port is occupied it auto-retries the next available port (up to
4066
).
  1. Ensure htmlWorkdir is configured (MUST complete before
    app create
    in a Workflow, and before
    server start
    ):
    htmlWorkdir is configured in Step 2.5 (persists across sessions).
    app create
    sync-creates the local project folder under
    htmlWorkdir
    , and
    server start
    validates
    htmlWorkdir
    before launching — if it is not configured,
    app create
    skips local folder creation (returns a
    warning
    ) and
    server start
    refuses to start, causing fileWatcher to miss
    .html
    changes and the canvas to stay blank ("page generated but canvas not showing").
    If Step 2.5 was skipped (e.g. resuming a session), verify now:
    gemdesign server workdir
    (no flags) returns
    {"success":true,"htmlWorkdir":"<absolute path>"}
    . If it returns an empty
    htmlWorkdir
    , run
    gemdesign server workdir --path ./output
    before proceeding.
  2. Stop any previously running server (MANDATORY before every
    server start
    , CANNOT be skipped):
    CRITICAL — 执行
    server start
    之前必须先执行
    server stop
    终止之前启动的服务
    ,无论应用是新建还是复用都不可跳过。这确保 fileWatcher 绑定到正确的项目目录,避免残留进程干扰新会话。
    HARD GATE - 严禁跳过此步:无论你认为当前是否已有服务在运行,都必须执行
    gemdesign server stop
    命令。禁止以"服务器未运行"、"上一次会话已启动"、"浏览器预览已打开"、"为了节省时间"等任何理由跳过 stop。必须以
    gemdesign server stop
    的实际返回结果作为唯一判定依据。
    bash
    gemdesign server stop
    • 返回
      {"success":true,"message":"本地服务已停止"}
      表示已停止,继续下一步。
    • 返回
      {"success":false,"error":"未发现运行中的本地服务"}
      表示无运行中的服务,忽略此错误继续下一步。
    • 必须等待上述命令返回结果后才能进入第 2 步。在 stop 命令未返回前,不得执行任何
      server start
      操作。
  3. Start the local server using the CLI command:
    bash
    gemdesign server start
    必须在执行此命令前先完成上一步的
    gemdesign server stop
    ,不得在未停止旧服务的情况下直接 start。
    HARD GATE - 顺序约束
    server start
    必须在
    server stop
    命令返回结果(成功或"未发现运行中的本地服务"错误)之后才能执行。严禁以下行为:
    • server stop
      server start
      并行执行(例如在同一个并行工具调用批次中);
    • server stop
      命令尚未返回结果时就发起
      server start
    • 先执行
      server start
      再执行
      server stop
    • 因为"觉得没必要 stop"而跳过 stop 直接 start。
    正确顺序:执行
    gemdesign server stop
    -> 等待命令返回结果 -> 执行
    gemdesign server start
    。这是不可逆的串行依赖关系。
    • If the server starts successfully, the command returns JSON:
      {"success":true,"port":<port>,"url":"http://localhost:<port>"}
    • If the server fails to start, the command returns JSON with an error:
      {"success":false,"error":"<error message>"}
    • On error: Read the error message carefully. Common errors:
      • "服务文件不存在"
        : The CLI installation is incomplete — reinstall the CLI.
      • "服务启动失败,进程已退出"
        : Possible port conflict or config file error — check
        ~/.gemdesign/config.json
        .
    • Record the
      <port>
      from the success response for subsequent steps.
  4. Check server status (optional, for debugging):
    bash
    gemdesign server status
    Returns:
    {"success":true,"status":"running","port":<port>,"url":"http://localhost:<port>"}
    or
    {"success":true,"status":"stopped"}
  5. Open the preview (MANDATORY — HARD GATE, DO NOT SKIP): After the server is confirmed running (the
    server start
    command returned success), you MUST open the browser and navigate to the service page named GemDesign设计器 (URL:
    http://localhost:<port>
    - use the port from the
    server start
    response).
    This step is NON-NEGOTIABLE. Do NOT proceed to any page generation workflow (Workflow A/B/C) until the browser is open at
    http://localhost:<port>
    . The server being up is NOT the same as the preview being open - the user must SEE the preview surface in the browser.
    DO NOT just output a URL in chat text. You MUST use a tool to actually open the browser. Outputting something like "服务器启动成功!请在浏览器中打开 http://localhost:4056" is a VIOLATION — the browser must be opened programmatically, not by asking the user to click a link.
    How to open the browser — use the following methods in priority order:
    Try the following methods in priority order. Use the FIRST one that is available and succeeds. If a method fails, skip it and try the next:
    PriorityMethodHow to use
    1Your platform's built-in browser/preview toolYou MUST check what browser/preview tools are available on your current agent platform and use the most appropriate one. Different platforms provide different built-in tools — use whichever one your platform offers. Examples of platform-specific tools: Trae provides
    OpenPreview
    and the
    integrated_browser
    MCP's
    browser_navigate
    ; Cursor provides its own preview mechanism; other platforms may have equivalent tools. The key requirement is: you MUST use a tool to programmatically open the browser, not just output a URL in chat. Navigate to
    http://localhost:<port>/
    using the tool.
    2OS default browser commandIf no built-in browser/preview tool is available (or it failed), open the default browser via OS command: Windows
    start http://localhost:<port>/
    , macOS
    open http://localhost:<port>/
    , Linux
    xdg-open http://localhost:<port>/
    .
    3Tell the user to open the URLIf ALL above methods fail or are unavailable, as a last resort, clearly tell the user: "请在浏览器中打开 http://localhost:<port>/ 查看设计器预览" and wait for the user to confirm before proceeding.
    How to find your platform's built-in tool: Check your available tools list — look for tools with names like
    OpenPreview
    ,
    browser_navigate
    ,
    preview
    ,
    browser
    , or similar. Any tool that can open a URL in a browser panel qualifies. Use it with the URL
    http://localhost:<port>/
    .
    Ensuring success:
    • If the highest-priority method returned an error or you're unsure whether it succeeded, immediately fall back to the next method in the table.
    • After opening the browser, verify the server is still accessible by re-checking the debug endpoint (
      http://localhost:<port>/api/local/stream/debug
      returns 200).
    • Only proceed to page generation after you have made a best-effort attempt to open the browser using at least one available method.
    After the preview is open, you may proceed to page generation workflows.
    CRITICAL - The browser is opened EXACTLY ONCE, only here in Step 3. Once the browser is open at
    http://localhost:<port>
    (the designer SPA root), you MUST NEVER open the browser again — not during page generation (Workflows A/B/C), not during modification flows, not to "refresh" or "show" a generated page. The designer SPA stays open for the entire session; generated HTML is loaded into an iframe INSIDE the designer via SSE (see "Streaming Write Workflow"), NOT by navigating the browser to a new URL.
    Opening the browser again will navigate it away from the designer to whatever URL you passed — this OVERWRITES the designer with the generated HTML (or a 404), destroying the preview surface the user needs. The URL used to open the browser MUST ALWAYS be the designer root URL
    http://localhost:<port>/
    — NEVER a path to a generated
    .html
    file (e.g.
    http://localhost:<port>/output/<projectDir>/<pageuuid>.html
    ), NEVER a page-specific URL. Generated pages have no direct browser URL; they are only viewable through the designer's iframe via SSE.
关键 - 硬性要求:此步骤中必须打开浏览器。这是不可协商的,不得跳过、延迟或视为可选操作。在浏览器打开之前生成任何页面是严重违规的 — 用户需要实时预览界面来查看生成的页面。你必须使用平台内置的浏览器/预览工具主动打开浏览器(请参阅下面步骤3中的备用策略)。请勿仅在聊天文本中输出URL并等待用户点击 — 你必须以编程方式打开浏览器。
时机 — 在工作流内部执行,而非登录后立即执行。步骤3从工作流A/B/C内部调用(请参阅每个工作流的"启动本地服务器"步骤),即通过
gemdesign app create
/
gemdesign app use
创建或复用应用并通过
gemdesign app info
确认之后。请勿在步骤2(登录)后立即启动服务器 — 服务器从应用对应的项目子目录(
<projectDir> = {projectName}__{appuuid}
)提供页面服务,因此应用必须先存在。在应用存在之前启动服务器是违规的。
确认步骤1(CLI已安装)、步骤2(登录已验证)以及应用已创建/复用(在工作流内部)全部完成后,启动本地服务器以实现实时流式预览。
本地服务器提供HTML页面生成过程中的实时流式预览。服务器内置在CLI中,通过
gemdesign server
命令管理。服务器默认在端口
4056
运行;如果该端口被占用,它会自动重试下一个可用端口(最高到
4066
)。
  1. 确保htmlWorkdir已配置(必须在工作流中的
    app create
    之前以及
    server start
    之前完成):
    htmlWorkdir在步骤2.5中配置(会话间持久化)。
    app create
    会在
    htmlWorkdir
    下同步创建本地项目文件夹,
    server start
    在启动前会验证
    htmlWorkdir
    — 如果未配置,
    app create
    会跳过本地文件夹创建(返回
    warning
    ),
    server start
    会拒绝启动,导致fileWatcher无法检测到
    .html
    文件变化,画布保持空白("页面已生成但画布不显示")。
    如果跳过了步骤2.5(例如恢复会话),现在验证:
    gemdesign server workdir
    (不带参数)返回
    {"success":true,"htmlWorkdir":"<absolute path>"}
    。如果返回空的
    htmlWorkdir
    ,在继续之前运行
    gemdesign server workdir --path ./output
  2. 停止任何之前运行的服务器(每次
    server start
    之前必须执行,不可跳过):
    关键 — 执行
    server start
    之前必须先执行
    server stop
    终止之前启动的服务
    ,无论应用是新建还是复用都不可跳过。这确保fileWatcher绑定到正确的项目目录,避免残留进程干扰新会话。
    硬性要求 - 严禁跳过此步:无论你认为当前是否已有服务在运行,都必须执行
    gemdesign server stop
    命令。禁止以"服务器未运行"、"上一次会话已启动"、"浏览器预览已打开"、"为了节省时间"等任何理由跳过stop。必须以
    gemdesign server stop
    的实际返回结果作为唯一判定依据。
    bash
    gemdesign server stop
    • 返回
      {"success":true,"message":"本地服务已停止"}
      表示已停止,继续下一步。
    • 返回
      {"success":false,"error":"未发现运行中的本地服务"}
      表示无运行中的服务,忽略此错误继续下一步。
    • 必须等待上述命令返回结果后才能进入第2步。在stop命令未返回前,不得执行任何
      server start
      操作。
  3. 使用CLI命令启动本地服务器
    bash
    gemdesign server start
    必须在执行此命令前先完成上一步的
    gemdesign server stop
    ,不得在未停止旧服务的情况下直接start。
    硬性要求 - 顺序约束
    server start
    必须在
    server stop
    命令返回结果(成功或"未发现运行中的本地服务"错误)之后才能执行。严禁以下行为:
    • server stop
      server start
      并行执行(例如在同一个并行工具调用批次中);
    • server stop
      命令尚未返回结果时就发起
      server start
    • 先执行
      server start
      再执行
      server stop
    • 因为"觉得没必要stop"而跳过stop直接start。
    正确顺序:执行
    gemdesign server stop
    -> 等待命令返回结果 -> 执行
    gemdesign server start
    。这是不可逆的串行依赖关系。
    • 如果服务器启动成功,命令返回JSON:
      {"success":true,"port":<port>,"url":"http://localhost:<port>"}
    • 如果服务器启动失败,命令返回包含错误的JSON:
      {"success":false,"error":"<error message>"}
    • 错误处理:仔细阅读错误信息。常见错误:
      • "服务文件不存在"
        :CLI安装不完整 — 重新安装CLI。
      • "服务启动失败,进程已退出"
        :可能是端口冲突或配置文件错误 — 检查
        ~/.gemdesign/config.json
    • 记录成功响应中的
      <port>
      供后续步骤使用。
  4. 检查服务器状态(可选,用于调试):
    bash
    gemdesign server status
    返回:
    {"success":true,"status":"running","port":<port>,"url":"http://localhost:<port>"}
    {"success":true,"status":"stopped"}
  5. 打开预览(必须执行 — 硬性要求,请勿跳过):确认服务器已运行(
    server start
    命令返回成功)后,必须打开浏览器并导航到名为GemDesign设计器的服务页面(URL:
    http://localhost:<port>
    — 使用
    server start
    响应中的端口)。
    此步骤不可协商。在浏览器打开
    http://localhost:<port>
    之前,不得进入任何页面生成工作流(工作流A/B/C)。服务器运行并不等同于预览已打开 — 用户必须在浏览器中看到预览界面。
    请勿仅在聊天文本中输出URL。你必须使用工具实际打开浏览器。输出类似"服务器启动成功!请在浏览器中打开 http://localhost:4056"的内容是违规的 — 必须以编程方式打开浏览器,而非让用户点击链接。
    打开浏览器的方法 — 按优先级顺序使用
    按以下优先级顺序尝试方法。使用第一个可用且成功的方法。如果某方法失败,跳过它并尝试下一个:
    优先级方法使用方式
    1平台内置浏览器/预览工具你必须检查当前Agent平台可用的浏览器/预览工具,并使用最合适的工具。不同平台提供不同的内置工具 — 使用你的平台提供的工具。平台特定工具示例:Trae提供
    OpenPreview
    integrated_browser
    MCP的
    browser_navigate
    ;Cursor提供自己的预览机制;其他平台可能有等效工具。核心要求是:你必须使用工具以编程方式打开浏览器,而非仅在聊天中输出URL。使用工具导航到
    http://localhost:<port>/
    2系统默认浏览器命令如果没有内置浏览器/预览工具(或工具失败),通过系统命令打开默认浏览器:Windows使用
    start http://localhost:<port>/
    ,macOS使用
    open http://localhost:<port>/
    ,Linux使用
    xdg-open http://localhost:<port>/
    3告知用户打开URL如果上述所有方法都失败或不可用,作为最后手段,明确告知用户:"请在浏览器中打开 http://localhost:<port>/ 查看设计器预览",并等待用户确认后再继续。
    如何找到平台内置工具:查看可用工具列表 — 寻找名称类似
    OpenPreview
    browser_navigate
    preview
    browser
    的工具。任何能在浏览器面板中打开URL的工具都符合要求。使用该工具打开URL
    http://localhost:<port>/
    确保成功
    • 如果最高优先级的方法返回错误或你不确定是否成功,立即回退到表格中的下一个方法。
    • 打开浏览器后,通过重新检查调试端点(
      http://localhost:<port>/api/local/stream/debug
      返回200)验证服务器是否仍可访问。
    • 只有在尝试至少一种可用方法打开浏览器后,才能进入页面生成步骤。
    预览打开后,你可以进入页面生成工作流。
    关键 - 浏览器仅在此步骤3中打开一次。一旦浏览器打开到
    http://localhost:<port>
    (设计器SPA根目录),不得再次打开浏览器 — 无论是在页面生成期间(工作流A/B/C)、修改流程期间,还是为了"刷新"或"显示"生成的页面。设计器SPA会在整个会话中保持打开;生成的HTML通过SSE加载到设计器内部的iframe中(请参阅"流式写入工作流"),而非通过导航浏览器到新URL。
    再次打开浏览器会将其从设计器导航到你传入的任何URL — 这会用生成的HTML(或404页面)覆盖设计器,破坏用户需要的预览界面。打开浏览器必须始终使用设计器根URL
    http://localhost:<port>/
    — 绝不能是生成的
    .html
    文件的路径(例如
    http://localhost:<port>/output/<projectDir>/<pageuuid>.html
    ),也不能是页面特定的URL。生成的页面没有直接的浏览器URL;只能通过设计器的iframe通过SSE查看。

CLI Command Reference

CLI命令参考

Server Management

服务器管理

bash
gemdesign server start [--port <port>]   # 启动本地设计器服务(默认端口 4056)
gemdesign server stop                    # 停止本地设计器服务
gemdesign server status                  # 查看服务运行状态
gemdesign server workdir --path <path>   # 保存 HTML 工作目录(htmlWorkdir,相对路径基于当前目录解析为绝对路径)
gemdesign server workdir                 # 查看当前 htmlWorkdir
gemdesign server workdir --clear         # 清除 htmlWorkdir 配置
gemdesign server cleanup                 # 清理空项目目录和遗留的流式文件
server workdir 保存 HTML 工作目录到
~/.gemdesign/config.json
htmlWorkdir
字段。本地服务启动后通过 fileWatcher 监听此目录下的
.html
文件变更,并经 SSE 推送到浏览器画布。
app create
会在此目录下同步创建项目子目录
{projectName}__{appuuid}
server start
也会在启动前校验 htmlWorkdir 是否已配置
--未配置时
app create
跳过本地目录创建(返回
warning
),
server start
拒绝启动并返回错误提示,避免后台进程 cwd 与实际 HTML 生成目录不一致导致"页面生成但画布不显示"。建议在登录后、
app create
之前
执行一次
gemdesign server workdir --path ./output
(路径通常是
./output
,即页面 HTML 的根目录)。配置一次后持久化,后续无需重复设置。 server start 以后台进程方式启动本地服务。执行
server start
之前必须先执行
server stop
终止之前的服务
,不得在未停止旧服务的情况下直接 start。
server stop
严禁跳过
(即使你认为没有运行中的服务也必须执行该命令),且
server start
必须等
server stop
命令返回结果后才能执行
——禁止将两者并行执行、或在 stop 未返回时就发起 start。启动成功返回含
port
url
的 JSON;失败返回含
error
的 JSON,需仔细阅读错误信息诊断并修复后再重试(重试前同样要先 stop)。 server stop stops the running server. On Windows, uses
taskkill
to terminate the process tree. Returns error if no server is running or if the process cannot be terminated — 此时该错误可忽略(表示本就无运行中的服务),但仍视为 stop 步骤已执行完成,可继续 start。 server status returns the current status (
running
or
stopped
), port, and URL if running.
bash
gemdesign server start [--port <port>]   # 启动本地设计器服务(默认端口 4056)
gemdesign server stop                    # 停止本地设计器服务
gemdesign server status                  # 查看服务运行状态
gemdesign server workdir --path <path>   # 保存HTML工作目录(htmlWorkdir,相对路径基于当前目录解析为绝对路径)
gemdesign server workdir                 # 查看当前htmlWorkdir
gemdesign server workdir --clear         # 清除htmlWorkdir配置
gemdesign server cleanup                 # 清理空项目目录和遗留的流式文件
server workdir 将HTML工作目录保存到
~/.gemdesign/config.json
htmlWorkdir
字段。本地服务启动后,通过fileWatcher监听此目录下的
.html
文件变更,并通过SSE推送到浏览器画布。
app create
会在此目录下同步创建项目子目录
{projectName}__{appuuid}
server start
也会在启动前校验htmlWorkdir是否已配置
——未配置时
app create
跳过本地目录创建(返回
warning
),
server start
拒绝启动并返回错误提示,避免后台进程cwd与实际HTML生成目录不一致导致"页面生成但画布不显示"。建议在登录后、
app create
之前
执行一次
gemdesign server workdir --path ./output
(路径通常为
./output
,即页面HTML的根目录)。配置一次后持久化,后续无需重复设置。 server start 以后台进程方式启动本地服务。执行
server start
之前必须先执行
server stop
终止之前的服务
,不得在未停止旧服务的情况下直接start。
server stop
严禁跳过
(即使你认为没有运行中的服务也必须执行该命令),且
server start
必须等
server stop
命令返回结果后才能执行
——禁止将两者并行执行、或在stop未返回时就发起start。启动成功返回含
port
url
的JSON;失败返回含
error
的JSON,需仔细阅读错误信息诊断并修复后再重试(重试前同样要先stop)。 server stop 停止运行中的服务器。在Windows上,使用
taskkill
终止进程树。如果没有运行中的服务器或无法终止进程,会返回错误 — 此时该错误可忽略(表示本就无运行中的服务),但仍视为stop步骤已执行完成,可继续start。 server status 返回当前状态(
running
stopped
),如果运行中还会返回端口和URL。

Authentication

认证

bash
gemdesign auth login --token <token>   # Configure API token
gemdesign auth whoami                  # Verify identity
bash
gemdesign auth login --token <token>   # 配置API令牌
gemdesign auth whoami                  # 验证身份

App Management

应用管理

bash
gemdesign app create --name "MyApp" [--type web|app] [--width <px>] [--height <px>] [--workdir <path>]    # Create new app (sync-creates local project folder under htmlWorkdir), --type defaults to web
gemdesign app list                     # List all apps
gemdesign app info [--appuuid <id>]    # App details
gemdesign app use --appuuid <id>       # Switch current default app
app create 画布尺寸:
--width
/
--height
用于指定画布像素尺寸。不传时按
--type
取默认值:
web
-> 1920×1080,
app
-> 440×956。传入的尺寸会随应用信息同步到本地设计器画布(覆盖默认值)。示例:
gemdesign app create --name "PadApp" --type app --width 768 --height 1024
CRITICAL -
server workdir
MUST run BEFORE
app create
:
app create
成功后会在
htmlWorkdir
同步创建本地项目子目录
{projectName}__{appuuid}
(与
page
命令的命名规范一致),后续页面 HTML 直接写入该目录,local-server 也据此扫描项目。因此
gemdesign server workdir --path <path>
必须在
app create
之前执行
(或通过
--workdir <path>
在创建应用时一并指定,效果等同于先
server workdir
app create
)。若未配置
htmlWorkdir
,应用仍会在服务端创建成功,但本地目录创建会被跳过,并在返回结果中以
warning
提示。 appuuid priority:
--appuuid
flag >
defaultAppUuid
(set by
app create
/
app use
) >
GEMDESIGN_APPUUID
env Once you run
app create
or
app use
, subsequent
page
commands don't need
--appuuid
. IMPORTANT: Always check
gemdesign app list
BEFORE creating a new app. Reuse existing apps to keep all pages in the same project folder. Only create a new app when the user explicitly asks for one. CRITICAL - Never create duplicate apps: Never call
gemdesign app create
more than once in a single session/task. If you have already run
app create
in this session, you MUST NOT run it again — even if a later workflow step or retry seems to require app setup. Instead, reuse the existing app by running
gemdesign app list
to find it, then
gemdesign app use --appuuid <id>
. Creating a second app leaves the first one empty and orphaned on the platform. CRITICAL - Restart the server around every
app create
or
app use
: 正确顺序为:
gemdesign server stop
-> (等待 stop 命令返回结果) -> (确保
htmlWorkdir
已配置) ->
gemdesign app create
/
gemdesign app use
->
gemdesign server start
。该顺序由 workflow 步骤强制执行,不要作为独立序列重复执行。执行
server start
之前必须先执行
server stop
终止之前的服务
,无论应用是新建还是复用,否则旧服务的 fileWatcher 仍绑定在前一个 app 的
<projectDir>
,新页面不会推送到画布。
server stop
这一步严禁跳过
(即使你认为没有运行中的服务也必须执行),且
server start
必须等
server stop
命令返回结果后才能执行
,禁止并行执行或先 start 后 stop。 IMPORTANT - Output app info to user: After selecting/switching/creating an app (i.e., after any
app create
,
app use
, or
app info
call that establishes the working app), you MUST clearly tell the user in your text response which app is now the active target for page generation. At minimum, output the app name and appuuid (and ideally the computed
<projectDir>
). This ensures the user always knows which app pages will be generated/modified in, and can interrupt if the wrong app was picked. See the "Output current app info to user" step in each workflow for the exact format. CRITICAL - App type determines page type: Apps have a type -
web
(桌面端) or
app
(移动端) - returned by
app info
as the
pageScene
field. When generating new pages, the page type MUST match the app type: a
web
app can only contain
web
pages (desktop layout, wide screen), and an
app
app can only contain
app
pages (mobile layout, narrow screen). Before generating any HTML, check the app's
pageScene
from
app info
and design the page accordingly. Do NOT generate a desktop-width page for an
app
type app, or a mobile-width page for a
web
type app.
bash
gemdesign app create --name "MyApp" [--type web|app] [--width <px>] [--height <px>] [--workdir <path>]    # 创建新应用(在htmlWorkdir下同步创建本地项目文件夹),--type默认值为web
gemdesign app list                     # 列出所有应用
gemdesign app info [--appuuid <id>]    # 查看应用详情
gemdesign app use --appuuid <id>       # 切换当前默认应用
app create画布尺寸
--width
/
--height
用于指定画布像素尺寸。不传时按
--type
取默认值:
web
-> 1920×1080,
app
-> 440×956。传入的尺寸会随应用信息同步到本地设计器画布(覆盖默认值)。示例:
gemdesign app create --name "PadApp" --type app --width 768 --height 1024
关键 -
server workdir
必须在
app create
之前执行
app create
成功后会在
htmlWorkdir
同步创建本地项目子目录
{projectName}__{appuuid}
(与
page
命令的命名规范一致),后续页面HTML直接写入该目录,local-server也据此扫描项目。因此
gemdesign server workdir --path <path>
必须在
app create
之前执行
(或通过
--workdir <path>
在创建应用时一并指定,效果等同于先
server workdir
app create
)。若未配置
htmlWorkdir
,应用仍会在服务端创建成功,但本地目录创建会被跳过,并在返回结果中以
warning
提示。 appuuid优先级
--appuuid
参数 >
defaultAppUuid
(由
app create
/
app use
设置) >
GEMDESIGN_APPUUID
环境变量 运行
app create
app use
后,后续的
page
命令无需
--appuuid
参数。 重要:创建新应用之前,务必先运行
gemdesign app list
。复用现有应用以将所有页面保存在同一个项目文件夹中。仅当用户明确要求时才创建新应用。 关键 - 请勿创建重复应用:在单个会话/任务中,请勿多次调用
gemdesign app create
。如果已在本次会话中运行过
app create
,不得再次运行 — 即使后续工作流步骤或重试似乎需要设置应用。相反,通过运行
gemdesign app list
找到现有应用,然后执行
gemdesign app use --appuuid <id>
复用它。创建第二个应用会在平台上留下第一个空的孤立应用。 关键 - 每次
app create
app use
前后重启服务器
:正确顺序为:
gemdesign server stop
->(等待stop命令返回结果)->(确保
htmlWorkdir
已配置)->
gemdesign app create
/
gemdesign app use
->
gemdesign server start
。该顺序由工作流步骤强制执行,不要作为独立序列重复执行。执行
server start
之前必须先执行
server stop
终止之前的服务
,无论应用是新建还是复用,否则旧服务的fileWatcher仍绑定在前一个app的
<projectDir>
,新页面不会推送到画布。
server stop
这一步严禁跳过
(即使你认为没有运行中的服务也必须执行),且
server start
必须等
server stop
命令返回结果后才能执行
,禁止并行执行或先start后stop。 重要 - 向用户输出应用信息:选择/切换/创建应用后(即执行任何
app create
app use
app info
调用确定工作应用后),必须在文本响应中明确告知用户当前哪个应用是页面生成的目标。至少输出应用名称appuuid(最好还有计算出的
<projectDir>
)。这确保用户始终知道页面将生成/修改到哪个应用中,如果选错了应用可以中断。请参阅每个工作流中的"向用户输出当前应用信息"步骤获取确切格式。 关键 - 应用类型决定页面类型:应用有类型 —
web
(桌面端)或
app
(移动端),由
app info
返回的
pageScene
字段表示。生成新页面时,页面类型必须与应用类型匹配
web
应用只能包含
web
页面(桌面布局,宽屏),
app
应用只能包含
app
页面(移动端布局,窄屏)。生成任何HTML之前,检查
app info
返回的
pageScene
并据此设计页面。请勿为
app
类型应用生成桌面宽度页面,也请勿为
web
类型应用生成移动端宽度页面。

Style Search (optional helper)

样式搜索(可选辅助工具)

bash
gemdesign style search --keywords "科技,深蓝,企业" --limit 5   # Search styles
gemdesign style get --id <styleId> --format html                 # Get full style
Style search is optional. You can also design styles yourself or use other UI design skills.
bash
gemdesign style search --keywords "科技,深蓝,企业" --limit 5   # 搜索样式
gemdesign style get --id <styleId> --format html                 # 获取完整样式
样式搜索是可选的。你也可以自行设计样式或使用其他UI设计技能。

Page - View

页面 - 查看

bash
gemdesign page list [--appuuid <id>]                                        # List pages
gemdesign page get --pageuuid <id> --file ./output/<projectDir>/<id>.html  # Get page HTML (auto-creates projectDir)
gemdesign page doc get --pageuuid <id> --file ./output/<projectDir>/<id>.md  # Get requirement doc
bash
gemdesign page list [--appuuid <id>]                                        # 列出页面
gemdesign page get --pageuuid <id> --file ./output/<projectDir>/<id>.html  # 获取页面HTML(自动创建projectDir)
gemdesign page doc get --pageuuid <id> --file ./output/<projectDir>/<id>.md  # 获取需求文档

Page - Create (streaming mode)

页面 - 创建(流式模式)

bash
gemdesign page create --pageuuid <readable-id> --name "<pageName>"   # Create page + enter streaming mode
page create
signals the local server to start streaming mode for this page, enabling real-time HTML preview as you write to the
.html
file. This command should be called BEFORE writing the HTML file, and the streaming mode is automatically ended when
page save
completes.
bash
gemdesign page create --pageuuid <readable-id> --name "<pageName>"   # 创建页面并进入流式模式
page create
通知本地服务器为此页面启动流式模式,使你写入
.html
文件时能实现实时HTML预览。此命令应在写入HTML文件之前调用,流式模式会在
page save
完成后自动结束。

Page - Save (with validation)

页面 - 保存(带验证)

bash
gemdesign page save --pageuuid <id> --file ./output/<projectDir>/<id>.html                                         # Update existing
gemdesign page save --new --pageuuid <readable-id> --name "Login" --file ./output/<projectDir>/<readable-id>.html  # Create new
gemdesign page doc save --pageuuid <id> --file ./doc.md                                                           # Save requirement doc
page save
automatically validates the HTML against the GemDesign Page Spec before uploading. After a successful save, it automatically ends streaming mode, triggering the browser to fetch the final render.
page doc save
saves an agent-generated requirement document to the platform.
--pageuuid
for
--new
: Use a human-readable id (e.g. filename without
.html
). Ensure uniqueness within the app. This id is used directly as
data-uuid
in navigation elements - no need to change them after saving. Project subdirectory: Always use
./output/<projectDir>/
in paths. The CLI is idempotent - if the path already contains
<projectDir>
, it won't duplicate it. See "Local File Management" for details.
bash
gemdesign page save --pageuuid <id> --file ./output/<projectDir>/<id>.html                                         # 更新现有页面
gemdesign page save --new --pageuuid <readable-id> --name "Login" --file ./output/<projectDir>/<readable-id>.html  # 创建新页面
gemdesign page doc save --pageuuid <id> --file ./doc.md                                                           # 保存需求文档
page save
会在上传前自动根据GemDesign页面规范验证HTML。保存成功后,会自动结束流式模式,触发浏览器获取最终渲染结果。
page doc save
将Agent生成的需求文档保存到平台。
--new
--pageuuid
:使用易读的ID(例如不带
.html
的文件名)。确保在应用内唯一。此ID会直接用作导航元素中的
data-uuid
— 保存后无需修改。 项目子目录:路径中始终使用
./output/<projectDir>/
。CLI具有幂等性 — 如果路径已包含
<projectDir>
,不会重复添加。请参阅"本地文件管理"了解详情。

Validate Only

仅验证

bash
gemdesign validate --file ./page.html    # Validate without saving
bash
gemdesign validate --file ./page.html    # 仅验证不保存

Local File Management

本地文件管理

For every page, save HTML files locally under
./output/
, organized by project subdirectory:
FilePurposeHow to generate
./output/<projectDir>/<pageuuid>.html
Page HTML (contains DSL, for editing and saving)The file you generate and write
Project subdirectory naming:
<projectDir> = {projectName}__{appuuid}
  • projectName
    comes from
    app info
    (illegal filesystem chars
    \/:*?"<>|
    removed, whitespace collapsed to
    _
    )
  • Empty
    projectName
    falls back to
    默认项目
    ; empty
    appuuid
    falls back to
    local
  • Examples:
    CRM系统__abc-123
    ,
    电商App__9f3e
    ,
    默认项目__local
  • Directory creation: This subdirectory is sync-created by
    app create
    under
    htmlWorkdir
    (requires
    htmlWorkdir
    configured first via
    server workdir
    );
    page get
    /
    page save
    also create it idempotently when writing files.
How to write files:
  • Always use
    ./output/<projectDir>/<pageuuid>.html
    in all file paths, whether writing files directly or passing to CLI commands.
  • The CLI is idempotent: if the path already contains
    <projectDir>
    , it will NOT duplicate it. You can safely pass
    ./output/CRM系统__abc-123/home.html
    to
    page get --file
    or
    page save --file
    without worrying about nesting.
  • Compute
    <projectDir>
    first
    : Run
    gemdesign app info
    -> get
    {appuuid}
    and
    {projectName}
    -> compute
    <projectDir> = {projectName}__{appuuid}
    (sanitize projectName).
  • Validate
    <projectDir>
    before creating files
    : Ensure
    <projectDir>
    is non-empty and matches
    {nonEmptyName}__{nonEmptyUuid}
    . If
    projectName
    or
    appuuid
    is empty/undefined, re-run
    gemdesign app info
    . Never create files with an empty or partial
    <projectDir>
    (e.g.
    __abc
    or
    MyApp__
    ) - this creates orphaned unnamed directories.
The local server automatically serves pages from the project subdirectory path.
每个页面的HTML文件都保存在本地
./output/
目录下,按项目子目录组织:
文件用途生成方式
./output/<projectDir>/<pageuuid>.html
页面HTML(包含DSL,用于编辑和保存)你生成并写入的文件
项目子目录命名
<projectDir> = {projectName}__{appuuid}
  • projectName
    来自
    app info
    (移除非法文件系统字符
    \/:*?"<>|
    ,空格替换为
    _
  • 如果
    projectName
    为空,回退为
    默认项目
    ;如果
    appuuid
    为空,回退为
    local
  • 示例:
    CRM系统__abc-123
    电商App__9f3e
    默认项目__local
  • 目录创建:此子目录由
    app create
    htmlWorkdir
    下同步创建(需要先通过
    server workdir
    配置
    htmlWorkdir
    );
    page get
    /
    page save
    写入文件时也会幂等性地创建它。
文件写入方式
  • 所有文件路径中始终使用
    ./output/<projectDir>/<pageuuid>.html
    ,无论是直接写入文件还是传递给CLI命令。
  • CLI具有幂等性:如果路径已包含
    <projectDir>
    ,不会重复添加。你可以安全地将
    ./output/CRM系统__abc-123/home.html
    传递给
    page get --file
    page save --file
    ,无需担心嵌套问题。
  • 先计算
    <projectDir>
    :运行
    gemdesign app info
    -> 获取
    {appuuid}
    {projectName}
    -> 计算
    <projectDir> = {projectName}__{appuuid}
    (清理projectName)。
  • 创建文件前验证
    <projectDir>
    :确保
    <projectDir>
    非空且符合
    {nonEmptyName}__{nonEmptyUuid}
    格式。如果
    projectName
    appuuid
    为空/未定义,重新运行
    gemdesign app info
    。请勿使用空的或不完整的
    <projectDir>
    创建文件(例如
    __abc
    MyApp__
    )——这会创建孤立的无名称目录。
本地服务器会自动从项目子目录路径提供页面服务。

Streaming Write Workflow (Real-time Display)

流式写入工作流(实时显示)

When generating HTML pages, use the streaming write workflow to enable real-time display in the browser. The GemDesign local server watches for file changes and pushes incremental content to the browser via Server-Sent Events (SSE).
CRITICAL — Do NOT open the browser again during streaming write (or at any point after Step 3). The designer SPA (already open in the browser from Step 3) watches for
.html
file changes and auto-loads the generated HTML into its inner iframe via SSE. You do NOT need to "open" or "refresh" anything — just write the files and the designer updates itself in real time. Navigating the browser to the generated
.html
URL (e.g. via a preview tool or OS browser command with a page-specific URL) will OVERWRITE the designer with the generated HTML and break the preview surface. The only valid URL for opening the browser is the designer root
http://localhost:<port>/
, and even that should NOT be re-used after Step 3.
生成HTML页面时,使用流式写入工作流实现浏览器中的实时显示。GemDesign本地服务器监听文件变化,并通过Server-Sent Events(SSE)将增量内容推送到浏览器。
关键 — 流式写入期间(或步骤3之后的任何时候)请勿再次打开浏览器。步骤3中已在浏览器中打开的设计器SPA会监听
.html
文件变化,并通过SSE自动将生成的HTML加载到内部iframe中。你无需"打开"或"刷新"任何内容 — 只需写入文件,设计器就会实时更新。导航浏览器到生成的
.html
URL(例如通过预览工具或系统浏览器命令打开页面特定URL)会用生成的HTML覆盖设计器,破坏预览界面。打开浏览器的唯一有效URL是设计器根目录
http://localhost:<port>/
,即使是这个URL也不应在步骤3之后再次使用。

How It Works

工作原理

The CLI automatically manages the streaming lifecycle for you. The
gemdesign page create
command starts streaming mode, and
gemdesign page save
automatically ends it. The browser receives incremental HTML as you append to the
.html
file:
  1. gemdesign page create
    → browser enters streaming mode for that page
  2. Append to
    .html
    → browser receives incremental HTML and re-renders in real-time
  3. gemdesign page save
    → browser fetches the complete HTML and switches to final render
CLI会自动为你管理流式生命周期。
gemdesign page create
命令启动流式模式,
gemdesign page save
会自动结束它。浏览器会在你追加
.html
文件内容时接收增量HTML:
  1. gemdesign page create
    → 浏览器为此页面进入流式模式
  2. 追加到
    .html
    文件
    → 浏览器接收增量HTML并实时重新渲染
  3. gemdesign page save
    → 浏览器获取完整HTML并切换到最终渲染

Steps

步骤

For each page you generate, follow this workflow instead of writing the complete HTML in one shot:
  1. Compute path:
    • htmlPath = ./output/<projectDir>/<pageuuid>.html
  2. Create the page (enter streaming mode):
    bash
    gemdesign page create --pageuuid <pageuuid> --name "<pageName>"
    This signals the local server to start streaming mode for this page. The browser will enter streaming mode and prepare to receive incremental HTML.
  3. Write the HTML file (append-only after the first write, NEVER overwrite with shorter content):
    • You may write the HTML in one shot or in multiple appends — the local server detects file changes and pushes each append to the browser in real-time.
    • The HTML must be a complete document:
      <!DOCTYPE html>
      +
      <head>
      (with all dependencies and styles) +
      <body>...</body>
      +
      </html>
      .
    • If writing in multiple appends, ensure the first write includes the
      <body>
      tag so the browser can start rendering immediately (the browser only renders after
      <body>
      appears).
    CRITICAL RULES:
    • Always append to the file after the first write. Never overwrite with shorter content during streaming — this triggers a
      pageReset
      event and forces the browser to re-render from scratch.
    • If you must rewrite from scratch, delete the
      .html
      file first, then start over.
    • The first write creates the file (length goes from 0 to N), subsequent writes append (length goes from N to N+M).
    • No delays or chunk-size limits: Write as fast as you like, in any size. The local server pushes every file change to the browser within ~10ms.
    • Clean up on failure: If streaming write fails or is interrupted, delete any partial
      .html
      file for that page. You can also run
      gemdesign server cleanup
      to clean up orphaned files and empty project directories.
  4. Validate the HTML:
    bash
    gemdesign validate --file ./output/<projectDir>/<pageuuid>.html
    If validation fails, fix the HTML and re-validate. The browser continues to show the streaming state, giving immediate feedback on fixes.
  5. Save to platform:
    bash
    gemdesign page save --new --pageuuid <pageuuid> --name "<pageName>" --file ./output/<projectDir>/<pageuuid>.html
    When the save completes, the CLI automatically ends streaming mode. The browser fetches the complete HTML and switches to the final render.
生成每个页面时,请遵循此工作流,而非一次性写入完整HTML:
  1. 计算路径
    • htmlPath = ./output/<projectDir>/<pageuuid>.html
  2. 创建页面(进入流式模式)
    bash
    gemdesign page create --pageuuid <pageuuid> --name "<pageName>"
    此命令通知本地服务器为此页面启动流式模式。浏览器会进入流式模式并准备接收增量HTML。
  3. 写入HTML文件(首次写入后仅追加,绝不要用更短的内容覆盖):
    • 你可以一次性写入HTML,也可以分多次追加 — 本地服务器会检测文件变化并将每次追加内容实时推送到浏览器。
    • HTML必须是完整文档:
      <!DOCTYPE html>
      +
      <head>
      (包含所有依赖和样式) +
      <body>...</body>
      +
      </html>
    • 如果分多次写入,确保首次写入包含
      <body>
      标签,以便浏览器能立即开始渲染(浏览器仅在
      <body>
      出现后才会渲染)。
    关键规则
    • 首次写入后始终追加到文件。流式写入期间绝不要用更短的内容覆盖 — 这会触发
      pageReset
      事件,迫使浏览器从头开始重新渲染。
    • 如果必须从头重写,先删除
      .html
      文件,然后重新开始。
    • 首次写入创建文件(长度从0变为N),后续写入追加内容(长度从N变为N+M)。
    • 无延迟或块大小限制:随意快速写入,块大小不限。本地服务器会在约10ms内将每次文件变化推送到浏览器。
    • 失败时清理:如果流式写入失败或中断,删除该页面的任何部分
      .html
      文件。你也可以运行
      gemdesign server cleanup
      清理孤立文件和空项目目录。
  4. 验证HTML
    bash
    gemdesign validate --file ./output/<projectDir>/<pageuuid>.html
    如果验证失败,修复HTML并重新验证。浏览器会继续显示流式状态,提供修复的即时反馈。
  5. 保存到平台
    bash
    gemdesign page save --new --pageuuid <pageuuid> --name "<pageName>" --file ./output/<projectDir>/<pageuuid>.html
    保存完成后,CLI会自动结束流式模式。浏览器获取完整HTML并切换到最终渲染。

Example (Streaming Write for a "home" page)

示例("首页"的流式写入)

bash
undefined
bash
undefined

1. Create the page (enter streaming mode)

1. 创建页面(进入流式模式)

gemdesign page create --pageuuid home --name "首页"
gemdesign page create --pageuuid home --name "首页"

2. Write the HTML file (one shot or multiple appends — your choice)

2. 写入HTML文件(一次性写入或分多次追加 — 任选其一)

Use Write tool to create ./output/MyApp__abc-123/home.html with the complete HTML:

使用Write工具创建./output/MyApp__abc-123/home.html并写入完整HTML:

<!DOCTYPE html><html><head>...<script src="tailwind"></script>...</head><body>...content...</body></html>

<!DOCTYPE html><html><head>...<script src="tailwind"></script>...</head><body>...content...</body></html>

Or write in multiple appends (ensure first write includes <body> tag).

或分多次写入(确保首次写入包含<body>标签)。

3. Validate

3. 验证

gemdesign validate --file ./output/MyApp__abc-123/home.html
gemdesign validate --file ./output/MyApp__abc-123/home.html

Fix any validation errors and re-validate before proceeding

修复任何验证错误并重新验证后再继续

4. Save to platform (automatically ends streaming mode)

4. 保存到平台(自动结束流式模式)

gemdesign page save --new --pageuuid home --name "首页" --file ./output/MyApp__abc-123/home.html
undefined
gemdesign page save --new --pageuuid home --name "首页" --file ./output/MyApp__abc-123/home.html
undefined

Workflows

工作流

PRECONDITION FOR ALL WORKFLOWS: Step 1 (CLI installed & up-to-date), Step 2 (Login verified via
gemdesign auth whoami
), AND Step 2.5 (htmlWorkdir configured + cleanup) MUST be confirmed complete BEFORE starting any workflow. If login is not confirmed, do NOT generate HTML, do NOT create
./output/
files, do NOT start streaming write - stop and resolve authentication first. Step 3 (local server running AND browser preview opened) is NOT executed before starting a workflow — it is executed INSIDE each workflow, AFTER the app is created/reused (and
app info
confirms
<projectDir>
), and BEFORE any page generation. This applies to Workflow A, B, and C alike.
所有工作流的前提条件:步骤1(CLI已安装并更新到最新版本)、步骤2(通过
gemdesign auth whoami
验证登录)以及步骤2.5(已配置htmlWorkdir并完成清理)必须确认完成后才能启动任何工作流。如果未确认登录,请勿生成HTML、创建
./output/
文件或启动流式写入 — 停止操作并先解决认证问题。步骤3(本地服务器运行且浏览器预览已打开)无需在启动工作流前执行 — 它会在每个工作流内部执行,即创建或复用应用(并通过
app info
确认
<projectDir>
)之后,且在任何页面生成之前执行。此规则适用于工作流A、B和C。

Workflow A: Batch Generation from Requirements

工作流A:根据需求批量生成

  1. Complete Prerequisites: Ensure Step 1 (CLI install/update), Step 2 (Login), AND Step 2.5 (htmlWorkdir configured + cleanup) are confirmed complete before proceeding. Step 3 (local server + browser preview) is NOT done here — it is executed in step 5 below, AFTER the app is created/reused.
  2. Ensure app exists (reuse first!):
    • Ensure htmlWorkdir is configured (MUST complete before
      app create
      )
      : htmlWorkdir was configured in Step 2.5 (persists across sessions). Verify with
      gemdesign server workdir
      (no flags); if it returns an empty
      htmlWorkdir
      , run
      gemdesign server workdir --path ./output
      first. This MUST be done before
      app create
      so that
      app create
      synchronously creates the local project folder
      {projectName}__{appuuid}
      under
      htmlWorkdir
      .
    • Run
      gemdesign app list
      to check existing apps
    • If apps already exist: Run
      gemdesign app use --appuuid <id>
      to set the target app as default. Do NOT create a new app unless the user explicitly asks for a new one.
    • If no apps exist: Run
      gemdesign app create --name "<AppName>" [--type web|app] [--width <px>] [--height <px>] [--workdir <path>]
      to create one (default type is
      web
      ; default canvas size:
      web
      -> 1920×1080,
      app
      -> 440×956).
      app create
      sync-creates the local project folder under
      htmlWorkdir
      (pass
      --workdir
      to set it in one step). After creating, immediately run
      gemdesign app info
      to confirm the app exists and record its appuuid. Do NOT run
      app create
      again for any reason in this session.
      之前运行中的服务会在步骤 5 的
      server stop
      中统一终止。
    • CRITICAL - No duplicate apps: If you already ran
      app create
      earlier in this session (even in a previous workflow attempt), do NOT run it again. Reuse the existing app via
      app list
      +
      app use
      . Creating a second app leaves the first one empty and orphaned.
    • CRITICAL: All pages in the same batch MUST go into the same app. Reusing an existing app prevents pages from being scattered across different project folders.
  3. Get project directory name:
    • Run
      gemdesign app info
      to get
      {appuuid}
      and
      {projectName}
    • Compute
      <projectDir> = {projectName}__{appuuid}
      (remove illegal chars
      \/:*?"<>|
      from projectName, collapse whitespace to
      _
      )
    • Example: project name "电商 App" with appuuid "abc-123" →
      <projectDir> = "电商_App__abc-123"
  4. Output current app info to user (CRITICAL — user must know which app pages will be generated into):
    • Before generating any HTML, clearly tell the user in your text response which app you are generating pages into. At minimum, output:
      • App name (
        projectName
        from
        app info
        )
      • App UUID (
        appuuid
        from
        app info
        )
      • App type (
        pageScene
        from
        app info
        -
        web
        for 桌面端,
        app
        for 移动端)
      • Project directory (
        <projectDir>
        computed in step 3)
      • Page count to be generated in this batch (from step 7 analysis)
    • Example output format:
      📦 当前应用信息
      - 应用名称:电商 App
      - 应用 ID:abc-123
      - 应用类型:app(移动端)
      - 项目目录:电商_App__abc-123
      - 本次将生成页面数:5
    • Type matching: The
      pageScene
      value determines the page layout you MUST follow. Generate
      web
      (desktop, wide-screen) pages for
      web
      apps,
      app
      (mobile, narrow-screen) pages for
      app
      apps. Do NOT mix types - a web app cannot contain app pages, and vice versa.
    • If the user did not explicitly specify an app and you reused an existing app, also tell the user which app was selected (e.g. "已复用现有应用:电商 App") so they can interrupt if it's the wrong one.
    • Pause-friendly: This is informational only - no user reply is required unless the user wants to switch apps. Continue to the next step immediately after outputting.
  5. Start the local server (Step 3): Now that the app exists and
    <projectDir>
    is computed, execute Step 3 (see the "Step 3: Start the Local Server" section above) — 必须先执行
    gemdesign server stop
    终止之前的服务
    (无论应用是新建还是复用,也无论之前是否已运行服务,均不可跳过此步),必须等
    server stop
    命令返回结果(确认已停止或无运行中的服务)之后
    ,才能执行
    gemdesign server start
    启动本地服务,并仅打开一次浏览器到设计器
    http://localhost:<port>/
    。记录
    server start
    返回的
    <port>
    供后续步骤使用。这是 HARD GATE:服务未运行或浏览器预览未打开前,不得进入任何页面生成。
    • CRITICAL - 严禁跳过
      server stop
      这一步
      :即使你认为当前会话中没有运行中的服务,也必须执行
      gemdesign server stop
      命令并以命令返回结果为准。禁止以"服务器已在运行"、"上一次 workflow 已启动"、"浏览器预览已打开"等理由跳过 stop。stop 返回
      {"success":false,"error":"未发现运行中的本地服务"}
      时表示无服务可停,此时可继续下一步 start。
    • CRITICAL -
      server start
      必须等
      server stop
      执行完成后再执行
      :禁止将 stop 和 start 并行执行、或先 start 后 stop。
      server start
      的前置条件是
      server stop
      已返回结果。
    • Never open the browser with a generated-page URL (e.g.
      http://localhost:<port>/output/<projectDir>/<pageuuid>.html
      ) - that overwrites the designer with the generated HTML and destroys the preview surface.
  6. Search style (optional):
    gemdesign style search --keywords "电商,现代,简洁"
    → select one →
    gemdesign style get --id <id>
  7. Analyze requirements: Read the requirements doc, break down into individual pages. Assign each page a readable
    pageuuid
    (e.g.
    home
    ,
    product-list
    ,
    cart
    ).
  8. Generate design system page (only for newly created apps): If a new app was created in step 2 (not reused), generate a design system page as the visual style baseline before generating business pages. All subsequent business pages should follow this style. Determine the design system type based on
    pageScene
    from
    app info
    , and generate the page following the type table and page structure in the dedicated "Design System Page Spec" section below. The pageuuid is fixed as
    design-system
    and is NOT counted as a business page. You MUST save the design system page to the platform (not just write it locally) - otherwise it will not appear in the app and cannot serve as the style baseline. Use the Streaming Write Workflow with these explicit steps (same create-validate-save process as business pages):
    • Create page (enter streaming mode):
      gemdesign page create --pageuuid design-system --name "设计系统"
    • Write the HTML file to
      ./output/<projectDir>/design-system.html
      (follow the Design System Page Spec; pageuuid is
      design-system
      )
    • Validate:
      gemdesign validate --file ./output/<projectDir>/design-system.html
      (fix errors and re-validate)
    • Save to platform (MANDATORY - do NOT skip):
      gemdesign page save --new --pageuuid design-system --name "设计系统" --file ./output/<projectDir>/design-system.html
      (uploads the design system page into the app so it persists on the platform and shows up in
      page list
      ; automatically ends streaming mode)
    • Verify it was saved:
      gemdesign page list
      (confirm
      design-system
      appears in the list) If the app was reused (switched via
      app use
      in step 2), skip this step AND skip step 9.
  9. Design System Review Gate (CRITICAL — only when step 8 generated a design system page): Before generating any business page, you MUST apply the "Design System Review Gate" rules (see that section below). Evaluate the continue conditions; if none apply, STOP and ask the user for confirmation/feedback on the design system using the format specified in that section. Do not proceed to step 10 until the design system is confirmed by the user or a continue condition is met. If the app was reused (step 8 was skipped), skip this step too.
  10. For each page (use Streaming Write Workflow above for real-time display):
    • Generate HTML following the Page Spec below (incorporate style if available). Use the assigned
      pageuuid
      as
      data-uuid
      in navigation elements. All business pages MUST follow the style baseline established (and, if applicable, confirmed) in the design system page.
    • Use streaming write (see "Streaming Write Workflow" section for details):
      • Create page (enter streaming mode):
        gemdesign page create --pageuuid <pageuuid> --name "页面名"
      • Write the HTML file to:
        ./output/<projectDir>/<pageuuid>.html
        (create the directory if it doesn't exist; use the
        <projectDir>
        computed in step 3)
      • Validate:
        gemdesign validate --file ./output/<projectDir>/<pageuuid>.html
      • Fix any validation errors, re-validate
      • Save to platform:
        gemdesign page save --new --pageuuid <pageuuid> --name "页面名" --file ./output/<projectDir>/<pageuuid>.html
        (uploads to platform, automatically ends streaming mode)
  11. Verify:
    gemdesign page list
  12. Output designer link (MANDATORY - output ONCE, only after ALL pages are generated): After ALL pages in the batch are generated, validated, and saved (i.e., after step 10's loop is fully complete and step 11 verification passes), you MUST output a clickable link in your text response so the user can easily open the designer to view the final result. The link MUST be:
    • Name:
      gemdesign 设计器
      (exact text, do NOT change or translate)
    • URL:
      http://localhost:<port>
      (use the port recorded from Step 3's
      server start
      response)
    • Format (markdown link):
      [gemdesign 设计器](http://localhost:<port>)
    • Example:
      [gemdesign 设计器](http://localhost:4056)
    CRITICAL - Do NOT output this link after each individual page in step 10. Output it exactly ONCE, at the very end of the entire batch, after every page has been generated and saved. Outputting the link after each page clutters the conversation and violates the "all pages complete" requirement.
    Note: This is the ONLY exception to the "do not output URLs in chat text" rule in Step 3. Step 3's rule prohibits outputting a URL instead of programmatically opening the browser during setup. This step is different - it runs AFTER all page generation is complete, and outputs a text link for the user to click at their discretion (e.g. if they closed the browser or want to reopen the designer). This is NOT an automatic browser open action - it is a markdown link in your final summary.
  1. 完成前提条件:确保步骤1(CLI安装/更新)、步骤2(登录)以及步骤2.5(已配置htmlWorkdir并完成清理)已确认完成后再继续。步骤3(本地服务器+浏览器预览)无需在此执行 — 它会在下面的步骤5中执行,即创建或复用应用之后。
  2. 确保应用存在(优先复用!)
    • 确保htmlWorkdir已配置(必须在
      app create
      之前完成)
      :htmlWorkdir已在步骤2.5中配置(会话间持久化)。用
      gemdesign server workdir
      (不带参数)验证;如果返回空的
      htmlWorkdir
      ,先运行
      gemdesign server workdir --path ./output
      。这必须在
      app create
      之前完成,以便
      app create
      htmlWorkdir
      下同步创建本地项目文件夹
      {projectName}__{appuuid}
    • 运行
      gemdesign app list
      检查现有应用
    • 如果已有应用:运行
      gemdesign app use --appuuid <id>
      将目标应用设置为默认应用。除非用户明确要求,否则请勿创建新应用。
    • 如果没有应用:运行
      gemdesign app create --name "<AppName>" [--type web|app] [--width <px>] [--height <px>] [--workdir <path>]
      创建应用(默认类型为
      web
      ;默认画布尺寸:
      web
      -> 1920×1080,
      app
      -> 440×956)。
      app create
      会在
      htmlWorkdir
      下同步创建本地项目文件夹(传递
      --workdir
      可一步设置)。创建后立即运行
      gemdesign app info
      确认应用存在并记录其appuuid。本次会话中无论任何理由都请勿再次运行
      app create
      之前运行的服务会在步骤5的
      server stop
      中统一终止。
    • 关键 - 请勿创建重复应用:如果已在本次会话中运行过
      app create
      (即使是之前的工作流尝试),请勿再次运行。通过
      app list
      +
      app use
      复用现有应用。创建第二个应用会在平台上留下第一个空的孤立应用。
    • 关键:同一批次的所有页面必须放入同一个应用。复用现有应用可防止页面分散到不同项目文件夹中。
  3. 获取项目目录名称
    • 运行
      gemdesign app info
      获取
      {appuuid}
      {projectName}
    • 计算
      <projectDir> = {projectName}__{appuuid}
      (从projectName中移除非法字符
      \/:*?"<>|
      ,空格替换为
      _
    • 示例:项目名称"电商 App",appuuid为"abc-123" →
      <projectDir> = "电商_App__abc-123"
  4. 向用户输出当前应用信息(关键 — 用户必须知道页面将生成到哪个应用中):
    • 生成任何HTML之前,必须在文本响应中明确告知用户页面将生成到哪个应用中。至少输出:
      • 应用名称(来自
        app info
        projectName
      • 应用UUID(来自
        app info
        appuuid
      • 应用类型(来自
        app info
        pageScene
        web
        表示桌面端,
        app
        表示移动端)
      • 项目目录(步骤3中计算的
        <projectDir>
      • 本次将生成的页面数量(来自步骤7的分析)
    • 示例输出格式:
      📦 当前应用信息
      - 应用名称:电商 App
      - 应用 ID:abc-123
      - 应用类型:app(移动端)
      - 项目目录:电商_App__abc-123
      - 本次将生成页面数:5
    • 类型匹配
      pageScene
      值决定了你必须遵循的页面布局。为
      web
      应用生成
      web
      (桌面端,宽屏)页面,为
      app
      应用生成
      app
      (移动端,窄屏)页面。请勿混合类型 — web应用不能包含app页面,反之亦然。
    • 如果用户未明确指定应用且你复用了现有应用,还需告知用户选择了哪个应用(例如"已复用现有应用:电商 App"),以便用户选错时可以中断。
    • 无需等待回复:此信息仅作告知 — 除非用户想要切换应用,否则无需等待用户回复。输出后立即进入下一步。
  5. 启动本地服务器(步骤3):现在应用已存在且
    <projectDir>
    已计算完成,执行步骤3(请参阅上面的"步骤3:启动本地服务器"部分) — 必须先执行
    gemdesign server stop
    终止之前的服务
    (无论应用是新建还是复用,也无论之前是否已运行服务,均不可跳过此步),必须等
    server stop
    命令返回结果(确认已停止或无运行中的服务)之后
    ,才能执行
    gemdesign server start
    启动本地服务,并仅打开一次浏览器到设计器
    http://localhost:<port>/
    。记录
    server start
    返回的
    <port>
    供后续步骤使用。这是硬性要求:服务未运行或浏览器预览未打开前,不得进入任何页面生成。
    • 关键 - 严禁跳过
      server stop
      这一步
      :即使你认为当前会话中没有运行中的服务,也必须执行
      gemdesign server stop
      命令并以命令返回结果为准。禁止以"服务器已在运行"、"上一次workflow已启动"、"浏览器预览已打开"等理由跳过stop。stop返回
      {"success":false,"error":"未发现运行中的本地服务"}
      时表示无服务可停,此时可继续下一步start。
    • 关键 -
      server start
      必须等
      server stop
      执行完成后再执行
      :禁止将stop和start并行执行、或先start后stop。
      server start
      的前置条件是
      server stop
      已返回结果。
    • 绝不要用生成页面的URL打开浏览器(例如
      http://localhost:<port>/output/<projectDir>/<pageuuid>.html
      )——这会用生成的HTML覆盖设计器,破坏预览界面。
  6. 搜索样式(可选):
    gemdesign style search --keywords "电商,现代,简洁"
    → 选择一个样式 →
    gemdesign style get --id <id>
  7. 分析需求:阅读需求文档,拆分为单个页面。为每个页面分配易读的
    pageuuid
    (例如
    home
    product-list
    cart
    )。
  8. 生成设计系统页面(仅适用于新建应用):如果步骤2中创建了新应用(而非复用),在生成业务页面之前先生成设计系统页面作为视觉样式基准。后续所有业务页面都应遵循此样式。根据
    app info
    返回的
    pageScene
    确定设计系统类型,并按照下面专门的**"设计系统页面规范"部分中的类型表和页面结构生成页面。pageuuid固定为
    design-system
    ,不计为业务页面。必须将设计系统页面保存到平台(而非仅写入本地)——否则它不会出现在应用中,无法作为样式基准。 使用
    流式写入工作流**并遵循以下明确步骤(与业务页面的创建-验证-保存流程相同):
    • 创建页面(进入流式模式):
      gemdesign page create --pageuuid design-system --name "设计系统"
    • 将HTML文件写入
      ./output/<projectDir>/design-system.html
      (遵循设计系统页面规范;pageuuid为
      design-system
    • 验证:
      gemdesign validate --file ./output/<projectDir>/design-system.html
      (修复错误并重新验证)
    • 保存到平台(必须执行 - 请勿跳过)
      gemdesign page save --new --pageuuid design-system --name "设计系统" --file ./output/<projectDir>/design-system.html
      (将设计系统页面上传到应用,使其在平台上持久化并显示在
      page list
      中;自动结束流式模式)
    • 验证已保存:
      gemdesign page list
      (确认
      design-system
      出现在列表中) 如果应用是复用的(步骤2中通过
      app use
      切换),跳过此步骤和步骤9。
  9. 设计系统审核关卡(关键 — 仅当步骤8生成了设计系统页面时执行):生成任何业务页面之前,必须应用**"设计系统审核关卡"**规则(请参阅下面的该部分)。评估继续条件;如果没有条件适用,停止操作并按照该部分指定的格式请求用户确认/反馈设计系统。在用户确认设计系统或满足继续条件之前,请勿进入步骤10。如果应用是复用的(跳过了步骤8),也跳过此步骤。
  10. 为每个页面(使用上面的流式写入工作流实现实时显示):
    • 按照下面的页面规范生成HTML(如果有样式则整合进去)。将分配的
      pageuuid
      用作导航元素中的
      data-uuid
      。所有业务页面必须遵循设计系统页面中确立(并在适用时已确认)的样式基准。
    • 使用流式写入(请参阅"流式写入工作流"部分了解详情):
      • 创建页面(进入流式模式):
        gemdesign page create --pageuuid <pageuuid> --name "页面名"
      • 将HTML文件写入:
        ./output/<projectDir>/<pageuuid>.html
        (如果目录不存在则创建;使用步骤3中计算的
        <projectDir>
      • 验证:
        gemdesign validate --file ./output/<projectDir>/<pageuuid>.html
      • 修复任何验证错误,重新验证
      • 保存到平台:
        gemdesign page save --new --pageuuid <pageuuid> --name "页面名" --file ./output/<projectDir>/<pageuuid>.html
        (上传到平台,自动结束流式模式)
  11. 验证
    gemdesign page list
  12. 输出设计器链接(必须执行 - 仅在所有页面生成完成后输出一次):批次中所有页面都已生成、验证并保存后(即步骤10的循环完全完成且步骤11验证通过后),必须在文本响应中输出可点击链接,方便用户打开设计器查看最终结果。链接必须:
    • 名称
      gemdesign 设计器
      (确切文本,请勿修改或翻译)
    • URL
      http://localhost:<port>
      (使用步骤3中
      server start
      响应记录的端口)
    • 格式(markdown链接):
      [gemdesign 设计器](http://localhost:<port>)
    • 示例:
      [gemdesign 设计器](http://localhost:4056)
    关键 - 请勿在步骤10中每个页面生成后输出此链接。仅在整个批次完全结束时输出一次,即所有页面都已生成并保存后。每个页面生成后输出链接会使对话杂乱,违反"所有页面完成"的要求。
    注意:这是步骤3中"请勿在聊天文本中输出URL"规则的唯一例外。步骤3的规则禁止在设置期间仅输出URL而不通过编程方式打开浏览器。此步骤不同 — 它在所有页面生成完成后执行,输出文本链接供用户自行点击(例如用户关闭了浏览器或想要重新打开设计器)。这不是自动打开浏览器的操作 — 是最终总结中的markdown链接。

Workflow B: Conversational Generation

工作流B:对话式生成

When user asks for a page in conversation:
  1. Complete Prerequisites: Ensure Step 1 (CLI install/update), Step 2 (Login), AND Step 2.5 (htmlWorkdir configured + cleanup) are confirmed complete before proceeding. Step 3 (local server + browser preview) is NOT done here — it is executed in step 5 below, AFTER the app is created/reused.
  2. Ensure app exists (reuse first!):
    • Ensure htmlWorkdir is configured (MUST complete before
      app create
      )
      : htmlWorkdir was configured in Step 2.5 (persists across sessions). Verify with
      gemdesign server workdir
      (no flags); if it returns an empty
      htmlWorkdir
      , run
      gemdesign server workdir --path ./output
      first. This MUST be done before
      app create
      so that
      app create
      synchronously creates the local project folder
      {projectName}__{appuuid}
      under
      htmlWorkdir
      .
    • Run
      gemdesign app list
      to check existing apps
    • If apps already exist: Run
      gemdesign app use --appuuid <id>
      to set the target app as default. Do NOT create a new app unless the user explicitly asks for a new one.
    • If no apps exist: Run
      gemdesign app create --name "<AppName>" [--type web|app] [--width <px>] [--height <px>] [--workdir <path>]
      to create one (default type is
      web
      ; default canvas size:
      web
      -> 1920×1080,
      app
      -> 440×956).
      app create
      sync-creates the local project folder under
      htmlWorkdir
      (pass
      --workdir
      to set it in one step). After creating, immediately run
      gemdesign app info
      to confirm the app exists and record its appuuid. Do NOT run
      app create
      again for any reason in this session.
      之前运行中的服务会在步骤 5 的
      server stop
      中统一终止。
    • CRITICAL - No duplicate apps: If you already ran
      app create
      earlier in this session (even in a previous workflow attempt), do NOT run it again. Reuse the existing app via
      app list
      +
      app use
      . Creating a second app leaves the first one empty and orphaned.
    • CRITICAL: All pages MUST go into the same app. Reusing an existing app prevents pages from being scattered across different project folders.
  3. Get project directory name:
    • Run
      gemdesign app info
      to get
      {appuuid}
      and
      {projectName}
    • Compute
      <projectDir> = {projectName}__{appuuid}
      (remove illegal chars
      \/:*?"<>|
      from projectName, collapse whitespace to
      _
      )
  4. Output current app info to user (CRITICAL — user must know which app the page will be generated into):
    • Before generating any HTML, clearly tell the user in your text response which app you are generating the page into. At minimum, output:
      • App name (
        projectName
        from
        app info
        )
      • App UUID (
        appuuid
        from
        app info
        )
      • App type (
        pageScene
        from
        app info
        -
        web
        for 桌面端,
        app
        for 移动端)
      • Project directory (
        <projectDir>
        computed in step 3)
    • Example output format:
      📦 当前应用信息
      - 应用名称:电商 App
      - 应用 ID:abc-123
      - 应用类型:app(移动端)
      - 项目目录:电商_App__abc-123
    • Type matching: The
      pageScene
      value determines the page layout you MUST follow. Generate
      web
      (desktop, wide-screen) pages for
      web
      apps,
      app
      (mobile, narrow-screen) pages for
      app
      apps. Do NOT mix types - a web app cannot contain app pages, and vice versa.
    • If the user did not explicitly specify an app and you reused an existing app, also tell the user which app was selected (e.g. "已复用现有应用:电商 App") so they can interrupt if it's the wrong one.
    • Pause-friendly: This is informational only — no user reply is required unless the user wants to switch apps. Continue to the next step immediately after outputting.
  5. Start the local server (Step 3): Now that the app exists and
    <projectDir>
    is computed, execute Step 3 (see the "Step 3: Start the Local Server" section above) — 必须先执行
    gemdesign server stop
    终止之前的服务
    (无论应用是新建还是复用,也无论之前是否已运行服务,均不可跳过此步),必须等
    server stop
    命令返回结果(确认已停止或无运行中的服务)之后
    ,才能执行
    gemdesign server start
    启动本地服务,并仅打开一次浏览器到设计器
    http://localhost:<port>/
    。记录
    server start
    返回的
    <port>
    供后续步骤使用。这是 HARD GATE:服务未运行或浏览器预览未打开前,不得进入任何页面生成。
    • CRITICAL - 严禁跳过
      server stop
      这一步
      :即使你认为当前会话中没有运行中的服务,也必须执行
      gemdesign server stop
      命令并以命令返回结果为准。禁止以"服务器已在运行"、"上一次 workflow 已启动"、"浏览器预览已打开"等理由跳过 stop。stop 返回
      {"success":false,"error":"未发现运行中的本地服务"}
      时表示无服务可停,此时可继续下一步 start。
    • CRITICAL -
      server start
      必须等
      server stop
      执行完成后再执行
      :禁止将 stop 和 start 并行执行、或先 start 后 stop。
      server start
      的前置条件是
      server stop
      已返回结果。
    • Never open the browser with a generated-page URL (e.g.
      http://localhost:<port>/output/<projectDir>/<pageuuid>.html
      ) - that overwrites the designer with the generated HTML and destroys the preview surface.
  6. Generate design system page (only for newly created apps): If a new app was created in step 2 (not reused), generate a design system page as the visual style baseline before generating business pages. All subsequent business pages should follow this style. Determine the design system type based on
    pageScene
    from
    app info
    , and generate the page following the type table and page structure in the dedicated "Design System Page Spec" section below. The pageuuid is fixed as
    design-system
    and is NOT counted as a business page. You MUST save the design system page to the platform (not just write it locally) - otherwise it will not appear in the app and cannot serve as the style baseline. Use the Streaming Write Workflow with these explicit steps (same create-validate-save process as business pages):
    • Create page (enter streaming mode):
      gemdesign page create --pageuuid design-system --name "设计系统"
    • Write the HTML file to
      ./output/<projectDir>/design-system.html
      (follow the Design System Page Spec; pageuuid is
      design-system
      )
    • Validate:
      gemdesign validate --file ./output/<projectDir>/design-system.html
      (fix errors and re-validate)
    • Save to platform (MANDATORY - do NOT skip):
      gemdesign page save --new --pageuuid design-system --name "设计系统" --file ./output/<projectDir>/design-system.html
      (uploads the design system page into the app so it persists on the platform and shows up in
      page list
      ; automatically ends streaming mode)
    • Verify it was saved:
      gemdesign page list
      (confirm
      design-system
      appears in the list) If the app was reused (switched via
      app use
      in step 2), skip this step AND skip step 7.
  7. Design System Review Gate (CRITICAL — only when step 6 generated a design system page): Apply the "Design System Review Gate" rules (see that section below). If no continue condition applies, STOP and ask the user for confirmation/feedback before proceeding. Do not proceed to step 8 until the design system is confirmed or a continue condition is met. If the app was reused (step 6 was skipped), skip this step too.
  8. Determine a readable
    pageuuid
    (e.g. filename without
    .html
    , unique within the app)
  9. Generate HTML following the Page Spec, using
    pageuuid
    as
    data-uuid
    in navigation elements. Follow the style baseline established (and, if applicable, confirmed) in the design system page.
  10. Use streaming write (see "Streaming Write Workflow" section):
    • Create page (enter streaming mode):
      gemdesign page create --pageuuid <pageuuid> --name "<pageName>"
    • Write the HTML file to
      ./output/<projectDir>/<pageuuid>.html
      (create the directory if it doesn't exist; use the
      <projectDir>
      computed in step 3)
  11. gemdesign validate --file ./output/<projectDir>/<pageuuid>.html
  12. Fix errors if any, re-validate
  13. gemdesign page save --new --pageuuid <pageuuid> --name "<pageName>" --file ./output/<projectDir>/<pageuuid>.html
    (uploads to platform, automatically ends streaming mode)
  14. Describe the result to the user
  15. Output designer link (MANDATORY - output ONCE, only after ALL page work is complete): After the page is generated, validated, and saved, you MUST output a clickable link in your text response so the user can easily open the designer. The link MUST be:
    • Name:
      gemdesign 设计器
      (exact text, do NOT change or translate)
    • URL:
      http://localhost:<port>
      (use the port recorded from Step 3's
      server start
      response)
    • Format (markdown link):
      [gemdesign 设计器](http://localhost:<port>)
    • Example:
      [gemdesign 设计器](http://localhost:4056)
    CRITICAL - Output this link exactly ONCE, at the very end of the workflow. Do NOT output it after each intermediate step. This is a text link for the user to click at their discretion, NOT an automatic browser open action. See Workflow A step 12 for the full rationale on why this does not conflict with Step 3's "do not output URLs in chat" rule.
When user requests modifications:
  1. gemdesign page get --pageuuid <id> --file ./output/<projectDir>/<id>.html
    to retrieve HTML+DSL for editing
  2. Modify the HTML (adjust DOM, add/remove interaction DSL, update jsHandle)
    • For substantial modifications, use the Streaming Write Workflow: rewrite the HTML (delete the old file first if starting fresh, or append if only adding)
  3. gemdesign validate --file ./output/<projectDir>/<id>.html
  4. Fix errors if any, re-validate
  5. gemdesign page save --pageuuid <id> --file ./output/<projectDir>/<id>.html
  6. If requirement doc needs updating:
    gemdesign page doc save --pageuuid <id> --file <updated-doc.md>
当用户在对话中请求页面时:
  1. 完成前提条件:确保步骤1(CLI安装/更新)、步骤2(登录)以及步骤2.5(已配置htmlWorkdir并完成清理)已确认完成后再继续。步骤3(本地服务器+浏览器预览)无需在此执行 — 它会在下面的步骤5中执行,即创建或复用应用之后。
  2. 确保应用存在(优先复用!)
    • 确保htmlWorkdir已配置(必须在
      app create
      之前完成)
      :htmlWorkdir已在步骤2.5中配置(会话间持久化)。用
      gemdesign server workdir
      (不带参数)验证;如果返回空的
      htmlWorkdir
      ,先运行
      gemdesign server workdir --path ./output
      。这必须在
      app create
      之前完成,以便
      app create
      htmlWorkdir
      下同步创建本地项目文件夹
      {projectName}__{appuuid}
    • 运行
      gemdesign app list
      检查现有应用
    • 如果已有应用:运行
      gemdesign app use --appuuid <id>
      将目标应用设置为默认应用。除非用户明确要求,否则请勿创建新应用。
    • 如果没有应用:运行
      gemdesign app create --name "<AppName>" [--type web|app] [--width <px>] [--height <px>] [--workdir <path>]
      创建应用(默认类型为
      web
      ;默认画布尺寸:
      web
      -> 1920×1080,
      app
      -> 440×956)。
      app create
      会在
      htmlWorkdir
      下同步创建本地项目文件夹(传递
      --workdir
      可一步设置)。创建后立即运行
      gemdesign app info
      确认应用存在并记录其appuuid。本次会话中无论任何理由都请勿再次运行
      app create
      之前运行的服务会在步骤5的
      server stop
      中统一终止。
    • 关键 - 请勿创建重复应用:如果已在本次会话中运行过
      app create
      (即使是之前的工作流尝试),请勿再次运行。通过
      app list
      +
      app use
      复用现有应用。创建第二个应用会在平台上留下第一个空的孤立应用。
    • 关键:所有页面必须放入同一个应用。复用现有应用可防止页面分散到不同项目文件夹中。
  3. 获取项目目录名称
    • 运行
      gemdesign app info
      获取
      {appuuid}
      {projectName}
    • 计算
      <projectDir> = {projectName}__{appuuid}
      (从projectName中移除非法字符
      \/:*?"<>|
      ,空格替换为
      _
  4. 向用户输出当前应用信息(关键 — 用户必须知道页面将生成到哪个应用中):
    • 生成任何HTML之前,必须在文本响应中明确告知用户页面将生成到哪个应用中。至少输出:
      • 应用名称(来自
        app info
        projectName
      • 应用UUID(来自
        app info
        appuuid
      • 应用类型(来自
        app info
        pageScene
        web
        表示桌面端,
        app
        表示移动端)
      • 项目目录(步骤3中计算的
        <projectDir>
    • 示例输出格式:
      📦 当前应用信息
      - 应用名称:电商 App
      - 应用 ID:abc-123
      - 应用类型:app(移动端)
      - 项目目录:电商_App__abc-123
    • 类型匹配
      pageScene
      值决定了你必须遵循的页面布局。为
      web
      应用生成
      web
      (桌面端,宽屏)页面,为
      app
      应用生成
      app
      (移动端,窄屏)页面。请勿混合类型 — web应用不能包含app页面,反之亦然。
    • 如果用户未明确指定应用且你复用了现有应用,还需告知用户选择了哪个应用(例如"已复用现有应用:电商 App"),以便用户选错时可以中断。
    • 无需等待回复:此信息仅作告知 — 除非用户想要切换应用,否则无需等待用户回复。输出后立即进入下一步。
  5. 启动本地服务器(步骤3):现在应用已存在且
    <projectDir>
    已计算完成,执行步骤3(请参阅上面的"步骤3:启动本地服务器"部分) — 必须先执行
    gemdesign server stop
    终止之前的服务
    (无论应用是新建还是复用,也无论之前是否已运行服务,均不可跳过此步),必须等
    server stop
    命令返回结果(确认已停止或无运行中的服务)之后
    ,才能执行
    gemdesign server start
    启动本地服务,并仅打开一次浏览器到设计器
    http://localhost:<port>/
    。记录
    server start
    返回的
    <port>
    供后续步骤使用。这是硬性要求:服务未运行或浏览器预览未打开前,不得进入任何页面生成。
    • 关键 - 严禁跳过
      server stop
      这一步
      :即使你认为当前会话中没有运行中的服务,也必须执行
      gemdesign server stop
      命令并以命令返回结果为准。禁止以"服务器已在运行"、"上一次workflow已启动"、"浏览器预览已打开"等理由跳过stop。stop返回
      {"success":false,"error":"未发现运行中的本地服务"}
      时表示无服务可停,此时可继续下一步start。
    • 关键 -
      server start
      必须等
      server stop
      执行完成后再执行
      :禁止将stop和start并行执行、或先start后stop。
      server start
      的前置条件是
      server stop
      已返回结果。
    • 绝不要用生成页面的URL打开浏览器(例如
      http://localhost:<port>/output/<projectDir>/<pageuuid>.html
      )——这会用生成的HTML覆盖设计器,破坏预览界面。
  6. 生成设计系统页面(仅适用于新建应用):如果步骤2中创建了新应用(而非复用),在生成业务页面之前先生成设计系统页面作为视觉样式基准。后续所有业务页面都应遵循此样式。根据
    app info
    返回的
    pageScene
    确定设计系统类型,并按照下面专门的**"设计系统页面规范"部分中的类型表和页面结构生成页面。pageuuid固定为
    design-system
    ,不计为业务页面。必须将设计系统页面保存到平台(而非仅写入本地)——否则它不会出现在应用中,无法作为样式基准。 使用
    流式写入工作流**并遵循以下明确步骤(与业务页面的创建-验证-保存流程相同):
    • 创建页面(进入流式模式):
      gemdesign page create --pageuuid design-system --name "设计系统"
    • 将HTML文件写入
      ./output/<projectDir>/design-system.html
      (遵循设计系统页面规范;pageuuid为
      design-system
    • 验证:
      gemdesign validate --file ./output/<projectDir>/design-system.html
      (修复错误并重新验证)
    • 保存到平台(必须执行 - 请勿跳过)
      gemdesign page save --new --pageuuid design-system --name "设计系统" --file ./output/<projectDir>/design-system.html
      (将设计系统页面上传到应用,使其在平台上持久化并显示在
      page list
      中;自动结束流式模式)
    • 验证已保存:
      gemdesign page list
      (确认
      design-system
      出现在列表中) 如果应用是复用的(步骤2中通过
      app use
      切换),跳过此步骤和步骤7。
  7. 设计系统审核关卡(关键 — 仅当步骤6生成了设计系统页面时执行):应用**"设计系统审核关卡"**规则(请参阅下面的该部分)。如果没有继续条件适用,停止操作并请求用户确认/反馈后再继续。在设计系统得到确认或满足继续条件之前,请勿进入步骤8。如果应用是复用的(跳过了步骤6),也跳过此步骤。
  8. 确定易读的
    pageuuid
    (例如不带
    .html
    的文件名,在应用内唯一)
  9. 按照页面规范生成HTML,将
    pageuuid
    用作导航元素中的
    data-uuid
    。遵循设计系统页面中确立(并在适用时已确认)的样式基准。
  10. 使用流式写入(请参阅"流式写入工作流"部分):
    • 创建页面(进入流式模式):
      gemdesign page create --pageuuid <pageuuid> --name "<pageName>"
    • 将HTML文件写入
      ./output/<projectDir>/<pageuuid>.html
      (如果目录不存在则创建;使用步骤3中计算的
      <projectDir>
  11. gemdesign validate --file ./output/<projectDir>/<pageuuid>.html
  12. 如果有错误则修复,重新验证
  13. gemdesign page save --new --pageuuid <pageuuid> --name "<pageName>" --file ./output/<projectDir>/<pageuuid>.html
    (上传到平台,自动结束流式模式)
  14. 向用户描述结果
  15. 输出设计器链接(必须执行 - 仅在所有页面工作完成后输出一次):页面生成、验证并保存后,必须在文本响应中输出可点击链接,方便用户打开设计器。链接必须:
    • 名称
      gemdesign 设计器
      (确切文本,请勿修改或翻译)
    • URL
      http://localhost:<port>
      (使用步骤3中
      server start
      响应记录的端口)
    • 格式(markdown链接):
      [gemdesign 设计器](http://localhost:<port>)
    • 示例:
      [gemdesign 设计器](http://localhost:4056)
    关键 - 仅在工作流结束时输出此链接一次。请勿在每个中间步骤后输出。这是供用户自行点击的文本链接,而非自动打开浏览器的操作。请参阅工作流A步骤12了解此操作不违反步骤3中"请勿在聊天中输出URL"规则的完整理由。
当用户请求修改时:
  1. gemdesign page get --pageuuid <id> --file ./output/<projectDir>/<id>.html
    获取用于编辑的HTML+DSL
  2. 修改HTML(调整DOM、添加/移除交互DSL、更新jsHandle)
    • 对于大幅修改,使用流式写入工作流:重写HTML(如果从头开始则先删除旧文件,或仅追加内容)
  3. gemdesign validate --file ./output/<projectDir>/<id>.html
  4. 如果有错误则修复,重新验证
  5. gemdesign page save --pageuuid <id> --file ./output/<projectDir>/<id>.html
  6. 如果需求文档需要更新:
    gemdesign page doc save --pageuuid <id> --file <updated-doc.md>

Workflow C: Modify Existing Page

工作流C:修改现有页面

  1. Complete Prerequisites: Ensure Step 1 (CLI install/update), Step 2 (Login), AND Step 2.5 (htmlWorkdir configured + cleanup) are confirmed complete before proceeding. Step 3 (local server + browser preview) is NOT done here — it is executed in step 4 below, AFTER
    app info
    confirms
    <projectDir>
    .
  2. Get project directory name: Run
    gemdesign app info
    → compute
    <projectDir> = {projectName}__{appuuid}
    (remove illegal chars
    \/:*?"<>|
    from projectName, collapse whitespace to
    _
    )
  3. Output current app info to user (CRITICAL — user must know which app the page being modified belongs to):
    • Before modifying any HTML, clearly tell the user in your text response which app the target page belongs to. At minimum, output:
      • App name (
        projectName
        from
        app info
        )
      • App UUID (
        appuuid
        from
        app info
        )
      • App type (
        pageScene
        from
        app info
        -
        web
        for 桌面端,
        app
        for 移动端)
      • Project directory (
        <projectDir>
        computed in step 2)
    • Example output format:
      📦 当前应用信息
      - 应用名称:电商 App
      - 应用 ID:abc-123
      - 应用类型:app(移动端)
      - 项目目录:电商_App__abc-123
    • Type matching: The
      pageScene
      value determines the page layout you MUST follow. Generate
      web
      (desktop, wide-screen) pages for
      web
      apps,
      app
      (mobile, narrow-screen) pages for
      app
      apps. Do NOT mix types - a web app cannot contain app pages, and vice versa.
    • This confirms to the user that the modification will land in the correct app, especially when multiple apps exist. If the user wanted a different app, they can interrupt here to switch via
      gemdesign app use
      .
    • Pause-friendly: This is informational only — no user reply is required unless the user wants to switch apps. Continue to the next step immediately after outputting.
  4. Start the local server (Step 3): Now that the app exists and
    <projectDir>
    is computed, execute Step 3 (see the "Step 3: Start the Local Server" section above) — 必须先执行
    gemdesign server stop
    终止之前的服务
    (无论应用是新建还是复用,也无论之前是否已运行服务,均不可跳过此步),必须等
    server stop
    命令返回结果(确认已停止或无运行中的服务)之后
    ,才能执行
    gemdesign server start
    启动本地服务,并仅打开一次浏览器到设计器
    http://localhost:<port>/
    。记录
    server start
    返回的
    <port>
    供后续步骤使用。这是 HARD GATE:服务未运行或浏览器预览未打开前,不得进入任何页面修改。
    • CRITICAL - 严禁跳过
      server stop
      这一步
      :即使你认为当前会话中没有运行中的服务,也必须执行
      gemdesign server stop
      命令并以命令返回结果为准。禁止以"服务器已在运行"、"上一次 workflow 已启动"、"浏览器预览已打开"等理由跳过 stop。stop 返回
      {"success":false,"error":"未发现运行中的本地服务"}
      时表示无服务可停,此时可继续下一步 start。
    • CRITICAL -
      server start
      必须等
      server stop
      执行完成后再执行
      :禁止将 stop 和 start 并行执行、或先 start 后 stop。
      server start
      的前置条件是
      server stop
      已返回结果。
    • Never open the browser with a generated-page URL (e.g.
      http://localhost:<port>/output/<projectDir>/<pageuuid>.html
      ) - that overwrites the designer with the generated HTML and destroys the preview surface.
  5. gemdesign page list
    -> find the target page
  6. gemdesign page get --pageuuid <id> --file ./output/<projectDir>/<id>.html
    -> retrieve HTML+DSL for editing
  7. Analyze HTML structure and interactions
  8. Modify HTML as needed
    • For substantial modifications, use the Streaming Write Workflow (see above): rewrite the HTML
  9. gemdesign validate --file ./output/<projectDir>/<id>.html
  10. Fix errors if any, re-validate
  11. gemdesign page save --pageuuid <id> --file ./output/<projectDir>/<id>.html
  12. If requirement doc needs updating:
    gemdesign page doc save --pageuuid <id> --file <updated-doc.md>
  13. Output designer link (MANDATORY - output ONCE, only after ALL page work is complete): After the page is modified, validated, and saved, you MUST output a clickable link in your text response so the user can easily open the designer to view the updated result. The link MUST be:
    • Name:
      gemdesign 设计器
      (exact text, do NOT change or translate)
    • URL:
      http://localhost:<port>
      (use the port recorded from Step 3's
      server start
      response)
    • Format (markdown link):
      [gemdesign 设计器](http://localhost:<port>)
    • Example:
      [gemdesign 设计器](http://localhost:4056)
    CRITICAL - Output this link exactly ONCE, at the very end of the workflow. Do NOT output it after each intermediate step. This is a text link for the user to click at their discretion, NOT an automatic browser open action. See Workflow A step 12 for the full rationale on why this does not conflict with Step 3's "do not output URLs in chat" rule.

  1. 完成前提条件:确保步骤1(CLI安装/更新)、步骤2(登录)以及步骤2.5(已配置htmlWorkdir并完成清理)已确认完成后再继续。步骤3(本地服务器+浏览器预览)无需在此执行 — 它会在下面的步骤4中执行,即
    app info
    确认
    <projectDir>
    之后。
  2. 获取项目目录名称:运行
    gemdesign app info
    → 计算
    <projectDir> = {projectName}__{appuuid}
    (从projectName中移除非法字符
    \/:*?"<>|
    ,空格替换为
    _
  3. 向用户输出当前应用信息(关键 — 用户必须知道要修改的页面属于哪个应用):
    • 修改任何HTML之前,必须在文本响应中明确告知用户目标页面所属的应用。至少输出:
      • 应用名称(来自
        app info
        projectName
      • 应用UUID(来自
        app info
        appuuid
      • 应用类型(来自
        app info
        pageScene
        web
        表示桌面端,
        app
        表示移动端)
      • 项目目录(步骤2中计算的
        <projectDir>
    • 示例输出格式:
      📦 当前应用信息
      - 应用名称:电商 App
      - 应用 ID:abc-123
      - 应用类型:app(移动端)
      - 项目目录:电商_App__abc-123
    • 类型匹配
      pageScene
      值决定了你必须遵循的页面布局。为
      web
      应用生成
      web
      (桌面端,宽屏)页面,为
      app
      应用生成
      app
      (移动端,窄屏)页面。请勿混合类型 — web应用不能包含app页面,反之亦然。
    • 这向用户确认修改将在正确的应用中进行,尤其是存在多个应用时。如果用户想要修改其他应用,他们可以在此中断并通过
      gemdesign app use
      切换。
    • 无需等待回复:此信息仅作告知 — 除非用户想要切换应用,否则无需等待用户回复。输出后立即进入下一步。
  4. 启动本地服务器(步骤3):现在应用已存在且
    <projectDir>
    已计算完成,执行步骤3(请参阅上面的"步骤3:启动本地服务器"部分) — 必须先执行
    gemdesign server stop
    终止之前的服务
    (无论应用是新建还是复用,也无论之前是否已运行服务,均不可跳过此步),必须等
    server stop
    命令返回结果(确认已停止或无运行中的服务)之后
    ,才能执行
    gemdesign server start
    启动本地服务,并仅打开一次浏览器到设计器
    http://localhost:<port>/
    。记录
    server start
    返回的
    <port>
    供后续步骤使用。这是硬性要求:服务未运行或浏览器预览未打开前,不得进入任何页面修改。
    • 关键 - 严禁跳过
      server stop
      这一步
      :即使你认为当前会话中没有运行中的服务,也必须执行
      gemdesign server stop
      命令并以命令返回结果为准。禁止以"服务器已在运行"、"上一次workflow已启动"、"浏览器预览已打开"等理由跳过stop。stop返回
      {"success":false,"error":"未发现运行中的本地服务"}
      时表示无服务可停,此时可继续下一步start。
    • 关键 -
      server start
      必须等
      server stop
      执行完成后再执行
      :禁止将stop和start并行执行、或先start后stop。
      server start
      的前置条件是
      server stop
      已返回结果。
    • 绝不要用生成页面的URL打开浏览器(例如
      http://localhost:<port>/output/<projectDir>/<pageuuid>.html
      )——这会用生成的HTML覆盖设计器,破坏预览界面。
  5. gemdesign page list
    -> 找到目标页面
  6. gemdesign page get --pageuuid <id> --file ./output/<projectDir>/<id>.html
    -> 获取用于编辑的HTML+DSL
  7. 分析HTML结构和交互
  8. 根据需要修改HTML
    • 对于大幅修改,使用流式写入工作流(请参阅上面):重写HTML
  9. gemdesign validate --file ./output/<projectDir>/<id>.html
  10. 如果有错误则修复,重新验证
  11. gemdesign page save --pageuuid <id> --file ./output/<projectDir>/<id>.html
  12. 如果需求文档需要更新:
    gemdesign page doc save --pageuuid <id> --file <updated-doc.md>
  13. 输出设计器链接(必须执行 - 仅在所有页面工作完成后输出一次):页面修改、验证并保存后,必须在文本响应中输出可点击链接,方便用户打开设计器查看更新后的结果。链接必须:
    • 名称
      gemdesign 设计器
      (确切文本,请勿修改或翻译)
    • URL
      http://localhost:<port>
      (使用步骤3中
      server start
      响应记录的端口)
    • 格式(markdown链接):
      [gemdesign 设计器](http://localhost:<port>)
    • 示例:
      [gemdesign 设计器](http://localhost:4056)
    关键 - 仅在工作流结束时输出此链接一次。请勿在每个中间步骤后输出。这是供用户自行点击的文本链接,而非自动打开浏览器的操作。请参阅工作流A步骤12了解此操作不违反步骤3中"请勿在聊天中输出URL"规则的完整理由。

Design System Page Spec

设计系统页面规范

When the app is newly created, generate a design system page (with pageuuid fixed as
design-system
) before generating business pages, serving as the visual style baseline for the app. All subsequent business pages should follow the colors, border radii, shadows, and component styles established in this design system. The design system page also follows the GemDesign Page Specification (see below), including tech stack rules, CSS rules, Lite-Interaction DSL, etc.
当应用是新建时,在生成业务页面之前先生成设计系统页面(pageuuid固定为
design-system
),作为应用的视觉样式基准。后续所有业务页面都应遵循此设计系统中确立的颜色、圆角、阴影和组件样式。设计系统页面也遵循GemDesign页面规范(请参阅下面),包括技术栈规则、CSS规则、Lite-Interaction DSL等。

Type Determination

类型确定

Determine the design system type based on the
pageScene
field returned by
app info
:
pageSceneDesign System TypeCore Objective
app
Mobile C-end experience-drivenCreate a consumer-facing, experience-and-emotion-driven mobile app UI design system showcase page. Showcase common interaction patterns and visual components of C-end apps, emphasizing content consumption, social interaction, and personalized experience. The page uses a mobile-width layout directly (no phone frame/外框 wrapper), presenting the mobile app interface as-is.
web
Enterprise admin function-drivenCreate a function-driven, enterprise/admin-management-oriented Web UI design system showcase page. Showcase common framework structures, data operations, and form input components of admin systems, emphasizing information density, operational efficiency, and status feedback. The page uses a full-width admin layout, simulating a real admin management system interface.
OtherFlexible analysisAnalyze the most suitable design system type based on requirements, and design flexibly using the Header + Design Tokens + Components basic structure.
根据
app info
返回的
pageScene
字段确定设计系统类型:
pageScene设计系统类型核心目标
app
移动端C端体验驱动型创建面向消费者、以体验和情感为驱动的移动端App UI设计系统展示页面。展示C端应用的常见交互模式和视觉组件,强调内容消费、社交互动和个性化体验。页面直接使用移动端宽度布局(无手机外框包装),真实呈现移动端App界面。
web
企业后台功能驱动型创建以功能为驱动、面向企业/后台管理的Web UI设计系统展示页面。展示后台系统的常见框架结构、数据操作和表单输入组件,强调信息密度、操作效率和状态反馈。页面使用全屏后台布局,模拟真实的后台管理系统界面。
其他灵活分析型根据需求分析最合适的设计系统类型,使用Header + Design Tokens + Components的基础结构灵活设计。

Page Structure —
app
Type (Mobile C-end)

页面结构 —
app
类型(移动端C端)

Header
  • Include system logo/icon, system name (Chinese), and brief description
  • Use dark or brand-color background with white text
  • Fixed at top or as a page-top banner
Section 1: Design Tokens
  • Section title style: Use a left-side colored border bar (
    border-l-4
    , using the style's primary color) + large title + tag badge combination
  • Color system: Use color swatch cards to display primary, secondary, functional, and neutral colors, with Hex values and usage notes
  • Border radius & shadows: Use physicalized blocks to display shadow effects at different levels, large radius specs (e.g. 16px/24px), soft shadows or diffuse glow
Section 2: Components
  • Media Cards: Image-text cards (large image mode), masonry/waterfall cards, video/live cover containers
  • Social Elements: User avatars, like/favorite/comment icons (with micro-interaction styles), follow buttons
  • Interactive Containers: Bottom sheet panels (Bottom Sheet/Drawer), Toast notifications (shown only as style effect displays within containers — do NOT simulate real popup effects fixed in page layout)
  • Navigation: Immersive top bar (transparent gradient), bottom navigation bar (icon + text, with selected-state animation hints)
  • Empty/Loading: Loading placeholders (Skeleton), empty-state illustration placeholders
Header
  • 包含系统Logo/图标、系统名称(中文)和简要描述
  • 使用深色或品牌色背景搭配白色文字
  • 固定在顶部或作为页面顶部横幅
第1部分:Design Tokens
  • 章节标题样式:使用左侧彩色边框条(
    border-l-4
    ,使用样式的主色调)+ 大标题 + 标签徽章组合
  • 颜色系统:使用色卡展示主色、辅助色、功能色和中性色,附带Hex值和使用说明
  • 圆角与阴影:使用实体块展示不同层级的阴影效果、大圆角规格(例如16px/24px)、柔和阴影或漫射光晕
第2部分:组件
  • 媒体卡片:图文卡片(大图模式)、瀑布流卡片、视频/直播封面容器
  • 社交元素:用户头像、点赞/收藏/评论图标(带微交互样式)、关注按钮
  • 交互容器:底部弹窗面板(Bottom Sheet/Drawer)、Toast通知(仅在容器内显示样式效果 — 请勿模拟固定在页面布局中的真实弹窗效果)
  • 导航:沉浸式顶部栏(透明渐变)、底部导航栏(图标+文字,带选中状态动画提示)
  • 空状态/加载状态:加载占位符(Skeleton)、空状态插图占位符

Page Structure —
web
Type (Enterprise Admin)

页面结构 —
web
类型(企业后台)

Header
  • Include system logo/icon, system name (Chinese), and brief description
  • Use dark or brand-color background with white text
  • Fixed at top or as a page-top banner
Section 1: Design Tokens
  • Section title style: Use a left-side colored border bar (
    border-l-4
    , using the style's primary color) + large title + tag badge combination
  • Color system: Use color swatch cards to display primary, secondary, functional, and neutral colors, with Hex values and usage notes
  • Typography hierarchy: Display H1-H4, Body, and Caption level comparisons within cards, with font/size/weight annotations
  • Border radius & shadows: Use physicalized blocks to display shadow effects at different levels
Section 2: Components
  • Use grid layout (
    grid-cols-1 lg:grid-cols-2/3
    ) to organize component displays
  • Structure/Shell: Sidebar nav items (selected/hover), top breadcrumb, Page Header
  • Data Display: Data tables (header, zebra striping, row hover, pagination), Tab pages, Tags (Tag/Badge), key-value pair lists
  • Form Elements: Input boxes (Input), dropdown selects (Select), checkboxes/radio buttons (Checkbox/Radio), switches (Switch) — must include default, Hover, Focus, and Error states
  • Actions: Action buttons (Primary, Secondary, Ghost, Icon Button)
  • Feedback/Overlays: Global messages (Message), notifications (Notification), dialogs (Modal/Dialog, shown as example displays — do NOT use full-screen modals), loading states (Skeleton/Spinner)
Header
  • 包含系统Logo/图标、系统名称(中文)和简要描述
  • 使用深色或品牌色背景搭配白色文字
  • 固定在顶部或作为页面顶部横幅
第1部分:Design Tokens
  • 章节标题样式:使用左侧彩色边框条(
    border-l-4
    ,使用样式的主色调)+ 大标题 + 标签徽章组合
  • 颜色系统:使用色卡展示主色、辅助色、功能色和中性色,附带Hex值和使用说明
  • 排版层级:在卡片内展示H1-H4、正文和说明文字的层级对比,附带字体/字号/字重注释
  • 圆角与阴影:使用实体块展示不同层级的阴影效果
第2部分:组件
  • 使用网格布局(
    grid-cols-1 lg:grid-cols-2/3
    )组织组件展示
  • 结构/框架:侧边栏导航项(选中/悬停状态)、顶部面包屑、页面Header
  • 数据展示:数据表格(表头、斑马纹、行悬停、分页)、标签页、标签(Tag/Badge)、键值对列表
  • 表单元素:输入框(Input)、下拉选择器(Select)、复选框/单选按钮(Checkbox/Radio)、开关(Switch)— 必须包含默认、悬停、聚焦和错误状态
  • 操作:操作按钮(主按钮、次按钮、幽灵按钮、图标按钮)
  • 反馈/浮层:全局消息(Message)、通知(Notification)、对话框(Modal/Dialog,仅作为示例展示 — 请勿使用全屏弹窗)、加载状态(Skeleton/Spinner)

Page Structure — Other Types

页面结构 — 其他类型

Follow the Header + Design Tokens + Components basic structure, and determine suitable components and visual style based on requirements analysis.

遵循Header + Design Tokens + Components的基础结构,根据需求分析确定合适的组件和视觉样式。

Design System Review Gate (CRITICAL)

设计系统审核关卡(关键)

When the design system page is generated (newly created apps only), you MUST apply this review gate before generating any business page. This gate does not apply to reused apps (which skip design system generation) or to Workflow C (modify existing page).
当生成设计系统页面时(仅适用于新建应用),在生成任何业务页面之前必须应用此审核关卡。此关卡不适用于复用应用(跳过设计系统生成)或工作流C(修改现有页面)。

Why this gate exists (first principles)

此关卡存在的原因(核心原则)

The design system page is a high-leverage decision point. It locks in the colors, typography, shadows, radii, and component styles that every subsequent business page will inherit. Two properties make the moment right after its generation a natural checkpoint:
  1. Asymmetric error cost. A wrong style decision made here propagates to every business page generated afterward. Correcting it after N pages exist means reworking N pages; correcting it immediately costs one round-trip with the user. The expected cost of skipping the gate grows linearly with page count, while the cost of pausing is constant and tiny.
  2. Information-state flip. Before generation, the agent can only infer the user's visual preference from the requirements doc — an uncertain state. After generation, the user can see a concrete proposal rendered in the browser — a certain state. This is the first moment the user possesses actionable information to confirm or redirect. Capturing that signal here yields maximum value: it is the cheapest point in the whole workflow to correct course.
设计系统页面是高影响力的决策点。它锁定了后续每个业务页面都将继承的颜色、排版、阴影、圆角和组件样式。其生成后的时刻成为自然检查点的两个原因:
  1. 错误成本不对称。此处做出的错误样式决策会传播到后续生成的每个业务页面。在生成N个页面后纠正错误意味着要重新处理N个页面;立即纠正仅需与用户进行一次交互。跳过此关卡的预期成本随页面数量线性增长,而暂停的成本是恒定且微小的。
  2. 信息状态转变。生成之前,Agent只能从需求文档中推断用户的视觉偏好 — 这是不确定状态。生成之后,用户可以在浏览器中看到具体的提案 — 这是确定状态。这是用户首次拥有可操作信息来确认或调整方向的时刻。在此处捕获该信号价值最大:这是整个工作流中纠正方向成本最低的节点。

Decision rule — stop or continue?

决策规则 — 停止还是继续?

After the design system page is generated, validated, and saved, evaluate the continue conditions below. The default is STOP and ask; you may only continue without asking if at least one continue condition is clearly met.
Continue conditions (any ONE is sufficient to skip the pause and proceed directly to business pages):
#ConditionWhy it's safe to continue
C1The user explicitly specified the visual style in their original request (e.g. specific brand colors, "深蓝科技风", "参考某App的样式", a mood-board, a hex code)The style direction is already locked by the user — there is no information gap for the gate to close.
C2The user ran
style search
+
style get
earlier in this session AND the design system page faithfully reflects that selected style
The user pre-signaled their preference through an explicit selection action; the design system is executing that choice, not proposing a new one.
C3The user explicitly waived the review (e.g. "不用确认,直接全部生成", "全自动跑完", "不要中途停")The user has voluntarily forfeited the checkpoint. Respect their stated preference.
If NO continue condition applies → you MUST stop. This is the default and the most common case for a freshly created app driven only by a requirements document.
设计系统页面生成、验证并保存后,评估下面的继续条件。默认是停止并询问;只有至少一个继续条件明确满足时,才能无需询问直接继续。
继续条件(满足任意一个即可跳过暂停,直接进入业务页面生成):
#条件为何可以安全继续
C1用户在原始请求中明确指定了视觉样式(例如特定品牌颜色、"深蓝科技风"、"参考某App的样式"、情绪板、Hex色值)样式方向已由用户锁定 — 此关卡无需填补信息差距。
C2用户在本次会话中已运行
style search
+
style get
,且设计系统页面忠实地反映了所选样式
用户通过明确的选择操作预先表达了偏好;设计系统是在执行该选择,而非提出新方案。
C3用户明确放弃审核(例如"不用确认,直接全部生成"、"全自动跑完"、"不要中途停")用户自愿放弃了检查点。尊重他们明确的偏好。
如果没有继续条件适用 → 必须停止。这是默认情况,也是仅由需求文档驱动的新建应用最常见的情况。

When you stop — what to present

停止时 — 展示什么内容

Do not merely announce "设计系统已生成". Present a decision-ready summary so the user can confirm or redirect with minimal effort:
  1. Style decisions made — primary/secondary colors (with hex), overall direction (e.g. 科技感/温暖/极简), key component treatments (card radius, shadow style, button style). Be concrete, not vague.
  2. Reasoning link — connect the decisions back to the requirements (e.g. "基于需求文档中'面向年轻人的社交平台'定位,主色选用高饱和的紫色…").
  3. Explicit ask — use the
    AskUserQuestion
    tool to structure the choice. Suggested options:
    • "确认,继续生成业务页面"
    • "调整配色方案"
    • "调整整体风格方向"
    • (the user can also type a custom response via "其他")
不要仅仅宣布"设计系统已生成"。展示便于决策的摘要,让用户能以最小的努力确认或调整方向:
  1. 已做出的样式决策 — 主色/辅助色(带Hex值)、整体风格方向(例如科技感/温暖/极简)、关键组件处理方式(卡片圆角、阴影样式、按钮样式)。要具体,不要模糊。
  2. 推理链接 — 将决策与需求关联(例如"基于需求文档中'面向年轻人的社交平台'定位,主色选用高饱和的紫色…")。
  3. 明确询问 — 使用
    AskUserQuestion
    工具构建选项。建议选项:
    • "确认,继续生成业务页面"
    • "调整配色方案"
    • "调整整体风格方向" -(用户也可以通过"其他"输入自定义回复)

After the user responds

用户回复后

  • User confirms → proceed to business page generation, treating the confirmed design system as the locked style baseline for all pages.
  • User requests adjustments -> modify the design system page first (edit -> validate -> save), then either re-present (if the change is major/subjective, e.g. a pivot from "科技蓝" to "温暖橙") or proceed (if the change is minor and clearly resolved, e.g. a single hex value tweak). Use judgment here. The "save" step here means re-running
    gemdesign page save --pageuuid design-system --file ./output/<projectDir>/design-system.html
    (NO
    --new
    flag - the page already exists on the platform from step 7/5;
    --new
    would error on duplicate pageuuid). Confirm the update with
    gemdesign page list
    .
  • Never start business pages until the design system is either (a) confirmed by the user or (b) covered by a continue condition above.

  • 用户确认 → 进入业务页面生成,将已确认的设计系统作为所有页面的锁定样式基准。
  • 用户请求调整 -> 先修改设计系统页面(编辑 -> 验证 -> 保存),然后要么重新展示(如果修改重大/主观,例如从"科技蓝"转向"温暖橙"),要么继续(如果修改微小且明确解决了问题,例如调整单个Hex值)。此处需自行判断。此处的"保存"步骤意味着重新运行
    gemdesign page save --pageuuid design-system --file ./output/<projectDir>/design-system.html
    (请勿使用
    --new
    参数 — 页面已在步骤7/5中保存到平台;
    --new
    会因pageuuid重复报错)。用
    gemdesign page list
    确认更新。
  • 在设计系统得到用户确认或满足上述继续条件之前,绝不要开始生成业务页面

GemDesign Page Specification

GemDesign页面规范

You MUST follow this spec when generating HTML. The
gemdesign validate
command checks all these rules.
生成HTML时必须遵循此规范。
gemdesign validate
命令会检查所有这些规则。

Overview

概述

A GemDesign page = HTML(DOM) + TailwindCSS(style) + Lite-Interaction DSL(interaction).
GemDesign页面 = HTML(DOM) + TailwindCSS(样式) + Lite-Interaction DSL(交互)

Tech Stack Rules

技术栈规则

Allowed: HTML native tags, TailwindCSS (via
<script>
tag), CSS (
<style>
), Font Awesome, ECharts Forbidden: Any JS framework (Vue/React/jQuery), hand-written DOM JS (except jsHandle), CSS Hack,
vh
unit
允许:HTML原生标签、TailwindCSS(通过
<script>
标签引入)、CSS(
<style>
)、Font Awesome、ECharts 禁止:任何JS框架(Vue/React/jQuery)、手写DOM JS(jsHandle除外)、CSS Hack、
vh
单位

Only Two Types of Scripts Allowed

仅允许两种类型的脚本

  1. <script id="interaction-data">
    — Lite-Interaction JSON string (interaction logic)
  2. <script id="funcName">function funcName(event){...}</script>
    — jsHandle custom function
  1. <script id="interaction-data">
    — Lite-Interaction JSON字符串(交互逻辑)
  2. <script id="funcName">function funcName(event){...}</script>
    — jsHandle自定义函数

Dependencies

依赖

html
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- ECharts (only when using charts): -->
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
<!-- ECharts China map (only when using china map): -->
<script src="https://cdn.jsdmirror.com/npm/echarts/map/js/china.js"></script>
html
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- ECharts(仅在使用图表时引入): -->
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
<!-- ECharts中国地图(仅在使用中国地图时引入): -->
<script src="https://cdn.jsdmirror.com/npm/echarts/map/js/china.js"></script>

Layout Rules

布局规则

  1. Use TailwindCSS for layout component classes.
  2. Prefer flexbox layout; Flexbox, padding, and gap are the core tools for interface layout.
  3. Block elements can be used for simple elements (text, decorative images), but NOT for layout. All elements default to the
    border-box
    box model.
  4. Fixed elements (sidebars, nav bars) must have explicit height/width; content area needs matching padding.
  5. Masks and modals/drawers must be nested. The mask/overlay layer MUST have a semi-transparent background color (e.g.
    bg-black/50
    ), and the inner modal/drawer content container MUST have an opaque background color (e.g.
    bg-white
    ) - a transparent content container is a SERIOUS VIOLATION, as it lets the mask color bleed through.
  6. When centering elements, absolutely do NOT use
    mx-auto
    or
    m-auto
    - you MUST use flex layout's
    justify-center
    and
    items-center
    on the parent element.
  1. 使用TailwindCSS布局组件类。
  2. 优先使用flexbox布局;Flexbox、内边距和间隙是界面布局的核心工具。
  3. 块元素可用于简单元素(文本、装饰图片),但不可用于布局。所有元素默认使用
    border-box
    盒模型。
  4. 固定元素(侧边栏、导航栏)必须有明确的高度/宽度;内容区域需要匹配的内边距。
  5. 遮罩和弹窗/抽屉必须嵌套。遮罩/浮层必须有半透明背景色(例如
    bg-black/50
    ),内部弹窗/抽屉内容容器必须有不透明背景色(例如
    bg-white
    )— 透明内容容器是严重违规的,因为它会让遮罩颜色透出来。
  6. 居中元素时,绝对不要使用
    mx-auto
    m-auto
    — 必须在父元素上使用flex布局的
    justify-center
    items-center

CSS Rules

CSS规则

Rule 1: No
vh
unit

规则1:禁止使用
vh
单位

Forbidden: the
vh
unit, any Tailwind CSS class containing
vh
, and any class containing
vh
(e.g.
h-[80vh]
).
禁止:
vh
单位、任何包含
vh
的Tailwind CSS类、任何包含
vh
的自定义类(例如
h-[80vh]
)。

Rule 2: HIGHEST-LEVEL RED LINE - ABSOLUTELY NO Margin

规则2:最高级别红线 — 绝对禁止使用外边距

The entire page is ABSOLUTELY FORBIDDEN from using ANY margin! This includes native CSS and ALL Tailwind class names with margin semantics! The model is highly prone to habitually using margin for "icon spacing" and "element top/bottom spacing" - you MUST overcome this habit!
If your output code contains ANY of the following prefixes (positive OR negative), it is a SERIOUS VIOLATION:
  • m-
    (e.g.
    m-2
    ,
    m-auto
    )
  • mt-
    (e.g.
    mt-4
    )
  • mb-
    (e.g.
    mb-3
    ,
    mb-4
    ,
    mb-6
    )
  • ml-
    (e.g.
    ml-2
    )
  • mr-
    (e.g.
    mr-1
    ,
    mr-2
    )
  • mx-
    (e.g.
    mx-auto
    )
  • my-
    (e.g.
    my-4
    )
  • space-x-
    /
    space-y-
    (the underlying implementation is also margin, ABSOLUTELY forbidden)
Mandatory alternatives - for the scenarios you are most prone to violating:
  • ❌ Violation habit 1 (icon and text spacing):
    <i class="fas fa-edit mr-1"></i>编辑
  • ✅ Correct practice 1 (use flex + gap):
    <div class="flex items-center gap-1"><i class="fas fa-edit"></i><span>编辑</span></div>
  • ❌ Violation habit 2 (title/paragraph bottom spacing):
    <h3 class="mb-4">标题</h3><form>...</form>
  • ✅ Correct practice 2 (parent flex + gap):
    <div class="flex flex-col gap-4"><h3>标题</h3><form>...</form></div>
  • ❌ Violation habit 3 (center alignment):
    class="mx-auto"
    or
    class="m-auto"
  • ✅ Correct practice 3 (parent centering): use
    flex justify-center items-center
    on the parent element
整个页面绝对禁止使用任何外边距!包括原生CSS和所有带有外边距语义的Tailwind类名!模型很容易习惯性地使用外边距来实现"图标间距"和"元素上下间距" — 必须克服这个习惯!
如果你的输出代码包含以下任何前缀(正或负),就是严重违规:
  • m-
    (例如
    m-2
    m-auto
  • mt-
    (例如
    mt-4
  • mb-
    (例如
    mb-3
    mb-4
    mb-6
  • ml-
    (例如
    ml-2
  • mr-
    (例如
    mr-1
    mr-2
  • mx-
    (例如
    mx-auto
  • my-
    (例如
    my-4
  • space-x-
    /
    space-y-
    (底层实现也是外边距,绝对禁止)
强制替代方案 — 针对你最容易违规的场景
  • ❌ 违规习惯1(图标与文本间距):
    <i class="fas fa-edit mr-1"></i>编辑
  • ✅ 正确做法1(使用flex + gap):
    <div class="flex items-center gap-1"><i class="fas fa-edit"></i><span>编辑</span></div>
  • ❌ 违规习惯2(标题/段落底部间距):
    <h3 class="mb-4">标题</h3><form>...</form>
  • ✅ 正确做法2(父元素flex + gap):
    <div class="flex flex-col gap-4"><h3>标题</h3><form>...</form></div>
  • ❌ 违规习惯3(居中对齐):
    class="mx-auto"
    class="m-auto"
  • ✅ 正确做法3(父元素居中):在父元素上使用
    flex justify-center items-center

Lite-Interaction DSL (Core)

Lite-Interaction DSL(核心)

All interactions are declared in
<script id="interaction-data">
as a JSON array wrapped in backticks.
typescript
interface TriggerEvent {
  original: string;        // Selector: #id or .class only
  trigger: 'click' | 'mouseover' | 'mouseenter' | 'mouseleave' | 'mousedown' | 'mouseup';
  actions: Action[];
}

interface Action {
  operation: 'show' | 'hide' | 'openModal' | 'closeModal' | 'addClass' | 'removeClass' | 'openPage' | 'back' | 'openLink' | 'jsHandle';
  target?: string;         // Required for show/hide/addClass/removeClass. #id only, multiple: "#id1,#id2"
  params?: string;         // addClass/removeClass: class names (comma-separated); openPage: pageUuid; openLink: URL. Forbidden for jsHandle. Must be a plain string, no code/variables.
  funcName?: string;       // Only for jsHandle
  operationTitle?: string; // Required for jsHandle/addClass/removeClass (2-8 Chinese chars)
  animation?: string;      // Animation effect name
  animationTime?: number;  // Animation duration in seconds
  delayTime?: number;      // Delay before execution in seconds
}
所有交互都在
<script id="interaction-data">
中声明为包裹在反引号中的JSON数组。
typescript
interface TriggerEvent {
  original: string;        // 选择器:仅支持#id或.class
  trigger: 'click' | 'mouseover' | 'mouseenter' | 'mouseleave' | 'mousedown' | 'mouseup';
  actions: Action[];
}

interface Action {
  operation: 'show' | 'hide' | 'openModal' | 'closeModal' | 'addClass' | 'removeClass' | 'openPage' | 'back' | 'openLink' | 'jsHandle';
  target?: string;         // show/hide/addClass/removeClass必填。仅支持#id,多个用逗号分隔:"#id1,#id2"
  params?: string;         // addClass/removeClass:类名(逗号分隔);openPage:pageUuid;openLink:URL。jsHandle禁止使用。必须是纯字符串,不能是代码/变量。
  funcName?: string;       // 仅jsHandle使用
  operationTitle?: string; // jsHandle/addClass/removeClass必填(2-8个中文字符)
  animation?: string;      // 动画效果名称
  animationTime?: number;  // 动画持续时间(秒)
  delayTime?: number;      // 执行前延迟时间(秒)
}

Selector Rules (CRITICAL)

选择器规则(关键)

RuleDetail
original
and
target
Only
#id
or
.class
— NO attribute selectors (
[data-xxx]
)
original
Single element only — no multiple selectors
target
Multiple IDs allowed:
"#id1,#id2"
— NO
.class
allowed
If element only has data attributesYou MUST add an
id
to it, then use
#id
in DSL
规则细节
original
target
仅支持
#id
.class
— 禁止属性选择器(
[data-xxx]
original
仅支持单个元素 — 禁止多个选择器
target
允许多个ID:
"#id1,#id2"
— 禁止
.class
如果元素只有data属性必须为其添加
id
,然后在DSL中使用
#id

Operation Priority

操作优先级

  1. show
    /
    hide
    — preferred for opening/closing modals
  2. addClass
    /
    removeClass
    — CSS changes
  3. openPage
    — page navigation (params must be pageUuid string only)
  4. back
    — go back
  5. jsHandle
    — only when above can't satisfy the requirement
  1. show
    /
    hide
    — 优先用于打开/关闭弹窗
  2. addClass
    /
    removeClass
    — CSS样式变更
  3. openPage
    — 页面导航(params必须是pageUuid字符串)
  4. back
    — 返回
  5. jsHandle
    — 仅当上述操作无法满足需求时使用

jsHandle Rules

jsHandle规则

  1. Each function in its own
    <script>
    tag
  2. Script
    id
    MUST match function name exactly
  3. Only one parameter:
    event
  4. No API calls inside
html
<script id="tabSwitchXxx">
function tabSwitchXxx(event) {
  // full implementation
}
</script>
  1. 每个函数单独放在一个
    <script>
    标签中
  2. Script的
    id
    必须与函数名完全匹配
  3. 仅允许一个参数:
    event
  4. 内部禁止调用API
html
<script id="tabSwitchXxx">
function tabSwitchXxx(event) {
  // 完整实现
}
</script>

Page Navigation

页面导航

For navigation elements, add
id
AND
data-uuid
to the HTML tag. The
data-uuid
value MUST match the
--pageuuid
you pass to
page save --new
:
html
<!-- If you will save this target page with: page save --new --pageuuid home --name "首页" -->
<a id="nav-home" data-uuid="home" href="javascript:void(0);">首页</a>
Do NOT add openPage events in interaction-data for these — they are auto-generated.
对于导航元素,在HTML标签中添加
id
data-uuid
data-uuid
的值必须与你传递给
page save --new
--pageuuid
一致:
html
<!-- 如果将此目标页面保存为:page save --new --pageuuid home --name "首页" -->
<a id="nav-home" data-uuid="home" href="javascript:void(0);">首页</a>
请勿在interaction-data中添加openPage事件 — 它们会自动生成。

Image Placeholders

图片占位符

Use placeholder URLs, the platform replaces them with real images:
html
<img src="./api/searchImage?query=premium laptop on white background&width=400&height=400" class="w-full h-full object-cover" />
使用占位符URL,平台会将其替换为真实图片:
html
<img src="./api/searchImage?query=premium laptop on white background&width=400&height=400" class="w-full h-full object-cover" />

Button Rules

按钮规则

  • ALL buttons must have
    type="button"
  • NO
    type="submit"
  • Use
    href="javascript:void(0);"
    for links, never
    href="#"
  • 所有按钮必须有
    type="button"
  • 禁止使用
    type="submit"
  • 链接使用
    href="javascript:void(0);"
    ,绝不要使用
    href="#"

Design Constraints

设计约束

  • Shadows: Use diffuse shadows:
    shadow-[0_8px_30px_rgba(0,0,0,0.04)]
    , not short dark shadows
  • Native controls: No
    <select>
    or radio buttons for option switching — use capsule segmented controls
  • Horizontal scroll: Hide scrollbar with
    scrollbar-hide
  • Modals/masks/drawers: Add
    hidden
    class by default; use nested structure. The mask/overlay layer MUST have a semi-transparent background color (e.g.
    bg-black/50
    ), and the inner modal/drawer content container MUST have an opaque background color (e.g.
    bg-white
    ). A transparent content container is a SERIOUS VIOLATION - the mask color will bleed through and the popup content area will appear as the mask color. Example:
    html
    <div id="modalMask" class="modal-mask hidden fixed inset-0 bg-black/50 flex justify-center items-center z-50">
      <div class="bg-white rounded-lg p-6">
        <!-- Modal content - inner container MUST have bg-white or other opaque color -->
      </div>
    </div>
  • CSS override: When status class (like
    hidden
    ) overrides component class, combine in stylesheet:
    .modal-mask.hidden { display: none; }
    — do NOT use
    @apply hidden
  • 阴影:使用漫射阴影:
    shadow-[0_8px_30px_rgba(0,0,0,0.04)]
    ,不要使用短而深的阴影
  • 原生控件:不要使用
    <select>
    或单选按钮进行选项切换 — 使用胶囊分段控件
  • 横向滚动:使用
    scrollbar-hide
    隐藏滚动条
  • 弹窗/遮罩/抽屉:默认添加
    hidden
    类;使用嵌套结构。遮罩/浮层必须有半透明背景色(例如
    bg-black/50
    ),内部弹窗/抽屉内容容器必须有不透明背景色(例如
    bg-white
    )。透明内容容器是严重违规的 — 遮罩颜色会透出来,弹窗内容区域会显示为遮罩颜色。示例:
    html
    <div id="modalMask" class="modal-mask hidden fixed inset-0 bg-black/50 flex justify-center items-center z-50">
      <div class="bg-white rounded-lg p-6">
        <!-- 弹窗内容 - 内部容器必须有bg-white或其他不透明颜色 -->
      </div>
    </div>
  • CSS覆盖:当状态类(如
    hidden
    )覆盖组件类时,在样式表中合并:
    .modal-mask.hidden { display: none; }
    — 禁止使用
    @apply hidden

Script Order

脚本顺序

  1. TailwindCSS (in
    <head>
    )
  2. ECharts dependency (in
    <head>
    , optional)
  3. tailwind.config
    configuration
  4. ECharts config scripts (
    <script id="echarts_*" type="echarts">
    , optional)
  5. jsHandle function scripts (
    <script id="funcName">
    , optional)
  6. interaction-data
    MUST be the last
    <script>
    tag
  1. TailwindCSS(在
    <head>
    中)
  2. ECharts依赖(在
    <head>
    中,可选)
  3. tailwind.config
    配置
  4. ECharts配置脚本(
    <script id="echarts_*" type="echarts">
    ,可选)
  5. jsHandle函数脚本(
    <script id="funcName">
    ,可选)
  6. interaction-data
    必须是最后一个
    <script>
    标签

Complete Page Template

完整页面模板

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdn.tailwindcss.com"></script>
  <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css">
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: { primary: '#1890ff' }
        }
      }
    };
  </script>
  <style>
    .modal-mask.hidden { display: none; }
  </style>
</head>
<body>
  <div id="app">
    <!-- Page DOM -->
  </div>

  <!-- jsHandle functions (optional) -->
  <!-- <script id="funcName">function funcName(event) {...}</script> -->

  <!-- Interaction DSL (MUST be last script) -->
  <script id="interaction-data">
`
[
  {
    "original": "#elementId",
    "trigger": "click",
    "actions": [
      { "operation": "show", "target": "#targetId" }
    ]
  }
]
`
  </script>
</body>
</html>
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdn.tailwindcss.com"></script>
  <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css">
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: { primary: '#1890ff' }
        }
      }
    };
  </script>
  <style>
    .modal-mask.hidden { display: none; }
  </style>
</head>
<body>
  <div id="app">
    <!-- 页面DOM -->
  </div>

  <!-- jsHandle函数(可选) -->
  <!-- <script id="funcName">function funcName(event) {...}</script> -->

  <!-- 交互DSL(必须是最后一个脚本) -->
  <script id="interaction-data">
`
[
  {
    "original": "#elementId",
    "trigger": "click",
    "actions": [
      { "operation": "show", "target": "#targetId" }
    ]
  }
]
`
  </script>
</body>
</html>

Validation Rules Summary

验证规则摘要

The
gemdesign validate
command checks:
#RuleWhat it checks
1interaction_data_exists
<script id="interaction-data">
present
2dsl_json_validContent is valid JSON array
3selector_existsAll original/target selectors exist in DOM
4selector_formatOnly #id and .class, no attribute selectors
5original_singleoriginal has only one selector
6target_no_classtarget uses only #id, no .class
7jshandle_func_matchEach funcName has matching
<script id="funcName">
8script_id_funcname_matchscript id equals function name
9button_typeAll buttons have type="button", no type="submit"
10no_vhNo vh unit in classes or styles
11no_hash_hrefNo href="#"
12image_url_formatPlaceholder image URLs use
./api/searchImage?query=...&width=...&height=...
with numeric width/height, no spaces around
&
13data_uuid_completeTags with data-uuid also have id
14interaction_data_lastinteraction-data is the last script tag
gemdesign validate
命令检查以下内容:
#规则检查内容
1interaction_data_exists是否存在
<script id="interaction-data">
标签
2dsl_json_valid内容是否为有效的JSON数组
3selector_exists所有original/target选择器是否在DOM中存在
4selector_format仅支持#id和.class,禁止属性选择器
5original_singleoriginal仅包含一个选择器
6target_no_classtarget仅使用#id,禁止.class
7jshandle_func_match每个funcName是否有匹配的
<script id="funcName">
8script_id_funcname_matchscript id是否与函数名一致
9button_type所有按钮是否有type="button",禁止type="submit"
10no_vh类或样式中是否存在vh单位
11no_hash_href是否存在href="#"
12image_url_format占位符图片URL是否使用
./api/searchImage?query=...&width=...&height=...
格式,width/height为数字,
&
周围无空格
13data_uuid_complete带有data-uuid的标签是否同时有id
14interaction_data_lastinteraction-data是否是最后一个脚本标签

Tips

提示

  • Always validate before saving —
    gemdesign validate
    catches errors early
  • For batch generation, validate each page individually before saving
  • Save HTML locally for every page:
    ./output/<projectDir>/<pageuuid>.html
    for editing and saving to the platform. Always compute
    <projectDir> = {projectName}__{appuuid>
    first via
    gemdesign app info
    . The CLI is idempotent - passing a path that already contains
    <projectDir>
    will not duplicate it.
  • When creating a new page, pass a readable
    --pageuuid
    (e.g.
    home
    ,
    login
    ) - use the same value as
    data-uuid
    in navigation elements, so you don't need to update them after saving
  • Use
    gemdesign page get --file <path>
    to retrieve editable HTML+DSL before modifying
  • The full page spec is available at
    page-spec.md
    in the CLI project directory
  • 保存前始终进行验证 —
    gemdesign validate
    能及早发现错误
  • 批量生成时,每个页面保存前单独验证
  • 为每个页面保存本地HTML
    ./output/<projectDir>/<pageuuid>.html
    用于编辑和保存到平台。始终先通过
    gemdesign app info
    计算
    <projectDir> = {projectName}__{appuuid}
    。CLI具有幂等性 — 传递已包含
    <projectDir>
    的路径不会重复添加。
  • 创建新页面时,传递易读的
    --pageuuid
    (例如
    home
    login
    )— 与导航元素中的
    data-uuid
    使用相同值,保存后无需修改。
  • 修改前使用
    gemdesign page get --file <path>
    获取可编辑的HTML+DSL
  • 完整页面规范可在CLI项目目录的
    page-spec.md
    中查看