mcpField
G
gemdesign-skill

gemdesign-skill

github.com/gemdesign-ai设计与 UI2183 次安装9 周前更新
代码仓库

关于 gemdesign-skill

gemdesign-skill 指导用户通过 gemdesign CLI 在 GemDesign 平台创建、保存和修改高保真原型页面,适用于 UI 原型设计与批量页面生成。它规定了 CLI、登录、工作目录和本地预览的操作顺序。

主要功能

  1. 01生成符合 Page Spec 的 HTML
  2. 02校验并保存原型页面
  3. 03创建或复用 GemDesign 应用
  4. 04配置 HTML 工作目录
  5. 05启动本地实时预览服务
  6. 06规定 CLI 与登录前置检查

适用场景

  1. 01根据需求文档批量生成页面
  2. 02修改现有 GemDesign 页面
  3. 03查看已保存的原型页面
  4. 04生成页面时查看实时预览

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/gemdesign-ai/skills --skill gemdesign-skill

安装后在 Claude Code 中输入/gemdesign-skill确认已加载。

附带文件README.md

详细介绍

GemDesign 原型设计

使用 gemdesign CLI 在 GemDesign 平台上创建、保存和修改高保真原型页面。你需要按照 GemDesign Page Spec 生成 HTML、进行验证,然后通过 CLI 保存。

何时调用

  • 用户想创建 UI 原型或设计页面
  • 用户有需求文档,并希望批量生成页面
  • 用户想修改现有的 GemDesign 页面
  • 用户想查看现有的 GemDesign 页面

前置条件

关键:在开始任何工作流之前,必须严格按照顺序执行步骤 1、步骤 2 和步骤 2.5。每一步都必须完全完成后,才能继续下一步。请勿跳过、并行执行,也不要在当前步骤确认成功之前进入下一步。

重要 — 步骤 3 的时机:步骤 3(启动本地服务)不会在登录后立即执行。必须在某个工作流内部、应用创建或复用之后(即执行 gemdesign app create 或 gemdesign app use + gemdesign app info 之后)、生成任何页面之前执行。在应用存在之前启动服务属于违规操作——服务会提供应用对应的项目子目录中的页面,因此必须先创建应用。

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

务必先确认 CLI 已安装且版本正确,再进行任何其他操作。此步骤是硬性门槛——在确认此步骤完成之前,不得运行任何其他操作(auth、app、page、style 等)。

  1. 检查 CLI 是否已安装:

    npm list -g @gemdesign-ai/cli
    
    • 如果命令返回版本信息(例如 @gemdesign-ai/[email protected]),则 CLI 已安装——继续步骤 2。
    • 如果命令返回空结果或错误(例如 (empty) 或 ERR!),则表示 CLI 尚未安装。运行:
      npm install -g @gemdesign-ai/cli
      
      等待安装完成,然后使用 npm list -g @gemdesign-ai/cli 再次验证。在再次验证确认已安装相应版本之前,请勿继续。
  2. 检查 CLI 是否为最新版本(仅在步骤 1 确认 CLI 已安装后执行):

    npm outdated -g @gemdesign-ai/cli
    
    • 如果命令返回空结果或显示 Current=Latest,则表示 CLI 已是最新版本——此步骤完成,继续步骤 2。
    • 如果命令显示版本信息,且 Current 和 Latest 的值不同,则表示 CLI 版本过旧。请更新到最新版本:
      npm update -g @gemdesign-ai/cli
      
      等待更新完成,然后使用 npm outdated -g @gemdesign-ai/cli 再次验证。在再次验证确认 CLI 已是最新版本之前,请勿继续。

确认此步骤完成后,即可全局使用最新版本的 gemdesign-ai 命令。只有此时才能进入步骤 2。

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

步骤 1 完成后,务必验证登录状态。运行此命令:

gemdesign auth whoami
  • 如果成功(返回用户信息),则用户已登录——继续执行工作流(A/B/C)。步骤 3(本地服务)将在工作流内部、创建或复用应用后执行。
  • 如果失败(返回类似“GemDesign令牌 无效”或“未提供 GemDesign令牌”的错误),则用户未通过身份验证。你必须:
    1. 告知用户:如果他们还没有账号或 GemDesign令牌,请前往 https://design.gemcoder.com 注册账号并获取 GemDesign令牌。GemDesign令牌的获取路径为:登录平台 -> 点击 个人中心 (Personal Center) -> 获取 GemDesign令牌 (GemDesign令牌)。
    2. 向用户索取 GemDesign令牌(使用 AskUserQuestion 工具提示用户输入其 GemDesign令牌)。
    3. 用户提供 GemDesign令牌后,自动为其运行登录命令:
      gemdesign auth login --token <user_provided_token>
      
    4. 使用 gemdesign auth whoami 重新验证,确认登录成功。
    5. 如果登录仍然失败,从步骤 2 重试(再次询问用户提供 GemDesign令牌)。
    6. 只有确认登录后,才能继续执行工作流。

严格门禁:在通过 gemdesign auth whoami 确认登录之前,绝不能执行任何页面生成工作——包括 CLI 命令(app、page、style、validate)和本地文件操作(写入 .html、流式写入、创建 ./output/ 目录)。本地 HTML 生成不能绕过登录门禁;只有通过身份验证的用户才能将页面保存到平台,因此登录前生成页面是无用功。如果登录失败,请停止并先解决身份验证问题——不要开始编写任何 HTML。

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

确认登录后,先清理之前中断的会话遗留的空项目目录,再配置 HTML 工作目录(htmlWorkdir)。顺序为强制要求:必须先运行 cleanup,再运行 workdir --path,绝不能颠倒。两项操作都必须在启动任何工作流之前完成(尤其是在 app create 之前)。

重要——为什么必须先运行 cleanup(顺序不可更改):gemdesign server workdir --path ./output 会创建 ./output 目录——此时该目录是一个空工作目录,其中还没有项目子目录({projectName}__{appuuid}),因为尚未运行 app create。gemdesign server cleanup 会运行 pruneEmptyWorkdirs(),删除不包含任何项目子目录的工作目录,并将其从 htmlWorkdir 配置中移除。如果先运行 workdir 再运行 cleanup,新创建的空 ./output 会被视为过期的空工作目录——cleanup 会删除该目录并将其从配置中清除,导致 htmlWorkdir 为空。后续影响:app create 会跳过本地文件夹的创建(返回 warning),而 server start 会拒绝启动("未配置 htmlWorkdir..."),导致“页面已生成,但画布未显示”。先运行 cleanup 可避免此问题:它会清除之前会话遗留的状态,然后由 workdir 最后创建 ./output,使其保留下来。(注意:cleanup 不要求预先配置 htmlWorkdir——如果尚未配置,它只会返回 "未配置 htmlWorkdir,无需清理" 并正常退出。)

  1. 清理空项目目录(必须首先运行,在配置 htmlWorkdir 之前):

    gemdesign server cleanup
    
    • 如果尚未配置 htmlWorkdir,命令会返回 {"success":true,"message":"未配置 htmlWorkdir,无需清理","removedDirs":[],"removedLocks":[],"removedWorkdirs":[],"removedWorkdirDirs":[]}——这是正常情况,请继续执行步骤 2。
    • 如果已在之前的会话中配置 htmlWorkdir,命令会扫描每个已配置的工作目录,查找项目子目录(名称为 {projectName}__{appuuid}),并执行以下操作:
      • 删除空项目目录:其中不包含任何 .html 文件的项目子目录(由 app create 创建,但从未保存过页面,例如会话中断的情况)。
      • 清理遗留的流式写入文件:清理由已启动但未完成的流式写入留下的 .stream.lock 文件。
      • 移除空工作目录:不包含任何项目子目录的工作目录会被删除并从配置中移除(这正是 workdir --path 必须在 cleanup 之后运行的原因)。
    • 返回 JSON:{"success":true,"message":"清理完成:删除 N 个空项目目录,清理 M 个遗留文件,移除 K 个无项目的 htmlWorkdir","removedDirs":[...],"removedLocks":[...],"removedWorkdirs":[...],"removedWorkdirDirs":[...]}
    • 此步骤不会阻塞后续操作:清理失败不会阻止继续执行工作流。除非发生意外错误,否则命令始终返回 success: true。
  2. 配置 htmlWorkdir(必须在步骤 1 之后运行;仅需运行一次,配置会在不同会话间保留):

    **重要——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 变更,画布也会保持空白(“页面已生成,但画布未显示”)。

    gemdesign server workdir --path ./output
    
    • 相对路径会根据当前工作目录解析为绝对路径。
    • 使用 gemdesign server workdir(不带标志)验证——返回 {"success":true,"htmlWorkdir":["<absolute path>"]}。
    • 此处创建的 ./output 目录不会在同一个步骤 2.5 中被 cleanup 删除,因为 cleanup 已在步骤 1 中运行。此步骤之后不要重新运行 cleanup——重新运行会删除刚创建的空 ./output(因为尚未运行 app create,其中没有项目子目录)。
