一句话
App 里只做「一个会播的壳」,画面和规则全部由服务器下发。 以后新增一个 Tool = 往一张表插一行 + 传一份网页,不用重新出 App 包。
他的原话(2026-08-28 22:26 语音,本地 Whisper 转的)
之前那两条把方向定死的话也在同一段对话里:
- 22:23:05 —— 「我是要以后可以直接加载,不用去 build 呀… 不是更好?」
- 22:35:04 —— 「@Gode 你别动代码,但详细告诉 Tora 怎么写」;Gode 随后给了字段清单,这份图纸照着落的。
TOOS,
可能是 Tools(工具) 也可能是 Toss(往屏幕上丢) —— 这两个做出来是两样东西。
问了一句,他回「tools」。猜错的代价是整套白做,问一句是 30 秒。三层模型
整件事只有三层,每一层只知道自己那一份。这是为了让「加一个新玩法」不需要动前两层。
互动怎么走
猜拳这种「你点一下、我点一下」的,事件不直连,一律经后端转:
分工:判据在一边,转发在另一边
| 问题 | 谁答得了 | 住在哪 |
|---|---|---|
| 这个 Tool 是不是 live?序号重放了没?这一分钟几条了? | 只有 Tools 这个域知道 | domain/chattool |
| 这条要转给谁?他是这间会话的人吗? | 只有消息/会话域知道 | domain/message |
两边各答自己知道的那一半,谁都不用抄对方的表(铁律 23)。 合成一处的话,总有一边要复制另一边的数据,而复制出来的那份一定会腐。
已经做好的 已落地
两刀:e00bd1fb(后端)· 5788e95a(App,v1.442)。
后端 —— 已上生产
| 东西 | 在哪 | 证据 |
|---|---|---|
目录表 chat_tools | migrations/000310_chat_tools.up.sql | 生产库 select version,dirty → 310 | f;18 个列都在 |
GET /v1/tools | domain/chattool/handler.go:21 | 打真接口 HTTP 200 {"tools":[]} |
| 读目录 | domain/chattool/chattool.go:109 ListLive | 只返回 status='live' |
| 转发判据 | chattool.go:203 AllowEvent · :163 ValidateShape · :229 allowRate · :258 bumpSeq | Go 单测 + 3 把坏刀 |
| WS 那条路 | domain/message/handler.go:1087 case "tool.event" |
生产二进制里 tool.event 命中 2 处 |
| 转给谁 | domain/message/tool_relay.go:34 RelayToolEvent | — |
| 接线 | server/router.go:111-112 · :485-491 | — |
App —— 写好了,但真机上还看不到
| 东西 | 在哪 |
|---|---|
| 容器 | app/lib/widgets/chat_tool_layer.dart:43 ChatToolLayer · :231 showChatTool |
| 同源闸(纯函数,能穷举测) | chat_tool_layer.dart:31 toolUrlAllowed |
| 目录模型 | app/lib/models.dart:2196 ChatTool |
| 取目录 | app/lib/api/api_client.dart:916 chatTools() |
验过什么、没验过什么
go build ./... / go vet ./... 全绿;
Go 侧 8 组用例、App 侧 11 条用例全绿;flutter analyze 0 issue;
9 把「故意弄坏」的刀,每把都红在该红的那一条(见⑤)。trigger 改成了
trigger_mode(TRIGGER 是 PostgreSQL 的关键字)。怎么写一个 Tool
写一份单文件网页就够了。它在容器里跑,能用的东西只有下面这三句。
目录里那一行长这样
| 字段 | 意思 | 写错了会怎样 |
|---|---|---|
id | 短名,只收英数和 - _ | 带冒号/斜杠会被拒(它要进 Redis 键名) |
version | 换了内容就 +1 | 不加 = 用户手机上还是旧的那份 |
entry_url | 网页地址。同时就是白名单 | 必须 https |
width/height | 0 = 铺满聊天画面;>0 = 一块浮层(dp) | — |
duration_ms | >0 = 到点自动收;0 = 用户自己关 | 铺满的那种不给上限 = 挡住对方的聊天 |
trigger_mode | send 发出去双方就播 / tap 点了才开 / manual 只从「+」开 | 认不得的值客户端一律当 tap(最保守那个) |
interactive | 要不要双方同步 | false 的后端一条事件都不转 |
perms | 能力白名单,默认空 | 相机/通讯录不在可选项里,不是"默认关" |
status | draft / live / off | 只有 live 进目录、只有 live 转事件 |
页面里能用的三句(经 /tools/_kit.js,2026-08-29 命名审读后的定稿)
为什么隔一层 kit(它就 40 行):以前页面直接喊
window.flutter_inappwebview.callHandler ——
框架名漏进每份工具页,容器哪天换实现,所有页一起崩。现在框架名只活在 kit 一份文件里。
_recv 是容器递事件的内部口,工具页别碰;正门是 onEvent。instance_id 由开局方铸(UUID) —— 它是「这一局」,不是「这个 Tool」。
上架一个 Tool 的三步
- 把网页传到 Tools 专属静态站:
hoop-games 仓 tools/ → ./tools/deploy_tools.sh → hoop-tools.pages.dev(08-29 从游戏部署分家 —— 游戏的版本化铸号要令牌,Tools 没有版本化,不该被那把钥匙挡路;脚本自带逐网址核 sha) - 往
chat_tools插一行,status='draft'先自己试 - 改成
status='live'—— 用户下次打开聊天就有了,不用出包
五道闸
每一道后面那句「不装会怎样」才是它存在的理由。 五道全都有「故意弄坏 → 确认它真报红」的记录。
先看一眼:谁守哪道(2026-08-29 补,Lisa 问「怎么一会五道一会四道」问出来的)
| 闸 | 谁守 | 住在哪 |
|---|---|---|
| ① 同源 | 客户端 | chat_tool_layer.dart 的 toolUrlAllowed(纯函数,穷举测) |
| ② 权限拒 | 客户端 | onPermissionRequest 一律 DENY |
| ③ 到点收 | 客户端 | duration_ms 定时器(收自己那条 route,不是 maybePop —— 坏刀 11) |
| ④ 一局一次 | 两边 | 客户端 _openInstances 去重 + 后端序号线 |
| ⑤ 后端四条 | 后端 | chattool/gate.go(sender 后端填 · 序号前进 · 限流 · live 才转) |
| ⑤′ 收侧会话校验 | 客户端 | 收事件 instance 和会话都要对上(坏刀 10 —— 08-29 审读补的洞) |
| ①′ 子资源 | 客户端 | fetch / XHR 跨源一律 ABORT(09-02 审读补:光拦导航拦不住页面偷偷往外 POST)。管不到 <img>/<script src>/WebSocket —— WebView 不给钩子,真要堵死要走原生拦截,先如实写在这 |
| ⑤″ 发卡限流 | 后端 | AllowCard 复用事件的 allowRate,每 Tool 每人每分钟(09-02 补:send 类自动盖屏,不限流=按住小猫泼到天荒地老),超了回 429 |
① 只准去它自己那个源
白名单不是另一张表 —— 就是这一行的 entry_url 自己的源。
协议 + 主机 + 端口三样都一样才放行;子域名不算。
http:// · javascript: · file:// · data: · about: 全拦。
location.href 就能把整块画面换成别人的站,
而在手机上看起来完全正常(它照样是一个网页窗)。entry_url 同步,
漏了的表现是这个 Tool 白屏,而且零报错。同一件事只能有一个出处(铁律 23)。② 权限一律拒
相机 / 麦克风 / 定位一律 DENY,不许自己开新窗口,读不了本地文件。
③ 到点自己收
④ 同一局只开一次
「这一局」用 instance_id 认,不是用 Tool 的编号认。
而
instance_id 认错了同样出事: 用 Tool 编号的话,同一间房先后开两局,
第二局的第 1 手会被当成第一局的重放丢掉。⑤ 后端那四条
| 闸 | 不装会怎样 |
|---|---|
| 「谁发的」由后端填 | 谁都能冒充对方出拳,两边界面都不报错 |
| 序号必须往前走(每人每局各一条线) | 抓一条「我出石头」重发十遍,对面收到十次 合成一条线的话:你出拳会被判成我的重放,对面永远等不到 |
| 必须是这间会话的成员 | 拿到别人的会话号就能往里灌事件(路人替你出拳) |
| 不互动的 Tool 一条都不转 | 「转了也没人用」的路,就是没人盯着的滥用面 |
坏刀记录(15 把,每把红在该红的那一条)
第 12~15 把(2026-09-02 二次审读,Lisa「细节是不是做的不好」): 12 同一局重开手数从头数 → 后端判重放静默丢(修:按 instance 记在类外 + 时间戳兜底); 13 发卡第 11 张不被拒(修:AllowCard 接 allowRate,429); 14 停在第 3 页时工具变少,页码越界炸屏(修:页码回夹。当时的容器是 IndexedStack,2026-09-11 换成跟手滑动的 Stack 后回夹照旧要做 —— 越界的是页码,不是容器); 15 打点 conversation_id 畸形串(LooksUUID,不像的存 NULL)。另有一处没法用刀量的:闸① 补 fetch/XHR 拦截。
| 把哪儿弄坏 | 哪条守卫报红 |
|---|---|
| 拆掉重放检查 | Replay |
| 序号键里不带发件人 | SeqIsPerSender |
| 放行不互动的 Tool | Rejections/不互动 |
| 不查会话成员 | RelayToolEvent_Guards |
| sender_id 改成信客户端报的 | SenderIsFilledByServer |
| 同源改成「结尾对得上就行」 | 别人家的一律拦 + 子域不算(两条) |
| 拿掉自动收 | 到点自己收掉 |
| 拿掉「同一局只开一次」 | 同一局只开一次 |
| 触发方式默认改成 send | 认不得当 tap |
两个 Tool 待做
Gode 定的验收判据是:同一个容器要能跑出两种完全不同的玩法 —— 一个要互动、一个不要;一个是浮层、一个铺满;一个没有时限、一个到点就收。 挑这两个不是随便挑的,它们把容器的每一档都撑到了两头。
| ✊ 猜拳 | 🐱 小猫泼墨 | |
|---|---|---|
| 互动 | 要(两边各出一手) | 不要(发出去就播) |
| 尺寸 | 浮层(约 300×380) | 铺满聊天画面 |
| 时长 | 0 —— 打完自己关 | 3000 ms 到点收 |
| 触发 | tap(收到一张卡,点了才开) | send(发出去双方就播) |
| 它验证了什么 | 事件转发那条路真的通 | 播放能力真的能盖满、能自己退场 |
猜拳的一局怎么走
tools/rps/_test_pair.html,两个 iframe 装真页+模拟后端语义)全场景驱动过:
胜负两边镜像 · 平局 · 网络重发丢弃 · 路人闯入零接收(对手锁定)· 三轮比分对齐 · 暗色主题截图看过。
页面自带一道图纸没写但该有的保守:没都出齐前,对面只显示「出了没」(✅),不露是哪只手。
🐱 泼墨页也已写(08-29 同晚):铺满透明盖在聊天上演 3 秒,墨团二次曲线(直线是碎玻璃,曲线才是湿墨),
一场一种墨色随机;假聊天验证台截图核过、close 后备验过、外部请求 0。
三页已上线(08-29 深夜,Tools 专属项目 hoop-tools.pages.dev,逐网址核过 sha):
/tools/calc/ · /tools/rps/ · /tools/inkcat/。
目录 draft 三行已在生产库(08-30 部署,迁移 310→314 全上、验收全绿)。真机对玩 = P1 刀 6,只等 TF;验完把三行 draft 翻 live 即全量可见。
⚠️ 顺带一条给刀 6:铺满型的「点空白收掉」在容器里点不到(WebView 盖在手势层上面)—— 3 秒自收的泼墨无所谓,但真机验收时别拿这条当用例。还没做的
- 待做 接进聊天页 —— 容器做好了,但聊天里还没有开它的入口 (从「+」里选一个 Tool 发出去 / 收到那张卡点开)。
- 待做 猜拳和小猫泼墨两个网页。
- 卡住 把网页传上线 —— 这台机器没有 Cloudflare 的钥匙。
可执行的解法:在终端跑一次
npx wrangler login,或者给一个 Pages:Edit 的 API token。 - 待做 两台真手机对着玩一局 —— 这是唯一能证明"真的通了"的验收, 而它得等下一班 TestFlight。
待 Jeff 拍板 待拍板
- Tool 从哪儿进? 现在的设想是聊天「+」面板里一格。 但那个面板已经有 9 项了(相册/相机/文件/名片/群/投票/接龙/怪兽/歌)。 是再加一格,还是和贴纸面板并成一排(它本来就"比贴纸大一点")?
- 群里能不能用? 现在的转发是发给这间会话的所有人,一对一和群都能跑。 但猜拳是两个人的事 —— 20 个人的群里三个人同时开三局猜拳,界面上怎么摆? 最省事的一刀:互动型的 Tool 只在一对一开放,群里只给不互动的(泼墨那种)。要不要这么切?
- 谁能上架 Tool? 现在只有改数据库这一条路(等于只有我们自己)。 这个问题 08-29 和 Lisa 聊出了一份完整提案(行业尸检 + 三级火箭),全文在 ⑧ —— 拍板请拍那一节,这里不抄第二份。
- 泼墨那种能不能"强制"盖住对方的屏幕?
现在的设计是能(
trigger_mode=send发出去双方就播)。 这会被拿来骚扰 —— 现有的挡法只有「每分钟几条」。 要不要加一条「对方可以关掉这类特效」的开关?
相关
- 这套东西的近亲是小游戏平台(
docs/GAME_PLATFORM_SPEC.md)和 小程序平台(docs/MINIAPP_PLATFORM.md)—— 都是「服务器下发一份网页」。 故意没有并进它们:那两个都是整屏的、有排行榜/收入/审核队列, 而 Tool 是聊天里的一小片、活几秒钟。并进去的代价是每一条现有查询都得加一句"排除 Tool",漏一处就会有一个猜拳出现在游戏中心里。 - 全屏特效的老做法是 怪兽(
app/lib/widgets/chat_monster.dart)—— 那是 Flutter 手画的,加一个新的就要出一次包。Tools 就是来替掉这条路的。
谁来造 —— 行业尸检 + 三级火箭 待拍板
这一节回答待拍板第 3 条「谁能上架」。先看别人怎么死的,再说我们怎么走 —— 下面的行业事实都是 08-29 现查的,带出处。
同一个想法,四家巨头做过
| 谁 | 哪年 | 做的是什么 | 下场 |
|---|---|---|---|
| Apple · iMessage App Store | 2016 | 聊天里的小 app / 小游戏抽屉 —— 和我们的 Tools 几乎同一个想法 | flop。苹果自己弃养,几年没大更新,沦为贴纸抽屉 |
| Snapchat · Minis | 2020 | 聊天里的 HTML5 小工具(一起冥想、一起订票)—— 连技术选型都和我们一样 | 2022-08 随裁员 20% 一起砍(SEC 文件原话:对增长和收入没贡献),2023-02 正式下线 |
| Facebook · Messenger 小游戏 | 2016 | 聊天里直接开小游戏 | 悄悄撤出聊天,挪去独立的 Gaming 标签页 |
| Slack · 互动消息 | 至今 | 消息里的按钮/表单/审批(纯 JSON 原生渲染) | 唯一活着的 —— 但只活在企业场景 |
注意:没有一条死因是「用户不想要」。反证:iMessage 那片废墟里唯一长盛不衰的是 GamePigeon —— 聊天里跟朋友玩台球猜拳。需求一直在,断的是供给。
三条路,只有一条没人走过
| 谁来造 | 案例 | 死穴 |
|---|---|---|
| 平台自己造 | 微信原生功能;我们的猜拳 | 质量高、数量死 —— 平台想象不出也养不起长尾:我们造 20 个,用户要 2 万种 |
| 开放给职业开发者 | iMessage / Snap / Telegram bot | 经济账不成立(死因①),消费级聊天里全灭 |
| 开放给用户,AI 代工 | 没人做过 | 待验证 —— 但上面两个死穴它天生没有 |
提案:三级火箭 待拍板
| 级 | 谁造 | 干什么 | 依赖 |
|---|---|---|---|
| 一级 · 点火(现在) | 我们自己 | 头 20 个 Tool(猜拳/泼墨已在走)。目的不是数量,是三件事:货架不空着开张 · 五道闸先在自己人身上磨利(坏刀已砍 9 把) · 给后来者立质量标杆 | 无,已在跑 |
| 二级 · 主引擎 | 用户说,AI 造 | 用户在聊天里描述 → AI 工人造出网页 → 平台托管 → 五道闸圈住 → 上目录。这是差异化赌注所在 | 游戏线的工人池 + 三闸代推纹路照抄(docs/GAME_WORKERS.md) |
| 三级 · 顺风 | 职业开发者 | 门开着,想来就来 —— 但不指望:历史已证明这条道养不活消费级小工具 | 开发者平台纹路现成(docs/DEVELOPER_PLATFORM.md) |
乐高桶对目录的两条硬要求(随二级一起拍)
- 同类多款并存,靠使用量排序。不是一个品类一个坑 —— 三个作者的三款接龙可以同时在架上, 差的被好的顶下去。原生功能也不豁免:原生接龙做得不好,就该被 Tool 接龙抢走用户。
- 房间级装删。每个群自己管「装了哪些 Tool」,可装、可删、可换 —— Telegram「把 bot 加进群」的模型。 现在的图纸还没有这一层,这是真正的增量(目前目录是全局一张表)。
连带一条:闸要分两种看待(影响⑤的措辞,拍了板再改那页)
体验闸(③到点自己收 · ④一局一次)是参数,按 Tool 类型调。 ③的本意是「别把聊天挡到天荒地老」,不是「禁止活得久」—— 一个缩成角落药丸的音乐小播放器(播 HOOP 生态的歌,源是自己的)不违反本意。 判据:安全闸看「代码能碰到什么」,体验闸看「用户被挡住了什么」 —— 前者不谈判,后者谈参数。
边界:Bot 是另半边,别揉进来
docs/AI_BOTS.md,
两份图纸、两个入口、两套审核,不合并。行业事实来源(08-29 查):techstory.in / screenrant.com(Snap Minis 之死) · medium.com @aleksanders「The state of the iMessage App Store」 · macworld.com(iMessage 反思) · docs.discord.com(Activities 沙盒) · developers.weixin.qq.com(小程序双线程) · docs.slack.dev(Block Kit)
产品蓝图 —— 把「一个功能」做成「一个平台」缺哪几块 待拍板
这一节是全景图:产品是什么 · 平台由哪十块组成 · 每块现状(带出处)· 分几期 · 怎么算成了。 机制细节在①~⑤,谁来造在⑧ —— 这里不重抄,只指路(铁律 23)。
产品一句话
和另外两根柱子的关系 —— 小游戏是整屏的娱乐(分钟~小时),小程序是整屏的服务(常驻), 小工具是聊天里的一片(秒~分钟,一局有「完」的时刻)。三者共用「服务器下发网页」的地基,各有目录、互不混。
差异化赌注(⑧的结论):造工具不需要会编程 —— 用户说一句话,AI 造,平台托管,群里可装可删可换(乐高桶)。
四个角色,四条旅程
| 角色 | 旅程 | 现状 |
|---|---|---|
| 用的人(群成员) | 聊天里点开一张 Tool 卡 → 玩一局 → 到点自己收 | 容器已写好,等 TF;入口在哪待拍板(⑦-1) |
| 管的人(群主/成员) | 给自己的群装 / 删 / 换 Tool —— 乐高桶 | 整层缺失(⑧-乐高桶第 2 条) |
| 造的人(任何用户) | 说一句「我要一个 XX」→ AI 造 → 先只在自己群用 → 好用了上公共目录 | 缺失,纹路现成(⑧-三级火箭二级) |
| 平台(我们) | 守闸 · 排序 · 下架 · 分账 | 运行时闸已落地;审核/排序/经济缺失(下表) |
平台十块 —— 每块现状与缺口(这就是「我们需要做什么」)
| # | 部件 | 现状 | 缺什么 | 借谁的纹路 |
|---|---|---|---|---|
| 1 | 运行时(窗 + 五道闸) | 已落地后端上生产;App 写好等 TF(③) | 两台真机验一局(⑦-4) | —— |
| 2 | 首批内容 | 待做猜拳/泼墨两页(⑥) | 头 20 个 Tool(⑧-一级点火);候选清单见下 | —— |
| 3 | 入口 | 待拍板(⑦-1) | 「+」面板一格 or 并进贴纸排 | —— |
| 4 | 目录(App 里能逛) | 只有后端一张表,App 里没有货架 | 可浏览目录 + 同类多款、使用量排序(⑧-乐高桶 1) | 游戏中心 / Apps 目录页 |
| 5 | 房间级装删 | 整层缺失 | 每群一份「装了什么」+ 装/删/换交互(⑧-乐高桶 2) | Telegram「加 bot 进群」模型 |
| 6 | AI 造的管线 | 缺失 | 说→造→沙盒验→先私有后公开 | 工人池 + 三闸代推(GAME_WORKERS.md) |
| 7 | 审核与下架 | 运行时闸有,上架前的闸没有 | AI/用户造的过什么检查才上目录 · 举报 · 一键下架(kill switch) | 游戏线 CI 三闸 · 音乐线四种下架 |
| 8 | 数据层 | 一局之内:Redis 序号 30 分钟 TTL,已建成不动(chattool.go seqTTL) |
跨局:chat_tool_kv 一张表,键 (tool_id, conversation_id)(房间的数据,全群同一份 —— 这正是它和 game_saves 个人存档的差别),
单格 JSONB ≤16KB + expires_at(活跃期 Tool 自己声明,平台上限 30 天)。
记录不陪葬(Lisa 08-29 抓出的窟窿):工作台可以到期,但到期前必须先把最终结果定格成一条消息发进聊天流 ——
记录从此跟着聊天历史走(普通房永存、幽灵房随房毁,自动继承房间的生死规则),然后才许物理删工作台。
铁顺序:没定格的不许删。微信接龙就是这个模型:接龙结束,那条消息就是永久记录。
页面 API 就两句 hoopTool.kv.get/set,写入走现有转发管道(复用闸④⑤,不开新口) |
game_saves(16KB 限)· miniapp_kv(命名)· 幽灵房(TTL 毁灭) |
| 9 | 经济 | 缺失 | 绿能量打赏 → 造者分成;Snap 死因②的疫苗(⑧末警告) | 音乐线两层分成 · 绿能量 as-built |
| 10 | 度量 | 缺失 | 局数/完成率打点 —— 没有它,目录排序(4)和「算不算成」都是瞎的 | 游戏线打点 |
分期与刀数 —— 每刀独立可验,顺序即依赖(Lisa 08-29:「每一个 P 都要详细写刀数」)
P1 能玩 —— 7 刀
| 刀 | 干什么 | 状态 |
|---|---|---|
| 1 | 「+」入口:Lisa 08-30 拍板「放聊天+里,做翻页」。面板改分页器(第0页老九格逐像素不变,Tools 每页12格横滑+圆点;2026-09-11 起横滑是跟手的 —— Mike「不要给 instant animation」,位置从整数下标改成连续量,手指走多少页面走多少,松手用弹簧归位,过半即翻不必甩);点开=铸 instance 开容器。1b 也已落(同日):'tool' 进类型名单(000314)+ 发卡端点 + ChatToolCard 气泡(名字图标查目录不进 body)+ 点卡进同一局 + 泼墨照怪兽先例在 message.new 自动播。三种触发方式全通 | 已做 08-30,等 TF + 迁移上云 |
| 2 | 计算器页:第一个 Tool,单文件 6.5KB,manual 触发、interactive=false、零外源 | 已做且已上线 hoop-tools.pages.dev/tools/calc/;目录 draft 行 = 迁移 000313 |
| 3 | 猜拳页:第一个互动 Tool,吃转发管道(闸④⑤的第一个真用户) | 已做 08-29,双人测试台全场景验过(⑥) |
| 4 | 泼墨页:第一个 send 触发 Tool,duration 上限必设(闸③) | 已做 08-29,透明验证台核过(⑥) |
| 5 | 打点:open/close 进 chat_tool_events(迁移 000312,POST /v1/tools/track;容器开局/关局自动发射,fire-and-forget)。round_done 故意不进表 —— 它 = P3 定格卡消息,再记一份是手抄镜像(铁律 23) | 已做 08-29;迁移待上云、App 半等 TF |
| 6 | 三个 Tool draft→live,两台真机对玩一局(总验收刀) | 待做,等 TF |
| 7 | TF 出包(NOVA 捎班,铁律 17) | 待做 |
P2 乐高桶 —— 6 刀
| 刀 | 干什么 |
|---|---|
| 1 | conversation_tools 表(房间装了什么)+ 迁移 000328 已做 09-02。主键 (群,工具);工具下架不删装配记录(下架可逆,装配是群主的选择) |
| 2 | 装 / 删 / 列三个端点 已做 09-02:GET/PUT/DELETE /v1/conversations/{id}/tools[/{tool}]。看=成员;装删=CanManageTools(群主/管理员;私聊两人皆可;9 格穷举测)。装删都幂等 |
| 3 | 工具商店 已做 09-02(v1.676):按类分组、组内按后端用量序、每行「本周 N 局」;入口=「+」货架末尾 Add 格(零工具也有 Tools 页) |
| 4 | 群装删 已做 09-02(v1.676):群信息页「Tools」一行进同一个商店页,装/拆按钮当场翻;403 一句话说清。货架读会话的,后端没记录=默认集(全部 live),第一次装拆先落成显式记录 —— 拆一个不会连坐其它 |
| 5 | 使用量排序 已做 09-02:读时聚合(最近 7 天 open 数,rank.go),不建榜表不起定时任务 —— 榜表就是一份要人记得刷新的手抄镜像(铁律 23)。目录 JSON 多一列 opens_7d |
| 6 | category 已做 09-02(000329):game / utility / effect / social,目录属性不是人手标签;商店按它分组,组内按用量 —— 同类多款并存、差的被顶下去 |
P3 人人能造 —— 7 刀
| 刀 | 干什么 |
|---|---|
| 1 | chat_tool_kv 表 + 定格卡铁顺序 后端已上生产 09-02(000331;到期清理那半留着,清之前先定格) |
| 2 | SDK v2 已上线:kv/shared/collection/finish/players 全包;合同和范例在 /tools-sdk。容器 v2 已做 09-02(v1.686):注入 ctx、影子身份(SHA-256(局:id) 前 16 位,页面永远见不到真 id)、kv/finish 桥;等 TF。09-11(v2.037)加注入 CSS 变量 --hoop-safe-top = 真实状态栏高度 —— 工具的 WebView 是整屏铺开的,而这个容器里 WKWebView 报的 env(safe-area-inset-top) 是 0,页面自己问不到;写 var(--hoop-safe-top, 自己的兜底),新容器给真值、老容器吃兜底 |
| 3 | 定格卡:不新开消息类型,复用 tool 卡加 result{title,lines} 后端已收;App 结果卡 已做 09-02(v1.686):标题 + ≤12 行,不可点 |
| 4 | AI 工人造 Tool:模板 + 沙盒验证(照 GAME_WORKERS.md 三闸代推) |
| 5 | chat_tools 加 owner_conversation_id 可空列:私有 Tool 只在那个房可见 后端已做 09-02(000332;目录/装卸/发卡/转事件四处都按会话过滤,别人群的私有工具等于不存在) |
| 6 | 「造一个工具」的聊天入口 已做 09-02(v1.704):货架顶行 → 造工具屏(复制提示给你的 AI / 填清单 / 贴网页 / 交到这个群;拒绝原话原样摆出来;非开发者给「申请」)。现在的引擎是用户自己的 AI;「说一句话 → 工人接单」那半是刀 4 |
| 7 | 上传门 后端已做 09-02:POST /v1/tools/submit 四闸(开发者身份 / 清单+群角色 / 网页静态安检 / 留痕)→ 文件 commit 进 HOOP-games tools/p/<id>/ → CI 部署 → 私有 live + 自动装进那个群;publish-request 打时间戳,审核是人。顺序改了(Lisa 09-02):先开开发者的门,模板池/工人那两刀(4、6)排它后面。规格全在 /tools-sdk ⑨ |
P4 看得见 —— 1 条尺子(原「养得活」4 刀,Lisa 09-02 砍成这样)
| 原刀 | 下场 |
|---|---|
| 打赏 / 分成 | 不做。Lisa 09-02:「不给他们分钱,我们都无法收取」—— 钱不经平台的手就没有"收取",做了只是替人转账。真要做,前提是先有一条钱进平台的路,那是另一张图纸 |
| 开发者上传门 | 提前到 P3 刀 7 做完了 |
| 北极星周报 | 留:每周活跃群里开过 Tool 局的比例。数据在 chat_tool_events(000312),一条 SQL,不算一刀 |
hoop-tool.d.ts、模拟器 _sim.html;_kit.js 由工具网页运行时从站上加载。入口放在首页左上角三条线的 HOOP SPACE 侧栏「Tools SDK」一格(她点的位置),三个链接都能复制,给 AI 的提示一键复制。P1 首批候选(Lisa 08-29 那批 + 补充,已按五道闸过筛)
✅ 改个源就成:新闻轻读窗(读我们自己的新闻后端) · HOOP 音乐小播放器(缩成药丸,不挡聊天)
🔀 归别处:发定位/翻译/文件扫描 → 原生功能线;YouTube → 外域,安全闸不放;真钱捐箱 → 合规,用绿能量心意箱替
新增待拍板(蓝图带出来的,和⑦⑧的合并算总账)
- 跨局存储:方案与时机。方案已写死在第 8 块(KV 工作台可到期 + 结果定格成消息永生,铁顺序「没定格的不许删」)。 时机推荐:P1 不等它(P1 只上「一局完」的 Tool),P3 第一刀落表,报名器/任务榜跟着上。要拍的是「定格成消息」这个产品行为。
- 私有 Tool 的边界:AI 给一个群造的 Tool,默认只在那个群活(私有)。上公共目录要过第 7 块的闸 —— 私有的那份要不要也过一道轻闸?(它毕竟是外来代码在我们的壳里跑)
- 北极星指标选哪个:建议「周活跃群里开过 Tool 局的比例」—— 它同时逼供给、发现、质量三件事;单看局数会被一个爆款游戏骗。
- 产品名:对用户叫什么?「小工具」贴切但平淡;候选:工具箱 / 道具 / Tools 原文。英文优先(铁律 11),中文跟着定。
- 装删的权限:Lisa 09-02 拍「先群主」→ 已按此落地:群主/管理员能动、成员不能;私聊两人皆可。放开是
CanManageTools改一行。