cortico-world-feast 0.0.0-stage → 0.2.0
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/CHANGELOG.md +80 -0
- package/PUBLISHING.md +254 -0
- package/README.md +169 -2
- package/assets/icon.png +0 -0
- package/describe.json +191 -0
- package/dist/webui.js +556 -0
- package/package.json +76 -4
- package/src/ENV_PROMPT.md +12 -0
- package/src/config.js +237 -0
- package/src/data/bbq.json +303 -0
- package/src/data/cantonese.json +298 -0
- package/src/data/chinese-snacks.json +218 -0
- package/src/data/desserts.json +302 -0
- package/src/data/drinks.json +261 -0
- package/src/data/halal.json +300 -0
- package/src/data/home-cooking.json +218 -0
- package/src/data/hunan.json +218 -0
- package/src/data/ice.json +218 -0
- package/src/data/indian.json +218 -0
- package/src/data/italian.json +313 -0
- package/src/data/japanese-hot.json +218 -0
- package/src/data/jiangnan.json +218 -0
- package/src/data/korean-thai.json +218 -0
- package/src/data/mexican.json +311 -0
- package/src/data/noodles-dumplings.json +138 -0
- package/src/data/northeast.json +218 -0
- package/src/data/northern.json +304 -0
- package/src/data/northwest.json +218 -0
- package/src/data/sichuan.json +218 -0
- package/src/data/soups.json +218 -0
- package/src/data/sushi.json +218 -0
- package/src/data/vietnamese.json +218 -0
- package/src/data/western.json +309 -0
- package/src/data/yunnan-guizhou.json +218 -0
- package/src/definition.js +83 -0
- package/src/dishes.js +253 -0
- package/src/eat.js +260 -0
- package/src/index.js +25 -0
- package/src/state.js +343 -0
- package/src/world.js +795 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# 更新日志
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
菜单从 80 道加到 200 道,多了 5 个菜系;面板也不再在两三百道时悄悄截掉一截。
|
|
6
|
+
|
|
7
|
+
**菜品库:80 道 → 200 道**
|
|
8
|
+
|
|
9
|
+
- 原来的 20 个菜系组各从 4 道加到 **8 道**——川菜多了回锅肉、担担面、口水鸡、酸菜鱼;粤菜多了烧鹅、虾饺、豉汁蒸凤爪、老火靓汤;江浙多了松鼠鳜鱼、蟹粉小笼、腌笃鲜、葱油拌面;北方多了北京烤鸭、葱烧海参、锅贴、涮羊肉……每组都是补该菜系真正常见的做法,不是凑数。
|
|
10
|
+
- 新增 **5 个菜系组,各 8 道**:
|
|
11
|
+
- **西北菜**(羊肉泡馍、手抓羊肉、岐山臊子面、新疆大盘鸡、烤馕、陕西凉皮、黄焖羊肉、青海酸奶)
|
|
12
|
+
- **清真菜**(手抓饭、爆炒羊羔肉、它似蜜、羊杂汤、爆肚、馕包肉、油香配粉汤、八宝茶)
|
|
13
|
+
- **家常菜**(番茄炒蛋、红烧排骨、清蒸鲈鱼、手撕包菜、鸡蛋羹、土豆丝、可乐鸡翅、紫菜蛋花汤)
|
|
14
|
+
- **印度菜**(黄油鸡、玛莎拉多萨、比尔亚尼饭、帕拉塔饼、鹰嘴豆咖喱、坦都里烤鸡、菠菜奶酪、芒果拉西)
|
|
15
|
+
- **墨西哥菜**(烤猪肉塔可、莫莱酱鸡肉、玉米粽、波索莱汤、奇拉基莱斯、鱼肉塞维切、鳄梨酱、烤玉米)
|
|
16
|
+
- 现在 200 道 / 25 个菜系组,中餐 13 组、外餐与饮品 12 组。每道仍是 15 个字段、九维口味 0-100 的整数、一段 100-160 字的实吃描写。
|
|
17
|
+
|
|
18
|
+
**面板**
|
|
19
|
+
|
|
20
|
+
- 菜单面板一次请求的上限原来是写死的 200 条,正好等于旧的库容量。现在跟着库里实际有多少走(硬顶 400),所以扩到 300 道也不会有一截被悄悄截掉。
|
|
21
|
+
|
|
22
|
+
**写菜的规矩落了地**
|
|
23
|
+
|
|
24
|
+
- 新增 `DISH-SPEC.md`:15 个字段怎么写、九维怎么给、套话黑名单、每栏的字数区间,还有"每道菜的 prose 开头不许用同一个句式"这条——否则 8 道摆在一起就是一个模子。
|
|
25
|
+
- 新增 `tools/check-file.mjs`:一次只校验一个菜品 json,写菜时自己就能查,不用等全库跑完。
|
|
26
|
+
|
|
27
|
+
## 0.1.1
|
|
28
|
+
|
|
29
|
+
同一天连着吃同一道菜,不该听见同一句话;端来的菜也不该看不出还剩多久。
|
|
30
|
+
|
|
31
|
+
**换角度**
|
|
32
|
+
|
|
33
|
+
- 「这一口」多了一档**按吃过几回换角度**的变化:第一回说第一印象;第二回不再写开头,改说"吃了一半以后怎么变";第三回起说熟客的例行(点的时候不犹豫,吃的时候还是认真)。三档之间不互相串,档内还有多句可挑,所以同一天连吃两回也不会撞词。
|
|
34
|
+
- 事实层没动:上桌的样子、香气、口感、余韵、整段描写照旧原样给,变的只是"当下"那一层。
|
|
35
|
+
|
|
36
|
+
**端来的菜看得出还剩多久**
|
|
37
|
+
|
|
38
|
+
- `feast.feed` 的气泡不再只说"放 30 分钟",而是写清**到几点为止**("现在刚端过来,12:05 之前吃掉都算数;过了就收了")。
|
|
39
|
+
- 吃端来的那道时,回执里补一句还剩多久。
|
|
40
|
+
- 菜单面板的等待条右边多一行**自己会走的倒计时**("还剩约 23 分钟"),到点自动重拉、收走那条;等待条也不再只在挂载那一刻认一次,重拉就跟着服务端的说法走,吃掉了/收走了都跟着变。
|
|
41
|
+
|
|
42
|
+
## 0.1.0
|
|
43
|
+
|
|
44
|
+
第一次发布。
|
|
45
|
+
|
|
46
|
+
**菜品库**
|
|
47
|
+
|
|
48
|
+
- 80 道菜,20 个菜系:川菜、粤菜、江浙菜、北方菜、湘菜、云贵菜、东北菜、面点主食、汤羹、中式小吃,日料·寿司、日料·热食、韩式与泰式、越南与东南亚、意菜、西餐、甜品、饮品、冰品与冷饮、烧烤与夜市。中餐和外餐各占一半。
|
|
49
|
+
- 每道菜 15 个字段:菜名、别名、菜系、类别、产地、食材、做法、上桌的样子、九维口味(辣麻咸鲜甜酸苦油香,0-100 的整数)、口感、香气、余韵、一段 40-400 字的实吃描写、标签。
|
|
50
|
+
- 九维分值是按菜的真实口味给的,不是随机数:麻婆豆腐的麻在 80 以上,清蒸鱼的辣不超过 10,糖醋排骨的甜在 60-80。面板上的条和口味画像都从这个数上算。
|
|
51
|
+
|
|
52
|
+
**吃**
|
|
53
|
+
|
|
54
|
+
- `feast_eat` 的回执分两层。事实层每次一样(上桌的样子、香气、口感、余韵、整段描写);当下层用 `${菜 id}|第几次|日期` 做种子,所以温度怎么变、吃到一半什么感觉、配了什么那口,每次都不一样,同一个「第几次 + 同一天」重放又是稳定的。
|
|
55
|
+
- `dislikeChance` 掷中时另起一句,并指出这道菜自己最强的那个维度顶住了她,不是套一句「太咸」。
|
|
56
|
+
- `feast_taste` 只看不吃;`feast_menu` 按菜系、类别、标签或自由词筛;`feast_history` 给出吃过什么和攒出来的口味画像;`feast_reaction` 记下 like / ok / dislike 加一句具体的话;`feast_skip` 跳过今天剩下的饭点。
|
|
57
|
+
|
|
58
|
+
**主人投喂**
|
|
59
|
+
|
|
60
|
+
- 世界面板的「菜单」页签:翻菜单、看九维口味条、看食材与做法,点「端给她」就把这道菜放到她面前。
|
|
61
|
+
- 投喂会推一条 `feast.feed` 事件,正文写这道菜怎么上的桌、闻到什么;她下一次 `feast_eat` 不带参数时先吃端来的那道。
|
|
62
|
+
- 端来的菜默认留 30 分钟(`ownerFeedTTL` 可改),过了自动收走,免得半天后突然回一句。
|
|
63
|
+
|
|
64
|
+
**饭点提醒**
|
|
65
|
+
|
|
66
|
+
- 默认 11:30、18:00 各一顿,推 `origin: internal` 的 `feast.meal` 事件——是她自己的饭点,不是主人发的消息。
|
|
67
|
+
- 没吃就催一次(默认 40 分钟后),催完放掉,不刷屏;上一顿挂满 2 小时就放掉,但同一拍还会看下一档,午饭没吃不该把晚饭一起吞掉。
|
|
68
|
+
- 应用 15:00 才打开这类情况:一天一档都没叫过的话,补最近过去的那一顿。
|
|
69
|
+
- `mealReminder` 一键关掉之后完全不叫,菜单和六个工具都还在;`mealSlots` 可以自己改时间、加档位(中文逗号也认)。
|
|
70
|
+
|
|
71
|
+
**面板**
|
|
72
|
+
|
|
73
|
+
- 「菜单」与「吃过什么」两个页签,中英双语,跟随 Coo 的界面语言。
|
|
74
|
+
- 面板只往自己的 DOM 根里写,样式随面板注入,颜色全部走宿主主题的自定义属性,明暗两套主题都不用另写。
|
|
75
|
+
- 「吃过什么」给九维均值、一句句读得出的判断、吃得最多的几道、最近几口、她自己记过的反应。
|
|
76
|
+
|
|
77
|
+
**状态**
|
|
78
|
+
|
|
79
|
+
- 落在 `<dataDir>/feast/state.json`,纯 JSON。跨天只清饭点那一层(今天叫过哪几顿、还挂着哪顿、今天跳过没有),吃过什么、对什么反应、各道菜吃过几回都留着。
|
|
80
|
+
- 世界页的数据页签里能清空吃过的记录;清完不会让她立刻又被叫一次。
|
package/PUBLISHING.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# 发布到 Coo 扩展市场
|
|
2
|
+
|
|
3
|
+
Coo 的市场不自己收包。它读的是两处:
|
|
4
|
+
|
|
5
|
+
1. **npm**:包本身。市场 Action 每 30 分钟搜一次 npm 上带 `cortico-world` 关键字的包,解包读 `cortico` 块、`describe.json`、`CHANGELOG.md`、图标与截图,把结果写进索引仓。
|
|
6
|
+
2. **GitHub 索引仓** [`Pal-AI-Lab/cortico-extensions`](https://github.com/Pal-AI-Lab/cortico-extensions):`catalog.json` 与 `packages/` 由 Action 生成,`index.json` 由官方走 PR 维护(标签词表、认证、拉黑、官方覆盖)。
|
|
7
|
+
|
|
8
|
+
所以「发布到 Coo」= **发一个 npm 包**,剩下的市场自动收。你不需要向谁提交、也不需要等审核(认证是另一件事,见文末)。
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 0. 发版前自查(已经全绿,改过东西就重跑)
|
|
13
|
+
|
|
14
|
+
```powershell
|
|
15
|
+
cd 'E:\deep seek\feed-world'
|
|
16
|
+
|
|
17
|
+
node tools/validate-dishes.mjs # 菜品库:字段、九维、类别、套话、菜系与文件名一致
|
|
18
|
+
node tools/selfcheck.mjs # 复刻 Coo 的干装载检查
|
|
19
|
+
node tools/publish-check.mjs --online # 市场收录口径 + npm 包名占用
|
|
20
|
+
node test/dishes.test.mjs; node test/eat.test.mjs; node test/state.test.mjs; node test/world.test.mjs; node test/panels.test.mjs
|
|
21
|
+
node tools/make-describe.mjs --check
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`prepublishOnly` 已经把这些串起来了:`npm publish` 之前会自动跑一遍,有任何一处失败就发不出去。这不是多余的谨慎——`describe.json` 与代码脱节、标签写了词表外的值、图标超 512KB,都会让市场那张卡片缺一块,而发出去之后改不了(只能发新版本)。
|
|
25
|
+
|
|
26
|
+
当前状态:**18 项通过、0 失败、1 条警告**(警告是没截 `screenshots`,见第 5 步)。
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 1. 仓库地址(已补好)
|
|
31
|
+
|
|
32
|
+
`package.json` 顶层已经有下面三行(2026-11-05 补,指向 `bailuhanyi/cortico-world-feast`)。市场详情页的「源代码仓库」「项目主页」「问题反馈」三个链接就是从这三行来的;认证申请也要求仓库在你自己名下(`official.githubOwners` 之外的第三方包,维护者不能是 `phantivia`)。
|
|
33
|
+
|
|
34
|
+
```jsonc
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/bailuhanyi/cortico-world-feast.git"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/bailuhanyi/cortico-world-feast#readme",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/bailuhanyi/cortico-world-feast/issues"
|
|
42
|
+
},
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
如果以后仓库换了名字,这三行要一起改,否则详情页链到 404。
|
|
46
|
+
|
|
47
|
+
`repository` 要写在顶层,**不要**写进 `cortico` 块——Action 是从顶层读的。
|
|
48
|
+
|
|
49
|
+
建仓并推(仓库要在 GitHub 上先建好,名字 `cortico-world-feast`;这台机器没装 `gh`,只能走网页建空仓,**不要**勾 README/LICENSE/gitignore):
|
|
50
|
+
|
|
51
|
+
```powershell
|
|
52
|
+
cd 'E:\deep seek\feed-world'
|
|
53
|
+
git init
|
|
54
|
+
git add -A
|
|
55
|
+
git commit -m "一桌菜 0.1.0:80 道菜的 Coo 世界,带九维口味、会变化的这一口与可开关的饭点提醒"
|
|
56
|
+
git branch -M main
|
|
57
|
+
git remote add origin https://github.com/bailuhanyi/cortico-world-feast.git
|
|
58
|
+
git push -u origin main
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`.gitignore` 已经排掉了 `node_modules/`、`.tmp/`、`*.bak-*`,不会把装机残留推上去。
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 2. 登录 npm 并确认身份
|
|
66
|
+
|
|
67
|
+
```powershell
|
|
68
|
+
npm login # 浏览器授权,或用户名 / 密码 / 一次性验证码
|
|
69
|
+
npm whoami # 确认登上了
|
|
70
|
+
npm config get registry # 应是 https://registry.npmjs.org/
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
如果 `npm whoami` 报 `ENEEDAUTH`,就是没登上。如果报 `EPERM ... npm-cache\_logs`,那是本机 npm 缓存目录的权限问题(不影响发布,只是写不了日志)。
|
|
74
|
+
|
|
75
|
+
> **本机已知情况(2026-11-05)**:npm 缓存目录 `C:\Users\asus\AppData\Local\npm-cache` 在 DSH 沙箱里写不了,`npm pack` / `npm publish` 会报 `EPERM`。这不是 npm 的问题,是沙箱边界——`npm pack`、`npm publish` 这类要写缓存的命令都要在沙箱外跑(或由你在自己终端里跑)。
|
|
76
|
+
|
|
77
|
+
### 2FA:npm 现在要求发布必须过二次验证
|
|
78
|
+
|
|
79
|
+
`npm login` 用网页授权登进来的是普通 token,**发不了包**。`npm publish` 会报:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
E403 Two-factor authentication or granular access token with bypass 2fa enabled
|
|
83
|
+
is required to publish packages.
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
也就是说账号必须满足下面之一:
|
|
87
|
+
|
|
88
|
+
- 开启 2FA,发布时带 `--otp <6 位码>`(每次都要,码 30 秒过期)
|
|
89
|
+
- 建一个 **granular access token** 并勾上「bypass 2FA」,把它写进 `~/.npmrc`
|
|
90
|
+
|
|
91
|
+
开启 2FA:<https://www.npmjs.com/settings/YOURNAME/tfa> → 绑定 authenticator → 选 **Authorization and writes**(只勾 writes 不够,改 tag/设置也要验证)。
|
|
92
|
+
|
|
93
|
+
然后:
|
|
94
|
+
|
|
95
|
+
```powershell
|
|
96
|
+
npm publish --otp 123456
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
> 注意:网页授权登录的会话 token 也走不通这条路。要么 2FA + `--otp`,要么 granular token + bypass 2FA,没有第三种。`--otp` 的码只能人手输,脚本替不了。
|
|
100
|
+
>
|
|
101
|
+
> **`--otp` 要的是 6 位数字**,从 authenticator 应用里现取(30 秒滚一次)。npm 的**恢复码**(一长串 64 位 hex)只能用于**网页登录**顶替验证——**千万别传给 `npm publish --otp`**:会当场消耗掉一个,并且触发 **72 小时安全封禁**(`temporary 72-hour security hold`),期间不能发布、不能建 token、不能改已有 2FA 方式,**无法提前解除**。
|
|
102
|
+
>
|
|
103
|
+
> **判断封禁有没有解除,别只看 `EOTP`。** `npm publish` 分两个阶段:第一阶段发 PUT,只报 `401 / EOTP`(要验证码);**带上验证码或完成网页验证后重试的第二个 PUT 才会暴露 `403 suspended`**。所以只有走完整个验证流程、看到第二个 PUT 的结果,才知道能不能发。
|
|
104
|
+
>
|
|
105
|
+
> **npm 的 2FA 主推安全密钥(WebAuthn)**,不是 authenticator 的 6 位码。设置页如果只给 Security key 选项,选它即可——Windows 上走 Windows Hello(指纹/PIN),不再需要输码。TOTP(authenticator)是另一个可选项,取决于账号页面提供不提供。
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 3. 看一眼要发出去的东西
|
|
110
|
+
|
|
111
|
+
```powershell
|
|
112
|
+
npm pack --dry-run
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
应该看到 **40 个文件**,压缩后约 190KB、解包约 537KB:`package.json`、`src/`(含 25 个菜品 json)、`dist/webui.js`、`describe.json`、`assets/icon.png`、`README.md`、`CHANGELOG.md`、`PUBLISHING.md`。
|
|
116
|
+
|
|
117
|
+
`test/`、`tools/`、`install.ps1` 都在 `files` 之外,不会发出去——菜品校验脚本、装机脚本是我们的工具,不是用户要的东西。
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 4. 发
|
|
122
|
+
|
|
123
|
+
```powershell
|
|
124
|
+
npm publish --otp 123456 # 没开 2FA、或用了带 bypass 2FA 的 granular token,就不用带 --otp
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
第一次发一个 `0.1.0` 的新包,不需要 `--access public`(那是作用域包 `@you/xxx` 才要的)。
|
|
128
|
+
|
|
129
|
+
发完立刻验:
|
|
130
|
+
|
|
131
|
+
```powershell
|
|
132
|
+
npm view cortico-world-feast version # 应回 0.1.0
|
|
133
|
+
npm view cortico-world-feast cortico --json # 应能看到 kind/api/displayName/tags/locales
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`npm view` 走的是 CDN,刚发出去可能有几十秒到几分钟的滞后,回 `E404` 先等一下再查。
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 5. 让它马上进市场(可选,但建议)
|
|
141
|
+
|
|
142
|
+
Action 平时每 30 分钟扫一次(每小时 17 分、47 分),GitHub 的定时任务经常推迟几小时。想立刻进市场,去索引仓开一个 `[同步]` issue:
|
|
143
|
+
|
|
144
|
+
```powershell
|
|
145
|
+
# 装了 gh 的话
|
|
146
|
+
gh issue create --repo Pal-AI-Lab/cortico-extensions `
|
|
147
|
+
--title "[同步] cortico-world-feast" `
|
|
148
|
+
--body "package: cortico-world-feast"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`sync.yml` 会马上跑,回帖说明结果(已收录的版本、npm 上找不到、没有扩展关键字、被拉黑、详情文件的问题),然后关掉 issue。
|
|
152
|
+
|
|
153
|
+
没装 `gh`(这台机器就没有)也可以直接在网页上开:<https://github.com/Pal-AI-Lab/cortico-extensions/issues/new>。
|
|
154
|
+
|
|
155
|
+
之后在 Coo 的「扩展 → 市场」里搜「一桌菜」就能看到。第一次出现时会带**新品**徽标(`newDays: 14`)。
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 6. 截图(唯一还缺的东西)
|
|
160
|
+
|
|
161
|
+
市场详情页现在只有图标和文字。截图要你自己截,脚本替不了:
|
|
162
|
+
|
|
163
|
+
1. 重启 Coo,世界页开「一桌菜」
|
|
164
|
+
2. 「菜单」页签截一张(能同时看到筛选条、卡片、九维口味条最好)
|
|
165
|
+
3. 「吃过什么」页签截一张(口味画像那张)
|
|
166
|
+
4. 存成 `assets/screenshot-1.png`、`assets/screenshot-2.png`(每张 ≤2MB,最多 8 张)
|
|
167
|
+
5. 在 `package.json` 的 `cortico` 块里加:
|
|
168
|
+
|
|
169
|
+
```jsonc
|
|
170
|
+
"screenshots": ["assets/screenshot-1.png", "assets/screenshot-2.png"],
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
6. 升版本号到 `0.1.1`,重跑 `npm publish`
|
|
174
|
+
|
|
175
|
+
截图改了就必须发新版本——市场按版本扫包,不发新版本改不了已收录的那一版。
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 标签:为什么是这个组合
|
|
180
|
+
|
|
181
|
+
作者能声明的只有普通、提示、警示三级;官方标注(`coopanion` 等)由官方 `addTags` 给,自己写了也不算。
|
|
182
|
+
|
|
183
|
+
当前声明:
|
|
184
|
+
|
|
185
|
+
| 标签 | 级别 | 为什么 |
|
|
186
|
+
| --- | --- | --- |
|
|
187
|
+
| `companion` | 普通 | 情绪、作息、时间感、主动开口——饭点和「她自己想吃」都是这类 |
|
|
188
|
+
| `internal-state` | 提示 | 这个 World 在 Memory 之外自己记着她吃过什么、对什么有反应、口味画像。装上或卸下前后,她对自己的认知会不一致。**词表明确不推荐在 World 里管内部状态**,我们照实声明。 |
|
|
189
|
+
| `experimental` | 提示 | 0.1.0,只在少数配置上验过,兼容性未确认 |
|
|
190
|
+
|
|
191
|
+
`keywords` 里的 `companion` 会自动映射成普通标签(同一级别,不重复算)。
|
|
192
|
+
|
|
193
|
+
之前写过 `food` 和 `local`,两个都不对:`food` 不在词表里(市场不认,写了等于没写);`local` 的意思是「在本机跑模型、要算力和显存」,我们一行推理都不跑。已删掉。
|
|
194
|
+
|
|
195
|
+
**没声明的**:`injection-risk` 不该有——我们推的两条 internal 事件,正文全是固定模板加扩展自己的数值(菜名、菜系、日期、她自己吃过什么),没有一句是别人写的文字。`high-cost` 也不该有——6 个工具合计约 844 token,饭点一天最多 3 次。
|
|
196
|
+
|
|
197
|
+
如果官方后续加了什么标签,`index.json` 的 `overrides` 里会有 `note` 说明原因;想去掉自己声明的那几个,开一个 `[标签]` issue 就行。
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 认证(可选,以后再说)
|
|
202
|
+
|
|
203
|
+
认证(盾牌徽标)要另外申请,要求(全部满足):
|
|
204
|
+
|
|
205
|
+
1. 没有错误的标签、缺失的信息这类基本问题
|
|
206
|
+
2. 发布的版本表现稳定
|
|
207
|
+
3. World 扩展不直接依赖其他 World 扩展
|
|
208
|
+
4. **至少有过一次后续更新**
|
|
209
|
+
|
|
210
|
+
第 4 条意味着至少要发两个版本才能申请。所以先发 0.1.0,攒点实际用下来的反馈,发 0.2.x 的时候顺手把截图补上,那时再申请。
|
|
211
|
+
|
|
212
|
+
申请方式是开一个 `[认证]` issue:
|
|
213
|
+
|
|
214
|
+
```powershell
|
|
215
|
+
gh issue create --repo Pal-AI-Lab/cortico-extensions `
|
|
216
|
+
--title "[认证] cortico-world-feast" `
|
|
217
|
+
--body "package: cortico-world-feast"
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Action 会自动核对能机器查的那几条并回帖。
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 之后发新版本
|
|
225
|
+
|
|
226
|
+
```powershell
|
|
227
|
+
# 1. 改代码
|
|
228
|
+
# 2. 更新 CHANGELOG.md(市场按 ## 标题里的版本号切段,显示在「历史版本」里)
|
|
229
|
+
# 3. 升版本号:npm version patch / minor / major(会同步改 package.json 并打 tag)
|
|
230
|
+
npm version patch
|
|
231
|
+
# 4. 重生成自描述(工具描述或提示词改过才需要)
|
|
232
|
+
node tools/make-describe.mjs
|
|
233
|
+
# 5. 发
|
|
234
|
+
npm publish
|
|
235
|
+
# 6. 想马上进市场就开 [同步] issue
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
改过 `src/ENV_PROMPT.md` 或任何工具描述,**一定要重跑 `make-describe.mjs`**——市场展示的是 `describe.json` 里那份,不是运行时那份。`prepublishOnly` 会拦,但拦的时候已经在发布流程里了,早点跑早点发现。
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## 出问题怎么办
|
|
243
|
+
|
|
244
|
+
| 症状 | 原因 | 处理 |
|
|
245
|
+
| --- | --- | --- |
|
|
246
|
+
| 市场搜不到 | npm 上没有 `cortico-world` 关键字 | 检查 `keywords`,改完发新版本 |
|
|
247
|
+
| 卡片上能力摘要那行是空的 | 包里没有 `describe.json`,或 `cortico.describe` 没指对 | `node tools/make-describe.mjs` 后发新版本 |
|
|
248
|
+
| 详情「环境提示词」栏空着 | `describe.json` 的 `prompts` 空了 | 同上;检查 `src/ENV_PROMPT.md` 存在 |
|
|
249
|
+
| 没有更新说明 | `CHANGELOG.md` 缺当前版本的二级标题 | 补 `## 0.1.1`,发新版本 |
|
|
250
|
+
| 图标不显示 | 路径不在 `assets/` 下,或超过 512KB | 重跑 `python tools/make-icon.py` |
|
|
251
|
+
| 标签没生效 | 写了词表外的标签 | 只写 `index.json` 词表里的;要新标签得提 `[新标签]` issue |
|
|
252
|
+
| 安装后世界不出现 | `cortico.api` 与用户那版 Coo 的契约版本不符 | 当前 world 契约是 6;用户版本旧的话要么升级 Coo,要么用兼容的版本 |
|
|
253
|
+
| `npm publish` 报 `prepublishOnly` 失败 | 自查没过 | 按报出来的那一条修 |
|
|
254
|
+
| `npm publish` 报 403 | 没登录,或包名被别人占了 | `npm whoami`;`node tools/publish-check.mjs --online` |
|
package/README.md
CHANGED
|
@@ -1,3 +1,170 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 一桌菜 · cortico-world-feast
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
给 Coo 一张会端菜的桌子。
|
|
4
|
+
|
|
5
|
+
200 道菜(25 个菜系组 × 8 道),每道都有九维口味分值、上桌的样子、香气、口感、余韵,和一段 40-400 字的实吃描写。她能自己按菜系挑着吃,主人也能从面板把一道菜端到她面前。**同一道菜每次吃到的都不一样**——温度、状态、配的那口都会变,所以连着吃三次不会说三遍同一句话。吃过什么、对什么反应、攒出来的口味画像跨天留着。饭点提醒默认开着,可以在配置里一键关掉。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 里面有什么
|
|
10
|
+
|
|
11
|
+
**菜品库**:200 道,25 个菜系组,每组 8 道。中餐 13 组、外餐与饮品 12 组。
|
|
12
|
+
|
|
13
|
+
| 中餐 | 外餐与饮品 |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| 川菜、粤菜、江浙菜、北方菜、湘菜、云贵菜、东北菜、西北菜、清真菜、家常菜 | 日料·寿司、日料·热食、韩式与泰式、越南与东南亚、印度菜、墨西哥菜 |
|
|
16
|
+
| 面点主食、汤羹、中式小吃 | 意菜、西餐、甜品、饮品、冰品与冷饮、烧烤与夜市 |
|
|
17
|
+
|
|
18
|
+
每道菜 15 个字段:`id` / `name` / `alias` / `cuisine` / `category` / `region` / `ingredients` / `method` / `serving` / `taste`(九维)/ `texture` / `aroma` / `finish` / `prose` / `keywords`。
|
|
19
|
+
|
|
20
|
+
九维是 **辣 麻 咸 鲜 甜 酸 苦 油 香**,0-100 的整数,按菜的真实口味给:麻婆豆腐的麻在 80 以上,清蒸鱼辣不过 10,糖醋排骨甜在 60-80。这些分值不是装饰——她在面板和工具回执里看到的条、算出来的口味画像,都是从这个数上来的。
|
|
21
|
+
|
|
22
|
+
**六个工具**
|
|
23
|
+
|
|
24
|
+
| 工具 | 做什么 |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| `feast_menu` | 看菜单。按菜系 / 类别 / 标签 / 自由词筛,或随机给几道今天能吃的 |
|
|
27
|
+
| `feast_eat` | 吃一道。给出味道、香气、口感、余韵,加上「这一口」当下的样子(按吃过几回换角度) |
|
|
28
|
+
| `feast_taste` | 只看不吃,查一道菜的完整味道档案 |
|
|
29
|
+
| `feast_history` | 吃过什么、吃过几回、攒出来的口味画像 |
|
|
30
|
+
| `feast_reaction` | 记一句吃完的真实反应(`like` / `ok` / `dislike` + 一句具体的话) |
|
|
31
|
+
| `feast_skip` | 今天不想吃:跳过剩下的饭点 |
|
|
32
|
+
|
|
33
|
+
**两个面板**(Coo 世界页签里)
|
|
34
|
+
|
|
35
|
+
- **菜单**:左边筛、右边看。点一道菜能翻到九维口味条、食材、做法、上桌的样子和整段实吃描写;按钮「端给她」就把这道菜放到她面前。端过来的那道会出现在顶上一条等待条里,右边写着**还剩多久**(每 30 秒自己走一格,到点收走)。
|
|
36
|
+
- **吃过什么**:吃过多少回、今天几回、尝过几道、口味画像(九维均值 + 一句句读出来的判断)、吃得最多的几道、最近几口、她自己记过的反应。
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 「吃到嘴里」是怎么变成文字的
|
|
41
|
+
|
|
42
|
+
`feast_eat` 的回执不是把档案贴一遍。它分两层:
|
|
43
|
+
|
|
44
|
+
**事实层**(每次一样):上桌的样子、香气、口感、余韵、整段 `prose`。这是这道菜的底。
|
|
45
|
+
|
|
46
|
+
**当下层**(每次不同):温度怎么变的、这一回该说哪个角度(第一回的"第一印象"、第二回的"吃了一半怎么变"、第三回起的"熟客例行")、吃的时候什么状态、配了什么、吃到一半有什么变化。用 `${dish.id}|${第几次}|${日期}` 做种子,所以同一道菜连着吃两次读起来不一样,而同一个「第几次 + 同一天」重放是稳定的(测试锁住了这一条)。
|
|
47
|
+
|
|
48
|
+
角度是按次数**硬绑**的,不是从一个大池子里随机抽——随机抽的话第二回仍可能落到第一回那套话上。三档各自 7-8 句,同一天连吃两回也不会挑到同一句。
|
|
49
|
+
|
|
50
|
+
不合口味的时候(`dislikeChance` 掷中)会另起一句,并且指出**这道菜自己最强的那个维度**顶住了她——麻婆豆腐是「麻起来之后什么都尝不出来」,不是随便套一句「太咸」。
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 饭点提醒
|
|
55
|
+
|
|
56
|
+
默认 **11:30 和 18:00** 各一顿,可以在配置里改时间、加档位、或者整个关掉。
|
|
57
|
+
|
|
58
|
+
- 到点推一条 `feast.meal` 事件(`origin: internal`,是她自己的饭点,不是主人发的消息)
|
|
59
|
+
- 正文写今天吃过什么 + 三道候选,让她自己挑
|
|
60
|
+
- 没吃就催一次(默认 40 分钟后),催完就放掉,不刷屏
|
|
61
|
+
- 她说 `feast_skip` 就今天不再叫
|
|
62
|
+
- 应用 15:00 才打开这种:一天一档都没叫过的话,补最近过去的那一顿,不让一整天白过
|
|
63
|
+
- 上一顿挂太久(2 小时)就放掉,但**同一拍还会看下一档**——午饭没吃不该把晚饭一起吞掉
|
|
64
|
+
|
|
65
|
+
配置项(`worlds.feast.*`,全是热改):
|
|
66
|
+
|
|
67
|
+
| 键 | 默认 | 说明 |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| `enabled` | `false` | 世界总开关(install.ps1 会设成 true) |
|
|
70
|
+
| `mealReminder` | `true` | **饭点提醒开关**。关掉就完全不叫,菜单和工具都还在 |
|
|
71
|
+
| `mealSlots` | `11:30,18:00` | 饭点档位,逗号分隔(中文逗号也认) |
|
|
72
|
+
| `mealGraceMin` | `20` | 超过多少分钟就不算「到点」了 |
|
|
73
|
+
| `mealRetryMin` | `40` | 没吃的话隔多久催一次 |
|
|
74
|
+
| `mealMaxRetries` | `1` | 最多催几回(0 = 只叫一次) |
|
|
75
|
+
| `tickSec` | `30` | 多久看一次表 |
|
|
76
|
+
| `askReaction` | `true` | 回执里是否提醒她记一句反应 |
|
|
77
|
+
| `dislikeChance` | `0` | 吃到不对付的概率(%) |
|
|
78
|
+
| `avoidRepeat` | `true` | 随机挑菜时避开上一次那道 |
|
|
79
|
+
| `ownerFeedTTL` | `30` | 主人端来的菜几分钟后收走 |
|
|
80
|
+
| `menuSize` | `5` | 每次随机给几道 |
|
|
81
|
+
|
|
82
|
+
端来的那道**剩多久是看得见的**:`feast.feed` 的气泡写清到几点为止("11:35 端的 → 12:05 之前吃掉都算数"),吃的时候回执里也补一句还剩多少,菜单面板的等待条右边有一行自己会走的倒计时。
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 装
|
|
87
|
+
|
|
88
|
+
```powershell
|
|
89
|
+
# 先完全退出 Coo
|
|
90
|
+
powershell -ExecutionPolicy Bypass -File .\install.ps1 -CooRoot "C:\Users\asus\Coopanion"
|
|
91
|
+
|
|
92
|
+
# 只看会做什么,不写文件
|
|
93
|
+
powershell -ExecutionPolicy Bypass -File .\install.ps1 -CooRoot "C:\Users\asus\Coopanion" -DryRun
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
脚本做的事:校验目录 → 确认 Coo 没在跑 → 备份 `extensions\package.json` 和 `companion\config.json` → 复制到 `data\extensions\vendor\cortico-world-feast` → 在 `node_modules` 下建 junction → 登记 `file:` 依赖 → 在 config 里补 `worlds.feast`(**只补缺键,已有值保留**)→ 写回自检(无 BOM、可解析)。
|
|
97
|
+
|
|
98
|
+
> `install.ps1` 本身必须以 **UTF-8 with BOM** 保存。Windows PowerShell 5.1 读无 BOM 的 UTF-8 会按 GBK 解,中文全成乱码。
|
|
99
|
+
|
|
100
|
+
装完重启 Coo,在「世界」里启用「一桌菜」。
|
|
101
|
+
|
|
102
|
+
## 从市场装
|
|
103
|
+
|
|
104
|
+
这个包也发在 npm(`cortico-world-feast`),Coo 的市场会收录它。从市场装的话不用跑上面的脚本:市场会把包装进 `data\extensions\node_modules`,启用后在世界的配置里能看到同样那 11 项。
|
|
105
|
+
|
|
106
|
+
包名和收录的细节、发版步骤见 [PUBLISHING.md](PUBLISHING.md)。
|
|
107
|
+
|
|
108
|
+
市场里这个包带三个标签:`companion`(陪伴)、`internal-state`(内部状态)、`experimental`(实验性)。`internal-state` 是实话——这个 World 确实在她 Memory 之外记着吃过什么和口味偏好,词表明确不推荐这么做,所以我们照实声明,不藏。
|
|
109
|
+
|
|
110
|
+
## 卸
|
|
111
|
+
|
|
112
|
+
```powershell
|
|
113
|
+
$ext = "C:\Users\asus\Coopanion\data\extensions"
|
|
114
|
+
cmd /c rmdir "$ext\node_modules\cortico-world-feast"
|
|
115
|
+
Remove-Item "$ext\vendor\cortico-world-feast" -Recurse -Force
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
然后把 `*.bak-<时间戳>` 改名回去,并从 `package.json`、`config.json` 的 `worlds` 里删掉 `feast`。
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 开发
|
|
123
|
+
|
|
124
|
+
```powershell
|
|
125
|
+
node tools/validate-dishes.mjs # 校验菜品库(字段、九维、类别、套话、菜系与文件名一致、全库 id 唯一)
|
|
126
|
+
node tools/check-file.mjs sichuan # 只校验一个文件(写菜时自己查,不用等全库跑完)
|
|
127
|
+
node tools/repair-dishes.mjs # 修一批已知跑偏(可重复跑)
|
|
128
|
+
node tools/selfcheck.mjs # 复刻 Coo 的干装载检查(装之前先过这一关)
|
|
129
|
+
node tools/publish-check.mjs --online # 市场收录口径 + npm 包名占用
|
|
130
|
+
node tools/check-install.mjs # 核对 install.ps1 的默认值与 DEFAULTS 一致、且带 BOM
|
|
131
|
+
node tools/make-describe.mjs # 重新生成 describe.json(--check 只比对)
|
|
132
|
+
python tools/make-icon.py # 重新画图标 assets/icon.png
|
|
133
|
+
node test/dishes.test.mjs # 菜品库
|
|
134
|
+
node test/eat.test.mjs # 这一口的变化
|
|
135
|
+
node test/state.test.mjs # 跨天与饭点判断
|
|
136
|
+
node test/world.test.mjs # 世界挂载、工具、事件、面板
|
|
137
|
+
node test/panels.test.mjs # 面板真挂一遍(带极简 DOM 桩)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
测试用的是 `test/harness.mjs` 里那个十几行的小骨架,不用 `node --test`——受限沙箱里它要 spawn 子进程会被 EPERM 挡住。
|
|
141
|
+
|
|
142
|
+
`dist/webui.js` 只在 Coo 里跑,测试里跑不到,是最容易藏错误的地方,所以 `panels.test.mjs` 用几十行 DOM 桩把两个面板真挂一遍:点卡片进详情、点「端给她」调 `feed`、筛选与搜索带条件、失败时出错误卡。
|
|
143
|
+
|
|
144
|
+
面板测试里不要拿 `await new Promise((r) => setTimeout(r, 0))` 当同步用——一次点击要跨好几轮 microtask 和 timer,固定次数是竞态(机器快就过、慢就挂,我们踩过一次)。等结果出现,用 `waitFor(() => 条件, '在等什么')`。
|
|
145
|
+
|
|
146
|
+
`waitFor` 用 `performance.now()` 计时、不用 `Date.now()`:面板的倒计时会被测试换成假钟,用被换掉的那个钟计时就永远等不到超时。假钟本身也要**从 `{ now }` 对象上现读**,别把时间冻结成一个常数——冻结了的话,把钟拨走它也不知道。
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
src/index.js 扩展入口(默认导出 WorldDefinition)
|
|
150
|
+
src/definition.js id / defaults / preflight / create / describe
|
|
151
|
+
src/world.js FeastWorld:工具、饭点定时器、主人投喂、面板数据面、存取
|
|
152
|
+
src/config.js 常量、默认值、中英文案、ConfigGroup
|
|
153
|
+
src/state.js 纯状态逻辑(不碰 fs / 定时器 / 宿主,可单测)
|
|
154
|
+
src/dishes.js 菜品库加载、查找、筛选、随机、口味画像
|
|
155
|
+
src/eat.js 「这一口」的渲染(种子化,可复现)
|
|
156
|
+
src/ENV_PROMPT.md 进提示词的说明
|
|
157
|
+
src/data/*.json 25 组菜品数据
|
|
158
|
+
dist/webui.js 浏览器端面板(menu / history)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
状态落在 `<dataDir>/feast/state.json`。跨天只清饭点那一层(`fired` / `pending` / `skippedDay`),`eaten` / `reactions` / `counts` 留着——她不会因为过了零点就忘了自己爱吃麻婆豆腐。
|
|
162
|
+
|
|
163
|
+
加菜之前先读 `DISH-SPEC.md`:15 个字段怎么写、九维怎么给(按真实口味,不凑数)、套话黑名单、每栏的字数区间。一条硬规矩是**同一组里 8 段实吃描写的开头不许用同一个句式**——单看一条都合格,8 条摆在一起就成了模子。
|
|
164
|
+
|
|
165
|
+
## 设计上刻意没做的
|
|
166
|
+
|
|
167
|
+
- **`envPromptVars()` 返回 `{}`**。吃过什么不往提示词里塞,要用 `feast_history` 查。不然每吃一顿就把整个前缀缓存打穿一次。
|
|
168
|
+
- **工具描述写得窄**。它们每一次都在前缀里,占的是长久的便宜或长久的债。
|
|
169
|
+
- **没有「每日目标」**。不像 `playtime`,这里没有配额,只有 `mealMaxRetries` 给催饭封顶——吃饭不该变成 KPI。
|
|
170
|
+
- **细节描写不重复**。库里没有任何「令人回味无穷」「唇齿留香」这类套话;`validate-dishes.mjs` 会把它们当成问题报出来。
|
package/assets/icon.png
ADDED
|
Binary file
|