# @blinkk/root-cms 中文文档

规范地址：https://npmcn.com/package/%40blinkk/root-cms/

版本：4\.3\.5
npm 元数据更新时间：2026-11-06T00:30:24.442Z
中文译文更新时间：2026-11-08T06:52:25.239Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40blinkk/root-cms
原文对照：https://npmcn.com/package/%40blinkk/root-cms/?lang=original
源码仓库：https://github.com/blinkk/rootjs

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：15.3 MB，743 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=24\.0\.0
- 运行依赖：32 个
- peer 依赖：@blinkk/root 4\.3\.5，firebase-admin \>=11，firebase-functions \>=4
- 首次发布：2022-10-28T23:52:46.613Z
- 最新版本发布：2026-11-06T00:30:24.138Z
- 近 30 天下载量：16146（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：340（近 12 个月 91 个）

## 中文简介

暂无中文简介

## 安装

```sh
npm install @blinkk/root-cms
```

也可以使用：`pnpm add @blinkk/root-cms`、`yarn add @blinkk/root-cms`、`bun add @blinkk/root-cms`

## README

# 建立消防站

消防车必须设置为 `Native Mode` 没有 `Datastore Mode`

Firestore read/writes 需要通过在安全规则上添加以下内容来被锁定(Firebase's Firestore UI) :

```
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }

    match /Projects/{project} {
      allow write:
        if isSignedIn() && userIsAdmin();
      allow read:
        if isSignedIn() && userCanRead();

      match /{collection}/{document=**} {
        allow write:
          if isSignedIn() && userCanPublish();
        allow read:
          if isSignedIn() && userCanRead();
      }

      match /Collections/{collectionId}/Drafts/{document=**} {
        allow write:
          if isSignedIn() && userCanEdit();
      }

      function isSignedIn() {
        return request.auth != null;
      }

      function getRoles() {
        return get(/databases/$(database)/documents/Projects/$(project)).data.roles;
      }

      function userCanRead() {
        let roles = getRoles();
        let email = request.auth.token.email;
        let domain = '*@' + email.split('@')[1];
        return (roles[email] in ['ADMIN', 'EDITOR', 'CONTRIBUTOR', 'VIEWER']) || (roles[domain] in ['ADMIN', 'EDITOR', 'CONTRIBUTOR', 'VIEWER']);
      }

      function userCanPublish() {
        let roles = getRoles();
        let email = request.auth.token.email;
        let domain = '*@' + email.split('@')[1];
        return (roles[email] in ['ADMIN', 'EDITOR']) || (roles[domain] in ['ADMIN', 'EDITOR']);
      }

      function userCanEdit() {
        let roles = getRoles();
        let email = request.auth.token.email;
        let domain = '*@' + email.split('@')[1];
        return (roles[email] in ['ADMIN', 'EDITOR', 'CONTRIBUTOR']) || (roles[domain] in ['ADMIN', 'EDITOR', 'CONTRIBUTOR']);
      }

      function userIsAdmin() {
        let roles = getRoles();
        let email = request.auth.token.email;
        let domain = '*@' + email.split('@')[1];
        return (roles[email] == 'ADMIN') || (roles[domain] == 'ADMIN');
      }
    }
  }
}
```

在 Firstore 中,在 `Projects/<yourprojectid>` 值为 `{roles: {"youremail@yourdomain.tld": "ADMIN"}}`。 。 。 .

使用 Firestore 工作室 :

-   下 `Give the collection an ID`设置 `Collection ID` 改为 `Projects`
-   下 `Add its first document` 设定 `Document ID` 转到您的项目 ID
-   第一套记录 `Field name` 改为 `roles` 带有 `Field type` 联 合 国 `map`
-   在地图上设置新 `Field name` 给您的电子邮件, `Field type` 改为 `string` 财务报告和审定财务报表 `Field value` 改为 `ADMIN` 并拯救我们.

## 说明 `*@domain` 角色补助金

以上规则支持通配符 `*@example.com` 输入 `roles` 那个 匹配每个已签名的用户,其已核实的电子邮件结束于 `@example.com`。 。 。 . 这方便于允许进入整个工作空间,但请注意:

-   任何消防基地Auth承认 `@example.com` 电子邮件——包括: 新创建的账户和任何你不再控制的账户—— 立即增加角色,没有选择进入或审计线索.
-   永远不要对自由电子邮件提供者使用通配符(例如. `*@gmail.com`: 允许任何有谷歌账户的人访问.
-   优先提供明确的电子邮件赠款 `ADMIN` 财务报告和审定财务报表 `EDITOR`; 保留 通配符 `CONTRIBUTOR` 或者说 `VIEWER` 如果你用它的话.

# AI代理人的CLI(`root-cms client.*`(中文(简体) )

这个 `root-cms` CLI 暴露出允许 AI 编码代理( 或任何) 脚本)驱动 `RootCMSClient` 方案方面。 把他们从根中找出来 Root.js项目(包含 `root.config.ts`) (中文(简体) ).

发现可用的 API :

```bash
# Human-readable list of methods + descriptions
root-cms client.methods

# Machine-readable JSON, including referenced type/interface definitions
root-cms client.methods --json --types
```

调用 JSON 系列位置参数的任何方法 :

```bash
# getDoc(collectionId, slug, options)
root-cms client.call getDoc '["Pages", "home", {"mode": "draft"}]'

# A no-arg method (omit the JSON array)
root-cms client.call publishScheduledDocs

# Read large args from stdin by passing `-`
echo '["Pages/home", {"title": "Hello"}]' | root-cms client.call saveDraftData -
```

`client.call` 打印出一个单行 JSON 信封以退出非零 失败时 :

```json
{"ok": true, "result": <value>}
{"ok": false, "error": "<message>"}
```

消防车 `Timestamp`, (中文(简体) ), `GeoPoint`,以及 `DocumentReference` 数值被编码 作为 `{"_seconds","_nanoseconds"}`, (中文(简体) ), `{"_latitude","_longitude"}`,以及 `{"_referencePath"}` 分别载于论据和结果.

## 改革提议

人工智能特工可以 **提议** 内容更改而不是直接写入 火炉. 一个提议是单一的Markdown文件,描述编辑——doc id,, 字段路径、旧值、新值 —— 将致力于您的重播和 在拉动请求中审查。 在应用之前,任何内容都不要触及数据库.

每个更改和操作都是标题,每个编辑的值都是 `diff` 代码块, 因此,拉动请求显示了确切的行变化:

````md
# Refresh the homepage hero

- **id:** `2026-08-20-hero-refresh`
- **version:** 1

## Edit `Pages/home`

### Set `hero.title`

```diff text
-Welcome to Acme
+Build faster with Acme
```
````

一个值块是 `text` (字符串,逐字记录), `yaml`,或 `json`A级 `diff` 块以每行前缀保存整个值 `" "` (不变), `-` (以前),或 `+` (后经. 提案也可用YAML(`.yaml` 文件),原始格式.

支持的更改类型为 `doc.edit`, (中文(简体) ), `doc.create`, (中文(简体) ), `doc.duplicate`, (中文(简体) ), `release.create`, (中文(简体) ), `release.update`,以及 `translations` (标题) `## Edit`, (中文(简体) ), `## Create`, (中文(简体) ), `## Duplicate … to …`, (中文(简体) ), `## Create release`, (中文(简体) ), `## Update release`, (中文(简体) ), 财务报告和审定财务报表 `## Translations`) (中文(简体) ). 编辑操作 (单位:千美元)`set`, (中文(简体) ), `insert_item`, (中文(简体) ), `remove_item`) 使用零基的已点字段路径 数组索引,并依次应用.

