ai_co_discuss 0.2.70 → 0.2.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/discuss-host/SKILL.md +5 -1
- package/.agents/skills/discuss-host/references/manual.md +1 -1
- package/.agents/skills/discuss-participant/SKILL.md +1 -1
- package/.agents/skills/discuss-participant/references/free.md +2 -0
- package/backend/free_room.py +124 -29
- package/backend/schema.sql +26 -0
- package/backend/server.py +69 -16
- package/docs/architecture.md +4 -3
- package/docs/cli.md +1 -1
- package/docs/deployment.md +225 -225
- package/docs/runner.md +455 -454
- package/docs/skills.md +1 -1
- package/docs/workflow.md +8 -6
- package/package.json +1 -1
- package/runner/api_participant.mjs +235 -230
- package/runner/discussion_adapters.mjs +70 -2
- package/runner/discussion_runner.mjs +1 -1
- package/runner/free_runner.mjs +78 -6
- package/runner/scheduler.mjs +48 -24
- package/web/app.js +5 -5
- package/web/icons/typesafe.png +0 -0
- package/web/modern.css +1 -1
- package/web/modern.js +4148 -3876
package/docs/architecture.md
CHANGED
|
@@ -257,10 +257,11 @@ running 状态即使只有 pending 事件,也必须先暂停才能重新启动
|
|
|
257
257
|
- **手动成员注册**:`member_registrations`(`member_id`、`room_id`、`token_hash`、`registered_at`)记录手动成员自己发起的注册,`POST /api/rooms/ID/register` 只接受该成员自己的凭证(房主凭据与他人凭证返回 403),重复调用保留首次时间。记录绑定注册时的凭证哈希:请回换发新凭证后旧记录不再匹配,视图中的 `registered_at` 回到空串,须重新注册。会话 ID 不属于注册内容,仍由 CLI 头部采集进 `member_sessions`;`adopt` 要求已注册。讨论房间的成员视图与自由房间 `free.members` 都带 `registered_at`;新表为独立表,D1 重新应用 schema 即可。
|
|
258
258
|
- **请求**:用户消息按结构化接收者 `to`(成员名)为每位成员生成一条请求;省略且仅有一位在场成员时默认点名该成员,多位成员时交给主持人(`route`),只有在线成员而没有主持人时只作留言,不广播。网页只从正文中代码与引用之外的 `@成员` 生成 `to`,没有 @ 时省略 `to`。请求状态为 `pending`(待投递)→ `delivering`(处理中)→ `completed` / `cancelled` / `failed`。
|
|
259
259
|
- **取消原因**:`request_cancel_reasons`(`request_id`、`reason`)是独立侧表,记录请求被取消的原因(`user_stop`、`member_away`、`member_removed`、`rerouted` 智能调度改派或换主持人、`no_reply` 无需回应、`archived` 房间归档),房间视图的每条请求带 `cancel_reason`;此表加入前已取消的请求没有记录,旧库重复执行 schema 即可。归档自由房间会作废其未完成的执行与排队请求;主持人离开、被移出或被更换时,其尚未开始的 `route` 请求由新主持人重新接收。
|
|
260
|
-
- **执行**:`member_executions` 每位成员最多一个 `dispatched/started`(部分唯一索引),不同成员可并行。接入程序用控制凭据 `GET inbox`、`POST executions {member_id, client_id}`(同一 `client_id` 返回同一执行)把成员的全部待投递请求打包;`POST executions/ID {action}` 支持 `renew`(租约 120 秒,不超过单次执行时限,默认 20
|
|
260
|
+
- **执行**:`member_executions` 每位成员最多一个 `dispatched/started`(部分唯一索引),不同成员可并行。接入程序用控制凭据 `GET inbox`、`POST executions {member_id, client_id}`(同一 `client_id` 返回同一执行)把成员的全部待投递请求打包;`POST executions/ID {action}` 支持 `renew`(租约 120 秒,不超过单次执行时限,默认 20 分钟;可附 `activity` 与 `activity_at`,即软件最近一次输出的阶段与秒级时间,阶段为 `thinking`/`command`/`tool`/`editing`/`writing` 或空,时间不早于执行创建、超过服务器时间按当前时间记,不附则保留上次报告;还可附 `notes: [{seq, text}]`,每次最多 10 条,`seq` 为 1–50、`text` 为 1–500 字,同一执行同一 `seq` 只存一次,重试续租不重复。房间视图只给执行附 `notes` 条数,正文由 `GET executions/ID/notes` 读取,读取权限与房间视图相同)、`fail`(请求标记失败)和 `release`(仅确认未送达时退回队列)。租约过期的执行在下次读取或领取时标记失败,不自动重发。
|
|
261
261
|
- **主持人与任务链**:用户是需求方,不担任主持人。只要有在场的非在线成员,房间就保持恰好一位主持人:成员变动时,离开或移出的主持人失去角色,由第一位在场的 runner 成员(没有则手动成员)接任;建房和每条房主消息前也做同样的补位,因此旧房间在下一条消息时自动获得主持人。房主用 `POST members/ID {action:"role", role:"host"}` 更换主持人(在线成员不能担任),把现任主持人改为 `member` 会被拒绝。多位成员时未点名的房主消息生成给主持人的 `route` 请求。主持人的回答可带 `to` 点名其他成员(不能点名自己),这些请求组成一个批次(`free_batches`);批次内全部进入终态后:只有一个请求的批次不再回交(该成员的回答直接面向用户);多个请求的批次只要有一个完成就给主持人生成一次 `handoff` 请求;全部失败则停下该任务链。每条房主消息开启一条任务链(`chain_id` 为该消息编号),链上 AI 发起的请求(派活与回交)最多 8 次,超出即停下(`free_chains`,原因 `budget` / `all_failed`),房主发新消息开启新链。Worker 用同一批次内的集合 SQL 完成回交,回交请求按(派活消息,主持人)唯一,重复执行不会重复唤醒。
|
|
262
|
-
- **发言顺序**:房间视图 `speaking_order`(亦可 `GET speaking-order` 单独读取)在两种模式下给出同一结构:`kind`、`items[{name, state}]`(`done` / `speaking` / `queued` / `idle`,依次为已发言、正在发言、待发言、其余成员)、可调整的 `movable`、房间默认顺序 `default` 与 `revision`。自由协作有未完成的依次点名时 `kind=queue`(`message_id` 为该消息),否则 `kind=default`、全体成员按默认顺序为 `idle`;讨论为 `kind=turns
|
|
263
|
-
-
|
|
262
|
+
- **发言顺序**:房间视图 `speaking_order`(亦可 `GET speaking-order` 单独读取)在两种模式下给出同一结构:`kind`、`items[{name, state}]`(`done` / `speaking` / `queued` / `idle`,依次为已发言、正在发言、待发言、其余成员)、可调整的 `movable`、房间默认顺序 `default` 与 `revision`。自由协作有未完成的依次点名时 `kind=queue`(`message_id` 为该消息),否则 `kind=default`、全体成员按默认顺序为 `idle`;讨论为 `kind=turns`,由本轮已发言者、当前安排与本轮的排队安排组成;排队按轮切分(专家在正在填充的一轮里第二次出现即开始下一轮),后续轮次以 `later`(每轮一组名字)列出,不在 `movable` 中,调序请求带上它们返回 400。房主用控制凭据 `POST speaking-order {revision, order}` 调整:缺 revision 400,已变化 409,`order` 须恰好包含 `movable`(缺少或多出的名字列在 400 中)。`queue` 删除并按新顺序重插该消息尚未请求的 `free_queue` 行;`turns` 只在本轮排队安排(队列最前面的若干行)的 id 之间整体交换内容(专家、问题、提交编号、创建时间),id 顺序即接力顺序,原计划的提交编号仍对应原内容;`default` 写入 `speaking_orders`(成员编号 JSON 数组,未列出者排在后面,主持人在前、其余按编号)。主持人的 `turn roster` 按此顺序列出专家。
|
|
263
|
+
- **全体点名**:房主消息带 `to`(多于一人)且 `order: "auto"`(网页 `@全体成员` / `@all`)、主持人由本机唤醒(`access=runner`)时,只给主持人建一条 `purpose=group` 请求;主持人不由本机唤醒时按普通点名同时请求。`group` 请求从不投递(预留执行时排除,`inbox` 仍列出),由接入程序用 `POST recommendations/MESSAGE_ID {action:"all"|"sequential"}` 安排:`all` 与未点名消息的全体相同,把它原地改为 `all` 并为其他成员各建一条 `all` 请求;`sequential` 删除这条请求,再把在场成员按房间默认顺序写入 `free_queue`(同下条依次点名)。对 `group` 请求用其他 action 返回 400,已安排过返回 409 或 404(依次安排后已无该请求)。主持人更换、离开或被移除时,尚未安排的 `group` 请求与 `route` 一样交给新主持人。
|
|
264
|
+
- **依次点名**:房主消息带 `to` 且 `sequential: true`(网页手动输入 `@全体依次` / `@all-seq`)时把被点名成员按房间默认顺序写入 `free_queue`,只给第一位建 `ask` 请求(`created_by=user`、`chain_id` 为原消息、不进 `free_batches`)。每次结算批次(回答、失败、打断、离开、租约过期)时,该消息已没有 `pending` / `delivering` 请求就为下一位尚未请求的成员建请求;尚未请求且已不在场的成员被删去。已请求的行保留,供发言顺序显示已发言者。Python 与 Worker 用相同的集合 SQL 推进;`free_queue` 与 `speaking_orders` 不进备份,删除房间时一并清除(独立表,D1 重新应用 schema 即可)。
|
|
264
265
|
- **智能调度推荐**:接入程序用控制凭据 `POST recommendations {message_id, member_id, provider, confidence}` 为一条已交给主持人(`route`)的未点名消息记录推荐对象(在场的非该主持人成员,含手动与在线成员),写入 `member_recommendations`(每条消息一条,重复提交忽略;独立表,D1 重新应用 schema 即可),有效期 60 秒,主持人的请求不受影响。房主用 `POST recommendations/MESSAGE_ID {action:"adopt", mode}` 采纳:`interrupt` 取消主持人这条请求(已投递则作废主持人本次整个执行),`after` 等主持人这条请求进入终态。两种方式都先置为 `waiting`,由 `release`(采纳时与每次 `inbox` 读取时执行)在主持人请求已终态时为推荐成员建一条 `ask` 请求(`created_by=user`、`chain_id` 为原消息),状态改为 `adopted`。过期 5 秒宽限后采纳返回 409,重复采纳返回原结果。同一入口的 `{action:"all"}` / `{action:"none"}` 不经推荐表:全体把主持人尚未开始的 `route` 请求原地改为 `purpose=all`(每条消息每位成员只有一条请求),并为其余在场成员各建一条 `all` 请求(`created_by=user`、`chain_id` 为原消息、不进 `free_batches`,因此没有 `handoff`);无需回应取消该 `route` 请求;主持人请求已不是 `pending` 时返回 409。主持人本次回答的请求全是 `all` 时,带 `to` 的回答被拒绝(400),避免重复请求其他成员。房间视图 `free.recommendations` 带成员名、状态、方式、置信度与剩余秒数 `expires_in`;备份、导入(仅作历史,不再生效)与删除一并处理。`inbox` 的待投递项带 `purpose` 供接入程序识别。`inbox.members` 只列由本机唤醒的成员;手动与在线成员另列于 `inbox.observers`(含待处理请求,供智能调度识别主持人与推荐对象),接入程序从不向它们投递。
|
|
265
266
|
- **回应建议**:普通成员新发言的结构化 `to` 与正文在场成员 @ 合并保存到 `member_suggestions`(原消息编号、稳定成员编号),排除自己、代码与引用;不会创建请求。消息读取返回 `suggestions`,包含目标在场状态及已转换的请求编号。房主用 `POST suggestions {message_id,member_id}` 转换:同一事务记录用户确认消息,调用现有建请求路径,`message_id` 保留原回答、`chain_id` 使用用户确认消息编号、`created_by=user`。`UNIQUE(message_id,member_id)` 使重复或并发点击只生成一个请求及一条确认,终态不重新派发。权限、在场状态和未存档条件在写入事务内校验;Worker 使用批次断言。升级须应用包含新表的 schema;Python 重启时自动建表,D1 发布前显式执行。已有历史消息不补写建议。
|
|
266
267
|
- **讨论中的直接提问**:讨论房间的用户消息带 `to`(点名成员名列表)时,除保存消息外为每位被点名的在场成员建一条 `ask` 请求(`created_by=user`,不入 `free_batches`,不占安排);讨论运行中点名主持人不重复建请求。`GET inbox`、`POST executions` 与 `executions/ID` 对讨论房间同样可用,成员以 `execution_id`(接入程序交付)或 `request_ids`(手动 / 代发)提交 `chat` 回答,走自由房间的写入校验。同一成员的 `member_executions` 与 `discussion_events` 互斥(任一方领取时另一方有进行中则返回 409)。房间视图 `asks` 给出最近请求与执行,供消息旁的状态徽标。本机服务以 `DiscussionWithQuestions`(`runner/discussion_service.mjs`)并行运行讨论 runner 与 `FreeRoomRunner`,共用同一成员会话绑定。
|
package/docs/cli.md
CHANGED
|
@@ -126,7 +126,7 @@ codiscuss state view $room
|
|
|
126
126
|
| 主持发言 | `message post ROOM --as Codex --kind moderation --body-file FILE --submission-id UUID` |
|
|
127
127
|
| 在线专家代发 | 被正式安排后,主持人 `message post ROOM --as Codex --author Claude --turn TURN --summary-file SUMMARY --summary-by Claude --body-file FILE --submission-id UUID` |
|
|
128
128
|
| 整轮安排 | 主持人 `turn roster ROOM` 后 `turn create ROOM --as Codex --plan-file PLAN.json --roster REV --submission-id UUID`;PLAN 为 `[{"expert":"Claude","question":"…"}]`,按顺序接力;多项计划须先 `turn roster ROOM` 取得最新专家状态,把其 `revision` 用 `--roster` 带上,并包含 `waiting` 中的每位专家(主持人除外;尚未注册的手动专家列在 `unregistered`,不在 `waiting` 中,也不能被安排,否则返回 400 并列出名字):未带 revision 返回 400,名单已变化返回 409,缺人返回 400 并列出名字 |
|
|
129
|
-
| 发言顺序 | `turn order ROOM` 读取发言顺序(`items` 的已发言 / 正在发言 / 待发言、可调整的 `movable` 与 `revision
|
|
129
|
+
| 发言顺序 | `turn order ROOM` 读取发言顺序(`items` 的已发言 / 正在发言 / 待发言、可调整的 `movable`、讨论中后续轮次的只读 `later` 与 `revision`),自由协作与讨论通用;讨论中只能调整本轮;房主凭据 `turn reorder ROOM --revision REV --member A --member B …` 按新顺序列出 `movable` 中的全部成员,已发言与正在发言者不动:未带 revision 返回 400,顺序已变化返回 409,缺少或多出成员返回 400 并列出名字 |
|
|
130
130
|
| 继续原计划 | 用户介入或打断后,主持人 `turn continue ROOM --as Codex`;改用新安排则排队自动作废 |
|
|
131
131
|
| 取消安排 | 主持人 `turn cancel ROOM TURN --as Codex` |
|
|
132
132
|
| 切换阶段 | `room update ROOM --as Codex --phase discussing` |
|
package/docs/deployment.md
CHANGED
|
@@ -1,225 +1,225 @@
|
|
|
1
|
-
# 部署指南
|
|
2
|
-
|
|
3
|
-
本地 Python / SQLite 与 Cloudflare Pages / D1 提供同样的讨论接口。二选一即可,数据库彼此独立,不自动同步。
|
|
4
|
-
|
|
5
|
-
当前服务没有用户登录和读取权限隔离;所有新房间都要求房主或成员写入凭据。先阅读 [安全说明](../.github/SECURITY.md),再决定是否暴露到公网。外部访问控制也可能阻止在线 AI 读取;此时按工作流转交必要材料。
|
|
6
|
-
|
|
7
|
-
## Python 服务
|
|
8
|
-
|
|
9
|
-
通过 [npm 安装配置](runner.md#npm-安装与本机配置) 的本机用户可直接 `codiscuss local open`,它使用包内网页、已配置 Python 和包外持久数据库,同时启用仅限回环的网页启动入口。以下参数适用于直接运行源码或独立部署;两种路径的数据位置不同,不自动迁移。
|
|
10
|
-
|
|
11
|
-
Python 3.10+,无第三方 Python 依赖。前端已经随仓库提供;修改源码后在 Node.js 24+ 环境中重新构建:
|
|
12
|
-
|
|
13
|
-
```sh
|
|
14
|
-
npm ci
|
|
15
|
-
npm run build:ui
|
|
16
|
-
python server.py --host 127.0.0.1 --port 8765 --no-demo
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
| 选项 | 环境变量 | 默认值 |
|
|
20
|
-
| --- | --- | --- |
|
|
21
|
-
| `--host` | `HOST` | `127.0.0.1` |
|
|
22
|
-
| `--port` | `PORT` | `8765` |
|
|
23
|
-
| `--database` | `DATABASE_PATH` | 项目 `data/discuss.sqlite3` |
|
|
24
|
-
| `--no-demo` | 无 | 不传时在新数据库写入带示例标记的欢迎记录 |
|
|
25
|
-
| `--local-launch` | 无 | 显式开启本机软件配置与网页启动,仅允许绑定 127.0.0.1,需 Node.js 24+ |
|
|
26
|
-
|
|
27
|
-
命令行参数优先于环境变量。使用独立测试库可加 `--database data/test.sqlite3`。停止后重新启动沿用原库;`--no-demo` 不清理已有数据。长期部署应使用自己的进程管理和反向代理提供 HTTPS,按需要限制访问与请求规模。
|
|
28
|
-
|
|
29
|
-
管理员账号:绑定 127.0.0.1 时无需账号,访问者即管理员,可存档、恢复、永久删除任意房间。绑定其他地址(如 `--host 0.0.0.0`)时须注册:首次打开网站在左下角注册,需要安装令牌。环境变量 `DISCUSS_ADMIN_SETUP_KEY` 可固定令牌,未设置时每次启动随机生成并写入启动日志(仅在尚未注册时打印)。注册后可存档、恢复、永久删除任意房间;忘记密码运行 `python server.py --reset-admin`(不停服务也可执行)后重新注册。
|
|
30
|
-
|
|
31
|
-
网页 SSE 推送在 Python 服务中默认启用,无需额外进程或数据库迁移。反向代理应关闭 `/api/updates` 的响应缓冲并允许长连接;服务每 15 秒发送心跳。页面隐藏时断开,重新打开后补取最新数据;代理不支持推送时回退轮询。
|
|
32
|
-
|
|
33
|
-
附件保存在数据库旁的 `<数据库文件名>.attachments/`,例如 `data/discuss.sqlite3.attachments/`;Docker 中同样位于数据卷内。备份时先停止对应写入进程,再一并复制数据库和附件目录;只备份 SQLite 不包含原文件。无附件时也可用 SQLite 的在线备份工具生成一致快照,不要仅复制正在写入的主文件而遗漏 WAL。恢复前保留原库和附件目录,再用 `--database` 指向恢复副本核验。
|
|
34
|
-
|
|
35
|
-
## Docker
|
|
36
|
-
|
|
37
|
-
仓库自带前端产物,直接用 Docker 即可启动;只有修改前端源码后才需要先执行 `npm ci` 和 `npm run build:ui`。在仓库根目录显式指定 `deploy/Dockerfile`,镜像只复制服务、schema、许可证和运行资源:
|
|
38
|
-
|
|
39
|
-
```sh
|
|
40
|
-
docker build -f deploy/Dockerfile -t ai-co-discuss .
|
|
41
|
-
docker volume create ai-co-discuss-data
|
|
42
|
-
docker run --name ai-co-discuss -p 127.0.0.1:8765:8765 -v ai-co-discuss-data:/data ai-co-discuss
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
镜像以非 root 用户运行,默认空库;持久数据位于命名卷 `/data`,容器删除不代表卷已删除。此处只绑定本机端口,需要远程访问时由部署者配置反向代理与访问边界。
|
|
46
|
-
|
|
47
|
-
`deploy/Dockerfile.dockerignore` 按 [Docker 的专用排除文件约定](https://docs.docker.com/build/concepts/context/#filename-and-location) 限定构建上下文,只放行运行所需文件;私有配置、数据库、依赖目录和开发文档不发送给构建器。
|
|
48
|
-
|
|
49
|
-
## Cloudflare Pages + Functions + D1
|
|
50
|
-
|
|
51
|
-
采用 Pages advanced mode:`backend/worker.mjs` 打包成 `_worker.js`,直接绑定 D1 的 `DB`。没有外部 Worker service binding,也不需要 Nuxt 服务端。配置依据见 [Cloudflare Pages Wrangler 文档](https://developers.cloudflare.com/pages/functions/wrangler-configuration/)。
|
|
52
|
-
|
|
53
|
-
### 本地预览
|
|
54
|
-
|
|
55
|
-
```sh
|
|
56
|
-
npm ci
|
|
57
|
-
npm run db:local
|
|
58
|
-
npm run dev
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
打开 <http://127.0.0.1:8787>。本地 D1 状态位于 `.wrangler/`,与 Python 数据库独立。根目录 `wrangler.jsonc` 是可提交的模板,数据库 ID 为占位值;本地模拟不访问远端数据库。
|
|
62
|
-
|
|
63
|
-
### 创建自己的部署配置
|
|
64
|
-
|
|
65
|
-
首次部署需要 Node.js 24+、npm 和 Cloudflare 账号。先克隆仓库并进入根目录,再执行以下命令安装依赖、登录并创建自己的云资源;将占位名称替换为实际名称。相关平台步骤见 [Pages 直接上传](https://developers.cloudflare.com/pages/get-started/direct-upload/) 与 [D1 入门](https://developers.cloudflare.com/d1/get-started/)。
|
|
66
|
-
|
|
67
|
-
```sh
|
|
68
|
-
npm ci
|
|
69
|
-
npx wrangler login
|
|
70
|
-
npx wrangler d1 create YOUR_DATABASE_NAME
|
|
71
|
-
npx wrangler r2 bucket create YOUR_ATTACHMENT_BUCKET
|
|
72
|
-
npx wrangler pages project create YOUR_PROJECT_NAME --production-branch main
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
如果 Wrangler 询问是否自动修改根配置,选择否;实际资源配置填写到下面的私有文件。创建已忽略的 `.wrangler/deploy/` 目录并复制模板,首次部署任选对应系统的命令:
|
|
76
|
-
|
|
77
|
-
Windows PowerShell:
|
|
78
|
-
|
|
79
|
-
```powershell
|
|
80
|
-
New-Item -ItemType Directory -Force -Path .wrangler/deploy
|
|
81
|
-
Copy-Item -LiteralPath wrangler.jsonc -Destination .wrangler/deploy/wrangler.jsonc
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
macOS / Linux:
|
|
85
|
-
|
|
86
|
-
```sh
|
|
87
|
-
mkdir -p .wrangler/deploy
|
|
88
|
-
cp wrangler.jsonc .wrangler/deploy/wrangler.jsonc
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
编辑 `.wrangler/deploy/wrangler.jsonc`,按下面结构填写实际项目名、数据库名和刚返回的 ID,同时调整两个相对路径:
|
|
92
|
-
|
|
93
|
-
```json
|
|
94
|
-
{
|
|
95
|
-
"$schema": "../../node_modules/wrangler/config-schema.json",
|
|
96
|
-
"name": "YOUR_PROJECT_NAME",
|
|
97
|
-
"pages_build_output_dir": "../../dist/pages",
|
|
98
|
-
"compatibility_date": "2026-10-14",
|
|
99
|
-
"d1_databases": [
|
|
100
|
-
{
|
|
101
|
-
"binding": "DB",
|
|
102
|
-
"database_name": "YOUR_DATABASE_NAME",
|
|
103
|
-
"database_id": "YOUR_DATABASE_ID"
|
|
104
|
-
}
|
|
105
|
-
],
|
|
106
|
-
"r2_buckets": [
|
|
107
|
-
{ "binding": "ATTACHMENTS", "bucket_name": "YOUR_ATTACHMENT_BUCKET" }
|
|
108
|
-
]
|
|
109
|
-
}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
`DB` 和 `ATTACHMENTS` 绑定名保持不变;输出路径和 `$schema` 相对于这份配置的位置。附件通过同站点路由读取,无需开启桶的公开域名;缺少 R2 绑定时文字讨论可用,上传返回 503。D1 备份只含附件元数据,站点恢复须同时保留 R2 对象;网页导出对话的 ZIP 包含已发送原文件。不要把个人资源配置覆盖回可提交模板。Wrangler Pages 不支持 `--config`,因此部署用 `--cwd .wrangler/deploy` 选择配置;D1 命令支持 `--config`。
|
|
113
|
-
|
|
114
|
-
### 初始化与部署
|
|
115
|
-
|
|
116
|
-
以下命令从仓库根目录运行,明确操作自己的远端数据库和站点:
|
|
117
|
-
|
|
118
|
-
```sh
|
|
119
|
-
npx wrangler d1 execute DB --remote --config .wrangler/deploy/wrangler.jsonc --file backend/schema.sql
|
|
120
|
-
npm run deploy -- --cwd .wrangler/deploy
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
管理员注册:Cloudflare 站点须先设置安装令牌机密,未设置则无法注册管理员:`npx wrangler pages secret put ADMIN_SETUP_KEY --project-name YOUR_PROJECT_NAME`。忘记密码时在 D1 执行 `DELETE FROM admin_sessions; DELETE FROM site_admin;` 后重新注册。
|
|
124
|
-
|
|
125
|
-
第一次对新库执行 schema;升级已有站点前先备份并在本地副本核验迁移。当前 schema
|
|
126
|
-
|
|
127
|
-
`deploy` 会先构建,再将 `dist/pages/` 发布到 `main`。配置为真值前不要直接运行根目录默认部署。构建本身不发布、不改远端数据库。Git 集成部署需自行将实际 D1 配置提供给构建环境,不能直接用公开模板当作生产配置。
|
|
128
|
-
|
|
129
|
-
发布后先打开返回的实际网址及 `/api/health`,确认网页可见且健康接口返回 `ok: true`。已安装统一 CLI 时,再用实际域名检查:
|
|
130
|
-
|
|
131
|
-
```sh
|
|
132
|
-
codiscuss health --site https://YOUR_PROJECT_NAME.pages.dev
|
|
133
|
-
codiscuss room list --site https://YOUR_PROJECT_NAME.pages.dev
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
未安装统一命令时可用 `python runner/discuss.py` 替换 `codiscuss`。同时打开网页与实际房间的 `/r/ROOM_ID`,检查静态资源、中文原文和读取链接。仅首页可见不能证明数据库或动态路由正常。
|
|
137
|
-
|
|
138
|
-
### 网页推送(可选)
|
|
139
|
-
|
|
140
|
-
Pages 的跨实例推送使用独立 Durable Object Worker;[Cloudflare 要求先部署该 Worker,再通过 `script_name` 绑定到 Pages](https://developers.cloudflare.com/pages/functions/bindings/#durable-objects)。原有 D1 业务与静态部署无需依赖它,未绑定时仍每 12 秒轮询。配置后改为写入通知驱动,另每 60 秒补读。
|
|
141
|
-
|
|
142
|
-
在仓库根目录明确部署通知 Worker:
|
|
143
|
-
|
|
144
|
-
```sh
|
|
145
|
-
npx wrangler deploy --config deploy/updates.wrangler.jsonc
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
配置默认名为 `ai-co-discuss-updates`,不开放 `workers.dev` 或预览 URL,也没有公开发布路由。需要自定义名称时使用自己的部署配置副本,并同步下面的 `script_name`。随后在已有 `.wrangler/deploy/wrangler.jsonc` 顶层加入:
|
|
149
|
-
|
|
150
|
-
```json
|
|
151
|
-
"durable_objects": {
|
|
152
|
-
"bindings": [
|
|
153
|
-
{ "name": "UPDATES", "class_name": "DiscussionUpdates", "script_name": "ai-co-discuss-updates" }
|
|
154
|
-
]
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
再按前节命令部署 Pages。使用不同 D1 数据库的生产与预览环境若共用这个 Worker,应分别设置 `vars.UPDATES_CHANNEL` 为不同值;同一数据库的 Pages 域名与自定义域名应使用同一值,缺省为 `default`。通知只含“数据已变化”,不包含讨论记录。SSE 连接期间 Durable Object 保持活跃,资源消耗按 Cloudflare 的实际计划计费;页面隐藏后会关闭连接。
|
|
159
|
-
|
|
160
|
-
部署后用两个浏览器标签打开同一讨论,在一处发送用户留言,另一处应自动出现;网络面板的 `/api/updates` 应为 `text/event-stream`,能看到 `ready` 和 `change`。断开再恢复网络后应补齐消息。没有配置绑定时返回 204 属于轮询兼容路径,不代表已启用推送。
|
|
161
|
-
|
|
162
|
-
## 构建产物与发布边界
|
|
163
|
-
|
|
164
|
-
`npm run build` 执行语法检查,构建 Markdown、备份和 Vue 三个入口,再运行 `scripts/build_pages.mjs`。输出包含网页、JS/CSS、内联字体、本地图标、404、robots、路由规则和唯一 `_worker.js`;`frontend/` 源码与隐藏文件不进入发布目录。`_routes.json` 仅让 `/api`、`/api/*`、`/r`、`/r/*` 调用 Function。
|
|
165
|
-
|
|
166
|
-
不要部署仓库根目录,那里含开发文件和潜在本地数据。`dist/pages/` 是可重复生成的发布目录,同时附带根许可证与第三方许可声明。更新 Vue 界面修改 `frontend/` 源码,再重新构建,不直接编辑产物。
|
|
167
|
-
|
|
168
|
-
## 常见问题
|
|
169
|
-
|
|
170
|
-
全自动接入的本机配置见下节;网站与软件接入程序分别部署。
|
|
171
|
-
|
|
172
|
-
- **`no such table`**:所连接的数据库尚未执行 schema;先核对本地/远端及配置文件,不能为消除错误随意执行到别的数据库。
|
|
173
|
-
- **本地网页正常、在线 AI 读不到**:回环地址、登录验证、域名访问策略均可能导致不可达。在专家实际环境中核对,必要时转交原始材料;不能凭浏览器成功推定远端 AI 可读。
|
|
174
|
-
- **CLI 请求超时但可能已保存**:按原提交编号查询,见 [CLI 写入核对](cli.md#写入核对与错误处理)。
|
|
175
|
-
- **端口占用**:服务拒绝两个实例监听同一端口;选择其他端口,并同步实际 `--site`。Windows 也采用独占绑定,避免两个实例返回不同数据库的数据;不要停止未确认归属的进程。
|
|
176
|
-
- **重新构建后页面未变化**:确认服务目录和发布产物,浏览器刷新;不要据旧标签页判断构建失败。
|
|
177
|
-
|
|
178
|
-
## 可选的全自动接入
|
|
179
|
-
|
|
180
|
-
本机使用可直接通过 `codiscuss local open` 打开网页启动入口,或在 AI 对话中调用主持 Skill 使用 `codiscuss launch start`。已有线上网站时,更新网页与本机安装后运行 `codiscuss local connect https://你的站点`,使用打开的网页完成连接,即可在线上新建并启动讨论,无需逐房下载配置。浏览器与 AI 须在同一台电脑;连接与权限说明见 [线上网页连接本机](runner.md#线上网页连接本机)。各入口共用本机默认配置与单场覆盖。以下手动导出与登记方式继续适用于未连接的浏览器或已有配置。
|
|
181
|
-
|
|
182
|
-
接入程序随本仓库提供,无需安装其他项目。网页可以运行在本机或 Cloudflare,常驻服务与实际 AI 软件仍运行在你的电脑;网站不启动本机进程。服务需要 Node.js 24+,AI 通过 CLI 读写网站另需 Python 3.10+。Python 网站启动时自动应用 schema;升级 D1 必须先在测试库核对,再由部署者执行 schema,不能只更新网页资源。
|
|
183
|
-
|
|
184
|
-
### 安装、登记与启动服务
|
|
185
|
-
|
|
186
|
-
在仓库根目录安装一次统一命令;已经安装依赖时无需重复 `npm ci`:
|
|
187
|
-
|
|
188
|
-
```sh
|
|
189
|
-
npm ci
|
|
190
|
-
npm link
|
|
191
|
-
codiscuss --help
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
1. 在房间“接入”选择“全自动讨论”,按需填写讨论所属项目和 cwd,点击“下载接入配置”。选择本身不会开始讨论。
|
|
195
|
-
2. 填写参与软件路径和会话/项目绑定;`cli_project` 可删除,默认使用本仓库。`discussion_project` 与 `cwd` 都允许省略;各参与者可覆盖。详细 JSON 和软件差异见 [自动接入程序](runner.md)。
|
|
196
|
-
3. Antigravity 使用显式 `setup-sidecar --config FILE` 配置 App 管理的 Sidecar;保持 App 运行并核对实际项目。Codex 新建需实际来源聊天 ID,可绑定当前主持会话;Claude 使用已登录的官方 Code CLI,工具许可由本机配置提供。
|
|
197
|
-
4. 将 `PRIVATE.json` 替换为补齐后的私有配置实际路径,在任意目录登记房间并启动服务:
|
|
198
|
-
|
|
199
|
-
```sh
|
|
200
|
-
codiscuss service add --config "PRIVATE.json"
|
|
201
|
-
codiscuss
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
相对路径以终端当前目录为准,建议传完整路径。配置文件登记后保留在原位置,包含本房间控制凭据,不上传或提交。前台运行需保持终端打开,`Ctrl+C` 会暂停托管中的讨论并退出。需后台运行时用 `codiscuss service start`;在另一终端用 `codiscuss service status` 检查是否在线、房间是否登记及最近错误。安装、登录自启、移除登记和卸载命令见 [常驻讨论服务](runner.md#常驻讨论服务)。
|
|
205
|
-
|
|
206
|
-
### 首次启动房间
|
|
207
|
-
|
|
208
|
-
服务运行后,在网页先设置有限总时长(例如 60 分钟),并确认主持和专家都为本地 CLI。保持服务终端打开,在另一终端用统一 CLI 读取最新运行版本,再明确开始:
|
|
209
|
-
|
|
210
|
-
```sh
|
|
211
|
-
codiscuss run view ROOM --site SITE
|
|
212
|
-
codiscuss run start ROOM --site SITE --revision REV --access-file "PRIVATE.json"
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
`ROOM` 和 `SITE` 分别替换为配置中的 `room`、`site`;`REV` 替换为刚才查询返回的 `data.revision`。`PRIVATE.json` 使用登记时的同一份私有配置。网站命令只改变房间运行状态,由已运行的常驻服务消费事件并唤醒 AI。
|
|
216
|
-
|
|
217
|
-
网页“重启”按钮用于已暂停或到期的自动讨论;尚未启动的新房间使用上述命令。超过既定上限时先调整上限再继续。`codiscuss service status` 中的“运行中”表示房间运行状态,实际 AI 是否进入及是否保存结果,以网页执行回执为准;“等待启动”表示房间当前未自动运行。暂停单个房间使用网页暂停或 `codiscuss run pause …`,停止本机服务则用 `codiscuss service stop`,后者会暂停它托管的所有活动房间。
|
|
218
|
-
|
|
219
|
-
轮次、时长及单次执行上限由网站保存并校验;到限后讨论结束,房间回到自由协作。准备/暂停阶段可编辑参数,保存不重新计时。运行控制字段见 [CLI 使用](cli.md#运行控制与一次执行)。
|
|
220
|
-
|
|
221
|
-
需要单个房间运行而不使用常驻服务时,可在仓库执行 `npm run runner -- start --config FILE --minutes 60`;`watch` 仅恢复事件消费,不恢复已暂停房间。`--minutes` 可省略并采用网页总时长,0 表示不另设运行期限;同时设置时取更早的非零截止。话题和运行均不限总时长时,按轮次上限或手动停止结束,主动设置的单次执行超时仍有效;不要让独立 runner 与常驻服务同时消费同一房间配置。
|
|
222
|
-
|
|
223
|
-
自动模式可连接运行中的 Codex App、Antigravity App,或按需启动 Claude Code CLI、Codex CLI、Antigravity CLI(`agy`)。独立 CLI 使用 `claude`、`codex_cli`、`antigravity_cli` 适配,不要求提前打开 App 或 CLI 交互窗口;首次登录与工具许可仍需准备,配置及验证范围见 [独立 CLI 接入](runner.md#独立-cli-接入)。App 关闭、账号失效或权限等待不能算作已开始;已交付任务等待实际进入,不因聊天忙碌重复新建,等待仍受整场截止约束。接入程序退出、断网或崩溃后,旧执行最多在剩余租约内写入;恢复前核对原会话,过期资格不会重新激活。重试和停止规则见 [自动接入程序](runner.md)。
|
|
224
|
-
|
|
225
|
-
手动兜底:由房主暂停并核对原执行停止后,切换手动接入;复制原接入指令,在原会话继续。每位本地成员使用自己的私有文件作为 `--access-file`,不能使用房主文件署名,也不把 token 放进复制文本。公开房间不保存本机目录、软件账号或配置文件。
|
|
1
|
+
# 部署指南
|
|
2
|
+
|
|
3
|
+
本地 Python / SQLite 与 Cloudflare Pages / D1 提供同样的讨论接口。二选一即可,数据库彼此独立,不自动同步。
|
|
4
|
+
|
|
5
|
+
当前服务没有用户登录和读取权限隔离;所有新房间都要求房主或成员写入凭据。先阅读 [安全说明](../.github/SECURITY.md),再决定是否暴露到公网。外部访问控制也可能阻止在线 AI 读取;此时按工作流转交必要材料。
|
|
6
|
+
|
|
7
|
+
## Python 服务
|
|
8
|
+
|
|
9
|
+
通过 [npm 安装配置](runner.md#npm-安装与本机配置) 的本机用户可直接 `codiscuss local open`,它使用包内网页、已配置 Python 和包外持久数据库,同时启用仅限回环的网页启动入口。以下参数适用于直接运行源码或独立部署;两种路径的数据位置不同,不自动迁移。
|
|
10
|
+
|
|
11
|
+
Python 3.10+,无第三方 Python 依赖。前端已经随仓库提供;修改源码后在 Node.js 24+ 环境中重新构建:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm ci
|
|
15
|
+
npm run build:ui
|
|
16
|
+
python server.py --host 127.0.0.1 --port 8765 --no-demo
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
| 选项 | 环境变量 | 默认值 |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| `--host` | `HOST` | `127.0.0.1` |
|
|
22
|
+
| `--port` | `PORT` | `8765` |
|
|
23
|
+
| `--database` | `DATABASE_PATH` | 项目 `data/discuss.sqlite3` |
|
|
24
|
+
| `--no-demo` | 无 | 不传时在新数据库写入带示例标记的欢迎记录 |
|
|
25
|
+
| `--local-launch` | 无 | 显式开启本机软件配置与网页启动,仅允许绑定 127.0.0.1,需 Node.js 24+ |
|
|
26
|
+
|
|
27
|
+
命令行参数优先于环境变量。使用独立测试库可加 `--database data/test.sqlite3`。停止后重新启动沿用原库;`--no-demo` 不清理已有数据。长期部署应使用自己的进程管理和反向代理提供 HTTPS,按需要限制访问与请求规模。
|
|
28
|
+
|
|
29
|
+
管理员账号:绑定 127.0.0.1 时无需账号,访问者即管理员,可存档、恢复、永久删除任意房间。绑定其他地址(如 `--host 0.0.0.0`)时须注册:首次打开网站在左下角注册,需要安装令牌。环境变量 `DISCUSS_ADMIN_SETUP_KEY` 可固定令牌,未设置时每次启动随机生成并写入启动日志(仅在尚未注册时打印)。注册后可存档、恢复、永久删除任意房间;忘记密码运行 `python server.py --reset-admin`(不停服务也可执行)后重新注册。
|
|
30
|
+
|
|
31
|
+
网页 SSE 推送在 Python 服务中默认启用,无需额外进程或数据库迁移。反向代理应关闭 `/api/updates` 的响应缓冲并允许长连接;服务每 15 秒发送心跳。页面隐藏时断开,重新打开后补取最新数据;代理不支持推送时回退轮询。
|
|
32
|
+
|
|
33
|
+
附件保存在数据库旁的 `<数据库文件名>.attachments/`,例如 `data/discuss.sqlite3.attachments/`;Docker 中同样位于数据卷内。备份时先停止对应写入进程,再一并复制数据库和附件目录;只备份 SQLite 不包含原文件。无附件时也可用 SQLite 的在线备份工具生成一致快照,不要仅复制正在写入的主文件而遗漏 WAL。恢复前保留原库和附件目录,再用 `--database` 指向恢复副本核验。
|
|
34
|
+
|
|
35
|
+
## Docker
|
|
36
|
+
|
|
37
|
+
仓库自带前端产物,直接用 Docker 即可启动;只有修改前端源码后才需要先执行 `npm ci` 和 `npm run build:ui`。在仓库根目录显式指定 `deploy/Dockerfile`,镜像只复制服务、schema、许可证和运行资源:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
docker build -f deploy/Dockerfile -t ai-co-discuss .
|
|
41
|
+
docker volume create ai-co-discuss-data
|
|
42
|
+
docker run --name ai-co-discuss -p 127.0.0.1:8765:8765 -v ai-co-discuss-data:/data ai-co-discuss
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
镜像以非 root 用户运行,默认空库;持久数据位于命名卷 `/data`,容器删除不代表卷已删除。此处只绑定本机端口,需要远程访问时由部署者配置反向代理与访问边界。
|
|
46
|
+
|
|
47
|
+
`deploy/Dockerfile.dockerignore` 按 [Docker 的专用排除文件约定](https://docs.docker.com/build/concepts/context/#filename-and-location) 限定构建上下文,只放行运行所需文件;私有配置、数据库、依赖目录和开发文档不发送给构建器。
|
|
48
|
+
|
|
49
|
+
## Cloudflare Pages + Functions + D1
|
|
50
|
+
|
|
51
|
+
采用 Pages advanced mode:`backend/worker.mjs` 打包成 `_worker.js`,直接绑定 D1 的 `DB`。没有外部 Worker service binding,也不需要 Nuxt 服务端。配置依据见 [Cloudflare Pages Wrangler 文档](https://developers.cloudflare.com/pages/functions/wrangler-configuration/)。
|
|
52
|
+
|
|
53
|
+
### 本地预览
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
npm ci
|
|
57
|
+
npm run db:local
|
|
58
|
+
npm run dev
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
打开 <http://127.0.0.1:8787>。本地 D1 状态位于 `.wrangler/`,与 Python 数据库独立。根目录 `wrangler.jsonc` 是可提交的模板,数据库 ID 为占位值;本地模拟不访问远端数据库。
|
|
62
|
+
|
|
63
|
+
### 创建自己的部署配置
|
|
64
|
+
|
|
65
|
+
首次部署需要 Node.js 24+、npm 和 Cloudflare 账号。先克隆仓库并进入根目录,再执行以下命令安装依赖、登录并创建自己的云资源;将占位名称替换为实际名称。相关平台步骤见 [Pages 直接上传](https://developers.cloudflare.com/pages/get-started/direct-upload/) 与 [D1 入门](https://developers.cloudflare.com/d1/get-started/)。
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
npm ci
|
|
69
|
+
npx wrangler login
|
|
70
|
+
npx wrangler d1 create YOUR_DATABASE_NAME
|
|
71
|
+
npx wrangler r2 bucket create YOUR_ATTACHMENT_BUCKET
|
|
72
|
+
npx wrangler pages project create YOUR_PROJECT_NAME --production-branch main
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
如果 Wrangler 询问是否自动修改根配置,选择否;实际资源配置填写到下面的私有文件。创建已忽略的 `.wrangler/deploy/` 目录并复制模板,首次部署任选对应系统的命令:
|
|
76
|
+
|
|
77
|
+
Windows PowerShell:
|
|
78
|
+
|
|
79
|
+
```powershell
|
|
80
|
+
New-Item -ItemType Directory -Force -Path .wrangler/deploy
|
|
81
|
+
Copy-Item -LiteralPath wrangler.jsonc -Destination .wrangler/deploy/wrangler.jsonc
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
macOS / Linux:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
mkdir -p .wrangler/deploy
|
|
88
|
+
cp wrangler.jsonc .wrangler/deploy/wrangler.jsonc
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
编辑 `.wrangler/deploy/wrangler.jsonc`,按下面结构填写实际项目名、数据库名和刚返回的 ID,同时调整两个相对路径:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"$schema": "../../node_modules/wrangler/config-schema.json",
|
|
96
|
+
"name": "YOUR_PROJECT_NAME",
|
|
97
|
+
"pages_build_output_dir": "../../dist/pages",
|
|
98
|
+
"compatibility_date": "2026-10-14",
|
|
99
|
+
"d1_databases": [
|
|
100
|
+
{
|
|
101
|
+
"binding": "DB",
|
|
102
|
+
"database_name": "YOUR_DATABASE_NAME",
|
|
103
|
+
"database_id": "YOUR_DATABASE_ID"
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"r2_buckets": [
|
|
107
|
+
{ "binding": "ATTACHMENTS", "bucket_name": "YOUR_ATTACHMENT_BUCKET" }
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`DB` 和 `ATTACHMENTS` 绑定名保持不变;输出路径和 `$schema` 相对于这份配置的位置。附件通过同站点路由读取,无需开启桶的公开域名;缺少 R2 绑定时文字讨论可用,上传返回 503。D1 备份只含附件元数据,站点恢复须同时保留 R2 对象;网页导出对话的 ZIP 包含已发送原文件。不要把个人资源配置覆盖回可提交模板。Wrangler Pages 不支持 `--config`,因此部署用 `--cwd .wrangler/deploy` 选择配置;D1 命令支持 `--config`。
|
|
113
|
+
|
|
114
|
+
### 初始化与部署
|
|
115
|
+
|
|
116
|
+
以下命令从仓库根目录运行,明确操作自己的远端数据库和站点:
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
npx wrangler d1 execute DB --remote --config .wrangler/deploy/wrangler.jsonc --file backend/schema.sql
|
|
120
|
+
npm run deploy -- --cwd .wrangler/deploy
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
管理员注册:Cloudflare 站点须先设置安装令牌机密,未设置则无法注册管理员:`npx wrangler pages secret put ADMIN_SETUP_KEY --project-name YOUR_PROJECT_NAME`。忘记密码时在 D1 执行 `DELETE FROM admin_sessions; DELETE FROM site_admin;` 后重新注册。
|
|
124
|
+
|
|
125
|
+
第一次对新库执行 schema;升级已有站点前先备份并在本地副本核验迁移。当前 schema 以增量表、索引和触发器扩展数据结构,重复执行不应清空已有记录;仍需按实际升级版本测试。`CREATE TABLE IF NOT EXISTS` 不会给已有表补列:Python 服务启动时自动补自由房间的新列,D1 需手动执行,例如执行进度两列:`ALTER TABLE member_executions ADD COLUMN activity TEXT NOT NULL DEFAULT ''` 与 `ALTER TABLE member_executions ADD COLUMN activity_at INTEGER NOT NULL DEFAULT 0`。新增的表(如过程说明 `execution_notes`)重新执行 `backend/schema.sql` 即可创建。
|
|
126
|
+
|
|
127
|
+
`deploy` 会先构建,再将 `dist/pages/` 发布到 `main`。配置为真值前不要直接运行根目录默认部署。构建本身不发布、不改远端数据库。Git 集成部署需自行将实际 D1 配置提供给构建环境,不能直接用公开模板当作生产配置。
|
|
128
|
+
|
|
129
|
+
发布后先打开返回的实际网址及 `/api/health`,确认网页可见且健康接口返回 `ok: true`。已安装统一 CLI 时,再用实际域名检查:
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
codiscuss health --site https://YOUR_PROJECT_NAME.pages.dev
|
|
133
|
+
codiscuss room list --site https://YOUR_PROJECT_NAME.pages.dev
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
未安装统一命令时可用 `python runner/discuss.py` 替换 `codiscuss`。同时打开网页与实际房间的 `/r/ROOM_ID`,检查静态资源、中文原文和读取链接。仅首页可见不能证明数据库或动态路由正常。
|
|
137
|
+
|
|
138
|
+
### 网页推送(可选)
|
|
139
|
+
|
|
140
|
+
Pages 的跨实例推送使用独立 Durable Object Worker;[Cloudflare 要求先部署该 Worker,再通过 `script_name` 绑定到 Pages](https://developers.cloudflare.com/pages/functions/bindings/#durable-objects)。原有 D1 业务与静态部署无需依赖它,未绑定时仍每 12 秒轮询。配置后改为写入通知驱动,另每 60 秒补读。
|
|
141
|
+
|
|
142
|
+
在仓库根目录明确部署通知 Worker:
|
|
143
|
+
|
|
144
|
+
```sh
|
|
145
|
+
npx wrangler deploy --config deploy/updates.wrangler.jsonc
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
配置默认名为 `ai-co-discuss-updates`,不开放 `workers.dev` 或预览 URL,也没有公开发布路由。需要自定义名称时使用自己的部署配置副本,并同步下面的 `script_name`。随后在已有 `.wrangler/deploy/wrangler.jsonc` 顶层加入:
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
"durable_objects": {
|
|
152
|
+
"bindings": [
|
|
153
|
+
{ "name": "UPDATES", "class_name": "DiscussionUpdates", "script_name": "ai-co-discuss-updates" }
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
再按前节命令部署 Pages。使用不同 D1 数据库的生产与预览环境若共用这个 Worker,应分别设置 `vars.UPDATES_CHANNEL` 为不同值;同一数据库的 Pages 域名与自定义域名应使用同一值,缺省为 `default`。通知只含“数据已变化”,不包含讨论记录。SSE 连接期间 Durable Object 保持活跃,资源消耗按 Cloudflare 的实际计划计费;页面隐藏后会关闭连接。
|
|
159
|
+
|
|
160
|
+
部署后用两个浏览器标签打开同一讨论,在一处发送用户留言,另一处应自动出现;网络面板的 `/api/updates` 应为 `text/event-stream`,能看到 `ready` 和 `change`。断开再恢复网络后应补齐消息。没有配置绑定时返回 204 属于轮询兼容路径,不代表已启用推送。
|
|
161
|
+
|
|
162
|
+
## 构建产物与发布边界
|
|
163
|
+
|
|
164
|
+
`npm run build` 执行语法检查,构建 Markdown、备份和 Vue 三个入口,再运行 `scripts/build_pages.mjs`。输出包含网页、JS/CSS、内联字体、本地图标、404、robots、路由规则和唯一 `_worker.js`;`frontend/` 源码与隐藏文件不进入发布目录。`_routes.json` 仅让 `/api`、`/api/*`、`/r`、`/r/*` 调用 Function。
|
|
165
|
+
|
|
166
|
+
不要部署仓库根目录,那里含开发文件和潜在本地数据。`dist/pages/` 是可重复生成的发布目录,同时附带根许可证与第三方许可声明。更新 Vue 界面修改 `frontend/` 源码,再重新构建,不直接编辑产物。
|
|
167
|
+
|
|
168
|
+
## 常见问题
|
|
169
|
+
|
|
170
|
+
全自动接入的本机配置见下节;网站与软件接入程序分别部署。
|
|
171
|
+
|
|
172
|
+
- **`no such table`**:所连接的数据库尚未执行 schema;先核对本地/远端及配置文件,不能为消除错误随意执行到别的数据库。
|
|
173
|
+
- **本地网页正常、在线 AI 读不到**:回环地址、登录验证、域名访问策略均可能导致不可达。在专家实际环境中核对,必要时转交原始材料;不能凭浏览器成功推定远端 AI 可读。
|
|
174
|
+
- **CLI 请求超时但可能已保存**:按原提交编号查询,见 [CLI 写入核对](cli.md#写入核对与错误处理)。
|
|
175
|
+
- **端口占用**:服务拒绝两个实例监听同一端口;选择其他端口,并同步实际 `--site`。Windows 也采用独占绑定,避免两个实例返回不同数据库的数据;不要停止未确认归属的进程。
|
|
176
|
+
- **重新构建后页面未变化**:确认服务目录和发布产物,浏览器刷新;不要据旧标签页判断构建失败。
|
|
177
|
+
|
|
178
|
+
## 可选的全自动接入
|
|
179
|
+
|
|
180
|
+
本机使用可直接通过 `codiscuss local open` 打开网页启动入口,或在 AI 对话中调用主持 Skill 使用 `codiscuss launch start`。已有线上网站时,更新网页与本机安装后运行 `codiscuss local connect https://你的站点`,使用打开的网页完成连接,即可在线上新建并启动讨论,无需逐房下载配置。浏览器与 AI 须在同一台电脑;连接与权限说明见 [线上网页连接本机](runner.md#线上网页连接本机)。各入口共用本机默认配置与单场覆盖。以下手动导出与登记方式继续适用于未连接的浏览器或已有配置。
|
|
181
|
+
|
|
182
|
+
接入程序随本仓库提供,无需安装其他项目。网页可以运行在本机或 Cloudflare,常驻服务与实际 AI 软件仍运行在你的电脑;网站不启动本机进程。服务需要 Node.js 24+,AI 通过 CLI 读写网站另需 Python 3.10+。Python 网站启动时自动应用 schema;升级 D1 必须先在测试库核对,再由部署者执行 schema,不能只更新网页资源。
|
|
183
|
+
|
|
184
|
+
### 安装、登记与启动服务
|
|
185
|
+
|
|
186
|
+
在仓库根目录安装一次统一命令;已经安装依赖时无需重复 `npm ci`:
|
|
187
|
+
|
|
188
|
+
```sh
|
|
189
|
+
npm ci
|
|
190
|
+
npm link
|
|
191
|
+
codiscuss --help
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
1. 在房间“接入”选择“全自动讨论”,按需填写讨论所属项目和 cwd,点击“下载接入配置”。选择本身不会开始讨论。
|
|
195
|
+
2. 填写参与软件路径和会话/项目绑定;`cli_project` 可删除,默认使用本仓库。`discussion_project` 与 `cwd` 都允许省略;各参与者可覆盖。详细 JSON 和软件差异见 [自动接入程序](runner.md)。
|
|
196
|
+
3. Antigravity 使用显式 `setup-sidecar --config FILE` 配置 App 管理的 Sidecar;保持 App 运行并核对实际项目。Codex 新建需实际来源聊天 ID,可绑定当前主持会话;Claude 使用已登录的官方 Code CLI,工具许可由本机配置提供。
|
|
197
|
+
4. 将 `PRIVATE.json` 替换为补齐后的私有配置实际路径,在任意目录登记房间并启动服务:
|
|
198
|
+
|
|
199
|
+
```sh
|
|
200
|
+
codiscuss service add --config "PRIVATE.json"
|
|
201
|
+
codiscuss
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
相对路径以终端当前目录为准,建议传完整路径。配置文件登记后保留在原位置,包含本房间控制凭据,不上传或提交。前台运行需保持终端打开,`Ctrl+C` 会暂停托管中的讨论并退出。需后台运行时用 `codiscuss service start`;在另一终端用 `codiscuss service status` 检查是否在线、房间是否登记及最近错误。安装、登录自启、移除登记和卸载命令见 [常驻讨论服务](runner.md#常驻讨论服务)。
|
|
205
|
+
|
|
206
|
+
### 首次启动房间
|
|
207
|
+
|
|
208
|
+
服务运行后,在网页先设置有限总时长(例如 60 分钟),并确认主持和专家都为本地 CLI。保持服务终端打开,在另一终端用统一 CLI 读取最新运行版本,再明确开始:
|
|
209
|
+
|
|
210
|
+
```sh
|
|
211
|
+
codiscuss run view ROOM --site SITE
|
|
212
|
+
codiscuss run start ROOM --site SITE --revision REV --access-file "PRIVATE.json"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`ROOM` 和 `SITE` 分别替换为配置中的 `room`、`site`;`REV` 替换为刚才查询返回的 `data.revision`。`PRIVATE.json` 使用登记时的同一份私有配置。网站命令只改变房间运行状态,由已运行的常驻服务消费事件并唤醒 AI。
|
|
216
|
+
|
|
217
|
+
网页“重启”按钮用于已暂停或到期的自动讨论;尚未启动的新房间使用上述命令。超过既定上限时先调整上限再继续。`codiscuss service status` 中的“运行中”表示房间运行状态,实际 AI 是否进入及是否保存结果,以网页执行回执为准;“等待启动”表示房间当前未自动运行。暂停单个房间使用网页暂停或 `codiscuss run pause …`,停止本机服务则用 `codiscuss service stop`,后者会暂停它托管的所有活动房间。
|
|
218
|
+
|
|
219
|
+
轮次、时长及单次执行上限由网站保存并校验;到限后讨论结束,房间回到自由协作。准备/暂停阶段可编辑参数,保存不重新计时。运行控制字段见 [CLI 使用](cli.md#运行控制与一次执行)。
|
|
220
|
+
|
|
221
|
+
需要单个房间运行而不使用常驻服务时,可在仓库执行 `npm run runner -- start --config FILE --minutes 60`;`watch` 仅恢复事件消费,不恢复已暂停房间。`--minutes` 可省略并采用网页总时长,0 表示不另设运行期限;同时设置时取更早的非零截止。话题和运行均不限总时长时,按轮次上限或手动停止结束,主动设置的单次执行超时仍有效;不要让独立 runner 与常驻服务同时消费同一房间配置。
|
|
222
|
+
|
|
223
|
+
自动模式可连接运行中的 Codex App、Antigravity App,或按需启动 Claude Code CLI、Codex CLI、Antigravity CLI(`agy`)。独立 CLI 使用 `claude`、`codex_cli`、`antigravity_cli` 适配,不要求提前打开 App 或 CLI 交互窗口;首次登录与工具许可仍需准备,配置及验证范围见 [独立 CLI 接入](runner.md#独立-cli-接入)。App 关闭、账号失效或权限等待不能算作已开始;已交付任务等待实际进入,不因聊天忙碌重复新建,等待仍受整场截止约束。接入程序退出、断网或崩溃后,旧执行最多在剩余租约内写入;恢复前核对原会话,过期资格不会重新激活。重试和停止规则见 [自动接入程序](runner.md)。
|
|
224
|
+
|
|
225
|
+
手动兜底:由房主暂停并核对原执行停止后,切换手动接入;复制原接入指令,在原会话继续。每位本地成员使用自己的私有文件作为 `--access-file`,不能使用房主文件署名,也不把 token 放进复制文本。公开房间不保存本机目录、软件账号或配置文件。
|