步骤 3:启动本地服务(必须在创建或复用 app 后、生成任何页面前完成)

**重要——硬性要求:此步骤中必须打开浏览器。**这项要求不可协商,绝不能跳过、延后或视为可选。浏览器打开之前生成任何页面都属于严重违规——用户需要通过实时预览界面查看页面生成过程。你必须使用平台内置的浏览器/预览工具主动打开浏览器(回退方案见下方步骤 3)。不要只在聊天中输出 URL 并等待用户点击——必须以编程方式打开浏览器。

**时机——在工作流内部执行,不要在登录后立即执行。**步骤 3 应从工作流 A/B/C 内调用(参见各工作流中的“启动本地服务”步骤),并且要在通过 gemdesign app create / gemdesign app use 创建或复用 app 后,再通过 gemdesign app info 确认。不要在步骤 2(登录)后立即启动服务——服务会从 app 对应的项目子目录(<projectDir> = {projectName}__{appuuid})提供页面,因此 app 必须先存在。在 app 不存在时启动服务属于违规行为。 完成第 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 的实际返回结果作为唯一判定依据。

    gemdesign server stop
    
    • 返回 {"success":true,"message":"本地服务已停止"} 表示已停止,继续下一步。
    • 返回 {"success":false,"error":"未发现运行中的本地服务"} 表示无运行中的服务,忽略此错误,继续下一步。
    • 必须等待上述命令返回结果后才能进入第 2 步。在 stop 命令未返回前,不得执行任何 server start 操作。
  3. 使用 CLI 命令启动本地服务:

    gemdesign server start
    

    必须在执行此命令前先完成上一步的 gemdesign server stop,不得在未停止旧服务的情况下直接 start。

    硬性门槛 — 顺序约束:只有在 server stop 命令返回结果(成功或“未发现运行中的本地服务”错误)之后,才能执行 server start。严禁以下行为:

    • 并行执行 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. 检查服务状态(可选,用于调试):

    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:/ 查看设计器预览”,并等待用户确认后再继续。

    如何查找平台内置工具: 检查可用工具列表——查找名称类似 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 必须始终是设计器根 URL http://localhost:<port>/——绝不能是生成的 .html 文件路径(例如 http://localhost:<port>/output/<projectDir>/<pageuuid>.html),也绝不能是特定页面的 URL。生成的页面没有可直接在浏览器中访问的 URL;只能通过 SSE 在设计器的 iframe 中查看。

CLI 命令参考

Server Management
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.

Authentication
gemdesign auth login --token <token>   # 配置 GemDesign 令牌
gemdesign auth whoami                  # Verify identity
应用管理
gemdesign app create --name "MyApp" --workdir <path> [--type web|app] [--width <px>] [--height <px>]    # Create new app (sync-creates local project folder under --workdir), --type defaults to web
gemdesign app list                     # List all apps
gemdesign app info [--appuuid <id>]    # App details
gemdesign app use --appuuid <id> --workdir <path>       # Switch current default app (creates/locates local project folder under --workdir)

app create 画布尺寸:--width/--height 用于指定画布像素尺寸。不传时按 --type 取默认值:web -> 1920×1080,app -> 440×956。传入的尺寸会随应用信息同步到本地设计器画布(覆盖默认值)。示例:gemdesign app create --name "PadApp" --type app --width 768 --height 1024。 严重:app create 和 app use 必须指定 --workdir:app create 和 app use 的 --workdir <path> 是必填参数,用于指定本地项目子目录 {projectName}__{appuuid} 的父目录。路径由 Agent 显式提供,CLI 不再通过配置自动猜测。--workdir 会自动追加到 htmlWorkdir 配置数组(去重),local-server 据此扫描所有项目目录。建议传入 ./output(即 gemdesign server workdir --path ./output 配置的同一目录)。page create 的 --file <path> 同理:lock 文件直接写入由 --file 推导出的项目子目录,确保 lock 与 html 位于同一目录。 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> --workdir ./output 复用该应用。在平台上创建第二个应用会导致第一个应用空置并成为孤立应用。 严重:会话锁错误处理:CLI 现在会自动通过 appuuid 验证会话锁。如果 app create 返回 stage: "appCreateSession"(存在会话锁,且远程服务上仍有该应用),请勿使用 --force 重试。应按以下步骤处理:(1) 运行 gemdesign app use --appuuid <existingApp.appuuid> --workdir ./output 复用该应用。(2) 如果现有应用来自另一项已完成的任务,运行 gemdesign app end-session,然后运行 app create(不带 --force)。(3) 仅当通过 app list 确认会话锁对应的应用已从远程服务删除时,才使用 --force。请注意,CLI 现在会自动清理过期的会话锁(应用已从远程服务删除),因此通常很少需要使用 --force。(4) 如果 app create 返回 stage: "appCreateSessionVerify"(因网络错误无法验证应用是否存在),请等待后重试,不要使用 --force。 严重:每次 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 stop 命令返回结果后才能执行 server start,禁止并行执行或先 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 类型的应用生成移动端宽度页面。

样式搜索(可选辅助工具)
gemdesign style search --keywords "科技,深蓝,企业" --limit 5   # Search styles
gemdesign style get --id <styleId> --format html                 # Get full style

样式搜索是可选的。你也可以自行设计样式,或使用其他 UI 设计技能。

页面 - 查看
gemdesign page list [--appuuid <id>]                                        # List pages
gemdesign page get --pageuuid <id> --file ./output/<projectDir>/<subfolder>/<id>.html  # Get page HTML (auto-creates projectDir)
gemdesign page doc get --pageuuid <id> --file ./output/<projectDir>/<subfolder>/<id>.md  # Get requirement doc

