- 桌面应用
- CLI
【免费下载链接】MiaoYan
⛷ Lightweight Markdown app to help you write great sentences.
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中手动注册四处:
PBXBuildFile条目;PBXFileReference条目;- 所属 group 的
children列表; - target 的
PBXSourcesBuildPhasefiles 列表。
做法是模仿一个现有同层条目,并为每个新对象使用全新的 24 位十六进制唯一 ID。这一步极易遗漏,是新手贡献者最常见的失败点。
单元测试实践
单元测试位于MiaoYanTests/下,覆盖面聚焦纯逻辑接口(ImageLinkParser、WikilinkIndex.updateNote、String+扩展等,对应仓库中的 ImageLinkParserTests.swift、WikilinkIndexTests.swift、StringExtensionsTests.swift 等测试文件)。UI 流程不做 XCUITest,而是靠构建后的人工冒烟验证。
新增测试的规范步骤:
- 创建
MiaoYanTests/<Subject>Tests.swift(XCTest;若测试方法触碰@MainActor隔离类型则给方法加@MainActor;setUp()覆写不能是@MainActor,需要在测试方法内部构造隔离对象)。 - 与 App 源码一样,手动注册到 pbxproj 的同一四个位置,但挂到
MiaoYanTestsgroup 和MiaoYanTeststarget 的PBXSourcesBuildPhase,参照现有NoteFrontmatterTests.swift条目。scripts/add_tests_target.rb在 target 已存在时是空操作(它只在 pbxproj 重置后做引导),且它依赖的xcodeprojgem 在本机并未安装。 - 本地跑
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:
- build-mac(macOS Debug 构建 + 单元测试):运行于
macos-15,固定DEVELOPER_DIR为 Xcode 16.3;先-resolvePackageDependencies,再xcodebuild build,随后xcodebuild test,全程CODE_SIGNING_ALLOWED=NO(免签名),输出经xcbeautify转为 GitHub Actions 格式。 - lint(SwiftLint + swift-format,双 --strict):
brew install swiftlint后跑swiftlint lint --strict;再安装 swift-format 并跑swift-format lint --recursive . --strict。任何 warning 都是合并门槛。 - release-notes-smoke(发布说明渲染冒烟):在 ubuntu 上跑
scripts/release-ci/notes_to_html.sh与render_release_body.sh渲染.github/RELEASE_NOTES.md,并断言输出非空。这样坏掉的发布说明文件会在发布前而不是发布中被发现。 - 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/文件夹,引用为;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 规定了从宽到窄的调查顺序:
- ARCHITECTURE.md——真实的顶层依赖图;
- Controllers/AppDelegate.swift;
- Controllers/MainWindowController.swift;
- Controllers/ViewController.swift;
- 再收窄到
Helpers/、Views/、Business/、Extensions/下的相关文件; - 仅当涉及构建、签名、target 成员或版本行为时,才查看相关 Xcode 工程设置。
除非任务明确针对它们,否则避免对build/、.build/、dist/与内置 Web 资产做宽泛扫描。
验证清单(提交前自检)
AGENTS.md 的 Verification 节给出了按改动类型的验收标准:
- Swift 改动:跑上述 Debug
xcodebuild命令。 - 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.
相关推荐
Vim 仓库开发协作指南:面向 AI Coding Agent 与贡献者的贡献规范、构建测试与代码风格全解析
Vim 仓库开发协作指南:面向 AI Coding Agent 与贡献者的贡献规范、构建测试与代码风格全解析 本文以 Vim 官方仓库根目录的 AGENTS.m
开发工具代码编辑器WPScan 仓库开发指南:面向 AI Agent 的架构解析、测试与构建实践
WPScan 仓库开发指南:面向 AI Agent 的架构解析、测试与构建实践 本文以仓库根目录的 AGENTS.md https://link.gitcode
网络安全漏洞扫描渗透测试应用安全CLI面向 AI 编码 Agent 的 Vim 仓库开发指南:构建、测试与代码规范全解析
面向 AI 编码 Agent 的 Vim 仓库开发指南:构建、测试与代码规范全解析 本指南以 macvim 仓库根目录的 AGENTS.md https://l
开发工具桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考