零依赖、无转译:源码分成多段,桥接在请求 /support.js(prompts/ 在前、src/ 在后)与 /app.css 时按路径顺序即时拼接(子目录就地展开)(ETag 取各段的大小与修改时间),改一段刷新即生效;不落成文件,仓库里没有拼好的产物。
| 目录 / 文件 | 内容 |
|---|---|
src/ |
页面脚本,按领域分段,拼进同一个闭包:00-state 数据模型(Store / Conversation / Message / Step / Profile… 以 JSDoc typedef 写在顶部)与跨领域的页面状态,01-bridge 与桥接说话的唯一口子(接上、总线、bridge()),01-store/ 存储(各段自带自己的常量与簿记,90-open 在它们立起之后读出 store),其后是对话数据、笔意图标与小工具、Markdown、启动、言 / 行两态与欢迎页(06-mode-welcome/:目录与权限档位、欢迎页、目录签与附件签、开合对话)、渲染与画法(07-render/)、行迹(08-trail/)、附件、旁注、记忆、外观、输入区、文件与卷宗(13-files/)、对话引擎(14-chat-engine/:历史、进行中的活、发送、读流、轮次、拟题、系统提示、上下文压缩,以及信——帮手回报与后台指令结束的消息寄给该醒的那一个)、工具(15-tools/)、接口与余墨(16-api)、设置(17-settings/)、计数与导航、导出、意(19-intent/:一件工程要成立的结论图,存在目录的 .yan/意.json、跨对话沿用——理顺改动、判状态与回归、写给模型读的字,凭据的登记,读写与附着、收尾前对照,卡片上那张图的摆法与画法)、分组、听音、游目(26-stage/)。一块写大了就拆成同序号的子目录,里面各段照名字顺序就地展开,拼出来与一个文件无异。各领域自己的状态写在自己那一段开头,不往 00-state 堆。types.d.ts 是给类型检查用的全局声明,运行时不加载 |
| 登记表 | 扩展言的几处口子都是一张表,加一样东西只加一份登记:工具(src/15-tools/,一件一份:给谁用、可否并发、有无副作用、怎么执行、行迹怎么画、带给下一问的摘要;作答途中从外面递进来的话——补言、回报、传话——也登记在这张表里,replay 写明它给模型的那一条,当场递上与往后重装这一答(下一问、续写、压缩转写都经 answerParts)走同一个写法,递得进去的往后就重装得出来;交给模型的定义、执行、行迹卡片、出处都从这张表派生,另在 prompts/tools.js 写一段说明)、模型接口(server/model/ 的 PROVIDERS:往哪发、带什么头、请求体与事件流怎么换、怎么列模型、档位有无定表;页面只说 OpenAI chat.completions 的话)、设置栏(src/17-settings/00-panel.js 的 SETTINGS_TABS:画法与接事件一对,面板可写在自己的领域里)、系统提示(prompts/assistant.js 末的 order 表)、正文嵌件(src/04-markdown/00-markdown.js 的 EMBEDS:认哪种围栏、写到一半的占位、写完的样子、画进页面后起来的一步;交互网页是其中一份)、文件种类(src/13-files/00-kinds.js 的 FILE_KINDS:扩展名、大类、件图、预览器怎么看、正文怎么抽)、浮层(src/03-ui-utils.js 的 LAYERS:Esc 收最上面开着的一层,各层登记在自己那一段)、菜单(openMenu:一列项,按钮与点了做什么出自同一份)、消息动作(src/07-message-actions.js 的 MESSAGE_ACTIONS)、凭据(src/19-intent/05-anchors.js 的 ANCHOR_KINDS:意里一项凭什么成立——写法、多久取一回指纹、怎么取、怎么说给人听、罩不罩得住某个改过的文件;文件、目录、探针、测试各一份)。新功能先看它是哪张表的一份登记;哪张都不是,先立表再落第一份 |
styles/ |
样式,按层次分段(基础与主题、布局、欢迎页、对话、正文内容、文件、输入区、设置、行迹、组件、动效与响应式、纸墨皮肤);顺序即层叠顺序 |
i18n/ |
界面的英文译文表 en.js:键是界面上的中文原文(带变量的记作 {0},译文里 {0|question|questions} 按数挑单复数)。页面上给人看的字写成 t("…") 或 t`…${x}…`;桥接回的整句报错在显示处(提示条、对话里的报错、设置的状态行)过 tr(),逻辑里仍认中文原文。印章与给模型看的话不进表。选了英文才由 theme-boot.js 载入;test/i18n.mjs 会列出界面上漏翻的字 |
prompts/ |
内置提示词与工具说明,拼 /support.js 时排在最前(闭包之外),见其 README |
server.js · server/bus.js · server/model/ · server/web.js · server/search.js · server/headless.js · server/http.js · server/work/ · server/chats.js · server/store.js · server/files.js · server/video.js · server/sandbox.js · server/mcp/ · server/skills.js · server/env/ · server/mirror.js · server/stage.js · server/taskbar.js · server/platform.js · server/headless-proxy.js · server/checkpoints.js · server/timers.js · server/usage.js |
本机桥接:server.js 管门禁、接口表、静态与拼接,server/bus.js 是总线(一个页面一条事件流,长请求的响应都从它回去,页面只常占一条连接,不被浏览器同源六条连接的上限卡住),server/model/ 管模型转发(测试连接、列模型、对话;OpenAI 兼容、Anthropic、ChatGPT 订阅各一份登记;别家事件流换回 chat.completions 分块的骨架在 sse.js,各家只写一个事件换成什么;交给页面的只有事件流,流还是整份看正文开头,也只在这里判),server/web.js 管联网(地址门禁、翻网页、调接口;公网请求只经 fetchPublicResponse 一路),server/search.js 管检索(几家检索源登记成表、按序试,结果答非所问即换下一家),server/headless.js 是检索与翻网页兜底用的无头浏览器(本机 Edge / Chrome,按需起、闲三分钟关,页里每个请求都过地址门禁),server/http.js 是各接口共用的读写 JSON、出错回 400、收直传的原件与原子写盘;server/work/ 是执事接口(index.js 落点与沙箱筛查、指令与后台指令的接口并装配其余几段,files.js 写、读、改、下载,find.js 列目录与检索,intent.js 意的读写与内容指纹,paths.js 目录内外与越界链接,text.js 编码认读,shell.js 起指令、收进程树与后台指令,locks.js 同一文件的写锁,atomic.js 先写临时文件再替换的原子写,picker.js 系统的选择框(目录、文件))与卷宗目录接口(archive.js:列、收、取、删);对话目录接口(整读、存、删)、附件目录接口(存、取、删、清)与存储目录(配置的读写、换位置;有对话正作答时不换);MCP 服务池(起、连外部服务,列工具、调工具);技能(skills.js:照 SKILL.md 写法认存储根的 技能/ 一处,列出、只读技能目录之内的文件,并存、删);沙箱环境(装、查、清,给桥接起的进程接上);视频换壳(浏览器认不得的封装借环境里的 ffmpeg 换进 MP4);下载源自适应(mirror.js:环境与游目共用,镜像与官方各取一截比快慢);游目的浏览器接法(stage.js:给 Playwright 补调试口与放行,替页面问调试口地址;taskbar.js:屏幕外那扇窗不占任务栏);碰系统的几件事(platform.js:开网页、开文件、在文件管理器里显出、收进程树、找本机浏览器、读系统代理,Windows 与 macOS 各一份);无头浏览器的本机代理(headless-proxy.js:连接时只用验过的 IP);检查点(checkpoints.js:一答头一回动手前记下目录的样子,可整个退回;文件按内容哈希存一份,不靠 git);候的等时刻(timers.js:约好的时刻记在存储根,到点交给页面,重启不丢);用量簿(usage.js:页面报增量,按日按类加进 用量.json);沙箱的三道筛(指令、路径、环境变量)是纯函数,单独一段 |
test/ |
npm test 先跑 test/unit/(Node 自带的 node --test,把 src/ 拼起来在 Node 里测纯函数:工具参数救治、流式分段、diff 计数、余墨、思考档位、只读指令、输出裁行、沙箱筛查……几秒跑完),再跑端到端:起假模型接口、测试桥接与无头 Edge / Chrome,逐个跑用例(对谈、执事、言行合一与卷宗、差遣、旁注、记忆、分组、余墨与历史、表单、健壮性、桥接安全);以 Windows 为准,macOS 上也跑得通(指令类的测试数据按平台给 PowerShell 或 sh 写法,见 test/helpers/shell-command.mjs)。推到 main 与每个 PR 都由 GitHub Actions(.github/workflows/ci.yml)在 Windows 上跑单测、类型检查、格式检查与端到端,这两项挡合并;macOS 全套(类型、单测、端到端)也跑,不挡 |
pack/ |
Windows 便携包:pack.mjs 把运行所需的文件、官方 Node 与启动器 言.exe(launcher.cs,系统自带的 csc 编)打成 dist/yan-<版本>-win-x64.zip,见 启动与运行 |
build.js |
拼接规则(桥接与单元测试共用);npm run format 用 Prettier 统一格式,npm run check 用 tsc --checkJs 做类型检查(页面按 jsconfig.json,桥接按 jsconfig.server.json)——Prettier 经 npx 临时取用,TypeScript 与 Node 的类型表装进不入库的 node_modules(--no-save),只在开发时,不进运行时、不进依赖 |
内置提示词的写法、拼接次序与轻重之分,见 prompts/README.md。