news 2026/10/4 9:01:35

面向 Agent 与开发者的 MiaoYan 仓库工程指南:构建、测试、CI 与高风险区域全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
面向 Agent 与开发者的 MiaoYan 仓库工程指南:构建、测试、CI 与高风险区域全解析
  • 桌面应用
  • CLI

【免费下载链接】MiaoYan

⛷ Lightweight Markdown app to help you write great sentences.

项目地址:https://gitcode.com/gh_mirrors/mi/MiaoYan
点击查看免费下载

MiaoYan 是一个基于 Swift/AppKit 的轻量级 Markdown 编辑器(macOS 原生应用),本指南以仓库根目录的 AGENTS.md 为核心骨架,结合 Package.swift、.github/workflows/ci.yml、Helpers/Diagnostics.swift 等源码证据,系统讲解该仓库面向 AI Agent 与人类开发者的协作约定:本地构建验证命令、单元测试接入、CI 流水线、错误上报机制、发布渠道,以及当前维护者明确标注的高风险代码区域。读完本文,你可以安全地在该仓库中定位问题、修改代码、跑通验证并理解每一次改动可能触碰的隐式约束。

仓库定位与维护模式

MiaoYan 是一个用 Swift 编写、基于 AppKit 的轻量级 Markdown 编辑器,通过 GitHub Release、Sparkle 自动更新和 Homebrew 三种渠道直接分发下载。自 2026-09-28 起,该开源仓库进入维护模式:只接受严肃的缺陷修复("it takes serious fixes only")。所有新功能与界面工作集中在私有仓库tw93/MiaoYan-Pro(App Store 版、iPhone/iPad 应用),该仓库的任何内容不会回推到这里;两边都需要的修复会以独立 commit 手工移植进来。

这一点决定了本指南的基调:在此仓库提交改动,应当以修复缺陷、保持既有行为一致性为优先,而非引入全新功能。

技术栈一览

从 Package.swift(swift-tools-version: 6.0)与 AGENTS.md 可确认核心技术选型:

能力技术备注
Markdown 解析swift-cmark-gfm(1.0.2)GitHub Flavored Markdown 语法
语法高亮Highlightr(2.3.0)编辑器与预览代码高亮
数学公式 / 图表LaTeX、Mermaid、PlantUML由预览渲染管线支持
幻灯片模式Reveal.js---分隔符切分幻灯片
自动更新Sparkle(2.8.0)直接下载版更新通道
快捷键KeyboardShortcuts(2.4.0)用户可自定义快捷键
自动格式化Prettier(0.2.1)编辑器内集成自动格式化

平台声明为 macOS 11+ 与 iOS 18+(后者的 App Store 版本实际构建于私有仓库)。笔记存储采用文件系统方案:文件夹嵌套、文件系统监听、自动保存与版本历史;编辑器提供实时预览、语法高亮、键盘快捷键与 Prettier 集成的自动格式化。

仓库目录地图

AGENTS.md 给出了明确的目录职责划分,与 ARCHITECTURE.md 的顶层结构相互印证:

  • Controllers/:视图控制器与窗口控制器(AppKit)。
  • Views/:UI 组件(NSView/NSOutlineView/NSTableView子类)。
  • Business/:模型与业务逻辑(Storage、Note、Project、WikilinkIndex 等核心域)。
  • Helpers/:工具与服务(高亮、格式化、主题、诊断)。
  • Extensions/:对 Foundation / AppKit 类型的 Swift 扩展。
  • Resources/:内置资源,含DownView.bundle(预览用的 HTML/CSS/JS)。
  • MiaoYan.xcodeproj/:Xcode 工程与版本设置(pbxproj)。
  • Package.swift:Swift Package 依赖声明与支持平台。
  • scripts/:本地构建、发布与工程维护脚本;scripts/release-ci/负责发布说明渲染、appcast、公证与打包辅助。
  • skills/miaoyan/:对外发布的 Agent Skill(受版本管理),描述 MiaoYan 的 Markdown、PPT 与miaoCLI 接口面。
  • .github/RELEASE_NOTES.md:GitHub Release 与 appcast body 的公开发布说明来源。
  • .github/workflows/:仅含ci.yml;发布构建不由受版本管理的 release workflow 驱动。

