2 Commits
Author SHA1 Message Date
SkyJourneyandClaude Sonnet 5 1fc30f8cf5 fix: 补齐 macOS 桌面应用的 Markdown 文件关联
问题修复:electron-builder 的 mac 配置块此前没有声明 fileAssociations,
打包出的 .app 缺少 Info.plist 的 CFBundleDocumentTypes,导致 Finder"打开
方式"里找不到 MorphDoc,也无法通过双击 .md/.markdown 文件启动。现在新增
对应声明(.md、.markdown,角色 Editor),与 Windows 侧 ProgID 注册对齐;
主进程既有的 open-file 事件处理无需改动。

验证结果:重新打包 arm64 版本后,用 NSWorkspace 查询 .md 候选打开应用,
MorphDoc.app 已正确出现在列表中。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5N6pcbjV4jVfXrcH3NcLP
2026-08-27 19:52:42 +08:00
SkyJourneyandClaude Sonnet 5 7533226366 chore: 规范化 DOCX 发布门禁产出目录并新增清理脚本
问题修复:verify-docx-release-gate-suite.mjs 默认输出目录此前写死为
output/docx-release-gate-v0.6.2,版本升级后需要手工改字符串。改为从根
package.json 动态读取版本号,生成 output/docx-release-gate/v<version>/,
环境变量 MD_TO_PDF_RELEASE_GATE_OUTPUT_DIR 覆盖行为不变。

新增能力:新增 npm run clean:docx-gate-output,清理新目录结构及历史遗留的
output/docx-release-gate-v* 旧命名目录。

