# 仓库配置

自动识别不够时，使用 .prosefly/config.yaml 显式描述内容空间。

Prosefly 会在扫描仓库时自动识别受支持框架的配置。大多数 Astro、Starlight、Fumadocs、Lotus 和 Dahlia 网站都不需要额外配置文件。

如果仓库使用自定义 loader、monorepo 目录结构、生成式配置，或其他无法从静态文件安全识别的结构，可以使用 `.prosefly/config.yaml`。该文件随仓库一起提交，并成为其中所定义 Space 设置的来源。

## 什么时候需要配置文件

先尝试普通扫描。当扫描找不到正确的内容目录，或需要声明静态 schema 中无法体现的信息时，再添加配置文件，例如：

- 位于应用子目录中的 Space；
- 使用不同 profile 或文件格式的多个 Markdown Collection；
- 存放在不同目录中的多语言内容；
- 希望在 Prosefly 中编辑的自定义 frontmatter 字段；
- 自动识别无法将原生导航文件与 Collection 关联起来的受支持导航配置。

编辑器不会执行仓库代码。因此，即使网站可以正常构建，动态 loader 仍可能需要显式定义。

## 文件位置和生效方式

在仓库根目录创建：

```text
.prosefly/config.yaml
```

添加或修改后，重新执行 **扫描仓库**。Prosefly 会在创建或更新 Space 前校验文件。由该文件加载的 Space 会被标记为配置托管：名称、路径、profile、framework 或发布方式需要在 Git 中修改，然后重新扫描。草稿和内容编辑仍保留在 Prosefly 中，直到你发布。

## 最小配置

顶层文档必须包含 `version: 1` 和至少一个 Space。路径相对于仓库根目录；Collection 的 `directory` 相对于所属 Space 的 `root`。

```yaml
version: 1
spaces:
  - name: Documentation
    root: apps/docs
    publicDir: public
    profile: starlight
    framework: astro
    publishMode: pull-request
    collections:
      - name: Docs
        directory: src/content/docs
        extensions: [md, mdx]
        fields:
          - name: title
            label: Title
            type: string
            required: true
```

### Space 选项

`spaces` 下的每一项可以定义：

- `name`：Prosefly 中显示的 Space 名称；
- `root`：应用目录；仓库根目录使用 `.`；
- `publicDir`：发布公共文件的目录，默认为 `public`；
- `publicImageDir`：`publicDir` 中的图片目录，默认为 `images`；
- `profile`：`prosefly`、`fumadocs`、`starlight` 或 `generic`；
- `framework`：`astro`、`nextjs`、`react-router`、`tanstack-start`、`waku`、`hugo` 或 `unknown`；
- `publishMode`：`commit` 或 `pull-request`；
- `collections`：一个或多个内容定义。

`framework` 和 Space 级别的 `profile` 定义默认编辑行为。不同目录使用不同组件语法时，可以在 Collection 级别覆盖 profile。

## Collection 选项

每个 Collection 都需要 `name`、`directory`、`extensions` 和 `fields`：

```yaml
collections:
  - name: Blog
    directory: src/content/blog
    extensions: [md, mdx]
    profile: prosefly
    fields:
      - { name: title, label: Title, type: string, required: true }
      - { name: date, label: Date, type: string, format: iso-date }
      - name: tags
        label: Tags
        type: array
        items:
          type: string
        widget: tags
```

支持的扩展名是 `md`、`mdx`、`yaml`、`yml` 和 `json`。Markdown Collection 和资源 Collection 需要分别定义，不能在同一个 Collection 中混用文档和资源格式。资源文件使用 `generic` profile，也没有文档导航。

对于多语言 Markdown，请将语言目录放在 Collection 内，并同时声明包含的目录和语言代码：

```yaml
collections:
  - name: Docs
    directory: content
    includeDirectories: [en, zh-cn, ja]
    locales:
      - { locale: en, directory: en }
      - { locale: zh-CN, directory: zh-cn }
      - { locale: ja, directory: ja }
    extensions: [md, mdx]
    fields: []
```