本地构建与验证命令

AGENTS.md 给出的标准命令集是任何改动进入 CI 前的"准入清单":

# 1. Debug 构建(Swift / 工程改动的默认验证方式) xcodebuild -project MiaoYan.xcodeproj -scheme MiaoYan -configuration Debug build # 2. 清理 xcodebuild clean # 3. 跑单元测试(注意 CODE_SIGNING_ALLOWED=NO) xcodebuild test -project MiaoYan.xcodeproj -scheme MiaoYan -destination 'platform=macOS' CODE_SIGNING_ALLOWED=NO # 4. 静态检查(--strict 是 CI 门槛) swiftlint lint --strict swift-format lint --recursive . --strict # 不加 --strict 的本地通过仍可能被 CI 拦截 # 5. 构建发布产物(Developer ID、公证、Sparkle) bash scripts/build.sh # 6. 仅在 pbxproj 重置后重新接线测试 target 时使用 ruby scripts/add_tests_target.rb

关键原则:优先使用范围最窄的相关命令;Swift 或工程改动一律以完整 App 构建作为默认验证。需要注意swift-format的--strict不是可选项——项目的 .swift-format 关闭了代码库刻意违反的规则(PascalCase 枚举成员、retroactive NSTextStorageDelegate、块注释、forEach),剩余的告警是真实的,会直接卡住 CI。

新增源文件的 pbxproj 注册(四个位置)

该项目使用经典 pbxproj groups,没有文件系统同步组(filesystem-synchronized groups)。新增一个源文件必须在MiaoYan.xcodeproj/project.pbxproj中手动注册四处:

  1. PBXBuildFile条目;
  2. PBXFileReference条目;
  3. 所属 group 的children列表;
  4. target 的PBXSourcesBuildPhasefiles 列表。

做法是模仿一个现有同层条目,并为每个新对象使用全新的 24 位十六进制唯一 ID。这一步极易遗漏,是新手贡献者最常见的失败点。

单元测试实践

单元测试位于MiaoYanTests/下,覆盖面聚焦纯逻辑接口(ImageLinkParser、WikilinkIndex.updateNote、String+扩展等,对应仓库中的 ImageLinkParserTests.swift、WikilinkIndexTests.swift、StringExtensionsTests.swift 等测试文件)。UI 流程不做 XCUITest,而是靠构建后的人工冒烟验证。

新增测试的规范步骤:

  1. 创建MiaoYanTests/<Subject>Tests.swift(XCTest;若测试方法触碰@MainActor隔离类型则给方法加@MainActor;setUp()覆写不能是@MainActor,需要在测试方法内部构造隔离对象)。
  2. 与 App 源码一样,手动注册到 pbxproj 的同一四个位置,但挂到MiaoYanTestsgroup 和MiaoYanTeststarget 的PBXSourcesBuildPhase,参照现有NoteFrontmatterTests.swift条目。scripts/add_tests_target.rb在 target 已存在时是空操作(它只在 pbxproj 重置后做引导),且它依赖的xcodeprojgem 在本机并未安装。
  3. 本地跑xcodebuild test ...通过后推送。

为什么必须带 CODE_SIGNING_ALLOWED=NO

本地测试命令必须带CODE_SIGNING_ALLOWED=NO,因为MiaoYan.app使用的开发签名身份与MiaoYanTests.xctest使用的逐开发者身份最终得到不同的 Team ID,导致 dyld 拒绝把测试 bundle 加载进宿主 App。这不是本地特例:.github/workflows/ci.yml对每次xcodebuild调用都传了同一标志。

CI 流水线解读

