内容
# CampaignRepo
CampaignRepo 是一个基于 Git 的桌面 RPG 游戏主战役平台。每个战役都存放在一个普通的仓库中 - GitHub 或本地文件夹 - 一个特制的网络应用程序将该仓库变成一个 wiki、地图查看器、会话工作区、关系图、 日历等。Markdown 文件保持可移植;不需要 CampaignRepo 读取它们。
游戏主可以获得版本历史、私人笔记、审查队列和对玩家可见内容的完全控制。玩家可以获得一个干净的门户,只显示经过批准、对玩家安全的内容 - 不需要 GitHub 账户。
## 当前状态
CampaignRepo 现在是一个可用的战役管理应用程序,而不仅仅是一个 wiki 原型。它支持本地文件夹和 GitHub 支持的战役;私人游戏主工作区;对玩家安全门户;公开发布的世界;公开战役发现和克隆;会话规划;任务跟踪;幻想日历;地图;关系图;手稿;板块;词典;AI 工具;MCP 访问;完整的 ZIP/JSON 战役备份;以及 Docker/GHCR 部署。
下一个优先级是可靠性。CampaignRepo 的长期形态是**应用程序优先,基于 Git**:
- 即使 GitHub 很慢,CampaignRepo 也应该感觉很快。
- Markdown 和仓库文件保持可移植和耐用。
- 应用程序应该保持本地工作副本以进行实时编辑。
- Git 提交应该是批处理同步操作,而不是每个侧边栏移动、批准或页面编辑的热路径。
- 生成的文件(例如 `.campaignrepo/index.json` 和 `wiki/search/index.json`)应该是可重建的快照,而不是不可替代的真实来源。
请参阅 [ROADMAP.md](ROADMAP.md) 获取可靠性路线图和同步路线图,包括测试、备用方案和最大的隐藏风险。
## 产品导览
### 战役仪表盘
跨连接的每个战役进行搜索,打开仓库,或在需要时扩展设置工具。一旦连接了 GitHub,设置面板默认情况下保持折叠。

### 战役工作区
每个战役都有一个包含 wiki、地图、关系图、时间线、日历、会话板块、任务跟踪器、媒体管理器、设置和健康中心的 工作区。战役主题可以为任何 RPG 系统重新设计工作区。

### Wiki 页面编辑器
页面使用带有 YAML 前置元数据的 Markdown。编辑器并排显示源代码和预览,带有斜杠命令菜单、格式工具栏、粘贴上传图片、wiki 链接插入、画廊块、转录和仅限游戏主块。

### 游戏主审查队列
AI 创建、导入或以其他方式未经批准的内容在成为玩家可见之前等待游戏主审查。

### 玩家门户
玩家只能看到既批准又标记为对玩家可见的页面。仅限游戏主块、导入元数据和草稿内容被删除。

