内容
# Rails Markup
指向并点击注释工具,适用于Rails应用程序。点击任意元素,描述需要更改的内容,您的AI代理通过MCP读取并根据您的反馈采取行动。
**v1.0** — 作者归属,导出,搜索,带有绘图工具的截图,Kanban板,通知钩子。
## 工作原理
1. **安装gem** — 添加迁移,工具栏,身份验证控制器和路由
2. **打开您的应用程序** — 注释工具栏作为浮动按钮出现
3. **点击任意元素** — 鼠标悬停突出显示,点击注释并截图
4. **在截图上绘图** — 箭头,矩形,突出显示在捕获的元素上
5. **代理读取它** — AI通过MCP调用`rails_markup_read`
6. **代理修复它** — 解决注释并继续
## 安装
```ruby
# Gemfile
gem "rails-markup", github: "nauman/rails-markup", require: "rails_markup"
```
```bash
bundle install
rails generate rails_markup:install
rails db:migrate
```
升级现有安装时,复制并运行新的引擎迁移:
```bash
bin/rails railties:install:migrations FROM=rails_markup
bin/rails db:migrate
```
### Rails Markup 1.2 滚动UUID升级
1.2升级迁移添加,修复并唯一索引`client_uuid`,但故意使其可为空,而旧应用程序实例可能仍在提供流量。新的安装立即创建它为`NOT NULL`。
对于滚动升级:
1. 运行复制的迁移并将1.2部署到每个应用程序实例。
2. 等待所有旧的pre-1.2实例都被耗尽并停止。
3. 修复在混合版本窗口期间写入的任何行,然后验证:
```bash
bin/rails rails_markup:client_uuids:repair
bin/rails rails_markup:client_uuids:verify
```
这两个命令可以安全地重复。包含任何剩余的空白或非规范标识的拉取请求返回`503`而不改变数据。在旧实例耗尽后,请勿添加`NOT NULL`约束;该显式合约迁移应在后续版本中进行。
生成器创建:
| 文件 | 目的 |
|------|---------|
| `db/migrate/*_create_rails_markup_annotations.rb` | 注释表 |
| `config/initializers/rails_markup.rb` | 配置 |
| `app/controllers/rails_markup_auth_controller.rb` | 身份验证控制器 |
| `bin/markup` | CLI包装器 |
| 路由挂载 | 引擎位于`/admin/annotations` |
| 工具栏注入 | `<%= render "rails_markup/shared/toolbar" %>` 在您的布局中 |
### 生成器选项
```bash
rails generate rails_markup:install \
--mount-path=/admin/annotations \
--base-controller=Admin::BaseController \
--layout=application
```
### 身份验证和浏览器同步
生成的`RailsMarkupAuthController`保护安装的仪表板和工具栏API。它拒绝访问除非`current_user.admin?`为真;自定义`authorize_rails_markup!`如果您的主机使用其他授权策略。配置的基控制器必须实际执行授权。选择公共控制器使两个接口公开。
工具栏使用与仪表板相同的宿主身份验证边界,并发送正常的Rails CSRF令牌进行每个变体。 在宿主布局中保留`csrf_meta_tags`。 Rails是权威的;localStorage是离线缓存和持久化期望状态输出框,按客户端UUID键入。
在协调期间,浏览器拥有的内容,意图,严重性,选择,目标,允许的元数据和显式脏状态在成功的UUID PUT之前保持本地。 服务器拥有的线程,作者/用户身份和时间戳始终获胜。 完整的确切页面拉取可能会删除一个与Rails同步的本地记录,该记录不存在于Rails中,但绝不会删除待处理的上载或删除墓碑。
### 卸载
```bash
rails generate rails_markup:uninstall
# 添加 --remove-migration 以删除迁移文件
```
## 配置
```ruby
# config/initializers/rails_markup.rb
RailsMarkup.configure do |config|
# 仪表板和工具栏API的身份验证控制器;它必须授权访问。
config.base_controller_class = "RailsMarkupAuthController"
# 外部API令牌(用于MCP生产工具)
config.api_token = Rails.application.credentials.dig(:rails_markup, :api_token)
# 当前用户中作者的显示名称
config.author_name_method = :name
# 或使用Proc:
# config.author_name_method = ->(user) { "#{user.first_name} #{user.last_name}" }
# 在创建每个注释后触发的回调
config.on_create_callback = ->(annotation) {
SlackNotifier.notify("反馈位于 #{annotation.page_url}: #{annotation.content}")
}
# 工具栏强调色:indigo, amber, blue, emerald, rose
config.toolbar_accent = "indigo"
# 显示或隐藏注释工具栏和FAB(默认:true)
config.toolbar_enabled = true
# FAB角:bl, br, tl, tr;大小:slim, compact, default
config.toolbar_position = "bl"
config.toolbar_size = "default"
# 元素截图(默认:true)
config.enable_screenshots = true
# 仪表板分页(默认:25)
config.per_page = 25
# “返回应用程序”链接
config.return_url = "/admin"
end
```
## 仪表板
访问`/admin/annotations`以获取完整的仪表板:
- **列表视图** — 状态过滤器,搜索,作者过滤器,加载更多分页
- **看板视图** — 带有拖放状态转换的看板
- **导出** — CSV和JSON下载(尊重当前过滤器)
- **详细信息面板** — 完整内容,元数据,截图,线程
- **批量操作** — 忽略所有待处理/已确认
### 搜索和过滤器
- **文本搜索** — 搜索注释内容和选定文本
- **作者过滤器** — 按创建注释的人员过滤
- **页面URL过滤器** — 按注释页面过滤
- **状态标记** — 待处理,已确认,已解决,已忽略
## 截图和绘图
当您点击一个元素时,工具栏使用SVG foreignObject捕获截图。在提交之前,您可以在其上绘图:
- **箭头** — 点击并拖动以绘制红色箭头
- **矩形** — 点击并拖动以绘制红色轮廓框
- **突出显示** — 自由手绘半透明黄色笔画
- **撤销** — 删除上一个绘图操作
截图存储为注释元数据中的base64,并在仪表板详细信息视图中显示。
## CLI
```bash
# 设置
bin/markup init # 交互式设置向导(TUI)
bin/markup configure # 设置.mcp.json环境变量
bin/markup status # 显示配置(令牌被屏蔽)
bin/markup setup-production --url=URL # 生成令牌 + 配置
# 服务器
bin/markup server # HTTP + MCP服务器
bin/markup mcp # 仅MCP服务器(stdio)
# 注释(匹配MCP工具动词)
bin/markup pending # 从开发环境获取待处理注释
bin/markup pending --production # 从生产环境获取待处理注释
bin/markup resolve 42 --summary "..." # 解决注释
bin/markup dismiss 42 --reason "..." # 忽略注释
bin/markup reply 42 "message" # 回复注释
bin/markup acknowledge 42 # 标记为已确认
bin/markup watch # 轮询新注释
bin/markup watch --production # 监视生产环境
# 信息
bin/markup sessions # 会话信息(仅限MCP)
bin/markup session ID # 会话详细信息(仅限MCP)
```
### 设置向导
运行`bin/markup init`以获取交互式设置向导,引导您完成:
1. 工具栏强调色(indigo, amber, blue, emerald, rose)
2. 工具栏位置(左下,右下,左上,右上)
3. 工具栏大小(slim, compact, default)
4. 截图捕获(开/关)
5. 生产URL(可选)
自动写入`config/initializers/rails_markup.rb`并更新`.mcp.json`。
## MCP设置
添加到 `.mcp.json`:
```json
{
"mcpServers": {
"rails-markup": {
"type": "stdio",
"command": "ruby",
"args": ["bin/markup", "mcp"],
"env": {
"RAILS_MARKUP_DEV_URL": "http://localhost:3000",
"RAILS_MARKUP_PROD_URL": "https://yourapp.com",
"RAILS_MARKUP_PROD_TOKEN": "your-prod-api-token"
}
}
}
}
```
### MCP工具(五个规范的薄枚举工具)
MCP服务器恰好宣传五个工具。 它们的模式拒绝未知参数并使用小的枚举而不是乘法环境特定的工具名称:
| 工具 | 合同 |
|------|----------|
| `rails_markup_read` | 读取`pending`,`sessions`,`session`或`annotation`;永不确认 |
| `rails_markup_watch` | 监视开发注释,带有有界超时/窗口 |
| `rails_markup_transition` | `acknowledge`或`resolve`注释 |
| `rails_markup_reply` | 添加代理回复 |
| `rails_markup_dismiss` | 销毁忽略并附带原因 |
`environment`是`development`或`production`(在支持的情况下)。 生产URL和承载凭证仅来自受信任的进程配置。 调用者提供的URL和令牌重写被拒绝并且从不转发。
### 旧MCP兼容性
旧名称在1.2/1.3兼容性窗口期间仍然隐藏但可调用为显式、发出警告的适配器。 它们从不恢复调用者控制的凭证或变异读取。 它们将在1.3.0后删除;将客户端迁移到上述五个规范工具。
## 注释数据
每个注释包括:
- **内容** — 需要更改的内容(最大5000字符)
- **CSS选择器** — `div#hero.max-w-xl`
- **CSS路径** — `body > main > div:nth-of-type(2) > div#hero`
- **边界框** — `{ top, left, width, height }`
- **附近文本** — 元素文本的前80个字符
- **选定文本** — 点击前突出显示的文本
- **截图** — 元素捕获并带有可选绘图
- **作者** — 通过`author_name_method`创建它的人
- **意图** — `fix`,`change`,`question`或`approve`
- **严重性** — `suggestion`,`important`或`blocking`
## 架构
```
浏览器工具栏 AI代理(Claude Code,Cursor)
| |
| 身份验证的同源API | MCP(stdio JSON-RPC)
| (拉取+ UUID PUT/DELETE,CSRF) | 或CLI(bin/markup pending)
v v
+----------------------------------------------------------+
| Rails引擎 |
| |
| 工具栏 → 注释 → 仪表板 |
| (vanilla JS) (ActiveRecord) (列表+ 看板视图) |
| ↑ |
| 外部API(/external/*) |
| (令牌身份验证,用于MCP) |
+----------------------------------------------------------+
```
## 开发
```bash
git clone https://github.com/nauman/rails-markup
cd rails-markup && bundle install
bundle exec ruby -Ilib:test test/**/*_test.rb
```
## 许可证
MIT。 见 [LICENSE](LICENSE)。