.github/workflows/ci.yml在每次 PR 与 push 到main时运行,共四个 job:

  1. build-mac(macOS Debug 构建 + 单元测试):运行于macos-15,固定DEVELOPER_DIR为 Xcode 16.3;先-resolvePackageDependencies,再xcodebuild build,随后xcodebuild test,全程CODE_SIGNING_ALLOWED=NO(免签名),输出经xcbeautify转为 GitHub Actions 格式。
  2. lint(SwiftLint + swift-format,双 --strict):brew install swiftlint后跑swiftlint lint --strict;再安装 swift-format 并跑swift-format lint --recursive . --strict。任何 warning 都是合并门槛。
  3. release-notes-smoke(发布说明渲染冒烟):在 ubuntu 上跑scripts/release-ci/notes_to_html.sh与render_release_body.sh渲染.github/RELEASE_NOTES.md,并断言输出非空。这样坏掉的发布说明文件会在发布前而不是发布中被发现。
  4. version-consistency(版本三元组一致性):仅在 tag push(refs/tags/V*)时触发,从project.pbxproj提取所有MARKETING_VERSION与CURRENT_PROJECT_VERSION值,逐一断言等于去除V前缀的 tag。注意它收集的是去重后的全部值而非第一个匹配,因为 V3.5.1/#524 事故正是单个 target 失同步造成的(详见下文"发布说明规范")。

CI不运行公证与 Sparkle 签名脚本——它们需要维护者托管的签名密钥,只在维护者本机执行。

错误上报机制:trackError 单一漏斗

AppDelegate.trackError(_:context:)是运行时错误的唯一上报入口(Controllers/AppDelegate.swift):

  • DEBUG:仍打印到 stdout,保留给 Xcode 控制台工作流。
  • RELEASE:路由到 Helpers/Diagnostics.swift,写入一条.fault级os_log,同时写入~/Library/Logs/MiaoYan/diagnostics.log的 JSON 行环形缓冲(上限 50 条,每条含ts/ctx/domain/code/desc字段)。50 条的容量约对应 50 KB 文件,足够容纳一次典型事故的可粘贴诊断块。

接入新失败路径时,应当调用AppDelegate.trackError(error, context:)而不是print(...)或try?静默吞掉;context字符串是维护者排查时唯一的 breadcrumb。实际调用点遍布各处,例如 ViewController+Editor.swift 的格式化失败、ViewController+Action.swift 的重命名失败,以及编辑器所有者漂移守卫 ViewController.swift(context: "ViewController.textDidChange.ownerGuard")。

工程约定与工作规则

AGENTS.md 将产品偏好与硬性代码规则并列,是贡献者必须遵守的隐性约束。

产品偏好

  • 付费用户视角:默认按 App Store 付费版的精致度做,每次视觉/交互改动先问"对得起付费用户吗"。
  • 预览边界:图片、视频、iframe 必须保持在max-width: 100%内;宽表格允许在.table-scroll内滚动,但不得撑宽页面;PDF/PNG 导出必须把表格适配到输出宽度(导出内容不能滚动)。改表格布局时要同时复核初始渲染、增量更新与重复导出。
  • 设计参考:UI/CSS 抄不出来时参考维护者已满意的样式(~/www/weekly、~/www/tw93.github.io),不要凭空发挥。
  • 视觉方向:macOS 26 风格 sidebar(玻璃态、透明、最新一代 SF Symbols)是长期方向,但不要整体重设计——一次整机改造已被维护者否决;打磨侧栏/按钮应做小步增量(间距、对齐、hover、focus、字重)。
  • 快捷键约束:cmd-数字已占满 0–5(1 侧栏、2 笔记列表、3 Toggle Preview、4 Toggle Presentation、5 TOC、0 Actual Size)。新增前先grep 'keyEquivalent="N"' Resources/Localization/Base.lproj/Main.storyboard核对,绑定只存在于 storyboard,代码里没有 keyBindings 表。

工作规则

  • UI 更新保持在主线程。
  • 除非不变量明显且局部,否则避免 force unwrap。
  • 新代码优先AppEnvironment.current.<service>而非直接访问单例。.swiftlint.yml 中的no_direct_singleton_in_new_code自定义规则在配置里是severity: warning,但 CI 跑--strict会把它提升为合并门槛;存量调用点已豁免(grandfathered),不要把新文件加进豁免列表。
  • 文件写入限定在用户文档或 App 控制的路径内。
  • 没有明确用户需求,不引入网络调用、shell 执行或宽泛的文件访问。
  • 编辑器核心、预览管线与既有 storyboard 场景保持 AppKit;仅全新的独立面板可通过NSHostingView承载 SwiftUI,不得借此把 SwiftUI 推进EditTextView/MPreviewView/ViewController。
  • 删除流程必须可恢复:笔记与附件应走与当前上下文匹配的 App 废纸篓或系统废纸篓,而不是直接消失。App 废纸篓可能解析为卷上系统废纸篓同一目录,对已在此处的条目再次调用FileManager.trashItem会原地改名使其"复现",需用AppIdentifier.removedFromTrashKey标记并在 Trash 项目内排除该标记,保证 Finder 恢复到普通项目后仍然可见。
  • iCloud 同步与符号链接目录属于文件系统敏感面:刻意解析路径,避免循环或重复索引。