### fields 语法

`fields` 中的每一项描述一个 frontmatter 或资源属性。`name` 必须与源文件中的 key 一致，`label` 是编辑器中显示的名称。保持字段名称稳定，才能让已有草稿和索引条目继续对应。

| 选项          | 作用                                                                                                 |
| ------------- | ---------------------------------------------------------------------------------------------------- |
| `name`        | 属性在源文件中的 key。命名字段必填。                                                                 |
| `type`        | 值的形状：`string`、`number`、`boolean`、`date`、`object`、`array`、`reference`、`enum` 或 `union`。 |
| `label`       | 可选的编辑器标签。                                                                                   |
| `required`    | 要求 key 存在，但不代表文本或列表不能为空。                                                          |
| `default`     | 创建新条目时使用的值，不会改写已有源文件。                                                           |
| `nullable`    | 允许明确写入 `null`。                                                                                |
| `format`      | 字符串格式，例如 `iso-date`、`iso-datetime`、`url`、`email` 或 `uuid`。                              |
| `validations` | 类型相关的限制，例如 `min`、`max`、`integer` 或日期时间选项。                                        |
| `widget`      | 兼容的编辑器控件，例如 `textarea`、`tags`、`select` 或 `image-src`；不会改变存储类型。               |

对象使用 `fields` 声明命名子字段，数组使用 `items`，枚举使用 `values`，引用使用 `collection`，联合类型使用 `variants`：

```yaml
fields:
  - name: title
    label: Title
    type: string
    required: true
    validations:
      min: 1
  - name: publishedAt
    label: Published at
    type: string
    format: iso-datetime
  - name: tags
    label: Tags
    type: array
    items:
      type: string
    widget: tags
```

`required` 检查 key 是否存在；如果要要求字符串或列表非空，可以使用 `validations.min`。默认值必须符合字段定义，并且只用于新条目。`widget` 只改变编辑控件，不改变源文件接受的值。

## 声明导航

如果网站没有可写的原生导航，或只需要发布内容，可以省略 `navigation`。这个关联配置属于 Space 里的目标 Collection，而不是顶层 Space。对于 JSON 导航文件，将文件和对象 key 与该 Collection 关联：

```yaml
collections:
  - name: Docs
    directory: src/content/docs
    extensions: [md, mdx]
    fields: []
    navigation:
      provider: json
      configPath: theme.config.json
      key: docsNav
```

对于受支持的原生集成，请声明 provider、配置路径和网站使用的版本。路径都相对于 Space 的 `root`，因此新的 Space 不需要额外声明应用根目录。Starlight 使用前面已经声明的 Astro 配置和 Collection 目录：

```yaml
collections:
  - name: Docs
    directory: src/content/docs
    extensions: [md, mdx]
    fields: []
    navigation:
      provider: starlight
      configPath: astro.config.mjs
      version: 0.37.0
```

provider 必须与网站的实际配置相符。Prosefly 会将导航变更和文档变更一起审阅；扫描时不会改写框架配置。

## 扫描和排查

1. 将 `.prosefly/config.yaml` 提交到 Prosefly 扫描的分支。
2. 执行 **扫描仓库**，检查识别出的 Space 和 Collection。
3. 确认 profile、路径、字段和导航关联。
4. 打开文档；如果 Space 已经存在，再重建索引。

如果校验失败，请检查缩进、相对路径、Space root 是否唯一、扩展名是否受支持，以及是否填写了必需的 `publishMode`。配置错误不会执行仓库代码，也不会修改 Git 文件。

如果网站使用 Prosefly 无法编辑的导航格式，仍可保留 Collection 定义，并使用仅发布内容的方式。导航行为见[仓库与内容空间](/docs/zh-cn/repositories-and-spaces/)，最终 diff 见[发布审阅](/docs/zh-cn/publishing/#review-content-and-navigation-together)。
