桌面应用开发工具【免费下载链接】MooToolHandy tool set for developers项目地址https://gitcode.com/gh_mirrors/mo/MooTool点击查看免费下载DIFF-572 是 MooTool next-compose 版本在 Electron 功能对等parity推进过程中的一个增量切片它把 F03 格式化工具的「文件 Tab」导入/另存逻辑收敛进ReformatWiringPresentation补齐了mooFileDropRow样式组件并新增了 Vault MCP stdio 双库 notes search→read 的 body offset 端到端测试。本文结合该文档与仓库源码讲解每一条改动背后的实现与验证依据读完可以掌握 Compose 版 F03 文件 Tab 的完整接线链路、Vault MCP 只读工具的调用约定以及本项目惯用的「切片文档 证据脚本 Compose 帧」验证模式。背景DIFF-572 在整个 parity 链中的位置根据 next-compose/docs/diff/572-reformat-mcp-css-slice.md 与 next-compose/docs/evidence/2026-09-14-parity-gap/results.mdMooTool 的 Compose 桌面版通过一串连续的 DIFF 切片逐步向 Electron 版对齐。DIFF-571 已完成 F04JsonWiringPresentation.run*、JSON 检查器样式与 Vault MCP 双库json search→readbody offset、Compose 帧 166DIFF-572 在其后继续推进F03 格式化工具的ReformatWiringPresentation.runReadSourceFile/runWriteResult/inferTypeFromFileNameElectron.file-drop-row对应的 Compose 样式mooFileDropRowVault MCP 双库notes search→readbody offset与 571 的 json search→read、567 的 notes search only、570 的 notes read only 链条相互区分。parity-gap 结果文档中明确记载截至该切片六套 CSS 逐选择器皮肤、产品主窗 Tab/IME/TCC PNG、P7 三平台安装仍未完成「目标未达成」。F03 格式化 run*文件读取、类型推断与结果写入读取源文件并推断格式类型ReformatWiringPresentation.runReadSourceFile是文件 Tab「导入」的核心入口实现位于 ReformatWiringPresentation.ktfun runReadSourceFile(file: File): ReadSourceOutcome runCatching { ReadSourceOutcome.Success( fileName file.name, content file.readText(StandardCharsets.UTF_8), inferredType inferTypeFromFileName(file.name), ) }.getOrElse { ReadSourceOutcome.Failure(it) }它一次性完成三件事以 UTF-8 读取文件内容、记录文件名、通过扩展名推断格式化类型。类型推断规则同样在 Presentation 层集中定义fun inferTypeFromFileName(fileName: String): ReformatType? { val ext fileName.substringAfterLast(., ).lowercase() return when (ext) { conf, nginx - ReformatType.Nginx java - ReformatType.Java xml, xsd, svg - ReformatType.Xml html, htm - ReformatType.Html else - null } }注意两点扩展名被统一lowercase()且svg/xsd会归入 XML 类型conf/nginx归入 Nginx 类型。支持的类型集合在 ReformatEngine.kt 中定义为enum class ReformatType { Nginx, Java, Xml, Html }并配有四种语言的内置示例文本samples。inferTypeFromFileName的映射行为在 ReformatWiringPresentationTest.kt 中被逐一验证App.java→Java、site.conf→Nginx、index.htm→Html、readme.txt→null。写入结果与默认另存文件名runWriteResult用 UTF-8 写回格式化结果fun runWriteResult(file: File, content: String): WriteResultOutcome runCatching { file.writeText(content, StandardCharsets.UTF_8) }.fold( onSuccess { WriteResultOutcome.Success }, onFailure { WriteResultOutcome.Failure(it) }, )而「另存」时默认文件名的生成逻辑defaultSaveFileName依据当前ReformatType决定扩展名Nginx→.conf、Java→.java、Xml→.xml、Html→.html并以去掉原扩展名后的文件名为基础若源文件名为空则回退为formattedval base sourceFileName.replace(Regex(\\.[^.]$), ).ifEmpty { formatted } return $base.$extension该行为在测试中有对应断言App.java Java →App.java空文件名 Nginx →formatted.conf。由于该函数在 DIFF-551 就已被引入DIFF-572 并未重做只在其后的切片中持续被复用。与 ReformatScreen 的 UI 接线文件 Tab 的 UI 侧由 ReformatScreen.kt 驱动loadSourceFile调用runReadSourceFile成功时把fileName/fileSource填入会话、清空fileResult并通过outcome.inferredType?.let { session.type it }自动切换格式化类型失败时走reformat.error.read文案与 error toast。saveResult调用defaultSaveFileName生成默认名、runWriteResult写盘成功后持久化导出目录persistToolsExportDirectory。因此导入/另存全部经过 PresentationrunCatching 直接读写不再散落在 Screen 各处——这正是 DIFF-572 所强调的「ReformatScreen 文件 Tab 导入/另存经 Presentation」接线目标。样式组件mooFileDropRowElectron 端.file-drop-row选择行在 Compose 端的对应物是mooFileDropRow修饰符定义于 Controls.kt/** Electron .file-drop-row 选择行10dp 间距 最小高度对齐 control。 */ Composable fun Modifier.mooFileDropRow(): Modifier heightIn(min 34.dp)它设定 34dp 的最小行高。而 10dp 间距来自FileDropRow组件内部同一文件的 Controls.ktRow( modifier modifier.fillMaxWidth().mooFileDropRow().then(dropModifier) .padding(if (onDropFiles ! null) 2.dp else 0.dp), verticalAlignment Alignment.CenterVertically, horizontalArrangement Arrangement.spacedBy(10.dp) ) { MooButton(chooseLabel, onClick onChoose, enabled enabled, p5Toolbar p5Toolbar) Text(fileName.ifEmpty { emptyLabel }, ... maxLines 1, overflow TextOverflow.Ellipsis) }FileDropRow是通用组件左侧「选择文件」按钮 右侧 11sp muted 省略文件名可选挂接desktopFileDropTarget支持系统文件拖放acceptMultiple控制多选并支持p5Toolbar密度与enabled禁用态。DIFF-572 引入该组件后F03 文件 Tab 直接复用它随后在 DIFF-573 等后续切片中被其他工具继续引用。Vault MCP stdio双库 notes search→read 的 body offset 分页调用约定Vault MCP 提供四个只读工具由 VaultMcpTools.kt 登记mootool_notes_search、mootool_notes_read随手记/Notes Vaultmootool_json_documents_search、mootool_json_documents_readJSON Vault工具的调用参数经过严格校验searchArgs与readArgs定义了明确的边界工具参数默认值范围*_searchquery最长 200*_searchlimit201–50*_searchoffset00–2000*_readpath必填非空、最长 1000*_readoffset00–2,000,000*_readlength200001–50000边界越界会直接抛错Invalid ...与 Electron 端vaultTools.ts的 Zod strict 语义对齐「不静默钳制」。search→read 的标准工作流在 MCP SKILL 中给出SKILL.md 明确要求「先 search把返回的相对路径交给对应_read工具按nextOffset翻页search 报告truncated时收窄查询而非声称穷尽返回的 note 内容不含 YAML metadata 头」。服务经McpLaunchResolver.clientLaunch以--mcp --access-file path启动子进程McpLaunchResolver.ktaccess 文件 JSON 形如{version:1,notes:...,json:...}可同时授权双库。双库场景下的端到端验证DIFF-572 对应的测试subprocessDualVaultNotesSearchThenReadHonorsBodyOffset位于 AiIntegrationVaultMcpConnectionTest.kt。它构造一个 notes 根含alpha.md/beta.md与一个 json 根两者同时写入同一 access 文件模拟「双库同会话授权」。随后mootool_notes_search以{query:572, limit:1, offset:1}翻页断言命中beta.md而非alpha.md——验证search 的 offset在双库授权下依然生效mootool_notes_read以{path:beta.md, offset:7, length:7}精确取 body 片段断言命中572tail且不出现skip572前缀——验证read 的 body offset/length。这条链路与 571json search→read、567notes search only、570notes read only刻意区分每个切片只补一类组合测试名以subprocessDualVault...前缀统一标识双库场景。同文件中 562–577 附近还有DualVaultNotesSearchHonorsOffsetWhenJsonGranted、DualVaultJsonReadThenNotesSearchHonorsBodyOffset等组合测试共同覆盖 search/read × notes/json 的排列可据此推断该测试类就是 MCP 双库矩阵的主阵地。证据脚本与 Compose 帧 167每个切片都会配套「证据」产出便于人工验收与产物归档mootool_evidence_print_reformat_file_drop_tab_focus_hint在 product-evidence-common.sh 中打印提示指出对应截图路径为docs/evidence/2026-09-15-inspector-screencapture/windows/167-compose-reformat-file-drop-tab-focus.pngverify-product-evidence-prep.sh 在全部证据准备脚本的冒烟校验通过后调用该 hint 函数用来核对脚本语法并登记产物位置。帧 167 由 ReformatFileDropCaptureTest.kt 生成它在 420×120 的 Compose 测试窗口内渲染FileDropRow选择按钮 无文件提示文本对按钮requestFocus()后截图到167-compose-reformat-file-drop-tab-focus.png并断言截图中出现不少于 8 个0x316DC0焦点环像素countRingPixels。因此该帧是非产品主窗的组件级焦点证据用于验证.file-drop-row在 Compose 端的最小行高、间距与焦点环呈现。验证方式DIFF-572 文档声明的验证链路与仓库中的实际测试一致均可离线复现ReformatWiringPresentationTest覆盖canRunFormat/formatActionEnabled守卫、复制/另存可用性、defaultSaveFileName、runFormat引擎调用、formatErrorMessage定位文案reformat.error.located携带 line/column、inferTypeFromFileName与runReadSourceFile临时文件读取见 ReformatWiringPresentationTest.ktAiIntegrationVaultMcpConnectionTest经真实StdioClientTransport启动 MCP 子进程执行 search→read 双库分页断言ReformatFileDropCaptureTest生成帧 167 并做像素级焦点环断言。命令行侧仓库提供两层校验./scripts/verify-product-evidence-prep.sh # 证据准备脚本语法 hint 输出 ./gradlew :composeApp:desktopTest --offline # JDK 21 下离线跑全部桌面测试未做与后续切片的衔接按文档声明DIFF-572 未做的内容包括Electron 六套 CSS 逐选择器的全量移植、产品主窗 F03/IME/TCC 的手工 PNG、P7 三平台安装/公证。后续 DIFF-573TextDiffPresentation.runReadImportFile、mooDiffToolbarOptions等 json search→notes read 帧 168开始承接下一批切片mooFileDropRow与 FileDropRow 也被后续 F02 等工具的导入行复用。这说明 DIFF-572 的价值不仅在于当次增量也在于为后续文件的 IO 接线提供了统一的 Presentation 模式与证据流模板。赞分享桌面应用开发工具【免费下载链接】MooToolHandy tool set for developers项目地址https://gitcode.com/gh_mirrors/mo/MooTool点击查看免费下载相关推荐MooTool NextComposeDIFF-570 解读F06 配置转换 run* 接线、validate CSS 与 Vault MCP 双库 notes read 分页MooTool NextComposeDIFF 570 解读F06 配置转换 run 接线、validate CSS 与 Vault MCP 双库 not桌面应用开发工具MooTool Next Compose 的 F06 配置工具接线与 Vault MCP 双库读取偏移DIFF-570 技术解析MooTool Next Compose 的 F06 配置工具接线与 Vault MCP 双库读取偏移DIFF 570 技术解析 导读 DIFF 570 是桌面应用开发工具MooTool next-compose 开发切片解读F 工具 run* 引擎接线、Vault 冲突/MCP 分页与 CSS 组件批次MooTool next compose 开发切片解读F 工具 run 引擎接线、Vault 冲突/MCP 分页与 CSS 组件批次 导读 DIFF 563桌面应用开发工具上一篇Repomix 的 Claude Code 官方插件MCP 服务器、Slash 命令与 AI 仓库探索实战指南下一篇Anthropic-Cybersecurity-Skills 技能库实战依赖混淆Dependency Confusion检测与防护完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考