关键 - 同步远程页面时必须保留文件夹结构:page list 返回的每个页面都包含 dirName 字段(远程所在文件夹,多级文件夹用 / 分隔,根级页面为 null/空)。将远程页面同步到本地时(尤其是在“同步后编辑”的场景中),page get --file 的 <subfolder> 必须与该页面的 dirName 一致,也就是说,文件必须保存到 ./output/<projectDir>/<dirName>/<pageuuid>.html。严禁将所有页面统一放在项目根目录中——否则后续编辑并保存时,本地推导出的目录将与远程目录不一致,可能导致页面脱离远程文件夹。例如:page list 返回的页面 report-sales 的 dirName 为 reports,则必须执行 gemdesign page get --pageuuid report-sales --file ./output/<projectDir>/reports/report-sales.html。

页面 - 创建(流式模式)
gemdesign page create --pageuuid <readable-id> --name "<pageName>" --file ./output/<projectDir>/<subfolder>/<readable-id>.html   # Create page + enter streaming mode (.stream.lock written next to --file)

page create 会通知本地服务器为此页面启动流式模式,以便在你写入 .html 文件时实时预览 HTML。此命令必须在写入 HTML 文件之前调用;page save 完成后会自动结束流式模式。

【关键 - HTML 文件名必须等于 pageuuid】 --file 中的文件名部分必须与 --pageuuid 完全一致。例如,--pageuuid customers-list 必须搭配 --file .../customers-list.html。local-server 的 fileWatcher、streamPoller 和 pageCache 全部基于“文件名 = pageUuid”的假设运行。不一致会导致:lock 文件与 HTML 文件脱离关联、前端流式状态异常,以及 .meta.json 与远程 pageuuid 不匹配。page create 响应会在检测到不一致时发出 WARNING,务必按建议修正路径。

页面 - 保存(含验证)
gemdesign page save --pageuuid <id> --file ./output/<projectDir>/<subfolder>/<id>.html                                         # Update existing
gemdesign page save --new --pageuuid <readable-id> --name "Login" --file ./output/<projectDir>/<subfolder>/<readable-id>.html  # Create new
gemdesign page doc save --pageuuid <id> --file ./output/<projectDir>/<subfolder>/doc.md                                                           # Save requirement doc

page save 会在上传前,根据 GemDesign Page Spec 自动验证 HTML。保存成功后,它会自动结束流式模式,触发浏览器获取最终渲染结果。 page doc save 会将 Agent 生成的需求文档保存到平台。 --new 的 --pageuuid:使用易读的 ID(例如不含 .html 的文件名)。确保它在应用中唯一。此 ID 会直接用作导航元素中的 data-uuid,保存后无需更改。 项目子目录:路径中始终使用 ./output/<projectDir>/。CLI 具有幂等性——如果路径中已包含 <projectDir>,就不会重复添加。详情请参阅“本地文件管理”。 文件夹组织:直接在 --file 中包含文件夹路径(例如 --file ./output/<projectDir>/crm/客户管理/page.html)。CLI 会自动根据文件路径推导远程 dirName。

仅验证
gemdesign validate --file ./output/<projectDir>/<subfolder>/page.html    # Validate without saving
本地文件管理

对于每个页面,都要将 HTML 文件保存在本地 ./output/ 下,并按项目子目录组织:

文件用途生成方式
./output/<projectDir>/<subfolder>/<pageuuid>.html页面 HTML(包含 DSL,用于编辑和保存)仅当 page create 创建 .stream.lock 后,才由 Agent 写入(严禁不创建 lock 就直接创建文件;<subfolder> 可以包含多级文件夹路径)
./output/<projectDir>/<subfolder>/<pageuuid>.meta.json页面位置元数据(存储画布布局所用的 { position: { x, y } })仅由 CLI 管理——由 page get 自动生成;page save 会读取其中的位置。Agent 绝不能手动创建或修改此文件。该文件与 HTML 文件位于同一目录。

.meta.json 与 HTML 文件位于同一目录:无论文件夹有多深,.meta.json 文件始终与对应的 .html 文件生成在同一目录中。例如:

  • --file ./output/<projectDir>/page.html → meta.json 位于 ./output/<projectDir>/page.meta.json
  • --file ./output/<projectDir>/crm/page.html → meta.json 位于 ./output/<projectDir>/crm/page.meta.json
  • --file ./output/<projectDir>/crm/客户管理/page.html → meta.json 位于 ./output/<projectDir>/crm/客户管理/page.meta.json

绝不能手动创建或修改 .meta.json 文件——该文件仅由 CLI 管理(page get 生成,page save 读取)。调用 page save 时,它会从与 HTML 文件位于同一目录的 .meta.json 中读取位置(如果不存在 meta.json,则回退到 --x/--y 标志)。 目录一致性检查(自动):在 page get 或 page save 写入任何文件之前,CLI 会自动扫描项目目录,检查是否已在与 --file 指向目录不同的目录中存在同名 .html 文件。如果检测到不匹配(例如,HTML 文件位于 customers/,但 --file 指向根目录),CLI 会返回包含 suggestedFilePath 的错误——你必须使用建议的路径重新执行命令。此检查会在写入任何文件之前运行,以防止产生脏数据。如果收到此错误,切勿忽略——请使用错误响应中的确切 suggestedFilePath 重新运行命令。

项目子目录命名:<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>/<subfolder>/<pageuuid>.html,无论是直接写入文件还是传给 CLI 命令。如果需要,请在 <subfolder> 中包含文件夹路径(例如,./output/<projectDir>/crm/客户管理/page.html)。HTML 文件名必须等于 pageuuid(如 --pageuuid customers-list → 文件名必须是 customers-list.html,不能用 list.html)。
  • 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__)——这会创建无名的孤立目录。

本地服务会自动从项目子目录路径提供页面。

页面文件夹组织

页面可以在项目目录中按子文件夹组织。只需在 --file 中包含文件夹路径:

  • 根目录页面:--file ./output/<projectDir>/page.html → 放置在项目根目录
  • 子文件夹页面:--file ./output/<projectDir>/crm/page.html → 放置在 crm 子文件夹中
  • 多级文件夹:--file ./output/<projectDir>/crm/客户管理/page.html → 放置在嵌套目录结构中
# Single-level folder
gemdesign page create --pageuuid customer-list --name "客户列表" --file ./output/<projectDir>/crm/customer-list.html
gemdesign page save --new --pageuuid customer-list --name "客户列表" --file ./output/<projectDir>/crm/customer-list.html

# Multi-level folder
gemdesign page create --pageuuid customer-detail --name "客户详情" --file ./output/<projectDir>/crm/客户管理/customer-detail.html
gemdesign page save --new --pageuuid customer-detail --name "客户详情" --file ./output/<projectDir>/crm/客户管理/customer-detail.html