## CampaignRepo 的功能
- 将所有内容存储在 Git 中:页面、媒体、地图、会话、任务、模板、日历配置和战役设置,均为 Markdown 和 YAML。
- 从生成的 `.campaignrepo/index.json` 清单加载战役导航,这样大型仓库不需要枚举每个文件夹或在启动时下载每个 Markdown 文件。
- 使用 `[[链接]]`、`别名`、`反向链接`、`封面`、`画廊`、`转录` 和 `:::gm` 机密块渲染 wiki 页面。
- 提供带有引脚、玩家/游戏主层、嵌套地图链接和文章面板的交互式地图查看器。
- 显示带有类型边、类别筛选器和详细信息面板的有向关系图。
- 使用目标、派系时钟、参与者链接和弧分组跟踪任务。
- 运行带有议程清单、固定页面、游戏主笔记、分发队列和会话到事件报告生成的会话工作区。
- 管理带有可配置月份、星期几和纪元的自定义幻想日历 - 以及跨会话和事件的世界时间线。
- 为每个页面保留版本历史,带有差异和恢复到编辑器工作流。
- 发布一个无需登录的公开网站,展示批准的、玩家可见的传说和任务 - 可分享和克隆。
- 发送应用内通知,用于审查请求、分配、提及和受监视的页面更改。
- 从 Foundry 演员和日志、角色 JSON、Obsidian、Notion、Google Docs、CSV、Roll20、LegendKeeper、World Anvil 和其他世界/日志导出导入。
- 导出完整的 CampaignRepo 备份为 ZIP 或 JSON,包括页面、媒体、地图、会话、任务、搜索数据、模板和设置。
- 在 Markdown 上提供 AI 页面生成和全战役问答,附带引文。
- 为 AI 工具和外部客户端公开 MCP JSON-RPC API。
## 核心功能
### 账户和权限
- 带有用户名/密码登录的本地账户。
- 种子管理员账户,强制首次登录密码更改。
- 用于用户、战役成员资格、角色、密码重置和禁用账户的全局管理员仪表盘。
- 用于成员、邀请链接和玩家访问的每个战役的游戏主工具。
- 所有者、游戏主和玩家战役角色。
### 存储后端
- **本地文件夹** - 不需要 GitHub 账户;离线工作;与 Dropbox、Syncthing、Nextcloud 或 OneDrive 兼容以实现可选同步。
- **GitHub** - 版本历史、异地备份、协作、通过 GitHub 应用程序或个人令牌的多机访问。
基于 GitHub 的战役功能强大,但 GitHub 不是低延迟数据库。路线图将例行编辑转向本地数据库工作副本,带有排队 Git 同步,因此页面组织和批准保持快速,而仓库仍然是耐用的存档。
### Wiki 和编辑器
- 带有 YAML 前置元数据和每种文章类型的结构化字段的 Markdown 页面。
- 类别:角色、NPC、组织、种族、地点、物品、事件、传说、游戏笔记等。
- `[[页面]]` 和 `[[页面|标签]]` wiki 链接、别名、关键链接和反向链接。
- 斜杠命令菜单(/)用于标题、表格、代码块、分隔符、游戏主块、转录和任务列表。
- 在编辑器中粘贴图像以上传并一步插入。
- `:::gm` 仅限游戏主块、`:::gallery` 图像网格和 `:::include` 转录。
- 封面图像渲染为文章横幅。
- 打开文件后检测保存冲突。
- 游戏主预览、玩家预览和讲义视图。
- 编辑器内斜杠命令、格式工具栏和基于差异的历史记录恢复。
### 地图
- 上传地图图像并放置链接到 wiki 页面的引脚。
- 将引脚组织成玩家可见或仅限游戏主的层。
- 标记已发现/未发现的位置并预览对玩家安全地图视图。
- 将引脚链接到嵌套地图以及 wiki 页面。
- 点击引脚打开文章面板而不离开地图。
- 引脚存储为与地图图像一起的可移植 JSON。
- 路线、区域、测量和旅程的早期 UI 存在;完整的 2.0 地图模型仍需要完整的持久性。
### 关系图
- 按类别着色的节点的有向 SVG 图。
- 20 种内置类型关系(成员、位于、结盟、父子、出现在会话中等)及定义的逆关系。
- 类型边虚线并在悬停时标记;类别筛选复选框和仅限类型切换。
- 点击节点聚焦:使未连接的节点变暗,显示带有输出和输入链接的详细信息面板。
### 家族树
- 独家家族树路线,独立于一般关系图。
- 仅显示家族关系:父母、子女、配偶、兄弟姐妹、监护人和被监护人。
- 默认采用层次布局,将配偶放在彼此旁边,并在可用时使用现有的页面肖像/图像。
- 编辑写入普通关系前置元数据,以便谱系在战役仓库中保持可移植。
### 会话
- 会话存储为 `wiki/sessions/<slug>.md`,带有 YAML 前置元数据和 Markdown 笔记。
- 议程检查清单、固定页面、状态、日期、私人游戏主笔记和带有复制链接的分发队列。
- “创建报告页面”会将选定的议程项目和笔记转换为 wiki 事件页面。
- 仪表盘上的下一会话小部件。
### 任务
- 任务存储为 `wiki/quests/<slug>.md`,带有状态、弧线、奖励、可见性、目标和参与者/位置链接。
- 派系时钟:SVG 环段,单击填充和可配置的段数。
- 战役概览仪表盘上的活跃任务小部件。
- 玩家可见的任务出现在玩家门户和公共 `/site/<slug>` 视图中。
### 日历和世界时间线
- 每个战役的自定义日历:可配置的月份(名称 + 长度)、星期几和纪元名称。
- 使用星期几正确的格式跟踪世界内的当前日期。
- 从日历视图按天、周或月推进日期。
- 日历页面上的世界时间线显示按世界日期排序的过去和未来的会话和事件,带有“现在”分隔符。
- 仪表盘上的当前日期小部件。
### 版本历史和活动
- 页面阅读器中的历史选项卡:最后 20 次提交,包含日期、作者、消息、SHA 和 GitHub 差异链接。
- 差异查看器:单击比较任何历史版本与当前文本,显示彩色添加/删除/不变行。
- 恢复:将任何历史版本加载到编辑器中进行审查,然后保存。
- 战役活动提要,显示在概览仪表盘上:最后 30 条仓库提交,包含作者、日期和消息。
### 战役概览仪表盘
- 可在 `campaign.yaml` 中配置的小部件布局。
- 小部件:页面数量、活跃任务、下一会话、当前日历日期、最近活动、审查队列和战役健康状况。
- 游戏主可以启用/禁用和拖动以重新排序小部件;玩家获得一个安全的视图(永远不会渲染仅限游戏主的小部件)。
### 战役健康中心
- 扫描每个页面是否有损坏的 wiki 链接、无效父级、父级类别不匹配、缺失媒体、重复别名、空名称、未批准页面、孤立页面(无传入链接和无父级)和超大媒体文件。
- 按类型分组的结果,带有严重性徽章和受影响页面的链接。
- 内联批量修复:批准所有未批准的、清除无效父级等。
### 批量组织
- 表格视图,显示带有筛选器、排序、多选和批量更改的页面,适用于类别、可见性、批准、父级和标签。
- 媒体表格,显示名称/类型/标签/未使用筛选器、排序、批量添加/删除标签和批量删除。
### 角色导入同步
- 单个角色 JSON 导入保留原始源,位于 `wiki/imports/characters` 下。
- 导入的页面在前置元数据中存储源路径、源 ID 和稳定的源哈希,以便后续导入可以识别为新的、不变的或更改的。
### 角色卡
- **旅行者(Mongoose 2e)**:特性(STR/DEX/END/INT/EDU/SOC),带有计算的 DM、技能、武器、护甲、装备、联系人和积分。单击任何特性或技能以使用动画结果吐司掷 2D6 + 该修正值。
- **D&D 5e**:围栏的 `dnd-sheet` YAML 块渲染为设计好的角色卡,Foundry D&D 演员导入可以创建这些块。
- **Pathfinder 2e**:围栏的 `dnd-sheet` YAML 块,带有 `system: pathfinder2`,渲染出具有排名意识的技能、豁免、动作、专长、装备和法术/焦点部分的角色卡。
- **黑暗世界**:围栏的 `wod-sheet` YAML 块渲染出黑暗世界风格的角色卡。
- 旅行者目前拥有最完整的编辑器/掷骰体验;D&D、Pathfinder 和 黑暗世界仍需要更深入的字段编辑器和更多的印刷润色。
### 公共站点和发现
- 游戏主为任何战役发布一个无需登录的公共站点,网址为稳定的 `/site/<slug>` URL。
- 公共链接名称可以从战役设置中自定义。
- 公共站点包括批准的、玩家可见的页面、媒体、封面、画廊、wiki 链接和玩家可见的任务。
- 单个页面和任务也可以通过 `/share/<token>` 获得基于令牌的公共分享链接。
- `/site` 上的公共画廊列出了所有已发布的世界,按克隆最多的排序,显示名称和系统搜索。
- “克隆此世界”会将发布的战役复制到查看者的自己的 GitHub 仓库中,作为新的战役。
- 公共世界的合作提案是可用的;真正的跨仓库 GitHub 拉取请求仍在路线图中。
### 命令调色板
- 从任何已认证的屏幕按 `Cmd/Ctrl+K`:搜索页面、导航到工作区部分和查找媒体。
### 导入和 MCP
- Foundry Actor JSON 和通用角色 JSON 导入,带有可选字段映射和源差异比较,以便重新导入。
- Foundry 日志、Obsidian、Notion、Google Docs、CSV、Roll20、LegendKeeper、World Anvil 和世界/日志导出导入路由。
- 基本导出下载为 ZIP 或 JSON,来自导入/导出中心。
- 媒体上传、重命名、删除、标题、替代文本、标签和仓库持久化元数据。
- SQLite 全文搜索、可移植的 `/wiki/search/index.json` 快照和 `.campaignrepo/index.json` 处的仓库导航清单。
- `/api/mcp` 处的 MCP JSON-RPC 端点,带有用于搜索、页面读取/创建/更新、模板、媒体、图形数据、审查队列和设置说明的工具。
### AI 工具
- NPC、定居点、派系、谣言、任务和遭遇的随机表格生成器。
- 可选的 OpenAI 兼容端点扩展,生成的草稿在审查之前保持未批准状态。
- 通过搜索索引与页面引文进行全战役问答聊天。
### 协作和工作流
- 玩家可见草稿的审查队列。
- 应用内通知,用于审查请求、分配、提及和受监视的页面更改。
- 页面监视和分配前置元数据。
- 未来软锁和实时协作的端点基础。
### 主题
- 每个战役的强调色、显示字体和横幅图像存储在 `campaign.yaml` 中。
- 特定 RPG 系统(旅行者、黑暗时代:吸血鬼等)的旗舰主题,带有精选的调色板和战役标题徽标。
- 应用于工作区、玩家门户和公共站点。
## 快速入门
安装依赖并运行开发服务器:
```bash
npm install
npm run dev
```
打开:
```text
http://127.0.0.1:3000
```
本地数据库为此第一个管理员账户提供种子:
```text
Email: admin@example.local
Password: admin
```
CampaignRepo 强制种子管理员密码在仪表板或 API 使用之前更改。
## 常用命令
```bash
npm run dev # 启动本地开发服务器
npm run typecheck # TypeScript 检查
npm test # 运行 Vitest 测试
npm run build # 生产构建
npm start # 启动构建的 Next.js 应用程序
```
## GitHub 应用程序设置
最简单的设置路径来自 CampaignRepo 仪表盘:
1. 以全局管理员身份登录。
2. 点击 **连接 GitHub**。
3. 让 GitHub 从清单中创建 CampaignRepo GitHub 应用程序。
4. 选择应用程序可以访问的战役仓库。
5. 返回 CampaignRepo 并连接或修复战役仓库。
CampaignRepo 在 SQLite 中存储 GitHub 应用程序配置,并使用短期安装令牌进行仓库访问。
要手动创建 GitHub 应用程序,请在以下位置创建新的应用程序:
```text
https://github.com/settings/apps/new
```
使用这些值:
- 主页 URL:您的 CampaignRepo URL。
- 回调 URL:`https://YOUR-CAMPAIGNREPO-HOST/api/github/app/callback`。
- 设置 URL:`https://YOUR-CAMPAIGNREPO-HOST/api/github/app/callback`。
- 仓库权限:
- 内容:读取/写入。
- 元数据:只读。
- 安装访问:仅 CampaignRepo 应管理的仓库。
添加 `GITHUB_APP_*` 环境变量并重启应用程序后,使用仪表盘上的 **安装或更新 GitHub 应用程序访问**。
## 战役仓库布局
CampaignRepo 在每个战役仓库中创建并期望以下结构:
```text
/.campaignrepo
index.json
/wiki
/pages
/media
media.json
/templates/<game-type>
/imports/characters
/sessions
/quests
/maps
/search
index.json
campaign.yaml
README.md
```
欢迎进行手动编辑。保留 YAML 前置元数据和 CampaignRepo 约定,以确保 wiki 链接、可见性、批准和仅限游戏主块。
### 仓库清单
CampaignRepo 仓库包括在以下位置生成的清单:
```text
.campaignrepo/index.json
```
清单是 CampaignRepo 的快速导航/索引层。它存储页面 ID、标题、路径、类型、标签、别名、摘要、可见性、批准状态、父级元数据和链接元数据。Markdown 文件仍然是页面内容和前置元数据的规范来源;清单不会复制完整的 Markdown 正文。
通常的仓库加载使用以下模式:
```text
打开战役:
1. 获取 .campaignrepo/index.json
2. 从清单中构建侧边栏、标签、链接、反向链接和公共导航。
打开页面:
1. 获取单个 Markdown 文件
2. 渲染页面正文
```
如果 `.campaignrepo/index.json` 丢失,CampaignRepo 将退回到 `wiki/search/index.json` 和较旧的缓存/重建路径。重建搜索索引也会写入仓库清单。 通过 CampaignRepo 创建页面会同时提交 Markdown 文件和清单更新,保持仓库索引一致。
生成的索引是可处置的。如果清单、搜索快照或数据库缓存与实际页面内容不一致,修复路径应从规范页面源重建生成状态,而不是将生成的文件视为真实的来源。
Git Trees API 用于恢复和重建路径,而不是作为常规导航源。GitHub 内容 API 仍然适合读取或写入单个已知文件。
## 可见性规则
玩家安全性基于页面元数据和仅限游戏主块:
- `visibility: players` 使页面有资格供玩家查看。
- 需要 `approvalStatus: approved` 才能让玩家看到它。
- `:::gm` 块从玩家读取中删除。
- 源导入元数据对玩家读取隐藏。
- 玩家可以在没有 GitHub 凭证的情况下读取战役内容。
## Docker
从GitHub容器注册中心运行预构建的镜像:
```bash
docker compose -f docker-compose.image.yml up -d
```
发布的镜像是:
```text
ghcr.io/avorial/campaignrepo:latest
```
对于Portainer, 从`docker-compose.image.yml`创建一个堆栈或在您自己的compose文件中使用的镜像。 SQLite数据库存储在`campaignrepo-data`卷的`/app/data`中。
首次发布后,如果您希望进行未经身份验证的拉取,请在GitHub Packages中将GHCR包设为公开。
如果要本地构建:
```bash
docker compose up -d --build
```
打开:
```text
http://127.0.0.1:3000
```
有用的环境变量:
```bash
APP_URL=https://campaignrepo.example.com
SECURE_COOKIES=true
GITHUB_APP_ID=123456
GITHUB_APP_SLUG=your-github-app-slug
GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
GOOGLE_CLIENT_ID=your-google-oauth-client-id
GOOGLE_CLIENT_SECRET=your-google-oauth-client-secret
GITHUB_OAUTH_CLIENT_ID=your-github-oauth-client-id
GITHUB_OAUTH_CLIENT_SECRET=your-github-oauth-client-secret
```
在HTTPS后面提供服务时设置`SECURE_COOKIES=true`,以便会话cookie使用`Secure`标志。
Google和GitHub登录是可选的。 Docker镜像仅包含OAuth代码;每个服务器在运行时提供自己的凭证。使用这些重定向网址创建OAuth客户端:
- Google: `https://your-domain.example/api/auth/oauth/google/callback`
- GitHub OAuth应用程序: `https://your-domain.example/api/auth/oauth/github/callback`
GitHub OAuth登录请求`repo`访问权限,以便它也可以作为CampaignRepo内的用户GitHub连接。如果您想通过install-per-repo流程进行存储库连接,请改用上面的单独GitHub应用程序设置。
无需Compose:
```bash
docker build -t campaignrepo .
docker run -p 3000:3000 -v campaignrepo-data:/app/data campaignrepo
```
## Portainer更新
对于本地Portainer安装,GitOps轮询比Webhook在测试期间更简单。
推荐的堆栈设置:
- 仓库: `https://github.com/avorial/CampaignRepo.git`
- 参考: `refs/heads/main`
- Compose路径: `docker-compose.yml`
- 更新方法: 轮询
- 轮询间隔: 5分钟
## 路线图
在 [ROADMAP.md](ROADMAP.md) 中查看当前已发布/部分/开放的功能状态、可靠性/同步架构计划和推荐的下一个发布序列。
## 许可证
查看 [LICENSE](LICENSE)。