npx skills add https://github.com/subframeapp/subframe --skill develop在代码库中实现 Subframe 设计。通过 MCP 获取设计,同步组件,并添加业务逻辑。
如果找不到 get_page_info 工具(或任何 Subframe MCP 工具),MCP 服务器可能需要认证。请用户认证 Subframe MCP 服务器。如果用户正在使用 Claude Code,请指导他们运行 /mcp 来查看并认证他们的 MCP 服务器,完成后说“完成”。
开始之前,检查当前目录中是否存在 package.json 和 .subframe/ 文件夹:
| 条件 | 操作 |
|---|---|
没有 package.json | 首先运行 /subframe:setup — 目前还没有项目可以实施。 |
有 package.json 并且有 文件夹 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
.subframe/| 继续下面的工作流程。 |
有 package.json 但没有 .subframe/ 文件夹 | 询问用户(见下文)。 |
如果当前目录有 package.json 但没有 .subframe/ 文件夹,询问用户他们更喜欢哪种方法:
/subframe:setup,然后继续下面的工作流程。get_page_info 并传入 URL、ID 或名称。当用户选择在现有的非 Subframe 项目中将设计作为灵感来源时,使用此工作流程。
get_page_info 并传入 URL、ID 或名称以获取设计的布局和结构。根据需要,使用其他可用的 Subframe MCP 工具来获取更多上下文(例如,使用 get_component_info 来了解组件的属性,使用 get_theme 来检查主题值)。Button → 项目自己的按钮组件)// 通过 URL
get_page_info({ url: "https://app.subframe.com/PROJECT_ID/design/PAGE_ID/edit" })
// 通过 ID(例如,来自 /subframe:design)
get_page_info({ id: "PAGE_ID", projectId: "PROJECT_ID" })
// 通过名称
get_page_info({ name: "Settings Page", projectId: "PROJECT_ID" })
// 如果需要,首先列出所有页面
list_pages({ projectId: "PROJECT_ID" })
从 .subframe/sync.json 获取 projectId。如果 .subframe/sync.json 不存在或不包含 projectId,请调用 list_projects 以获取可用的项目。每个项目都包含 projectId、name、teamId 和 teamName。
teamName 以消除歧义。如果用户已经提到了特定的团队或项目名称,请将其与 teamName 和 name 字段进行匹配 — 但在继续之前仍需确认。当存在多个项目时,切勿静默地选择一个项目。当组件在本地不存在时,同步组件。您可以通过名称同步特定组件:
npx @subframe/cli@latest sync Button Alert TextField
或者同步所有组件:
npx @subframe/cli@latest sync --all
何时同步:
切勿修改已同步的组件文件 - 它们会被覆盖。如果需要添加逻辑,请创建包装组件。
如果必须直接修改已同步的组件文件,请在文件顶部添加 // @subframe/sync-disable:
// @subframe/sync-disable
import * as React from "react"
// ... 组件其余部分
这可以防止该文件在未来的同步中被覆盖。
更新已禁用同步的组件:
如果用户想要更新一个已禁用同步的组件,同步命令将跳过它。要获取最新版本:
get_component_info 从 Subframe 获取最新代码Subframe 生成带有占位数据的展示性代码。您需要添加:
数据获取:
const { data, isLoading, error } = useQuery(...)
if (isLoading) return <Skeleton />
if (error) return <Alert variant="error">{error.message}</Alert>
return <PageComponent {...data} />
表单处理:
const handleSubmit = async (e: FormEvent) => {
e.preventDefault()
await submitForm(formData)
}
事件处理程序:
<Button onClick={handleClick}>Submit</Button>
<Card actionSlot={<IconButton onClick={handleDelete} />} />
当设计发生变化时:
在将更新后的设计与现有代码进行比较时,如果存在超出用户要求您设计范围的设计更改(例如,布局调整、新元素、移除的部分),请明确指出并询问是否要包含它们。
| 工具 | 用途 | 关键参数 |
|---|---|---|
get_page_info | 获取页面代码 | url、id 或 name;projectId |
get_component_info | 获取组件代码 | url、id 或 name;projectId |
list_pages | 列出所有页面 | projectId |
list_components | 列出所有组件 | projectId |
get_theme | 获取 Tailwind 配置 | projectId、cssType |
每周安装量
315
代码仓库
GitHub 星标数
379
首次出现
2026年2月6日
安全审计
安装于
cursor227
codex130
opencode54
github-copilot54
claude-code53
gemini-cli51
Implement Subframe designs in the codebase. Fetch the design via MCP, sync components, and add business logic.
If you cannot find the get_page_info tool (or any Subframe MCP tools), the MCP server likely needs to be authenticated. Ask the user to authenticate the Subframe MCP server. If the user is using Claude Code, instruct them to run /mcp to view and authenticate their MCP servers, and then say "done" when they're finished.
Before starting, check for package.json and .subframe/ folder in the current directory:
| Condition | Action |
|---|---|
No package.json | Run /subframe:setup first — there's no project to implement into yet. |
Has package.json AND has .subframe/ folder | Proceed with the workflow below. |
Has package.json but NO .subframe/ folder | Ask the user (see below). |
If the current directory has a package.json but no .subframe/ folder, ask the user which approach they prefer:
/subframe:setup first, then continue with the Workflow below.get_page_info with the URL, ID, or name.Use this workflow when the user chose to use the design as inspiration in an existing non-Subframe project.
get_page_info with the URL, ID, or name to get the design's layout and structure. Use other available Subframe MCP tools as needed to get additional context (e.g., get_component_info to understand a component's props, get_theme to check theme values).Button → the project's own button component)// By URL
get_page_info({ url: "https://app.subframe.com/PROJECT_ID/design/PAGE_ID/edit" })
// By ID (e.g., from /subframe:design)
get_page_info({ id: "PAGE_ID", projectId: "PROJECT_ID" })
// By name
get_page_info({ name: "Settings Page", projectId: "PROJECT_ID" })
// List all pages first if needed
list_pages({ projectId: "PROJECT_ID" })
Get the projectId from .subframe/sync.json. If .subframe/sync.json doesn't exist or doesn't contain a projectId, call list_projects to get the available projects. Each project includes a projectId, name, teamId, and teamName.
teamName to disambiguate. If the user already mentioned a specific team or project name, match it against the teamName and name fields — but still confirm before proceeding. Never silently pick a project when multiple exist.Sync components when they don't exist locally. You can sync specific components by name:
npx @subframe/cli@latest sync Button Alert TextField
Or sync all components:
npx @subframe/cli@latest sync --all
When to sync:
Never modify synced component files - they get overwritten. Create wrapper components if you need to add logic.
If you must modify a synced component file directly, add // @subframe/sync-disable to the top of the file:
// @subframe/sync-disable
import * as React from "react"
// ... rest of component
This prevents the file from being overwritten on future syncs.
Updating a sync-disabled component:
If the user wants to update a component that has sync-disable, the sync command will skip it. To get the latest version:
get_component_info to fetch the latest code from SubframeSubframe generates presentational code with placeholder data. You add:
Data fetching:
const { data, isLoading, error } = useQuery(...)
if (isLoading) return <Skeleton />
if (error) return <Alert variant="error">{error.message}</Alert>
return <PageComponent {...data} />
Form handling:
const handleSubmit = async (e: FormEvent) => {
e.preventDefault()
await submitForm(formData)
}
Event handlers:
<Button onClick={handleClick}>Submit</Button>
<Card actionSlot={<IconButton onClick={handleDelete} />} />
When a design changes:
When diffing the updated design against the existing code, if there are design changes beyond what the user asked you to design (e.g., layout tweaks, new elements, removed sections), call those out and ask whether to include them.
| Tool | Purpose | Key Parameters |
|---|---|---|
get_page_info | Fetch page code | url, id, or name; projectId |
get_component_info | Fetch component code | url, id, or name; |
Weekly Installs
315
Repository
GitHub Stars
379
First Seen
Feb 6, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
cursor227
codex130
opencode54
github-copilot54
claude-code53
gemini-cli51
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
140,500 周安装
Docassemble 表单构建器技能 - 创建智能动态问卷与文档生成工具
257 周安装
Fastify TypeScript 生产级后端框架指南:高性能 Node.js Web 开发与 JSON 模式验证
257 周安装
AI 演示文稿生成器 | 一键创建专业幻灯片,支持 Marp 格式输出
257 周安装
Mapbox搜索模式指南:地理编码、POI搜索与位置发现最佳实践
257 周安装
Zustand适配器:为json-render提供状态管理后端,支持嵌套切片与Zustand v5+
257 周安装
Blender MCP 插件使用指南:3D 场景自动化与 Python 脚本控制教程
257 周安装
projectIdlist_pages | List all pages | projectId |
list_components | List all components | projectId |
get_theme | Get Tailwind config | projectId, cssType |