Keep a persistent header guide button, restore upward label transitions, remove duplicate CSS and obsolete notice events, and move replay styling to CSS. Document proportional UX checks and interruption recovery checkpoints. Validated update_guide.mjs, 48-module parse/link check, diff check, and live ComfyUI manual open, Escape, replay, Help and sidebar keyboard labels. No backend behavior changed; mobile and alternate themes were not exercised.
118 lines
12 KiB
Markdown
118 lines
12 KiB
Markdown
# 开发与维护规范
|
|
|
|
适用于本插件的所有修改,包括 Gemini、Codex 和人工维护。目标是让 UX 持续改善,同时让代码职责、状态来源和验证方式保持清楚。
|
|
用户明确的当前要求优先;确需偏离本规范时,采用最小例外,在交付说明中写明原因、影响和验证。常规实现选择自行处理,不因本规范增加无必要的确认步骤。
|
|
|
|
## 1. 修改前先定位责任
|
|
|
|
1. 查看 `git status` 和相关差异,保留已有工作;不覆盖、回退或提交他人的无关修改。
|
|
2. 阅读 [ARCHITECTURE.md](ARCHITECTURE.md),再按阅读地图打开与任务有关的专题,避免每次加载全部文档。
|
|
3. 搜索目标函数的调用方、相关状态、CSS 选择器及已有辅助函数,再确定修改位置。
|
|
4. 简短说明本次行为变化和负责它的模块。一个修复优先落在能解释问题的最小责任范围内。
|
|
|
|
UX 请求默认允许调整布局、交互和文案,不代表允许改变文件存储位置、接口协议、工作流语义、模型识别依据或用户数据。
|
|
|
|
### 小型 UX 修改快速流程
|
|
|
|
仅调整文案、图标、颜色、间距或局部交互时:查看相关差异 → 定位负责规则 → 最小修改 → 验证受影响界面 → 本地提交。
|
|
同一任务已读过且未变化的规范不反复通读;只读相关专题,不做全仓审查,不顺手重构。
|
|
按第 7 节选择相关检查,不默认运行全部 JS/Python 测试。检查通过后,除非又改了代码或出现新问题,不重复运行。
|
|
没有改变职责、接口或持久化契约时,不更新架构文档或新增经验记录。提交说明由 AI 根据实际差异编写,无需用户代写。
|
|
|
|
### 任务中断后的接续与快照
|
|
|
|
- 开工先检查状态和差异。工作区干净时直接继续,不制造空提交。
|
|
- 上次因额度或其他原因中断,存在属于该任务的改动时,先确认文件范围,再选择性暂存这些文件;不得使用无差别的 `git add .` 收入用户数据、凭据、临时文件或无关工作。
|
|
- 已完成且有验证记录的改动可补正式提交;尚未验证或未完成的改动可先保存 `chore(checkpoint): <实际改动摘要>` 恢复快照,提交正文明确“未完成/验证待完成”、已做检查和下一步。快照是恢复点,不代表验收通过。
|
|
- 后续修改和验证另作正式提交,不自动 amend、reset 或改写快照历史。若无法区分遗留文件归属,保留原状并说明,不猜测打包。
|
|
- 长任务按可独立验证的完整阶段提交,避免把所有 Git 收尾留到最后。测试范围内检查完成后及时提交,不为额外润色拖延快照。
|
|
- 上述快照和正式提交均只保存在本地,未经明确授权不推送。
|
|
|
|
## 2. 模块职责与规模
|
|
|
|
- `web/main.js` 负责注册和接线;`ui_sidebar.js` 的 `createDOM` 负责外壳装配。新工具的完整实现放在自己的模块,不继续塞进这两个入口。
|
|
- 界面模块负责交互和渲染;组合、转换、校验等纯逻辑放在对应领域模块。底层模块不能反向导入上层界面,也不能读取 DOM 或选中节点来暗中决定业务行为。
|
|
- 一个模块应有可用一句话解释的主要职责。按“谁拥有状态、谁负责关闭、谁发起请求”拆分,不按随意的行号切割。
|
|
- 复用现有 `ui_lifecycle.js`、`ui_dom.js`、`translation_service.js`、`node_material_actions.js` 等接口。不要为同一行为再复制一套实现。
|
|
- 通用文件不能成为杂物箱。不要为了省一个文件,把新领域逻辑塞进 `utils`、素材详情渲染器或浏览器主对象。
|
|
- 不引入没有当前调用方的管理器、适配层、配置项、事件总线或依赖。一次性的简单逻辑可以留在其责任模块内。
|
|
|
|
**规模审查阈值:** 普通逻辑文件超过约 600 行,或单函数超过约 100 行时,新增功能前必须检查能否提取独立职责。继续扩展时,在交付说明中解释为什么仍属于同一职责。已有超大模块的小修复不要求顺手重写全文件;语言目录、数据表和样式表不按这个行数阈值拆分。不能通过空壳包装、压缩代码或碎片化文件绕过审查。
|
|
|
|
## 3. 状态、关闭与异步
|
|
|
|
- 每份可变状态只有一个权威来源。预览、计数、序列化结果从它派生,不维护几份会互相覆盖的数据。
|
|
- 子视图状态默认留在子视图。跨界面确需保留的状态才放到 `owner`;新增共享字段时说明拥有者、初始化、重置和释放时机。
|
|
- 父子视图传容器、必要数据和明确回调,不让子模块随意修改父视图的私有 DOM 和字段。
|
|
- 新建临时窗口优先使用 `createViewScope()`。按钮、Esc、遮罩、替换窗口、父窗口关闭必须走同一个清理入口;重复关闭应安全。
|
|
- 视图创建的全局事件、观察器、定时任务、拖拽监听和临时预览都要有对应释放路径。禁止仅 `element.remove()` 就当作关闭完成。
|
|
- 拖拽中关闭也必须释放鼠标监听,恢复此前的 cursor 和 user-select。子窗口消费 Esc 时,不能顺带关闭父窗口。
|
|
- 视图读取请求使用其生命周期的 `AbortSignal`;重新查询时取消或隔离旧请求。请求返回后检查当前视图和请求身份,不能让旧结果覆盖新内容。
|
|
- 异步写入画布前捕获原 graph/node/widget/value,返回后复核身份及输入;不能在返回后重新找“当前选中节点”然后直接写。
|
|
- 已发出的保存可能在窗口关闭后完成。不要假称取消了服务端写入,也不要让完成回调重新打开或修改已关闭的界面。
|
|
|
|
提示词工坊的具体状态约定见 [frontend.md](docs/architecture/frontend.md)。不要恢复已删除的嵌入式工坊、旧导入抽屉或第二套草稿来源。
|
|
|
|
## 4. CSS 和 UX 迭代
|
|
|
|
- 改样式前搜索同名选择器及主题、响应式覆盖,修改实际负责该属性的规则。禁止每轮都在文件末尾追加“最终修复 / override v2”覆盖包。
|
|
- 变更后删除本次取代的重复声明、失效选择器和旧布局分支;不能仅依靠更高 specificity 让旧实现暂时失效。
|
|
- 优先使用现有 `--amb-*` 设计变量。新增变量必须有实际用途和清楚的归属,不为每个常量包装一层变量。
|
|
- 不新增无解释的 `!important`。确因宿主样式或既有层叠边界需要时,在附近注释说明冲突对象与原因,并验证普通模式和受影响主题。
|
|
- 静态布局和外观放在 CSS。行内样式用于实际运行时值,例如拖动宽度、定位和数据决定的颜色,不用 JavaScript 重写整套固定样式。
|
|
- 保持插件选择器作用域,避免影响 ComfyUI 的其他按钮、弹窗和输入框。
|
|
- 添加功能时检查窄宽度、长中文、空列表、加载中、失败和禁用状态,以及焦点、键盘访问和嵌套窗口层级。
|
|
- 不为了视觉调整改变按钮的写入、覆盖、删除含义。成功提示必须来自真实成功结果,失败和取消不能显示“已应用”。
|
|
|
|
## 5. 文案、数据与文件
|
|
|
|
- 新增固定界面文案放入 `locales.js`,同步中英文;不继续增加散落的 `lang === 'zh' ? ... : ...` 分支。
|
|
- 用户输入、文件名、模型名和元数据通过 `textContent` 或已验证的转义工具进入 DOM;不要拼进未转义的 `innerHTML`。
|
|
- 列表摘要不能当作详情。正文通过对应详情接口读取;分页、去重、空结果和取消语义必须明确。
|
|
- 路径与文件名在后端使用现有边界校验;不能只检查 `..`。前端校验不能替代后端校验。
|
|
- 修改模型、封面、附属文件或导入包前先完整校验和暂存。失败时保留旧数据,避免先删除旧文件再尝试保存新文件。
|
|
- 修改多文件发布流程要覆盖中途失败和冲突。单个 JSON 的原子写入不能冒充整组文件的事务。
|
|
- 大目录遍历、哈希和大量磁盘 I/O 使用已有工作线程/进程路径,不阻塞 aiohttp 事件循环。
|
|
- UI 适配不能偷偷迁移用户数据、修改全局配置或改变现有路由与存储格式。确需改协议时同步调用方、兼容策略和测试。
|
|
|
|
## 6. 清理旧实现
|
|
|
|
- 替换一条路径时搜索它的导入、导出、调用、字段、事件和选择器;确认无用后一起移除。
|
|
- 不保留注释掉的大段旧代码、`EXTRACTED` 占位、无人使用的备选实现或“以后可能需要”的分支。
|
|
- 拆模块后检查移动函数引用的闭包变量、导入、回调参数和返回值。语法通过不代表按钮点击不会出现未定义变量。
|
|
- 不保留两个相互覆盖的 `onclick` 或两条完成同一请求的路径;让所有入口调用同一个实现。
|
|
- 不用空 `catch`、伪造成功值或任意 optional chaining 掩盖结构错误。可选宿主能力才允许局部降级,并给出准确结果。
|
|
|
|
## 7. 按风险验证
|
|
|
|
从插件根目录运行相关检查。选择与变化相称的验证,不为纯文案、文档或低风险样式改动制造镜像测试。
|
|
|
|
| 修改范围 | 至少验证 |
|
|
| --- | --- |
|
|
| 导入、导出、模块拆分 | JS 语法、模块链接,以及受影响按钮的真实执行路径 |
|
|
| 工坊状态与生命周期 | `node --experimental-vm-modules tests/prompt_ui_lifecycle.mjs` |
|
|
| 词卡读取、分页 | `node tests/prompt_material_source.mjs` |
|
|
| 翻译桥接 | `node tests/translation_service_contracts.mjs`,异步节点写入另跑工坊生命周期测试 |
|
|
| 素材应用、笔记隔离 | `node --experimental-vm-modules tests/material_workspace_flow.mjs` |
|
|
| 素材提示词协议、配方筛选、拖拽清理 | `node --experimental-vm-modules tests/studio_contracts.mjs` |
|
|
| CSS、布局、交互 | 实际浏览器验证受影响状态;涉及宿主行为时验证 ComfyUI |
|
|
| 文件修改、导入、存储 | 对应 Python 测试,至少覆盖成功、冲突和中途失败保留旧数据 |
|
|
| 仅文档 | 检查链接、命令、实际代码一致性和 Git 差异 |
|
|
|
|
- 模拟测试尽量加载实际模块,只替换外部系统边界;不要把待验证的业务函数也 mock 成成功。
|
|
- 修复故障时,优先补充能复现原故障的行为测试。不能只通过源码字符串“存在某段代码”来证明修复。
|
|
- UX 明确替换旧交互时,更新测试到新的用户流程,并保留原本要保护的行为;不要仅删除失败断言或重新塞回废弃功能。
|
|
- 新增应随仓库交付的回归测试要检查 `.gitignore`,确认确实进入版本控制。
|
|
- 历史本地 Python 测试可能不在 Git 中。使用合适环境运行相关测试,例如 `python -m unittest discover -s tests -p 'test_*.py'`,核对实际发现的数量;零项测试不算通过。
|
|
- 无法运行真实宿主、网络服务或完整测试时,准确说明缺口;不要将模拟画布、语法检查或已有通过数量称为本轮宿主验证。
|
|
|
|
## 8. 文档与交付
|
|
|
|
- 架构文档只记录职责、数据流、契约和关键约束。颜色、像素值及审美描述以 CSS 为准,不每次 UX 更新都往架构入口追加长篇设计说明。
|
|
- 改动架构时更新最窄的相关专题。修改规范时以本文件为唯一正文,`GEMINI.md` 只保留阅读入口,避免两套要求漂移。
|
|
- 完成前审查差异、死代码、临时文件和空白错误;保留现有文件编码及换行风格。
|
|
- 验证后按仓库约定形成一个连贯的本地提交,只包含本任务文件;没有明确授权不推送 GitHub。
|
|
- 交付说明包含:改了什么与原因、验证结果与限制、剩余问题、本地提交。仅在触发规模阈值或规则例外时额外解释取舍。
|
|
|
|
**交付自查:** 新职责放对位置了吗?是否只有一个状态来源?每条关闭路径会释放资源吗?迟到请求会写错对象吗?旧代码和旧 CSS 清掉了吗?新文案已本地化吗?用户文件失败时还在吗?测试验证了实际行为吗?
|