关于 gemdesign-skill
gemdesign-skill 指导用户通过 gemdesign CLI 在 GemDesign 平台创建、保存和修改高保真原型页面,适用于 UI 原型设计与批量页面生成。它规定了 CLI、登录、工作目录和本地预览的操作顺序。
主要功能
- 01生成符合 Page Spec 的 HTML
- 02校验并保存原型页面
- 03创建或复用 GemDesign 应用
- 04配置 HTML 工作目录
- 05启动本地实时预览服务
- 06规定 CLI 与登录前置检查
适用场景
- 01根据需求文档批量生成页面
- 02修改现有 GemDesign 页面
- 03查看已保存的原型页面
- 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 等)。
-
检查 CLI 是否已安装:
npm list -g @gemdesign-ai/cli- 如果命令返回版本信息(例如
@gemdesign-ai/[email protected]),则 CLI 已安装——继续步骤 2。 - 如果命令返回空结果或错误(例如
(empty)或ERR!),则表示 CLI 尚未安装。运行:
等待安装完成,然后使用npm install -g @gemdesign-ai/clinpm list -g @gemdesign-ai/cli再次验证。在再次验证确认已安装相应版本之前,请勿继续。
- 如果命令返回版本信息(例如
-
检查 CLI 是否为最新版本(仅在步骤 1 确认 CLI 已安装后执行):
npm outdated -g @gemdesign-ai/cli- 如果命令返回空结果或显示
Current=Latest,则表示 CLI 已是最新版本——此步骤完成,继续步骤 2。 - 如果命令显示版本信息,且
Current和Latest的值不同,则表示 CLI 版本过旧。请更新到最新版本:
等待更新完成,然后使用npm update -g @gemdesign-ai/clinpm outdated -g @gemdesign-ai/cli再次验证。在再次验证确认 CLI 已是最新版本之前,请勿继续。
- 如果命令返回空结果或显示
确认此步骤完成后,即可全局使用最新版本的 gemdesign-ai 命令。只有此时才能进入步骤 2。
步骤 2:验证登录(必须在步骤 1 完成后、任何工作流开始前完成)
步骤 1 完成后,务必验证登录状态。运行此命令:
gemdesign auth whoami
- 如果成功(返回用户信息),则用户已登录——继续执行工作流(A/B/C)。步骤 3(本地服务)将在工作流内部、创建或复用应用后执行。
- 如果失败(返回类似“GemDesign令牌 无效”或“未提供 GemDesign令牌”的错误),则用户未通过身份验证。你必须:
- 告知用户:如果他们还没有账号或 GemDesign令牌,请前往 https://design.gemcoder.com 注册账号并获取 GemDesign令牌。GemDesign令牌的获取路径为:登录平台 -> 点击 个人中心 (Personal Center) -> 获取 GemDesign令牌 (GemDesign令牌)。
- 向用户索取 GemDesign令牌(使用
AskUserQuestion工具提示用户输入其 GemDesign令牌)。 - 用户提供 GemDesign令牌后,自动为其运行登录命令:
gemdesign auth login --token <user_provided_token> - 使用
gemdesign auth whoami重新验证,确认登录成功。 - 如果登录仍然失败,从步骤 2 重试(再次询问用户提供 GemDesign令牌)。
- 只有确认登录后,才能继续执行工作流。
严格门禁:在通过 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,无需清理"并正常退出。)
-
清理空项目目录(必须首先运行,在配置 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。
- 如果尚未配置
-
配置 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)。
-
确保已配置 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,再继续。 -
停止任何先前运行的服务(每次执行
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操作。
- 返回
-
使用 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>,供后续步骤使用。
- 并行执行
-
检查服务状态(可选,用于调试):
gemdesign server status返回:
{"success":true,"status":"running","port":<port>,"url":"http://localhost:<port>"}或{"success":true,"status":"stopped"} -
打开预览(必须执行 — 硬性门槛,不得跳过):确认服务正在运行后(
server start命令返回成功),必须打开浏览器并导航到名为 GemDesign设计器 的服务页面(URL:http://localhost:<port>;使用server start响应中的端口)。此步骤不可妥协。 在浏览器中打开
http://localhost:<port>之前,不要继续执行任何页面生成工作流(工作流 A/B/C)。服务器已启动并不等于预览已在浏览器中打开——用户必须能在浏览器中看到预览界面。不要只在聊天文本中输出 URL。 你必须使用工具实际打开浏览器。输出类似“服务器启动成功!请在浏览器中打开 http://localhost:4056”的内容属于违规行为——必须通过程序打开浏览器,而不是让用户点击链接。
如何打开浏览器——按以下优先级使用这些方法:
按优先级依次尝试以下方法。使用第一个可用且成功的方法。如果某个方法失败,请跳过它并尝试下一个:
优先级 方法 使用方式 1 平台内置的浏览器/预览工具 必须检查当前 Agent 平台上有哪些浏览器/预览工具可用,并使用最合适的工具。 不同平台提供的内置工具各不相同——使用平台提供的任意工具。例如,特定平台的工具包括:Trae 提供 OpenPreview和integrated_browserMCP 中的browser_navigate;Cursor 提供自己的预览机制;其他平台可能提供同类工具。关键要求是:必须使用工具以程序方式打开浏览器,而不能只在聊天中输出 URL。 使用该工具导航到http://localhost:<port>/。2 操作系统默认浏览器命令 如果没有可用的内置浏览器/预览工具(或工具失败),请通过操作系统命令打开默认浏览器:Windows start http://localhost:<port>/、macOSopen http://localhost:<port>/、Linuxxdg-open http://localhost:<port>/。3 告知用户打开 URL 如果以上所有方法均失败或不可用,作为最后的手段,明确告知用户:“请在浏览器中打开 http://localhost:/ 查看设计器预览”,并等待用户确认后再继续。 如何查找平台内置工具: 检查可用工具列表——查找名称类似
OpenPreview、browser_navigate、preview、browser的工具。任何能在浏览器面板中打开 URL 的工具都符合要求。使用工具打开 URLhttp://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, usestaskkillto 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 (runningorstopped), 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 中。你不需要“打开”或“刷新”任何内容——只需写入文件,设计器就会实时更新。将浏览器导航到生成的.htmlURL(例如,通过预览工具或使用特定页面 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:
gemdesign page create→ 浏览器进入该页面的流式模式- 追加内容到
.html→ 浏览器收到增量 HTML,并实时重新渲染 gemdesign page save→ 浏览器获取完整 HTML,并切换到最终渲染
步骤
生成每个页面时,都要遵循此工作流。该工作流包含3 个必需步骤——page create、写入 HTML 和 page save。每个页面都必须完成全部 3 个步骤。写入 HTML 后就停止属于严重违规——页面不会出现在平台上。
-
计算路径:
htmlPath = ./output/<projectDir>/<subfolder>/<pageuuid>.html(将文件夹路径包含在<subfolder>中;根级页面可省略<subfolder>)
-
创建页面(进入流式模式):
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 后不要停止。 -
编写 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清理孤立文件和空项目目录。
- 前提条件:步骤 2 的
-
(可选)验证 HTML——仅在你想于保存前尽早发现错误时执行:
gemdesign validate --file ./output/<projectDir>/<subfolder>/<pageuuid>.html如果验证失败,请修复 HTML 并重新验证。注意:
page save也会在内部进行验证——如果保存时验证失败,请修复 HTML 并重新运行page save。 -
保存到平台(必须——写入 HTML 后必须调用):
gemdesign page save --new --pageuuid <pageuuid> --name "<pageName>" --file ./output/<projectDir>/<subfolder>/<pageuuid>.htmlpage 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(安装/更新 CLI)、步骤 2(登录)以及步骤 2.5(配置 htmlWorkdir 并清理)均已完成。此处不执行步骤 3(启动本地服务并打开浏览器预览)——该步骤会在下方步骤 5 中、创建/复用应用之后执行。
- 确保应用存在(优先复用!):
- 确保已配置 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。 - 重要:同一批次中的所有页面都必须放入同一个应用。复用现有应用可以避免页面分散到不同的项目文件夹中。
- 确保已配置 htmlWorkdir:htmlWorkdir 已在步骤 2.5 中配置(跨会话保留)。
- 获取项目目录名称:
- 运行
gemdesign app info获取{appuuid}和{projectName} - 计算
<projectDir> = {projectName}__{appuuid}(从 projectName 中移除非法字符\/:*?"<>|,并将连续空白字符替换为_) - 示例:项目名称为 "电商 App",appuuid 为 "abc-123" →
<projectDir> = "电商_App__abc-123"
- 运行
- 向用户输出当前应用信息(重要——用户必须知道页面将生成到哪个应用中):
- 生成任何 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”),以便用户在选错时及时打断。
- 无需等待回复:此步骤仅用于告知信息——除非用户想切换应用,否则不需要用户回复。输出后立即继续下一步。
- 生成任何 HTML 之前,必须在回复中明确告知用户页面将生成到哪个应用中。至少输出以下信息:
- 启动本地服务(步骤 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 覆盖设计器并破坏预览界面。
- 重要——严禁跳过
- 搜索样式(可选):
gemdesign style search --keywords "电商,现代,简洁"→ 选择一个 →gemdesign style get --id <id> - 分析需求:阅读需求文档,将其拆分为各个页面。为每个页面分配易读的
pageuuid(例如home、product-list、cart)。 - 生成设计系统页面(仅适用于新建的应用):如果在步骤 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。
- 创建页面(进入流式模式):
- 设计系统审核关卡(重要——仅当步骤 8 生成了设计系统页面时适用):生成任何业务页面之前,必须遵循**“设计系统审核关卡”**中的规则(见下方对应部分)。评估是否满足继续条件;如果均不满足,则停止并按照该部分指定的格式,请用户确认或反馈设计系统。在用户确认设计系统或满足继续条件之前,不得进入步骤 10。如果应用是复用的(跳过了步骤 8),也跳过此步骤。
- 逐页生成(实时显示时使用上方的流式写入工作流):
- 硬性门槛——每页写完立即保存,严禁攒批:生成方式不限(串行或并行均可),但每个页面的 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会在内部进行验证——如果验证失败,修复后重新运行。
- 硬性门槛——每页写完立即保存,严禁攒批:生成方式不限(串行或并行均可),但每个页面的 HTML 一写完,就必须立即执行该页的
- 验证:
gemdesign page list - 输出设计器链接(必须输出一次,且仅在所有页面生成后输出):本批次中的所有页面生成、验证并保存完成后(即步骤 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(安装/更新 CLI)、步骤 2(登录)和步骤 2.5(已配置 htmlWorkdir 并完成清理)均已完成。此处不执行步骤 3(本地服务 + 浏览器预览)——该步骤将在下文步骤 5 中、创建/复用应用后执行。
- 确保应用存在(优先复用!):
- 确保已配置 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。 - 关键:所有页面都必须放在同一个应用中。复用现有应用可避免页面分散到不同的项目文件夹。
- 确保已配置 htmlWorkdir:htmlWorkdir 已在步骤 2.5 中配置(跨会话保留)。
- 获取项目目录名称:
- 运行
gemdesign app info获取{appuuid}和{projectName} - 计算
<projectDir> = {projectName}__{appuuid}(从 projectName 中移除非法字符\/:*?"<>|,将连续空白字符替换为_)
- 运行
- 向用户输出当前应用信息(关键——用户必须知道页面将生成到哪个应用中):
- 生成任何 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”),以便用户在选错时及时中止。
- 便于暂停:这只是信息提示——除非用户想切换应用,否则无需等待用户回复。输出后立即继续下一步。
- 生成任何 HTML 前,必须在回复中明确告知用户你将在哪个应用中生成页面。至少输出:
- 启动本地服务(步骤 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 覆盖设计器并破坏预览界面。
- 关键——严禁跳过
- 生成设计系统页面(仅适用于新建应用):如果在步骤 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。
- 创建页面(进入流式模式):
- 设计系统审核关卡(关键——仅当步骤 6 已生成设计系统页面时适用):遵循**“设计系统审核关卡”**规则(参见下方对应部分)。如果不满足任何继续条件,则停止并征求用户确认/反馈。在设计系统获得确认或满足继续条件之前,不要进入步骤 8。如果复用了应用(跳过了步骤 6),也跳过此步骤。
- 确定易读的
pageuuid(例如,使用不带.html的文件名;在应用内保持唯一) - 遵循页面规范生成 HTML,并将
pageuuid用作导航元素中的data-uuid。遵循设计系统页面所确立的样式基准(如适用,还应遵循已确认的样式)。 - 使用流式写入(必需的 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,页面将不会显示在平台上。
- 向用户描述结果
- 输出设计器链接(必须——所有页面工作完成后仅输出一次):页面生成、验证并保存后,必须在回复中输出可点击链接,以便用户轻松打开设计器。链接必须符合以下要求:
- 名称:
gemdesign 设计器(必须完全一致,不得更改或翻译) - URL:
http://localhost:<port>(使用步骤 3 的server start返回结果中记录的端口) - 格式(Markdown 链接):
[gemdesign 设计器](http://localhost:<port>) - 示例:
[gemdesign 设计器](http://localhost:4056)
**关键——必须在工作流结束时、最末尾精确输出一次此链接。**不要在每个中间步骤后输出链接。这是供用户自行决定是否点击的文本链接,并非自动打开浏览器的操作。完整说明见工作流 A 步骤 12,了解为何这不会与步骤 3 中的“不要在聊天中输出 URL”规则冲突。 当用户请求修改时:
- 名称:
- 使用
gemdesign page get --pageuuid <id> --file ./output/<projectDir>/<subfolder>/<id>.html获取 HTML+DSL,以便编辑 - 修改 HTML(调整 DOM、添加/删除交互 DSL、更新 jsHandle)
- 对于大幅修改,请使用流式写入工作流:重写 HTML(从头开始时先删除旧文件;仅添加内容时则追加)
- **(可选)**使用
gemdesign validate --file ./output/<projectDir>/<subfolder>/<id>.html进行验证 — 如有错误,请修复 - 使用
gemdesign page save --pageuuid <id> --file ./output/<projectDir>/<subfolder>/<id>.html保存 — 必须执行 - 如果需要更新需求文档:使用
gemdesign page doc save --pageuuid <id> --file ./output/<projectDir>/<subfolder>/updated-doc.md
工作流 C:修改现有页面
- 完成前置条件:在继续之前,确保已确认完成步骤 1(CLI 安装/更新)、步骤 2(登录)和步骤 2.5(已配置 htmlWorkdir 并完成清理)。此处不会执行步骤 3(本地服务+浏览器预览)——应在下方步骤 4 中,
app info确认<projectDir>之后执行。 - 获取项目目录名称:运行
gemdesign app info→ 计算<projectDir> = {projectName}__{appuuid}(从 projectName 中移除非法字符\/:*?"<>|,并将连续空白字符合并为_) - 向用户输出当前应用信息(关键——用户必须知道正在修改的页面属于哪个应用):
- 修改任何 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进行切换。 - 可暂停:此步骤仅用于提供信息——除非用户想切换应用,否则无需等待用户回复。输出后立即继续下一步。
- 修改任何 HTML 之前,必须在回复中清楚告知用户目标页面所属的应用。至少输出:
- 启动本地服务(步骤 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 覆盖设计器并破坏预览界面。
- 关键——严禁跳过
gemdesign page list→ 查找目标页面gemdesign page get --pageuuid <id> --file ./output/<projectDir>/<subfolder>/<id>.html→ 获取 HTML+DSL 以供编辑- 分析 HTML 结构和交互
- 根据需要修改 HTML
- 对于大幅修改,请使用流式写入工作流(参见上文):重写 HTML
- (可选)验证:
gemdesign validate --file ./output/<projectDir>/<subfolder>/<id>.html——如有错误,请修复 - 保存到平台(必须):
gemdesign page save --pageuuid <id> --file ./output/<projectDir>/<subfolder>/<id>.html- 关键:仅修改本地文件而不调用
page save,更改将不会同步到平台。page save会在内部进行验证。
- 关键:仅修改本地文件而不调用
- 如果需要更新需求文档:
gemdesign page doc save --pageuuid <id> --file ./output/<projectDir>/<subfolder>/updated-doc.md - 输出设计器链接(必须——仅在所有页面工作完成后输出一次):页面修改、验证并保存后,必须在回复中输出一个可点击链接,方便用户打开设计器查看更新后的结果。链接必须满足以下要求:
- 名称:
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(修改现有页面)。
此关卡存在的原因(第一性原理)
设计系统页面是一个高杠杆决策点。它确定了后续所有业务页面都会继承的颜色、字体排版、阴影、圆角和组件样式。生成后立即检查之所以是自然的检查点,基于两个特性:
-
错误成本不对称。 此处做出的错误样式决策会传播到之后生成的每个业务页面。已有 N 个页面后再进行修正,意味着需要返工 N 个页面;立即修正只需与用户沟通一轮。跳过此关卡的预期成本会随页面数量线性增长,而暂停的成本始终很低。
-
信息状态翻转。 生成前,Agent 只能根据需求文档推断用户的视觉偏好——此时状态不确定。生成后,用户可以在浏览器中看到具体的渲染方案——此时状态确定。这是用户首次掌握可用于确认或调整方向的信息。此时获取这一反馈最有价值:在整个工作流中,这是修正方向成本最低的节点。
决策规则——停止还是继续?
设计系统页面生成、验证并保存后,评估下面的继续条件。默认操作是停止并询问;只有明确满足至少一项继续条件时,才可以不询问并直接继续生成业务页面。
继续条件(满足任意一项即可跳过暂停,直接继续生成业务页面):
| # | 条件 | 可以安全继续的原因 |
|---|---|---|
| C1 | 用户在最初的请求中明确指定了视觉风格(例如指定品牌色、“深蓝科技风”、“参考某App的样式”、情绪板或十六进制颜色代码) | 风格方向已由用户确定——不存在需要通过此检查点解决的信息缺口。 |
| C2 | 用户在本次会话中较早时运行了 style search + style get,并且设计系统页面忠实体现了所选风格 | 用户通过明确的选择操作预先表达了偏好;设计系统是在执行该选择,而非提出新的风格方案。 |
| C3 | 用户明确表示无需审核(例如“不用确认,直接全部生成”、“全自动跑完”、“不要中途停”) | 用户主动放弃了此检查点。请尊重用户表达的偏好。 |
如果没有任何继续条件适用 → 必须停止。 对于仅根据需求文档新建的应用,这是默认且最常见的情况。
停止时——应展示的内容
不要只宣布“设计系统已生成”。请提供一份便于用户做出决定的摘要,让用户可以轻松确认或提出调整:
- 风格决策——主色和辅助色(附十六进制代码)、整体方向(例如科技感/温暖/极简)、关键组件的设计处理(卡片圆角、阴影样式、按钮样式)。内容要具体,不要含糊。
- 决策依据——说明这些决策与需求之间的关联(例如“基于需求文档中‘面向年轻人的社交平台’这一定位,主色选用高饱和度的紫色……”)。
- 明确询问——使用
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 单位
仅允许两种类型的脚本
<script id="interaction-data">— Lite-Interaction JSON 字符串(交互逻辑)<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>
布局规则
- 使用 TailwindCSS 的布局组件类。
- 优先使用 flexbox 布局;Flexbox、内边距和 gap 是界面布局的核心工具。
- 块级元素可用于简单元素(文本、装饰性图片),但不能用于布局。所有元素默认采用
border-box盒模型。 - 固定元素(侧边栏、导航栏)必须设置明确的高度和宽度;内容区域需要设置对应的内边距。
- 遮罩和模态框/抽屉必须嵌套。遮罩/覆盖层必须使用半透明背景色(例如
bg-black/50),内部模态框/抽屉内容容器必须使用不透明背景色(例如bg-white)——内容容器透明属于严重违规,因为遮罩颜色会透出来。 - 居中对齐元素时,绝对不要使用
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 |
操作优先级
show/hide——打开/关闭模态框时优先使用addClass/removeClass——更改 CSSopenPage——页面导航(参数只能是 pageUuid 字符串)back——返回jsHandle——仅在上述操作无法满足需求时使用
jsHandle 规则
- 每个函数必须放在单独的
<script>标签中 - 脚本的
id必须与函数名完全一致 - 只能有一个参数:
event - 内部不能调用 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
脚本顺序
- TailwindCSS(在
<head>中) - ECharts 依赖项(在
<head>中,可选) tailwind.config配置- ECharts 配置脚本(
<script id="echarts_*" type="echarts">,可选) - jsHandle 函数脚本(
<script id="funcName">,可选) 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 命令会检查:
| # | 规则 | 检查内容 |
|---|---|---|
| 1 | interaction_data_exists | 是否存在 <script id="interaction-data"> |
| 2 | dsl_json_valid | 内容是否为有效的 JSON 数组 |
| 3 | selector_exists | 所有原始/目标选择器是否存在于 DOM 中 |
| 4 | selector_format | 是否仅使用 #id 和 .class,不使用属性选择器 |
| 5 | original_single | original 是否只有一个选择器 |
| 6 | target_no_class | target 是否只使用 #id,不使用 .class |
| 7 | jshandle_func_match | 每个 funcName 是否有匹配的 <script id="funcName"> |
| 8 | script_id_funcname_match | script id 是否等于函数名称 |
| 9 | button_type | 所有按钮是否都具有 type="button",且没有 type="submit" |
| 10 | no_vh | 类或样式中是否不含 vh 单位 |
| 11 | no_hash_href | 是否不含 href="#" |
| 12 | image_url_format | 占位图片 URL 是否使用 ./api/searchImage?query=...&width=...&height=...,且 width/height 为数字、& 两侧没有空格 |
| 13 | data_uuid_complete | 带有 data-uuid 的标签是否也具有 id |
| 14 | interaction_data_last | interaction-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