3个命令驱动工作流程 :

```bash
# Check the proposal format. No db access, so it works as a CI gate on a PR.
root-cms proposal.check cms-proposals/2026-08-20-hero-refresh.md

# Resolve against the live db, validate against collection schemas, and
# report what it would write.
root-cms proposal.diff cms-proposals/2026-08-20-hero-refresh.md

# Apply it.
root-cms proposal.apply cms-proposals/2026-08-20-hero-refresh.md
```

应用写入 **仅草稿** 它从不出版、时间表或删除 -- 除非提案中的每一项改变都得到彻底的解决,否则什么都不是书面的. 每个命令都打印出相同的单行 JSON 信封 `client.call`。 。 。 .

提议 `before` 值是人类读取 diff 的文件; 除非您通过,否则不会与数据库核对 `--verify-before`。 。 。 .

### 预览提案

`RootCMSClient` 可以覆盖一个未应用的建议 对于它读到的一切,所以 您可以在接受之前先在运行中的网站看到所推荐的内容 :

```ts
import {RootCMSClient, parseProposalFile} from '@blinkk/root-cms/core';

const filepath = 'cms-proposals/x.md';
const res = parseProposalFile(fs.readFileSync(filepath, 'utf8'), filepath);
if (res.ok) {
  const client = new RootCMSClient(rootConfig, {proposal: res.proposal});
  // getDoc(), listDocs(), and batch reads now reflect the proposal.
}
```

复数仅适用于读取. 写作时从来不会折叠提议 `getRawDoc()` 编号 : `listDocs({raw: true})` 故意绕过提议 内容永远不能泄漏到一个 `setRawDoc()` 圆通相去.

## 可下载代理技能

