[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6DT7KEAVA6PFXMA391GWWSE":3,"skill-same:01M6DT7KEAVA6PFXMA391GWWSE":64},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":21,"frontMatter":22,"refName":23,"commitSha":24,"skillDirectory":25,"forksCount":26,"repositoryHtmlUrl":27,"repositoryHomepageUrl":28,"ownerHtmlUrl":29,"ownerBlogUrl":30,"ownerDescription":6,"updatedAt":31,"install":32,"resources":45},"01M6DT7KEAVA6PFXMA391GWWSE","nimble-window",null,"liwusen\u002FFaustBot-llm-vtuber","liwusen","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F33620294?v=4","01M6DT6ES2QEX7T1WFY1MQ0K1A","allenlee","01M6DT6EWK9J0J4ZMC27B7XK2Z",45,"GPL-3.0","https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Fnimble-window\u002FSKILL.md",[],[18],"nimble window","2026-11-10 10:12:30",false,"# 灵动窗口（Nimble Window）技能\n\n灵动窗口是显示在虚拟形象旁的 HTML 小窗口，以小组件形式注册，用户可拖动\u002F缩放。\n本技能介绍窗口的创建方式、console 双向通信协议，并提供三个可直接使用的游戏模板（三子棋、五子棋、Wordle 猜词）。\n\n## 1. 创建窗口\n\n使用 `showNimbleWindowTool` 创建。html 参数支持两种形式：\n\n- 直接传 HTML 字符串；\n- `path:{URI}` 从文件加载，例如本技能自带的模板：\n  - `path:skill:\u002F\u002Fnimble-window\u002Ftictactoe.html` — 三子棋（井字棋）\n  - `path:skill:\u002F\u002Fnimble-window\u002Fgomoku.html` — 五子棋\n  - `path:skill:\u002F\u002Fnimble-window\u002Fwordle.html` — Wordle 猜词（你出题，用户猜）\n\n示例：\n\n```\nshowNimbleWindowTool(\n    html=\"path:skill:\u002F\u002Fnimble-window\u002Ftictactoe.html\",\n    title=\"三子棋对战\",\n    recall_text=\"正在和用户下三子棋，检查是否轮到你落子。\",\n    lifespan=3600,\n)\n```\n\n工具返回 callback_id，后续通信都围绕它进行。\n\n## 2. 双向通信协议（console）\n\n每个窗口在 VFS 暴露三个节点：\n\n| 路径 | 说明 |\n|------|------|\n| `faustbot:\u002F\u002Fnimble\u002F{callback_id}\u002Fsummary` | 窗口概览（自动生成，可用 write 覆写正文） |\n| `faustbot:\u002F\u002Fnimble\u002F{callback_id}\u002Fconsole` | 终端式对话记录（核心通信通道） |\n| `faustbot:\u002F\u002Fnimble\u002F{callback_id}\u002Fcode-readonly` | 窗口 HTML 源码（只读） |\n\nconsole 是累积式记录，格式如下：\n\n```\nFrontend>{\"game\":\"tictactoe\",\"board\":[[\"X\",\"\",\"\"],[\"\",\"\",\"\"],[\"\",\"\",\"\"]],\"last_move\":[0,0],\"turn\":\"agent\"}\nYou>{\"type\":\"move\",\"pos\":[1,1]}\n```\n\n- 前端页面调用 `nimble.sendMessage(createEventTrigger, payload)` → 追加 `Frontend>` 行；\n  createEventTrigger=true 时会用 trigger 唤醒你。\n- 你用 write 工具写入 console 路径 → 追加 `You>` 行，并实时发给页面的 messageHandler：\n\n```\nwrite(\"faustbot:\u002F\u002Fnimble\u002F{callback_id}\u002Fconsole\", '{\"type\":\"move\",\"pos\":[1,1]}')\n```\n\n保留命令（前端运行时拦截，不进 messageHandler）：\n\n- `{\"type\":\"command\",\"command\":\"close-window\",\"args\":{}}` — 关闭窗口\n- `{\"type\":\"command\",\"command\":\"set-scale\",\"args\":{\"scale\":1.2}}` — 设置缩放\n- `{\"type\":\"command\",\"command\":\"set-coord\",\"args\":{\"x\":0.5,\"y\":0.5}}` — 设置屏幕坐标（0~1）\n\n## 2.1 关闭窗口\n\n两种等价方式，任选其一：\n\n- 工具：`closeNimbleWindowTool(callback_id=\"nimble_xxx\")` — 直接关闭并清理 trigger 与 VFS 节点；\n- 命令：`write(\"faustbot:\u002F\u002Fnimble\u002F{callback_id}\u002Fconsole\", '{\"type\":\"command\",\"command\":\"close-window\"}')`。\n\n**你自己关掉的窗口不会再唤醒你**（不会有\"窗口已关闭\"的 trigger），所以关闭前该说的话要说完。\n反之，用户点右上角 × 关闭窗口时会唤醒你一次（payload 为 `{\"type\":\"window-closed\",\"reason\":\"closed_by_user\"}`），\n此时 console 节点已被删除，你只需知道\"窗口没了\"，不必再去读 console。\n\n## 3. 对弈游戏协议（模板已实现）\n\n### 3.1 棋类（三子棋 \u002F 五子棋）\n\n两个棋类模板使用同一套协议：**每步全盘状态携带**，你无需自己记住棋局。\n\n前端 → 你（用户落子后，trigger 唤醒你）：\n\n```json\n{\"game\":\"tictactoe\",\"board\":[[\"X\",\"\",\"O\"],[\"\",\"X\",\"\"],[\"\",\"\",\"\"]],\"last_move\":[1,1],\"turn\":\"agent\"}\n```\n\n- `board`：完整棋盘。三子棋 3×3，取值 `\"\"`\u002F`\"X\"`(用户)\u002F`\"O\"`(你)；\n  五子棋 15×15，取值 `\"\"`\u002F`\"B\"`(用户执黑)\u002F`\"W\"`(你执白)。\n- `last_move`：用户刚下的 `[row, col]`。\n- `turn`：`\"agent\"` 表示轮到你。\n\n你 → 前端（写 console）：\n\n```json\n{\"type\":\"move\",\"pos\":[row,col]}\n```\n\n页面负责落子渲染与胜负判定。若你下了非法位置（已占用\u002F越界），页面会回发：\n\n```json\n{\"game\":\"...\",\"type\":\"invalid_move\",\"reason\":\"cell occupied\",\"board\":[...],\"turn\":\"agent\"}\n```\n\n此时请重新选择位置。游戏结束时页面发送（不唤醒，仅记录）：\n\n```json\n{\"game\":\"...\",\"type\":\"game_over\",\"winner\":\"user|agent|draw\",\"board\":[...]}\n```\n\n对弈建议：收到 trigger 后先读 console 确认最新盘面，再落子；不要凭记忆下棋。\n\n### 3.2 Wordle 猜词（你出题，用户猜）\n\n模板：`path:skill:\u002F\u002Fnimble-window\u002Fwordle.html`。规则：6 次机会猜一个 5 字母英文单词，每次猜测后每个字母给出反馈（绿=位置正确、黄=字母在词中但位置不对、灰=词中没有该字母）。\n\n**你负责出题**，流程是「创建窗口 + 立刻下发题目」两步（同一次回复里连续两个工具调用即可）：\n\n```\nshowNimbleWindowTool(\n    html=\"path:skill:\u002F\u002Fnimble-window\u002Fwordle.html\",\n    title=\"Wordle 猜词\",\n    recall_text=\"正在和用户玩 Wordle，用户每次猜测后都会唤醒你，检查 console 最新一条 Frontend> 行。\",\n    lifespan=3600,\n)\nwrite(\"faustbot:\u002F\u002Fnimble\u002F{callback_id}\u002Fconsole\", '{\"type\":\"set-word\",\"word\":\"CRANE\",\"hint\":\"常见名词\"}')\n```\n\n- `word`：必填，**必须恰好 5 个 A-Z 字母**（大小写均可，页面统一转大写）。页面不接受非 5 字母内容，会回发 `error` 让你重发。\n- `hint`：可选，显示在状态栏下方的一行灰字提示（如词性、主题、首字母）。**绝不要在 hint 里泄露答案**。\n- 判分由页面本地完成并即时上色，不需要你逐字母判断，你也不必在回复里复述判分结果。\n\n前端 → 你（**每一次有效猜测都会 trigger 唤醒你**，含猜对的那一次）：\n\n```json\n{\"game\":\"wordle\",\"type\":\"guess\",\"guess\":\"CRANE\",\"result\":[\"correct\",\"absent\",\"present\",\"absent\",\"absent\"],\n \"solved\":false,\"finished\":false,\"attempts_used\":1,\"attempts_left\":5,\n \"board\":[{\"guess\":\"CRANE\",\"result\":[...]}]}\n```\n\n- `result`：每个字母的判定，取值 `correct` \u002F `present` \u002F `absent`。\n- `solved`：本次猜中；`finished`：本局结束（猜中或 6 次用尽）。\n- `attempts_used` \u002F `attempts_left`：已用与剩余次数。\n- `board`：本局全部历史猜测（每步全量携带，你不必凭记忆还原进度）。\n- 非法输入（长度\u002F字符不对）由页面本地拦下，不会唤醒你，也不会消耗次数。\n\n其他前端 → 你的消息：\n\n```json\n{\"game\":\"wordle\",\"type\":\"restart_request\"}                    \u002F\u002F 用户点了「换一题」，请重新下发 set-word\n{\"game\":\"wordle\",\"type\":\"error\",\"reason\":\"...\",\"got\":\"...\"}    \u002F\u002F 你的 word 不合法（不是 5 个 A-Z 字母），请重新下发\n{\"game\":\"wordle\",\"type\":\"revealed\",\"answer\":\"...\",\"attempts_used\":2,\"board\":[...]}  \u002F\u002F 你主动 reveal 后页面的回执\n```\n\n你 → 前端（写 console）：\n\n```json\n{\"type\":\"set-word\",\"word\":\"CRANE\",\"hint\":\"常见名词\"}   \u002F\u002F 出题 \u002F 换题（会清空棋盘）\n{\"type\":\"reveal\"}                                     \u002F\u002F 直接公布答案（用户放弃时用）\n```\n\n互动建议：收到 `guess` 后可以就着反馈吐槽或打气（例如「黄了？再想想」），然后等下一次唤醒；猜中时给点祝贺，6 次用尽时公布答案并可以再发一个 `set-word` 直接开下一局。\n\n## 4. 页面内可用的 JS API（写自定义 HTML 时参考）\n\n脚本以 `new Function('nimble', code)` 执行，`nimble` 对象为每窗口独立注入：\n\n- `nimble.sendMessage(createEventTrigger:bool, payload)` — 发消息给你（Promise）,createEventTrigger代表是否使用EventTrigger唤醒你\n- `nimble.setMessageHandler(func)` — 接收你写入 console 的消息（保留命令除外）\n- `nimble.resize(width, height)` \u002F `nimble.setFullscreen(enabled)` \u002F `nimble.getConfig()`\n- 元素加 `class=\"nimble-pass-through\"` 可在点击穿透模式下不阻挡桌面操作\n- 可以读取三个模板来学习API使用方法\n\n**窗口是亮色主题**：外壳背景为 `rgba(255,255,255,0.94)`、文字色 `#1a2433`。自定义 HTML 必须使用深色文字与浅色块，可直接抄模板配色：\n\n| 用途 | 取值 |\n|------|------|\n| 主文字 | `#1a2433` |\n| 次要文字 | `#647086` |\n| 描边\u002F分隔 | `rgba(190,201,217,0.9)` |\n| 主色（按钮\u002F强调） | `#3f6be8` |\n| 浅色块底 | `#eef1f6` |\n| 警示\u002F强调红 | `#e54447` |\n\n不要写 `color:#fff` 之类的浅色文字，在白底窗口里会看不见。\n\n注意：模板内使用了固定的元素 id，同一游戏模板同时只开一个窗口。\n",{},"main","9b6375444e3dd715ef960debd9a6a23875aa3e31","backend\u002Fskill_template\u002Fnimble-window",4,"https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber","https:\u002F\u002Ffaustbot.allenlee.xyz","https:\u002F\u002Fgithub.com\u002Fliwusen","https:\u002F\u002Fallenlee.xyz","2026-10-29 21:25:43",{"source":7,"skillName":5,"commands":33,"prompt":43,"zipAvailable":44},[34,37,40],{"tool":35,"command":36},"npx","npx skills add liwusen\u002FFaustBot-llm-vtuber --skill nimble-window",{"tool":38,"command":39},"bunx","bunx skills add liwusen\u002FFaustBot-llm-vtuber --skill nimble-window",{"tool":41,"command":42},"pnpm","pnpm dlx skills add liwusen\u002FFaustBot-llm-vtuber --skill nimble-window","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Fnimble-window\u002FSKILL.md",true,[46,52,56,60],{"path":47,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":50,"sourceHtmlUrl":51},"_meta.json","REFERENCE","参考文档",430,"https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Fnimble-window\u002F_meta.json",{"path":53,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":54,"sourceHtmlUrl":55},"gomoku.html",4556,"https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Fnimble-window\u002Fgomoku.html",{"path":57,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":58,"sourceHtmlUrl":59},"tictactoe.html",4169,"https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Fnimble-window\u002Ftictactoe.html",{"path":61,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":62,"sourceHtmlUrl":63},"wordle.html",9352,"https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Fnimble-window\u002Fwordle.html",[65,75,89,95,101,109],{"skillNo":66,"name":67,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":19},"01M6DT7RGPMB7EERSG4H3RV3DR","self-improvement-using-agile","https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Fself-improvement-using-agile\u002FSKILL.md",[],[71,72,73,74],"agile","self improvement","self","self improvement using agile",{"skillNo":76,"name":77,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":85,"publishedAt":19},"01M6DT7P6KWAMXPH4933661G36","plugin-creation","https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Fplugin-creation\u002FSKILL.md",[80],{"categoryNo":81,"categoryName":82,"taxonomyType":83,"taxonomyTypeDesc":84},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[86,87,88],"plugin","creation","plugin creation",{"skillNo":90,"name":91,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":94,"publishedAt":19},"01M6DT7F7C525SCTH5D3DXTEJK","minecraft","https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Fminecraft\u002FSKILL.md",[],[91],{"skillNo":96,"name":97,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":19},"01M6DT7CKB243AY1S7KC7569EV","gesellschaft","https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Fgesellschaft\u002FSKILL.md",[],[97],{"skillNo":102,"name":103,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":104,"categories":105,"keywords":106,"publishedAt":19},"01M6DT7ANWB1F7DX98BV8XFY1S","faustbot-using-guide","https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Ffaustbot-using-guide\u002FSKILL.md",[],[107,108],"guide","faustbot using guide",{"skillNo":110,"name":111,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":112,"categories":113,"keywords":114,"publishedAt":19},"01M6DT76MTHWPVXS99266PQCBX","desktop-mood-rules","https:\u002F\u002Fgithub.com\u002Fliwusen\u002FFaustBot-llm-vtuber\u002Fblob\u002Fmain\u002Fbackend\u002Fskill_template\u002Fdesktop-mood-rules\u002FSKILL.md",[],[115,116,117],"desktop","Rules","desktop mood rules"]