高风险区域深度解析(改动前必读)

AGENTS.md 用大量篇幅标注了"当前风险区域"——这是全文技术密度最高的部分,任何修改触碰这些区域都必须理解其隐式不变量。

编辑器缓冲区所有权(#543)

在预览/演示/PPT 模式下,EditTextView.note跟随列表选择,而textStorage保留的是最后编辑的笔记内容,二者合法地分叉。EditTextView.storageNote(Views/EditTextView.swift)记录缓冲区属于哪条笔记:

  • 所有整体存储赋值必须走publishStorage(_:owner:)(Views/EditTextView.swift),它同时写入字节并记录 owner;
  • 所有整缓冲区持久化必须走saveTextStorageContent(to:)(Views/EditTextView.swift),它会拒绝跨笔记写入(owner 与目标 URL 不一致时报错并调用trackError);
  • 绝不允许仅凭EditTextView.note或表格选择来持久化缓冲区;也绝不用EditTextView.note与自身比较作守卫——正是这个同义反复(tautology)导致了 V4.0.0 的内容互换事故。

侧栏横向布局

横向布局由SidebarProjectView.tile()独占(Views/SidebarProjectView.swift):reload 与 resize 后,outline 框架与第一列必须匹配 clip-view 宽度,且 clip-view 水平原点必须保持为零。不要用事件特定的宽度重置替换这个不变量。

Wikilink 与反向链接

依赖 Business/WikilinkIndex.swift 及笔记加载、搜索、侧栏刷新行为。保持[[note]]解析、递归搜索与废纸篓排除一致(测试见 WikilinkIndexTests.swift)。

iCloud 同步

位于 macOS 存储与 Business/CloudSyncManager.swift。iCloud 不可用时要验证回退行为。

废纸篓处理

横跨 Business/Storage.swift、Business/Note.swift、侧栏拖放、附件清理与系统废纸篓回退。成功移除的笔记必须在其 watcher、编辑器、生命周期 flush 或上传回调再次保存之前退役(retire)对应Note实例;对已消失文件的既有笔记写入必须"失败关闭";UI 行只能在文件系统操作成功后移除。

版本历史

位于 Business/NoteVersionManager.swift 与 Controllers/VersionHistoryViewController.swift。保持文件 IO 不在主线程、UI 更新在主线程。

导出管线

  • PNG 导出:每次调用都必须准备当前 DOM、注入导出样式并等待媒体;清理会移除这些样式,所以缓存中的笔记内容不能证明后续导出已就绪。
  • Mermaid 与 PDF 导出:横跨 Business/HtmlManager.swift、Helpers/PdfExportController.swift、Extensions/MPreviewView+Export.swift。捕获前必须等待图片与 Mermaid 渲染完成(测试见 MermaidExportTests.swift)。

笔记列表搜索

Controllers/ViewController+Data.swift 先按文件夹范围过滤,再把纯值NoteSearchCandidate交给 detached task 中的NoteContentMatcher,后者从磁盘读取未加载的正文;主线程只做快照与应用结果。绝不在主线程加载或小写化笔记正文,标题匹配不带.md扩展名。

异步加载

异步笔记/图片/文件加载是刻意的,不要为大型笔记或预览重新引入主线程阻塞读取。

附件约定与图片上传

  • 附件遵循共享的i/约定:图片放在笔记旁i/文件夹,引用为![](/i/<name>);App Store iPhone 应用读取同一约定,必须保持稳定。
  • 图片上传通过本地 PicGo/PicList HTTP 端点127.0.0.1:36677(Helpers/ClipboardManager.swift)。macOSInfo.plist的 ATS 经NSAllowsLocalNetworking放行该端点;不要放宽回NSAllowsArbitraryLoads。Markdown 预览通过loadFileURL(file://)加载而非本地 Web 服务器,所以 ATS 不约束预览渲染。

Markdown 渲染单一漏斗

renderMarkdownHTML(Business/Markdown.swift)是预览、分栏、导出、PPT 与动作的唯一 markdown→HTML 漏斗。后渲染变换(如 GitHub Alerts 引用块改写为 callout)必须放在该函数末尾,绝不能在各个调用点分别做。Alert 样式位于DownView.bundle/css/typography.css,深色覆盖在theme-dark.css(.darkmode *颜色规则强制显式重述深色值)。

Frontmatter 剥离是逐表面不变量

每个输出笔记或 markdown 内容的表面(macOS 预览/导出、appcast/发布说明渲染、任何未来导出)都必须剥离开头的 YAML frontmatter;新渲染表面应在同一 commit 中加上剥离逻辑(---date/image---曾原样泄漏进 appcast body)。Note.cleanMetaData是规则本身。CRLF 陷阱:"\r\n"是一个 Swift 字素,range(of: "\n---")永远无法匹配它,需同时搜索"\n---"与"\r\n---"。

TypographyCleaner 受保护区域

Helpers/TypographyCleaner.swift(Edit → Clean Typography)绝不能改写受保护区域:围栏/行内代码、数学、链接目标、wikilink、裸 URL、frontmatter。扩展分段解析器,不要绕过它。Helpers/HtmlToMarkdown.swift 仅在存在块结构标签时才转换粘贴的 HTML,保持纯文本粘贴对来自编辑器复制的代码的权威性,不要移除这个门槛。

本地化新增项

新菜单项需要 storyboard 条目加上 ObjectID 键控的.title行,且要写入全部四个Main.strings(es/ja/zh-Hans/zh-Hant);新 toast 需要以英文文本为 key 写入全部四个Localizable.strings(Base 没有 Localizable.strings,英文回退到 key 本身)。漏掉一个文件会静默地把英文发到该语言。

发布渠道与版本一致性

本仓库只发布直接下载版:GitHub Release 资产加 appcast 条目,由 Sparkle 从https://miaoyan.app/appcast.xml原地更新,并被 Homebrew 接收。用scripts/build.sh构建(Developer ID、公证、Sparkle)。Mac 与 iPhone 的 App Store 构建只来自私有tw93/MiaoYan-Pro,App Store 用户永远不会看到本渠道的版本与 appcast。

两个关键事实:

  • appcast.xml位于 miaoyan.app 站点而非本仓库;scripts/release-ci/update_appcast.sh生成条目,scripts/build.sh打印 enclosure 行。enclosure URL 默认是miaoyan.app/Release/,新条目必须改指向已发布的 GitHub Release 资产;历史条目保留原 URL。
  • 两条安装路径都取发布资产而非 tag tarball:homebrew-cask 的url形如releases/download/V4.3.0/MiaoYan_V4.3.0.zip,appcast enclosure 同形。没有任何东西固定archive/refs/tags/*.tar.gz的哈希,所以无 release 的 tag 可删可重打而不破坏消费者;而删除有 release 的 tag 会立刻弄坏brew install --cask miaoyan,因为 cask 点名该资产。

字体与预览渲染的隐式规则

  • 字体菜单:偏好控制器被复用,菜单打开时才刷新;按已安装家族集合分类缓存(不是按数量),重建菜单时保留选中的存储家族。
  • 默认字体:TsangerJinKai02(TsangerJinKai02-W04)再次成为编辑器、预览与界面的默认字体——但仅按名称,因为它未随包分发(再分发需要仓耳授权,个人非商业使用免费)。未安装前全部用FontConfiguration.fallbackFont(PingFang)渲染;已存储的字体选择永不被改写(迁移或字体缺失都不改写);ViewController监听NSFont.fontSetChangedNotification,选中字体一出现就应用。下载按钮打开字厂直链.ttfURL(FontCatalog.retiredBundledDownloadURL),MiaoYan 从不托管该文件。
  • 字距单一数值:UserDefaultsManagement.letterSpacingEm(0.02em)同时驱动编辑器 kern、界面标签(按各标签字号缩放)与 typography.css 中的.heti。之前固定 0.5pt/0.6pt 与 0.04em 是 2022 年为 LXGW WenKai 调的,会把 PingFang 与所有拉丁字母拉散;三者必须一起改。
  • 两种拼写:Business/FontConfiguration.swift 的默认与回退是 PostScript 名(TsangerJinKai02-W04、PingFangSC-Regular),而字体弹窗写入的全是家族名(PingFang SC,因弹窗由availableFontFamilies构建)。任何比较存储值与默认值、或与弹窗行匹配的逻辑,都必须先经FontCatalog.familyName(forStored:)解析两侧——直接比原始字符串曾让预览的拉丁排序在用户打开弹窗后失效。
  • Latin 归属:FontCatalog.fontStack(forStored:)决定谁负责 Latin,判断标准是"用户是否选中了该字体"而非"是否 CJK 字体"。PingFang(回退)的 Latin 交给ui-sans-serif, system-ui, -apple-system;用户选中的字体自己带队整行(仓耳今楷一类的 Latin 与其中文配套)。
  • CSS 兼容下限:CSS 属性的最低版本须高于MACOSX_DEPLOYMENT_TARGET(当前 12.0);不同属性最低版本不同时,保留支持性回退并在两个引擎上验证无变量行为。
  • 粗体与代码字体:预览对粗体保留所选字体;不要重新引入更重字体的替换(V4.3.1 曾把 W05 换进标题与加粗文字导致变淡,维护者要求换回 W04)。正文用-webkit-font-smoothing: subpixel-antialiased;antialiased加在html上曾让每段都变细。代码字体只作用于围栏代码块(pre code,且不在blockquote内);行内代码与引用代码继承正文字体。存储默认是FontConfiguration.followTextFont(编辑器内用编辑器字体、预览内用预览字体栈),先查UserDefaultsManagement.codeFollowsText再决定是否把codeFontName当作字体。编辑器中的原始 HTML 标签用CodeBlockHighlighter.highlightInlineHTML着色,绝不用highlightCode(那会给它们代码字体和.codeBlock标记)。
  • PPT 字体:ppt.html只加载 reveal 样式表,不加载base.css/typography.css,所以--text-font*变量到不了它,--r-main-font是 reveal 唯一读取的变量。改预览字体时必须同时检查previewStyle()的 PPT 分支。

发布说明规范(Release Notes)

  • Tag 格式:大写Vx.y.z。
  • 一次发布一批:节奏约每月一次(V4.0.0→V4.1.0→V4.2.0 分别间隔 29 与 28 天);版本发布后,后续工作等待下一批。只有本版本引入的回归或用户别无他法的修复才值得追加 tag(V4.3.0 与 V4.3.1 相隔 1.4 小时发布,导致所有 Sparkle 用户一个下午更新两次,是反面教材)。
  • 版本三元组对齐:MARKETING_VERSION与CURRENT_PROJECT_VERSION(均在MiaoYan.xcodeproj/project.pbxproj)必须与发布 tag 对齐。Sparkle 用 appcast.xml 的sparkle:version对比CFBundleVersion(映射自CURRENT_PROJECT_VERSION)而非CFBundleShortVersionString;两者一旦分叉,用户会陷入无限更新提示循环(V3.5.1 事故,#524)。
  • 发布说明来源:.github/RELEASE_NOTES.md 是公开发布说明的唯一来源:# V{x.y.z} {Codename} {emoji}标题 + 中文编号列表 +---分隔 + 与中文一一对应的英文编号列表。scripts/release-ci/render_release_body.sh将其渲染进 GitHub release body 与 appcast 内容;代号遵循scripts/release-ci/generate_release_content.sh中的列表。发布标题形如V4.0.0 Valstrax 🚀;起草前先gh release view上一个 release,照抄其 body 形态而非凭记忆重写。
  • 发布收尾:用gh api添加六个正向 reaction(+1、laugh、heart、hooray、rocket、eyes)并读回确认;绝不添加-1或confused。
  • Sparkle 签名:直接下载版必须用 MiaoYan release key,而非默认的 Sparkle Keychain 账户。推送 appcast 改动前用scripts/release-ci/verify_sparkle_signature.sh对照已发布 ZIP 与 App 内嵌的SUPublicEDKey验证签名;仅签名修正的 appcast 只在 ZIP 字节与长度不变时有效。DMG、ZIP 与 Sparkle 元数据携带同一版本,appcast 指向的 ZIP 必须是签过名的那个文件,绝不能用重新压缩的副本。
  • 发布自动化依赖维护者托管的签名、公证与 Sparkle 凭据;不要记录或提交本地凭据路径、私钥文件名或机密值。

调查顺序:定位问题时的标准路线

当任务范围不明确时,AGENTS.md 规定了从宽到窄的调查顺序:

  1. ARCHITECTURE.md——真实的顶层依赖图;
  2. Controllers/AppDelegate.swift;
  3. Controllers/MainWindowController.swift;
  4. Controllers/ViewController.swift;
  5. 再收窄到Helpers/、Views/、Business/、Extensions/下的相关文件;
  6. 仅当涉及构建、签名、target 成员或版本行为时,才查看相关 Xcode 工程设置。

除非任务明确针对它们,否则避免对build/、.build/、dist/与内置 Web 资产做宽泛扫描。

验证清单(提交前自检)

AGENTS.md 的 Verification 节给出了按改动类型的验收标准:

  • Swift 改动:跑上述 Debugxcodebuild命令。
  • UI/交互修复:启动构建产物、实际走一遍改动流程再报告完成;绿色构建不是视觉证据。若首次修复不奏效,停止猜测,先加#if DEBUG运行时日志取证,再改下一处代码。
  • Lint/格式改动:跑 SwiftLint 与 swift-format 检查。
  • 发布/签名改动:验证版本对齐并检查相关仓库脚本;不要假设存在受跟踪的release.yml。
  • 发布说明改动:检查 .github/RELEASE_NOTES.md 与受影响的scripts/release-ci/渲染器。
  • 导出改动:把 Mermaid、图片、PDF 分页与异步就绪行为放在一起验证。
  • 纯文档改动:检查链接与命令准确性。

这份清单加上本文梳理的构建命令、测试接入流程、CI 门槛、错误上报约定与各高风险区域的不变量,构成了在 MiaoYan 开源仓库中安全协作的完整操作手册——无论贡献者是 AI Agent 还是人类开发者。

  • 桌面应用
  • CLI

【免费下载链接】MiaoYan

⛷ Lightweight Markdown app to help you write great sentences.

项目地址:https://gitcode.com/gh_mirrors/mi/MiaoYan
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 9:00:51

七日量化回测入门(四)Backtrader 双均线回测告别未来函数

1. 引言 在量化回测中&#xff0c;未来函数&#xff08;Look-ahead Bias&#xff09; 是导致回测结果虚高、实盘却亏损的头号杀手。它的本质是&#xff1a;在计算当天交易信号时&#xff0c;无意中使用了当天收盘后&#xff08;甚至未来&#xff09;才产生的数据。 正确做法是&…

作者头像 李华
网站建设 2026/10/4 8:58:19

GitHub热榜深度解析:从项目复现到技术趋势判断

GitHub 热榜&#xff08;Trending&#xff09;一直是我每周必刷的固定栏目&#xff0c;看它不是为了凑热闹&#xff0c;而是想搞清楚当下开发者到底在为什么东西兴奋、什么技术真正落到了能用甚至好用的阶段。这一期周榜扫下来&#xff0c;我最直观的感受是&#xff1a;榜单比前…

作者头像 李华
网站建设 2026/10/4 8:55:21

为什么AI也要算命考试?MingLi-Bench八字命理评测基准深度解析

为什么AI也要算命考试&#xff1f;MingLi-Bench八字命理评测基准深度解析 【免费下载链接】MingLi-Bench A benchmark for evaluating LLMs on Chinese traditional fortune telling — Bazi (八字) and Ziwei Doushu (紫微斗数). 项目地址: https://gitcode.com/gh_mirrors/…

作者头像 李华
网站建设 2026/10/4 8:53:32

架构不是堆层次:判断该不该加一层的实用标准

一次评审会上&#xff0c;年轻同事指着一份设计文档问我&#xff1a;“这个Manager层&#xff0c;是不是有点多余了&#xff1f;我数了一下&#xff0c;一个查询从Controller进来&#xff0c;要经过Service、Manager、Handler&#xff0c;最后才到Mapper&#xff0c;每一层代码…

作者头像 李华