训练AI编码员如何使用这些指令船的准备使用技能 与软件包一起: `root-cms-cli` (单位:千美元) `client.*` 命令), `root-cms-propose` (授权修改建议), `root-cms-apply` (审查和适用 他们, `root-cms-theme` (生成CMS UI的主题),并 `root-cms-email-setup` (部署电子邮件服务并设置电子邮件) 通知)。 装入:

```bash
root-cms skill.install
```

根保持对任何特定 AI 提供者的不可知性: 命令自动检测 现有代理技能目录(例如:. `.claude/skills`, (中文(简体) ), `.agent/skills`,或 任意 `.*/skills` 目录已经在您的工程中)并安装到它们中。 若为 没有找到,它安装到 `.agent/skills`。传递一个明确的目录到 超常检测(例如). `root-cms skill.install ./my-agent/skills`),或 `--force` 以覆盖现有副本。 过 `--skill <name>` 仅安装 其中一个.

# 嵌入CMS(`@blinkk/root-cms/browser-client`(中文(简体) )

`@blinkk/root-cms/browser-client` 是一个无依赖性,框架不可知 用于将Root CMS嵌入到另一个站点的浏览器库. 包起来 输入的 API 背后的 Iframe/ postMessage 线条, 所以线条协议 可以进化而不破坏你的融合.

用于弹出/帧嵌入( doc 编辑器和Root AI),嵌入页的 源代码必须允许在 CMS 插件配置中列出 :

```ts
// root.config.ts
cmsPlugin({
  // ...
  allowedIframeOrigins: ['https://app.example.com'],
});
```

## 无头 doc 编辑器( 流行或 iframe)

打开 `/cms/embed/content/<collection>/<slug>`,最小版本的文档 带有明确(非自动)保存的编辑器。 单位 `popup` 模式,用户的呼叫 手势(例如点击处理器),以避免弹出阻塞器。 关闭编辑器 丢弃未保存的更改 .

```ts
import {RootCMSBrowserClient} from '@blinkk/root-cms/browser-client';

const root = new RootCMSBrowserClient({cmsOrigin: 'https://cms.example.com'});

const editor = root.openEditor('Pages/about', {
  mode: 'popup', // or 'iframe' (pass `container`)
  deeplink: 'hero.title', // optional: field to scroll to on load
});
editor.on('ready', () => console.log('editor loaded'));
editor.on('saved', () => location.reload());
editor.on('published', () => editor.closeAndReload());
editor.on('close', () => console.log('editor closed'));
editor.focusField('hero.image'); // scroll the editor to a field
editor.reload();
editor.close(); // or editor.closeAndReload()
```

## 无头根 AI( 弹出或 Iframe)

打开 `/cms/embed/ai`,紧凑的 Root AI聊天,可选用 doc作为 语境 :

```ts
const ai = root.openRootAI({docId: 'Pages/about', mode: 'popup'});
ai.on('ready', () => console.log('chat loaded'));
ai.close();
```

## 从 CMS 预览面板( “ 单击以编辑 ” ) 中突出字段

当您的网站在 CMS 预览面板内渲染时, 请使用 `PreviewConnection` 从页面中聚焦编辑器字段并突出显示页面 编辑器要求时会结出节点. 预览面板与 CMS, 所以不需要配置, 当页面不存在时, 连接是惰性的 内嵌 :

```ts
import {RootCMSBrowserClient} from '@blinkk/root-cms/browser-client';

const preview = RootCMSBrowserClient.connectPreview();
if (preview.isEmbedded) {
  // "Click to edit": focus the field in the doc editor.
  el.addEventListener('click', () => preview.focusField('hero.title'));
  // Highlight page nodes when the editor hovers/focuses a field.
  preview.on('highlight', ({deepKey, scroll}) => {
    clearHighlights();
    if (deepKey) highlightNode(deepKey, {scroll});
  });
}
```

## 常见问题

### 如何安装 @blinkk/root-cms？

在项目目录运行 npm install @blinkk/root-cms，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@blinkk/root（4\.3\.5）、firebase-admin（\>=11）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。它还提供命令行工具 root-cms，可以用 npx root-cms 直接运行。

### @blinkk/root-cms 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @blinkk/root-cms 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @blinkk/root-cms 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=24\.0\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @blinkk/root-cms 可以商用吗？

@blinkk/root-cms 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @blinkk/root-cms 的下载量有多少？

根据 npm 官方下载统计，@blinkk/root-cms 在 2026/10/09 – 2026/11/07 这 30 天内被下载 16,146 次，日均约 538 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @blinkk/root-cms 还在维护吗？

最新版本 4\.3\.5 发布于 2026/11/06（2 天前）；至今共发布 340 个版本，其中过去 12 个月发布了 91 个；首次发布于 2022/10/29。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

