feat: add local approval submission drafts

This commit is contained in:
2026-08-19 15:53:47 +00:00
parent 0a7ad6a3b6
commit 5d889d4445
21 changed files with 176 additions and 25 deletions
+15
View File
@@ -36,6 +36,7 @@ test("customer distribution prefers remote MCP OAuth and keeps a generic compati
assert.match(compatibilityInstaller, /90 秒[\s\S]*stderr[\s\S]*stdout/);
assert.match(compatibilityInstaller, /登录链接过期.*绝不能重新安装.*approval_login.*loginCommand/s);
assert.match(compatibilityInstaller, /sourceStatus[\s\S]*dingtalk\.status[\s\S]*xft\.status[\s\S]*都必须是 `ok`/);
assert.match(compatibilityInstaller, /references\/local-drafts\.md/);
assert.match(compatibilityInstaller, /更新[\s\S]*update --json[\s\S]*卸载[\s\S]*uninstall --yes --json/);
assert.doesNotMatch(compatibilityInstaller, /TimeoutSec 300|--max-time 300|--timeout=300|至少 10 分钟超时/);
assert.doesNotMatch(compatibilityInstaller, /--host|WorkBuddy|Codex|Claude/);
@@ -80,7 +81,9 @@ test("customer distribution prefers remote MCP OAuth and keeps a generic compati
const skill = readFileSync("skills/dingtalk-approval/SKILL.md", "utf8");
const createApproval = readFileSync("skills/dingtalk-approval/references/create-approval.md", "utf8");
const localDrafts = readFileSync("skills/dingtalk-approval/references/local-drafts.md", "utf8");
assert.match(skill, /read `references\/create-approval\.md` completely/);
assert.match(skill, /read `references\/local-drafts\.md` completely/);
assert.doesNotMatch(skill, /XFT recall is experimental/);
assert.match(createApproval, /XFT recall is experimental.*XFTSYS9999/s);
assert.match(skill, /native remote-MCP OAuth flow when the user can complete its registered callback/);
@@ -90,6 +93,18 @@ test("customer distribution prefers remote MCP OAuth and keeps a generic compati
assert.match(skill, /authChallenge\.directUrl.*current reply/s);
assert.match(skill, /onboarding\.firstRun=true.*Do not execute an example automatically/s);
assert.match(skill, /link expires.*approval_login.*Never reinstall/s);
assert.match(localDrafts, /%LOCALAPPDATA%\\DingTalkApproval\\drafts/);
assert.match(localDrafts, /Library\/Application Support\/DingTalkApproval\/drafts/);
assert.match(localDrafts, /\.local\/share.*dingtalk-approval\/drafts/s);
assert.match(localDrafts, /mode `0700`.*mode `0600`/s);
assert.match(localDrafts, /atomically rename/);
assert.match(localDrafts, /more than 90 days old/);
assert.match(localDrafts, /SHA-256/);
assert.match(localDrafts, /Never store[\s\S]*templateId[\s\S]*confirmationId[\s\S]*complete upstream schema/);
assert.match(localDrafts, /outcome_uncertain[\s\S]*freeze[\s\S]*Never prepare or submit it again automatically/);
assert.match(localDrafts, /never on the approval gateway/);
assert.match(localDrafts, /local attachment path.*never a valid upstream attachment field value.*native client/s);
assert.match(createApproval, /Local file paths.*not valid attachment field values.*native client/s);
const builder = readFileSync("scripts/build-release.mjs", "utf8");
assert.match(builder, /schemaVersion: 3,\s+version,/s);