验证结果:test:docx-release-gate-suites、test:docx-real-world-corpus 通过;
本机手工构造新旧两种命名目录验证清理脚本均能正确删除且不误删其他 output
子目录。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5N6pcbjV4jVfXrcH3NcLP
2026-08-26 20:05:00 +08:00
5 changed files with 50 additions and 3 deletions
+5 -2
View File
@@ -9,9 +9,12 @@ Gitea Release 页面正文的基础;构建产物、校验和及详细验收记
## [Unreleased] ## [Unreleased]
### 变更 ### 修复
- 暂无。 - 修复 macOS 桌面应用未声明 `.md`/`.markdown` 文件关联的问题:`electron-builder`
`mac` 配置块新增 `fileAssociations`,写入 Info.plist 的
`CFBundleDocumentTypes`Finder"打开方式"中现在能正确列出 MorphDoc;主进程
既有的 `open-file` 事件处理无需改动。
## [0.6.4] - 2026-08-26 ## [0.6.4] - 2026-08-26
+12
View File
@@ -125,6 +125,18 @@ module.exports = {
target: "dmg" target: "dmg"
} }
], ],
// 声明 .md/.markdown 文件关联,写入 Info.plist 的 CFBundleDocumentTypes
// 否则 Finder 的"打开方式"里不会出现本应用;与 Windows 侧的 ProgID 注册
// 是对等能力,主进程已有的 open-file 事件处理无需改动。
fileAssociations: [
{
ext: ["md", "markdown"],
name: "Markdown",
description: "Markdown 文档",
role: "Editor",
icon: macIcon
}
],
extraResources: macTargetArch extraResources: macTargetArch
? [ ? [
{ {
+1
View File
@@ -54,6 +54,7 @@
"verify:docx-layout-visual-matrix": "npm run test:docx-layout-visual-matrix-cases && npm run verify:font-pack && npm run build:web-runtime && npm run build -w @md-to-pdf/document-visual-diff && npm run build -w @md-to-pdf/server && node scripts/verify-docx-layout-visual-matrix.mjs", "verify:docx-layout-visual-matrix": "npm run test:docx-layout-visual-matrix-cases && npm run verify:font-pack && npm run build:web-runtime && npm run build -w @md-to-pdf/document-visual-diff && npm run build -w @md-to-pdf/server && node scripts/verify-docx-layout-visual-matrix.mjs",
"verify:docx-release-gate-suite": "npm run test:docx-layout-visual-matrix-cases && npm run test:docx-real-world-corpus && npm run test:docx-release-gate-suites && npm run verify:font-pack && npm run build:web-runtime && npm run build -w @md-to-pdf/document-visual-diff && npm run build -w @md-to-pdf/server && node scripts/verify-docx-release-gate-suite.mjs", "verify:docx-release-gate-suite": "npm run test:docx-layout-visual-matrix-cases && npm run test:docx-real-world-corpus && npm run test:docx-release-gate-suites && npm run verify:font-pack && npm run build:web-runtime && npm run build -w @md-to-pdf/document-visual-diff && npm run build -w @md-to-pdf/server && node scripts/verify-docx-release-gate-suite.mjs",
"verify:docx-release-gate-560": "npm run verify:docx-release-gate-suite", "verify:docx-release-gate-560": "npm run verify:docx-release-gate-suite",
"clean:docx-gate-output": "node scripts/clean-docx-gate-output.mjs",
"test": "npm run test:release-stage && npm run test:docx-layout-visual-matrix-cases && npm run test:docx-real-world-corpus && npm run test:docx-release-gate-suites && npm run test -w @md-to-pdf/markdown-echarts && npm run test -w @md-to-pdf/core && npm run build -w @md-to-pdf/core && npm run test -w @md-to-pdf/semantic-document && npm run build -w @md-to-pdf/semantic-document && npm run test -w @md-to-pdf/docx-theme-engine && npm run test -w @md-to-pdf/document-visual-diff && npm run test -w @md-to-pdf/font-pack-registry && npm run build -w @md-to-pdf/font-pack-registry && npm run test -w @md-to-pdf/docx-engine && npm run build -w @md-to-pdf/docx-engine && npm run test -w @md-to-pdf/font-pack-builder && npm run test -w @md-to-pdf/renderer && npm run test -w @md-to-pdf/application && npm run build -w @md-to-pdf/application && npm run test -w @md-to-pdf/preview-engine && npm run build -w @md-to-pdf/preview-engine && npm run test -w @md-to-pdf/web && npm run test -w @md-to-pdf/server && npm run test -w @md-to-pdf/desktop", "test": "npm run test:release-stage && npm run test:docx-layout-visual-matrix-cases && npm run test:docx-real-world-corpus && npm run test:docx-release-gate-suites && npm run test -w @md-to-pdf/markdown-echarts && npm run test -w @md-to-pdf/core && npm run build -w @md-to-pdf/core && npm run test -w @md-to-pdf/semantic-document && npm run build -w @md-to-pdf/semantic-document && npm run test -w @md-to-pdf/docx-theme-engine && npm run test -w @md-to-pdf/document-visual-diff && npm run test -w @md-to-pdf/font-pack-registry && npm run build -w @md-to-pdf/font-pack-registry && npm run test -w @md-to-pdf/docx-engine && npm run build -w @md-to-pdf/docx-engine && npm run test -w @md-to-pdf/font-pack-builder && npm run test -w @md-to-pdf/renderer && npm run test -w @md-to-pdf/application && npm run build -w @md-to-pdf/application && npm run test -w @md-to-pdf/preview-engine && npm run build -w @md-to-pdf/preview-engine && npm run test -w @md-to-pdf/web && npm run test -w @md-to-pdf/server && npm run test -w @md-to-pdf/desktop",
"typecheck": "npm run typecheck -w @md-to-pdf/markdown-echarts && npm run build -w @md-to-pdf/markdown-echarts && npm run typecheck -w @md-to-pdf/core && npm run build -w @md-to-pdf/core && npm run typecheck -w @md-to-pdf/semantic-document && npm run build -w @md-to-pdf/semantic-document && npm run typecheck -w @md-to-pdf/docx-theme-engine && npm run build -w @md-to-pdf/docx-theme-engine && npm run typecheck -w @md-to-pdf/document-visual-diff && npm run typecheck -w @md-to-pdf/font-pack-registry && npm run typecheck -w @md-to-pdf/docx-engine && npm run build -w @md-to-pdf/docx-engine && npm run typecheck -w @md-to-pdf/font-pack-builder && npm run typecheck -w @md-to-pdf/renderer && npm run build -w @md-to-pdf/renderer && npm run typecheck -w @md-to-pdf/application && npm run build -w @md-to-pdf/application && npm run typecheck -w @md-to-pdf/preview-engine && npm run build -w @md-to-pdf/preview-engine && npm run typecheck -w @md-to-pdf/web && npm run typecheck -w @md-to-pdf/server && npm run typecheck -w @md-to-pdf/desktop" "typecheck": "npm run typecheck -w @md-to-pdf/markdown-echarts && npm run build -w @md-to-pdf/markdown-echarts && npm run typecheck -w @md-to-pdf/core && npm run build -w @md-to-pdf/core && npm run typecheck -w @md-to-pdf/semantic-document && npm run build -w @md-to-pdf/semantic-document && npm run typecheck -w @md-to-pdf/docx-theme-engine && npm run build -w @md-to-pdf/docx-theme-engine && npm run typecheck -w @md-to-pdf/document-visual-diff && npm run typecheck -w @md-to-pdf/font-pack-registry && npm run typecheck -w @md-to-pdf/docx-engine && npm run build -w @md-to-pdf/docx-engine && npm run typecheck -w @md-to-pdf/font-pack-builder && npm run typecheck -w @md-to-pdf/renderer && npm run build -w @md-to-pdf/renderer && npm run typecheck -w @md-to-pdf/application && npm run build -w @md-to-pdf/application && npm run typecheck -w @md-to-pdf/preview-engine && npm run build -w @md-to-pdf/preview-engine && npm run typecheck -w @md-to-pdf/web && npm run typecheck -w @md-to-pdf/server && npm run typecheck -w @md-to-pdf/desktop"
}, },
+28
View File
@@ -0,0 +1,28 @@
import fs from "node:fs";
import path from "node:path";
const repositoryDirectory = path.resolve(import.meta.dirname, "..");
const outputDirectory = path.join(repositoryDirectory, "output");
const targets = [path.join(outputDirectory, "docx-release-gate")];
if (fs.existsSync(outputDirectory)) {
for (const entry of fs.readdirSync(outputDirectory, { withFileTypes: true })) {
if (entry.isDirectory() && /^docx-release-gate-v/u.test(entry.name)) {
targets.push(path.join(outputDirectory, entry.name));
}
}
}
let removedCount = 0;
for (const target of targets) {
if (fs.existsSync(target)) {
fs.rmSync(target, { recursive: true, force: true });
process.stdout.write(`已删除:${path.relative(repositoryDirectory, target)}\n`);
removedCount += 1;
}
}
if (removedCount === 0) {
process.stdout.write("没有找到需要清理的门禁产出目录。\n");
}
+4 -1
View File
@@ -16,10 +16,13 @@ import {
const execFileAsync = promisify(execFile); const execFileAsync = promisify(execFile);
const repositoryDirectory = path.resolve(import.meta.dirname, ".."); const repositoryDirectory = path.resolve(import.meta.dirname, "..");
const matrixScript = path.join(repositoryDirectory, "scripts", "verify-docx-layout-visual-matrix.mjs"); const matrixScript = path.join(repositoryDirectory, "scripts", "verify-docx-layout-visual-matrix.mjs");
const repositoryVersion = JSON.parse(
fs.readFileSync(path.join(repositoryDirectory, "package.json"), "utf8")
).version;
const outputRoot = path.resolve( const outputRoot = path.resolve(
repositoryDirectory, repositoryDirectory,
process.env.MD_TO_PDF_RELEASE_GATE_OUTPUT_DIR?.trim() || process.env.MD_TO_PDF_RELEASE_GATE_OUTPUT_DIR?.trim() ||
"output/docx-release-gate-v0.6.2" path.join("output", "docx-release-gate", `v${repositoryVersion}`)
); );
const requestedSuiteId = process.env.MD_TO_PDF_RELEASE_GATE_SUITE?.trim() || "next"; const requestedSuiteId = process.env.MD_TO_PDF_RELEASE_GATE_SUITE?.trim() || "next";
const selectedCaseId = process.env.MD_TO_PDF_RELEASE_GATE_CASE?.trim() || undefined; const selectedCaseId = process.env.MD_TO_PDF_RELEASE_GATE_CASE?.trim() || undefined;