何时使用文件夹:当用户要求将页面按模块/类别组织时,请使用文件夹。例如,如果用户说“将客户页面放在 crm/客户 下”,请使用 --file ./output/<projectDir>/crm/客户/page.html。 文件夹名称:非法文件系统字符(\/:*?"<>|)会自动清理。文件夹名称应具有描述性且易于阅读。 本地服务:本地服务会自动递归扫描所有子文件夹,并在设计器中以树形结构显示。 远程同步:调用 page save 时,CLI 会自动从 --file 推导文件夹路径,并将其作为 dirName 发送到远程服务。你无需指定任何额外参数——CLI 会自动处理。

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

生成 HTML 页面时,请使用流式写入工作流,以便在浏览器中实时显示。GemDesign 本地服务器会监视文件变更,并通过 Server-Sent Events(SSE)将增量内容推送到浏览器。

**重要——流式写入期间(或步骤 3 之后的任何时候)都不要再次打开浏览器。**设计器 SPA(已在步骤 3 中于浏览器打开)会监视 .html 文件变更,并通过 SSE 自动将生成的 HTML 加载到其内部 iframe 中。你不需要“打开”或“刷新”任何内容——只需写入文件,设计器就会实时更新。将浏览器导航到生成的 .html URL(例如,通过预览工具或使用特定页面 URL 的操作系统浏览器命令)会用生成的 HTML 覆盖设计器,并破坏预览界面。打开浏览器时,唯一有效的 URL 是设计器根地址 http://localhost:<port>/,但步骤 3 之后也不得再次使用该地址。

严格要求——生成本地文件后必须调用 page save 命令:写入 HTML 文件后,必须调用 gemdesign page save 命令,将页面保存到远程服务器。严禁只写入本地文件而跳过 page save——这会导致页面仅存在于本地,不会出现在平台上,用户无法查看或使用该页面。完整流程为:page create → 写入 HTML → page save。page save 内置规范验证;验证失败时会返回错误,修复后重新执行 page save 即可。只写入本地文件而不调用 page save 属于严重违规。

注意:page create 的 JSON 响应中包含 warning 和 requiredNextSteps 字段,其中明确列出了后续必须执行的步骤。收到该响应后,必须按照 requiredNextSteps 中的步骤依次执行,不得在写入 HTML 后停止。

严格要求——严禁直接创建 .html 和 .meta.json 文件:智能体不得使用文件工具(Write/Edit 等)直接创建 .html 或 .meta.json 文件——这两类文件必须通过 CLI 命令创建:

  • 新建页面:必须先执行 gemdesign page create(该命令会在 --file 所在目录创建 .stream.lock 并进入流式模式),之后才允许写入 HTML。没有 lock 就写入 HTML 文件属于严重违规——local-server 无法进入流式模式,实时预览会失效,兜底保存也无法识别该页面尚未保存。
  • 修改已有页面:必须先执行 gemdesign page get 拉取 HTML(由 CLI 生成 .html 和 .meta.json),之后才允许修改。
  • .meta.json 是 CLI 专属文件:由 page get 自动生成,由 page save 读取,任何情况下都严禁智能体手动创建或修改 .meta.json 文件。

自检标准:写入任何 .html 文件之前,必须先存在该页面的 .stream.lock(新建页面时由 page create 创建),或先有 page get 的输出(修改已有页面时)。违反此顺序(先写文件、后补命令,或完全跳过命令)均属严重违规。

工作原理

CLI 会自动为你管理流式传输的整个生命周期。gemdesign page create 命令会启动流式模式,gemdesign page save 会自动结束该模式。追加内容到 .html 文件时,浏览器会收到增量 HTML:

  1. gemdesign page create → 浏览器进入该页面的流式模式
  2. 追加内容到 .html → 浏览器收到增量 HTML,并实时重新渲染
  3. gemdesign page save → 浏览器获取完整 HTML,并切换到最终渲染
步骤

生成每个页面时,都要遵循此工作流。该工作流包含3 个必需步骤——page create、写入 HTML 和 page save。每个页面都必须完成全部 3 个步骤。写入 HTML 后就停止属于严重违规——页面不会出现在平台上。

  1. 计算路径:

    • htmlPath = ./output/<projectDir>/<subfolder>/<pageuuid>.html(将文件夹路径包含在 <subfolder> 中;根级页面可省略 <subfolder>)
  2. 创建页面(进入流式模式):

    gemdesign page create --pageuuid <pageuuid> --name "<pageName>" --file ./output/<projectDir>/<subfolder>/<pageuuid>.html
    

    这会通知本地服务器为该页面启动流式模式。.stream.lock 会与 --file 位于同一目录,因此 lock 和 HTML 文件处于同一目录。浏览器将进入流式模式,并准备接收增量 HTML。

    **响应中包含 requiredNextSteps——必须遵循其中的步骤。**调用 page create 后,必须写入 HTML 文件,然后调用 page save。写入 HTML 后不要停止。

  3. 编写 HTML 文件(首次写入后仅追加,绝不覆盖为更短的内容):

    • 前提条件:步骤 2 的 page create 必须已成功(--file 旁边存在 .stream.lock)。没有锁时,绝不能创建或写入 HTML 文件——参见上文“严禁直接创建 .html 和 .meta.json 文件”硬性门槛。
    • 可以一次性写入 HTML,也可以分多次追加——本地服务会检测文件更改,并实时将每次追加内容推送到浏览器。
    • HTML 必须是完整文档:<!DOCTYPE html> + <head>(包含所有依赖项和样式)+ <body>...</body> + </html>。
    • 如果分多次追加,首次写入必须包含 <body> 标签,这样浏览器才能立即开始渲染(浏览器只有在出现 <body> 后才会渲染)。

    关键规则:

    • 首次写入后,始终对文件执行追加。流式传输期间,绝不能覆盖为更短的内容——这会触发 pageReset 事件,迫使浏览器从头开始重新渲染。
    • 如果必须从头重写,请先删除 .html 文件,然后重新开始。
    • 首次写入会创建文件(长度从 0 变为 N),后续写入会追加内容(长度从 N 变为 N+M)。
    • 没有延迟或分块大小限制:你可以按任意速度、以任意大小写入。本地服务会在约 10ms 内将每次文件更改推送到浏览器。
    • 失败时清理:如果流式写入失败或中断,请删除该页面的任何不完整 .html 文件。你也可以运行 gemdesign server cleanup 清理孤立文件和空项目目录。
  4. (可选)验证 HTML——仅在你想于保存前尽早发现错误时执行:

    gemdesign validate --file ./output/<projectDir>/<subfolder>/<pageuuid>.html
    

    如果验证失败,请修复 HTML 并重新验证。注意:page save 也会在内部进行验证——如果保存时验证失败,请修复 HTML 并重新运行 page save。

  5. 保存到平台(必须——写入 HTML 后必须调用):

    gemdesign page save --new --pageuuid <pageuuid> --name "<pageName>" --file ./output/<projectDir>/<subfolder>/<pageuuid>.html
    

    page save 会在保存前自动验证 HTML——如果验证失败,它会返回错误;请修复 HTML 并重新运行 page save。保存完成后,CLI 会自动结束流式模式。浏览器会获取完整 HTML,并切换到最终渲染结果。

    此步骤不可协商。 在本地写入 HTML 却不调用 page save,意味着页面仅存在于你的本地计算机上,不会显示在平台上。用户将看不到该页面。这是最常见且最严重的错误——绝不能犯。

    关键——页面 HTML 写入完成后立即调用;绝不能延迟或批量执行:某个页面的 HTML 一旦全部写入完成,就必须立即调用该页面的 page save——不得等到生成其他页面后再保存。page save 是唯一会删除 .stream.lock、结束流式模式并将页面同步到远程服务的操作。延迟保存会导致锁持续存在:页面卡在流式状态,无法同步到平台,浏览器画布也不会触发最终渲染。生成多个页面时,请参见下方“批量生成:逐页立即保存”硬性门槛。

硬性门槛——批量生成时每页写完必须立即保存(允许并行,严禁攒批):生成多个页面时,可以并行推进多个页面的生成,但每个页面的 HTML 一写完,就必须立即执行该页对应的后续命令(page save,或先 validate 再 page save),确认保存成功返回后,该页才算完成。正确示例:create(p1) → 写入 p1 → 立即 save(p1);create(p2) → 写入 p2 → 立即 save(p2)——各页面之间互不等待。

严禁把所有页面的 page save 留到最后统一执行(即等所有页面 HTML 都写完后再批量执行 save(p1)…save(pN),这是严重违规行为)。攒批保存的后果:每个页面的 .stream.lock 都迟迟不会被删除,页面一直处于流式状态、无法同步到远程服务器,浏览器画布也无法切换到最终渲染,用户看到的将是“所有页面都在加载中”,直到整批操作结束。

自检标准:任何一个页面的 HTML 写完后,该页的下一条执行命令必须是其对应的 page save(或先 validate 再 save)——不得先去写入其他页面的 HTML,更不得等所有页面都写完后再统一处理。并行场景下可以同时存在多个已执行 create 的页面,但不允许存在任何“HTML 已写完却迟迟未 save”的页面。

示例(“home”页面的流式写入)
# Step 1: Create the page (enter streaming mode)
gemdesign page create --pageuuid home --name "首页" --file ./output/MyApp__abc-123/home.html
# → Response includes requiredNextSteps — you MUST follow them

# Step 2: Write the HTML file (one shot or multiple appends)
#    Use Write tool to create ./output/MyApp__abc-123/home.html with the complete HTML

# Step 3 (OPTIONAL): Validate early to catch errors before saving
gemdesign validate --file ./output/MyApp__abc-123/home.html
# If validation fails, fix and re-validate

# Step 4 (MANDATORY): Save to platform — MUST call, otherwise page won't appear
gemdesign page save --new --pageuuid home --name "首页" --file ./output/MyApp__abc-123/home.html
# → page save also validates internally; if validation fails, fix HTML and re-run this command

工作流

所有工作流的前置条件:开始任何工作流之前,必须确认第 1 步(已安装 CLI 且为最新版本)、第 2 步(通过 gemdesign auth whoami 验证登录)和第 2.5 步(已配置 htmlWorkdir 并完成清理)均已完成。如果尚未确认登录,切勿生成 HTML、创建 ./output/ 文件或开始流式写入——请先停止并解决身份验证问题。开始工作流前不执行第 3 步(本地服务正在运行且已打开浏览器预览);该步骤应在各工作流中、创建或复用应用后(且 app info 确认 <projectDir>)、生成任何页面前执行。这同样适用于工作流 A、B 和 C。

工作流 A:根据需求批量生成
  1. 完成前置条件:继续之前,请确认步骤 1(安装/更新 CLI)、步骤 2(登录)以及步骤 2.5(配置 htmlWorkdir 并清理)均已完成。此处不执行步骤 3(启动本地服务并打开浏览器预览)——该步骤会在下方步骤 5 中、创建/复用应用之后执行。
  2. 确保应用存在(优先复用!):
    • 确保已配置 htmlWorkdir:htmlWorkdir 已在步骤 2.5 中配置(跨会话保留)。app create --workdir 和 app use --workdir 会自动将路径追加到 htmlWorkdir 配置中(并去重)。运行 gemdesign server workdir(不带标志)进行验证;如果返回的 htmlWorkdir 为空,仍可直接向 app create/app use 传入 --workdir ./output。
    • 运行 gemdesign app list 检查现有应用
    • 如果已有应用:运行 gemdesign app use --appuuid <id> --workdir ./output,将目标应用设为默认应用。除非用户明确要求新建应用,否则不要创建新应用。
    • 如果没有应用:运行 gemdesign app create --name "<AppName>" --workdir ./output [--type web|app] [--width <px>] [--height <px>] 创建一个(默认类型为 web;默认画布尺寸:web → 1920×1080,app → 440×956)。app create 会同步创建 --workdir 下的本地项目文件夹(并自动追加到 htmlWorkdir 配置中)。创建后,立即运行 gemdesign app info 确认应用存在,并记录其 appuuid。本会话中无论出于何种原因,都不要再次运行 app create。 之前运行中的服务会在步骤 5 的 server stop 中统一终止。
    • 重要——禁止创建重复应用:如果你已在本会话中运行过 app create(即使是在之前的工作流尝试中),不要再次运行。请通过 app list + app use 复用现有应用。创建第二个应用会导致第一个应用为空并成为孤立应用。
    • 重要——会话锁错误处理:如果 app create 返回 stage: "appCreateSession"(存在会话锁,且远程已有应用),不要使用 --force 重试。应按以下步骤处理:(1) 运行 app use --appuuid <existingApp.appuuid> --workdir ./output 进行复用。(2) 如果该锁来自另一项已完成的任务,运行 gemdesign app end-session,然后运行 app create(不带 --force)。(3) 如果返回 stage: "appCreateSessionVerify"(网络错误),等待后重试。CLI 会自动清理过期锁(远程已删除的应用),因此很少需要使用 --force。
    • 重要:同一批次中的所有页面都必须放入同一个应用。复用现有应用可以避免页面分散到不同的项目文件夹中。
  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 stop 执行完成后再运行 server start:禁止并行执行 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 "设计系统" --file ./output/<projectDir>/design-system.html
    • 将 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 一写完,就必须立即执行该页的 page save(最多先 validate 再 save),以此删除 .stream.lock、结束流式状态并同步远程服务器;确认保存成功后,该页才算完成。严禁等所有页面的 HTML 都写完后再统一批量 page save(攒批会导致 lock 滞留、页面一直处于流式状态且不同步远程)。详见“流式写入工作流”章节中的“批量生成:逐页立即保存”硬性门槛。
    • 按照下方的页面规范生成 HTML(如有可用样式,需将其融入页面)。在导航元素中使用分配给页面的 pageuuid 作为 data-uuid。所有业务页面都必须遵循设计系统页面中建立(且在适用时已确认)的样式基准。
    • 使用流式写入(每个页面都必须依次完成 3 个步骤:创建 → 写入 HTML → 保存):
      • gemdesign page create --pageuuid <pageuuid> --name "页面名" --file ./output/<projectDir>/<subfolder>/<pageuuid>.html
      • 将 HTML 文件写入 --file 指定的路径(如有需要,将文件夹包含在路径中;如果目录不存在,则创建目录)
      • **(可选)**运行 gemdesign validate --file ...,及早发现错误
      • gemdesign page save --new --pageuuid <pageuuid> --name "页面名" --file ./output/<projectDir>/<subfolder>/<pageuuid>.html——必须执行;否则页面不会显示在平台上;当前页面的 HTML 写入后必须立即调用此命令,且必须在处理下一个页面之前完成
    • 重要:page save 是最重要的步骤。只在本地写入 HTML 而不调用 page save,意味着页面不会显示在平台上。page save 会在内部进行验证——如果验证失败,修复后重新运行。
  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 链接。

工作流 B:对话式生成

当用户在对话中请求生成页面时:

  1. 完成前置条件:继续之前,确认步骤 1(安装/更新 CLI)、步骤 2(登录)和步骤 2.5(已配置 htmlWorkdir 并完成清理)均已完成。此处不执行步骤 3(本地服务 + 浏览器预览)——该步骤将在下文步骤 5 中、创建/复用应用后执行。
  2. 确保应用存在(优先复用!):
    • 确保已配置 htmlWorkdir:htmlWorkdir 已在步骤 2.5 中配置(跨会话保留)。app create --workdir 和 app use --workdir 会自动将路径追加到 htmlWorkdir 配置中(去重)。运行 gemdesign server workdir(不带参数)进行验证;如果返回的 htmlWorkdir 为空,仍可直接向 app create/app use 传入 --workdir ./output。
    • 运行 gemdesign app list 检查现有应用
    • 如果已有应用:运行 gemdesign app use --appuuid <id> --workdir ./output,将目标应用设为默认应用。除非用户明确要求新建应用,否则不要创建新应用。
    • 如果没有应用:运行 gemdesign app create --name "<AppName>" --workdir ./output [--type web|app] [--width <px>] [--height <px>] 创建应用(默认类型为 web;默认画布尺寸:web → 1920×1080,app → 440×956)。app create 会在 --workdir 下同步创建本地项目文件夹(并自动追加到 htmlWorkdir 配置)。创建后,立即运行 gemdesign app info,确认应用已存在并记录其 appuuid。本会话中无论出于何种原因,都不要再次运行 app create。 之前运行中的服务会在步骤 5 的 server stop 中统一终止。
    • 关键——禁止创建重复应用:如果你已在本会话中运行过 app create(即使是在之前的工作流尝试中),也不要再次运行。通过 app list + app use 复用现有应用。创建第二个应用会导致第一个应用内容为空且成为孤立应用。
    • 关键——会话锁错误处理:如果 app create 返回 stage: "appCreateSession"(存在会话锁且远程应用已存在),不要使用 --force 重试。应当:(1) 运行 app use --appuuid <existingApp.appuuid> --workdir ./output 进行复用。(2) 如果该锁来自另一项已完成的任务,运行 gemdesign app end-session,然后运行 app create(不带 --force)。(3) 如果返回 stage: "appCreateSessionVerify"(网络错误),请等待后重试。CLI 会自动清理失效锁(远程应用已删除),因此很少需要使用 --force。
    • 关键:所有页面都必须放在同一个应用中。复用现有应用可避免页面分散到不同的项目文件夹。
  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 命令,并以命令返回结果为准。禁止以“服务器已在运行”“上一次工作流已启动”“浏览器预览已打开”等理由跳过 stop。stop 返回 {"success":false,"error":"未发现运行中的本地服务"} 时,表示没有服务可停止,此时可以继续下一步 start。
    • 关键——必须等 server stop 执行完成后再运行 server start:禁止并行执行 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 "设计系统" --file ./output/<projectDir>/design-system.html
    • 将 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. 使用流式写入(必需的 3 个步骤:创建 → 写入 HTML → 保存):
    • gemdesign page create --pageuuid <pageuuid> --name "<pageName>" --file ./output/<projectDir>/<subfolder>/<pageuuid>.html
    • 将 HTML 文件写入 --file 路径(如有需要,在路径中包含文件夹;如果目录不存在,则创建该目录)
    • **(可选)**运行 gemdesign validate --file ...,以便及早发现错误
    • gemdesign page save --new --pageuuid <pageuuid> --name "<pageName>" --file ./output/<projectDir>/<subfolder>/<pageuuid>.html——必须执行,否则页面不会显示在平台上
    • 关键:如果只在本地写入 HTML 而不调用 page save,页面将不会显示在平台上。
  11. 向用户描述结果
  12. 输出设计器链接(必须——所有页面工作完成后仅输出一次):页面生成、验证并保存后,必须在回复中输出可点击链接,以便用户轻松打开设计器。链接必须符合以下要求:
    • 名称:gemdesign 设计器(必须完全一致,不得更改或翻译)
    • URL:http://localhost:<port>(使用步骤 3 的 server start 返回结果中记录的端口)
    • 格式(Markdown 链接):[gemdesign 设计器](http://localhost:<port>)
    • 示例:[gemdesign 设计器](http://localhost:4056)

    **关键——必须在工作流结束时、最末尾精确输出一次此链接。**不要在每个中间步骤后输出链接。这是供用户自行决定是否点击的文本链接,并非自动打开浏览器的操作。完整说明见工作流 A 步骤 12,了解为何这不会与步骤 3 中的“不要在聊天中输出 URL”规则冲突。 当用户请求修改时:

  13. 使用 gemdesign page get --pageuuid <id> --file ./output/<projectDir>/<subfolder>/<id>.html 获取 HTML+DSL,以便编辑
  14. 修改 HTML(调整 DOM、添加/删除交互 DSL、更新 jsHandle)
    • 对于大幅修改,请使用流式写入工作流:重写 HTML(从头开始时先删除旧文件;仅添加内容时则追加)
  15. **(可选)**使用 gemdesign validate --file ./output/<projectDir>/<subfolder>/<id>.html 进行验证 — 如有错误,请修复
  16. 使用 gemdesign page save --pageuuid <id> --file ./output/<projectDir>/<subfolder>/<id>.html 保存 — 必须执行
  17. 如果需要更新需求文档:使用 gemdesign page doc save --pageuuid <id> --file ./output/<projectDir>/<subfolder>/updated-doc.md
工作流 C:修改现有页面
  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 stop 执行完成后再执行 server start:禁止并行执行 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>/<subfolder>/<id>.html → 获取 HTML+DSL 以供编辑
  7. 分析 HTML 结构和交互
  8. 根据需要修改 HTML
    • 对于大幅修改,请使用流式写入工作流(参见上文):重写 HTML
  9. (可选)验证:gemdesign validate --file ./output/<projectDir>/<subfolder>/<id>.html——如有错误,请修复
  10. 保存到平台(必须):gemdesign page save --pageuuid <id> --file ./output/<projectDir>/<subfolder>/<id>.html
    • 关键:仅修改本地文件而不调用 page save,更改将不会同步到平台。page save 会在内部进行验证。
  11. 如果需要更新需求文档:gemdesign page doc save --pageuuid <id> --file ./output/<projectDir>/<subfolder>/updated-doc.md
  12. 输出设计器链接(必须——仅在所有页面工作完成后输出一次):页面修改、验证并保存后,必须在回复中输出一个可点击链接,方便用户打开设计器查看更新后的结果。链接必须满足以下要求:
    • 名称:gemdesign 设计器(文本必须完全一致,请勿更改或翻译)
    • URL:http://localhost:<port>(使用步骤 3 中 server start 返回的端口)
    • 格式(Markdown 链接):[gemdesign 设计器](http://localhost:<port>)
    • 示例:[gemdesign 设计器](http://localhost:4056)

    关键——仅在工作流最末尾输出此链接一次。 请勿在每个中间步骤后输出。这是供用户自行点击的文本链接,不是自动打开浏览器的操作。关于此操作为何不与步骤 3 的“不要在聊天中输出 URL”规则冲突,请参见工作流 A 的步骤 12,其中有完整说明。


设计系统页面规范

新建应用时,应先生成一个设计系统页面(将 pageuuid 固定为 design-system),再生成业务页面,作为应用的视觉风格基线。后续所有业务页面都应遵循此设计系统确立的颜色、圆角、阴影和组件样式。设计系统页面也遵循 GemDesign 页面规范(见下文),包括技术栈规则、CSS 规则、Lite-Interaction DSL 等。

类型判定

根据 app info 返回的 pageScene 字段确定设计系统类型:

pageScene设计系统类型核心目标
app移动端 C 端体验驱动型创建面向消费者、以体验和情感驱动的移动端应用 UI 设计系统展示页。展示 C 端应用的常见交互模式和视觉组件,突出内容消费、社交互动和个性化体验。页面直接采用移动端宽度布局(不使用手机外框),原样呈现移动应用界面。
web企业管理功能驱动型创建以功能为驱动、面向企业和管理场景的 Web UI 设计系统展示页。展示管理系统的常见框架结构、数据操作和表单输入组件,突出信息密度、操作效率和状态反馈。页面采用全宽管理后台布局,模拟真实的管理系统界面。
Other灵活分析根据需求分析最合适的设计系统类型,并灵活采用“Header + 设计令牌 + 组件”的基础结构进行设计。
页面结构 — app 类型(移动端 C 端)

页眉

  • 包含系统 Logo/图标、系统名称(中文)和简短描述
  • 使用深色或品牌色背景,搭配白色文字
  • 固定在顶部或作为页面顶部横幅

第 1 部分:设计令牌

  • 部分标题样式:使用左侧彩色边框条(border-l-4,采用样式的主色)+ 大号标题 + 标签徽章组合
  • 颜色系统:使用色板卡片展示主色、辅助色、功能色和中性色,并标注 Hex 值和用途说明
  • 圆角和阴影:使用立体化区块展示不同级别的阴影效果和较大圆角规格(如 16px/24px)、柔和阴影或漫射光晕

第 2 部分:组件

  • 媒体卡片:图文卡片(大图模式)、瀑布流卡片、视频/直播封面容器
  • 社交元素:用户头像、点赞/收藏/评论图标(带微交互样式)、关注按钮
  • 交互容器:底部抽屉面板(Bottom Sheet/Drawer)、Toast 通知(仅在容器内作为样式效果展示;请勿模拟固定在页面布局中的真实弹窗效果)
  • 导航:沉浸式顶部栏(透明渐变)、底部导航栏(图标 + 文字,带选中状态动画提示)
  • 空状态/加载:加载占位符(Skeleton)、空状态插画占位符
页面结构 — web 类型(企业管理后台)

页眉

  • 包含系统 Logo/图标、系统名称(中文)和简短描述
  • 使用深色或品牌色背景,并搭配白色文字
  • 固定在顶部,或作为页面顶部横幅

第 1 节:设计令牌

  • 章节标题样式:使用左侧彩色边框条(border-l-4,采用样式的主色)+ 大号标题 + 标签徽章组合
  • 颜色系统:使用色板卡片展示主色、次色、功能色和中性色,并标注 Hex 值和使用说明
  • 字体排版层级:在卡片中展示 H1-H4、正文和说明文字的级别对比,并标注字体、字号和字重
  • 边框圆角和阴影:使用实体化区块展示不同级别的阴影效果

第 2 节:组件

  • 使用网格布局(grid-cols-1 lg:grid-cols-2/3)组织组件展示
  • 结构/外壳:侧边栏导航项(选中/悬停)、顶部面包屑、页面标题
  • 数据展示:数据表格(表头、斑马纹、行悬停、分页)、标签页、标签(Tag/Badge)、键值对列表
  • 表单元素:输入框(Input)、下拉选择框(Select)、复选框/单选按钮(Checkbox/Radio)、开关(Switch)——必须包含默认、悬停、聚焦和错误状态
  • 操作:操作按钮(Primary、Secondary、Ghost、Icon Button)
  • 反馈/叠加层:全局消息(Message)、通知(Notification)、对话框(Modal/Dialog,以示例形式展示——请勿使用全屏模态框)、加载状态(Skeleton/Spinner)
页面结构 — 其他类型

遵循页眉 + 设计令牌 + 组件的基本结构,并根据需求分析确定合适的组件和视觉样式。


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

生成设计系统页面时(仅限新建应用),在生成任何业务页面之前,必须执行此审核关卡。 此关卡不适用于复用应用(此类应用会跳过设计系统生成),也不适用于工作流 C(修改现有页面)。

此关卡存在的原因(第一性原理)

设计系统页面是一个高杠杆决策点。它确定了后续所有业务页面都会继承的颜色、字体排版、阴影、圆角和组件样式。生成后立即检查之所以是自然的检查点,基于两个特性:

  1. 错误成本不对称。 此处做出的错误样式决策会传播到之后生成的每个业务页面。已有 N 个页面后再进行修正,意味着需要返工 N 个页面;立即修正只需与用户沟通一轮。跳过此关卡的预期成本会随页面数量线性增长,而暂停的成本始终很低。

  2. 信息状态翻转。 生成前,Agent 只能根据需求文档推断用户的视觉偏好——此时状态不确定。生成后,用户可以在浏览器中看到具体的渲染方案——此时状态确定。这是用户首次掌握可用于确认或调整方向的信息。此时获取这一反馈最有价值:在整个工作流中,这是修正方向成本最低的节点。

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

设计系统页面生成、验证并保存后,评估下面的继续条件。默认操作是停止并询问;只有明确满足至少一项继续条件时,才可以不询问并直接继续生成业务页面。

继续条件(满足任意一项即可跳过暂停,直接继续生成业务页面):

#条件可以安全继续的原因
C1用户在最初的请求中明确指定了视觉风格(例如指定品牌色、“深蓝科技风”、“参考某App的样式”、情绪板或十六进制颜色代码)风格方向已由用户确定——不存在需要通过此检查点解决的信息缺口。
C2用户在本次会话中较早时运行了 style search + style get,并且设计系统页面忠实体现了所选风格用户通过明确的选择操作预先表达了偏好;设计系统是在执行该选择,而非提出新的风格方案。
C3用户明确表示无需审核(例如“不用确认,直接全部生成”、“全自动跑完”、“不要中途停”)用户主动放弃了此检查点。请尊重用户表达的偏好。

如果没有任何继续条件适用 → 必须停止。 对于仅根据需求文档新建的应用,这是默认且最常见的情况。

停止时——应展示的内容

不要只宣布“设计系统已生成”。请提供一份便于用户做出决定的摘要,让用户可以轻松确认或提出调整:

  1. 风格决策——主色和辅助色(附十六进制代码)、整体方向(例如科技感/温暖/极简)、关键组件的设计处理(卡片圆角、阴影样式、按钮样式)。内容要具体,不要含糊。
  2. 决策依据——说明这些决策与需求之间的关联(例如“基于需求文档中‘面向年轻人的社交平台’这一定位,主色选用高饱和度的紫色……”)。
  3. 明确询问——使用 AskUserQuestion 工具来组织选项。建议选项:
    • “确认,继续生成业务页面”
    • “调整配色方案”
    • “调整整体风格方向”
    • (用户也可以通过“其他”输入自定义回复)
用户回复后
  • 用户确认 → 继续生成业务页面,并将已确认的设计系统视为所有页面的固定风格基准。
  • 用户要求调整 → 先修改设计系统页面(编辑 → 验证 → 保存),然后根据情况重新展示(如果调整幅度较大或涉及主观判断,例如从“科技蓝”转为“温暖橙”),或直接继续(如果调整较小且已明确解决,例如只微调一个十六进制颜色值)。请酌情判断。此处的“保存”步骤是重新运行 gemdesign page save --pageuuid design-system --file ./output/<projectDir>/design-system.html(不要使用 --new 标志——该页面已在步骤 7/5 中保存到平台;使用 --new 会因 pageuuid 重复而报错)。使用 gemdesign page list 确认更新。
  • 除非设计系统已经(a)由用户确认,或(b)符合上述继续条件,否则不得开始生成业务页面。

GemDesign 页面规范

生成 HTML 时,必须遵循此规范。gemdesign validate 命令会检查所有这些规则。

概述

GemDesign 页面 = HTML(DOM)+ TailwindCSS(样式)+ Lite-Interaction DSL(交互)。

技术栈规则

允许:HTML 原生标签、TailwindCSS(通过 <script> 标签)、CSS(<style>)、Font Awesome、ECharts
禁止:任何 JS 框架(Vue/React/jQuery)、手写 DOM JS(jsHandle 除外)、CSS Hack、vh 单位

仅允许两种类型的脚本
  1. <script id="interaction-data"> — Lite-Interaction JSON 字符串(交互逻辑)
  2. <script id="funcName">function funcName(event){...}</script> — jsHandle 自定义函数
依赖项
<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 src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.min.js"></script>

<script src="https://cdn.jsdmirror.com/npm/echarts/map/js/china.js"></script>
布局规则
  1. 使用 TailwindCSS 的布局组件类。
  2. 优先使用 flexbox 布局;Flexbox、内边距和 gap 是界面布局的核心工具。
  3. 块级元素可用于简单元素(文本、装饰性图片),但不能用于布局。所有元素默认采用 border-box 盒模型。
  4. 固定元素(侧边栏、导航栏)必须设置明确的高度和宽度;内容区域需要设置对应的内边距。
  5. 遮罩和模态框/抽屉必须嵌套。遮罩/覆盖层必须使用半透明背景色(例如 bg-black/50),内部模态框/抽屉内容容器必须使用不透明背景色(例如 bg-white)——内容容器透明属于严重违规,因为遮罩颜色会透出来。
  6. 居中对齐元素时,绝对不要使用 mx-auto 或 m-auto——必须在父元素上使用 flex 布局的 justify-center 和 items-center。
CSS 规则
规则 1:禁止使用 vh 单位

禁止使用:vh 单位、包含 vh 的任何 Tailwind CSS 类,以及包含 vh 的任何类(例如 h-[80vh])。

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

整个页面绝对禁止使用任何 Margin!这包括原生 CSS,以及所有具有 margin 语义的 Tailwind 类名!模型很容易习惯性地使用 margin 来设置“图标间距”和“元素顶部/底部间距”——必须克服这种习惯!

如果输出代码包含以下任何前缀(正向或负向),即属于严重违规:

  • 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-(底层实现同样使用 margin,绝对禁止)

强制替代方案——针对最容易违规的场景:

  • ❌ 违规习惯 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(核心)

所有交互都以 JSON 数组形式声明在 <script id="interaction-data"> 中,并用反引号包裹。

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
}
选择器规则(重要)
规则详情
original 和 target只能使用 #id 或 .class——不能使用属性选择器([data-xxx])
original只能选择单个元素——不能使用多个选择器
target可使用多个 ID:"#id1,#id2"——不能使用 .class
如果元素只有 data 属性必须为其添加 id,然后在 DSL 中使用 #id
操作优先级
  1. show/hide——打开/关闭模态框时优先使用
  2. addClass/removeClass——更改 CSS
  3. openPage——页面导航(参数只能是 pageUuid 字符串)
  4. back——返回
  5. jsHandle——仅在上述操作无法满足需求时使用
jsHandle 规则
  1. 每个函数必须放在单独的 <script> 标签中
  2. 脚本的 id 必须与函数名完全一致
  3. 只能有一个参数:event
  4. 内部不能调用 API
<script id="tabSwitchXxx">
function tabSwitchXxx(event) {
  // full implementation
}
</script>
页面导航

对于导航元素,需在 HTML 标签上添加 id 和 data-uuid。data-uuid 的值必须与传递给 page save --new 的 --pageuuid 一致:


<a id="nav-home" data-uuid="home" href="javascript:void(0);">首页</a>

不要在 interaction-data 中为这些元素添加 openPage 事件——这些事件会自动生成。

图片占位符

使用占位符 URL,平台会将其替换为真实图片:

<img src="./api/searchImage?query=premium laptop on white background&width=400&height=400" class="w-full h-full object-cover" />
按钮规则
  • 所有按钮都必须设置 type="button"
  • 禁止使用 type="submit"
  • 链接使用 href="javascript:void(0);",绝不要使用 href="#"
设计约束
  • 阴影:使用柔和的阴影:shadow-[0_8px_30px_rgba(0,0,0,0.04)],不要使用短促、深色的阴影
  • 原生控件:切换选项时,不要使用 <select> 或单选按钮;请使用胶囊式分段控件
  • 水平滚动:使用 scrollbar-hide 隐藏滚动条
  • 模态框/遮罩层/抽屉:默认添加 hidden 类;使用嵌套结构。遮罩层必须具有半透明背景色(例如 bg-black/50),内部模态框/抽屉内容容器必须具有不透明背景色(例如 bg-white)。内容容器透明属于严重违规——遮罩颜色会透出来,导致弹出内容区域呈现为遮罩颜色。示例:
    <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">
        
      </div>
    </div>
    
  • CSS 覆盖:当状态类(如 hidden)覆盖组件类时,在样式表中组合使用:.modal-mask.hidden { display: none; }——不要使用 @apply hidden
脚本顺序
  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> 标签
完整页面模板
<!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">
    
  </div>

  
  

  
  <script id="interaction-data">
`
[
  {
    "original": "#elementId",
    "trigger": "click",
    "actions": [
      { "operation": "show", "target": "#targetId" }
    ]
  }
]
`
  </script>
</body>
</html>

验证规则摘要

gemdesign validate 命令会检查:

#规则检查内容
1interaction_data_exists是否存在 <script id="interaction-data">
2dsl_json_valid内容是否为有效的 JSON 数组
3selector_exists所有原始/目标选择器是否存在于 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 是否为最后一个 script 标签

提示

  • 硬性要求——严禁直接创建 .html / .meta.json 文件:新建页面必须先执行 page create(创建 .stream.lock),再写入 HTML。没有 lock 就直接创建 HTML 属于严重违规;修改已有页面必须先执行 page get。.meta.json 由 CLI 专属管理(page get 生成、page save 读取),严禁 Agent 创建或修改。
  • 硬性要求——不可跳过 page save:写入 HTML 文件后,必须调用 gemdesign page save 保存到平台。只生成本地文件而不调用 page save 属于严重违规——页面不会出现在平台上,用户无法查看或使用该页面。完整流程:page create → 写入 HTML → page save。page save 内置规范验证;验证失败时会返回错误,修复后重新执行 page save 即可。
  • 硬性要求——批量生成时逐页立即保存:生成多个页面时可以并行推进,但每个页面的 HTML 写完后,必须立即执行该页面对应的 page save(删除 .stream.lock、结束流式处理、同步到远程),确认成功后该页面才算完成;严禁等所有页面都生成完后再统一批量 save——否则 lock 会滞留,页面会一直处于流式状态且不会同步到远程服务。
  • page create 的响应包含 requiredNextSteps 字段,其中列出了后续必须执行的步骤。收到该响应后必须按步骤执行,不可在写入 HTML 后停止。
  • gemdesign validate 是用于提前检测错误的可选工具——page save 内部已包含验证,但 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

评论

支持 Markdown